neo.mjs 5.15.5 → 5.16.1

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 (33) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/buildScripts/docs/jsdocx.mjs +8 -6
  3. package/docs/app/view/MainContainer.mjs +10 -0
  4. package/docs/app/view/classdetails/HeaderComponent.mjs +3 -3
  5. package/docs/app/view/classdetails/MainContainer.mjs +14 -4
  6. package/docs/app/view/classdetails/MembersList.mjs +5 -5
  7. package/examples/ServiceWorker.mjs +2 -2
  8. package/examples/form/field/fileupload/MainContainer.mjs +68 -10
  9. package/examples/form/field/fileupload/README.md +9 -0
  10. package/examples/form/field/fileupload/server.mjs +49 -0
  11. package/examples/form/field/switch/MainContainer.mjs +124 -0
  12. package/examples/form/field/switch/app.mjs +6 -0
  13. package/examples/form/field/switch/index.html +11 -0
  14. package/examples/form/field/switch/neo-config.json +6 -0
  15. package/package.json +2 -1
  16. package/resources/scss/src/apps/docs/HeaderContainer.scss +1 -1
  17. package/resources/scss/src/apps/docs/MainContainer.scss +5 -1
  18. package/resources/scss/src/apps/docs/classdetails/HeaderComponent.scss +2 -5
  19. package/resources/scss/src/apps/docs/classdetails/MainContainer.scss +1 -1
  20. package/resources/scss/src/component/Splitter.scss +3 -1
  21. package/resources/scss/src/form/field/FileUpload.scss +248 -2
  22. package/resources/scss/src/form/field/Switch.scss +85 -115
  23. package/resources/scss/src/tree/List.scss +2 -1
  24. package/resources/scss/theme-dark/form/field/FileUpload.scss +20 -4
  25. package/resources/scss/theme-dark/form/field/Switch.scss +10 -10
  26. package/resources/scss/theme-light/form/field/FileUpload.scss +20 -4
  27. package/resources/scss/theme-light/form/field/Switch.scss +10 -10
  28. package/src/DefaultConfig.mjs +2 -2
  29. package/src/component/Splitter.mjs +27 -22
  30. package/src/form/field/FileUpload.mjs +512 -4
  31. package/src/form/field/Switch.mjs +11 -11
  32. package/src/main/addon/Markdown.mjs +2 -2
  33. package/src/main/addon/ResizeObserver.mjs +79 -0
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.15.5'
23
+ * @member {String} version='5.16.1'
24
24
  */
25
- version: '5.15.5'
25
+ version: '5.16.1'
26
26
  }
27
27
 
28
28
  /**
@@ -1,9 +1,11 @@
1
- import fs from 'fs-extra';
2
- import helper from 'neo-jsdoc-x/src/lib/helper.js';
3
- import jsdocx from 'neo-jsdoc-x';
4
- import path from 'path';
1
+ import fs from 'fs-extra';
2
+ import helper from 'neo-jsdoc-x/src/lib/helper.js';
3
+ import jsdocx from 'neo-jsdoc-x';
4
+ import path from 'path';
5
+ import showdown from 'showdown';
5
6
 
6
7
  const __dirname = path.resolve(),
8
+ markdown = new showdown.Converter(),
7
9
  cwd = process.cwd(),
8
10
  requireJson = path => JSON.parse(fs.readFileSync((path))),
9
11
  packageJson = requireJson(path.resolve(cwd, 'package.json')),
@@ -324,12 +326,12 @@ jsdocx.parse(options)
324
326
  namespace.classData.push(item);
325
327
 
326
328
  if (item.description) {
327
- item.description = item.description.replace(/\n/g, "<br />");
329
+ item.description = markdown.makeHtml(item.description)
328
330
  }
329
331
 
330
332
  item.params?.forEach(param => {
331
333
  if (param.description) {
332
- param.description = param.description.replace(/\n/g, "<br />");
334
+ param.description = markdown.makeHtml(param.description)
333
335
  }
334
336
  });
335
337
 
@@ -6,6 +6,7 @@ import ExamplesTreeList from './ExamplesTreeList.mjs';
6
6
  import HeaderContainer from './HeaderContainer.mjs';
7
7
  import MainContainerController from './MainContainerController.mjs';
8
8
  import SourceViewComponent from './classdetails/SourceViewComponent.mjs';
9
+ import Splitter from '../../../src/component/Splitter.mjs';
9
10
  import TutorialComponent from './classdetails/TutorialComponent.mjs';
10
11
  import TutorialsTreeList from './TutorialsTreeList.mjs';
11
12
  import Viewport from '../../../src/container/Viewport.mjs';
@@ -85,6 +86,15 @@ class MainContainer extends Viewport {
85
86
  text : 'Examples'
86
87
  }
87
88
  }]
89
+ }, {
90
+ module : Splitter,
91
+ resizeTarget: 'previous',
92
+ size : 5,
93
+
94
+ style: {
95
+ borderTop: 'var(--tab-strip-height) solid var(--tab-strip-background-color)',
96
+ marginTop: 'var(--tab-button-height)'
97
+ }
88
98
  }, {
89
99
  module : ContentTabContainer,
90
100
  flex : 1,
@@ -38,9 +38,9 @@ class HeaderComponent extends Component {
38
38
  * @member {Object} _vdom
39
39
  */
