kempo-ui 0.0.77 → 0.0.79
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/.github/skills/highlight-code/SKILL.md +17 -30
- package/bin/highlight_code.js +34 -7
- package/dist/components/Table.js +120 -77
- package/dist/components/tableControls/DeleteSelected.js +7 -0
- package/docs/components/table.html +2 -1
- package/docs/components/tableServerSync.html +143 -0
- package/docs/icons/delete_sweep.svg +1 -0
- package/docs/src/components/Table.js +120 -77
- package/docs/src/components/tableControls/DeleteSelected.js +7 -0
- package/icons/delete_sweep.svg +1 -0
- package/package.json +2 -1
- package/src/components/Table.js +270 -253
- package/src/components/tableControls/DeleteSelected.js +27 -0
|
@@ -11,47 +11,34 @@ Use this skill whenever you need syntax-highlighted HTML to embed in a documenta
|
|
|
11
11
|
|
|
12
12
|
## Usage
|
|
13
13
|
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Or via npx:
|
|
19
|
-
```bash
|
|
20
|
-
npx kempo-highlightcode <lang> "<code>"
|
|
14
|
+
```powershell
|
|
15
|
+
node bin/highlight_code.js <lang> <code>
|
|
21
16
|
```
|
|
22
17
|
|
|
23
18
|
**Supported languages:** `html`, `css`, `js` / `javascript`, `ts` / `typescript`, `json`, `md` / `markdown`, `sh` / `bash`, `xml`
|
|
24
19
|
|
|
25
20
|
## Output
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
## Example
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
npm run highlightcode -- html "<p>Hello World</p>"
|
|
33
|
-
```
|
|
22
|
+
Prints the inner highlighted content (hljs spans, no `<pre><code>` wrapper) to stdout, with `<br>` tags instead of newlines — a single line suitable for embedding in HTML.
|
|
34
23
|
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
<span class="hljs-tag"><<span class="hljs-name">p</span>></span>Hello World<span class="hljs-tag"></<span class="hljs-name">p</span>></span>
|
|
38
|
-
```
|
|
24
|
+
Input is automatically beautified before highlighting, so you can pass minified code.
|
|
39
25
|
|
|
40
|
-
##
|
|
26
|
+
## Workflow for Updating Doc Code Samples
|
|
41
27
|
|
|
42
|
-
|
|
28
|
+
Run the script with minified code as a single argument, capture to `$hl`, then use PowerShell's `.Replace()` to patch the HTML file:
|
|
43
29
|
|
|
44
30
|
```powershell
|
|
45
|
-
$
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"@
|
|
50
|
-
node bin/highlight_code.js js $code
|
|
31
|
+
$hl = node bin/highlight_code.js xml "<k-table id=myExample></k-table><script type=module>doSomething('foo');</script>"
|
|
32
|
+
$html = [System.IO.File]::ReadAllText((Resolve-Path 'docs/components/my-component.html'))
|
|
33
|
+
$old = [regex]::Match($html, '(?s)<pre><code class="hljs xml">.*?</code></pre>').Value
|
|
34
|
+
[System.IO.File]::WriteAllText((Resolve-Path 'docs/components/my-component.html'), $html.Replace($old, "<pre><code class=`"hljs xml`">$hl</code></pre>"))
|
|
51
35
|
```
|
|
52
36
|
|
|
53
|
-
##
|
|
37
|
+
## Important Notes
|
|
54
38
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
39
|
+
- Use **outer double-quotes** for the PowerShell argument string, and **single-quotes** for JS string literals inside. This preserves all quoting correctly through to node.
|
|
40
|
+
- HTML attribute values should be **unquoted** in the argument (`id=foo` not `id="foo"`) — the beautifier adds consistent formatting anyway.
|
|
41
|
+
- Use `[System.IO.File]::ReadAllText` / `WriteAllText` + `.Replace()` (not `-replace`) to avoid regex interpretation of the replacement string.
|
|
42
|
+
- If a page has multiple `<pre><code>` blocks, adjust the regex to match the specific one (e.g. match by a nearby unique string, or loop with an index).
|
|
43
|
+
- The beautifier handles indentation and formatting automatically.
|
|
44
|
+
- Output uses `<br>` instead of `\n`, keeping the block on one line in the HTML source.
|
package/bin/highlight_code.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { highlight } from '../tools/highlight.js';
|
|
3
|
+
import beautify from 'js-beautify';
|
|
3
4
|
|
|
4
5
|
const LANG_ALIASES = {
|
|
5
6
|
js: 'javascript',
|
|
@@ -16,11 +17,17 @@ const LANG_ALIASES = {
|
|
|
16
17
|
markdown: 'markdown'
|
|
17
18
|
};
|
|
18
19
|
|
|
20
|
+
const BEAUTIFY_OPTIONS = {
|
|
21
|
+
indent_size: 2,
|
|
22
|
+
wrap_line_length: 0,
|
|
23
|
+
preserve_newlines: false,
|
|
24
|
+
max_preserve_newlines: 0
|
|
25
|
+
};
|
|
26
|
+
|
|
19
27
|
const args = process.argv.slice(2);
|
|
20
28
|
|
|
21
|
-
if(args.length <
|
|
22
|
-
console.error('Usage:
|
|
23
|
-
console.error('Example: kempo-highlightcode html "<p>Hello World</p>"');
|
|
29
|
+
if(args.length < 1){
|
|
30
|
+
console.error('Usage: node bin/highlight_code.js <lang> <code>');
|
|
24
31
|
process.exit(1);
|
|
25
32
|
}
|
|
26
33
|
|
|
@@ -33,7 +40,27 @@ if(!lang){
|
|
|
33
40
|
process.exit(1);
|
|
34
41
|
}
|
|
35
42
|
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
const beautifyCode = (code) => {
|
|
44
|
+
const fns = { javascript: beautify.js, css: beautify.css, html: beautify.html, xml: beautify.html };
|
|
45
|
+
const fn = fns[lang] || beautify.js;
|
|
46
|
+
return fn(code, BEAUTIFY_OPTIONS);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const run = (code) => {
|
|
50
|
+
const formatted = beautifyCode(code);
|
|
51
|
+
const full = highlight(formatted, lang);
|
|
52
|
+
process.stdout.write(
|
|
53
|
+
full
|
|
54
|
+
.replace(/^<pre><code class="hljs [^"]*">/, '')
|
|
55
|
+
.replace(/<\/code><\/pre>\n?$/, '')
|
|
56
|
+
.replace(/\n/g, '<br>') + '\n'
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
if(rest.length > 0){
|
|
61
|
+
run(rest.join(' '));
|
|
62
|
+
} else {
|
|
63
|
+
const chunks = [];
|
|
64
|
+
process.stdin.on('data', chunk => chunks.push(chunk));
|
|
65
|
+
process.stdin.on('end', () => run(chunks.join('')));
|
|
66
|
+
}
|
package/dist/components/Table.js
CHANGED
|
@@ -1,65 +1,64 @@
|
|
|
1
|
-
import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import{toTitleCase}from"../utils/string.js";import{boolExists}from"../utils/propConverters.js";const selected=Symbol("selected"),hidden=Symbol("hidden"),index=Symbol("index"),editing=Symbol("editing");export default class Table extends ShadowComponent{static properties={enablePages:{type:Boolean,reflect:!0,converter:boolExists,attribute:"enable-pages"},pageSize:{type:Number,reflect:!0,attribute:"page-size"},currentPage:{type:Number,reflect:!0,attribute:"current-page"},pageSizeOptions:{type:Array,attribute:"page-size-options"},enableSelection:{type:Boolean,reflect:!0,converter:boolExists,attribute:"enable-selection"},enableSorting:{type:Boolean,reflect:!0,converter:boolExists,attribute:"enable-sorting"},caseSensitiveFilters:{type:Boolean,reflect:!0,converter:boolExists,attribute:"case-sensitive-filters"},fields:{type:Array},records:{type:Array},filters:{type:Array},sort:{type:Array},columnSizes:{type:Object},fetchPending:{type:Boolean}};constructor(e={}){super(),void 0===this.pageSize&&(this.pageSize=50),void 0===this.currentPage&&(this.currentPage=1),void 0===this.pageSizeOptions&&(this.pageSizeOptions=[10,25,50,100,500]),void 0===this.records&&(this.records=e.records||[]),void 0===this.fields&&(this.fields=e.fields||[]),void 0===this.filters&&(this.filters=e.filters||[]),void 0===this.sort&&(this.sort=[]),void 0===this.columnSizes&&(this.columnSizes={}),void 0===this.fetchPending&&(this.fetchPending=!1)}handleSelectAllChange=e=>{e.target.checked?this.selectAllOnPage():this.deselectAllOnPage()};handleFieldClick=e=>{const t=this.sort.find(t=>t.name===e),s=!t||!t.asc;this.sortBy(e,s)};handleRecordSelectionChange=(e,t)=>{e[selected]=!!t.target.checked,this.requestUpdate(),this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0}))};firstUpdated(){this.setData({records:this.records,fields:this.fields,filters:this.filters})}childrenUpdated(){this.requestUpdate()}updated(e){if(super.updated(e),this.enableSelection){const e=this.shadowRoot.getElementById("select-all");e&&(e.checked=this.allOnPageSelected())}
|
|
2
|
-
<
|
|
3
|
-
<input
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
`),this.hasBeforeControls()&&e.push(html`
|
|
10
|
-
<div class="field cell field-before-controls" style="width: ${this.columnSizes.beforeControls}px"></div>
|
|
11
|
-
`),this.fields.forEach(({name:t,label:s,hidden:i})=>{if(i)return;const r=this.sort.find(e=>e.name===t),o=this.sort.length>0&&this.sort[this.sort.length-1].name===t,l=r?r.asc?"sort-asc":"sort-desc":"";e.push(html`
|
|
12
|
-
<div
|
|
13
|
-
class="field cell ${l}"
|
|
14
|
-
style="width: ${this.columnSizes[t]}px; ${this.enableSorting?"cursor: pointer;":""}"
|
|
1
|
+
import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import{toTitleCase}from"../utils/string.js";import{boolExists}from"../utils/propConverters.js";const selected=Symbol("selected"),hidden=Symbol("hidden"),index=Symbol("index"),editing=Symbol("editing");export default class Table extends ShadowComponent{static properties={enablePages:{type:Boolean,reflect:!0,converter:boolExists,attribute:"enable-pages"},pageSize:{type:Number,reflect:!0,attribute:"page-size"},currentPage:{type:Number,reflect:!0,attribute:"current-page"},pageSizeOptions:{type:Array,attribute:"page-size-options"},enableSelection:{type:Boolean,reflect:!0,converter:boolExists,attribute:"enable-selection"},enableSorting:{type:Boolean,reflect:!0,converter:boolExists,attribute:"enable-sorting"},caseSensitiveFilters:{type:Boolean,reflect:!0,converter:boolExists,attribute:"case-sensitive-filters"},requestEdit:{type:Boolean,reflect:!0,converter:boolExists,attribute:"request-edit"},requestDelete:{type:Boolean,reflect:!0,converter:boolExists,attribute:"request-delete"},fields:{type:Array},records:{type:Array},filters:{type:Array},sort:{type:Array},columnSizes:{type:Object},fetchPending:{type:Boolean}};constructor(e={}){super(),void 0===this.pageSize&&(this.pageSize=50),void 0===this.currentPage&&(this.currentPage=1),void 0===this.pageSizeOptions&&(this.pageSizeOptions=[10,25,50,100,500]),void 0===this.records&&(this.records=e.records||[]),void 0===this.fields&&(this.fields=e.fields||[]),void 0===this.filters&&(this.filters=e.filters||[]),void 0===this.sort&&(this.sort=[]),void 0===this.columnSizes&&(this.columnSizes={}),void 0===this.fetchPending&&(this.fetchPending=!1),void 0===this.requestEdit&&(this.requestEdit=!1),void 0===this.requestDelete&&(this.requestDelete=!1)}handleSelectAllChange=e=>{e.target.checked?this.selectAllOnPage():this.deselectAllOnPage()};handleFieldClick=e=>{const t=this.sort.find(t=>t.name===e),s=!t||!t.asc;this.sortBy(e,s)};handleRecordSelectionChange=(e,t)=>{e[selected]=!!t.target.checked,this.requestUpdate(),this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0}))};firstUpdated(){this.setData({records:this.records,fields:this.fields,filters:this.filters})}childrenUpdated(){this.requestUpdate()}updated(e){if(super.updated(e),this.enableSelection){const e=this.shadowRoot.getElementById("select-all");e&&(e.checked=this.allOnPageSelected())}}renderColgroupTemplate(){const e=[];return this.enableSelection&&e.push(html`<col style="width: 40px" />`),this.hasBeforeControls()&&e.push(html`<col style="width: ${this.columnSizes.beforeControls}px" />`),this.fields.forEach(({size:t,hidden:s})=>{s||e.push(t?html`<col style="width: ${t}px" />`:html`<col />`)}),this.hasAfterControls()&&e.push(html`<col style="width: ${this.columnSizes.afterControls}px" />`),e}getColumnCount(){let e=0;return this.enableSelection&&e++,this.hasBeforeControls()&&e++,this.fields.forEach(({hidden:t})=>{t||e++}),this.hasAfterControls()&&e++,e}renderFieldsTemplate(){const e=[];return this.enableSelection&&e.push(html`
|
|
2
|
+
<th class="controls field-select">
|
|
3
|
+
<input type="checkbox" id="select-all" @change=${this.handleSelectAllChange} />
|
|
4
|
+
</th>
|
|
5
|
+
`),this.hasBeforeControls()&&e.push(html`<th class="controls field-before-controls"></th>`),this.fields.forEach(({name:t,label:s,hidden:i})=>{if(i)return;const r=this.sort.find(e=>e.name===t),o=this.sort.length>0&&this.sort[this.sort.length-1].name===t,n=r?r.asc?"sort-asc":"sort-desc":"";e.push(html`
|
|
6
|
+
<th
|
|
7
|
+
class="${n}"
|
|
8
|
+
style="${this.enableSorting?"cursor: pointer;":""}"
|
|
15
9
|
@click=${this.enableSorting?()=>this.handleFieldClick(t):null}
|
|
16
10
|
>
|
|
17
11
|
${s}
|
|
18
12
|
${o?html`<k-icon name="arrow" direction="${r.asc?"down":"up"}" class="icon-sort"></k-icon>`:""}
|
|
19
|
-
</
|
|
20
|
-
`)}),this.hasAfterControls()&&e.push(html`
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<input
|
|
25
|
-
type="checkbox"
|
|
13
|
+
</th>
|
|
14
|
+
`)}),this.hasAfterControls()&&e.push(html`<th class="controls field-after-controls"></th>`),e}renderRecordsTemplate(){let e=this.getDisplayedRecords(),t=0,s=this.pageSize;this.enablePages&&(t=(this.currentPage-1)*this.pageSize,s=t+this.pageSize,e=e.slice(t,s));let i=null,r=0;const o=e.map((e,s)=>null!==e?this.renderRecordTemplate(e):(null===i&&(i=t+s),r++,html`<tr class="record fetching"><td class="cell" colspan="${this.getColumnCount()}">Loading...</td></tr>`));return null===i||this.fetchPending||setTimeout(()=>{this.fetchPending||this.dispatchEvent(new CustomEvent("fetchRecords",{detail:{start:i,count:r},bubbles:!0}))},0),o}renderRecordTemplate(e){const t=[];return this.enableSelection&&t.push(html`
|
|
15
|
+
<td class="cell selection controls">
|
|
16
|
+
<input
|
|
17
|
+
type="checkbox"
|
|
26
18
|
.checked=${e[selected]}
|
|
27
19
|
@change=${t=>this.handleRecordSelectionChange(e,t)}
|
|
28
20
|
/>
|
|
29
|
-
</
|
|
30
|
-
`),this.hasBeforeControls()&&t.push(this.renderBeforeControlsTemplate()),this.fields.forEach(({name:s,formatter:i,calculator:r,type:o,editor:
|
|
31
|
-
<
|
|
32
|
-
${e[editing]?this.renderEditingCell(e,s,a,r,
|
|
33
|
-
</
|
|
21
|
+
</td>
|
|
22
|
+
`),this.hasBeforeControls()&&t.push(this.renderBeforeControlsTemplate()),this.fields.forEach(({name:s,formatter:i,calculator:r,type:o,editor:n,hidden:l})=>{if(l)return;let a=e[s]||"";t.push(html`
|
|
23
|
+
<td class="cell" data-field=${s}>
|
|
24
|
+
${e[editing]?this.renderEditingCell(e,s,a,r,n,o):this.renderDisplayCell(e,s,a,r,i)}
|
|
25
|
+
</td>
|
|
34
26
|
`)}),this.hasAfterControls()&&t.push(this.renderAfterControlsTemplate()),html`
|
|
35
|
-
<
|
|
27
|
+
<tr class="record ${e[editing]?"editing":""}" data-index=${e[index]}>
|
|
36
28
|
${t}
|
|
37
|
-
</
|
|
29
|
+
</tr>
|
|
38
30
|
`}renderEditingCell(e,t,s,i,r,o){if(i)return html`<input disabled .value=${i(e,this)} />`;if(r){const e=r(s);return html`${e}`}switch(o||typeof s){case"number":return html`<input type="number" .value=${s} />`;case"date":return html`<input type="date" .value=${s} />`;case"boolean":return html`
|
|
39
31
|
<select .value=${s}>
|
|
40
32
|
<option value="true" ?selected=${s}>True</option>
|
|
41
33
|
<option value="false" ?selected=${!s}>False</option>
|
|
42
34
|
</select>
|
|
43
35
|
`;default:return html`<input type="text" .value=${s} />`}}renderDisplayCell(e,t,s,i,r){return i?i(e,this):r?r(s):s}renderBeforeControlsTemplate(){const e=[];return this.querySelectorAll('[slot="before"]').forEach(t=>{const s=t.tagName.toLowerCase(),i=document.createElement(s);Array.from(t.attributes).forEach(e=>{"slot"!==e.name&&i.setAttribute(e.name,e.value)}),t.innerHTML&&(i.innerHTML=t.innerHTML),e.push(i)}),html`
|
|
44
|
-
<
|
|
36
|
+
<td class="cell controls controls-before">
|
|
45
37
|
${e}
|
|
46
|
-
</
|
|
38
|
+
</td>
|
|
47
39
|
`}renderAfterControlsTemplate(){const e=[];return this.querySelectorAll('[slot="after"]').forEach(t=>{const s=t.tagName.toLowerCase(),i=document.createElement(s);Array.from(t.attributes).forEach(e=>{"slot"!==e.name&&i.setAttribute(e.name,e.value)}),t.innerHTML&&(i.innerHTML=t.innerHTML),e.push(i)}),html`
|
|
48
|
-
<
|
|
40
|
+
<td class="cell controls controls-after">
|
|
49
41
|
${e}
|
|
50
|
-
</
|
|
51
|
-
`}hasBeforeControls(){return!!this.querySelector('[slot="before"]')}hasAfterControls(){return!!this.querySelector('[slot="after"]')}hasTopControls(){return!!this.querySelector('[slot="top"]')}hasBottomControls(){return!!this.querySelector(":scope > :not([slot])")}editRecord(e){e[editing]=!0;const t=this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`);t&&(t.classList.add("editing"),t.setAttribute("editing","true"),t.querySelectorAll(".cell[data-field]").forEach(t=>{const s=t.dataset.field,i=this.fields.find(e=>e.name===s);if(i){const r=e[s]||"";if(t.innerHTML="",i.calculator){const s=document.createElement("input");s.disabled=!0,s.value=i.calculator(e,this),t.appendChild(s)}else if(i.editor)t.appendChild(i.editor(r));else{const e=i.type||typeof r,s=Table.editors[e]||Table.editors.string;t.appendChild(s(r))}}})),this.dispatchEvent(new CustomEvent("editingChange",{detail:{record:e,editing:!0},bubbles:!0}))}saveEditedRecord(e){const t=this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`);t&&(t.querySelectorAll(".cell[data-field]").forEach(t=>{const s=t.dataset.field,i=this.fields.find(e=>e.name===s);if(i&&!i.calculator){const i=t.querySelector("input, select");i&&(e[s]=i.value)}}),e[editing]=!1,t.classList.remove("editing"),t.removeAttribute("editing"),t.querySelectorAll(".cell[data-field]").forEach(t=>{const s=t.dataset.field,i=this.fields.find(e=>e.name===s);if(i){const r=e[s]||"";i.calculator?t.textContent=i.calculator(e,this):i.formatter?t.innerHTML=i.formatter(r):t.textContent=r}})),this.dispatchEvent(new CustomEvent("editingChange",{detail:{record:e,editing:!1},bubbles:!0}))}cancelEditedRecord(e){e[editing]=!1;const t=this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`);t&&(t.classList.remove("editing"),t.removeAttribute("editing"),t.querySelectorAll(".cell[data-field]").forEach(t=>{const s=t.dataset.field,i=this.fields.find(e=>e.name===s);if(i){const r=e[s]||"";i.calculator?t.textContent=i.calculator(e,this):i.formatter?t.innerHTML=i.formatter(r):t.textContent=r}})),this.dispatchEvent(new CustomEvent("editingChange",{detail:{record:e,editing:!1},bubbles:!0}))}recordIsEditing(e){return e[editing]}getCurrentPage(){return this.currentPage}getTotalPages(){return Math.ceil(this.getDisplayedRecords().length/this.pageSize)}setPage(e){e<1||e>this.getTotalPages()||(this.currentPage=e,this.requestUpdate(),this.dispatchEvent(new CustomEvent("pageChange",{bubbles:!0})))}firstPage(){1!==this.currentPage&&this.setPage(1)}nextPage(){this.currentPage<this.getTotalPages()&&this.setPage(this.currentPage+1)}prevPage(){this.currentPage>1&&this.setPage(this.currentPage-1)}lastPage(){this.currentPage!==this.getTotalPages()&&this.setPage(this.getTotalPages())}setPageSize(e){this.pageSize=e,this.currentPage=1,this.requestUpdate(),this.dispatchEvent(new CustomEvent("pageSizeChange",{bubbles:!0}))}getPageSize(){return this.pageSize}getPageSizeOptions(){return this.pageSizeOptions}getFieldLabel(e){const t=this.fields.find(t=>t.name===e);return t?t.label:toTitleCase(e)}setPageSizeOptions(e){this.pageSizeOptions=e,this.requestUpdate()}setData({records:e=!1,fields:t=!1,pageSize:s=!1,pageSizeOptions:i=!1,currentPage:r=!1,enableSelection:o}={}){let l=!1,n=this.getTotalPages(),a=this.currentPage;e&&(this.records=e.map(e=>({...e})),this.records.forEach((e,t)=>{e[index]=t,e[selected]=!1,e[hidden]=!1,e[editing]=!1}),this.fields=t||Table.extractFieldsFromRecords(this.records),l=!0),s&&(this.pageSize=s,l=!0),i&&(this.pageSizeOptions=i),r&&(this.currentPage=r,l=!0),void 0!==o&&(this.enableSelection=o,l=!0),l&&this.requestUpdate();const d=this.getTotalPages();d!==n&&this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:this.getTotalPages()},bubbles:!0})),a>d&&this.setPage(d)}setRecords(e,t){let s=this.getTotalPages(),i=this.currentPage;this.records=e.map(e=>({...e})),this.records.forEach((e,t)=>{e[index]=t,e[selected]=!1,e[hidden]=!1,e[editing]=!1}),this.fields=t||Table.extractFieldsFromRecords(this.records),this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordsSet",{detail:{records:e},bubbles:!0}));const r=this.getTotalPages();r!==s&&this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:this.getTotalPages()},bubbles:!0})),i>r&&this.setPage(r)}setupFetchRecords(e,t){const s=this.records.length,i=this.getTotalPages();if(s<e){this.records.length=e,this.records.fill(null,s),this.requestUpdate();const t=this.getTotalPages();t!==i&&setTimeout(()=>{this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:t},bubbles:!0}))},0)}this.addEventListener("fetchRecords",async e=>{if(this.fetchPending)return;this.fetchPending=!0;const{start:s,count:i}=e.detail,r=await t(s,i);r.forEach((e,t)=>{e[index]=s+t,void 0===e[selected]&&(e[selected]=!1),void 0===e[hidden]&&(e[hidden]=!1),void 0===e[editing]&&(e[editing]=!1)}),this.records.splice(s,r.length,...r),this.fetchPending=!1,this.requestUpdate()})}addRecord(e){e[selected]=!1,e[hidden]=!1,e[index]=this.records.length,this.records.push(e),this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordAdded",{detail:{record:e},bubbles:!0}))}updateRecord(e,t){let s=!1,i=this.records.find(t=>t===e);if(i||void 0===e[index]||(i=this.records[e[index]]),Object.keys(t).forEach(e=>{i.hasOwnProperty(e)&&(i[e]=t[e],s=!0)}),s){const e=(this.currentPage-1)*this.pageSize,t=e+this.pageSize;(!this.enablePages||i[index]>=e&&i[index]<t)&&this.requestUpdate()}}deleteRecord(e){let t=this.records.find(t=>t===e),s=this.getTotalPages();if(t||void 0===e[index]||(t=this.records[e[index]]),t){const e=this.records.indexOf(t);this.records.splice(e,1),this.records.forEach((e,t)=>{e[index]=t}),this.requestUpdate(),this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0})),this.dispatchEvent(new CustomEvent("recordDeleted",{detail:{index:e},bubbles:!0}));const i=this.getTotalPages();this.currentPage>i&&this.setPage(i),i!==s&&this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:i},bubbles:!0}))}}deleteSelected(){let e=this.getTotalPages();this.getSelectedRecords().forEach(e=>{let t=this.records.find(t=>t===e);if(t||void 0===e[index]||(t=this.records[e[index]]),t){const e=this.records.indexOf(t);this.records.splice(e,1)}}),this.records.forEach((e,t)=>{e[index]=t}),this.requestUpdate();const t=this.getTotalPages();this.currentPage>t&&this.setPage(t),t!==e&&this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:t},bubbles:!0})),this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0}))}getSelectedRecords(){return this.records.filter(e=>e[selected])}selectAllOnPage(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let s=e;s<t;s++)this.records[s][selected]=!0;this.requestUpdate(),setTimeout(()=>{this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0}))},0)}deselectAllOnPage(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let s=e;s<t;s++)this.records[s][selected]=!1;this.requestUpdate(),setTimeout(()=>{this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0}))},0)}allOnPageSelected(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let s=e;s<t;s++)if(!this.records[s][selected])return!1;return!0}sortBy(e,t=!0){this.sort=this.sort.filter(t=>t.name!==e),this.sort.push({name:e,asc:t}),this.requestUpdate()}hideRecord(e){let t=this.records.find(t=>t===e);t||void 0===e[index]||(t=this.records[e[index]]),t&&(t[hidden]=!0,this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordHidden",{bubbles:!0})))}showRecord(e){let t=this.records.find(t=>t===e);t||void 0===e[index]||(t=this.records[e[index]]),t&&(t[hidden]=!1,this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordShown",{bubbles:!0})))}showAllRecords(){this.records.forEach(e=>{e[hidden]=!1}),this.filters.length&&(this.filters=[],this.dispatchEvent(new CustomEvent("filterRemoved",{bubbles:!0})),this.dispatchEvent(new CustomEvent("filterChange",{bubbles:!0}))),this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordShown",{bubbles:!0})),this.dispatchEvent(new CustomEvent("allRecordsShown",{bubbles:!0}))}addFilter(e,t,s){this.filters.push({field:e,condition:t,value:s}),this.dispatchEvent(new CustomEvent("filterAdded",{bubbles:!0})),this.dispatchEvent(new CustomEvent("filterChange",{bubbles:!0})),this.requestUpdate()}removeFilter(e,t,s,i=!0){const r=this.filters.findIndex(i=>i.field===e&&i.condition===t&&i.value===s);-1!==r&&(this.records.forEach(i=>{this.testFilter(i,e,t,s)||(i[hidden]=!1)}),this.filters.splice(r,1),this.dispatchEvent(new CustomEvent("filterRemoved",{bubbles:!0})),this.dispatchEvent(new CustomEvent("filterChange",{bubbles:!0})),i&&this.requestUpdate())}testFilter(e,t,s,i){let r=e[t],o=i;switch(this.caseSensitiveFilters||"string"!=typeof r||"string"!=typeof i||(r=r.toLowerCase(),o=i.toLowerCase()),s){case"equals":return r===o;case"not-equals":return r!==o;case"contains":return r.includes(o);case"not-contains":return!r.includes(o);case"greater-than":return r>o;case"less-than":return r<o;case"greater-than-or-equal":return r>=o;case"less-than-or-equal":return r<=o;default:return!0}}removeAllFilters(){this.filters.length&&([...this.filters].forEach(({field:e,condition:t,value:s})=>{this.removeFilter(e,t,s,!1)}),this.requestUpdate())}search(e){const t=e.trim().toLowerCase();let s=!1;this.records.forEach(e=>{if(e[hidden])return;let i=!1;this.fields.forEach(({name:s})=>{(e[s]?.toString().toLowerCase()||"").includes(t)&&(i=!0)}),e[hidden]!==!i&&(e[hidden]=!i,s=!0)}),s&&(this.dispatchEvent(new CustomEvent("recordHidden",{bubbles:!0})),this.requestUpdate()),this.dispatchEvent(new CustomEvent("search",{detail:{term:e},bubbles:!0}))}getDisplayedRecords(){this.filters.forEach(({field:e,condition:t,value:s})=>{this.records.forEach(i=>{null!==i&&(this.testFilter(i,e,t,s)||(i[hidden]=!0))})});let e=this.records.filter(e=>null===e||!e[hidden]);return this.sort.forEach(({name:t,asc:s})=>{e.sort((e,i)=>null===e||null===i?0:e[t]<i[t]?s?-1:1:e[t]>i[t]?s?1:-1:0)}),e}getHiddenRecords(){return this.records.filter(e=>e[hidden])}calculateColumnSizes(){const e={total:0};this.enableSelection&&(e.total+=40);const t=Array.from(this.querySelectorAll('[slot="before"]')),s=Array.from(this.querySelectorAll('[slot="after"]'));e.beforeControls=t.reduce((e,t)=>e+(t.maxWidth||40),0),e.afterControls=s.reduce((e,t)=>e+(t.maxWidth||40),0),this.hasBeforeControls()&&(e.total+=e.beforeControls),this.hasAfterControls()&&(e.total+=e.afterControls),this.fields.forEach(t=>{if(t.size)e[t.name]=t.size,e.total+=t.size;else{let s=0;this.records.slice(0,100).forEach(e=>{if(null===e)return;let i=e[t.name];t.calculator&&(i=t.calculator(e,this)),t.formatter&&(i=t.formatter(i)),i&&i.toString().length>s&&(s=i.toString().length)}),e[t.name]=Math.max(10*s+32,128),t.hidden||(e.total+=e[t.name])}});const i=[...t,...s].some(e=>void 0===e.maxWidth);return JSON.stringify(this.columnSizes)!==JSON.stringify(e)&&(this.columnSizes=e),i&&setTimeout(()=>this.calculateColumnSizes(),0),this.columnSizes}setFieldHiddenState(e,t){const s=this.fields.find(t=>t.name===e);s&&(s.hidden=t,this.calculateColumnSizes(),this.requestUpdate(),this.dispatchEvent(new CustomEvent("fieldVisibilityChanged",{detail:{field:s},bubbles:!0})),this.dispatchEvent(new CustomEvent(t?"fieldHidden":"fieldShown",{detail:{field:s},bubbles:!0})))}hideField(e){this.setFieldHiddenState(e,!0)}showField(e){this.setFieldHiddenState(e,!1)}reorderFields(e){const t=[];e.forEach(e=>{const s=this.fields.find(t=>t.name===e);s&&t.push(s)}),this.fields=t,this.requestUpdate()}render(){return this.records&&this.fields?(this.calculateColumnSizes(),this.hasTopControls()?this.setAttribute("top-controls","true"):this.removeAttribute("top-controls"),this.hasBottomControls()?this.setAttribute("bottom-controls","true"):this.removeAttribute("bottom-controls"),html`
|
|
42
|
+
</td>
|
|
43
|
+
`}hasBeforeControls(){return!!this.querySelector('[slot="before"]')}hasAfterControls(){return!!this.querySelector('[slot="after"]')}hasTopControls(){return!!this.querySelector('[slot="top"]')}hasBottomControls(){return!!this.querySelector(":scope > :not([slot])")}editRecord(e){e[editing]=!0;const t=this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`);t&&(t.classList.add("editing"),t.setAttribute("editing","true"),t.querySelectorAll(".cell[data-field]").forEach(t=>{const s=t.dataset.field,i=this.fields.find(e=>e.name===s);if(i){const r=e[s]||"";if(t.innerHTML="",i.calculator){const s=document.createElement("input");s.disabled=!0,s.value=i.calculator(e,this),t.appendChild(s)}else if(i.editor)t.appendChild(i.editor(r));else{const e=i.type||typeof r,s=Table.editors[e]||Table.editors.string;t.appendChild(s(r))}}})),this.dispatchEvent(new CustomEvent("editingChange",{detail:{record:e,editing:!0},bubbles:!0}))}saveEditedRecord(e){const t=this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`),s={};t&&t.querySelectorAll(".cell[data-field]").forEach(e=>{const t=e.dataset.field,i=this.fields.find(e=>e.name===t);if(i&&!i.calculator){const i=e.querySelector("input, select");i&&(s[t]=i.value)}});const i=()=>{Object.assign(e,s),e[editing]=!1,t&&(t.classList.remove("editing"),t.removeAttribute("editing"),t.querySelectorAll(".cell[data-field]").forEach(t=>{const s=t.dataset.field,i=this.fields.find(e=>e.name===s);if(i){const r=e[s]||"";i.calculator?t.textContent=i.calculator(e,this):i.formatter?t.innerHTML=i.formatter(r):t.textContent=r}})),this.dispatchEvent(new CustomEvent("editingChange",{detail:{record:e,editing:!1},bubbles:!0}))};if(Object.keys(s).some(t=>String(e[t]??"")!==s[t]))if(this.requestEdit){t?.classList.add("pending");const r=()=>{t?.classList.remove("pending"),i()},o=()=>{t?.classList.remove("pending")};this.dispatchEvent(new CustomEvent("requestSave",{detail:{record:e,newData:s,approve:r,reject:o},bubbles:!0}))}else i();else this.cancelEditedRecord(e)}cancelEditedRecord(e){e[editing]=!1;const t=this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`);t&&(t.classList.remove("editing"),t.removeAttribute("editing"),t.querySelectorAll(".cell[data-field]").forEach(t=>{const s=t.dataset.field,i=this.fields.find(e=>e.name===s);if(i){const r=e[s]||"";i.calculator?t.textContent=i.calculator(e,this):i.formatter?t.innerHTML=i.formatter(r):t.textContent=r}})),this.dispatchEvent(new CustomEvent("editingChange",{detail:{record:e,editing:!1},bubbles:!0}))}recordIsEditing(e){return e[editing]}getCurrentPage(){return this.currentPage}getTotalPages(){return Math.ceil(this.getDisplayedRecords().length/this.pageSize)}setPage(e){e<1||e>this.getTotalPages()||(this.currentPage=e,this.requestUpdate(),this.dispatchEvent(new CustomEvent("pageChange",{bubbles:!0})))}firstPage(){1!==this.currentPage&&this.setPage(1)}nextPage(){this.currentPage<this.getTotalPages()&&this.setPage(this.currentPage+1)}prevPage(){this.currentPage>1&&this.setPage(this.currentPage-1)}lastPage(){this.currentPage!==this.getTotalPages()&&this.setPage(this.getTotalPages())}setPageSize(e){this.pageSize=e,this.currentPage=1,this.requestUpdate(),this.dispatchEvent(new CustomEvent("pageSizeChange",{bubbles:!0}))}getPageSize(){return this.pageSize}getPageSizeOptions(){return this.pageSizeOptions}getFieldLabel(e){const t=this.fields.find(t=>t.name===e);return t?t.label:toTitleCase(e)}setPageSizeOptions(e){this.pageSizeOptions=e,this.requestUpdate()}setData({records:e=!1,fields:t=!1,pageSize:s=!1,pageSizeOptions:i=!1,currentPage:r=!1,enableSelection:o}={}){let n=!1,l=this.getTotalPages(),a=this.currentPage;e&&(this.records=e.map(e=>({...e})),this.records.forEach((e,t)=>{e[index]=t,e[selected]=!1,e[hidden]=!1,e[editing]=!1}),this.fields=t||Table.extractFieldsFromRecords(this.records),n=!0),s&&(this.pageSize=s,n=!0),i&&(this.pageSizeOptions=i),r&&(this.currentPage=r,n=!0),void 0!==o&&(this.enableSelection=o,n=!0),n&&this.requestUpdate();const d=this.getTotalPages();d!==l&&this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:this.getTotalPages()},bubbles:!0})),a>d&&this.setPage(d)}setRecords(e,t){let s=this.getTotalPages(),i=this.currentPage;this.records=e.map(e=>({...e})),this.records.forEach((e,t)=>{e[index]=t,e[selected]=!1,e[hidden]=!1,e[editing]=!1}),this.fields=t||Table.extractFieldsFromRecords(this.records),this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordsSet",{detail:{records:e},bubbles:!0}));const r=this.getTotalPages();r!==s&&this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:this.getTotalPages()},bubbles:!0})),i>r&&this.setPage(r)}setupFetchRecords(e,t){const s=this.records.length,i=this.getTotalPages();if(s<e){this.records.length=e,this.records.fill(null,s),this.requestUpdate();const t=this.getTotalPages();t!==i&&setTimeout(()=>{this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:t},bubbles:!0}))},0)}this.addEventListener("fetchRecords",async e=>{if(this.fetchPending)return;this.fetchPending=!0;const{start:s,count:i}=e.detail,r=await t(s,i);r.forEach((e,t)=>{e[index]=s+t,void 0===e[selected]&&(e[selected]=!1),void 0===e[hidden]&&(e[hidden]=!1),void 0===e[editing]&&(e[editing]=!1)}),this.records.splice(s,r.length,...r),this.fetchPending=!1,this.requestUpdate()})}addRecord(e){e[selected]=!1,e[hidden]=!1,e[index]=this.records.length,this.records.push(e),this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordAdded",{detail:{record:e},bubbles:!0}))}updateRecord(e,t){let s=!1,i=this.records.find(t=>t===e);if(i||void 0===e[index]||(i=this.records[e[index]]),Object.keys(t).forEach(e=>{i.hasOwnProperty(e)&&(i[e]=t[e],s=!0)}),s){const e=(this.currentPage-1)*this.pageSize,t=e+this.pageSize;(!this.enablePages||i[index]>=e&&i[index]<t)&&this.requestUpdate()}}deleteRecord(e){let t=this.records.find(t=>t===e);const s=this.getTotalPages();if(t||void 0===e[index]||(t=this.records[e[index]]),!t)return;const i=()=>{const e=this.records.indexOf(t);this.records.splice(e,1),this.records.forEach((e,t)=>{e[index]=t}),this.requestUpdate(),this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0})),this.dispatchEvent(new CustomEvent("recordDeleted",{detail:{index:e},bubbles:!0}));const i=this.getTotalPages();this.currentPage>i&&this.setPage(i),i!==s&&this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:i},bubbles:!0}))};if(this.requestDelete){const e=this.shadowRoot.querySelector(`.record[data-index="${t[index]}"]`);e?.classList.add("pending");const s=()=>{e?.classList.remove("pending"),i()},r=()=>{e?.classList.remove("pending")};this.dispatchEvent(new CustomEvent("requestDelete",{detail:{records:[t],approve:s,reject:r},bubbles:!0}))}else i()}deleteSelected(){const e=this.getTotalPages(),t=this.getSelectedRecords().map(e=>this.records.find(t=>t===e)??(void 0!==e[index]?this.records[e[index]]:null)).filter(Boolean);if(!t.length)return;const s=()=>{t.forEach(e=>{const t=this.records.indexOf(e);-1!==t&&this.records.splice(t,1)}),this.records.forEach((e,t)=>{e[index]=t}),this.requestUpdate();const s=this.getTotalPages();this.currentPage>s&&this.setPage(s),s!==e&&this.dispatchEvent(new CustomEvent("pageCountChanged",{detail:{totalPages:s},bubbles:!0})),this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0}))};if(this.requestDelete){const e=t.map(e=>this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`)).filter(Boolean);e.forEach(e=>e.classList.add("pending"));const i=()=>{e.forEach(e=>e.classList.remove("pending")),s()},r=()=>{e.forEach(e=>e.classList.remove("pending"))};this.dispatchEvent(new CustomEvent("requestDelete",{detail:{records:t,approve:i,reject:r},bubbles:!0}))}else s()}getSelectedRecords(){return this.records.filter(e=>e[selected])}selectAllOnPage(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let s=e;s<t;s++)this.records[s][selected]=!0;this.requestUpdate(),setTimeout(()=>{this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0}))},0)}deselectAllOnPage(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let s=e;s<t;s++)this.records[s][selected]=!1;this.requestUpdate(),setTimeout(()=>{this.dispatchEvent(new CustomEvent("selectionChange",{bubbles:!0}))},0)}allOnPageSelected(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let s=e;s<t;s++)if(!this.records[s][selected])return!1;return!0}sortBy(e,t=!0){this.sort=this.sort.filter(t=>t.name!==e),this.sort.push({name:e,asc:t}),this.requestUpdate()}hideRecord(e){let t=this.records.find(t=>t===e);t||void 0===e[index]||(t=this.records[e[index]]),t&&(t[hidden]=!0,this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordHidden",{bubbles:!0})))}showRecord(e){let t=this.records.find(t=>t===e);t||void 0===e[index]||(t=this.records[e[index]]),t&&(t[hidden]=!1,this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordShown",{bubbles:!0})))}showAllRecords(){this.records.forEach(e=>{e[hidden]=!1}),this.filters.length&&(this.filters=[],this.dispatchEvent(new CustomEvent("filterRemoved",{bubbles:!0})),this.dispatchEvent(new CustomEvent("filterChange",{bubbles:!0}))),this.requestUpdate(),this.dispatchEvent(new CustomEvent("recordShown",{bubbles:!0})),this.dispatchEvent(new CustomEvent("allRecordsShown",{bubbles:!0}))}addFilter(e,t,s){this.filters.push({field:e,condition:t,value:s}),this.dispatchEvent(new CustomEvent("filterAdded",{bubbles:!0})),this.dispatchEvent(new CustomEvent("filterChange",{bubbles:!0})),this.requestUpdate()}removeFilter(e,t,s,i=!0){const r=this.filters.findIndex(i=>i.field===e&&i.condition===t&&i.value===s);-1!==r&&(this.records.forEach(i=>{this.testFilter(i,e,t,s)||(i[hidden]=!1)}),this.filters.splice(r,1),this.dispatchEvent(new CustomEvent("filterRemoved",{bubbles:!0})),this.dispatchEvent(new CustomEvent("filterChange",{bubbles:!0})),i&&this.requestUpdate())}testFilter(e,t,s,i){let r=e[t],o=i;switch(this.caseSensitiveFilters||"string"!=typeof r||"string"!=typeof i||(r=r.toLowerCase(),o=i.toLowerCase()),s){case"equals":return r===o;case"not-equals":return r!==o;case"contains":return r.includes(o);case"not-contains":return!r.includes(o);case"greater-than":return r>o;case"less-than":return r<o;case"greater-than-or-equal":return r>=o;case"less-than-or-equal":return r<=o;default:return!0}}removeAllFilters(){this.filters.length&&([...this.filters].forEach(({field:e,condition:t,value:s})=>{this.removeFilter(e,t,s,!1)}),this.requestUpdate())}search(e){const t=e.trim().toLowerCase();let s=!1;this.records.forEach(e=>{if(e[hidden])return;let i=!1;this.fields.forEach(({name:s})=>{(e[s]?.toString().toLowerCase()||"").includes(t)&&(i=!0)}),e[hidden]!==!i&&(e[hidden]=!i,s=!0)}),s&&(this.dispatchEvent(new CustomEvent("recordHidden",{bubbles:!0})),this.requestUpdate()),this.dispatchEvent(new CustomEvent("search",{detail:{term:e},bubbles:!0}))}getDisplayedRecords(){this.filters.forEach(({field:e,condition:t,value:s})=>{this.records.forEach(i=>{null!==i&&(this.testFilter(i,e,t,s)||(i[hidden]=!0))})});let e=this.records.filter(e=>null===e||!e[hidden]);return this.sort.forEach(({name:t,asc:s})=>{e.sort((e,i)=>null===e||null===i?0:e[t]<i[t]?s?-1:1:e[t]>i[t]?s?1:-1:0)}),e}getHiddenRecords(){return this.records.filter(e=>e[hidden])}calculateColumnSizes(){const e=Array.from(this.querySelectorAll('[slot="before"]')),t=Array.from(this.querySelectorAll('[slot="after"]')),s={beforeControls:e.reduce((e,t)=>e+(t.maxWidth||40),0),afterControls:t.reduce((e,t)=>e+(t.maxWidth||40),0)},i=[...e,...t].some(e=>void 0===e.maxWidth);return JSON.stringify(this.columnSizes)!==JSON.stringify(s)&&(this.columnSizes=s),i&&setTimeout(()=>this.calculateColumnSizes(),0),this.columnSizes}setFieldHiddenState(e,t){const s=this.fields.find(t=>t.name===e);s&&(s.hidden=t,this.calculateColumnSizes(),this.requestUpdate(),this.dispatchEvent(new CustomEvent("fieldVisibilityChanged",{detail:{field:s},bubbles:!0})),this.dispatchEvent(new CustomEvent(t?"fieldHidden":"fieldShown",{detail:{field:s},bubbles:!0})))}hideField(e){this.setFieldHiddenState(e,!0)}showField(e){this.setFieldHiddenState(e,!1)}reorderFields(e){const t=[];e.forEach(e=>{const s=this.fields.find(t=>t.name===e);s&&t.push(s)}),this.fields=t,this.requestUpdate()}render(){return this.records&&this.fields?(this.calculateColumnSizes(),this.hasTopControls()?this.setAttribute("top-controls","true"):this.removeAttribute("top-controls"),this.hasBottomControls()?this.setAttribute("bottom-controls","true"):this.removeAttribute("bottom-controls"),html`
|
|
52
44
|
<div id="wrapper">
|
|
53
|
-
<div id="top"
|
|
54
|
-
<div id="table">
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
45
|
+
<div id="top"><slot name="top"></slot></div>
|
|
46
|
+
<div id="table-container">
|
|
47
|
+
<table>
|
|
48
|
+
<colgroup>
|
|
49
|
+
${this.renderColgroupTemplate()}
|
|
50
|
+
</colgroup>
|
|
51
|
+
<thead>
|
|
52
|
+
<tr>
|
|
53
|
+
${this.renderFieldsTemplate()}
|
|
54
|
+
</tr>
|
|
55
|
+
</thead>
|
|
56
|
+
<tbody>
|
|
57
|
+
${this.renderRecordsTemplate()}
|
|
58
|
+
</tbody>
|
|
59
|
+
</table>
|
|
61
60
|
</div>
|
|
62
|
-
<div id="bottom"
|
|
61
|
+
<div id="bottom"><slot></slot></div>
|
|
63
62
|
</div>
|
|
64
63
|
<div style="display: none">
|
|
65
64
|
<slot name="before"></slot>
|
|
@@ -68,9 +67,8 @@ import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowCompon
|
|
|
68
67
|
`):html`
|
|
69
68
|
<div id="wrapper">
|
|
70
69
|
<div id="top"><slot name="top"></slot></div>
|
|
71
|
-
<div id="table">
|
|
72
|
-
<
|
|
73
|
-
<div id="records"></div>
|
|
70
|
+
<div id="table-container">
|
|
71
|
+
<table><thead><tr></tr></thead><tbody></tbody></table>
|
|
74
72
|
</div>
|
|
75
73
|
<div id="bottom"><slot></slot></div>
|
|
76
74
|
</div>
|
|
@@ -81,39 +79,99 @@ import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowCompon
|
|
|
81
79
|
`}static styles=css`
|
|
82
80
|
:host {
|
|
83
81
|
display: block;
|
|
84
|
-
width: 100%;
|
|
85
|
-
overflow: auto;
|
|
86
82
|
margin-bottom: var(--spacer);
|
|
87
83
|
}
|
|
88
84
|
#wrapper {
|
|
89
|
-
width: min-content;
|
|
90
85
|
border: 1px solid var(--c_border);
|
|
91
86
|
border-radius: var(--radius);
|
|
87
|
+
overflow: hidden;
|
|
92
88
|
}
|
|
93
|
-
#table {
|
|
94
|
-
|
|
89
|
+
#table-container {
|
|
90
|
+
overflow-x: auto;
|
|
95
91
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
92
|
+
table {
|
|
93
|
+
width: 100%;
|
|
94
|
+
border-collapse: collapse;
|
|
99
95
|
}
|
|
100
|
-
|
|
96
|
+
thead tr {
|
|
101
97
|
background-color: var(--c_bg__alt);
|
|
102
|
-
border-bottom: 1px solid var(--c_border);
|
|
103
98
|
}
|
|
104
|
-
|
|
105
|
-
#fields .cell:not(.controls) {
|
|
99
|
+
th, td {
|
|
106
100
|
padding: calc(0.5 * var(--spacer)) var(--spacer);
|
|
101
|
+
vertical-align: middle;
|
|
102
|
+
}
|
|
103
|
+
th:not(:last-child),
|
|
104
|
+
td:not(:last-child) {
|
|
105
|
+
border-right: 1px solid var(--c_border);
|
|
106
|
+
}
|
|
107
|
+
th:first-child,
|
|
108
|
+
td:first-child {
|
|
109
|
+
border-left: none;
|
|
110
|
+
}
|
|
111
|
+
th:last-child,
|
|
112
|
+
td:last-child {
|
|
113
|
+
border-right: none;
|
|
114
|
+
}
|
|
115
|
+
thead tr th {
|
|
116
|
+
border-top: none;
|
|
117
|
+
border-bottom: 1px solid var(--c_border);
|
|
107
118
|
}
|
|
108
|
-
|
|
119
|
+
tbody tr:not(:last-child) td {
|
|
120
|
+
border-bottom: 1px solid var(--c_border);
|
|
121
|
+
}
|
|
122
|
+
tbody tr:last-child td {
|
|
123
|
+
border-bottom: none;
|
|
124
|
+
}
|
|
125
|
+
tr.editing td.cell[data-field] {
|
|
126
|
+
padding: 0;
|
|
127
|
+
}
|
|
128
|
+
tr.editing td.cell[data-field] input,
|
|
129
|
+
tr.editing td.cell[data-field] select {
|
|
130
|
+
width: 100%;
|
|
131
|
+
height: 100%;
|
|
132
|
+
box-sizing: border-box;
|
|
133
|
+
}
|
|
134
|
+
tr.pending {
|
|
135
|
+
pointer-events: none;
|
|
136
|
+
}
|
|
137
|
+
tr.pending td {
|
|
138
|
+
position: relative;
|
|
139
|
+
overflow: hidden;
|
|
140
|
+
}
|
|
141
|
+
tr.pending td::before {
|
|
142
|
+
content: '';
|
|
143
|
+
position: absolute;
|
|
144
|
+
inset: 0;
|
|
145
|
+
background: linear-gradient(90deg, transparent, rgba(128, 128, 128, 0.15), transparent);
|
|
146
|
+
transform: translateX(-100%);
|
|
147
|
+
animation: row-pending 1.2s ease-in-out infinite;
|
|
148
|
+
}
|
|
149
|
+
@keyframes row-pending {
|
|
150
|
+
0% { transform: translateX(-100%); }
|
|
151
|
+
100% { transform: translateX(100%); }
|
|
152
|
+
}
|
|
153
|
+
th.controls,
|
|
154
|
+
td.controls {
|
|
155
|
+
padding: 0;
|
|
156
|
+
}
|
|
157
|
+
td.controls-after,
|
|
158
|
+
td.controls-before {
|
|
109
159
|
display: flex;
|
|
110
160
|
align-items: center;
|
|
111
161
|
}
|
|
112
|
-
.
|
|
113
|
-
|
|
162
|
+
.field-select,
|
|
163
|
+
.selection {
|
|
164
|
+
width: 40px;
|
|
165
|
+
text-align: center;
|
|
114
166
|
}
|
|
115
|
-
.
|
|
116
|
-
|
|
167
|
+
.field-select input,
|
|
168
|
+
.selection input {
|
|
169
|
+
width: 1.25rem;
|
|
170
|
+
height: 1.25rem;
|
|
171
|
+
}
|
|
172
|
+
.icon-sort {
|
|
173
|
+
float: right;
|
|
174
|
+
opacity: 0.5;
|
|
117
175
|
}
|
|
118
176
|
#top, #bottom {
|
|
119
177
|
display: flex;
|
|
@@ -133,19 +191,4 @@ import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowCompon
|
|
|
133
191
|
:host(:not([bottom-controls])) #bottom {
|
|
134
192
|
display: none;
|
|
135
193
|
}
|
|
136
|
-
.field-select,
|
|
137
|
-
.selection {
|
|
138
|
-
display: flex;
|
|
139
|
-
justify-content: center;
|
|
140
|
-
align-items: center;
|
|
141
|
-
}
|
|
142
|
-
.field-select input,
|
|
143
|
-
.selection input {
|
|
144
|
-
width: 1.25rem;
|
|
145
|
-
height: 1.25rem;
|
|
146
|
-
}
|
|
147
|
-
.icon-sort {
|
|
148
|
-
float: right;
|
|
149
|
-
opacity: 0.5;
|
|
150
|
-
}
|
|
151
194
|
`;static extractFieldsFromRecords(e,t=100){const s=new Set;return e.slice(0,t).forEach(e=>{Object.keys(e).forEach(e=>s.add(e))}),[...s].map(e=>({name:e,label:toTitleCase(e)}))}static format(e){return(Array.isArray(e)?Table.formatters.array:Table.formatters[typeof e])(e)}static formatters={string:e=>e,number:e=>`${e}`,date:e=>e.toLocaleDateString(),boolean:e=>e?"True":"False",array:e=>e.map(e=>Table.format(e)).join(", "),undefined:e=>"",null:e=>"<code>null</code>"};static editors={string:e=>{const t=document.createElement("input");return t.value=e,t},number:e=>{const t=document.createElement("input");return t.type="number",t.value=e,t},date:e=>{const t=document.createElement("input");return t.type="date",t.value=e,t},boolean:e=>{const t=document.createElement("select");return t.innerHTML=`\n <option value="true" ${e?"selected":""}>True</option>\n <option value="false" ${e?"":"selected"}>False</option>\n `,t.value=e,t},calculated:e=>{const t=document.createElement("input");return t.disabled=!0,t.value=e,t}}}window.customElements.define("k-table",Table);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import{html}from"../../lit-all.min.js";import"../Icon.js";export default class DeleteSelected extends TableControl{deleteSelected=()=>{this.table.deleteSelected()};render(){return html`
|
|
2
|
+
<button class="no-btn icon-btn" title="Delete Selected" @click="${this.deleteSelected}">
|
|
3
|
+
<slot>
|
|
4
|
+
<k-icon name="delete_sweep"></k-icon>
|
|
5
|
+
</slot>
|
|
6
|
+
</button>
|
|
7
|
+
`}}customElements.define("k-tc-delete-selected",DeleteSelected);
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
<a href="./tableSorting.html">Sorting</a><br />
|
|
35
35
|
<a href="./tableFieldSortHide.html">Field Sorting and Hiding</a><br />
|
|
36
36
|
<a href="./tableFetchRecords.html">Fetching Records</a><br />
|
|
37
|
+
<a href="./tableServerSync.html">Server Sync</a><br />
|
|
37
38
|
<h6 class="mt"><a href="#jsRef" class="no-link">JavaScript Reference</a></h6>
|
|
38
39
|
<a href="#constructor">Constructor</a><br />
|
|
39
40
|
<a href="#requirements">Requirements</a><br />
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
<p>In HTML create a <code><k-table></code>, and then in JavaScript call the <code>setData</code> method passing in an options object containing your data.</p>
|
|
51
52
|
|
|
52
53
|
<k-card label="HTML">
|
|
53
|
-
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">
|
|
54
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">basicUsageExample</span>></span><span class="hljs-tag"></<span class="hljs-name">k-table</span>></span><br><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">module</span>></span><span class="language-javascript"><br> <span class="hljs-keyword">await</span> <span class="hljs-variable language_">window</span>.<span class="hljs-property">customElements</span>.<span class="hljs-title function_">whenDefined</span>(<span class="hljs-string">'k-table'</span>);<br> <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">'basicUsageExample'</span>).<span class="hljs-title function_">setData</span>({<br> <span class="hljs-attr">records</span>: [{<br> <span class="hljs-attr">name</span>: <span class="hljs-string">'Dustin'</span>,<br> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">'(111) 111-1111'</span>,<br> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">'dustin@mailserver.com'</span>,<br> <span class="hljs-attr">gender</span>: <span class="hljs-string">'Male'</span><br> }, {<br> <span class="hljs-attr">name</span>: <span class="hljs-string">'Kayla'</span>,<br> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">'(222) 222-2222'</span>,<br> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">'kayla@mailserver.com'</span>,<br> <span class="hljs-attr">gender</span>: <span class="hljs-string">'Female'</span><br> }, {<br> <span class="hljs-attr">name</span>: <span class="hljs-string">'Alexander'</span>,<br> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">'(333) 333-33333'</span>,<br> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">'alex@mailserver.com'</span>,<br> <span class="hljs-attr">gender</span>: <span class="hljs-string">'Male'</span><br> }, {<br> <span class="hljs-attr">name</span>: <span class="hljs-string">'Amelia'</span>,<br> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">'(444) 444-44444'</span>,<br> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">'amelia@mailserver.com'</span>,<br> <span class="hljs-attr">gender</span>: <span class="hljs-string">'Female'</span><br> }]<br> });<br></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span></code></pre>
|
|
54
55
|
</k-card>
|
|
55
56
|
<k-card label="Results">
|
|
56
57
|
<k-table id="basicUsageExample"></k-table>
|