@saltcorn/markup 0.6.1 → 0.6.2-beta.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.
package/builder.js CHANGED
@@ -22,8 +22,8 @@ const {
22
22
  const { contract, is } = require("contractis");
23
23
 
24
24
  /**
25
- * @param {object} rec
26
- * @param {object} csrf
25
+ * @param {object} rec
26
+ * @param {object} csrf
27
27
  * @returns {object}
28
28
  */
29
29
  const addCsrf = (rec, csrf) => {
@@ -32,64 +32,69 @@ const addCsrf = (rec, csrf) => {
32
32
  };
33
33
 
34
34
  /**
35
- * @param {object} x
35
+ * @param {object} x
36
36
  * @returns {string}
37
37
  */
38
38
  const encode = (x) => encodeURIComponent(JSON.stringify(x));
39
39
 
40
- module.exports =
41
- /**
42
- * @param {object} opts
43
- * @param {object} opts.options
44
- * @param {object} opts.context
45
- * @param {object} opts.action
46
- * @param {string} opts.stepName
47
- * @param {object} opts.layout
48
- * @param {string} [opts.mode = "show"]
49
- * @param {object} opts
50
- * @param {object} csrfToken
51
- * @returns {div}
52
- */
53
- (
54
- { options, context, action, stepName, layout, mode = "show", version_tag },
55
- csrfToken
56
- ) =>
57
- div(
58
- script({
59
- src: version_tag
60
- ? `/static_assets/${version_tag}/builder_bundle.js`
61
- : "/builder_bundle.js",
62
- }),
63
- link({
64
- rel: "stylesheet",
65
- type: "text/css",
66
- media: "screen",
67
- href: version_tag
68
- ? `/static_assets/${version_tag}/fonticonpicker.react.css`
69
- : "/fonticonpicker.react.css",
70
- }),
71
- link({
72
- rel: "stylesheet",
73
- type: "text/css",
74
- media: "screen",
75
- href: version_tag
76
- ? `/static_assets/${version_tag}/saltcorn-builder.css`
77
- : "/saltcorn-builder.css",
78
- }),
79
- div({ id: "saltcorn-builder" }),
80
- form(
81
- { action, method: "post", id: "scbuildform" },
82
- input({
83
- type: "hidden",
84
- name: "contextEnc",
85
- value: encodeURIComponent(JSON.stringify(context)),
40
+ module.exports =
41
+ /**
42
+ * @param {object} opts
43
+ * @param {object} opts.options
44
+ * @param {object} opts.context
45
+ * @param {object} opts.action
46
+ * @param {string} opts.stepName
47
+ * @param {object} opts.layout
48
+ * @param {string} [opts.mode = "show"]
49
+ * @param {object} opts
50
+ * @param {object} csrfToken
51
+ * @returns {div}
52
+ */
53
+ (
54
+ { options, context, action, stepName, layout, mode = "show", version_tag },
55
+ csrfToken
56
+ ) =>
57
+ div(
58
+ script({
59
+ src: version_tag
60
+ ? `/static_assets/${version_tag}/builder_bundle.js`
61
+ : "/builder_bundle.js",
62
+ }),
63
+ script({
64
+ src: version_tag
65
+ ? `/static_assets/${version_tag}/ckeditor/ckeditor.js`
66
+ : "/ckeditor/ckeditor.js",
86
67
  }),
87
- input({ type: "hidden", name: "stepName", value: stepName }),
88
- input({ type: "hidden", name: "columns", value: "" }),
89
- input({ type: "hidden", name: "layout", value: "" }),
90
- input({ type: "hidden", name: "_csrf", value: csrfToken })
91
- ),
92
- script(`builder.renderBuilder(
68
+ link({
69
+ rel: "stylesheet",
70
+ type: "text/css",
71
+ media: "screen",
72
+ href: version_tag
73
+ ? `/static_assets/${version_tag}/fonticonpicker.react.css`
74
+ : "/fonticonpicker.react.css",
75
+ }),
76
+ link({
77
+ rel: "stylesheet",
78
+ type: "text/css",
79
+ media: "screen",
80
+ href: version_tag
81
+ ? `/static_assets/${version_tag}/saltcorn-builder.css`
82
+ : "/saltcorn-builder.css",
83
+ }),
84
+ div({ id: "saltcorn-builder" }),
85
+ form(
86
+ { action, method: "post", id: "scbuildform" },
87
+ input({
88
+ type: "hidden",
89
+ name: "contextEnc",
90
+ value: encodeURIComponent(JSON.stringify(context)),
91
+ }),
92
+ input({ type: "hidden", name: "stepName", value: stepName }),
93
+ input({ type: "hidden", name: "columns", value: "" }),
94
+ input({ type: "hidden", name: "layout", value: "" }),
95
+ input({ type: "hidden", name: "_csrf", value: csrfToken })
96
+ ),
97
+ script(`builder.renderBuilder(
93
98
  "saltcorn-builder",
94
99
  "${encode(addCsrf(options, csrfToken))}",
95
100
  "${encode(layout || {})}",
@@ -98,4 +103,4 @@ module.exports =
98
103
  document.addEventListener('DOMContentLoaded',
99
104
  function(){window.onerror=globalErrorCatcher},false);
100
105
  ;`)
101
- );
106
+ );
package/helpers.js CHANGED
@@ -17,16 +17,16 @@ const {
17
17
 
18
18
  /**
19
19
  * checks if x is defined
20
- * @param {*} x
20
+ * @param {*} x
21
21
  * @returns {boolean}
22
22
  */
23
23
  const isdef = (x) => typeof x !== "undefined";
24
24
 
25
25
  /**
26
- * @param {object|string} v
27
- * @param {object} hdr
28
- * @param {boolean} force_required
29
- * @param {string} neutral_label
26
+ * @param {object|string} v
27
+ * @param {object} hdr
28
+ * @param {boolean} force_required
29
+ * @param {string} neutral_label
30
30
  * @returns {string}
31
31
  */
32
32
  const select_options = (v, hdr, force_required, neutral_label = "") => {
@@ -56,7 +56,7 @@ const select_options = (v, hdr, force_required, neutral_label = "") => {
56
56
  };
57
57
 
58
58
  /**
59
- *
59
+ *
60
60
  * @param {object} opts
61
61
  * @param {string} opts.name
62
62
  * @param {object} [opts.options]
@@ -66,7 +66,15 @@ const select_options = (v, hdr, force_required, neutral_label = "") => {
66
66
  * @param {...*} opts.rest
67
67
  * @returns {string}
68
68
  */
69
- const radio_group = ({ name, options, value, inline, form_name, ...rest }) =>
69
+ const radio_group = ({
70
+ name,
71
+ options,
72
+ value,
73
+ inline,
74
+ form_name,
75
+ onChange,
76
+ ...rest
77
+ }) =>
70
78
  div(
71
79
  (options || [])
72
80
  .filter((o) => (typeof o === "string" ? o : o.value))
@@ -79,6 +87,7 @@ const radio_group = ({ name, options, value, inline, form_name, ...rest }) =>
79
87
  class: ["form-check-input", rest.class],
80
88
  type: "radio",
81
89
  name,
90
+ onChange,
82
91
  "data-fieldname": form_name,
83
92
  id,
84
93
  value: text_attr(myvalue),
@@ -93,6 +102,44 @@ const radio_group = ({ name, options, value, inline, form_name, ...rest }) =>
93
102
  .join("")
94
103
  );
95
104
 
105
+ const checkbox_group = ({
106
+ name,
107
+ options,
108
+ value,
109
+ inline,
110
+ form_name,
111
+ onChange,
112
+ ...rest
113
+ }) =>
114
+ div(
115
+ (options || [])
116
+ .filter((o) => (typeof o === "string" ? o : o.value))
117
+ .map((o, ix) => {
118
+ const myvalue = typeof o === "string" ? o : o.value;
119
+ const id = `input${text_attr(name)}${ix}`;
120
+ return div(
121
+ { class: ["form-check", inline && "form-check-inline"] },
122
+ input({
123
+ class: ["form-check-input", rest.class],
124
+ type: "checkbox",
125
+ name,
126
+ onChange: `check_state_field(this)`,
127
+ "data-fieldname": form_name,
128
+ id,
129
+ value: text_attr(myvalue),
130
+ checked: Array.isArray(value)
131
+ ? value.includes(myvalue)
132
+ : myvalue === value,
133
+ }),
134
+ label(
135
+ { class: "form-check-label", for: id },
136
+ typeof o === "string" ? o : o.label
137
+ )
138
+ );
139
+ })
140
+ .join("")
141
+ );
142
+
96
143
  /**
97
144
  * @param {object} opts
98
145
  * @param {number} opts.current_page
@@ -143,9 +190,9 @@ const pagination = ({
143
190
  };
144
191
 
145
192
  /**
146
- * @param {string} name
147
- * @param {object} v
148
- * @param {object} param2
193
+ * @param {string} name
194
+ * @param {object} v
195
+ * @param {object} param2
149
196
  * @returns {string}
150
197
  */
151
198
  const search_bar = (
@@ -217,4 +264,5 @@ module.exports = {
217
264
  search_bar,
218
265
  pagination,
219
266
  radio_group,
267
+ checkbox_group,
220
268
  };
package/index.js CHANGED
@@ -2,6 +2,22 @@
2
2
  * @category saltcorn-markup
3
3
  * @module saltcorn-markup/index
4
4
  */
5
+
6
+ /**
7
+ * All files in the saltcorn-markup package.
8
+ * @namespace saltcorn-markup_overview
9
+ * @property {module:builder} builder
10
+ * @property {module:emergency_layout} emergency_layout
11
+ * @property {module:form} from
12
+ * @property {module:helpers} helpers
13
+ * @property {module:layout_utils} layout_utils
14
+ * @property {module:layout} layout
15
+ * @property {module:mktag} mktag
16
+ * @property {module:table} table
17
+ * @property {module:tabs} tabs
18
+ * @category saltcorn-markup
19
+ */
20
+
5
21
  const renderForm = require("./form");
6
22
  const renderBuilder = require("./builder");
7
23
  const mkTable = require("./table");
package/layout.js CHANGED
@@ -34,7 +34,7 @@ const { search_bar_form, search_bar } = require("./helpers");
34
34
  const couldHaveAlerts = (alerts) => alerts || Array.isArray(alerts);
35
35
 
36
36
  /**
37
- * @param {string|object} body
37
+ * @param {string|object} body
38
38
  * @param {object[]} [alerts]
39
39
  * @returns {object}
40
40
  */
@@ -62,9 +62,9 @@ const makeSegments = (body, alerts) => {
62
62
  };
63
63
 
64
64
  /**
65
- *
66
- * @param {object} segment
67
- * @param {string} inner
65
+ *
66
+ * @param {object} segment
67
+ * @param {string} inner
68
68
  * @returns {div|span|string}
69
69
  */
70
70
  const applyTextStyle = (segment, inner) => {
@@ -97,10 +97,13 @@ const applyTextStyle = (segment, inner) => {
97
97
  * @param {string[]} opts.titles
98
98
  * @param {string} opts.tabsStyle
99
99
  * @param {*} opts.ntabs
100
- * @param {function} go
100
+ * @param {function} go
101
101
  * @returns {ul_div}
102
102
  */
103
- const renderTabs = ({ contents, titles, tabsStyle, ntabs }, go) => {
103
+ const renderTabs = (
104
+ { contents, titles, tabsStyle, ntabs, independent },
105
+ go
106
+ ) => {
104
107
  const rndid = `tab${Math.floor(Math.random() * 16777215).toString(16)}`;
105
108
  if (tabsStyle === "Accordion")
106
109
  return div(
@@ -130,7 +133,7 @@ const renderTabs = ({ contents, titles, tabsStyle, ntabs }, go) => {
130
133
  class: ["collapse", ix === 0 && "show"],
131
134
  id: `${rndid}tab${ix}`,
132
135
  "aria-labelledby": `${rndid}head${ix}`,
133
- "data-parent": `#${rndid}top`,
136
+ "data-parent": independent ? undefined : `#${rndid}top`,
134
137
  },
135
138
  div({ class: "card-body" }, go(t, false, ix))
136
139
  )
@@ -227,7 +230,12 @@ const render = ({ blockDispatch, layout, role, alerts, is_owner }) => {
227
230
  return wrap(segment, isTop, ix, segment.contents || "");
228
231
  }
229
232
  if (segment.type === "breadcrumbs") {
230
- return wrap(segment, isTop, ix, breadcrumbs(segment.crumbs || []));
233
+ return wrap(
234
+ segment,
235
+ isTop,
236
+ ix,
237
+ breadcrumbs(segment.crumbs || [], segment.right)
238
+ );
231
239
  }
232
240
  if (segment.type === "view") {
233
241
  return wrap(segment, isTop, ix, segment.contents || "");
package/layout_utils.js CHANGED
@@ -21,17 +21,19 @@ const {
21
21
  i,
22
22
  small,
23
23
  br,
24
+ form,
25
+ input,
24
26
  } = require("./tags");
25
27
 
26
28
  /**
27
- * @param {string} item
29
+ * @param {string} item
28
30
  * @returns {string}
29
31
  */
30
32
  const labelToId = (item) => text(item.replace(" ", ""));
31
33
 
32
34
  /**
33
- * @param {string} currentUrl
34
- * @param {object} item
35
+ * @param {string} currentUrl
36
+ * @param {object} item
35
37
  * @returns {boolean}
36
38
  */
37
39
  const active = (currentUrl, item) =>
@@ -40,7 +42,7 @@ const active = (currentUrl, item) =>
40
42
  item.subitems.some((si) => si.link && currentUrl.startsWith(si.link)));
41
43
 
42
44
  /**
43
- * @param {object[]} sections
45
+ * @param {object[]} sections
44
46
  * @returns {object[]}
45
47
  */
46
48
  const innerSections = (sections) => {
@@ -93,8 +95,8 @@ const navSubitems = ({ label, subitems, icon, isUser }) =>
93
95
  );
94
96
 
95
97
  /**
96
- * @param {string} currentUrl
97
- * @param {object[]} sections
98
+ * @param {string} currentUrl
99
+ * @param {object[]} sections
98
100
  * @returns {div}
99
101
  */
100
102
  const rightNavBar = (currentUrl, sections) =>
@@ -122,21 +124,54 @@ const rightNavBar = (currentUrl, sections) =>
122
124
  text(s.label)
123
125
  )
124
126
  )
127
+ : s.type === "Search"
128
+ ? li(
129
+ form(
130
+ {
131
+ action: "/search",
132
+ class: "menusearch",
133
+ method: "get",
134
+ },
135
+ div(
136
+ { class: "input-group search-bar" },
137
+
138
+ input({
139
+ type: "search",
140
+ class: "form-control search-bar pl-2 hasbl",
141
+ placeholder: s.label,
142
+ id: "inputq",
143
+ name: "q",
144
+ "aria-label": "Search",
145
+ "aria-describedby": "button-search-submit",
146
+ }),
147
+ div(
148
+ { class: "input-group-append" },
149
+ button(
150
+ {
151
+ class: "btn btn-outline-secondary search-bar",
152
+ type: "submit",
153
+ },
154
+ i({ class: "fas fa-search" })
155
+ )
156
+ )
157
+ )
158
+ )
159
+ )
125
160
  : ""
126
161
  )
127
162
  )
128
163
  );
129
164
 
130
- /**
131
- * @param {object[]} sections
132
- * @returns {boolean}
133
- */
165
+ /**
166
+ * @param {object[]} sections
167
+ * @returns {boolean}
168
+ */
134
169
  const hasMobileItems = (sections) =>
135
170
  innerSections(sections).some((s) => s.location === "Mobile Bottom");
136
171
 
137
172
  /**
138
- * @param {string} currentUrl
139
- * @param {object[]} sections
173
+ * @param {string} currentUrl
174
+ * @param {object[]} sections
140
175
  * @param {string} [cls = ""]
141
176
  * @param {string} [clsLink = ""]
142
177
  * @returns {footer|string}
@@ -212,9 +247,9 @@ const leftNavBar = ({ name, logo }) => [
212
247
  ];
213
248
 
214
249
  /**
215
- * @param {object} brand
216
- * @param {object[]} sections
217
- * @param {string} currentUrl
250
+ * @param {object} brand
251
+ * @param {object[]} sections
252
+ * @param {string} currentUrl
218
253
  * @param {object} opts
219
254
  * @param {boolean} [opts.fixedTop = true]
220
255
  * @returns {string}
@@ -235,8 +270,8 @@ const navbar = (brand, sections, currentUrl, opts = { fixedTop: true }) =>
235
270
  );
236
271
 
237
272
  /**
238
- * @param {string} type
239
- * @param {string} s
273
+ * @param {string} type
274
+ * @param {string} s
240
275
  * @returns {string}
241
276
  */
242
277
  const alert = (type, s) => {
@@ -266,8 +301,8 @@ const navbarSolidOnScroll = script(
266
301
  );
267
302
 
268
303
  /**
269
- * @param {object} x
270
- * @param {object} s
304
+ * @param {object} x
305
+ * @param {object} s
271
306
  * @returns {object}
272
307
  */
273
308
  const logit = (x, s) => {
@@ -277,7 +312,7 @@ const logit = (x, s) => {
277
312
  };
278
313
 
279
314
  /**
280
- * @param {number} len
315
+ * @param {number} len
281
316
  * @returns {function}
282
317
  */
283
318
  const standardBreadcrumbItem = (len) => ({ href, text }, ix) =>
@@ -311,10 +346,10 @@ const workflowBreadcrumbItem = ({ workflow, step }) =>
311
346
  .join("");
312
347
 
313
348
  /**
314
- * @param {object[]} crumbs
349
+ * @param {object[]} crumbs
315
350
  * @returns {string}
316
351
  */
317
- const breadcrumbs = (crumbs) =>
352
+ const breadcrumbs = (crumbs, right) =>
318
353
  nav(
319
354
  { "aria-label": "breadcrumb" },
320
355
  ol(
@@ -323,12 +358,13 @@ const breadcrumbs = (crumbs) =>
323
358
  c.workflow
324
359
  ? workflowBreadcrumbItem(c)
325
360
  : standardBreadcrumbItem(crumbs.length)(c)
326
- )
361
+ ),
362
+ right ? li({ class: "ml-auto" }, right) : ""
327
363
  )
328
364
  );
329
365
 
330
366
  /**
331
- * @param {object[]} headers
367
+ * @param {object[]} headers
332
368
  * @returns {string}
333
369
  */
334
370
  const headersInHead = (headers) =>
@@ -346,7 +382,7 @@ const headersInHead = (headers) =>
346
382
  .join("");
347
383
 
348
384
  /**
349
- * @param {object[]} headers
385
+ * @param {object[]} headers
350
386
  * @returns {string}
351
387
  */
352
388
  const headersInBody = (headers) =>
@@ -367,7 +403,7 @@ const headersInBody = (headers) =>
367
403
  .join("");
368
404
 
369
405
  /**
370
- * @param {object[]} tabList
406
+ * @param {object[]} tabList
371
407
  * @returns {ul}
372
408
  */
373
409
  const cardHeaderTabs = (tabList) =>
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@saltcorn/markup",
3
- "version": "0.6.1",
3
+ "version": "0.6.2-beta.3",
4
4
  "description": "Markup for Saltcorn, open-source no-code platform",
5
5
  "homepage": "https://saltcorn.com",
6
6
  "main": "index.js",
7
7
  "scripts": {
8
- "test": "jest"
8
+ "test": "jest",
9
+ "tsc": "echo \"Error: no TypeScript support yet\"",
10
+ "clean": "echo \"Error: no TypeScript support yet\""
9
11
  },
10
12
  "author": "Tom Nielsen",
11
13
  "license": "MIT",