@saltcorn/markup 0.6.2-beta.2 → 0.6.2

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 (60) hide show
  1. package/dist/builder.d.ts +18 -0
  2. package/dist/builder.d.ts.map +1 -0
  3. package/dist/builder.js +57 -0
  4. package/dist/builder.js.map +1 -0
  5. package/dist/emergency_layout.d.ts +6 -0
  6. package/dist/emergency_layout.d.ts.map +1 -0
  7. package/dist/emergency_layout.js +38 -0
  8. package/dist/emergency_layout.js.map +1 -0
  9. package/dist/form.d.ts +12 -0
  10. package/dist/form.d.ts.map +1 -0
  11. package/dist/form.js +372 -0
  12. package/dist/form.js.map +1 -0
  13. package/dist/helpers.d.ts +58 -0
  14. package/dist/helpers.d.ts.map +1 -0
  15. package/dist/helpers.js +169 -0
  16. package/dist/helpers.js.map +1 -0
  17. package/dist/index.d.ts +21 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +158 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/layout.d.ts +22 -0
  22. package/dist/layout.d.ts.map +1 -0
  23. package/dist/layout.js +338 -0
  24. package/dist/layout.js.map +1 -0
  25. package/dist/layout_utils.d.ts +21 -0
  26. package/dist/layout_utils.d.ts.map +1 -0
  27. package/dist/layout_utils.js +272 -0
  28. package/dist/layout_utils.js.map +1 -0
  29. package/dist/mktag.d.ts +12 -0
  30. package/dist/mktag.d.ts.map +1 -0
  31. package/dist/mktag.js +100 -0
  32. package/dist/mktag.js.map +1 -0
  33. package/dist/table.d.ts +22 -0
  34. package/dist/table.d.ts.map +1 -0
  35. package/dist/table.js +51 -0
  36. package/dist/table.js.map +1 -0
  37. package/dist/tabs.d.ts +7 -0
  38. package/dist/tabs.d.ts.map +1 -0
  39. package/dist/tabs.js +34 -0
  40. package/dist/tabs.js.map +1 -0
  41. package/dist/tags.d.ts +17 -0
  42. package/dist/tags.d.ts.map +1 -0
  43. package/dist/tags.js +71 -0
  44. package/dist/tags.js.map +1 -0
  45. package/dist/tsconfig.ref.tsbuildinfo +1 -0
  46. package/package.json +25 -6
  47. package/builder.js +0 -101
  48. package/emergency_layout.js +0 -54
  49. package/form.js +0 -603
  50. package/form.test.js +0 -98
  51. package/helpers.js +0 -268
  52. package/index.js +0 -226
  53. package/layout.js +0 -590
  54. package/layout.test.js +0 -39
  55. package/layout_utils.js +0 -394
  56. package/markup.test.js +0 -104
  57. package/mktag.js +0 -105
  58. package/table.js +0 -115
  59. package/tabs.js +0 -54
  60. package/tags.js +0 -56