40
40
  _vdom:
41
- {cn: [
42
- {tag: 'span', cls: ['neo-docs-header-text']}
43
- ]}
41
+ {cn: [
42
+ {tag: 'span', cls: ['neo-docs-header-text']}
43
+ ]}
44
44
  }
45
45
 
46
46
  /**
@@ -5,6 +5,7 @@ import MainContainerController from './MainContainerController.mjs';
5
5
  import MembersList from './MembersList.mjs';
6
6
  import Panel from '../../../../src/container/Panel.mjs';
7
7
  import SearchField from '../../../../src/form/field/Search.mjs';
8
+ import Splitter from '../../../../src/component/Splitter.mjs';
8
9
 
9
10
  /**
10
11
  * @class Docs.view.classdetails.MainContainer
@@ -42,10 +43,11 @@ class MainContainer extends Container {
42
43
  * @member {Array} items=[//...]]
43
44
  */
44
45
  items: [{
45
- ntype : 'container',
46
- _cls : ['neo-docs-classdetails-headercontainer'],
47
- flex : '1 0 auto',
48
- layout: {ntype: 'hbox', align: 'stretch'},
46
+ ntype : 'container',
47
+ cls : ['neo-docs-classdetails-headercontainer'],
48
+ flex : '1 1 auto',
49
+ layout : {ntype: 'hbox', align: 'stretch'},
50
+ minHeight: 200,
49
51
 
50
52
  items: [{
51
53
  module : Panel,
@@ -109,12 +111,20 @@ class MainContainer extends Container {
109
111
  flex : 1,
110
112
  record: '@config:structureData'
111
113
  }]
114
+ }, {
115
+ module: Splitter,
116
+ size : 5
112
117
  }, {
113
118
  module : HierarchyTreeList,
114
119
  flex : '0 0 auto',
115
120
  minWidth : 330,
116
121
  structureData: '@config:structureData'
117
122
  }]
123
+ }, {
124
+ module : Splitter,
125
+ direction : 'horizontal',
126
+ resizeTarget: 'previous',
127
+ size : 5
118
128
  }, {
119
129
  module : MembersList,
120
130
  flex : 1,
@@ -50,7 +50,7 @@ class MembersList extends Base {
50
50
  * @member {Object} _vdom={cn: []}
51
51
  */
52
52
  _vdom:
53
- {cn: []}
53
+ {cn: []}
54
54
  }
55
55
 
56
56
  /**
@@ -329,9 +329,9 @@ class MembersList extends Base {
329
329
 
330
330
  me.update();
331
331
 
332
- hasExamples && setTimeout(() => {
332
+ setTimeout(() => {
333
333
  Neo.main.addon.HighlightJS.syntaxHighlightInit();
334
- }, 100);
334
+ }, 100)
335
335
  }
336
336
 
337
337
  /**
@@ -412,7 +412,7 @@ class MembersList extends Base {
412
412
  cn : [{
413
413
  innerHTML: description.innerHTML
414
414
  },
415
- MembersList.createParametersTable(nestedParams)]
415
+ MembersList.createParametersTable(nestedParams)]
416
416
  }
417
417
  }
418
418
 
@@ -425,7 +425,7 @@ class MembersList extends Base {
425
425
  tag : 'td',
426
426
  innerHTML: param.type ? MembersList.escapeHtml(param.type.names.join(' | ')) : ''
427
427
  },
428
- description]
428
+ description]
429
429
  });
430
430
 
431
431
  if (hasDefaultValues) {
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.15.5'
23
+ * @member {String} version='5.16.1'
24
24
  */
25
- version: '5.15.5'
25
+ version: '5.16.1'
26
26
  }
