@operato/form 1.0.0-alpha.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 (61) hide show
  1. package/.editorconfig +29 -0
  2. package/.storybook/main.js +3 -0
  3. package/.storybook/server.mjs +8 -0
  4. package/CHANGELOG.md +11 -0
  5. package/LICENSE +21 -0
  6. package/README.md +75 -0
  7. package/demo/index.html +33 -0
  8. package/dist/src/components/ox-custom-input.d.ts +23 -0
  9. package/dist/src/components/ox-custom-input.js +114 -0
  10. package/dist/src/components/ox-custom-input.js.map +1 -0
  11. package/dist/src/components/ox-custom-select.d.ts +21 -0
  12. package/dist/src/components/ox-custom-select.js +100 -0
  13. package/dist/src/components/ox-custom-select.js.map +1 -0
  14. package/dist/src/components/ox-file-uploader.d.ts +13 -0
  15. package/dist/src/components/ox-file-uploader.js +166 -0
  16. package/dist/src/components/ox-file-uploader.js.map +1 -0
  17. package/dist/src/components/ox-form-master.d.ts +1 -0
  18. package/dist/src/components/ox-form-master.js +208 -0
  19. package/dist/src/components/ox-form-master.js.map +1 -0
  20. package/dist/src/components/ox-form-paginator.d.ts +9 -0
  21. package/dist/src/components/ox-form-paginator.js +70 -0
  22. package/dist/src/components/ox-form-paginator.js.map +1 -0
  23. package/dist/src/components/ox-search-form-paginator.d.ts +1 -0
  24. package/dist/src/components/ox-search-form-paginator.js +51 -0
  25. package/dist/src/components/ox-search-form-paginator.js.map +1 -0
  26. package/dist/src/components/ox-search-form.d.ts +56 -0
  27. package/dist/src/components/ox-search-form.js +284 -0
  28. package/dist/src/components/ox-search-form.js.map +1 -0
  29. package/dist/src/index.d.ts +3 -0
  30. package/dist/src/index.js +4 -0
  31. package/dist/src/index.js.map +1 -0
  32. package/dist/src/styles/index.d.ts +3 -0
  33. package/dist/src/styles/index.js +4 -0
  34. package/dist/src/styles/index.js.map +1 -0
  35. package/dist/src/styles/multi-column-form-styles.d.ts +1 -0
  36. package/dist/src/styles/multi-column-form-styles.js +192 -0
  37. package/dist/src/styles/multi-column-form-styles.js.map +1 -0
  38. package/dist/src/styles/search-form-styles.d.ts +1 -0
  39. package/dist/src/styles/search-form-styles.js +156 -0
  40. package/dist/src/styles/search-form-styles.js.map +1 -0
  41. package/dist/src/styles/single-column-form-styles.d.ts +1 -0
  42. package/dist/src/styles/single-column-form-styles.js +114 -0
  43. package/dist/src/styles/single-column-form-styles.js.map +1 -0
  44. package/dist/tsconfig.tsbuildinfo +1 -0
  45. package/package.json +77 -0
  46. package/src/components/ox-custom-input.ts +102 -0
  47. package/src/components/ox-custom-select.ts +90 -0
  48. package/src/components/ox-file-uploader.ts +163 -0
  49. package/src/components/ox-form-master.ts +241 -0
  50. package/src/components/ox-form-paginator.ts +60 -0
  51. package/src/components/ox-search-form-paginator.ts +46 -0
  52. package/src/components/ox-search-form.ts +317 -0
  53. package/src/index.ts +3 -0
  54. package/src/styles/index.ts +3 -0
  55. package/src/styles/multi-column-form-styles.ts +192 -0
  56. package/src/styles/search-form-styles.ts +156 -0
  57. package/src/styles/single-column-form-styles.ts +114 -0
  58. package/src/themes/form-theme.css +75 -0
  59. package/tsconfig.json +23 -0
  60. package/web-dev-server.config.mjs +27 -0
  61. package/web-test-runner.config.mjs +41 -0