package/form.test.js DELETED
@@ -1,98 +0,0 @@
1
- const { a, input, div, ul, text, text_attr } = require("./tags");
2
- const { renderForm } = require(".");
3
-
4
- class Form {
5
- constructor(o) {
6
- Object.entries(o).forEach(([k, v]) => {
7
- this[k] = v;
8
- });
9
- }
10
- }
11
-
12
- const nolines = (s) => s.split("\n").join("");
13
-
14
- describe("form render", () => {
15
- it("renders a simple form", () => {
16
- const form = new Form({
17
- action: "/",
18
- fields: [
19
- {
20
- name: "name",
21
- label: "Name",
22
- input_type: "text",
23
- form_name: "name",
24
- },
25
- ],
26
- });
27
- const want = `<form action="/" class="form-namespace " method="post">
28
- <input type="hidden" name="_csrf" value=""><div class="form-group">
29
- <div><label for="inputname">Name</label></div>
30
- <div><input type="text" class="form-control " data-fieldname="name" name="name" id="inputname">
31
- </div></div><div class="form-group row">
32
- <div class="col-sm-12">
33
- <button type="submit" class="btn btn-primary">Save</button>
34
- </div>
35
- </div>
36
- </form>`;
37
- expect(nolines(renderForm(form, ""))).toBe(nolines(want));
38
- });
39
- it("renders a form with layout", () => {
40
- const form = new Form({
41
- action: "/",
42
- fields: [
43
- {
44
- name: "name",
45
- label: "Name",
46
- input_type: "text",
47
- form_name: "name",
48
- },
49
- ],
50
- values: {},
51
- errors: {},
52
- layout: {
53
- above: [
54
- {
55
- type: "field",
56
- block: false,
57
- fieldview: "edit",
58
- textStyle: "h2",
59
- field_name: "name",
60
- },
61
- { type: "line_break" },
62
- ],
63
- },
64
- });
65
- const want = `<form action="/" class="form-namespace " method="post">
66
- <input type="hidden" name="_csrf" value="">
67
- <h2>
68
- <input type="text" class="form-control " data-fieldname="name" name="name" id="inputname">
69
- </h2><br /></form>`;
70
- expect(nolines(renderForm(form, ""))).toBe(nolines(want));
71
- });
72
- it("renders a simple form with errors", () => {
73
- const form = new Form({
74
- action: "/",
75
- errors: { name: "Not a foo" },
76
- values: { name: "Bar" },
77
- fields: [
78
- {
79
- name: "name",
80
- label: "Name",
81
- input_type: "text",
82
- form_name: "name",
83
- },
84
- ],
85
- });
86
- const want = `<form action="/" class="form-namespace " method="post">
87
- <input type="hidden" name="_csrf" value=""><div class="form-group">
88
- <div><label for="inputname">Name</label></div>
89
- <div><input type="text" class="form-control is-invalid " data-fieldname="name" name="name" id="inputname" value="Bar"><div>Not a foo</div>
90
- </div></div><div class="form-group row">
91
- <div class="col-sm-12">
92
- <button type="submit" class="btn btn-primary">Save</button>
93
- </div>
94
- </div>
95
- </form>`;
96
- expect(nolines(renderForm(form, ""))).toBe(nolines(want));
97
- });
98
- });
package/helpers.js DELETED
@@ -1,268 +0,0 @@
1
- /**
2
- * @category saltcorn-markup
3
- * @module helpers
4
- */
5
-
6
- const {
7
- a,
8
- text,
9
- div,
10
- input,
11
- text_attr,
12
- ul,
13
- li,
14
- span,
15
- label,
16
- } = require("./tags");
17
-
18
- /**
19
- * checks if x is defined
20
- * @param {*} x
21
- * @returns {boolean}
22
- */
23
- const isdef = (x) => typeof x !== "undefined";
24
-
25
- /**
26
- * @param {object|string} v
27
- * @param {object} hdr
28
- * @param {boolean} force_required
29
- * @param {string} neutral_label
30
- * @returns {string}
31
- */
32
- const select_options = (v, hdr, force_required, neutral_label = "") => {
33
- const options0 = hdr.options || [];
34
- const options1 = force_required
35
- ? options0.filter((o) => (typeof o === "string" ? o : o.value))
36
- : options0;
37
- const options = options1.map((o) =>
38
- o.value === "" ? { ...o, label: neutral_label } : o
39
- );
40
- const selected = typeof v === "object" ? (v ? v[hdr.name] : undefined) : v;
41
- const isSelected = (value) =>
42
- !selected
43
- ? false
44
- : selected.length
45
- ? selected.includes(value)
46
- : value === selected;
47
- return options
48
- .map((o) => {
49
- const label = typeof o === "string" ? o : o.label;
50
- const value = typeof o === "string" ? o : o.value;
51
- return `<option value="${text_attr(value)}"${
52
- isSelected(value) ? " selected" : ""
53
- }>${text(label)}</option>`;
54
- })
55
- .join("");
56
- };
57
-
58
- /**
59
- *
60
- * @param {object} opts
61
- * @param {string} opts.name
62
- * @param {object} [opts.options]
63
- * @param {string} opts.value
64
- * @param {object} opts.inline
65
- * @param {string} opts.form_name
66
- * @param {...*} opts.rest
67
- * @returns {string}
68
- */
69
- const radio_group = ({
70
- name,
71
- options,
72
- value,
73
- inline,
74
- form_name,
75
- onChange,
76
- ...rest
77
- }) =>
78
- div(
79
- (options || [])
80
- .filter((o) => (typeof o === "string" ? o : o.value))
81
- .map((o, ix) => {
82
- const myvalue = typeof o === "string" ? o : o.value;
83
- const id = `input${text_attr(name)}${ix}`;
84
- return div(
85
- { class: ["form-check", inline && "form-check-inline"] },
86
- input({
87
- class: ["form-check-input", rest.class],
88
- type: "radio",
89
- name,
90
- onChange,
91
- "data-fieldname": form_name,
92
- id,
93
- value: text_attr(myvalue),
94
- checked: myvalue === value,
95
- }),
96
- label(
97
- { class: "form-check-label", for: id },
98
- typeof o === "string" ? o : o.label
99
- )
100
- );
101
- })
102
- .join("")
103
- );
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
-
143
- /**
144
- * @param {object} opts
145
- * @param {number} opts.current_page
146
- * @param {number} opts.pages
147
- * @param {function} opts.get_page_link
148
- * @param {boolean} opts.trailing_ellipsis
149
- * @returns {string}
150
- */
151
- const pagination = ({
152
- current_page,
153
- pages,
154
- get_page_link,
155
- trailing_ellipsis,
156
- }) => {
157
- const from = Math.max(1, current_page - 3);
158
- const to = Math.min(pages, current_page + 3);
159
- var lis = [];
160
- if (from > 1) {
161
- lis.push(
162
- li(
163
- { class: `page-item` },
164
- a({ class: "page-link", href: get_page_link(1) }, 1)
165
- )
166
- );
167
- lis.push(li({ class: `page-item` }, span({ class: "page-link" }, "...")));
168
- }
169
-
170
- for (let index = from; index <= to; index++) {
171
- lis.push(
172
- li(
173
- { class: ["page-item", index === current_page && "active"] },
174
- a({ class: "page-link", href: get_page_link(index) }, index)
175
- )
176
- );
177
- }
178
- if (to < pages) {
179
- lis.push(li({ class: `page-item` }, span({ class: "page-link" }, "...")));
180
- lis.push(
181
- li(
182
- { class: `page-item` },
183
- a({ class: "page-link", href: get_page_link(pages) }, pages)
184
- )
185
- );
186
- }
187
- if (trailing_ellipsis)
188
- lis.push(li({ class: `page-item` }, span({ class: "page-link" }, "...")));
189
- return ul({ class: "pagination" }, lis);
190
- };
191
-
192
- /**
193
- * @param {string} name
194
- * @param {object} v
195
- * @param {object} param2
196
- * @returns {string}
197
- */
198
- const search_bar = (
199
- name,
200
- v,
201
- { placeHolder, has_dropdown, contents, badges, stateField, onClick } = {}
202
- ) => {
203
- const rndid = Math.floor(Math.random() * 16777215).toString(16);
204
- const clickHandler = stateField
205
- ? `(function(v){v ? set_state_field('${stateField}', v):unset_state_field('${stateField}');})($('input.search-bar').val())`
206
- : onClick || "";
207
- return `<div class="input-group search-bar">
208
- <div class="input-group-prepend">
209
- <button class="btn btn-outline-secondary search-bar" ${
210
- clickHandler ? `onClick="${clickHandler}"` : ""
211
- } type="submit" id="button-search-submit">
212
- <i class="fas fa-search"></i>
213
- </button>
214
- </div>
215
- <input type="search" class="form-control search-bar ${
216
- (badges && badges.length > 0) || has_dropdown ? "br-none" : ""
217
- }" placeholder="${placeHolder || "Search for..."}"
218
- }"
219
- }"
220
- id="input${text_attr(name)}" name="${name}"
221
- ${
222
- clickHandler
223
- ? `onsearch="${clickHandler}" onChange="${clickHandler}"`
224
- : ""
225
- }
226
- aria-label="Search" aria-describedby="button-search-submit" ${
227
- v ? `value="${text_attr(v)}"` : ""
228
- }>
229
- <div class="input-group-append">
230
- ${
231
- badges && badges.length > 0
232
- ? `<div class="input-group-text">${badges
233
- .map(
234
- (b) =>
235
- `<span class="badge badge-primary">${b.text}${
236
- b.onclick
237
- ? `<a href="javascript:${b.onclick}"><i class="ml-1 fas fa-lg fa-times"></i></a> `
238
- : ""
239
- }</span>`
240
- )
241
- .join("&nbsp;")}
242
- </div>`
243
- : ""
244
- }
245
- ${
246
- has_dropdown
247
- ? `<button class="btn btn-outline-secondary dropdown-toggle search-bar" id="dd${rndid}" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" onclick="align_dropdown('${rndid}')"></button>`
248
- : ""
249
- }
250
- ${
251
- has_dropdown
252
- ? `<div class="dropdown-menu search-bar p-2" id="dm${rndid}" aria-labelledby="dd${rndid}">
253
- ${contents}
254
- </div>`
255
- : ""
256
- }
257
- </div>
258
- </div>`;
259
- };
260
-
261
- module.exports = {
262
- isdef,
263
- select_options,
264
- search_bar,
265
- pagination,
266
- radio_group,
267
- checkbox_group,
268
- };
package/index.js DELETED
@@ -1,226 +0,0 @@
1
- /**
2
- * @category saltcorn-markup
3
- * @module saltcorn-markup/index
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
-
21
- const renderForm = require("./form");
22
- const renderBuilder = require("./builder");
23
- const mkTable = require("./table");
24
- const tabs = require("./tabs");
25
- const { a, text, div, button, time } = require("./tags");
26
-
27
- /**
28
- * @param {string} href
29
- * @param {string} s
30
- * @returns {string}
31
- */
32
- const link = (href, s) => a({ href: text(href) }, text(s));
33
-
34
- /**
35
- * @param {string} href
36
- * @param {string} s
37
- * @param {string} csrfToken
38
- * @param {object} opts
39
- * @param {string} [opts.btnClass = "btn-primary"]
40
- * @param {string} [opts.onClick]
41
- * @param {string} [opts.small]
42
- * @param {string} [opts.style]
43
- * @param {*} opts.ajax
44
- * @param {string} opts.reload_on_done
45
- * @param {string} opts.reload_delay
46
- * @param {string} [opts.klass = "btn-primary"]
47
- * @param {string} [opts.formClass]
48
- * @param {string} opts.spinner
49
- * @param {object} opts.req
50
- * @param {boolean} opts.confirm
51
- * @param {string} opts.icon
52
- * @returns {string}
53
- */
54
- const post_btn = (
55
- href,
56
- s,
57
- csrfToken,
58
- {
59
- btnClass = "btn-primary",
60
- onClick,
61
- small,
62
- style,
63
- ajax,
64
- reload_on_done,
65
- reload_delay,
66
- klass = "",
67
- formClass,
68
- spinner,
69
- req,
70
- confirm,
71
- icon,
72
- } = {}
73
- ) =>
74
- `<form action="${text(href)}" method="post"${
75
- formClass ? `class="${formClass}"` : ""
76
- }>
77
- <input type="hidden" name="_csrf" value="${csrfToken}">
78
- <button ${ajax ? 'type="button"' : 'type="submit"'} ${
79
- onClick
80
- ? `onclick="${spinner ? "press_store_button(this);" : ""}${onClick}"`
81
- : ajax && confirm
82
- ? `onclick="if(confirm('${req.__("Are you sure?")}')) {${
83
- spinner ? "press_store_button(this);" : ""
84
- }ajax_post_btn(this, ${reload_on_done}, ${reload_delay})}"`
85
- : ajax
86
- ? `onclick="${
87
- spinner ? "press_store_button(this);" : ""
88
- }ajax_post_btn(this, ${reload_on_done}, ${reload_delay})"`
89
- : confirm
90
- ? `onclick="return confirm('${req.__("Are you sure?")}')"`
91
- : ""
92
- } class="${klass} btn ${small ? "btn-sm" : ""} ${btnClass}"${
93
- style ? ` style="${style}"` : ""
94
- }>${icon ? `<i class="${icon}"></i>&nbsp;` : ""}${s}</button></form>`;
95
-
96
- /**
97
- * UI Form for Delete Item confirmation
98
- * @param {string} href - href
99
- * @param {string} req - Request
100
- * @param {string} what - Item
101
- * @returns {string} return html form
102
- */
103
- const post_delete_btn = (href, req, what) =>
104
- `<form action="${text(href)}" method="post" >
105
- <input type="hidden" name="_csrf" value="${req.csrfToken()}">
106
- <button type="submit" class="btn btn-danger btn-sm"
107
- onclick="return confirm('${
108
- what
109
- ? req.__("Are you sure you want to delete %s?", what)
110
- : req.__("Are you sure?")
111
- }')" />
112
- <i class="fas fa-trash-alt"></i>
113
- </button>
114
- </form>`;
115
-
116
- /**
117
- * @param {string} href
118
- * @param {string} s
119
- * @param {object} req
120
- * @param {boolean} confirm
121
- * @param {string} what
122
- * @returns {string}
123
- */
124
- const post_dropdown_item = (href, s, req, confirm, what) => {
125
- const id = href.split("/").join("");
126
- return `<a class="dropdown-item" onclick="${
127
- confirm
128
- ? `if(confirm('${
129
- what
130
- ? req.__("Are you sure you want to delete %s?", what)
131
- : req.__("Are you sure?")
132
- }')) `
133
- : ""
134
- }$('#${id}').submit()">${s}</a>
135
- <form id="${id}" action="${text(href)}" method="post">
136
- <input type="hidden" name="_csrf" value="${req.csrfToken()}">
137
- </form>`;
138
- };
139
-
140
- /**
141
- * @param {string} id
142
- * @param {*} elems
143
- * @returns {div}
144
- */
145
- const settingsDropdown = (id, elems) =>
146
- div(
147
- { class: "dropdown" },
148
- button(
149
- {
150
- class: "btn btn-sm btn-outline-secondary",
151
- "data-boundary": "viewport",
152
- type: "button",
153
- id,
154
- "data-toggle": "dropdown",
155
- "aria-haspopup": "true",
156
- "aria-expanded": "false",
157
- },
158
- '<i class="fas fa-ellipsis-h"></i>'
159
- ),
160
- div(
161
- {
162
- class: "dropdown-menu dropdown-menu-right",
163
- "aria-labelledby": id,
164
- },
165
- elems
166
- )
167
- );
168
-
169
- /**
170
- * @param {Date} date
171
- * @param {object} opts
172
- * @param {string} [opts.hour = "2-digit"]
173
- * @param {string} [opts.minute = "2-digit"]
174
- * @returns {string}
175
- */
176
- const localeTime = (date, options = { hour: "2-digit", minute: "2-digit" }) =>
177
- time(
178
- {
179
- datetime: date.toISOString(),
180
- "locale-time-options": encodeURIComponent(JSON.stringify(options)),
181
- },
182
- date.toLocaleTimeString("en", options)
183
- );
184
-
185
- /**
186
- * @param {Date} date
187
- * @param {object} [options ={}]
188
- * @returns {string}
189
- */
190
- const localeDateTime = (date, options = {}) =>
191
- time(
192
- {
193
- datetime: date.toISOString(),
194
- "locale-options": encodeURIComponent(JSON.stringify(options)),
195
- },
196
- date.toLocaleString("en", options)
197
- );
198
-
199
- /**
200
- * @param {Date} date
201
- * @param {object} [options = {}]
202
- * @returns {string}
203
- */
204
- const localeDate = (date, options = {}) =>
205
- time(
206
- {
207
- datetime: date.toISOString(),
208
- "locale-date-options": encodeURIComponent(JSON.stringify(options)),
209
- },
210
- date.toLocaleDateString("en", options)
211
- );
212
-
213
- module.exports = {
214
- mkTable,
215
- renderForm,
216
- settingsDropdown,
217
- renderBuilder,
218
- link,
219
- post_btn,
220
- post_delete_btn,
221
- post_dropdown_item,
222
- tabs,
223
- localeTime,
224
- localeDate,
225
- localeDateTime,
226
- };