27
27
 
28
28
  /**
@@ -1,9 +1,7 @@
1
- import CheckBox from '../../../../src/form/field/CheckBox.mjs';
2
1
  import ConfigurationViewport from '../../../ConfigurationViewport.mjs';
3
2
  import FileUploadField from '../../../../src/form/field/FileUpload.mjs';
4
3
  import NumberField from '../../../../src/form/field/Number.mjs';
5
- import Radio from '../../../../src/form/field/Radio.mjs';
6
- import TextField from '../../../../src/form/field/Text.mjs';
4
+ import Panel from '../../../../src/container/Panel.mjs';
7
5
 
8
6
  /**
9
7
  * @class Neo.examples.form.field.text.MainContainer
@@ -24,19 +22,79 @@ class MainContainer extends ConfigurationViewport {
24
22
  module : NumberField,
25
23
  labelText: 'width',
26
24
  listeners: {change: me.onConfigChange.bind(me, 'width')},
27
- maxValue : 300,
28
- minValue : 50,
25
+ maxValue : 350,
26
+ minValue : 200,
29
27
  stepSize : 5,
30
28
  style : {marginTop: '10px'},
31
29
  value : me.exampleComponent.width
32
- }]
30
+ }];
33
31
  }
34
32
 
35
33
  createExampleComponent() {
36
- return Neo.create(FileUploadField, {
37
- height: 50,
38
- width : 200
39
- })
34
+ return Neo.create(Panel, {
35
+ style : 'padding:1em',
36
+ items : [{
37
+ module : FileUploadField,
38
+ id : 'my-downloadable-test',
39
+ uploadUrl : 'http://127.0.0.1:3000/file-upload-test',
40
+ documentStatusUrl : 'http://127.0.0.1:3000/document-status-downloadable',
41
+ documentDeleteUrl : 'http://127.0.0.1:3000/document-delete',
42
+ downloadUrl : 'http://127.0.0.1:3000/getDocument',
43
+ width : 350,
44
+ maxSize : '10mb',
45
+ types : {
46
+ png : 1,
47
+ jpg : 1,
48
+ xls : 1,
49
+ pdf : 1
50
+ }
51
+ }, {
52
+ module : FileUploadField,
53
+ id : 'my-not-downloadable-test',
54
+ uploadUrl : 'http://127.0.0.1:3000/file-upload-test',
55
+ documentStatusUrl : 'http://127.0.0.1:3000/document-status-not-downloadable',
56
+ documentDeleteUrl : 'http://127.0.0.1:3000/document-delete',
57
+ downloadUrl : 'http://127.0.0.1:3000/getDocument',
58
+ width : 350,
59
+ maxSize : '10mb',
60
+ types : {
61
+ png : 1,
62
+ jpg : 1,
63
+ xls : 1,
64
+ pdf : 1
65
+ }
66
+ }, {
67
+ module : FileUploadField,
68
+ id : 'my-upload-fail-test',
69
+ uploadUrl : 'http://127.0.0.1:3000/file-upload-test-fail',
70
+ documentStatusUrl : 'http://127.0.0.1:3000/document-status',
71
+ documentDeleteUrl : 'http://127.0.0.1:3000/document-delete',
72
+ downloadUrl : 'http://127.0.0.1:3000/getDocument',
73
+ width : 350,
74
+ maxSize : '10mb',
75
+ types : {
76
+ png : 1,
77
+ jpg : 1,
78
+ xls : 1,
79
+ pdf : 1
80
+ }
81
+ }, {
82
+ module : FileUploadField,
83
+ id : 'my-scan-fail-test',
84
+ uploadUrl : 'http://127.0.0.1:3000/file-upload-test',
85
+ documentStatusUrl : 'http://127.0.0.1:3000/document-status-fail',
86
+ documentDeleteUrl : 'http://127.0.0.1:3000/document-delete',
87
+ downloadUrl : 'http://127.0.0.1:3000/getDocument',
88
+ width : 350,
89
+ maxSize : '10mb',
90
+ types : {
91
+ png : 1,
92
+ jpg : 1,
93
+ xls : 1,
94
+ pdf : 1
95
+ }
96
+ }]
97
+ });
40
98
  }
41
99
  }
42
100
 
@@ -0,0 +1,9 @@
1
+ # How to run this example
2
+ You need to install the following npm packages:
3
+ - cors
4
+ - express
5
+
6
+ To start the dummy backend, you need to use:
7
+ ```
8
+ node ./examples/form/field/fileupload/server.mjs
9
+ ```
@@ -0,0 +1,49 @@
1
+ import express from "express";
2
+ import cors from "cors"
3
+
4
+ const app = express();
5
+ const port = 3000;
6
+
7
+ app.use(cors());
8
+
9
+ app.post('/file-upload-test', async (req, res) => {
10
+
11
+ await new Promise(resolve => setTimeout(resolve, 3000));
12
+
13
+ res.set('Content-Type', 'application/json');
14
+ res.send('{"success":true,"documentId":"1"}');
15
+ })
16
+
17
+ app.post('/file-upload-test-fail', async (req, res) => {
18
+ res.set('Content-Type', 'application/json');
19
+ res.send('{"success":false,"message":"Something went wrong"}');
20
+ });
21
+
22
+ app.get('/document-status', async(req, res) => {
23
+ res.set('Content-Type', 'application/json');
24
+ res.send('{"status":"scanning"}');
25
+ });
26
+
27
+ app.get('/document-delete', async(req, res) => {
28
+ res.set('Content-Type', 'application/json');
29
+ res.send('');
30
+ });
31
+
32
+ app.get('/document-status-fail', async(req, res) => {
33
+ res.set('Content-Type', 'application/json');
34
+ res.send('{"status":"scan-failed"}');
35
+ });
36
+
37
+ app.get('/document-status-downloadable', async(req, res) => {
38
+ res.set('Content-Type', 'application/json');
39
+ res.send('{"status":"downloadable"}');
40
+ });
41
+
42
+ app.get('/document-status-not-downloadable', async(req, res) => {
43
+ res.set('Content-Type', 'application/json');
44
+ res.send('{"status":"not-downloadable"}');
45
+ });
46
+
47
+ app.listen(port, () => {
48
+ console.log(`Example app listening on port ${port}`)
49
+ });
@@ -0,0 +1,124 @@
1
+ import CheckBox from '../../../../src/form/field/CheckBox.mjs';
2
+ import ConfigurationViewport from '../../../ConfigurationViewport.mjs';
3
+ import NumberField from '../../../../src/form/field/Number.mjs';
4
+ import Radio from '../../../../src/form/field/Radio.mjs';
5
+ import SwitchField from '../../../../src/form/field/Switch.mjs';
6
+ import TextField from '../../../../src/form/field/Text.mjs';
7
+
8
+ /**
9
+ * @class Neo.examples.form.field.switch.MainContainer
10
+ * @extends Neo.examples.ConfigurationViewport
11
+ */
12
+ class MainContainer extends ConfigurationViewport {
13
+ static config = {
14
+ className : 'Neo.examples.form.field.switch.MainContainer',
15
+ autoMount : true,
16
+ configItemLabelWidth: 160,
17
+ layout : {ntype: 'hbox', align: 'stretch'}
18
+ }
19
+
20
+ createConfigurationComponents() {
21
+ let me = this;
22
+
23
+ return [{
24
+ module : CheckBox,
25
+ checked : me.exampleComponent.checked,
26
+ labelText: 'checked',
27
+ listeners: {change: me.onConfigChange.bind(me, 'checked')}
28
+ }, {
29
+ module : CheckBox,
30
+ checked : me.exampleComponent.disabled,
31
+ labelText: 'disabled',
32
+ listeners: {change: me.onConfigChange.bind(me, 'disabled')},
33
+ style : {marginTop: '10px'}
34
+ }, {
35
+ module : TextField,
36
+ clearable: true,
37
+ labelText: 'error',
38
+ listeners: {change: me.onConfigChange.bind(me, 'error')},
39
+ style : {marginTop: '10px'},
40
+ value : me.exampleComponent.error
41
+ }, {
42
+ module : CheckBox,
43
+ checked : me.exampleComponent.hideLabel,
44
+ labelText: 'hideLabel',
45
+ listeners: {change: me.onConfigChange.bind(me, 'hideLabel')},
46
+ style : {marginTop: '10px'}
47
+ }, {
48
+ module : Radio,
49
+ checked : me.exampleComponent.labelPosition === 'left',
50
+ hideValueLabel: false,
51
+ labelText : 'labelPosition',
52
+ listeners : {change: me.onRadioChange.bind(me, 'labelPosition', 'left')},
53
+ name : 'labelPosition',
54
+ style : {marginTop: '10px'},
55
+ valueLabelText: 'left'
56
+ }, {
57
+ module : Radio,
58
+ checked : me.exampleComponent.labelPosition === 'top',
59
+ hideValueLabel: false,
60
+ labelText : '',
61
+ listeners : {change: me.onRadioChange.bind(me, 'labelPosition', 'top')},
62
+ name : 'labelPosition',
63
+ valueLabelText: 'top'
64
+ }, {
65
+ module : TextField,
66
+ labelText: 'labelText',
67
+ listeners: {change: me.onConfigChange.bind(me, 'labelText')},
68
+ style : {marginTop: '10px'},
69
+ value : me.exampleComponent.labelText
70
+ }, {
71
+ module : NumberField,
72
+ labelText: 'labelWidth',
73
+ listeners: {change: me.onConfigChange.bind(me, 'labelWidth')},
74
+ maxValue : 200,
75
+ minValue : 50,
76
+ stepSize : 5,
77
+ value : me.exampleComponent.labelWidth
78
+ }, {
79
+ module : CheckBox,
80
+ checked : me.exampleComponent.readOnly,
81
+ labelText: 'readOnly',
82
+ listeners: {change: me.onConfigChange.bind(me, 'readOnly')},
83
+ style : {marginTop: '10px'}
84
+ }, {
85
+ module : CheckBox,
86
+ checked : me.exampleComponent.required,
87
+ labelText: 'required',
88
+ listeners: {change: me.onConfigChange.bind(me, 'required')},
89
+ style : {marginTop: '10px'}
90
+ }, {
91
+ module : TextField,
92
+ labelText: 'valueLabelText',
93
+ listeners: {change: me.onConfigChange.bind(me, 'valueLabelText')},
94
+ style : {marginTop: '10px'},
95
+ value : me.exampleComponent.valueLabelText
96
+ }, {
97
+ module : NumberField,
98
+ labelText: 'width',
99
+ listeners: {change: me.onConfigChange.bind(me, 'width')},
100
+ maxValue : 500,
101
+ minValue : 50,
102
+ stepSize : 5,
103
+ style : {marginTop: '10px'},
104
+ value : me.exampleComponent.width
105
+ }, {
106
+ ntype : 'button',
107
+ handler: (() => {me.exampleComponent.reset()}),
108
+ style : {marginTop: '10px', width: '50%'},
109
+ text : 'reset()'
110
+ }]
111
+ }
112
+
113
+ createExampleComponent() {
114
+ return Neo.create(SwitchField, {
115
+ labelText : 'Label',
116
+ labelWidth: 70,
117
+ width : 200
118
+ })
119
+ }
120
+ }
121
+
122
+ Neo.applyClassConfig(MainContainer);
123
+
124
+ export default MainContainer;
@@ -0,0 +1,6 @@
1
+ import MainContainer from './MainContainer.mjs';
2
+
3
+ export const onStart = () => Neo.app({
4
+ mainView: MainContainer,
5
+ name : 'Neo.examples.form.field.switch'
6
+ });
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE HTML>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <meta charset="UTF-8">
6
+ <title>Neo SwitchField</title>
7
+ </head>
8
+ <body>
9
+ <script src="../../../../src/MicroLoader.mjs" type="module"></script>
10
+ </body>
11
+ </html>
@@ -0,0 +1,6 @@
1
+ {
2
+ "appPath" : "examples/form/field/switch/app.mjs",
3
+ "basePath" : "../../../../",
4
+ "environment": "development",
5
+ "mainPath" : "./Main.mjs"
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "5.15.5",
3
+ "version": "5.16.1",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -57,6 +57,7 @@
57
57
  "neo-jsdoc-x": "1.0.5",
58
58
  "postcss": "^8.4.27",
59
59
  "sass": "^1.65.1",
60
+ "showdown": "^2.1.0",
60
61
  "webpack": "^5.88.2",
61
62
  "webpack-cli": "^5.1.4",
62
63
  "webpack-dev-server": "4.15.1",
@@ -10,4 +10,4 @@
10
10
  padding : v(docs-header-container-logo-padding);
11
11
  text-shadow : v(docs-header-container-logo-text-shadow);
12
12
  }