@@ -0,0 +1,208 @@
1
+ import { __decorate } from "tslib";
2
+ import { LitElement, css, html } from 'lit';
3
+ import { customElement, property, query, state } from 'lit/decorators.js';
4
+ let FormMaster = class FormMaster extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.maxRowCount = 2;
8
+ this.maxColumnCount = 4;
9
+ this.loadedCount = 0;
10
+ this.currentPage = 1;
11
+ }
12
+ connectedCallback() {
13
+ super.connectedCallback();
14
+ this.resizeEventHandler = this._adjustColumnProperty.bind(this);
15
+ window.addEventListener('resize', this.resizeEventHandler);
16
+ }
17
+ disconnectedCallback() {
18
+ super.disconnectedCallback();
19
+ if (this.resizeEventHandler) {
20
+ window.removeEventListener('resize', this.resizeEventHandler);
21
+ }
22
+ }
23
+ render() {
24
+ return html `
25
+ <form
26
+ @keypress=${(e) => {
27
+ if (e.keyCode === 13) {
28
+ this.submit();
29
+ }
30
+ }}
31
+ >
32
+ ${(this.fields || []).map(field => html `
33
+ ${field.type === 'select'
34
+ ? html `
35
+ <ox-custom-select
36
+ id=${field.id || field.name}
37
+ name=${field.name || field.id}
38
+ .props=${field.props}
39
+ .attrs=${field.attrs}
40
+ .value=${field.value}
41
+ .autofocus=${this.initFocus === field.name}
42
+ @load=${this._onInputLoad.bind(this)}
43
+ .options=${field.options}
44
+ ></ox-custom-select>
45
+ `
46
+ : html `
47
+ <ox-custom-input
48
+ id=${field.id || field.name}
49
+ name=${field.name || field.id}
50
+ .props=${field.props}
51
+ .attrs=${field.attrs}
52
+ .valueField=${field.valueField}
53
+ .displayField=${field.displayField}
54
+ .value=${field.value}
55
+ .autofocus=${this.initFocus === field.name}
56
+ @load=${this._onInputLoad.bind(this)}
57
+ ></ox-custom-input>
58
+ `}
59
+ `)}
60
+ </form>
61
+
62
+ <form-paginator .pageCount=${this.pageCount} @pageChange=${this._onPageChangeHandler.bind(this)}></form-paginator>
63
+ `;
64
+ }
65
+ updated(changes) {
66
+ if (changes.has('fields')) {
67
+ this._checkInputValidity();
68
+ }
69
+ }
70
+ _checkInputValidity() {
71
+ const names = (this.fields || []).map(i => i.name);
72
+ const result = names.every(name => {
73
+ return names.indexOf(name) === names.lastIndexOf(name);
74
+ });
75
+ if (!result) {
76
+ throw new Error('Field name is duplicated.');
77
+ }
78
+ }
79
+ _onInputLoad() {
80
+ this.loadedCount++;
81
+ if (this.loadedCount === (this.fields || []).length - 1) {
82
+ this._adjustColumnProperty();
83
+ this._initFocus();
84
+ this.dispatchEvent(new CustomEvent('load'));
85
+ }
86
+ }
87
+ getFields() {
88
+ return Array.from(this.form.querySelectorAll('ox-custom-select, ox-custom-input') || []);
89
+ }
90
+ _adjustColumnProperty() {
91
+ const inputElements = this.getFields();
92
+ if (inputElements.length === 0)
93
+ return;
94
+ const inputWidth = inputElements[0].offsetWidth;
95
+ const totalWidth = window.innerWidth;
96
+ const inputCount = inputElements.length;
97
+ let columnCount = Math.floor(totalWidth / inputWidth) < this.maxColumnCount
98
+ ? Math.floor(totalWidth / inputWidth)
99
+ : this.maxColumnCount > inputCount
100
+ ? inputCount
101
+ : this.maxColumnCount;
102
+ if (columnCount === 1) {
103
+ this.pageCount = Math.ceil(inputElements.length / this.maxRowCount);
104
+ this._filterActiveFields(this.currentPage);
105
+ }
106
+ else {
107
+ this.pageCount = 1;
108
+ this._activeFields();
109
+ }
110
+ this.style.setProperty('--form-grid-template-columns', `repeat(${columnCount}, 1fr)`);
111
+ }
112
+ _initFocus() {
113
+ if (!this.initFocus)
114
+ this.getFields()[0].focus();
115
+ }
116
+ getFieldByName(name) {
117
+ return this.renderRoot.querySelector(`[name=${name}]`);
118
+ }
119
+ reset() {
120
+ this.form && this.form.reset();
121
+ }
122
+ submit() {
123
+ this.dispatchEvent(new CustomEvent('submit'));
124
+ }
125
+ focusById(id) {
126
+ const input = this.renderRoot.querySelector(`form > #${id}`);
127
+ input.focus();
128
+ }
129
+ checkValidity() {
130
+ return this.form.checkValidity();
131
+ }
132
+ serialize() {
133
+ let data = {};
134
+ this.getFields().forEach(field => {
135
+ const name = field.name;
136
+ if (name) {
137
+ data[name] = field.value;
138
+ }
139
+ });
140
+ return data;
141
+ }
142
+ get searchParams() {
143
+ let searchParam = new URLSearchParams();
144
+ const data = this.serialize();
145
+ const fields = this.getFields();
146
+ fields.forEach(field => searchParam.append(field.name, field.value));
147
+ return decodeURI(searchParam.toString());
148
+ }
149
+ _onPageChangeHandler(event) {
150
+ this.currentPage = event.currentTarget.currentPage;
151
+ this._filterActiveFields(this.currentPage);
152
+ }
153
+ _activeFields() {
154
+ this.getFields().forEach(field => (field.hidden = false));
155
+ }
156
+ _filterActiveFields(currentPage = 1) {
157
+ if (this.pageCount > 1) {
158
+ const fields = this.getFields();
159
+ const chunkedFields = [];
160
+ for (let i = 0, j = fields.length; i < j; i += this.maxRowCount) {
161
+ chunkedFields.push(fields.slice(i, i + this.maxRowCount));
162
+ }
163
+ chunkedFields.forEach((fields, idx) => {
164
+ if (currentPage === idx + 1) {
165
+ fields.forEach(field => (field.hidden = false));
166
+ }
167
+ else {
168
+ fields.forEach(field => (field.hidden = true));
169
+ }
170
+ });
171
+ }
172
+ }
173
+ };
174
+ FormMaster.styles = css `
175
+ form {
176
+ display: grid;
177
+ padding: var(--form-padding, 10px);
178
+ grid-gap: var(--form-grid-gap, 10px);
179
+ grid-template-columns: var(--form-grid-template-columns);
180
+ background-color: var(--form-background-color, #e5e5e5);
181
+ }
182
+ custom-input,
183
+ custom-select {
184
+ justify-self: center;
185
+ }
186
+ `;
187
+ __decorate([
188
+ property({ type: Array })
189
+ ], FormMaster.prototype, "fields", void 0);
190
+ __decorate([
191
+ property({ type: Number })
192
+ ], FormMaster.prototype, "maxRowCount", void 0);
193
+ __decorate([
194
+ property({ type: Number })
195
+ ], FormMaster.prototype, "maxColumnCount", void 0);
196
+ __decorate([
197
+ property({ type: String })
198
+ ], FormMaster.prototype, "initFocus", void 0);
199
+ __decorate([
200
+ state()
201
+ ], FormMaster.prototype, "pageCount", void 0);
202
+ __decorate([
203
+ query('form')
204
+ ], FormMaster.prototype, "form", void 0);
205
+ FormMaster = __decorate([
206
+ customElement('ox-form-master')
207
+ ], FormMaster);
208
+ //# sourceMappingURL=ox-form-master.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-form-master.js","sourceRoot":"","sources":["../../../src/components/ox-form-master.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, PropertyValues, css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { CustomInput } from './ox-custom-input.js'\nimport { CustomSelect } from './ox-custom-select.js'\nimport { FormPaginator } from './ox-form-paginator.js'\n\n@customElement('ox-form-master')\nclass FormMaster extends LitElement {\n static styles = css`\n form {\n display: grid;\n padding: var(--form-padding, 10px);\n grid-gap: var(--form-grid-gap, 10px);\n grid-template-columns: var(--form-grid-template-columns);\n background-color: var(--form-background-color, #e5e5e5);\n }\n custom-input,\n custom-select {\n justify-self: center;\n }\n `\n\n @property({ type: Array }) fields?: {\n type: string\n hidden: boolean\n name: string\n id: string\n label: string\n placeholder: string\n value: any\n field: string\n queryName: string\n props: { [prop: string]: string }\n attrs: string[]\n valueField?: string\n displayField?: string\n options: { name: string; value: string }[]\n }[]\n @property({ type: Number }) maxRowCount: number = 2\n @property({ type: Number }) maxColumnCount: number = 4\n @property({ type: String }) initFocus?: string\n\n @state() private pageCount!: number\n\n @query('form') form!: HTMLFormElement\n\n private loadedCount: number = 0\n private resizeEventHandler?: EventListener\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.resizeEventHandler = this._adjustColumnProperty.bind(this)\n window.addEventListener('resize', this.resizeEventHandler)\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback()\n\n if (this.resizeEventHandler) {\n window.removeEventListener('resize', this.resizeEventHandler)\n }\n }\n\n render() {\n return html`\n <form\n @keypress=${(e: KeyboardEvent) => {\n if (e.keyCode === 13) {\n this.submit()\n }\n }}\n >\n ${(this.fields || []).map(\n field => html`\n ${field.type === 'select'\n ? html`\n <ox-custom-select\n id=${field.id || field.name}\n name=${field.name || field.id}\n .props=${field.props}\n .attrs=${field.attrs}\n .value=${field.value}\n .autofocus=${this.initFocus === field.name}\n @load=${this._onInputLoad.bind(this)}\n .options=${field.options}\n ></ox-custom-select>\n `\n : html`\n <ox-custom-input\n id=${field.id || field.name}\n name=${field.name || field.id}\n .props=${field.props}\n .attrs=${field.attrs}\n .valueField=${field.valueField}\n .displayField=${field.displayField}\n .value=${field.value}\n .autofocus=${this.initFocus === field.name}\n @load=${this._onInputLoad.bind(this)}\n ></ox-custom-input>\n `}\n `\n )}\n </form>\n\n <form-paginator .pageCount=${this.pageCount} @pageChange=${this._onPageChangeHandler.bind(this)}></form-paginator>\n `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('fields')) {\n this._checkInputValidity()\n }\n }\n\n _checkInputValidity() {\n const names = (this.fields || []).map(i => i.name)\n const result = names.every(name => {\n return names.indexOf(name) === names.lastIndexOf(name)\n })\n if (!result) {\n throw new Error('Field name is duplicated.')\n }\n }\n\n _onInputLoad() {\n this.loadedCount++\n if (this.loadedCount === (this.fields || []).length - 1) {\n this._adjustColumnProperty()\n this._initFocus()\n this.dispatchEvent(new CustomEvent('load'))\n }\n }\n\n getFields(): (CustomInput | CustomSelect)[] {\n return Array.from(this.form.querySelectorAll('ox-custom-select, ox-custom-input') || [])\n }\n\n private currentPage: number = 1\n\n _adjustColumnProperty() {\n const inputElements = this.getFields()\n\n if (inputElements.length === 0) return\n const inputWidth = inputElements[0].offsetWidth\n const totalWidth = window.innerWidth\n const inputCount = inputElements.length\n let columnCount =\n Math.floor(totalWidth / inputWidth) < this.maxColumnCount\n ? Math.floor(totalWidth / inputWidth)\n : this.maxColumnCount > inputCount\n ? inputCount\n : this.maxColumnCount\n\n if (columnCount === 1) {\n this.pageCount = Math.ceil(inputElements.length / this.maxRowCount)\n this._filterActiveFields(this.currentPage)\n } else {\n this.pageCount = 1\n this._activeFields()\n }\n\n this.style.setProperty('--form-grid-template-columns', `repeat(${columnCount}, 1fr)`)\n }\n\n _initFocus() {\n if (!this.initFocus) this.getFields()[0].focus()\n }\n\n getFieldByName(name: string) {\n return this.renderRoot.querySelector(`[name=${name}]`)\n }\n\n reset() {\n this.form && this.form.reset()\n }\n\n submit() {\n this.dispatchEvent(new CustomEvent('submit'))\n }\n\n focusById(id: string) {\n const input = this.renderRoot.querySelector(`form > #${id}`) as CustomInput | CustomSelect\n input.focus()\n }\n\n checkValidity() {\n return this.form.checkValidity()\n }\n\n serialize() {\n let data: { [name: string]: any } = {}\n\n this.getFields().forEach(field => {\n const name = field.name\n if (name) {\n data[name] = field.value\n }\n })\n\n return data\n }\n\n get searchParams() {\n let searchParam = new URLSearchParams()\n const data = this.serialize()\n const fields = this.getFields()\n fields.forEach(field => searchParam.append(field.name!, field.value))\n\n return decodeURI(searchParam.toString())\n }\n\n _onPageChangeHandler(event: Event) {\n this.currentPage = (event.currentTarget as FormPaginator).currentPage\n this._filterActiveFields(this.currentPage)\n }\n\n _activeFields() {\n this.getFields().forEach(field => (field.hidden = false))\n }\n\n _filterActiveFields(currentPage = 1) {\n if (this.pageCount > 1) {\n const fields = this.getFields()\n\n const chunkedFields = []\n for (let i = 0, j = fields.length; i < j; i += this.maxRowCount) {\n chunkedFields.push(fields.slice(i, i + this.maxRowCount))\n }\n\n chunkedFields.forEach((fields, idx) => {\n if (currentPage === idx + 1) {\n fields.forEach(field => (field.hidden = false))\n } else {\n fields.forEach(field => (field.hidden = true))\n }\n })\n }\n }\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { LitElement, PropertyValues } from 'lit';
2
+ export declare class FormPaginator extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ pageCount: number;
5
+ selectors: number[];
6
+ currentPage: number;
7
+ render(): import("lit-html").TemplateResult<1>;
8
+ updated(changes: PropertyValues<this>): void;
9
+ }
@@ -0,0 +1,70 @@
1
+ import { __decorate } from "tslib";
2
+ import { LitElement, css, html } from 'lit';
3
+ import { customElement, property, state } from 'lit/decorators.js';
4
+ let FormPaginator = class FormPaginator extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.pageCount = 1;
8
+ this.selectors = [];
9
+ this.currentPage = 1;
10
+ }
11
+ render() {
12
+ return html `
13
+ ${this.selectors.map(page => html `
14
+ <span
15
+ page=${page}
16
+ ?selected=${page == this.currentPage}
17
+ @click=${(e) => {
18
+ this.currentPage = page;
19
+ this.dispatchEvent(new CustomEvent('pageChange'));
20
+ this.requestUpdate();
21
+ }}
22
+ >&bull;</span
23
+ >
24
+ `)}
25
+ `;
26
+ }
27
+ updated(changes) {
28
+ if (changes.has('pageCount')) {
29
+ if (this.pageCount > 1) {
30
+ let i = 1;
31
+ this.selectors = [];
32
+ while (i <= this.pageCount) {
33
+ this.selectors.push(i);
34
+ i++;
35
+ }
36
+ }
37
+ else {
38
+ this.selectors = [];
39
+ }
40
+ }
41
+ }
42
+ };
43
+ FormPaginator.styles = css `
44
+ :host {
45
+ display: block;
46
+ background-color: var(--form-background-color, #e5e5e5);
47
+ font-size: 1.5em;
48
+ line-height: 0.5em;
49
+ text-align: center;
50
+ color: #c4c5c6;
51
+ }
52
+
53
+ [selected] {
54
+ color: #6f6f6f;
55
+ }
56
+ `;
57
+ __decorate([
58
+ property({ type: Number })
59
+ ], FormPaginator.prototype, "pageCount", void 0);
60
+ __decorate([
61
+ property({ type: Array })
62
+ ], FormPaginator.prototype, "selectors", void 0);
63
+ __decorate([
64
+ state()
65
+ ], FormPaginator.prototype, "currentPage", void 0);
66
+ FormPaginator = __decorate([
67
+ customElement('form-paginator')
68
+ ], FormPaginator);
69
+ export { FormPaginator };
70
+ //# sourceMappingURL=ox-form-paginator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-form-paginator.js","sourceRoot":"","sources":["../../../src/components/ox-form-paginator.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAkB,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGlE,IAAa,aAAa,GAA1B,MAAa,aAAc,SAAQ,UAAU;IAA7C;;QAgB8B,cAAS,GAAW,CAAC,CAAA;QACtB,cAAS,GAAa,EAAE,CAAA;QAEnC,gBAAW,GAAW,CAAC,CAAA;IAoCzC,CAAC;IAlCC,MAAM;QACJ,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,SAAS,CAAC,GAAG,CAClB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAA;;mBAED,IAAI;wBACC,IAAI,IAAI,IAAI,CAAC,WAAW;qBAC3B,CAAC,CAAa,EAAE,EAAE;YACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;YACvB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,YAAY,CAAC,CAAC,CAAA;YACjD,IAAI,CAAC,aAAa,EAAE,CAAA;QACtB,CAAC;;;SAGJ,CACF;KACF,CAAA;IACH,CAAC;IAED,OAAO,CAAC,OAA6B;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;YAC5B,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE;gBACtB,IAAI,CAAC,GAAG,CAAC,CAAA;gBACT,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;gBAEnB,OAAO,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;oBAC1B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;oBACtB,CAAC,EAAE,CAAA;iBACJ;aACF;iBAAM;gBACL,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;aACpB;SACF;IACH,CAAC;CACF,CAAA;AAtDQ,oBAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;GAalB,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDAAsB;AACtB;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;gDAAyB;AAE1C;IAAR,KAAK,EAAE;kDAA+B;AAnB5B,aAAa;IADzB,aAAa,CAAC,gBAAgB,CAAC;GACnB,aAAa,CAuDzB;SAvDY,aAAa","sourcesContent":["import { LitElement, PropertyValues, css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\n@customElement('form-paginator')\nexport class FormPaginator extends LitElement {\n static styles = css`\n :host {\n display: block;\n background-color: var(--form-background-color, #e5e5e5);\n font-size: 1.5em;\n line-height: 0.5em;\n text-align: center;\n color: #c4c5c6;\n }\n\n [selected] {\n color: #6f6f6f;\n }\n `\n\n @property({ type: Number }) pageCount: number = 1\n @property({ type: Array }) selectors: number[] = []\n\n @state() public currentPage: number = 1\n\n render() {\n return html`\n ${this.selectors.map(\n page => html`\n <span\n page=${page}\n ?selected=${page == this.currentPage}\n @click=${(e: MouseEvent) => {\n this.currentPage = page\n this.dispatchEvent(new CustomEvent('pageChange'))\n this.requestUpdate()\n }}\n >&bull;</span\n >\n `\n )}\n `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('pageCount')) {\n if (this.pageCount > 1) {\n let i = 1\n this.selectors = []\n\n while (i <= this.pageCount) {\n this.selectors.push(i)\n i++\n }\n } else {\n this.selectors = []\n }\n }\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,51 @@
1
+ import { __decorate } from "tslib";
2
+ import { LitElement, css, html } from 'lit';
3
+ import { customElement, property } from 'lit/decorators.js';
4
+ let SearchFormPaginator = class SearchFormPaginator extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.pageCount = 0;
8
+ this.currentPage = 0;
9
+ }
10
+ render() {
11
+ return html `
12
+ ${Array(this.pageCount)
13
+ .fill('')
14
+ .map((_, page) => html `
15
+ <span
16
+ ?selected=${page == this.currentPage}
17
+ @click=${(e) => this.dispatchEvent(new CustomEvent('pagechanged', {
18
+ detail: {
19
+ page
20
+ }
21
+ }))}
22
+ >&bull;</span
23
+ >
24
+ `)}
25
+ `;
26
+ }
27
+ };
28
+ SearchFormPaginator.styles = css `
29
+ :host {
30
+ display: block;
31
+ background-color: var(--form-background-color, #e5e5e5);
32
+ font-size: 1.5em;
33
+ line-height: 0.5em;
34
+ text-align: center;
35
+ color: #c4c5c6;
36
+ }
37
+
38
+ [selected] {
39
+ color: #6f6f6f;
40
+ }
41
+ `;
42
+ __decorate([
43
+ property({ type: Number })
44
+ ], SearchFormPaginator.prototype, "pageCount", void 0);
45
+ __decorate([
46
+ property({ type: Number })
47
+ ], SearchFormPaginator.prototype, "currentPage", void 0);
48
+ SearchFormPaginator = __decorate([
49
+ customElement('ox-search-form-paginator')
50
+ ], SearchFormPaginator);
51
+ //# sourceMappingURL=ox-search-form-paginator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-search-form-paginator.js","sourceRoot":"","sources":["../../../src/components/ox-search-form-paginator.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG3D,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,UAAU;IAA5C;;QAgB8B,cAAS,GAAW,CAAC,CAAA;QACrB,gBAAW,GAAW,CAAC,CAAA;IAwBrD,CAAC;IAtBC,MAAM;QACJ,OAAO,IAAI,CAAA;QACP,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;aACpB,IAAI,CAAC,EAAE,CAAC;aACR,GAAG,CACF,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAA;;0BAED,IAAI,IAAI,IAAI,CAAC,WAAW;uBAC3B,CAAC,CAAa,EAAE,EAAE,CACzB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,aAAa,EAAE;YAC7B,MAAM,EAAE;gBACN,IAAI;aACL;SACF,CAAC,CACH;;;WAGN,CACF;KACJ,CAAA;IACH,CAAC;CACF,CAAA;AAxCQ,0BAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;GAalB,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAAsB;AACrB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wDAAwB;AAjB/C,mBAAmB;IADxB,aAAa,CAAC,0BAA0B,CAAC;GACpC,mBAAmB,CAyCxB","sourcesContent":["import { LitElement, css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n@customElement('ox-search-form-paginator')\nclass SearchFormPaginator extends LitElement {\n static styles = css`\n :host {\n display: block;\n background-color: var(--form-background-color, #e5e5e5);\n font-size: 1.5em;\n line-height: 0.5em;\n text-align: center;\n color: #c4c5c6;\n }\n\n [selected] {\n color: #6f6f6f;\n }\n `\n\n @property({ type: Number }) pageCount: number = 0\n @property({ type: Number }) currentPage: number = 0\n\n render() {\n return html`\n ${Array(this.pageCount)\n .fill('')\n .map(\n (_, page) => html`\n <span\n ?selected=${page == this.currentPage}\n @click=${(e: MouseEvent) =>\n this.dispatchEvent(\n new CustomEvent('pagechanged', {\n detail: {\n page\n }\n })\n )}\n >&bull;</span\n >\n `\n )}\n `\n }\n}\n"]}
@@ -0,0 +1,56 @@
1
+ import '@material/mwc-icon';
2
+ import './ox-custom-input.js';
3
+ import './ox-custom-select.js';
4
+ import { LitElement, PropertyValues } from 'lit';
5
+ export declare class SearchForm extends LitElement {
6
+ static styles: import("lit").CSSResult[];
7
+ fields?: {
8
+ type: string;
9
+ hidden: boolean;
10
+ name: string;
11
+ id: string;
12
+ label: string;
13
+ placeholder: string;
14
+ value: any;
15
+ field: string;
16
+ queryName: string;
17
+ props: {
18
+ [prop: string]: string;
19
+ };
20
+ attrs: string[];
21
+ options: {
22
+ name: string;
23
+ value: string;
24
+ }[];
25
+ handlers: {
26
+ [event: string]: EventListener;
27
+ };
28
+ }[];
29
+ hideSearchButton: boolean;
30
+ form: HTMLFormElement;
31
+ formFields: ((HTMLInputElement | HTMLSelectElement) & {
32
+ field: string;
33
+ _value: any;
34
+ })[];
35
+ getFields(): Element[];
36
+ render(): import("lit-html").TemplateResult<1>;
37
+ updated(changes: PropertyValues<this>): Promise<void>;
38
+ _checkInputValidity(): void;
39
+ get searchParams(): string;
40
+ get queryFilters(): {
41
+ name: string;
42
+ value: string | number | boolean;
43
+ operator: string;
44
+ }[];
45
+ getQueryFilters(): Promise<{
46
+ name: string;
47
+ operator: string;
48
+ value: string | number | boolean | string[] | undefined;
49
+ relation: boolean;
50
+ }[]>;
51
+ private _getResourceIds;
52
+ serialize(): {
53
+ [name: string]: any;
54
+ };
55
+ submit(): void;
56
+ }