kempo-ui 0.0.79 → 0.0.80
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.
|
@@ -88,79 +88,8 @@ Do not prefix identifiers with underscores.
|
|
|
88
88
|
- Use clear, descriptive names without prefixes.
|
|
89
89
|
- When true privacy is needed inside classes, prefer native JavaScript private fields (e.g., `#myField`) instead of simulated privacy via underscores.
|
|
90
90
|
|
|
91
|
-
## Components
|
|
92
|
-
|
|
93
|
-
### Base Component Architecture
|
|
94
|
-
|
|
95
|
-
The project provides three base components for different rendering strategies. Choose the appropriate base component and extend it:
|
|
96
|
-
|
|
97
|
-
#### ShadowComponent
|
|
98
|
-
For components that need shadow DOM encapsulation and automatic `/kempo.css` stylesheet injection.
|
|
99
|
-
|
|
100
|
-
```javascript
|
|
101
|
-
import ShadowComponent from './ShadowComponent.js';
|
|
102
|
-
|
|
103
|
-
export default class MyComponent extends ShadowComponent {
|
|
104
|
-
render() {
|
|
105
|
-
return html`<p>Shadow DOM content with scoped styles</p>`;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
#### LightComponent
|
|
111
|
-
For components that render directly to light DOM without shadow DOM encapsulation.
|
|
112
|
-
|
|
113
|
-
```javascript
|
|
114
|
-
import LightComponent from './LightComponent.js';
|
|
115
|
-
|
|
116
|
-
export default class MyComponent extends LightComponent {
|
|
117
|
-
renderLightDom() {
|
|
118
|
-
return html`<p>Light DOM content</p>`;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
#### HybridComponent
|
|
124
|
-
For components that need both shadow DOM (with automatic `/kempo.css`) and light DOM rendering.
|
|
125
|
-
|
|
126
|
-
```javascript
|
|
127
|
-
import HybridComponent from './HybridComponent.js';
|
|
128
|
-
|
|
129
|
-
export default class MyComponent extends HybridComponent {
|
|
130
|
-
render() {
|
|
131
|
-
return html`<p>Shadow DOM content</p>`;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
renderLightDom() {
|
|
135
|
-
return html`<p>Light DOM content alongside natural children</p>`;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
**Important:** Always call `super.updated()` when overriding the `updated()` method in LightComponent or HybridComponent to ensure proper rendering.
|
|
141
|
-
|
|
142
|
-
### Component Architecture and Communication
|
|
143
|
-
|
|
144
|
-
- Use methods to cause actions; do not emit events to trigger logic. Events are for notifying that something already happened.
|
|
145
|
-
- Prefer `el.closest('ktf-test-framework')?.enqueueSuite({...})` over firing an `enqueue` event.
|
|
146
|
-
|
|
147
|
-
- Wrap dependent components inside a parent `ktf-test-framework` element. Children find it via `closest('ktf-test-framework')` and call its methods. The framework can query its subtree to orchestrate children.
|
|
148
|
-
|
|
149
|
-
- Avoid `window` globals and global custom events for coordination. If broadcast is needed, scope events to the framework element; reserve window events for global, non-visual concerns (e.g., settings changes).
|
|
150
|
-
|
|
151
91
|
## Development Workflow
|
|
152
92
|
|
|
153
|
-
### Icons
|
|
154
|
-
- All icons are stored in the `icons/` directory as SVG files
|
|
155
|
-
- Icons should have no `width` or `height` attributes, and use `fill="currentColor"` for theming
|
|
156
|
-
- To download new Material Icons from Google's CDN:
|
|
157
|
-
```bash
|
|
158
|
-
npm run geticon icon_name
|
|
159
|
-
```
|
|
160
|
-
Example: `npm run geticon format_bold`
|
|
161
|
-
- The script automatically formats the icon with proper attributes
|
|
162
|
-
- Browse available icons at [Google Material Symbols](https://fonts.google.com/icons)
|
|
163
|
-
|
|
164
93
|
### Local Development Server
|
|
165
94
|
- **DO NOT** start a development server - one is already running
|
|
166
95
|
- Default port: **8083**
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: new-component
|
|
3
|
+
description: Creates a new Kempo UI web component — choosing the right base class, writing the source file, registering the custom element, and adding documentation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# New Component
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
|
|
10
|
+
Use this skill any time you are asked to create a new component or add a new custom element to the project.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
Creating a component involves four steps:
|
|
17
|
+
|
|
18
|
+
1. **Choose the base component** — pick the right rendering strategy
|
|
19
|
+
2. **Write the source file** in `src/components/`
|
|
20
|
+
3. **Register the custom element** at the bottom of the source file
|
|
21
|
+
4. **Add documentation** in `docs/components/`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Step 1: Choose the Base Component
|
|
26
|
+
|
|
27
|
+
Three base classes are available. Pick based on rendering needs:
|
|
28
|
+
|
|
29
|
+
### `ShadowComponent`
|
|
30
|
+
Use when the component needs shadow DOM encapsulation. The base class automatically injects the `/kempo.css` stylesheet into the shadow root.
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
import { html } from '../lit-all.min.js';
|
|
34
|
+
import ShadowComponent from './ShadowComponent.js';
|
|
35
|
+
|
|
36
|
+
export default class MyComponent extends ShadowComponent {
|
|
37
|
+
render() {
|
|
38
|
+
return html`<p>Shadow DOM content with scoped styles</p>`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### `LightComponent`
|
|
44
|
+
Use when the component renders to the light DOM (no encapsulation, inherits page styles).
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
import { html } from '../lit-all.min.js';
|
|
48
|
+
import LightComponent from './LightComponent.js';
|
|
49
|
+
|
|
50
|
+
export default class MyComponent extends LightComponent {
|
|
51
|
+
renderLightDom() {
|
|
52
|
+
return html`<p>Light DOM content</p>`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `HybridComponent`
|
|
58
|
+
Use when the component needs both a shadow DOM portion and a light DOM portion (e.g. slotted children that also need managed light DOM output).
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
import { html } from '../lit-all.min.js';
|
|
62
|
+
import HybridComponent from './HybridComponent.js';
|
|
63
|
+
|
|
64
|
+
export default class MyComponent extends HybridComponent {
|
|
65
|
+
render() {
|
|
66
|
+
return html`<p>Shadow DOM content</p>`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
renderLightDom() {
|
|
70
|
+
return html`<p>Light DOM content alongside natural children</p>`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Important:** Always call `super.updated()` when overriding the `updated()` method in `LightComponent` or `HybridComponent`.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Step 2: Write the Source File
|
|
80
|
+
|
|
81
|
+
Create `src/components/MyComponent.js`. Follow these conventions:
|
|
82
|
+
|
|
83
|
+
- Use multi-line comments to separate logical sections: `Lifecycle Callbacks`, `Event Handlers`, `Public Methods`, `Utility Functions`, `Rendering`, `Styles`.
|
|
84
|
+
- Declare reactive properties with `static properties = { ... }` and initialize defaults in the constructor.
|
|
85
|
+
- Use `static styles = css\`...\`` for component-scoped CSS (shadow DOM only).
|
|
86
|
+
- Use arrow functions for class methods to avoid `.bind(this)`.
|
|
87
|
+
- Do not prefix private fields with underscores — use native JS private fields (`#field`) when true privacy is needed.
|
|
88
|
+
|
|
89
|
+
Example skeleton:
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
import { html, css } from '../lit-all.min.js';
|
|
93
|
+
import ShadowComponent from './ShadowComponent.js';
|
|
94
|
+
|
|
95
|
+
export default class MyComponent extends ShadowComponent {
|
|
96
|
+
static properties = {
|
|
97
|
+
value: { type: String, reflect: true }
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
Lifecycle Calblacks
|
|
102
|
+
*/
|
|
103
|
+
constructor(){
|
|
104
|
+
super();
|
|
105
|
+
this.value = 'default value';
|
|
106
|
+
}
|
|
107
|
+
connectedCallback(){
|
|
108
|
+
super.connectedCallback();
|
|
109
|
+
// Do things
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
Event Handlers
|
|
114
|
+
*/
|
|
115
|
+
handleClick = () => {
|
|
116
|
+
this.dispatchEvent(new CustomEvent('my-event', { bubbles: true, composed: true }));
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/*
|
|
120
|
+
Rendering
|
|
121
|
+
*/
|
|
122
|
+
render() {
|
|
123
|
+
return html`
|
|
124
|
+
<button @click=${this.handleClick}>${this.value}</button>
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
/*
|
|
128
|
+
Styles
|
|
129
|
+
*/
|
|
130
|
+
static styles = css`
|
|
131
|
+
:host {
|
|
132
|
+
display: block;
|
|
133
|
+
}
|
|
134
|
+
`;
|
|
135
|
+
|
|
136
|
+
/*
|
|
137
|
+
Static Methods
|
|
138
|
+
*/
|
|
139
|
+
static staticMethod(){
|
|
140
|
+
// Do things
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
customElements.define('k-my-component', MyComponent);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Custom element naming
|
|
148
|
+
- All elements use the `k-` prefix (e.g. `k-spinner`, `k-color-picker`).
|
|
149
|
+
- Use kebab-case for multi-word names.
|
|
150
|
+
- The `customElements.define(...)` call goes at the **bottom** of the file, after the class.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Step 3: Register in the Nav (if it should appear in docs)
|
|
155
|
+
|
|
156
|
+
Add a link to the component in `docs/nav.inc.html` inside the `<menu>` under the appropriate section, in alphabetical order:
|
|
157
|
+
|
|
158
|
+
```html
|
|
159
|
+
<a href="./components/my-component.html">My Component</a>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Step 4: Add Documentation
|
|
165
|
+
|
|
166
|
+
Create `docs/components/my-component.html`. Use an existing docs page (e.g. `docs/components/spinner.html`) as a reference for structure and conventions.
|
|
167
|
+
|
|
168
|
+
Key requirements:
|
|
169
|
+
- Consistent `<head>` with title, stylesheets, and `window.litDisableBundleWarning = true`.
|
|
170
|
+
- `<k-import src="../nav-1.inc.html"></k-import>` at the top of `<body>`.
|
|
171
|
+
- A Table of Contents accordion.
|
|
172
|
+
- Sections for: examples/usage, and a JavaScript Reference covering constructor, attributes/properties, CSS variables, events, and public methods (as applicable).
|
|
173
|
+
- Use the `highlight-code` skill for all code examples that need syntax highlighting.
|
|
174
|
+
- At the bottom of the file, load the component and its dependencies as `<script type="module">` tags:
|
|
175
|
+
|
|
176
|
+
```html
|
|
177
|
+
<script type="module" src="../src/components/MyComponent.js"></script>
|
|
178
|
+
<script type="module" src="../src/components/Import.js"></script>
|
|
179
|
+
<script type="module" src="../src/components/Accordion.js"></script>
|
|
180
|
+
<script type="module" src="../src/components/Card.js"></script>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Component Architecture and Communication
|
|
186
|
+
|
|
187
|
+
- Use **methods** to trigger actions. Events notify that something already happened; they should not be used to trigger logic.
|
|
188
|
+
- Prefer `el.closest('k-parent')?.doSomething()` over dispatching an event and listening for it.
|
|
189
|
+
- Child components should locate their parent via `closest('k-parent-element')` and call its methods directly.
|
|
190
|
+
- Avoid `window` globals and global custom events for coordination. Scope events to the relevant element; reserve `window` events for global, non-visual concerns (e.g. settings changes).
|
package/dist/components/Table.js
CHANGED
|
@@ -34,11 +34,11 @@ import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowCompon
|
|
|
34
34
|
</select>
|
|
35
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`
|
|
36
36
|
<td class="cell controls controls-before">
|
|
37
|
-
|
|
37
|
+
<div>${e}</div>
|
|
38
38
|
</td>
|
|
39
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`
|
|
40
40
|
<td class="cell controls controls-after">
|
|
41
|
-
|
|
41
|
+
<div>${e}</div>
|
|
42
42
|
</td>
|
|
43
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`
|
|
44
44
|
<div id="wrapper">
|
|
@@ -154,8 +154,8 @@ import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowCompon
|
|
|
154
154
|
td.controls {
|
|
155
155
|
padding: 0;
|
|
156
156
|
}
|
|
157
|
-
td.controls-after,
|
|
158
|
-
td.controls-before {
|
|
157
|
+
td.controls-after > div,
|
|
158
|
+
td.controls-before > div {
|
|
159
159
|
display: flex;
|
|
160
160
|
align-items: center;
|
|
161
161
|
}
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
<li><a href="./tableSorting.html">Sorting</a></li>
|
|
103
103
|
<li><a href="./tableFieldSortHide.html">Field Sorting and Hiding</a></li>
|
|
104
104
|
<li><a href="./tableFetchRecords.html">Fetching Records</a></li>
|
|
105
|
+
<li><a href="./tableServerSync.html">Server Sync</a></li>
|
|
105
106
|
</ul>
|
|
106
107
|
|
|
107
108
|
<br />
|
|
@@ -34,11 +34,11 @@ import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowCompon
|
|
|
34
34
|
</select>
|
|
35
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`
|
|
36
36
|
<td class="cell controls controls-before">
|
|
37
|
-
|
|
37
|
+
<div>${e}</div>
|
|
38
38
|
</td>
|
|
39
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`
|
|
40
40
|
<td class="cell controls controls-after">
|
|
41
|
-
|
|
41
|
+
<div>${e}</div>
|
|
42
42
|
</td>
|
|
43
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`
|
|
44
44
|
<div id="wrapper">
|
|
@@ -154,8 +154,8 @@ import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowCompon
|
|
|
154
154
|
td.controls {
|
|
155
155
|
padding: 0;
|
|
156
156
|
}
|
|
157
|
-
td.controls-after,
|
|
158
|
-
td.controls-before {
|
|
157
|
+
td.controls-after > div,
|
|
158
|
+
td.controls-before > div {
|
|
159
159
|
display: flex;
|
|
160
160
|
align-items: center;
|
|
161
161
|
}
|
package/package.json
CHANGED
package/src/components/Table.js
CHANGED
|
@@ -280,7 +280,7 @@ export default class Table extends ShadowComponent {
|
|
|
280
280
|
});
|
|
281
281
|
return html`
|
|
282
282
|
<td class="cell controls controls-before">
|
|
283
|
-
|
|
283
|
+
<div>${controls}</div>
|
|
284
284
|
</td>
|
|
285
285
|
`;
|
|
286
286
|
}
|
|
@@ -298,7 +298,7 @@ export default class Table extends ShadowComponent {
|
|
|
298
298
|
});
|
|
299
299
|
return html`
|
|
300
300
|
<td class="cell controls controls-after">
|
|
301
|
-
|
|
301
|
+
<div>${controls}</div>
|
|
302
302
|
</td>
|
|
303
303
|
`;
|
|
304
304
|
}
|
|
@@ -1131,8 +1131,8 @@ export default class Table extends ShadowComponent {
|
|
|
1131
1131
|
td.controls {
|
|
1132
1132
|
padding: 0;
|
|
1133
1133
|
}
|
|
1134
|
-
td.controls-after,
|
|
1135
|
-
td.controls-before {
|
|
1134
|
+
td.controls-after > div,
|
|
1135
|
+
td.controls-before > div {
|
|
1136
1136
|
display: flex;
|
|
1137
1137
|
align-items: center;
|
|
1138
1138
|
}
|