@nan0web/ui 1.8.0 → 1.10.0
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 +29 -10
- package/package.json +18 -22
- package/src/Model/index.js +32 -3
- package/src/core/Form/Form.js +8 -7
- package/src/core/Form/Message.js +1 -1
- package/src/core/GeneratorRunner.js +10 -0
- package/src/core/Intent.js +21 -5
- package/src/core/IntentErrorModel.js +6 -1
- package/src/core/Stream.js +16 -5
- package/src/core/index.js +1 -1
- package/src/domain/FooterModel.js +57 -0
- package/src/domain/HeaderModel.js +50 -0
- package/src/domain/HeroModel.js +48 -0
- package/src/domain/Navigation.js +11 -10
- package/src/domain/SandboxModel.js +66 -115
- package/src/domain/ShowcaseAppModel.js +133 -50
- package/src/domain/components/AccordionModel.js +38 -0
- package/src/domain/components/AutocompleteModel.js +11 -21
- package/src/domain/components/BannerModel.js +37 -0
- package/src/domain/components/BreadcrumbModel.js +11 -9
- package/src/domain/components/ButtonModel.js +31 -58
- package/src/domain/components/CommentModel.js +44 -0
- package/src/domain/components/ConfirmModel.js +26 -33
- package/src/domain/components/EmptyStateModel.js +45 -0
- package/src/domain/components/FAQModel.js +32 -0
- package/src/domain/components/FooterConfigModel.js +26 -0
- package/src/domain/components/FooterVisibilityModel.js +48 -0
- package/src/domain/components/GalleryModel.js +36 -0
- package/src/domain/components/HeaderConfigModel.js +26 -0
- package/src/domain/components/HeaderVisibilityModel.js +54 -0
- package/src/domain/components/InputModel.js +21 -41
- package/src/domain/components/PriceModel.js +30 -0
- package/src/domain/components/PricingModel.js +39 -0
- package/src/domain/components/PricingSectionModel.js +32 -0
- package/src/domain/components/ProfileDropdownModel.js +45 -0
- package/src/domain/components/SelectModel.js +11 -21
- package/src/domain/components/SpinnerModel.js +11 -26
- package/src/domain/components/StatsItemModel.js +38 -0
- package/src/domain/components/StatsModel.js +32 -0
- package/src/domain/components/TableModel.js +11 -24
- package/src/domain/components/TabsModel.js +30 -0
- package/src/domain/components/TestimonialModel.js +24 -0
- package/src/domain/components/TimelineItemModel.js +38 -0
- package/src/domain/components/TimelineModel.js +32 -0
- package/src/domain/components/ToastModel.js +24 -51
- package/src/domain/components/TreeModel.js +10 -26
- package/src/domain/components/index.js +34 -0
- package/src/domain/index.js +24 -0
- package/src/index.js +2 -0
- package/src/testing/GalleryGenerator.js +85 -0
- package/src/testing/LogicInspector.js +55 -0
- package/src/testing/SnapshotInspector.js +84 -0
- package/src/testing/VisualAdapter.js +41 -0
- package/src/testing/index.js +3 -0
- package/types/Model/index.d.ts +62 -4
- package/types/core/Form/Form.d.ts +2 -2
- package/types/core/GeneratorRunner.d.ts +4 -0
- package/types/core/Intent.d.ts +31 -3
- package/types/core/IntentErrorModel.d.ts +4 -0
- package/types/core/index.d.ts +1 -1
- package/types/domain/FooterModel.d.ts +52 -0
- package/types/domain/HeaderModel.d.ts +45 -0
- package/types/domain/HeroModel.d.ts +43 -0
- package/types/domain/Navigation.d.ts +10 -9
- package/types/domain/SandboxModel.d.ts +16 -40
- package/types/domain/ShowcaseAppModel.d.ts +26 -54
- package/types/domain/components/AccordionModel.d.ts +33 -0
- package/types/domain/components/AutocompleteModel.d.ts +10 -29
- package/types/domain/components/BannerModel.d.ts +32 -0
- package/types/domain/components/BreadcrumbModel.d.ts +13 -6
- package/types/domain/components/ButtonModel.d.ts +18 -54
- package/types/domain/components/CommentModel.d.ts +39 -0
- package/types/domain/components/ConfirmModel.d.ts +20 -35
- package/types/domain/components/EmptyStateModel.d.ts +40 -0
- package/types/domain/components/FAQModel.d.ts +27 -0
- package/types/domain/components/FooterConfigModel.d.ts +21 -0
- package/types/domain/components/FooterVisibilityModel.d.ts +43 -0
- package/types/domain/components/GalleryModel.d.ts +35 -0
- package/types/domain/components/HeaderConfigModel.d.ts +21 -0
- package/types/domain/components/HeaderVisibilityModel.d.ts +49 -0
- package/types/domain/components/HeroModel.d.ts +24 -0
- package/types/domain/components/InputModel.d.ts +19 -59
- package/types/domain/components/PriceModel.d.ts +25 -0
- package/types/domain/components/PricingModel.d.ts +34 -0
- package/types/domain/components/PricingSectionModel.d.ts +27 -0
- package/types/domain/components/ProfileDropdownModel.d.ts +40 -0
- package/types/domain/components/SelectModel.d.ts +13 -28
- package/types/domain/components/ShowcaseAppModel.d.ts +32 -0
- package/types/domain/components/SpinnerModel.d.ts +10 -27
- package/types/domain/components/StatsItemModel.d.ts +33 -0
- package/types/domain/components/StatsModel.d.ts +27 -0
- package/types/domain/components/TableModel.d.ts +10 -26
- package/types/domain/components/TabsModel.d.ts +28 -0
- package/types/domain/components/TestimonialModel.d.ts +18 -0
- package/types/domain/components/TimelineItemModel.d.ts +33 -0
- package/types/domain/components/TimelineModel.d.ts +27 -0
- package/types/domain/components/ToastModel.d.ts +16 -45
- package/types/domain/components/TreeModel.d.ts +13 -36
- package/types/domain/components/index.d.ts +20 -0
- package/types/domain/index.d.ts +4 -1
- package/types/index.d.ts +1 -0
- package/types/testing/GalleryGenerator.d.ts +1 -0
- package/types/testing/LogicInspector.d.ts +22 -0
- package/types/testing/SnapshotInspector.d.ts +17 -0
- package/types/testing/VisualAdapter.d.ts +15 -0
- package/types/testing/index.d.ts +3 -0
- package/src/README.md.js +0 -436
|
@@ -1,92 +1,65 @@
|
|
|
1
|
-
import { Model } from '@nan0web/
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {'primary'|'secondary'|'info'|'ok'|'warn'|'err'|'ghost'} ButtonVariant
|
|
5
|
-
* @typedef {'sm'|'md'|'lg'} ButtonSize
|
|
6
|
-
* @typedef {Object} ButtonData
|
|
7
|
-
* @property {string} [content]
|
|
8
|
-
* @property {ButtonVariant} [variant]
|
|
9
|
-
* @property {ButtonSize} [size]
|
|
10
|
-
* @property {boolean} [outline]
|
|
11
|
-
* @property {boolean} [disabled]
|
|
12
|
-
* @property {boolean} [loading]
|
|
13
|
-
*/
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
14
2
|
|
|
15
3
|
/**
|
|
16
4
|
* Model-as-Schema for Button component.
|
|
17
|
-
* Represents the intention and state of a Button interaction.
|
|
18
|
-
* Used exclusively for schema definition and editor validation.
|
|
19
5
|
*/
|
|
20
6
|
export class ButtonModel extends Model {
|
|
21
|
-
// ==========================================
|
|
22
|
-
// 1. MODEL AS SCHEMA (Static Definition)
|
|
23
|
-
// ==========================================
|
|
24
|
-
|
|
25
|
-
static content = {
|
|
26
|
-
help: 'Text or content inside the button',
|
|
27
|
-
default: 'Click Me',
|
|
28
|
-
type: 'string',
|
|
29
|
-
}
|
|
30
|
-
|
|
31
7
|
static variant = {
|
|
32
|
-
help: '
|
|
8
|
+
help: 'Button visual style',
|
|
33
9
|
default: 'primary',
|
|
34
|
-
options: ['primary', 'secondary', '
|
|
10
|
+
options: ['primary', 'secondary', 'danger', 'ghost'],
|
|
35
11
|
}
|
|
36
12
|
|
|
37
|
-
static
|
|
38
|
-
help: '
|
|
39
|
-
default: '
|
|
40
|
-
|
|
13
|
+
static content = {
|
|
14
|
+
help: 'Text displayed inside the button',
|
|
15
|
+
default: 'Click me',
|
|
16
|
+
type: 'string',
|
|
41
17
|
}
|
|
42
18
|
|
|
43
|
-
static
|
|
44
|
-
help: '
|
|
45
|
-
default:
|
|
46
|
-
type: '
|
|
19
|
+
static href = {
|
|
20
|
+
help: 'Optional link URL',
|
|
21
|
+
default: '',
|
|
22
|
+
type: 'string',
|
|
47
23
|
}
|
|
48
24
|
|
|
49
25
|
static disabled = {
|
|
50
|
-
help: 'Whether the button
|
|
26
|
+
help: 'Whether the button can be clicked',
|
|
51
27
|
default: false,
|
|
52
28
|
type: 'boolean',
|
|
53
29
|
}
|
|
54
30
|
|
|
55
|
-
static
|
|
56
|
-
help: '
|
|
31
|
+
static clicked = {
|
|
32
|
+
help: 'Interal flag: true if clicked',
|
|
57
33
|
default: false,
|
|
58
34
|
type: 'boolean',
|
|
59
35
|
}
|
|
60
36
|
|
|
61
37
|
/**
|
|
62
|
-
* @param {
|
|
38
|
+
* @param {Partial<ButtonModel> | Record<string, any>} data Model input data.
|
|
39
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
63
40
|
*/
|
|
64
|
-
constructor(data = {}) {
|
|
65
|
-
super(data)
|
|
66
|
-
/** @type {
|
|
67
|
-
/** @type {
|
|
68
|
-
/** @type {
|
|
69
|
-
/** @type {boolean
|
|
70
|
-
/** @type {boolean
|
|
71
|
-
/** @type {boolean|undefined} */ this.loading
|
|
41
|
+
constructor(data = {}, options = {}) {
|
|
42
|
+
super(data, options)
|
|
43
|
+
/** @type {'primary'|'secondary'|'danger'|'ghost'} Button visual style */ this.variant
|
|
44
|
+
/** @type {string} Text displayed inside the button */ this.content
|
|
45
|
+
/** @type {string} Optional link URL */ this.href
|
|
46
|
+
/** @type {boolean} Whether the button can be clicked */ this.disabled
|
|
47
|
+
/** @type {boolean} Reactive flag set to true when user activates the button */ this.clicked
|
|
72
48
|
}
|
|
73
49
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
50
|
+
/**
|
|
51
|
+
* @returns {AsyncGenerator<any, any, any>}
|
|
52
|
+
*/
|
|
78
53
|
async *run() {
|
|
79
|
-
// A basic button interaction intention:
|
|
80
|
-
// We simply yield ourselves as a 'button_click' intent.
|
|
81
|
-
// Adaptors will render the button and wait for the click event.
|
|
82
54
|
const response = yield {
|
|
83
55
|
type: 'ask',
|
|
84
|
-
field: '
|
|
85
|
-
schema: { help: 'Click the button
|
|
56
|
+
field: 'clicked',
|
|
57
|
+
schema: { help: 'Click the button' },
|
|
86
58
|
component: 'Button',
|
|
87
|
-
model:
|
|
59
|
+
model: this,
|
|
88
60
|
}
|
|
89
61
|
|
|
90
|
-
|
|
62
|
+
this.clicked = response.value?.clicked || false
|
|
63
|
+
return { type: 'result', data: { clicked: this.clicked } }
|
|
91
64
|
}
|
|
92
65
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CommentModel — OLMUI Model-as-Schema
|
|
5
|
+
* Base model for user-generated comments / reviews.
|
|
6
|
+
*/
|
|
7
|
+
export class CommentModel extends Model {
|
|
8
|
+
static $id = '@nan0web/ui/CommentModel'
|
|
9
|
+
|
|
10
|
+
static author = {
|
|
11
|
+
help: 'Author name',
|
|
12
|
+
placeholder: 'Jane Doe',
|
|
13
|
+
default: '',
|
|
14
|
+
required: true,
|
|
15
|
+
}
|
|
16
|
+
static avatar = {
|
|
17
|
+
help: 'Author avatar image URL',
|
|
18
|
+
placeholder: 'https://...',
|
|
19
|
+
default: '',
|
|
20
|
+
}
|
|
21
|
+
static text = {
|
|
22
|
+
help: 'Comment body text',
|
|
23
|
+
placeholder: 'Great product!',
|
|
24
|
+
default: '',
|
|
25
|
+
required: true,
|
|
26
|
+
}
|
|
27
|
+
static date = {
|
|
28
|
+
help: 'Comment date (ISO 8601)',
|
|
29
|
+
placeholder: '2026-01-01',
|
|
30
|
+
default: '',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {Partial<CommentModel> | Record<string, any>} data Model input data.
|
|
35
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
36
|
+
*/
|
|
37
|
+
constructor(data = {}, options = {}) {
|
|
38
|
+
super(data, options)
|
|
39
|
+
/** @type {string} Author name */ this.author
|
|
40
|
+
/** @type {string} Author avatar image URL */ this.avatar
|
|
41
|
+
/** @type {string} Comment body text */ this.text
|
|
42
|
+
/** @type {string} Comment date (ISO 8601) */ this.date
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -1,64 +1,57 @@
|
|
|
1
|
-
import { Model } from '@nan0web/
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* @property {string} [message]
|
|
6
|
-
* @property {string} [confirmText]
|
|
7
|
-
* @property {string} [cancelText]
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Model-as-Schema for Confirm component.
|
|
4
|
+
* Model-as-Schema for Confirmation dialog.
|
|
12
5
|
*/
|
|
13
6
|
export class ConfirmModel extends Model {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
static title = {
|
|
8
|
+
help: 'Short title for the action',
|
|
9
|
+
default: 'Confirm Action',
|
|
10
|
+
type: 'string',
|
|
11
|
+
}
|
|
17
12
|
|
|
18
13
|
static message = {
|
|
19
|
-
help: '
|
|
14
|
+
help: 'The question asked to the user',
|
|
20
15
|
default: 'Are you sure?',
|
|
21
16
|
type: 'string',
|
|
22
17
|
}
|
|
23
18
|
|
|
24
|
-
static
|
|
25
|
-
help: '
|
|
19
|
+
static okLabel = {
|
|
20
|
+
help: 'Text for the confirm button',
|
|
26
21
|
default: 'Yes',
|
|
27
22
|
type: 'string',
|
|
28
23
|
}
|
|
29
24
|
|
|
30
|
-
static
|
|
31
|
-
help: '
|
|
25
|
+
static cancelLabel = {
|
|
26
|
+
help: 'Text for the cancel button',
|
|
32
27
|
default: 'No',
|
|
33
28
|
type: 'string',
|
|
34
29
|
}
|
|
35
30
|
|
|
36
31
|
/**
|
|
37
|
-
* @param {
|
|
32
|
+
* @param {Partial<ConfirmModel> | Record<string, any>} data Model input data.
|
|
33
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
38
34
|
*/
|
|
39
|
-
constructor(data = {}) {
|
|
40
|
-
super(data)
|
|
41
|
-
/** @type {string
|
|
42
|
-
/** @type {string
|
|
43
|
-
/** @type {string
|
|
35
|
+
constructor(data = {}, options = {}) {
|
|
36
|
+
super(data, options)
|
|
37
|
+
/** @type {string} Short title for the action */ this.title
|
|
38
|
+
/** @type {string} The question asked to the user */ this.message
|
|
39
|
+
/** @type {string} Text for the confirm button */ this.okLabel
|
|
40
|
+
/** @type {string} Text for the cancel button */ this.cancelLabel
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
/**
|
|
44
|
+
* @returns {AsyncGenerator<any, any, any>}
|
|
45
|
+
*/
|
|
50
46
|
async *run() {
|
|
51
47
|
const response = yield {
|
|
52
48
|
type: 'ask',
|
|
53
49
|
field: 'confirmed',
|
|
54
|
-
schema: {
|
|
55
|
-
help: this.message,
|
|
56
|
-
type: 'boolean',
|
|
57
|
-
},
|
|
50
|
+
schema: { type: 'boolean', help: this.message },
|
|
58
51
|
component: 'Confirm',
|
|
59
|
-
model:
|
|
52
|
+
model: this,
|
|
60
53
|
}
|
|
61
54
|
|
|
62
|
-
return { type: 'result', data: { confirmed:
|
|
55
|
+
return { type: 'result', data: { confirmed: response.value === true } }
|
|
63
56
|
}
|
|
64
57
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
|
+
import Navigation from '../Navigation.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* EmptyStateModel — OLMUI Model-as-Schema
|
|
6
|
+
* Onboarding placeholder for empty tables, lists, or dashboards.
|
|
7
|
+
*/
|
|
8
|
+
export class EmptyStateModel extends Model {
|
|
9
|
+
static $id = '@nan0web/ui/EmptyStateModel'
|
|
10
|
+
|
|
11
|
+
static icon = {
|
|
12
|
+
help: 'Illustration or icon name for the empty state',
|
|
13
|
+
placeholder: 'inbox',
|
|
14
|
+
default: '',
|
|
15
|
+
}
|
|
16
|
+
static title = {
|
|
17
|
+
help: 'Empty state headline',
|
|
18
|
+
placeholder: 'No items yet',
|
|
19
|
+
default: '',
|
|
20
|
+
required: true,
|
|
21
|
+
}
|
|
22
|
+
static description = {
|
|
23
|
+
help: 'Helpful description guiding the user',
|
|
24
|
+
placeholder: 'Create your first item to get started',
|
|
25
|
+
default: '',
|
|
26
|
+
}
|
|
27
|
+
static action = {
|
|
28
|
+
help: 'Primary CTA action (Navigation link or button)',
|
|
29
|
+
type: 'Navigation',
|
|
30
|
+
hint: Navigation,
|
|
31
|
+
default: null,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {Partial<EmptyStateModel> | Record<string, any>} data Model input data.
|
|
36
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
37
|
+
*/
|
|
38
|
+
constructor(data = {}, options = {}) {
|
|
39
|
+
super(data, options)
|
|
40
|
+
/** @type {string} Illustration or icon name for the empty state */ this.icon
|
|
41
|
+
/** @type {string} Empty state headline */ this.title
|
|
42
|
+
/** @type {string} Helpful description guiding the user */ this.description
|
|
43
|
+
/** @type {Navigation|null} Primary CTA action (Navigation link or button) */ this.action
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
|
+
import { AccordionModel } from './AccordionModel.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* FAQModel — OLMUI Model-as-Schema
|
|
6
|
+
* A section containing a title and a collection of FAQ (accordion) items.
|
|
7
|
+
*/
|
|
8
|
+
export class FAQModel extends Model {
|
|
9
|
+
static $id = '@nan0web/ui/FAQModel'
|
|
10
|
+
|
|
11
|
+
static title = {
|
|
12
|
+
help: 'Section title',
|
|
13
|
+
placeholder: 'Frequently Asked Questions',
|
|
14
|
+
default: '',
|
|
15
|
+
}
|
|
16
|
+
static items = {
|
|
17
|
+
help: 'Array of FAQ items',
|
|
18
|
+
type: 'AccordionModel[]',
|
|
19
|
+
hint: AccordionModel,
|
|
20
|
+
default: [],
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {Partial<FAQModel> | Record<string, any>} data Model input data.
|
|
25
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
26
|
+
*/
|
|
27
|
+
constructor(data = {}, options = {}) {
|
|
28
|
+
super(data, options)
|
|
29
|
+
/** @type {string} Section title */ this.title
|
|
30
|
+
/** @type {AccordionModel[]} Array of FAQ items */ this.items
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
|
+
import { FooterVisibilityModel } from './FooterVisibilityModel.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* FooterConfigModel — OLMUI Model-as-Schema
|
|
6
|
+
* Configuration container mapping UI variant keys to FooterVisibilityModel instances.
|
|
7
|
+
*/
|
|
8
|
+
export class FooterConfigModel extends Model {
|
|
9
|
+
static $id = '@nan0web/ui/FooterConfigModel'
|
|
10
|
+
|
|
11
|
+
static ui = {
|
|
12
|
+
help: 'Map of UI variant name → FooterVisibilityModel',
|
|
13
|
+
type: 'Record<string, FooterVisibilityModel>',
|
|
14
|
+
hint: FooterVisibilityModel,
|
|
15
|
+
default: {},
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {Partial<FooterConfigModel> | Record<string, any>} data Model input data.
|
|
20
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
21
|
+
*/
|
|
22
|
+
constructor(data = {}, options = {}) {
|
|
23
|
+
super(data, options)
|
|
24
|
+
/** @type {Record<string, FooterVisibilityModel>} Map of UI variant name → FooterVisibilityModel */ this.ui
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* FooterVisibilityModel — OLMUI Model-as-Schema
|
|
5
|
+
* Boolean flags controlling which footer elements are visible.
|
|
6
|
+
*/
|
|
7
|
+
export class FooterVisibilityModel extends Model {
|
|
8
|
+
static $id = '@nan0web/ui/FooterVisibilityModel'
|
|
9
|
+
|
|
10
|
+
static copyright = {
|
|
11
|
+
help: 'Show copyright text',
|
|
12
|
+
default: true,
|
|
13
|
+
type: 'boolean',
|
|
14
|
+
}
|
|
15
|
+
static version = {
|
|
16
|
+
help: 'Show version string',
|
|
17
|
+
default: true,
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
}
|
|
20
|
+
static license = {
|
|
21
|
+
help: 'Show license info',
|
|
22
|
+
default: false,
|
|
23
|
+
type: 'boolean',
|
|
24
|
+
}
|
|
25
|
+
static nav = {
|
|
26
|
+
help: 'Show footer navigation',
|
|
27
|
+
default: true,
|
|
28
|
+
type: 'boolean',
|
|
29
|
+
}
|
|
30
|
+
static clock = {
|
|
31
|
+
help: 'Show clock widget',
|
|
32
|
+
default: false,
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {Partial<FooterVisibilityModel> | Record<string, any>} data Model input data.
|
|
38
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
39
|
+
*/
|
|
40
|
+
constructor(data = {}, options = {}) {
|
|
41
|
+
super(data, options)
|
|
42
|
+
/** @type {boolean} Show copyright text */ this.copyright
|
|
43
|
+
/** @type {boolean} Show version string */ this.version
|
|
44
|
+
/** @type {boolean} Show license info */ this.license
|
|
45
|
+
/** @type {boolean} Show footer navigation */ this.nav
|
|
46
|
+
/** @type {boolean} Show clock widget */ this.clock
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GalleryModel — OLMUI Model-as-Schema
|
|
5
|
+
* Image gallery / media grid with optional captions.
|
|
6
|
+
*/
|
|
7
|
+
export class GalleryModel extends Model {
|
|
8
|
+
static $id = '@nan0web/ui/GalleryModel'
|
|
9
|
+
|
|
10
|
+
static title = {
|
|
11
|
+
help: 'Gallery section title',
|
|
12
|
+
placeholder: 'Photo Gallery',
|
|
13
|
+
default: '',
|
|
14
|
+
}
|
|
15
|
+
static items = {
|
|
16
|
+
help: 'Gallery items (image URL + caption + alt)',
|
|
17
|
+
type: 'object[]',
|
|
18
|
+
default: [],
|
|
19
|
+
}
|
|
20
|
+
static columns = {
|
|
21
|
+
help: 'Number of columns in grid layout',
|
|
22
|
+
default: 3,
|
|
23
|
+
type: 'number',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {Partial<GalleryModel> | Record<string, any>} data Model input data.
|
|
28
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
29
|
+
*/
|
|
30
|
+
constructor(data = {}, options = {}) {
|
|
31
|
+
super(data, options)
|
|
32
|
+
/** @type {string} Gallery section title */ this.title
|
|
33
|
+
/** @type {Array<{src: string, caption?: string, alt?: string}>} Gallery items */ this.items
|
|
34
|
+
/** @type {number} Number of columns in grid layout */ this.columns
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
|
+
import { HeaderVisibilityModel } from './HeaderVisibilityModel.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HeaderConfigModel — OLMUI Model-as-Schema
|
|
6
|
+
* Configuration container mapping UI variant keys to HeaderVisibilityModel instances.
|
|
7
|
+
*/
|
|
8
|
+
export class HeaderConfigModel extends Model {
|
|
9
|
+
static $id = '@nan0web/ui/HeaderConfigModel'
|
|
10
|
+
|
|
11
|
+
static ui = {
|
|
12
|
+
help: 'Map of UI variant name → HeaderVisibilityModel',
|
|
13
|
+
type: 'Record<string, HeaderVisibilityModel>',
|
|
14
|
+
hint: HeaderVisibilityModel,
|
|
15
|
+
default: {},
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {Partial<HeaderConfigModel> | Record<string, any>} data Model input data.
|
|
20
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
21
|
+
*/
|
|
22
|
+
constructor(data = {}, options = {}) {
|
|
23
|
+
super(data, options)
|
|
24
|
+
/** @type {Record<string, HeaderVisibilityModel>} Map of UI variant name → HeaderVisibilityModel */ this.ui
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* HeaderVisibilityModel — OLMUI Model-as-Schema
|
|
5
|
+
* Boolean flags controlling which header elements are visible.
|
|
6
|
+
*/
|
|
7
|
+
export class HeaderVisibilityModel extends Model {
|
|
8
|
+
static $id = '@nan0web/ui/HeaderVisibilityModel'
|
|
9
|
+
|
|
10
|
+
static logo = {
|
|
11
|
+
help: 'Show logo',
|
|
12
|
+
default: true,
|
|
13
|
+
type: 'boolean',
|
|
14
|
+
}
|
|
15
|
+
static theme = {
|
|
16
|
+
help: 'Show theme toggle (dark/light)',
|
|
17
|
+
default: true,
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
}
|
|
20
|
+
static search = {
|
|
21
|
+
help: 'Show search input',
|
|
22
|
+
default: false,
|
|
23
|
+
type: 'boolean',
|
|
24
|
+
}
|
|
25
|
+
static share = {
|
|
26
|
+
help: 'Show share button',
|
|
27
|
+
default: false,
|
|
28
|
+
type: 'boolean',
|
|
29
|
+
}
|
|
30
|
+
static nav = {
|
|
31
|
+
help: 'Show navigation links',
|
|
32
|
+
default: true,
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
}
|
|
35
|
+
static langs = {
|
|
36
|
+
help: 'Show language switcher',
|
|
37
|
+
default: true,
|
|
38
|
+
type: 'boolean',
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {Partial<HeaderVisibilityModel> | Record<string, any>} data Model input data.
|
|
43
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
44
|
+
*/
|
|
45
|
+
constructor(data = {}, options = {}) {
|
|
46
|
+
super(data, options)
|
|
47
|
+
/** @type {boolean} Show logo */ this.logo
|
|
48
|
+
/** @type {boolean} Show theme toggle (dark/light) */ this.theme
|
|
49
|
+
/** @type {boolean} Show search input */ this.search
|
|
50
|
+
/** @type {boolean} Show share button */ this.share
|
|
51
|
+
/** @type {boolean} Show navigation links */ this.nav
|
|
52
|
+
/** @type {boolean} Show language switcher */ this.langs
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,30 +1,9 @@
|
|
|
1
|
-
import { Model } from '@nan0web/
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {'text'|'email'|'password'|'number'|'tel'|'url'|'date'} InputType
|
|
5
|
-
* @typedef {Object} InputData
|
|
6
|
-
* @property {InputType} [type]
|
|
7
|
-
* @property {string} [label]
|
|
8
|
-
* @property {string} [placeholder]
|
|
9
|
-
* @property {boolean} [required]
|
|
10
|
-
* @property {string} [pattern]
|
|
11
|
-
* @property {string} [min]
|
|
12
|
-
* @property {string} [max]
|
|
13
|
-
* @property {string} [step]
|
|
14
|
-
* @property {string} [hint]
|
|
15
|
-
* @property {boolean} [disabled]
|
|
16
|
-
* @property {string} [content]
|
|
17
|
-
*/
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
18
2
|
|
|
19
3
|
/**
|
|
20
4
|
* Model-as-Schema for Input component.
|
|
21
|
-
* Used exclusively for schema definition, validation, and editor reflection.
|
|
22
5
|
*/
|
|
23
6
|
export class InputModel extends Model {
|
|
24
|
-
// ==========================================
|
|
25
|
-
// 1. MODEL AS SCHEMA (Static Definition)
|
|
26
|
-
// ==========================================
|
|
27
|
-
|
|
28
7
|
static type = {
|
|
29
8
|
help: 'HTML5 Input type attribute',
|
|
30
9
|
default: 'text',
|
|
@@ -92,27 +71,27 @@ export class InputModel extends Model {
|
|
|
92
71
|
}
|
|
93
72
|
|
|
94
73
|
/**
|
|
95
|
-
* @param {
|
|
74
|
+
* @param {Partial<InputModel> | Record<string, any>} data Model input data.
|
|
75
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
96
76
|
*/
|
|
97
|
-
constructor(data = {}) {
|
|
98
|
-
super(data)
|
|
99
|
-
/** @type {
|
|
100
|
-
/** @type {string
|
|
101
|
-
/** @type {string
|
|
102
|
-
/** @type {boolean
|
|
103
|
-
/** @type {string
|
|
104
|
-
/** @type {string
|
|
105
|
-
/** @type {string
|
|
106
|
-
/** @type {string
|
|
107
|
-
/** @type {string
|
|
108
|
-
/** @type {boolean
|
|
109
|
-
/** @type {string
|
|
77
|
+
constructor(data = {}, options = {}) {
|
|
78
|
+
super(data, options)
|
|
79
|
+
/** @type {string} HTML5 Input type attribute */ this.type
|
|
80
|
+
/** @type {string} Label displayed above the input */ this.label
|
|
81
|
+
/** @type {string} Placeholder text shown when empty */ this.placeholder
|
|
82
|
+
/** @type {boolean} Whether the field must be filled out */ this.required
|
|
83
|
+
/** @type {string} RegExp pattern for validation */ this.pattern
|
|
84
|
+
/** @type {string} Minimum value */ this.min
|
|
85
|
+
/** @type {string} Maximum value */ this.max
|
|
86
|
+
/** @type {string} Step interval */ this.step
|
|
87
|
+
/** @type {string} Helper text displayed below the input */ this.hint
|
|
88
|
+
/** @type {boolean} Whether the input is disabled */ this.disabled
|
|
89
|
+
/** @type {string} The actual value of the input */ this.content
|
|
110
90
|
}
|
|
111
91
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
92
|
+
/**
|
|
93
|
+
* @returns {AsyncGenerator<any, any, any>}
|
|
94
|
+
*/
|
|
116
95
|
async *run() {
|
|
117
96
|
const response = yield {
|
|
118
97
|
type: 'ask',
|
|
@@ -127,13 +106,14 @@ export class InputModel extends Model {
|
|
|
127
106
|
if (!re.test(val)) return 'Invalid format'
|
|
128
107
|
} catch (e) {
|
|
129
108
|
// fallback if pattern is malformed
|
|
109
|
+
return 'Invalid format'
|
|
130
110
|
}
|
|
131
111
|
}
|
|
132
112
|
return true
|
|
133
113
|
},
|
|
134
114
|
},
|
|
135
115
|
component: 'Input',
|
|
136
|
-
model:
|
|
116
|
+
model: this,
|
|
137
117
|
}
|
|
138
118
|
|
|
139
119
|
this.content = response.value
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Model } from '@nan0web/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PriceModel — OLMUI Model-as-Schema
|
|
5
|
+
* Represents a monetary value with currency.
|
|
6
|
+
*/
|
|
7
|
+
export class PriceModel extends Model {
|
|
8
|
+
static $id = '@nan0web/ui/PriceModel'
|
|
9
|
+
|
|
10
|
+
static value = {
|
|
11
|
+
help: 'Numeric price value',
|
|
12
|
+
default: 0,
|
|
13
|
+
type: 'number',
|
|
14
|
+
}
|
|
15
|
+
static currency = {
|
|
16
|
+
help: 'Currency code (ISO 4217)',
|
|
17
|
+
placeholder: 'USD',
|
|
18
|
+
default: 'USD',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {Partial<PriceModel> | Record<string, any>} data Model input data.
|
|
23
|
+
* @param {object} [options] Extended options (db, etc.)
|
|
24
|
+
*/
|
|
25
|
+
constructor(data = {}, options = {}) {
|
|
26
|
+
super(data, options)
|
|
27
|
+
/** @type {number} Numeric price value */ this.value
|
|
28
|
+
/** @type {string} Currency code (ISO 4217) */ this.currency
|
|
29
|
+
}
|
|
30
|
+
}
|