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.
Files changed (120) hide show
  1. package/dist/components/Accordion.js +67 -0
  2. package/dist/components/LightComponent.js +1 -0
  3. package/dist/components/ShadowComponent.js +1 -0
  4. package/dist/components/Split.js +84 -0
  5. package/dist/components/Table.js +151 -0
  6. package/dist/{src/components → components}/Tabs.js +9 -8
  7. package/dist/{src/components → components}/Tree.js +0 -3
  8. package/dist/{src/components → components}/tableControls/FieldSortHide.js +1 -2
  9. package/dist/{src/components → components}/tableControls/Filters.js +2 -3
  10. package/docs/kempo-ui/components/accordion.html +28 -43
  11. package/docs/kempo-ui/components/card.html +24 -16
  12. package/docs/kempo-ui/components/content-slider.html +101 -78
  13. package/docs/kempo-ui/components/dialog.html +24 -20
  14. package/docs/kempo-ui/components/focus-capture.html +21 -16
  15. package/docs/kempo-ui/components/hybrid-component.html +13 -10
  16. package/docs/kempo-ui/components/icon.html +36 -28
  17. package/docs/kempo-ui/components/import.html +36 -26
  18. package/docs/kempo-ui/components/light-component.html +44 -25
  19. package/docs/kempo-ui/components/photo-viewer.html +151 -103
  20. package/docs/kempo-ui/components/resize.html +27 -22
  21. package/docs/kempo-ui/components/shadow-component.html +37 -22
  22. package/docs/kempo-ui/components/show-more.html +23 -18
  23. package/docs/kempo-ui/components/side-menu.html +1 -1
  24. package/docs/kempo-ui/components/sortable.html +20 -15
  25. package/docs/kempo-ui/components/split.html +60 -33
  26. package/docs/kempo-ui/components/table.html +71 -100
  27. package/docs/kempo-ui/components/tableControls.html +7 -3
  28. package/docs/kempo-ui/components/tableCustomFields.html +6 -3
  29. package/docs/kempo-ui/components/tablePagination.html +12 -10
  30. package/docs/kempo-ui/components/tableRecordEditing.html +7 -4
  31. package/docs/kempo-ui/components/tableRecordFiltering.html +1 -1
  32. package/docs/kempo-ui/components/tableRecordHiding.html +9 -6
  33. package/docs/kempo-ui/components/tableRecordSelection.html +6 -4
  34. package/docs/kempo-ui/components/tableRowControls.html +7 -6
  35. package/docs/kempo-ui/components/tabs.html +41 -91
  36. package/docs/kempo-ui/components/tags.html +85 -38
  37. package/docs/kempo-ui/components/theme-switcher.html +12 -7
  38. package/docs/kempo-ui/components/timestamp.html +78 -29
  39. package/docs/kempo-ui/components/toast.html +194 -154
  40. package/docs/kempo-ui/components/toggle.html +13 -8
  41. package/docs/kempo-ui/components/tree.html +48 -40
  42. package/docs/kempo-ui/index.html +0 -6
  43. package/docs/kempo-ui/nav.inc.html +0 -1
  44. package/docs/kempo-ui/nav.inc.js +12 -0
  45. package/docs/kempo-ui/src/components/Accordion.js +40 -9
  46. package/docs/kempo-ui/src/components/LightComponent.js +1 -1
  47. package/docs/kempo-ui/src/components/ShadowComponent.js +1 -1
  48. package/docs/kempo-ui/src/components/SideMenu.js +1 -1
  49. package/docs/kempo-ui/src/components/Split.js +1 -1
  50. package/docs/kempo-ui/src/components/Table.js +77 -77
  51. package/docs/kempo-ui/src/components/Tabs.js +9 -8
  52. package/docs/kempo-ui/src/components/Tree.js +0 -3
  53. package/docs/kempo-ui/src/components/tableControls/FieldSortHide.js +1 -2
  54. package/docs/kempo-ui/src/components/tableControls/Filters.js +2 -3
  55. package/docs/kempo-ui/src/kempo-hljs.css +1 -0
  56. package/docs/kempo-ui/src/kempo-vars.css +1 -0
  57. package/docs/kempo-ui/utils/debounce.html +16 -15
  58. package/docs/kempo-ui/utils/drag.html +22 -19
  59. package/docs/kempo-ui/utils/propConverters.html +4 -4
  60. package/package.json +2 -2
  61. package/scripts/build.js +5 -5
  62. package/src/components/LightComponent.js +22 -0
  63. package/src/components/ShadowComponent.js +23 -0
  64. package/src/components/SideMenu.js +1 -1
  65. package/src/components/Split.js +16 -8
  66. package/src/components/Table.js +112 -95
  67. package/src/components/Tree.js +0 -3
  68. package/src/components/tableControls/FieldSortHide.js +1 -1
  69. package/src/components/tableControls/Filters.js +2 -3
  70. package/dist/src/components/Accordion.js +0 -36
  71. package/dist/src/components/Collapsible.js +0 -41
  72. package/dist/src/components/LightComponent.js +0 -1
  73. package/dist/src/components/PersistantCollapsible.js +0 -1
  74. package/dist/src/components/ShadowComponent.js +0 -1
  75. package/dist/src/components/Split.js +0 -84
  76. package/dist/src/components/Table.js +0 -151
  77. package/dist/src/utils/watchWindowSize.js +0 -1
  78. package/docs/kempo-ui/src/components/Collapsible.js +0 -41
  79. package/docs/kempo-ui/src/components/PersistantCollapsible.js +0 -1
  80. package/docs/kempo-ui/src/utils/watchWindowSize.js +0 -1
  81. package/docs/kempo-ui/utils/watchWindowSize.html +0 -72
  82. package/src/utils/watchWindowSize.js +0 -16
  83. /package/dist/{src/components → components}/Card.js +0 -0
  84. /package/dist/{src/components → components}/ContentSlider.js +0 -0
  85. /package/dist/{src/components → components}/Dialog.js +0 -0
  86. /package/dist/{src/components → components}/FocusCapture.js +0 -0
  87. /package/dist/{src/components → components}/HybridComponent.js +0 -0
  88. /package/dist/{src/components → components}/Icon.js +0 -0
  89. /package/dist/{src/components → components}/Import.js +0 -0
  90. /package/dist/{src/components → components}/PhotoViewer.js +0 -0
  91. /package/dist/{src/components → components}/Resize.js +0 -0
  92. /package/dist/{src/components → components}/ShowMore.js +0 -0
  93. /package/dist/{src/components → components}/SideMenu.js +0 -0
  94. /package/dist/{src/components → components}/Sortable.js +0 -0
  95. /package/dist/{src/components → components}/Tags.js +0 -0
  96. /package/dist/{src/components → components}/ThemeSwitcher.js +0 -0
  97. /package/dist/{src/components → components}/Timestamp.js +0 -0
  98. /package/dist/{src/components → components}/Toast.js +0 -0
  99. /package/dist/{src/components → components}/Toggle.js +0 -0
  100. /package/dist/{src/components → components}/tableControls/DeleteRecord.js +0 -0
  101. /package/dist/{src/components → components}/tableControls/Edit.js +0 -0
  102. /package/dist/{src/components → components}/tableControls/ExportCSV.js +0 -0
  103. /package/dist/{src/components → components}/tableControls/ExportJson.js +0 -0
  104. /package/dist/{src/components → components}/tableControls/FirstPage.js +0 -0
  105. /package/dist/{src/components → components}/tableControls/HiddenCount.js +0 -0
  106. /package/dist/{src/components → components}/tableControls/Hide.js +0 -0
  107. /package/dist/{src/components → components}/tableControls/LastPage.js +0 -0
  108. /package/dist/{src/components → components}/tableControls/NextPage.js +0 -0
  109. /package/dist/{src/components → components}/tableControls/PageSelect.js +0 -0
  110. /package/dist/{src/components → components}/tableControls/PageSize.js +0 -0
  111. /package/dist/{src/components → components}/tableControls/PrevPage.js +0 -0
  112. /package/dist/{src/components → components}/tableControls/Search.js +0 -0
  113. /package/dist/{src/components → components}/tableControls/ShowAll.js +0 -0
  114. /package/dist/{src/components → components}/tableControls/TableControl.js +0 -0
  115. /package/dist/{src/lit-all.min.js → lit-all.min.js} +0 -0
  116. /package/dist/{src/utils → utils}/debounce.js +0 -0
  117. /package/dist/{src/utils → utils}/drag.js +0 -0
  118. /package/dist/{src/utils → utils}/formatTimestamp.js +0 -0
  119. /package/dist/{src/utils → utils}/propConverters.js +0 -0
  120. /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}static styles=css`
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: 2px solid var(--c_primary);
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
- `;render(){return html`
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
- `;render(){return html`<slot></slot>`}}export class TabSpacer extends ShadowComponent{constructor(){super(),this.slot="tabs"}static styles=css`
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;
@@ -27,9 +27,6 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css,render}from"..
27
27
  width: 100%;
28
28
  cursor: pointer;
29
29
  }
30
- .branch-label:hover{
31
- background-color: var(--c_bg__alt, #f5f5f5);
32
- }
33
30
  .branch-label:focus{
34
31
  box-shadow: none;
35
32
  }
@@ -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 pl">
22
+ <div class="m ">
24
23
  <h6>Examples</h6>
25
- <a href="#basicUsage" class="scroll-link">Basic Usage</a><br />
26
- <a href="#defaultOpen" class="scroll-link">Default Open Panel</a><br />
27
- <a href="#multiple" class="scroll-link">Multiple Panels Mode</a><br />
28
- <a href="#persistent" class="scroll-link">Persistent State Example</a><br />
29
- <h6 class="mt"><a href="#jsRef" class="no-link scroll-link">JavaScript Reference</a></h6>
30
- <a href="#accordion-ref" class="scroll-link">Accordion</a><br />
31
- <a href="#accordion-header-ref" class="scroll-link">AccordionHeader</a><br />
32
- <a href="#accordion-panel-ref" class="scroll-link">AccordionPanel</a><br />
33
- <a href="#events" class="scroll-link">Events</a><br />
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
- <h3 id="basicUsage"><a href="#basicUsage" class="no-link scroll-link">Basic Usage</a></h3>
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
- <h3 id="defaultOpen"><a href="#defaultOpen" class="no-link scroll-link">Default Open Panel</a></h3>
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
- <h3 id="multiple"><a href="#multiple" class="no-link scroll-link">Multiple Panels Mode</a></h3>
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
- <h3 id="persistent"><a href="#persistent" class="no-link scroll-link">Persistent State Example</a></h3>
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
- <h2 id="jsRef"><a href="#jsRef" class="no-link scroll-link">JavaScript Reference</a></h2>
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> If present, allows multiple panels to be open.</li>
164
- <li><code>persistentId: string</code> If set, open panel state is saved/restored via localStorage.</li>
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> The panel name this header controls.</li>
185
- <li><code>active: boolean</code> Whether this header is active.</li>
186
- <li><code>accordion: Accordion | null</code> <i>(read only)</i> Parent accordion.</li>
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> Unique panel identifier.</li>
199
- <li><code>active: boolean</code> Whether this panel is open.</li>
200
- <li><code>transitioning: boolean</code> Whether this panel is animating.</li>
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) Returns parent accordion.</li>
201
+ <li><code>accordion: Accordion | null</code> (getter) — Returns parent accordion.</li>
205
202
  </ul>
206
203
 
207
- <h3 id="events"><a href="#events" class="no-link scroll-link">Events</a></h3>
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
- document.querySelectorAll('.scroll-link').forEach(link => {
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>