13
- }
13
+ }
@@ -1,5 +1,9 @@
1
1
  .neo-docs-maincontainer {
2
2
  .neo-docs-navigation-tab-container {
3
3
  background-color: v(docs-navigation-tab-container-background-color);
4
+
5
+ .neo-tab-content-container {
6
+ border-right: none;
7
+ }
4
8
  }
5
- }
9
+ }
@@ -3,12 +3,9 @@
3
3
  z-index : 10;
4
4
  }
5
5
 
6
- .neo-docs-classdetails-headerpanel {
7
- border-right: v(docs-classdetails-headerpanel-border-right) !important;
8
- }
9
-
10
6
  .neo-docs-classdetails-headercomponent {
11
7
  background-color: v(docs-classdetails-headercomponent-background-color);
8
+ overflow-y : auto;
12
9
  padding : 15px;
13
10
 
14
11
  .neo-docs-header-description {
@@ -23,4 +20,4 @@
23
20
  font-weight : 800;
24
21
  text-shadow : 2px 2px 3px rgba(200,200,200,0.1);
25
22
  }
26
- }
23
+ }
@@ -2,4 +2,4 @@
2
2
  .neo-docs-classdetails-headerpanel {
3
3
  border: 0;
4
4
  }
5
- }
5
+ }
@@ -1,10 +1,11 @@
1
1
  .neo-splitter {
2
2
  background-color: v(splitter-background-color);
3
3
  border : v(splitter-border);
4
- transition : background-color 0.3s ease-in-out;
4
+ transition : background-color 0.3s ease-in-out, border-color 0.3s ease-in-out;
5
5
 
6
6
  &:hover {
7
7
  background-color: v(splitter-hover-color);
8
+ border-color : v(splitter-hover-color);
8
9
  }
9
10
 
10
11
  &.neo-horizontal {
@@ -23,5 +24,6 @@
23
24
  .neo-dragproxy {
24
25
  &.neo-splitter {
25
26
  background-color: v(splitter-hover-color);
27
+ border-color : v(splitter-hover-color);
26
28
  }
27
29
  }