@pageboard/html 0.11.25 → 0.11.26

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/elements/form.js CHANGED
@@ -168,7 +168,7 @@ exports.api_form = {
168
168
  tag: 'form[method="post"]',
169
169
  html: `<form is="element-form" method="post" name="[name]"
170
170
  action="/.api/form/[$id]"
171
- parameters="[$expr.action.parameters|ornull|templates:$query]"
171
+ parameters="[$expr.action.parameters|templates:$query]"
172
172
  success="[redirection|urltpl:url:parameters]"
173
173
  badrequest="[badrequest|urltpl:url:parameters]"
174
174
  unauthorized="[unauthorized|urltpl:url:parameters]"
@@ -76,7 +76,7 @@ exports.strike = {
76
76
  contents: "text*",
77
77
  inline: true,
78
78
  inplace: true,
79
- group: "inline nolink",
79
+ group: "nolink",
80
80
  tag: 's',
81
81
  html: '<s></s>'
82
82
  };
@@ -0,0 +1,35 @@
1
+ exports.pagination = {
2
+ priority: 13, // after fetch and after menu items
3
+ title: "Pagination",
4
+ icon: '<b class="icon">±N</b>',
5
+ menu: "link",
6
+ group: "block",
7
+ isolating: true,
8
+ properties: {
9
+ fetch: {
10
+ title: 'Fetch block',
11
+ type: 'string',
12
+ format: 'id',
13
+ $filter: {
14
+ name: 'block',
15
+ types: ["fetch"]
16
+ }
17
+ },
18
+ dir: {
19
+ title: 'Direction',
20
+ anyOf: [{
21
+ const: '-',
22
+ title: 'Backward'
23
+ }, {
24
+ const: '+',
25
+ title: 'Forward'
26
+ }],
27
+ default: '+'
28
+ },
29
+ },
30
+ contents: "inline*",
31
+ html: `<a class="ui button pagination" is="element-pagination" data-dir="[dir]" data-fetch="[fetch]">[dir|eq:1:Next:Prev]</a>`,
32
+ scripts: [
33
+ '../ui/pagination.js'
34
+ ]
35
+ };
@@ -0,0 +1,30 @@
1
+ exports.query_tags = {
2
+ priority: 10, // after fetch
3
+ title: 'Tags',
4
+ icon: '<i class="tags icon"></i>',
5
+ menu: "form",
6
+ group: "block",
7
+ properties: {
8
+ form: {
9
+ title: 'Form name',
10
+ type: 'string',
11
+ format: 'id',
12
+ nullable: true
13
+ }
14
+ },
15
+ contents: {
16
+ id: 'title',
17
+ nodes: 'inline*'
18
+ },
19
+ html: `<element-query-tags for="[form]">
20
+ <div block-content="title">Filters:</div>
21
+ <div class="ui labels"></div>
22
+ </element-query-tags>`,
23
+ stylesheets: [
24
+ '../lib/components/label.css',
25
+ '../ui/query-tags.css'
26
+ ],
27
+ scripts: [
28
+ '../ui/query-tags.js'
29
+ ]
30
+ };
@@ -1,82 +1,21 @@
1
- exports.fetch.install = function() {
2
- this.dom.classList.add('ui');
3
- };
4
- exports.message.install = function(node, d, scope) {
5
- this.dom.classList.add('ui', '[inverted|?]');
6
- };
1
+ exports.fetch.fragments.push({
2
+ attributes: {
3
+ className: "ui"
4
+ }
5
+ });
6
+
7
+ exports.message.fragments.push({
8
+ attributes: {
9
+ className: '[inverted|?]'
10
+ }
11
+ });
12
+
7
13
  exports.message.properties.inverted = {
8
14
  title: 'Inverted',
9
15
  type: 'boolean',
10
16
  default: false
11
17
  };
18
+
12
19
  exports.message.stylesheets.unshift(
13
20
  '../lib/components/message.css'
14
21
  );
15
-
16
- exports.query_tags = {
17
- priority: 10, // after fetch
18
- title: 'Tags',
19
- icon: '<i class="tags icon"></i>',
20
- menu: "form",
21
- group: "block",
22
- properties: {
23
- form: {
24
- title: 'Form name',
25
- type: 'string',
26
- format: 'id',
27
- nullable: true
28
- }
29
- },
30
- contents: {
31
- id: 'title',
32
- nodes: 'inline*'
33
- },
34
- html: `<element-query-tags for="[form]">
35
- <div block-content="title">Filters:</div>
36
- <div class="ui labels"></div>
37
- </element-query-tags>`,
38
- stylesheets: [
39
- '../lib/components/label.css',
40
- '../ui/query-tags.css'
41
- ],
42
- scripts: [
43
- '../ui/query-tags.js'
44
- ]
45
- };
46
-
47
- exports.pagination = {
48
- priority: 13, // after fetch and after menu items
49
- title: "Pagination",
50
- icon: '<b class="icon">±N</b>',
51
- menu: "link",
52
- context: 'menu//',
53
- group: "menu_item",
54
- properties: {
55
- name: {
56
- title: 'Offset name',
57
- description: 'Query parameter used by fetch block',
58
- type: 'string',
59
- format: 'id',
60
- default: 'offset'
61
- },
62
- value: {
63
- title: 'Offset value',
64
- description: 'Integer, can be negative',
65
- type: 'integer',
66
- default: 10
67
- },
68
- infinite: {
69
- title: 'Infinite loading',
70
- type: 'boolean',
71
- default: false
72
- }
73
- },
74
- contents: "inline*",
75
- html: `<a class="item" is="element-pagination" data-name="[name]" data-value="[value]" data-infinite="[infinite]"></a>`,
76
- stylesheets: [
77
- '../ui/pagination.css'
78
- ],
79
- scripts: [
80
- '../ui/pagination.js'
81
- ]
82
- };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pageboard/html",
3
- "version": "0.11.25",
3
+ "version": "0.11.26",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "repository": {
package/ui/pagination.js CHANGED
@@ -1,127 +1,49 @@
1
1
  class HTMLElementPagination extends HTMLAnchorElement {
2
- #observer;
3
- #queue;
4
- #reached;
5
- #size;
6
- #visible;
7
- #continue;
8
-
9
- constructor() {
10
- super();
11
- this.init?.();
12
- }
13
-
14
2
  patch(state) {
15
- if (this.isContentEditable || this.closest('[block-content="template"]')) {
16
- return;
17
- }
18
- const name = this.dataset.name || 'offset';
19
- const off = parseInt(state.query[name]) || 0;
20
- const delta = parseInt(this.dataset.value) || 0;
21
- const cur = off + delta;
22
- const disabled = cur < 0 || !this.#findFetch() || this.#continue && delta < 0 || false;
23
- this.classList.toggle('disabled', disabled);
24
-
25
- if (disabled) {
26
- this.removeAttribute('href');
27
- } else {
28
- this.setAttribute('href', Page.format({
29
- pathname: state.pathname,
30
- query: {
31
- ...state.query,
32
- [name]: cur || undefined
33
- }
34
- }));
35
- }
3
+ if (this.isContentEditable) return;
36
4
  state.finish(() => {
37
- this.#reached = false;
38
- if (this.#updateFetchSize() == false) {
39
- this.removeAttribute('href');
40
- this.classList.toggle('disabled', true);
41
- } else {
42
- this.#continue = true;
43
- }
44
- });
45
- }
46
-
47
- #more(state) {
48
- this.#reached = true;
49
- if (this.#queue) this.#queue = this.#queue.then(() => {
50
- if (!this.#continue || !this.hasAttribute('href')) {
51
- return;
52
- }
53
- const fetch = this.#findFetch();
54
- if (fetch) {
55
- fetch.infinite = true;
56
- return state.push(this.getAttribute('href'));
57
- }
58
- }).then(() => {
59
- this.#reached = false;
5
+ this.#update(state);
60
6
  });
61
7
  }
62
8
 
63
- #updateFetchSize() {
64
- const old = this.#size;
65
- const cur = this.#size = this.#findFetch()?.ownView.children.length ?? 0;
66
- if (this.#continue) return old != cur;
67
- else return cur != 0;
68
- }
69
-
70
- #findFetch() {
71
- const name = this.dataset.name || 'offset';
72
- const fetch = this.ownerDocument.querySelector(
73
- `element-template[block-type="fetch"][parameters~="$query.${name}|or:0"]`
9
+ #update(state) {
10
+ const node = this.ownerDocument.querySelector(
11
+ `element-template[action="/.api/query/${this.dataset.fetch}"]`
74
12
  );
75
- if (!fetch) {
76
- console.warn(`Pagination need Fetch to use $query.${name} parameter`);
13
+ if (!node) {
14
+ console.warn("pagination does not find fetch node", this.dataset.fetch);
15
+ return;
77
16
  }
78
- return fetch;
79
- }
80
-
81
- handleClick(e, state) {
82
- const fetch = this.#findFetch();
83
- if (fetch) fetch.infinite = false;
17
+ const name = node.dataset.pagination;
18
+ const start = parseInt(node.dataset.start) || 0;
19
+ const stop = parseInt(node.dataset.stop) || 0;
20
+ const limit = parseInt(node.dataset.limit) || 10;
21
+ const count = parseInt(node.dataset.count) || 0;
22
+ const sign = this.dataset.dir == "-" ? -1 : +1;
23
+ const cur = sign > 0 ? stop : (start - limit);
24
+
25
+ this.setAttribute('href', Page.format({
26
+ pathname: state.pathname,
27
+ query: {
28
+ ...state.query,
29
+ [name]: cur || undefined
30
+ }
31
+ }));
32
+ this.disabled = sign < 0 && cur + limit <= 0 || sign > 0 && count < limit;
84
33
  }
85
-
86
- paint(state) {
87
- const name = this.dataset.name || 'offset';
88
- const off = parseInt(state.query[name]) || 0;
89
- if (off == 0) {
90
- this.#continue = true;
91
- if (this.#visible) this.#more(state);
34
+ handleClick(e) {
35
+ if (this.disabled) {
36
+ e.preventDefault();
37
+ e.stopImmediatePropagation();
92
38
  }
93
39
  }
94
40
 
95
- setup(state) {
96
- if (this.isContentEditable || !this.#infinite) return;
97
- this.#queue = Promise.resolve();
98
- this.#observer = new IntersectionObserver(entries => {
99
- entries.forEach(entry => {
100
- if (this.#reached) return;
101
- if (this.offsetParent && (entry.intersectionRatio || 0) !== 0) {
102
- this.#visible = true;
103
- this.#more(state);
104
- } else {
105
- this.#visible = false;
106
- }
107
- });
108
- }, {
109
- threshold: [1]
110
- });
111
- this.#observer.observe(this);
112
- }
113
-
114
- close() {
115
- this.#queue = null;
116
- if (this.#observer) {
117
- this.#observer.unobserve(this);
118
- this.#observer.disconnect();
119
- this.#observer = null;
120
- }
41
+ set disabled(val) {
42
+ this.classList.toggle('disabled', val);
121
43
  }
122
44
 
123
- get #infinite() {
124
- return this.hasAttribute('data-infinite');
45
+ get disabled() {
46
+ return this.classList.contains('disabled');
125
47
  }
126
48
  }
127
49
 
package/ui/site.css CHANGED
@@ -293,6 +293,8 @@ body .ui.inverted::-webkit-scrollbar-thumb:hover {
293
293
  }
294
294
  .ui.grid.full {
295
295
  width: 100% !important;
296
+ margin-left: auto !important;
297
+ margin-right: auto !important;
296
298
  }
297
299
 
298
300
  /* for editor only, but semantic-ui dependent */
package/ui/pagination.css DELETED
@@ -1,3 +0,0 @@
1
- a[is="element-pagination"].disabled {
2
- display: none !important;
3
- }