@nan0web/ui 1.12.2 → 3.1.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 +18 -355
- package/package.json +36 -22
- package/src/Component/index.js +1 -5
- package/src/Model/Element.js +183 -0
- package/src/Model/index.js +2 -2
- package/src/Theme/AppTheme.js +19 -0
- package/src/Theme/CustomTheme.js +32 -0
- package/src/Theme/DarkLightTheme.js +34 -0
- package/src/Theme/Theme.js +25 -0
- package/src/Theme/atoms/Avatar.js +20 -0
- package/src/Theme/atoms/Badge.js +28 -0
- package/src/Theme/atoms/Button.js +88 -0
- package/src/Theme/atoms/Checkbox.js +26 -0
- package/src/Theme/atoms/Input.js +28 -0
- package/src/Theme/atoms/Radio.js +26 -0
- package/src/Theme/atoms/Select.js +16 -0
- package/src/Theme/atoms/TextArea.js +17 -0
- package/src/Theme/atoms/Typography.js +26 -0
- package/src/Theme/atoms/index.js +11 -0
- package/src/Theme/createTheme.js +22 -0
- package/src/Theme/index.js +20 -0
- package/src/Theme/molecules/Card.js +24 -0
- package/src/Theme/molecules/index.js +3 -0
- package/src/Theme/organisms/Modal.js +24 -0
- package/src/Theme/organisms/index.js +3 -0
- package/src/Theme/presets/HighContrastTheme.js +65 -0
- package/src/Theme/presets/NightTheme.js +66 -0
- package/src/Theme/presets/index.js +4 -0
- package/src/Theme/tokens.js +115 -0
- package/src/core/InputAdapter.js +1 -2
- package/src/core/Intent.js +22 -8
- package/src/core/Message/Message.js +3 -0
- package/src/core/OutputAdapter.js +9 -13
- package/src/core/index.js +7 -4
- package/src/core/resolvePositionalArgs.js +51 -0
- package/src/domain/Content.js +5 -5
- package/src/domain/Document.js +1 -1
- package/src/domain/HeroModel.js +1 -1
- package/src/domain/ModelAsApp.js +310 -20
- package/src/domain/ModelAsApp.story.js +117 -0
- package/src/domain/app/GalleryCommand.js +9 -8
- package/src/domain/app/{GalleryRenderIntent.js → GalleryRenderCommand.js} +20 -20
- package/src/domain/app/IntentAuditor.js +53 -0
- package/src/domain/app/JsIntentAuditor.js +145 -0
- package/src/domain/app/PyIntentAuditor.js +144 -0
- package/src/domain/app/SnapshotAuditor.js +82 -86
- package/src/domain/app/SnapshotRunner.js +1 -1
- package/src/domain/app/UIApp.js +12 -21
- package/src/domain/components/ShellModel.js +2 -2
- package/src/index.js +38 -10
- package/src/inspect.js +4 -0
- package/src/testing/SnapshotRunner.js +2 -1
- package/src/utils/format.js +21 -0
- package/src/utils/processI18n.js +27 -0
- package/src/utils/resolveContext.js +79 -0
- package/types/Component/index.d.ts +1 -5
- package/types/Model/Element.d.ts +87 -0
- package/types/Model/index.d.ts +2 -2
- package/types/Theme/AppTheme.d.ts +14 -0
- package/types/Theme/CustomTheme.d.ts +21 -0
- package/types/Theme/DarkLightTheme.d.ts +16 -0
- package/types/Theme/Theme.d.ts +18 -0
- package/types/Theme/atoms/Avatar.d.ts +14 -0
- package/types/Theme/atoms/Badge.d.ts +22 -0
- package/types/Theme/atoms/Button.d.ts +144 -0
- package/types/Theme/atoms/Checkbox.d.ts +20 -0
- package/types/Theme/atoms/Input.d.ts +22 -0
- package/types/Theme/atoms/Radio.d.ts +20 -0
- package/types/Theme/atoms/Select.d.ts +15 -0
- package/types/Theme/atoms/TextArea.d.ts +17 -0
- package/types/Theme/atoms/Typography.d.ts +47 -0
- package/types/Theme/atoms/index.d.ts +10 -0
- package/types/Theme/createTheme.d.ts +7 -0
- package/types/Theme/index.d.ts +10 -0
- package/types/Theme/molecules/Card.d.ts +18 -0
- package/types/Theme/molecules/index.d.ts +2 -0
- package/types/Theme/organisms/Modal.d.ts +18 -0
- package/types/Theme/organisms/index.d.ts +2 -0
- package/types/Theme/presets/HighContrastTheme.d.ts +2 -0
- package/types/Theme/presets/NightTheme.d.ts +2 -0
- package/types/Theme/presets/index.d.ts +3 -0
- package/types/Theme/tokens.d.ts +119 -0
- package/types/core/Intent.d.ts +10 -7
- package/types/core/Message/Message.d.ts +3 -0
- package/types/core/OutputAdapter.d.ts +2 -4
- package/types/core/index.d.ts +5 -2
- package/types/core/resolvePositionalArgs.d.ts +24 -0
- package/types/docs/README.md.d.ts +1 -0
- package/types/domain/Content.d.ts +2 -2
- package/types/domain/Document.d.ts +4 -3
- package/types/domain/FooterModel.d.ts +2 -1
- package/types/domain/HeroModel.d.ts +2 -2
- package/types/domain/ModelAsApp.d.ts +49 -5
- package/types/domain/ModelAsApp.story.d.ts +1 -0
- package/types/domain/app/GalleryCommand.d.ts +6 -37
- package/types/domain/app/GalleryRenderCommand.d.ts +27 -0
- package/types/domain/app/IntentAuditor.d.ts +23 -0
- package/types/domain/app/JsIntentAuditor.d.ts +22 -0
- package/types/domain/app/PyIntentAuditor.d.ts +22 -0
- package/types/domain/app/SnapshotAuditor.d.ts +34 -25
- package/types/domain/app/SnapshotRunner.d.ts +2 -2
- package/types/domain/app/UIApp.d.ts +14 -11
- package/types/domain/components/ShellModel.d.ts +1 -5
- package/types/index.d.ts +10 -10
- package/types/inspect.d.ts +4 -0
- package/types/testing/verifySnapshot.d.ts +1 -1
- package/types/utils/format.d.ts +5 -0
- package/types/utils/processI18n.d.ts +8 -0
- package/types/utils/resolveContext.d.ts +21 -0
- package/src/App/Command/DepsCommand.js +0 -24
- package/src/App/Core/CoreApp.js +0 -125
- package/src/App/Core/UI.js +0 -63
- package/src/App/Core/Widget.js +0 -61
- package/src/App/Core/index.js +0 -11
- package/src/App/Scenario.js +0 -45
- package/src/App/User/Command/Message.js +0 -3
- package/src/App/User/Command/index.js +0 -5
- package/src/App/User/UserApp.js +0 -85
- package/src/App/User/UserUI.js +0 -20
- package/src/App/User/index.js +0 -9
- package/src/App/index.js +0 -14
- package/src/Component/Process/Input.js +0 -63
- package/src/Component/Process/Process.js +0 -24
- package/src/Component/Process/index.js +0 -5
- package/src/Component/Welcome/Input.js +0 -48
- package/src/Component/Welcome/Welcome.js +0 -22
- package/src/Component/Welcome/index.js +0 -5
- package/src/Frame/Frame.js +0 -608
- package/src/Frame/Props.js +0 -96
- package/src/StdIn.js +0 -100
- package/src/StdOut.js +0 -95
- package/src/View/RenderOptions.js +0 -48
- package/src/View/View.js +0 -306
- package/src/core/Message/index.js +0 -6
- package/types/App/Command/DepsCommand.d.ts +0 -14
- package/types/App/Core/CoreApp.d.ts +0 -70
- package/types/App/Core/UI.d.ts +0 -38
- package/types/App/Core/Widget.d.ts +0 -39
- package/types/App/Core/index.d.ts +0 -10
- package/types/App/Scenario.d.ts +0 -26
- package/types/App/User/Command/Message.d.ts +0 -2
- package/types/App/User/Command/index.d.ts +0 -3
- package/types/App/User/UserApp.d.ts +0 -41
- package/types/App/User/UserUI.d.ts +0 -9
- package/types/App/User/index.d.ts +0 -8
- package/types/App/index.d.ts +0 -12
- package/types/Component/Process/Input.d.ts +0 -48
- package/types/Component/Process/Process.d.ts +0 -13
- package/types/Component/Process/index.d.ts +0 -4
- package/types/Component/Welcome/Input.d.ts +0 -34
- package/types/Component/Welcome/Welcome.d.ts +0 -13
- package/types/Component/Welcome/index.d.ts +0 -4
- package/types/Frame/Frame.d.ts +0 -186
- package/types/Frame/Props.d.ts +0 -77
- package/types/StdIn.d.ts +0 -62
- package/types/StdOut.d.ts +0 -52
- package/types/View/RenderOptions.d.ts +0 -29
- package/types/View/View.d.ts +0 -124
- package/types/core/Message/index.d.ts +0 -4
- package/types/domain/app/GalleryRenderIntent.d.ts +0 -31
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { tokens } from '../tokens.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Theme definition for Modal organism.
|
|
5
|
+
*
|
|
6
|
+
* @typedef {Object} ModalTheme
|
|
7
|
+
* @property {string} overlayBackground
|
|
8
|
+
* @property {string} borderRadius
|
|
9
|
+
* @property {string} boxShadow
|
|
10
|
+
* @property {string} padding
|
|
11
|
+
* @property {string} backgroundColor
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Modal organism theme.
|
|
16
|
+
* @type {ModalTheme}
|
|
17
|
+
*/
|
|
18
|
+
export default {
|
|
19
|
+
overlayBackground: 'rgba(0, 0, 0, 0.5)',
|
|
20
|
+
borderRadius: tokens.radius.lg,
|
|
21
|
+
boxShadow: tokens.shadow.lg,
|
|
22
|
+
padding: tokens.space.xl,
|
|
23
|
+
backgroundColor: tokens.color.background,
|
|
24
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createTheme } from '../createTheme.js'
|
|
2
|
+
import { tokens } from '../tokens.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* High contrast theme preset.
|
|
6
|
+
* Designed for maximum readability by increasing contrast between text and background.
|
|
7
|
+
*/
|
|
8
|
+
export default createTheme({
|
|
9
|
+
atoms: {
|
|
10
|
+
Button: {
|
|
11
|
+
fontFamily: tokens.font.family,
|
|
12
|
+
color: tokens.color.text,
|
|
13
|
+
background: tokens.color.primary,
|
|
14
|
+
shadow: tokens.shadow.sm,
|
|
15
|
+
hoverBackground: 'color-mix(in srgb, var(--color-primary) 80%, black)',
|
|
16
|
+
borderColor: tokens.border.color.default,
|
|
17
|
+
borderRadius: tokens.radius.sm,
|
|
18
|
+
borderWidth: tokens.border.width.sm,
|
|
19
|
+
fontSize: tokens.font.size.base,
|
|
20
|
+
paddingX: tokens.space.lg,
|
|
21
|
+
paddingY: tokens.space.md,
|
|
22
|
+
solid: {
|
|
23
|
+
primary: { background: '#000000', color: '#ffffff', border: '#000000' },
|
|
24
|
+
secondary: { background: '#333333', color: '#ffffff', border: '#333333' },
|
|
25
|
+
success: { background: '#006600', color: '#ffffff', border: '#006600' },
|
|
26
|
+
warning: { background: '#996600', color: '#000000', border: '#996600' },
|
|
27
|
+
danger: { background: '#990000', color: '#ffffff', border: '#990000' },
|
|
28
|
+
info: { background: '#006699', color: '#ffffff', border: '#006699' },
|
|
29
|
+
light: { background: '#dddddd', color: '#000000', border: '#dddddd' },
|
|
30
|
+
dark: { background: '#222222', color: '#ffffff', border: '#222222' },
|
|
31
|
+
link: { background: 'transparent', color: '#000099', border: 'transparent' },
|
|
32
|
+
},
|
|
33
|
+
outline: {
|
|
34
|
+
primary: { background: '#ffffff', color: '#000000', border: '#000000' },
|
|
35
|
+
secondary: { background: '#ffffff', color: '#333333', border: '#333333' },
|
|
36
|
+
success: { background: '#ffffff', color: '#006600', border: '#006600' },
|
|
37
|
+
warning: { background: '#ffffff', color: '#996600', border: '#996600' },
|
|
38
|
+
danger: { background: '#ffffff', color: '#990000', border: '#990000' },
|
|
39
|
+
info: { background: '#ffffff', color: '#006699', border: '#006699' },
|
|
40
|
+
light: { background: '#ffffff', color: '#000000', border: '#000000' },
|
|
41
|
+
dark: { background: '#ffffff', color: '#222222', border: '#222222' },
|
|
42
|
+
},
|
|
43
|
+
size: {
|
|
44
|
+
sm: {
|
|
45
|
+
fontSize: '0.875rem',
|
|
46
|
+
paddingX: '0.5rem',
|
|
47
|
+
paddingY: '0.25rem',
|
|
48
|
+
},
|
|
49
|
+
md: {
|
|
50
|
+
fontSize: '1rem',
|
|
51
|
+
paddingX: '1rem',
|
|
52
|
+
paddingY: '0.5rem',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
animation: {
|
|
56
|
+
transition: 'background 0.15s ease, transform 0.1s ease',
|
|
57
|
+
hoverAdjust: 20,
|
|
58
|
+
activeAdjust: -30,
|
|
59
|
+
focusScale: 1.02,
|
|
60
|
+
activeScale: 0.98,
|
|
61
|
+
disabledOpacity: 0.65,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { createTheme } from '../createTheme.js'
|
|
2
|
+
import { tokens } from '../tokens.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Night (dark) theme preset.
|
|
6
|
+
* Optimized for low-light environments with deep background colors and vibrant text.
|
|
7
|
+
* Overrides solid button styles while keeping contrast high.
|
|
8
|
+
*/
|
|
9
|
+
export default createTheme({
|
|
10
|
+
atoms: {
|
|
11
|
+
Button: {
|
|
12
|
+
fontFamily: tokens.font.family,
|
|
13
|
+
color: tokens.color.text,
|
|
14
|
+
background: tokens.color.primary,
|
|
15
|
+
shadow: tokens.shadow.sm,
|
|
16
|
+
hoverBackground: 'color-mix(in srgb, var(--color-primary) 80%, black)',
|
|
17
|
+
borderColor: tokens.border.color.default,
|
|
18
|
+
borderRadius: tokens.radius.sm,
|
|
19
|
+
borderWidth: tokens.border.width.sm,
|
|
20
|
+
fontSize: tokens.font.size.base,
|
|
21
|
+
paddingX: tokens.space.lg,
|
|
22
|
+
paddingY: tokens.space.md,
|
|
23
|
+
solid: {
|
|
24
|
+
primary: { background: '#0d6efd', color: '#ffffff', border: '#0d6efd' },
|
|
25
|
+
secondary: { background: '#6c757d', color: '#ffffff', border: '#6c757d' },
|
|
26
|
+
success: { background: '#198754', color: '#ffffff', border: '#198754' },
|
|
27
|
+
warning: { background: '#ffc107', color: '#000000', border: '#ffc107' },
|
|
28
|
+
danger: { background: '#dc3545', color: '#ffffff', border: '#dc3545' },
|
|
29
|
+
info: { background: '#0dcaf0', color: '#000000', border: '#0dcaf0' },
|
|
30
|
+
light: { background: '#aaaaaa', color: '#000000', border: '#aaaaaa' },
|
|
31
|
+
dark: { background: '#212529', color: '#ffffff', border: '#212529' },
|
|
32
|
+
link: { background: 'transparent', color: '#6ea8fe', border: 'transparent' },
|
|
33
|
+
},
|
|
34
|
+
outline: {
|
|
35
|
+
primary: { background: 'transparent', color: '#0d6efd', border: '#0d6efd' },
|
|
36
|
+
secondary: { background: 'transparent', color: '#6c757d', border: '#6c757d' },
|
|
37
|
+
success: { background: 'transparent', color: '#198754', border: '#198754' },
|
|
38
|
+
warning: { background: 'transparent', color: '#ffc107', border: '#ffc107' },
|
|
39
|
+
danger: { background: 'transparent', color: '#dc3545', border: '#dc3545' },
|
|
40
|
+
info: { background: 'transparent', color: '#0dcaf0', border: '#0dcaf0' },
|
|
41
|
+
light: { background: 'transparent', color: '#aaaaaa', border: '#aaaaaa' },
|
|
42
|
+
dark: { background: 'transparent', color: '#212529', border: '#212529' },
|
|
43
|
+
},
|
|
44
|
+
size: {
|
|
45
|
+
sm: {
|
|
46
|
+
fontSize: '0.875rem',
|
|
47
|
+
paddingX: '0.5rem',
|
|
48
|
+
paddingY: '0.25rem',
|
|
49
|
+
},
|
|
50
|
+
md: {
|
|
51
|
+
fontSize: '1rem',
|
|
52
|
+
paddingX: '1rem',
|
|
53
|
+
paddingY: '0.5rem',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
animation: {
|
|
57
|
+
transition: 'background 0.15s ease, transform 0.1s ease',
|
|
58
|
+
hoverAdjust: 20,
|
|
59
|
+
activeAdjust: -30,
|
|
60
|
+
focusScale: 1.02,
|
|
61
|
+
activeScale: 0.98,
|
|
62
|
+
disabledOpacity: 0.65,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
})
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// src/tokens.js
|
|
2
|
+
export const tokens = {
|
|
3
|
+
// Spacing
|
|
4
|
+
space: {
|
|
5
|
+
xs: '0.25rem',
|
|
6
|
+
sm: '0.5rem',
|
|
7
|
+
md: '0.75rem',
|
|
8
|
+
lg: '1rem',
|
|
9
|
+
xl: '1.5rem',
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
// Radius
|
|
13
|
+
radius: {
|
|
14
|
+
none: '0',
|
|
15
|
+
sm: '0.125rem',
|
|
16
|
+
md: '0.25rem',
|
|
17
|
+
lg: '0.5rem',
|
|
18
|
+
full: '9999px',
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
// Border
|
|
22
|
+
border: {
|
|
23
|
+
width: {
|
|
24
|
+
sm: '1px',
|
|
25
|
+
md: '2px',
|
|
26
|
+
},
|
|
27
|
+
color: {
|
|
28
|
+
default: 'var(--color-border)',
|
|
29
|
+
muted: 'var(--color-border-muted)',
|
|
30
|
+
error: 'var(--color-error)',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
// Color
|
|
35
|
+
color: {
|
|
36
|
+
text: 'var(--color-text)',
|
|
37
|
+
background: 'var(--color-background)',
|
|
38
|
+
primary: 'var(--color-primary)',
|
|
39
|
+
success: 'var(--color-success)',
|
|
40
|
+
warning: 'var(--color-warning)',
|
|
41
|
+
error: 'var(--color-error)',
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
// Typography
|
|
45
|
+
font: {
|
|
46
|
+
family: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
47
|
+
size: {
|
|
48
|
+
xs: '0.75rem',
|
|
49
|
+
sm: '0.875rem',
|
|
50
|
+
base: '1rem',
|
|
51
|
+
lg: '1.125rem',
|
|
52
|
+
xl: '1.25rem',
|
|
53
|
+
},
|
|
54
|
+
weight: {
|
|
55
|
+
normal: '400',
|
|
56
|
+
medium: '500',
|
|
57
|
+
bold: '700',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// Shadows
|
|
62
|
+
shadow: {
|
|
63
|
+
sm: '0 1px 2px rgba(0,0,0,0.05)',
|
|
64
|
+
md: '0 4px 6px rgba(0,0,0,0.1)',
|
|
65
|
+
lg: '0 10px 25px rgba(0,0,0,0.15)',
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
// Breakpoints (Bootstrap 5)
|
|
69
|
+
breakpoint: {
|
|
70
|
+
xs: '0', // extra‑small
|
|
71
|
+
sm: '576px',
|
|
72
|
+
md: '768px',
|
|
73
|
+
lg: '992px',
|
|
74
|
+
xl: '1200px',
|
|
75
|
+
xxl: '1400px',
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
// Container max‑widths (Bootstrap 5)
|
|
79
|
+
container: {
|
|
80
|
+
sm: '540px',
|
|
81
|
+
md: '720px',
|
|
82
|
+
lg: '960px',
|
|
83
|
+
xl: '1140px',
|
|
84
|
+
xxl: '1320px',
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
// Z‑index scale (Bootstrap)
|
|
88
|
+
zIndex: {
|
|
89
|
+
dropdown: 1000,
|
|
90
|
+
sticky: 1020,
|
|
91
|
+
fixed: 1030,
|
|
92
|
+
modalBackdrop: 1040,
|
|
93
|
+
modal: 1050,
|
|
94
|
+
popover: 1060,
|
|
95
|
+
tooltip: 1070,
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
// Opacity scale
|
|
99
|
+
opacity: {
|
|
100
|
+
0: '0',
|
|
101
|
+
10: '0.1',
|
|
102
|
+
25: '0.25',
|
|
103
|
+
50: '0.5',
|
|
104
|
+
75: '0.75',
|
|
105
|
+
90: '0.9',
|
|
106
|
+
100: '1',
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
// Transition durations
|
|
110
|
+
transition: {
|
|
111
|
+
fast: '150ms',
|
|
112
|
+
medium: '300ms',
|
|
113
|
+
slow: '500ms',
|
|
114
|
+
},
|
|
115
|
+
}
|
package/src/core/InputAdapter.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import Event from '@nan0web/event/oop'
|
|
2
2
|
import CancelError from './Error/CancelError.js'
|
|
3
|
-
import UiMessage from './Message/Message.js'
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* @typedef {Object} AskOptions
|
|
@@ -32,7 +31,7 @@ export class InputAdapter extends Event {
|
|
|
32
31
|
* @returns {void}
|
|
33
32
|
*/
|
|
34
33
|
start() {
|
|
35
|
-
this.emit('input',
|
|
34
|
+
this.emit('input', { body: 'Adapter started' })
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
/**
|
package/src/core/Intent.js
CHANGED
|
@@ -48,7 +48,7 @@ import { IntentErrorModel } from './IntentErrorModel.js'
|
|
|
48
48
|
* @typedef {'info' | 'warn' | 'error' | 'success'} ShowLevel
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
|
-
/** @typedef {ShowLevel} LogLevel */
|
|
51
|
+
/** @typedef {ShowLevel | 'debug'} LogLevel */
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* Model emits a show message. No response expected.
|
|
@@ -168,7 +168,14 @@ import { IntentErrorModel } from './IntentErrorModel.js'
|
|
|
168
168
|
* @typedef {'ask' | 'show' | 'progress' | 'render' | 'agent'} IntentType
|
|
169
169
|
*/
|
|
170
170
|
|
|
171
|
-
export const INTENT_TYPES = /** @type {const} */ ([
|
|
171
|
+
export const INTENT_TYPES = /** @type {const} */ ([
|
|
172
|
+
'ask',
|
|
173
|
+
'progress',
|
|
174
|
+
'show',
|
|
175
|
+
'log',
|
|
176
|
+
'render',
|
|
177
|
+
'agent',
|
|
178
|
+
])
|
|
172
179
|
|
|
173
180
|
/**
|
|
174
181
|
* Detects if a value is a Model-as-Schema class (has static fields with `help`).
|
|
@@ -286,16 +293,23 @@ export function progress(message, value = 0, optionsOrTotalOrId, id) {
|
|
|
286
293
|
}
|
|
287
294
|
}
|
|
288
295
|
|
|
289
|
-
return {
|
|
290
|
-
type: 'progress',
|
|
291
|
-
message,
|
|
292
|
-
value,
|
|
296
|
+
return {
|
|
297
|
+
type: 'progress',
|
|
298
|
+
message,
|
|
299
|
+
value,
|
|
293
300
|
total: options.total,
|
|
294
|
-
id: options.id || 'default',
|
|
295
|
-
options
|
|
301
|
+
id: options.id || 'default',
|
|
302
|
+
options,
|
|
296
303
|
}
|
|
297
304
|
}
|
|
298
305
|
|
|
306
|
+
/**
|
|
307
|
+
* Lgs a message if level is greater or equal the current view level.
|
|
308
|
+
* @param {LogLevel} level
|
|
309
|
+
* @param {string} message
|
|
310
|
+
* @param {object} [data={}]
|
|
311
|
+
* @returns {LogIntent}
|
|
312
|
+
*/
|
|
299
313
|
export function log(level, message, data = {}) {
|
|
300
314
|
return { type: 'log', level, message, ...data }
|
|
301
315
|
}
|
|
@@ -17,6 +17,9 @@ import { Message } from '@nan0web/co'
|
|
|
17
17
|
*
|
|
18
18
|
* @class UiMessage
|
|
19
19
|
* @extends Message
|
|
20
|
+
* @property {Record<string, any>} head - Message head.
|
|
21
|
+
* @property {boolean} isValid - True if message is valid.
|
|
22
|
+
* @property {Date} time - Creation timestamp.
|
|
20
23
|
*
|
|
21
24
|
* @example
|
|
22
25
|
* class UserLoginMessage extends UiMessage {
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import Event from '@nan0web/event/oop'
|
|
2
|
-
import OutputMessage from './Message/OutputMessage.js'
|
|
3
|
-
import FormMessage from './Form/Message.js'
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* Abstract output adapter for UI implementations.
|
|
@@ -12,7 +10,7 @@ class OutputAdapter extends Event {
|
|
|
12
10
|
/**
|
|
13
11
|
* Renders a message to the user.
|
|
14
12
|
*
|
|
15
|
-
* @param {
|
|
13
|
+
* @param {object} message - Message to render.
|
|
16
14
|
* @throws {Error} If not overridden by a subclass.
|
|
17
15
|
*/
|
|
18
16
|
render(message) {
|
|
@@ -27,16 +25,14 @@ class OutputAdapter extends Event {
|
|
|
27
25
|
* @returns {void}
|
|
28
26
|
*/
|
|
29
27
|
progress(progress, metadata = {}) {
|
|
30
|
-
this.render(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
metadata
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}),
|
|
39
|
-
)
|
|
28
|
+
this.render({
|
|
29
|
+
content: [],
|
|
30
|
+
metadata: {
|
|
31
|
+
...metadata,
|
|
32
|
+
progress,
|
|
33
|
+
elementType: 'progress',
|
|
34
|
+
},
|
|
35
|
+
})
|
|
40
36
|
}
|
|
41
37
|
|
|
42
38
|
/**
|
package/src/core/index.js
CHANGED
|
@@ -6,16 +6,16 @@ export { UIStream, UIStream as UiStream }
|
|
|
6
6
|
import StreamEntry from './StreamEntry.js'
|
|
7
7
|
export { StreamEntry, StreamEntry as UiStreamEntry }
|
|
8
8
|
|
|
9
|
-
export { default as UiMessage } from './Message/Message.js'
|
|
10
|
-
export { default as FormMessage } from './Form/Message.js'
|
|
11
9
|
export { default as FormInput } from './Form/Input.js'
|
|
12
10
|
|
|
13
11
|
import UIForm from './Form/Form.js'
|
|
14
12
|
export { UIForm, UIForm as UiForm }
|
|
15
13
|
|
|
16
|
-
export { default as
|
|
14
|
+
export { default as UiMessage } from './Message/Message.js'
|
|
15
|
+
export { default as FormMessage } from './Form/Message.js'
|
|
16
|
+
export { default as OutputMessage } from './Message/OutputMessage.js'
|
|
17
17
|
|
|
18
|
-
export { default as
|
|
18
|
+
export { default as Error, CancelError } from './Error/index.js'
|
|
19
19
|
|
|
20
20
|
// Flow — Yield-Based Universal UI Architecture
|
|
21
21
|
export {
|
|
@@ -43,6 +43,9 @@ export { default as Flow } from './Flow.js'
|
|
|
43
43
|
// OLMUI Generator Engine — Intent-based Model→Adapter contract
|
|
44
44
|
export { validateIntent, ask, progress, log, render, result, INTENT_TYPES, isModelSchema } from './Intent.js'
|
|
45
45
|
/** @typedef {import('./Intent.js').Intent} Intent */
|
|
46
|
+
/** @typedef {import('./Intent.js').ShowLevel} ShowLevel */
|
|
47
|
+
/** @typedef {import('./Intent.js').ShowIntent} ShowIntent */
|
|
48
|
+
/** @typedef {import('./Intent.js').ShowData} ShowData */
|
|
46
49
|
/** @typedef {import('./Intent.js').AskResponse} AskResponse */
|
|
47
50
|
/** @typedef {import('./InputAdapter.js').AskOptions} AskOptions */
|
|
48
51
|
export { IntentErrorModel } from './IntentErrorModel.js'
|
|
@@ -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
|
+
}
|
package/src/domain/Content.js
CHANGED
|
@@ -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) {
|
package/src/domain/Document.js
CHANGED
|
@@ -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)
|
package/src/domain/HeroModel.js
CHANGED
|
@@ -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)
|