kempo-ui 0.0.15 → 0.0.17
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/dist/components/Accordion.js +67 -0
- package/dist/components/LightComponent.js +1 -0
- package/dist/components/ShadowComponent.js +1 -0
- package/dist/components/Split.js +84 -0
- package/dist/components/Table.js +151 -0
- package/dist/{src/components → components}/Tabs.js +9 -8
- package/dist/{src/components → components}/Tree.js +0 -3
- package/dist/{src/components → components}/tableControls/FieldSortHide.js +1 -2
- package/dist/{src/components → components}/tableControls/Filters.js +2 -3
- package/docs/kempo-ui/components/accordion.html +28 -43
- package/docs/kempo-ui/components/card.html +24 -16
- package/docs/kempo-ui/components/content-slider.html +101 -78
- package/docs/kempo-ui/components/dialog.html +24 -20
- package/docs/kempo-ui/components/focus-capture.html +21 -16
- package/docs/kempo-ui/components/hybrid-component.html +13 -10
- package/docs/kempo-ui/components/icon.html +36 -28
- package/docs/kempo-ui/components/import.html +36 -26
- package/docs/kempo-ui/components/light-component.html +44 -25
- package/docs/kempo-ui/components/photo-viewer.html +151 -103
- package/docs/kempo-ui/components/resize.html +27 -22
- package/docs/kempo-ui/components/shadow-component.html +37 -22
- package/docs/kempo-ui/components/show-more.html +23 -18
- package/docs/kempo-ui/components/side-menu.html +1 -1
- package/docs/kempo-ui/components/sortable.html +20 -15
- package/docs/kempo-ui/components/split.html +60 -33
- package/docs/kempo-ui/components/table.html +71 -100
- package/docs/kempo-ui/components/tableControls.html +7 -3
- package/docs/kempo-ui/components/tableCustomFields.html +6 -3
- package/docs/kempo-ui/components/tablePagination.html +12 -10
- package/docs/kempo-ui/components/tableRecordEditing.html +7 -4
- package/docs/kempo-ui/components/tableRecordFiltering.html +1 -1
- package/docs/kempo-ui/components/tableRecordHiding.html +9 -6
- package/docs/kempo-ui/components/tableRecordSelection.html +6 -4
- package/docs/kempo-ui/components/tableRowControls.html +7 -6
- package/docs/kempo-ui/components/tabs.html +41 -91
- package/docs/kempo-ui/components/tags.html +85 -38
- package/docs/kempo-ui/components/theme-switcher.html +12 -7
- package/docs/kempo-ui/components/timestamp.html +78 -29
- package/docs/kempo-ui/components/toast.html +194 -154
- package/docs/kempo-ui/components/toggle.html +13 -8
- package/docs/kempo-ui/components/tree.html +48 -40
- package/docs/kempo-ui/index.html +0 -6
- package/docs/kempo-ui/nav.inc.html +0 -1
- package/docs/kempo-ui/nav.inc.js +12 -0
- package/docs/kempo-ui/src/components/Accordion.js +40 -9
- package/docs/kempo-ui/src/components/LightComponent.js +1 -1
- package/docs/kempo-ui/src/components/ShadowComponent.js +1 -1
- package/docs/kempo-ui/src/components/SideMenu.js +1 -1
- package/docs/kempo-ui/src/components/Split.js +1 -1
- package/docs/kempo-ui/src/components/Table.js +77 -77
- package/docs/kempo-ui/src/components/Tabs.js +9 -8
- package/docs/kempo-ui/src/components/Tree.js +0 -3
- package/docs/kempo-ui/src/components/tableControls/FieldSortHide.js +1 -2
- package/docs/kempo-ui/src/components/tableControls/Filters.js +2 -3
- package/docs/kempo-ui/src/kempo-hljs.css +1 -0
- package/docs/kempo-ui/src/kempo-vars.css +1 -0
- package/docs/kempo-ui/utils/debounce.html +16 -15
- package/docs/kempo-ui/utils/drag.html +22 -19
- package/docs/kempo-ui/utils/propConverters.html +4 -4
- package/package.json +2 -2
- package/scripts/build.js +5 -5
- package/src/components/LightComponent.js +22 -0
- package/src/components/ShadowComponent.js +23 -0
- package/src/components/SideMenu.js +1 -1
- package/src/components/Split.js +16 -8
- package/src/components/Table.js +112 -95
- package/src/components/Tree.js +0 -3
- package/src/components/tableControls/FieldSortHide.js +1 -1
- package/src/components/tableControls/Filters.js +2 -3
- package/dist/src/components/Accordion.js +0 -36
- package/dist/src/components/Collapsible.js +0 -41
- package/dist/src/components/LightComponent.js +0 -1
- package/dist/src/components/PersistantCollapsible.js +0 -1
- package/dist/src/components/ShadowComponent.js +0 -1
- package/dist/src/components/Split.js +0 -84
- package/dist/src/components/Table.js +0 -151
- package/dist/src/utils/watchWindowSize.js +0 -1
- package/docs/kempo-ui/src/components/Collapsible.js +0 -41
- package/docs/kempo-ui/src/components/PersistantCollapsible.js +0 -1
- package/docs/kempo-ui/src/utils/watchWindowSize.js +0 -1
- package/docs/kempo-ui/utils/watchWindowSize.html +0 -72
- package/src/utils/watchWindowSize.js +0 -16
- /package/dist/{src/components → components}/Card.js +0 -0
- /package/dist/{src/components → components}/ContentSlider.js +0 -0
- /package/dist/{src/components → components}/Dialog.js +0 -0
- /package/dist/{src/components → components}/FocusCapture.js +0 -0
- /package/dist/{src/components → components}/HybridComponent.js +0 -0
- /package/dist/{src/components → components}/Icon.js +0 -0
- /package/dist/{src/components → components}/Import.js +0 -0
- /package/dist/{src/components → components}/PhotoViewer.js +0 -0
- /package/dist/{src/components → components}/Resize.js +0 -0
- /package/dist/{src/components → components}/ShowMore.js +0 -0
- /package/dist/{src/components → components}/SideMenu.js +0 -0
- /package/dist/{src/components → components}/Sortable.js +0 -0
- /package/dist/{src/components → components}/Tags.js +0 -0
- /package/dist/{src/components → components}/ThemeSwitcher.js +0 -0
- /package/dist/{src/components → components}/Timestamp.js +0 -0
- /package/dist/{src/components → components}/Toast.js +0 -0
- /package/dist/{src/components → components}/Toggle.js +0 -0
- /package/dist/{src/components → components}/tableControls/DeleteRecord.js +0 -0
- /package/dist/{src/components → components}/tableControls/Edit.js +0 -0
- /package/dist/{src/components → components}/tableControls/ExportCSV.js +0 -0
- /package/dist/{src/components → components}/tableControls/ExportJson.js +0 -0
- /package/dist/{src/components → components}/tableControls/FirstPage.js +0 -0
- /package/dist/{src/components → components}/tableControls/HiddenCount.js +0 -0
- /package/dist/{src/components → components}/tableControls/Hide.js +0 -0
- /package/dist/{src/components → components}/tableControls/LastPage.js +0 -0
- /package/dist/{src/components → components}/tableControls/NextPage.js +0 -0
- /package/dist/{src/components → components}/tableControls/PageSelect.js +0 -0
- /package/dist/{src/components → components}/tableControls/PageSize.js +0 -0
- /package/dist/{src/components → components}/tableControls/PrevPage.js +0 -0
- /package/dist/{src/components → components}/tableControls/Search.js +0 -0
- /package/dist/{src/components → components}/tableControls/ShowAll.js +0 -0
- /package/dist/{src/components → components}/tableControls/TableControl.js +0 -0
- /package/dist/{src/lit-all.min.js → lit-all.min.js} +0 -0
- /package/dist/{src/utils → utils}/debounce.js +0 -0
- /package/dist/{src/utils → utils}/drag.js +0 -0
- /package/dist/{src/utils → utils}/formatTimestamp.js +0 -0
- /package/dist/{src/utils → utils}/propConverters.js +0 -0
- /package/dist/{src/utils → utils}/toTitleCase.js +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";import{boolExists,boolTrueFalse}from"../utils/propConverters.js";export default class Accordion extends ShadowComponent{static properties={multiple:{type:Boolean,reflect:!0,converter:boolExists},persistentId:{type:String,reflect:!0,attribute:"persistent-id"}};constructor(){super(),this.multiple=!1,this.persistentId=null}connectedCallback(){super.connectedCallback?.()}updated(e){if(super.updated?.(e),e.has("persistentId")&&this.persistentId&&window?.localStorage){const e=`accordion-persistent-id-${this.persistentId}`,t=window.localStorage.getItem(e);if(t){const e=t.split(",");this.querySelectorAll("k-accordion-panel").forEach(t=>{t.active=e.includes(t.name);const o=this.getHeader(t.name);o&&(o.active=e.includes(t.name))})}}}getHeader(e){return this.querySelector(`k-accordion-header[for-panel="${e}"]`)}getPanel(e){return this.querySelector(`k-accordion-panel[name="${e}"]`)}openPanel(e){this.multiple||this.querySelectorAll("k-accordion-panel[active]").forEach(t=>{if(t.name!==e){t.active=!1;const e=this.getHeader(t.name);e&&(e.active=!1)}});const t=this.getPanel(e);if(t){t.active=!0,t.transitioning=!0,setTimeout(()=>{t.transitioning=!1},parseInt(getComputedStyle(this).getPropertyValue("--animation_ms")||256));const o=this.getHeader(e);o&&(o.active=!0),this.dispatchEvent(new CustomEvent("openpanel",{detail:{panelName:e}})),setTimeout(()=>{if(this.persistentId&&window?.localStorage){const e=`accordion-persistent-id-${this.persistentId}`,t=Array.from(this.querySelectorAll("k-accordion-panel[active]")).map(e=>e.name);window.localStorage.setItem(e,t.join(","))}},parseInt(getComputedStyle(this).getPropertyValue("--animation_ms")||256))}}closePanel(e){const t=this.getPanel(e);if(t){t.active=!1,t.transitioning=!0,setTimeout(()=>{t.transitioning=!1},parseInt(getComputedStyle(this).getPropertyValue("--animation_ms")||256));const o=this.getHeader(e);o&&(o.active=!1),this.dispatchEvent(new CustomEvent("closepanel",{detail:{panelName:e}})),setTimeout(()=>{if(this.persistentId&&window?.localStorage){const e=`accordion-persistent-id-${this.persistentId}`,t=Array.from(this.querySelectorAll("k-accordion-panel[active]")).map(e=>e.name);window.localStorage.setItem(e,t.join(","))}},parseInt(getComputedStyle(this).getPropertyValue("--animation_ms")||256))}}togglePanel(e){const t=this.getPanel(e);t&&(t.active?this.closePanel(e):this.openPanel(e),this.dispatchEvent(new CustomEvent("togglepanel",{detail:{panelName:e}})))}get activeHeader(){return this.querySelector('k-accordion-header[active="true"]')}get activePanel(){return this.querySelector('k-accordion-panel[active="true"]')}static styles=css`
|
|
2
|
+
:host {
|
|
3
|
+
display: block;
|
|
4
|
+
border: 1px solid var(--c_border, #ccc);
|
|
5
|
+
border-radius: var(--radius);
|
|
6
|
+
}
|
|
7
|
+
::slotted(k-accordion-header) {
|
|
8
|
+
border-top: 1px solid var(--c_border, #ccc);
|
|
9
|
+
}
|
|
10
|
+
::slotted(k-accordion-header) {
|
|
11
|
+
position: relative;
|
|
12
|
+
}
|
|
13
|
+
::slotted(k-accordion-header)::after {
|
|
14
|
+
content: '';
|
|
15
|
+
display: block;
|
|
16
|
+
position: absolute;
|
|
17
|
+
left: var(--spacer_h, 0.5rem);
|
|
18
|
+
right: var(--spacer_h, 0.5rem);
|
|
19
|
+
bottom: 0;
|
|
20
|
+
height: 0;
|
|
21
|
+
width: calc(100% - var(--spacer, 1rem));
|
|
22
|
+
border-bottom: 1px solid var(--c_border, #ccc);
|
|
23
|
+
opacity: 0;
|
|
24
|
+
transition: opacity var(--animation_ms, 256ms);
|
|
25
|
+
pointer-events: none;
|
|
26
|
+
}
|
|
27
|
+
::slotted(k-accordion-header[active])::after {
|
|
28
|
+
opacity: 0.4;
|
|
29
|
+
}
|
|
30
|
+
::slotted(k-accordion-header:first-of-type) {
|
|
31
|
+
border-top: 0;
|
|
32
|
+
}
|
|
33
|
+
::slotted(k-accordion-header:last-of-type:not([active])) {
|
|
34
|
+
border-bottom: 0;
|
|
35
|
+
}
|
|
36
|
+
`;render(){return html`<slot></slot>`}}export class AccordionHeader extends ShadowComponent{static properties={forPanel:{type:String,reflect:!0,attribute:"for-panel"},active:{type:Boolean,reflect:!0,converter:boolExists}};constructor(){super(),this.forPanel="",this.active=!1}handleClick=()=>{this.accordion?.togglePanel(this.forPanel)};connectedCallback(){super.connectedCallback(),this.addEventListener("click",this.handleClick)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("click",this.handleClick)}get accordion(){return this.closest("k-accordion")}render(){return html`
|
|
37
|
+
<slot name="left-icon">
|
|
38
|
+
<k-icon id="icon" name="chevron-right"></k-icon>
|
|
39
|
+
</slot>
|
|
40
|
+
<slot></slot>
|
|
41
|
+
<slot name="right-icon"></slot>
|
|
42
|
+
`}static styles=css`
|
|
43
|
+
:host {
|
|
44
|
+
display: block;
|
|
45
|
+
padding: 1rem;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
}
|
|
48
|
+
#icon {
|
|
49
|
+
will-change: trnasform;
|
|
50
|
+
transition: transform var(--animation_ms, 256ms);
|
|
51
|
+
transform: rotate(0deg);
|
|
52
|
+
}
|
|
53
|
+
:host([active]) #icon {
|
|
54
|
+
transform: rotate(90deg);
|
|
55
|
+
}
|
|
56
|
+
`}export class AccordionPanel extends ShadowComponent{static properties={name:{type:String,reflect:!0},active:{type:Boolean,reflect:!0,converter:boolExists},transitioning:{type:Boolean,reflect:!0,converter:boolExists}};constructor(){super(),this.name="",this.active=!1,this.transitioning=!1}get accordion(){return this.closest("k-accordion")}static styles=css`
|
|
57
|
+
:host {
|
|
58
|
+
display: block;
|
|
59
|
+
interpolate-size: allow-keywords;
|
|
60
|
+
height: 0;
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
transition: height var(--animation_ms, 256ms) ease-in-out;
|
|
63
|
+
}
|
|
64
|
+
:host([active]) {
|
|
65
|
+
height: max-content;
|
|
66
|
+
}
|
|
67
|
+
`;render(){return html`<slot></slot>`}}customElements.define("k-accordion",Accordion),customElements.define("k-accordion-header",AccordionHeader),customElements.define("k-accordion-panel",AccordionPanel);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LitElement,html,render}from"../lit-all.min.js";export default class LightComponent extends LitElement{#e;createRenderRoot(){return this.lightRoot=document.createElement("div"),this.lightRoot.style.display="contents",this.appendChild(this.lightRoot),this}connectedCallback(){super.connectedCallback(),this.#e=new MutationObserver(()=>{this.childrenUpdated(),this.requestUpdate()}),this.#e.observe(this,{childList:!0})}disconnectedCallback(){super.disconnectedCallback(),this.#e?.disconnect()}updated(){render(this.renderLightDom(),this.lightRoot)}childrenUpdated(){}renderLightDom(){return html``}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LitElement}from"../lit-all.min.js";export default class ShadowComponent extends LitElement{static stylesheetPath="./kempo.min.css";#e;connectedCallback(){super.connectedCallback(),this.#e=new MutationObserver(()=>{console.log("MutationObserver fired for",this.constructor.name),this.childrenUpdated(),this.requestUpdate()}),this.#e.observe(this,{childList:!0})}disconnectedCallback(){super.disconnectedCallback(),this.#e?.disconnect()}childrenUpdated(){}createRenderRoot(){const e=this.attachShadow({mode:"open"}),t=document.createElement("link");t.rel="stylesheet",t.href=this.constructor.stylesheetPath,e.appendChild(t);const n=this.constructor.styles;if(n){const t=document.createElement("style");Array.isArray(n)?t.textContent=n.map(e=>e.cssText||e).join("\n"):t.textContent=n.cssText||n,e.appendChild(t)}const s=document.createElement("div");return s.style.display="contents",e.appendChild(s),s}}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import drag from"../utils/drag.js";export default class Split extends ShadowComponent{static properties={resizing:{type:Boolean,reflect:!0},stacked:{type:Boolean,reflect:!0},stackWidth:{type:Number,attribute:"stack-width"}};constructor(){super(),this.resizing=!1,this.stacked=!1,this.stackWidth=0,this.dragStartWidth=0,this.dragCleanup=()=>{},this.resizeObserver=null}firstUpdated(){super.firstUpdated(),this.setupDragHandler(),this.setupResizeObserver()}disconnectedCallback(){super.disconnectedCallback(),this.dragCleanup(),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}handleDragStart=()=>{this.resizing=!0,this.dragStartWidth=Math.round(this.shadowRoot.getElementById("left").getBoundingClientRect().width),this.dispatchEvent(new CustomEvent("resizestart",{detail:{startSize:this.dragStartWidth},bubbles:!0}))};handleDrag=({x:e})=>{const t=`${this.dragStartWidth+e}px`;this.setSize(t),this.dispatchEvent(new CustomEvent("resize",{detail:{size:t},bubbles:!0}))};handleDragEnd=({x:e})=>{this.resizing=!1;const t=`${this.dragStartWidth+e}px`;this.setSize(t),this.dispatchEvent(new CustomEvent("resizeend",{detail:{size:t},bubbles:!0}))};setSize(e){this.style.setProperty("--left_width",e)}setupDragHandler(){const e=this.shadowRoot.getElementById("divider-handle");e&&(this.dragCleanup=drag({element:e,callback:this.handleDrag,startCallback:this.handleDragStart,endCallback:this.handleDragEnd}))}setupResizeObserver(){this.resizeObserver=new ResizeObserver(e=>{for(const t of e){const e=t.contentRect.width;this.stacked=e<=this.stackWidth}}),this.resizeObserver.observe(this)}static styles=css`
|
|
2
|
+
:host {
|
|
3
|
+
--left_width: calc((100% - var(--handle_width)) / 2);
|
|
4
|
+
--handle_width: 0.5rem;
|
|
5
|
+
--min_pane_width: 6rem;
|
|
6
|
+
|
|
7
|
+
height: 100%;
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: stretch;
|
|
10
|
+
flex: 1 1 auto;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.pane, #divider-handle {
|
|
15
|
+
display: inline-block;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.pane {
|
|
19
|
+
min-width: var(--min_pane_width);
|
|
20
|
+
max-width: calc(100% - var(--min_pane_width));
|
|
21
|
+
max-height: 100%;
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#left {
|
|
26
|
+
flex: 0 0 var(--left_width);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#divider-handle {
|
|
30
|
+
display: flex;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
width: var(--handle_width);
|
|
33
|
+
cursor: ew-resize;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:host([resizing]) #divider-handle {
|
|
37
|
+
background-color: var(--tc_primary);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
:host([resizing]) .pane {
|
|
41
|
+
pointer-events: none;
|
|
42
|
+
user-select: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
#divider-border {
|
|
46
|
+
width: 1px;
|
|
47
|
+
height: 100%;
|
|
48
|
+
border-left: 1px solid var(--c_border);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#right {
|
|
52
|
+
flex: 1 1;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
:host([stacked]) #left,
|
|
56
|
+
:host([stacked]) #right {
|
|
57
|
+
display: block;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:host([stacked]) #divider-handle {
|
|
61
|
+
display: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
:host([stacked]) .pane {
|
|
65
|
+
min-width: 0;
|
|
66
|
+
max-width: 100%;
|
|
67
|
+
max-height: none;
|
|
68
|
+
overflow: auto;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:host([stacked]) {
|
|
72
|
+
display: block;
|
|
73
|
+
}
|
|
74
|
+
`;render(){return html`
|
|
75
|
+
<div id="left" class="pane">
|
|
76
|
+
<slot></slot>
|
|
77
|
+
</div>
|
|
78
|
+
<div id="divider-handle">
|
|
79
|
+
<div id="divider-border"></div>
|
|
80
|
+
</div>
|
|
81
|
+
<div id="right" class="pane">
|
|
82
|
+
<slot name="right"></slot>
|
|
83
|
+
</div>
|
|
84
|
+
`}}customElements.define("k-split",Split);
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import{html,css,unsafeStatic,literal}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import toTitleCase from"../utils/toTitleCase.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())}this.updateContainerWidths()}updateContainerWidths(){const e=this.columnSizes.total+"px",t=this.shadowRoot.getElementById("fields"),s=this.shadowRoot.getElementById("top"),i=this.shadowRoot.getElementById("bottom"),r=this.shadowRoot.getElementById("records");t&&(t.style.width=e),s&&(s.style.width=e),i&&(i.style.width=e),r&&(r.style.width=e)}renderFieldsTemplate(){this.calculateColumnSizes(),this.hasTopControls()?this.setAttribute("top-controls","true"):this.removeAttribute("top-controls"),this.hasBottomControls()?this.setAttribute("bottom-controls","true"):this.removeAttribute("bottom-controls");const e=[];return this.enableSelection&&e.push(html`
|
|
2
|
+
<div class="field controls cell field-select" style="width: 40px">
|
|
3
|
+
<input
|
|
4
|
+
type="checkbox"
|
|
5
|
+
id="select-all"
|
|
6
|
+
@change=${this.handleSelectAllChange}
|
|
7
|
+
/>
|
|
8
|
+
</div>
|
|
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;":""}"
|
|
15
|
+
@click=${this.enableSorting?()=>this.handleFieldClick(t):null}
|
|
16
|
+
>
|
|
17
|
+
${s}
|
|
18
|
+
${o?html`<k-icon name="${r.asc?"arrow-down":"arrow-up"}" class="icon-sort"></k-icon>`:""}
|
|
19
|
+
</div>
|
|
20
|
+
`)}),this.hasAfterControls()&&e.push(html`
|
|
21
|
+
<div class="field cell field-after-controls" style="width: ${this.columnSizes.afterControls}px"></div>
|
|
22
|
+
`),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`<div class="record fetching"><div class="cell">Loading...</div></div>`));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`
|
|
23
|
+
<div class="cell selection controls" style="width: 40px">
|
|
24
|
+
<input
|
|
25
|
+
type="checkbox"
|
|
26
|
+
.checked=${e[selected]}
|
|
27
|
+
@change=${t=>this.handleRecordSelectionChange(e,t)}
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
`),this.hasBeforeControls()&&t.push(this.renderBeforeControlsTemplate()),this.fields.forEach(({name:s,formatter:i,calculator:r,type:o,editor:l,hidden:n})=>{if(n)return;let a=e[s]||"";t.push(html`
|
|
31
|
+
<div class="cell" data-field=${s} style="width: ${this.columnSizes[s]}px">
|
|
32
|
+
${e[editing]?this.renderEditingCell(e,s,a,r,l,o):this.renderDisplayCell(e,s,a,r,i)}
|
|
33
|
+
</div>
|
|
34
|
+
`)}),this.hasAfterControls()&&t.push(this.renderAfterControlsTemplate()),html`
|
|
35
|
+
<div class="record ${e[editing]?"editing":""}" data-index=${e[index]}>
|
|
36
|
+
${t}
|
|
37
|
+
</div>
|
|
38
|
+
`}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
|
+
<select .value=${s}>
|
|
40
|
+
<option value="true" ?selected=${s}>True</option>
|
|
41
|
+
<option value="false" ?selected=${!s}>False</option>
|
|
42
|
+
</select>
|
|
43
|
+
`;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
|
+
<div class="cell controls controls-before" style="width: ${this.columnSizes.beforeControls}px">
|
|
45
|
+
${e}
|
|
46
|
+
</div>
|
|
47
|
+
`}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
|
+
<div class="cell controls controls-after" style="width: ${this.columnSizes.afterControls}px">
|
|
49
|
+
${e}
|
|
50
|
+
</div>
|
|
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`
|
|
52
|
+
<div id="wrapper">
|
|
53
|
+
<div id="top" style="width: ${this.columnSizes.total}px"><slot name="top"></slot></div>
|
|
54
|
+
<div id="table">
|
|
55
|
+
<div id="fields" style="width: ${this.columnSizes.total}px">
|
|
56
|
+
${this.renderFieldsTemplate()}
|
|
57
|
+
</div>
|
|
58
|
+
<div id="records" style="width: ${this.columnSizes.total}px">
|
|
59
|
+
${this.renderRecordsTemplate()}
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
<div id="bottom" style="width: ${this.columnSizes.total}px"><slot></slot></div>
|
|
63
|
+
</div>
|
|
64
|
+
<div style="display: none">
|
|
65
|
+
<slot name="before"></slot>
|
|
66
|
+
<slot name="after"></slot>
|
|
67
|
+
</div>
|
|
68
|
+
`):html`
|
|
69
|
+
<div id="wrapper">
|
|
70
|
+
<div id="top"><slot name="top"></slot></div>
|
|
71
|
+
<div id="table">
|
|
72
|
+
<div id="fields"></div>
|
|
73
|
+
<div id="records"></div>
|
|
74
|
+
</div>
|
|
75
|
+
<div id="bottom"><slot></slot></div>
|
|
76
|
+
</div>
|
|
77
|
+
<div style="display: none">
|
|
78
|
+
<slot name="before"></slot>
|
|
79
|
+
<slot name="after"></slot>
|
|
80
|
+
</div>
|
|
81
|
+
`}static styles=css`
|
|
82
|
+
:host {
|
|
83
|
+
display: block;
|
|
84
|
+
width: 100%;
|
|
85
|
+
overflow: auto;
|
|
86
|
+
margin-bottom: var(--spacer);
|
|
87
|
+
}
|
|
88
|
+
#wrapper {
|
|
89
|
+
width: min-content;
|
|
90
|
+
border: 1px solid var(--c_border);
|
|
91
|
+
border-radius: var(--radius);
|
|
92
|
+
}
|
|
93
|
+
#table {
|
|
94
|
+
width: min-content;
|
|
95
|
+
}
|
|
96
|
+
#fields,
|
|
97
|
+
.record {
|
|
98
|
+
display: flex;
|
|
99
|
+
}
|
|
100
|
+
#fields {
|
|
101
|
+
background-color: var(--c_bg__alt);
|
|
102
|
+
border-bottom: 1px solid var(--c_border);
|
|
103
|
+
}
|
|
104
|
+
.record:not([editing="true"]) .cell:not(.controls),
|
|
105
|
+
#fields .cell:not(.controls) {
|
|
106
|
+
padding: calc(0.5 * var(--spacer)) var(--spacer);
|
|
107
|
+
}
|
|
108
|
+
.cell {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
}
|
|
112
|
+
.cell:not(:first-child) {
|
|
113
|
+
border-left: 1px solid var(--c_border);
|
|
114
|
+
}
|
|
115
|
+
.record:not(:last-child) .cell {
|
|
116
|
+
border-bottom: 1px solid var(--c_border);
|
|
117
|
+
}
|
|
118
|
+
#top, #bottom {
|
|
119
|
+
display: flex;
|
|
120
|
+
width: 100%;
|
|
121
|
+
}
|
|
122
|
+
#top slot {
|
|
123
|
+
display: block;
|
|
124
|
+
width: 100%;
|
|
125
|
+
border-bottom: 1px solid var(--c_border);
|
|
126
|
+
}
|
|
127
|
+
#bottom slot {
|
|
128
|
+
display: block;
|
|
129
|
+
width: 100%;
|
|
130
|
+
border-top: 1px solid var(--c_border);
|
|
131
|
+
}
|
|
132
|
+
:host(:not([top-controls])) #top,
|
|
133
|
+
:host(:not([bottom-controls])) #bottom {
|
|
134
|
+
display: none;
|
|
135
|
+
}
|
|
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
|
+
`;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);
|
|
@@ -99,7 +99,11 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
|
|
|
99
99
|
<slot></slot>
|
|
100
100
|
</div>
|
|
101
101
|
</div>
|
|
102
|
-
`}}export class Tab extends ShadowComponent{static properties={active:{type:Boolean,reflect:!0,converter:boolExists},for:{type:String,reflect:!0}};constructor(){super(),this.active=!1,this.for="",this.slot="tabs"}handleClick=()=>{if(!this.active){const t=this.parentElement;t&&"K-TABS"===t.tagName&&(t.active=this.for||t.tabs.indexOf(this).toString())}};get tabs(){return"K-TABS"===this.parentElement?.tagName?this.parentElement:null}
|
|
102
|
+
`}}export class Tab extends ShadowComponent{static properties={active:{type:Boolean,reflect:!0,converter:boolExists},for:{type:String,reflect:!0}};constructor(){super(),this.active=!1,this.for="",this.slot="tabs"}handleClick=()=>{if(!this.active){const t=this.parentElement;t&&"K-TABS"===t.tagName&&(t.active=this.for||t.tabs.indexOf(this).toString())}};get tabs(){return"K-TABS"===this.parentElement?.tagName?this.parentElement:null}render(){return html`
|
|
103
|
+
<button id="button" @click=${this.handleClick}>
|
|
104
|
+
<slot></slot>
|
|
105
|
+
</button>
|
|
106
|
+
`}static styles=css`
|
|
103
107
|
:host {
|
|
104
108
|
margin-bottom: -1px;
|
|
105
109
|
flex: 0 0 auto;
|
|
@@ -120,24 +124,21 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
|
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
:host([active]) {
|
|
123
|
-
border-bottom:
|
|
127
|
+
border-bottom: 3px solid var(--c_primary);
|
|
124
128
|
margin-bottom: -1px;
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
:host([active]) #button {
|
|
128
132
|
color: var(--tc_primary);
|
|
129
133
|
}
|
|
130
|
-
|
|
131
|
-
<button id="button" @click=${this.handleClick}>
|
|
132
|
-
<slot></slot>
|
|
133
|
-
</button>
|
|
134
|
-
`}}export class TabContent extends ShadowComponent{static properties={active:{type:Boolean,reflect:!0,converter:boolExists},name:{type:String,reflect:!0}};constructor(){super(),this.active=!1,this.name=""}get tabs(){return"K-TABS"===this.parentElement?.tagName?this.parentElement:null}static styles=css`
|
|
134
|
+
`}export class TabContent extends ShadowComponent{static properties={active:{type:Boolean,reflect:!0,converter:boolExists},name:{type:String,reflect:!0}};constructor(){super(),this.active=!1,this.name=""}get tabs(){return"K-TABS"===this.parentElement?.tagName?this.parentElement:null}render(){return html`<slot></slot>`}static styles=css`
|
|
135
135
|
:host {
|
|
136
136
|
display: block;
|
|
137
137
|
height: 100%;
|
|
138
138
|
max-height: 100%;
|
|
139
139
|
flex: 1 1 auto;
|
|
140
140
|
overflow: auto;
|
|
141
|
+
padding-top: var(--spacer, 1rem);
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
:host([active]) {
|
|
@@ -147,7 +148,7 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
|
|
|
147
148
|
:host(:not([active])) {
|
|
148
149
|
display: none;
|
|
149
150
|
}
|
|
150
|
-
|
|
151
|
+
`}export class TabSpacer extends ShadowComponent{constructor(){super(),this.slot="tabs"}static styles=css`
|
|
151
152
|
:host {
|
|
152
153
|
flex: 1 1 auto !important;
|
|
153
154
|
height: 1px;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import TableControl from"./TableControl.js";import{html,render}from"../../lit-all.min.js";import"../Icon.js";import Dialog from"../Dialog.js";export default class FieldSortHide extends TableControl{constructor(){super({maxWidth:40})}handleClick=()=>{this.openDialog()};openDialog=()=>{import("../Sortable.js");const e=document.createElement("div");render(html`
|
|
2
|
-
<h3 class="m0 ph" slot="title">Show / Hide Fields</h3>
|
|
3
2
|
<div class="m">
|
|
4
3
|
<k-sortable id="sorting" @sort="${e=>{const t=Array.from(e.target.querySelectorAll("k-sortable-item")).map(e=>e.getAttribute("data-field"));this.table.reorderFields(t)}}">
|
|
5
4
|
${this.table.fields.map(e=>html`
|
|
@@ -19,7 +18,7 @@ import TableControl from"./TableControl.js";import{html,render}from"../../lit-al
|
|
|
19
18
|
`)}
|
|
20
19
|
</k-sortable>
|
|
21
20
|
</div>
|
|
22
|
-
`,e),Dialog.create(e,{width:"400px",cancelText:"Close"})};render(){return html`
|
|
21
|
+
`,e),Dialog.create(e,{title:"Show / Hide / Order Fields",width:"400px",cancelText:"Close"})};render(){return html`
|
|
23
22
|
<button class="no-btn icon-btn" @click="${this.handleClick}">
|
|
24
23
|
<k-icon name="table-visibility"></k-icon>
|
|
25
24
|
</button>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import TableControl from"./TableControl.js";import{html,render}from"../../lit-all.min.js";import"../Icon.js";import Dialog from"../Dialog.js";export default class Filters extends TableControl{constructor(){super({maxWidth:40})}handleFilter=()=>{this.openDialog()};openDialog=()=>{const t={equals:"equals","not-equals":"does not equal",contains:"contains","not-contains":"does not contain","greater-than":"is greater than","greater-than-or-equal":"is greater than or equal to","less-than":"is less than","less-than-or-equal":"is less than or equal to"},e=document.createElement("div");render(html`
|
|
2
|
-
<h3 slot="title" class="m0 pyh px">Filters</h3>
|
|
3
2
|
<div class="p">
|
|
4
3
|
${0===this.table.filters.length?html`
|
|
5
4
|
<p>No Current Filters.</p>
|
|
@@ -12,7 +11,7 @@ import TableControl from"./TableControl.js";import{html,render}from"../../lit-al
|
|
|
12
11
|
data-condition="${i}"
|
|
13
12
|
data-value="${o}"
|
|
14
13
|
>
|
|
15
|
-
${e} ${t[i]} ${o}
|
|
14
|
+
${this.table.getFieldLabel(e)} ${t[i]} "${o}"
|
|
16
15
|
<button class="remove-filter no-btn pq" @click="${t=>{this.table.removeFilter(e,i,o),l.close(),this.openDialog()}}">
|
|
17
16
|
<k-icon name="close"></k-icon>
|
|
18
17
|
</button>
|
|
@@ -40,7 +39,7 @@ import TableControl from"./TableControl.js";import{html,render}from"../../lit-al
|
|
|
40
39
|
`}
|
|
41
40
|
</form>
|
|
42
41
|
</div>
|
|
43
|
-
`,e);const l=Dialog.create(e,{width:"600px"})};render(){return html`
|
|
42
|
+
`,e);const l=Dialog.create(e,{width:"600px",title:"Filters"})};render(){return html`
|
|
44
43
|
<button class="no-btn icon-btn" @click="${this.handleFilter}">
|
|
45
44
|
<k-icon name="filter"></k-icon>
|
|
46
45
|
</button>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
|
|
4
3
|
<head>
|
|
5
4
|
<base href="/kempo-ui/">
|
|
6
5
|
<meta charset="UTF-8">
|
|
@@ -20,17 +19,17 @@
|
|
|
20
19
|
<k-accordion persistent-id="toc" class="b r mb">
|
|
21
20
|
<k-accordion-header for-panel="toc-panel">Table of Contents</k-accordion-header>
|
|
22
21
|
<k-accordion-panel name="toc-panel">
|
|
23
|
-
<div class="m
|
|
22
|
+
<div class="m ">
|
|
24
23
|
<h6>Examples</h6>
|
|
25
|
-
<a href="#basicUsage"
|
|
26
|
-
<a href="#defaultOpen"
|
|
27
|
-
<a href="#multiple"
|
|
28
|
-
<a href="#persistent"
|
|
29
|
-
<h6 class="mt"><a href="#jsRef" class="no-link
|
|
30
|
-
<a href="#accordion-ref"
|
|
31
|
-
<a href="#accordion-header-ref"
|
|
32
|
-
<a href="#accordion-panel-ref"
|
|
33
|
-
<a href="#events"
|
|
24
|
+
<a href="#basicUsage">Basic Usage</a><br />
|
|
25
|
+
<a href="#defaultOpen">Default Open Panel</a><br />
|
|
26
|
+
<a href="#multiple">Multiple Panels Mode</a><br />
|
|
27
|
+
<a href="#persistent">Persistent State Example</a><br />
|
|
28
|
+
<h6 class="mt"><a href="#jsRef" class="no-link">JavaScript Reference</a></h6>
|
|
29
|
+
<a href="#accordion-ref">Accordion</a><br />
|
|
30
|
+
<a href="#accordion-header-ref">AccordionHeader</a><br />
|
|
31
|
+
<a href="#accordion-panel-ref">AccordionPanel</a><br />
|
|
32
|
+
<a href="#events">Events</a><br />
|
|
34
33
|
</div>
|
|
35
34
|
</k-accordion-panel>
|
|
36
35
|
</k-accordion>
|
|
@@ -38,7 +37,7 @@
|
|
|
38
37
|
<h3>Description</h3>
|
|
39
38
|
<p>A widget that allows a single panel of content to be opened and closed.</p>
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
<h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
|
|
42
41
|
<div class="row -mx mb">
|
|
43
42
|
<div class="col d-span-6 m-span-12 px">
|
|
44
43
|
<k-card label="HTML">
|
|
@@ -67,10 +66,8 @@
|
|
|
67
66
|
|
|
68
67
|
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
<p>You can have a panel open by default by setting the <code>active</code> attribute to <code>true</code> on both
|
|
69
|
+
<h3 id="defaultOpen"><a href="#defaultOpen" class="no-link">Default Open Panel</a></h3>
|
|
72
70
|
<p>You can have a panel open by default by adding the <code>active</code> attribute to both the header and the
|
|
73
|
-
panel. The presence of the attribute means <code>true</code>.</p>
|
|
74
71
|
<div class="row -mx mb">
|
|
75
72
|
<div class="col d-span-6 m-span-12 px">
|
|
76
73
|
<k-card label="HTML">
|
|
@@ -97,7 +94,7 @@
|
|
|
97
94
|
</div>
|
|
98
95
|
</div>
|
|
99
96
|
|
|
100
|
-
|
|
97
|
+
<h3 id="multiple"><a href="#multiple" class="no-link">Multiple Panels Mode</a></h3>
|
|
101
98
|
<p>Add the <code>multiple</code> attribute to <code>k-accordion</code> to allow more than one panel to be open at a
|
|
102
99
|
time.</p>
|
|
103
100
|
<div class="row -mx mb">
|
|
@@ -126,7 +123,7 @@
|
|
|
126
123
|
</div>
|
|
127
124
|
</div>
|
|
128
125
|
|
|
129
|
-
|
|
126
|
+
<h3 id="persistent"><a href="#persistent" class="no-link">Persistent State Example</a></h3>
|
|
130
127
|
<p>Add the <code>persistent-id</code> attribute to <code>k-accordion</code> to save and restore open panels across
|
|
131
128
|
page reloads. The state is stored in <code>localStorage</code> (if available) using the provided ID.</p>
|
|
132
129
|
<div class="row -mx mb">
|
|
@@ -155,13 +152,13 @@
|
|
|
155
152
|
</div>
|
|
156
153
|
</div>
|
|
157
154
|
|
|
158
|
-
|
|
155
|
+
<h2 id="jsRef"><a href="#jsRef" class="no-link">JavaScript Reference</a></h2>
|
|
159
156
|
<k-card>
|
|
160
157
|
<h3 id="accordion-ref" class="bb pb">Accordion</h3>
|
|
161
158
|
<h4>Properties</h4>
|
|
162
159
|
<ul>
|
|
163
|
-
<li><code>multiple: boolean</code>
|
|
164
|
-
<li><code>persistentId: string</code>
|
|
160
|
+
<li><code>multiple: boolean</code>  If present, allows multiple panels to be open.</li>
|
|
161
|
+
<li><code>persistentId: string</code>  If set, open panel state is saved/restored via localStorage.</li>
|
|
165
162
|
</ul>
|
|
166
163
|
<h4>Methods</h4>
|
|
167
164
|
<ul>
|
|
@@ -181,9 +178,9 @@
|
|
|
181
178
|
<h3 id="accordion-header-ref" class="bb pb">AccordionHeader</h3>
|
|
182
179
|
<h4>Properties</h4>
|
|
183
180
|
<ul>
|
|
184
|
-
<li><code>forPanel: string</code>
|
|
185
|
-
<li><code>active: boolean</code>
|
|
186
|
-
<li><code>accordion: Accordion | null</code> <i>(read only)</i>
|
|
181
|
+
<li><code>forPanel: string</code>  The panel name this header controls.</li>
|
|
182
|
+
<li><code>active: boolean</code>  Whether this header is active.</li>
|
|
183
|
+
<li><code>accordion: Accordion | null</code> <i>(read only)</i>  Parent accordion.</li>
|
|
187
184
|
</ul>
|
|
188
185
|
<h4>Event Handlers</h4>
|
|
189
186
|
<ul>
|
|
@@ -195,16 +192,16 @@
|
|
|
195
192
|
<h3 id="accordion-panel-ref" class="bb pb">AccordionPanel</h3>
|
|
196
193
|
<h4>Properties</h4>
|
|
197
194
|
<ul>
|
|
198
|
-
<li><code>name: string</code>
|
|
199
|
-
<li><code>active: boolean</code>
|
|
200
|
-
<li><code>transitioning: boolean</code>
|
|
195
|
+
<li><code>name: string</code>  Unique panel identifier.</li>
|
|
196
|
+
<li><code>active: boolean</code>  Whether this panel is open.</li>
|
|
197
|
+
<li><code>transitioning: boolean</code>  Whether this panel is animating.</li>
|
|
201
198
|
</ul>
|
|
202
199
|
<h4>Methods</h4>
|
|
203
200
|
<ul>
|
|
204
|
-
<li><code>accordion: Accordion | null</code> (getter)
|
|
201
|
+
<li><code>accordion: Accordion | null</code> (getter)  Returns parent accordion.</li>
|
|
205
202
|
</ul>
|
|
206
203
|
|
|
207
|
-
|
|
204
|
+
<h3 id="events"><a href="#events" class="no-link">Events</a></h3>
|
|
208
205
|
<h5><code>openpanel</code></h5>
|
|
209
206
|
<p>Fired when a panel is opened. The event detail contains <code>{ panelName }</code>.</p>
|
|
210
207
|
<h5><code>closepanel</code></h5>
|
|
@@ -218,19 +215,7 @@
|
|
|
218
215
|
<script type="module" src="/kempo-ui/src/components/Import.js"></script>
|
|
219
216
|
<script type="module" src="/kempo-ui/src/components/Accordion.js"></script>
|
|
220
217
|
<script type="module" src="/kempo-ui/src/components/Card.js"></script>
|
|
221
|
-
<script>
|
|
222
|
-
|
|
223
|
-
link.addEventListener('click', function (e) {
|
|
224
|
-
e.preventDefault();
|
|
225
|
-
const targetId = this.getAttribute('href').replace('#', '');
|
|
226
|
-
const target = document.getElementById(targetId);
|
|
227
|
-
if (target) {
|
|
228
|
-
target.scrollIntoView({ behavior: 'smooth' });
|
|
229
|
-
const url = window.location.pathname + window.location.search + '#' + targetId;
|
|
230
|
-
history.replaceState(null, '', url);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
</script>
|
|
218
|
+
<script type="module" src="/kempo-ui/src/components/Resize.js"></script>
|
|
219
|
+
|
|
235
220
|
</body>
|
|
236
|
-
</html>
|
|
221
|
+
</html>
|