diff --git a/lib/ui.js b/lib/ui.js index 8099858..5f328e9 100644 --- a/lib/ui.js +++ b/lib/ui.js @@ -9,7 +9,7 @@ import { Grid } from "./ui/grid/grid"; import { GridColumn, GridInputColumn, GridDropdownColumn, GridCheckboxColumn, GridIconColumn, GridTextColumn } from './ui/grid/column'; import { Popup, createPopup, showAlert, showConfirm } from "./ui/popup"; import { createPicture, createAudio, createVideo, createFile } from './ui/media'; -import { validation } from './ui/extension'; +import { validation, convertCssStyle } from './ui/extension'; export { createElement, @@ -45,5 +45,6 @@ export { createVideo, createFile, // extension - validation + validation, + convertCssStyle } diff --git a/lib/ui/checkbox.js b/lib/ui/checkbox.js index 0f04cf2..731766e 100644 --- a/lib/ui/checkbox.js +++ b/lib/ui/checkbox.js @@ -22,7 +22,7 @@ function fillCheckbox(container, type = 'fa-regular', label, tabindex = -1, char ); if (label instanceof Element) { container.appendChild(label); - } else if (label?.length > 0) { + } else if (label != null && String(label).length > 0) { container.appendChild( createElement('span', span => span.innerText = label) ); diff --git a/lib/ui/css/grid.css b/lib/ui/css/grid.css index 3cd2ba6..3e3c53f 100644 --- a/lib/ui/css/grid.css +++ b/lib/ui/css/grid.css @@ -1 +1 @@ -.ui-grid{position:relative;box-sizing:border-box;overflow:auto}.ui-grid{--cell-hover-bg-color: lightyellow;--header-border-color: #adaba9;--header-bg-color: #fafafa;--header-fore-color: #000;--cell-border-color: #f0f0f0;--cell-fore-color: #333;--dark-border-color: #666;--split-border-color: #b3b3b3;--dragger-bg-color: #fff;--dragger-cursor-color: #333;--row-bg-color: #fff;--row-active-bg-color: #fafafa;--row-selected-bg-color: #e6f2fb;--text-disabled-color: gray;--filter-shadow: 0 3px 6px -4px rgba(0, 0, 0, .12), 0 6px 16px 0 rgba(0, 0, 0, .08), 0 9px 28px 8px rgba(0, 0, 0, .05);--filter-transition: transform .12s ease, opacity .24s ease;--row-height: 36px;--header-line-height: 26px;--text-indent: 8px;--loading-size: 40px;--loading-border-radius: 20px;--arrow-size: 4px;--filter-size: 10px;--split-width: 8px;--dragger-size: 20px;--dragger-opacity: .6;--dragger-cursor-size: 4px;--dragger-cursor-pos: -4px;--dragger-cursor-opacity: .3;--header-padding: 4px 12px 4px 8px;--header-filter-padding: 4px 26px 4px 8px;--spacing-s: 4px;--spacing-cell: 6px 4px 6px 8px;--filter-line-height: 30px;--filter-item-padding: 0 4px}.ui-grid:focus,.ui-grid:focus-visible{outline:none}.ui-grid::-webkit-scrollbar{width:8px;height:8px}.ui-grid::-webkit-scrollbar-thumb{background-color:rgba(168,168,168,.9);border-radius:4px}.ui-grid,.ui-grid input[type=text],.ui-grid textarea{font-size:var(--font-size);font-family:var(--font-family)}.ui-grid>.ui-grid-sizer{position:absolute;white-space:nowrap;font-weight:bold;visibility:hidden}.ui-grid>.ui-grid-wrapper{position:relative}.ui-grid>.ui-grid-wrapper>.ui-grid-table{position:absolute;width:100%;min-width:100%;margin:0;border-collapse:collapse;border-spacing:0;table-layout:fixed}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr{color:var(--header-fore-color);position:sticky;top:0;z-index:2}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th{background-color:var(--header-bg-color);-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:0;margin:0;word-wrap:break-word;white-space:normal;position:relative}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th.sticky{position:sticky;z-index:2}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>div{border-bottom:1px solid var(--header-border-color);line-height:var(--header-line-height);min-height:var(--row-height);display:flex;align-items:center;padding:var(--header-padding);box-sizing:border-box}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>div>span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow{width:0;height:0;top:50%;margin-top:calc(0px - var(--arrow-size)/2);right:calc(var(--arrow-size)/2);position:absolute}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow.asc{border-bottom:var(--arrow-size) solid var(--dark-border-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow.desc{border-top:var(--arrow-size) solid var(--dark-border-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow.asc,.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow.desc{border-left:var(--arrow-size) solid rgba(0,0,0,0);border-right:var(--arrow-size) solid rgba(0,0,0,0)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter{width:var(--filter-size);height:var(--filter-size);top:50%;margin-top:calc(0px - var(--filter-size)/2);right:calc(var(--arrow-size)*2 + 4px);position:absolute;display:flex}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter>svg{width:100%;height:100%;fill:var(--color);opacity:.2;transition:opacity .12s ease}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter>svg:hover{opacity:.8}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter.hover>svg{opacity:.8}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter.active>svg{opacity:1}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.spliter{position:absolute;height:100%;top:0;right:calc(0px - var(--split-width)/2);width:var(--split-width);cursor:ew-resize;z-index:2}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.spliter::after{content:"";height:100%;width:1px;display:block;margin:0 auto;transition:background-color .12s ease}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.spliter:hover::after{background-color:var(--split-border-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger{position:absolute;left:0;top:0;min-width:var(--dragger-size);height:100%;background-color:var(--dragger-bg-color);opacity:var(--dragger-opacity);display:none}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor{position:absolute;top:0;height:100%;border:1px solid var(--dragger-cursor-color);box-sizing:border-box;margin-left:0;opacity:var(--dragger-cursor-opacity);display:none;transition:left .12s ease}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor::before{top:-1px;border-top:var(--dragger-cursor-size) solid}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor::after{bottom:-1px;border-bottom:var(--dragger-cursor-size) solid}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor::before,.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor::after{content:"";position:absolute;left:var(--dragger-cursor-pos);border-left:var(--dragger-cursor-size) solid rgba(0,0,0,0);border-right:var(--dragger-cursor-size) solid rgba(0,0,0,0)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th.header-filter>div{padding:var(--header-filter-padding)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody{color:var(--cell-fore-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row{line-height:var(--line-height);white-space:nowrap;background-color:var(--row-bg-color);border-bottom:1px solid var(--cell-border-color);box-sizing:border-box}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row:hover{background-color:var(--row-active-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row:hover>td.sticky{background-color:var(--row-active-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row.selected{background-color:var(--row-selected-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row.selected>td.sticky{background-color:var(--row-selected-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td{padding:0}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td.sticky{position:sticky;z-index:1;background-color:var(--row-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>span{padding:var(--spacing-cell);display:block;overflow:hidden;text-overflow:ellipsis;white-space:pre}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text],.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea{border:none;box-sizing:border-box;width:100%;padding:0}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text]:focus,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text]:focus-visible,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea:focus,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea:focus-visible{outline:none}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text]:disabled,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea:disabled{color:var(--text-disabled-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text]{height:var(--row-height);text-indent:var(--text-indent)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea{resize:none;line-height:var(--line-height);display:block;padding:var(--spacing-cell);white-space:nowrap}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea::-webkit-scrollbar{width:8px;height:8px}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea::-webkit-scrollbar-thumb{background-color:rgba(168,168,168,.9);border-radius:4px}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-check-wrapper{display:flex;justify-content:center}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-check-wrapper .ui-check-inner,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-check-wrapper .ui-check-inner>svg{transition:none}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-drop-wrapper{height:var(--row-height);width:100%;display:flex;flex-direction:column}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-drop-wrapper>.ui-drop-header{border:none;height:100%;background-color:rgba(0,0,0,0)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-drop-wrapper>.ui-drop-header>.ui-drop-text{padding:var(--spacing-cell)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon{display:flex;cursor:pointer;justify-content:center;align-items:center;position:relative}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon>svg{width:16px;height:16px;fill:var(--primary-color);transition:opacity .12s ease}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon:hover>svg{opacity:.4}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon.disabled{cursor:unset}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon.disabled>svg{fill:var(--header-border-color);opacity:unset}.ui-grid>.ui-grid-wrapper .ui-grid-hover-holder{box-sizing:border-box;position:absolute;line-height:var(--line-height);padding:var(--spacing-cell);background-color:var(--cell-hover-bg-color);white-space:pre;display:flex;align-items:center;visibility:hidden;opacity:0;transition:visibility 0s linear .12s,opacity .12s ease;z-index:3}.ui-grid>.ui-grid-wrapper .ui-grid-hover-holder.active{visibility:visible;opacity:1}.ui-grid>.ui-grid-loading{position:absolute;top:0;right:0;bottom:0;left:0;visibility:hidden;opacity:0;transition:visibility 0s linear .12s,opacity .12s ease;background-color:var(--loading-bg-color);display:flex;justify-content:center;align-items:center;z-index:3}.ui-grid>.ui-grid-loading>div{background-color:var(--loading-fore-color);border-radius:var(--loading-border-radius)}.ui-grid>.ui-grid-loading>div>svg{width:var(--loading-size);height:var(--loading-size);padding:20px;animation:loading-spinner 1.2s infinite linear}.ui-grid>.ui-drop-box{max-width:300px}.ui-grid>.filter-panel{position:absolute;width:200px;height:300px;box-shadow:var(--filter-shadow);transition:var(--filter-transition);background-color:var(--bg-color);transform:scaleY(0);transform-origin:top;opacity:0;display:flex;flex-direction:column;z-index:3}.ui-grid>.filter-panel.active{transform:scaleY(1);opacity:1}.ui-grid>.filter-panel>.filter-search-holder{position:relative;margin:8px 8px 4px}.ui-grid>.filter-panel>.filter-search-holder>.filter-search-box{box-sizing:border-box;text-indent:16px;width:100%;font-size:var(--font-smaller-size);height:var(--line-height);line-height:var(--line-height)}.ui-grid>.filter-panel>.filter-search-holder>svg{position:absolute;width:12px;height:12px;top:calc(50% - 6px);left:4px;fill:var(--color);cursor:text}.ui-grid>.filter-panel>.filter-item-list{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none}.ui-grid>.filter-panel>.filter-item-list::-webkit-scrollbar{width:8px;height:8px}.ui-grid>.filter-panel>.filter-item-list::-webkit-scrollbar-thumb{background-color:rgba(168,168,168,.9);border-radius:4px}.ui-grid>.filter-panel>.filter-item-list>.filter-content{position:absolute;width:100%}.ui-grid>.filter-panel>.filter-item-list .filter-item{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-sizing:border-box;padding:var(--filter-item-padding)}.ui-grid>.filter-panel>.filter-item-list .filter-item:hover{background-color:var(--hover-bg-color)}.ui-grid>.filter-panel>.filter-item-list .filter-item .ui-check-wrapper{height:var(--filter-line-height);display:flex}.ui-grid>.filter-panel>.filter-item-list .filter-item .ui-check-wrapper .ui-check-inner+*{font-size:var(--font-smaller-size)}.ui-grid>.filter-panel>.filter-function{display:flex;justify-content:flex-end;padding:4px}.ui-grid>.filter-panel>.filter-function>button{box-sizing:border-box;margin-right:10px;min-width:40px;height:var(--filter-line-height);border:none;background-color:rgba(0,0,0,0);cursor:pointer;border-radius:0;transition:background-color .12s ease}.ui-grid>.filter-panel>.filter-function>button:focus,.ui-grid>.filter-panel>.filter-function>button:focus-visible{outline:none}.ui-grid>.filter-panel>.filter-function>button:hover{background-color:var(--hover-bg-color)} \ No newline at end of file +.ui-grid{position:relative;box-sizing:border-box;overflow:auto}.ui-grid{--cell-hover-bg-color: lightyellow;--header-border-color: #adaba9;--header-bg-color: #fafafa;--header-fore-color: #000;--cell-border-color: #f0f0f0;--cell-fore-color: #333;--dark-border-color: #666;--split-border-color: #b3b3b3;--dragger-bg-color: #fff;--dragger-cursor-color: #333;--row-bg-color: #fff;--row-active-bg-color: #fafafa;--row-selected-bg-color: #e6f2fb;--text-disabled-color: gray;--filter-shadow: 0 3px 6px -4px rgba(0, 0, 0, .12), 0 6px 16px 0 rgba(0, 0, 0, .08), 0 9px 28px 8px rgba(0, 0, 0, .05);--filter-transition: transform .12s ease, opacity .24s ease;--row-height: 36px;--header-line-height: 26px;--text-indent: 8px;--loading-size: 40px;--loading-border-radius: 20px;--arrow-size: 4px;--filter-size: 10px;--split-width: 8px;--dragger-size: 20px;--dragger-opacity: .6;--dragger-cursor-size: 4px;--dragger-cursor-pos: -4px;--dragger-cursor-opacity: .3;--header-padding: 4px 12px 4px 8px;--header-filter-padding: 4px 26px 4px 8px;--spacing-s: 4px;--spacing-cell: 6px 4px 6px 8px;--filter-line-height: 30px;--filter-item-padding: 0 4px}.ui-grid:focus,.ui-grid:focus-visible{outline:none}.ui-grid::-webkit-scrollbar{width:8px;height:8px}.ui-grid::-webkit-scrollbar-thumb{background-color:rgba(168,168,168,.9);border-radius:4px}.ui-grid,.ui-grid input[type=text],.ui-grid textarea{font-size:var(--font-size);font-family:var(--font-family)}.ui-grid>.ui-grid-sizer{position:absolute;white-space:nowrap;font-weight:bold;visibility:hidden}.ui-grid>.ui-grid-wrapper{position:relative}.ui-grid>.ui-grid-wrapper>.ui-grid-table{position:absolute;width:100%;min-width:100%;margin:0;border-collapse:collapse;border-spacing:0;table-layout:fixed}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr{color:var(--header-fore-color);position:sticky;top:0;z-index:2}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th{background-color:var(--header-bg-color);-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:0;margin:0;word-wrap:break-word;white-space:normal;position:relative}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th.sticky{position:sticky;z-index:2}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>div{border-bottom:1px solid var(--header-border-color);line-height:var(--header-line-height);min-height:var(--row-height);display:flex;align-items:center;padding:var(--header-padding);box-sizing:border-box}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>div>span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow{width:0;height:0;top:50%;margin-top:calc(0px - var(--arrow-size)/2);right:calc(var(--arrow-size)/2);position:absolute}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow.asc{border-bottom:var(--arrow-size) solid var(--dark-border-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow.desc{border-top:var(--arrow-size) solid var(--dark-border-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow.asc,.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.arrow.desc{border-left:var(--arrow-size) solid rgba(0,0,0,0);border-right:var(--arrow-size) solid rgba(0,0,0,0)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter{width:var(--filter-size);height:var(--filter-size);top:50%;margin-top:calc(0px - var(--filter-size)/2);right:calc(var(--arrow-size)*2 + 4px);position:absolute;display:flex}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter>svg{width:100%;height:100%;fill:var(--color);opacity:.2;transition:opacity .12s ease}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter>svg:hover{opacity:.8}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter.hover>svg{opacity:.8}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.filter.active>svg{opacity:1}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.spliter{position:absolute;height:100%;top:0;right:calc(0px - var(--split-width)/2);width:var(--split-width);cursor:ew-resize;z-index:2}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.spliter::after{content:"";height:100%;width:1px;display:block;margin:0 auto;transition:background-color .12s ease}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.spliter:hover::after{background-color:var(--split-border-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger{position:absolute;left:0;top:0;min-width:var(--dragger-size);height:100%;background-color:var(--dragger-bg-color);opacity:var(--dragger-opacity);display:none}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor{position:absolute;top:0;height:100%;border:1px solid var(--dragger-cursor-color);box-sizing:border-box;margin-left:0;opacity:var(--dragger-cursor-opacity);display:none;transition:left .12s ease}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor::before{top:-1px;border-top:var(--dragger-cursor-size) solid}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor::after{bottom:-1px;border-bottom:var(--dragger-cursor-size) solid}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor::before,.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th>.dragger-cursor::after{content:"";position:absolute;left:var(--dragger-cursor-pos);border-left:var(--dragger-cursor-size) solid rgba(0,0,0,0);border-right:var(--dragger-cursor-size) solid rgba(0,0,0,0)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>thead tr>th.header-filter>div{padding:var(--header-filter-padding)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody{color:var(--cell-fore-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row{line-height:var(--line-height);white-space:nowrap;background-color:var(--row-bg-color);border-bottom:1px solid var(--cell-border-color);box-sizing:border-box}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row:hover{background-color:var(--row-active-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row:hover>td.sticky{background-color:var(--row-active-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row.selected{background-color:var(--row-selected-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row.selected>td.sticky{background-color:var(--row-selected-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td{padding:0}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td.sticky{position:sticky;z-index:1;background-color:var(--row-bg-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>span{padding:var(--spacing-cell);display:block;overflow:hidden;text-overflow:ellipsis;white-space:pre}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text],.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea{border:none;box-sizing:border-box;width:100%;padding:0}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text]:focus,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text]:focus-visible,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea:focus,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea:focus-visible{outline:none}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text]:disabled,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea:disabled{color:var(--text-disabled-color)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>input[type=text]{height:var(--row-height);text-indent:var(--text-indent)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea{resize:none;line-height:var(--line-height);display:block;padding:var(--spacing-cell);white-space:nowrap}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea::-webkit-scrollbar{width:8px;height:8px}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td>textarea::-webkit-scrollbar-thumb{background-color:rgba(168,168,168,.9);border-radius:4px}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-check-wrapper{display:flex;justify-content:center}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-check-wrapper .ui-check-inner,.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-check-wrapper .ui-check-inner>svg{transition:none}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-drop-wrapper{height:var(--row-height);width:100%;display:flex;flex-direction:column}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-drop-wrapper>.ui-drop-header{border:none;height:100%}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-drop-wrapper>.ui-drop-header>.ui-drop-text{padding:var(--spacing-cell)}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon{display:flex;cursor:pointer;justify-content:center;align-items:center;position:relative}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon>svg{width:16px;height:16px;fill:var(--primary-color);transition:opacity .12s ease}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon:hover>svg{opacity:.4}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon.disabled{cursor:unset}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .col-icon.disabled>svg{fill:var(--header-border-color);opacity:unset}.ui-grid>.ui-grid-wrapper .ui-grid-hover-holder{box-sizing:border-box;position:absolute;line-height:var(--line-height);padding:var(--spacing-cell);background-color:var(--cell-hover-bg-color);white-space:pre;display:flex;align-items:center;visibility:hidden;opacity:0;transition:visibility 0s linear .12s,opacity .12s ease;z-index:3}.ui-grid>.ui-grid-wrapper .ui-grid-hover-holder.active{visibility:visible;opacity:1}.ui-grid>.ui-grid-loading{position:absolute;top:0;right:0;bottom:0;left:0;visibility:hidden;opacity:0;transition:visibility 0s linear .12s,opacity .12s ease;background-color:var(--loading-bg-color);display:flex;justify-content:center;align-items:center;z-index:3}.ui-grid>.ui-grid-loading>div{background-color:var(--loading-fore-color);border-radius:var(--loading-border-radius)}.ui-grid>.ui-grid-loading>div>svg{width:var(--loading-size);height:var(--loading-size);padding:20px;animation:loading-spinner 1.2s infinite linear}.ui-grid>.ui-drop-box{max-width:300px}.ui-grid>.filter-panel{position:absolute;width:200px;height:300px;box-shadow:var(--filter-shadow);transition:var(--filter-transition);background-color:var(--bg-color);transform:scaleY(0);transform-origin:top;opacity:0;display:flex;flex-direction:column;z-index:3}.ui-grid>.filter-panel.active{transform:scaleY(1);opacity:1}.ui-grid>.filter-panel>.filter-search-holder{position:relative;margin:8px 8px 4px}.ui-grid>.filter-panel>.filter-search-holder>.filter-search-box{box-sizing:border-box;text-indent:16px;width:100%;font-size:var(--font-smaller-size);height:var(--line-height);line-height:var(--line-height)}.ui-grid>.filter-panel>.filter-search-holder>svg{position:absolute;width:12px;height:12px;top:calc(50% - 6px);left:4px;fill:var(--color);cursor:text}.ui-grid>.filter-panel>.filter-item-list{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none}.ui-grid>.filter-panel>.filter-item-list::-webkit-scrollbar{width:8px;height:8px}.ui-grid>.filter-panel>.filter-item-list::-webkit-scrollbar-thumb{background-color:rgba(168,168,168,.9);border-radius:4px}.ui-grid>.filter-panel>.filter-item-list>.filter-content{position:absolute;width:100%}.ui-grid>.filter-panel>.filter-item-list .filter-item{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-sizing:border-box;padding:var(--filter-item-padding)}.ui-grid>.filter-panel>.filter-item-list .filter-item:hover{background-color:var(--hover-bg-color)}.ui-grid>.filter-panel>.filter-item-list .filter-item .ui-check-wrapper{height:var(--filter-line-height);display:flex}.ui-grid>.filter-panel>.filter-item-list .filter-item .ui-check-wrapper .ui-check-inner+*{font-size:var(--font-smaller-size)}.ui-grid>.filter-panel>.filter-function{display:flex;justify-content:flex-end;padding:4px}.ui-grid>.filter-panel>.filter-function>button{box-sizing:border-box;margin-right:10px;min-width:40px;height:var(--filter-line-height);border:none;background-color:rgba(0,0,0,0);cursor:pointer;border-radius:0;transition:background-color .12s ease}.ui-grid>.filter-panel>.filter-function>button:focus,.ui-grid>.filter-panel>.filter-function>button:focus-visible{outline:none}.ui-grid>.filter-panel>.filter-function>button:hover{background-color:var(--hover-bg-color)} \ No newline at end of file diff --git a/lib/ui/css/grid.scss b/lib/ui/css/grid.scss index b6f9829..e57bfe5 100644 --- a/lib/ui/css/grid.scss +++ b/lib/ui/css/grid.scss @@ -333,7 +333,6 @@ >.ui-drop-header { border: none; height: 100%; - background-color: transparent; >.ui-drop-text { padding: var(--spacing-cell); diff --git a/lib/ui/dropdown.js b/lib/ui/dropdown.js index 8756794..b76bc26 100644 --- a/lib/ui/dropdown.js +++ b/lib/ui/dropdown.js @@ -284,6 +284,8 @@ export class Dropdown { const html = item[htmlkey]; if (html instanceof HTMLElement) { this._var.label.replaceChildren(html.cloneNode(true)); + } else if (typeof html === 'string') { + this._var.label.innerHTML = html; } else { let text = item[textkey]; if (nullOrEmpty(text)) { @@ -462,6 +464,9 @@ export class Dropdown { const html = item[htmlkey]; if (html instanceof HTMLElement) { label = html; + } else if (typeof html === 'string') { + label = createElement('span'); + label.innerHTML = html; } if (multiselect) { const selected = selectedlist.some(s => s[valuekey] === val); diff --git a/lib/ui/extension.d.ts b/lib/ui/extension.d.ts index 2a8be64..dc7f882 100644 --- a/lib/ui/extension.d.ts +++ b/lib/ui/extension.d.ts @@ -1 +1,2 @@ -export function validation(element: HTMLElement, regex: RegExp) : HTMLElement \ No newline at end of file +export function validation(element: HTMLElement, regex: RegExp): HTMLElement +export function convertCssStyle(style: Object): string diff --git a/lib/ui/extension.js b/lib/ui/extension.js index 3d41dcd..b53a75b 100644 --- a/lib/ui/extension.js +++ b/lib/ui/extension.js @@ -9,4 +9,8 @@ export function validation(element, regex) { }) } return element; +} + +export function convertCssStyle(style) { + return Object.entries(style).map(s => `${s[0]}: ${s[1]}`).join('; '); } \ No newline at end of file diff --git a/lib/ui/grid/column.js b/lib/ui/grid/column.js index af9f16a..f2cd64e 100644 --- a/lib/ui/grid/column.js +++ b/lib/ui/grid/column.js @@ -5,6 +5,7 @@ import { createIcon } from "../icon"; import { createCheckbox } from "../checkbox"; // import { setTooltip } from "../tooltip"; import { Dropdown } from "../dropdown"; +import { convertCssStyle } from "../extension"; export class GridColumn { static create() { @@ -16,9 +17,10 @@ export class GridColumn { } static setStyle(element, style) { - for (let css of Object.entries(style)) { - element.style.setProperty(css[0], css[1]); - } + // for (let css of Object.entries(style)) { + // element.style.setProperty(css[0], css[1]); + // } + element.style.cssText = convertCssStyle(style); } static setEnabled(element, enabled) { diff --git a/lib/ui/grid/grid.js b/lib/ui/grid/grid.js index c3e6a10..1a05b6a 100644 --- a/lib/ui/grid/grid.js +++ b/lib/ui/grid/grid.js @@ -6,6 +6,7 @@ import { createElement } from "../../functions"; import { createIcon } from "../icon"; import { createCheckbox } from "../checkbox"; import { setTooltip } from "../tooltip"; +import { convertCssStyle } from "../extension"; import { GridColumn, GridInputColumn, GridTextColumn, GridDropdownColumn, GridCheckboxColumn, GridIconColumn } from "./column"; const ColumnChangedType = { @@ -236,7 +237,7 @@ export class Grid { return; } this._var.el.scrollTop = top; - this.reload(); + this.reload(true); } init(container = this._var.parent) { @@ -353,15 +354,17 @@ export class Grid { this._var.bodyClientWidth = body.clientWidth; } - reload() { + reload(keep) { let length = this._var.currentSource.length; if (this.extraRows > 0) { length += this.extraRows; } this._var.containerHeight = length * (this.rowHeight + 1); - // this._var.refs.body.scrollTop = 0; - // this._var.refs.body.scrollLeft = 0; - this._var.refs.table.style.top = '0px'; + if (!keep) { + this._var.el.scrollTop = 0; + // this._var.el.scrollLeft = 0; + this._var.refs.table.style.top = '0px'; + } this._var.refs.wrapper.style.height = `${this._var.containerHeight}px`; this._adjustRows(this._var.refs.body); this.refresh(); @@ -515,19 +518,18 @@ export class Grid { this._set(col.key, 'style', style); // element const th = createElement('th', 'column'); + const thStyle = { ...style }; if (col.isfixed) { th.classList.add('sticky'); - th.style.left = `${left}px`; + thStyle.left = `${left}px`; } left += col.width; th.dataset.key = col.key; - for (let css of Object.entries(style)) { - th.style.setProperty(css[0], css[1]); - } if (col.sortable) { - th.style.cursor = 'pointer'; + thStyle.cursor = 'pointer'; th.addEventListener('click', e => this._onHeaderClicked(e, col)); } + th.style.cssText = convertCssStyle(thStyle); if (col.orderable !== false) { col.orderable = true; th.addEventListener('mousedown', e => this._onDragStart(e, col)); @@ -542,9 +544,7 @@ export class Grid { } const caption = createElement('span'); if (col.textStyle != null) { - for (let css of Object.entries(col.textStyle)) { - caption.style.setProperty(css[0], css[1]); - } + caption.style.cssText = convertCssStyle(col.textStyle); } caption.innerText = col.caption ?? ''; wrapper.appendChild(caption); @@ -629,23 +629,20 @@ export class Grid { cols.forEach((col, j) => { const cell = createElement('td'); if (col.visible !== false) { + let style = this._get(col.key, 'style') ?? {}; if (col.isfixed) { cell.classList.add('sticky'); - cell.style.left = `${left}px`; + style.left = `${left}px`; } left += col.width; cell.dataset.row = String(exists + i); cell.dataset.col = String(j); - const style = this._get(col.key, 'style'); - if (style != null) { - for (let css of Object.entries(style)) { - cell.style.setProperty(css[0], css[1]); - } - } if (col.css != null) { - for (let css of Object.entries(col.css)) { - cell.style.setProperty(css[0], css[1]); - } + style = { ...style, ...col.css }; + } + style = convertCssStyle(style); + if (style !== '') { + cell.style.cssText = style; } if (Grid.ColumnTypes.isCheckbox(col.type)) { cell.appendChild(GridCheckboxColumn.createEdit(e => this._onRowChanged(e, exists + i, col, e.target.checked, cell))); @@ -719,8 +716,8 @@ export class Grid { val = col.filter(item, selected, this._var.refs.body); } else { val = item[col.key]; - if (val?.displayValue != null) { - val = val.displayValue; + if (val?.DisplayValue != null) { + val = val.DisplayValue; } } val ??= ''; @@ -854,9 +851,7 @@ export class Grid { _changingColumnOrder(index, offset, x, offsetLeft) { const children = this._var.refs.header.children; let element = children[index]; - this._var.refs.dragger.style.left = `${element.offsetLeft - offsetLeft + offset}px`; - this._var.refs.dragger.style.width = element.style.width; - this._var.refs.dragger.style.display = 'block'; + this._var.refs.dragger.style.cssText = `left: ${element.offsetLeft - offsetLeft + offset}px; width: ${element.style.width}; display: block`; offset = x - element.offsetLeft; // getOffsetLeftFromWindow(element); let idx; if (offset < 0) { @@ -896,8 +891,7 @@ export class Grid { if (element == null) { return; } - this._var.refs.draggerCursor.style.left = `${element.offsetLeft - offsetLeft}px`; - this._var.refs.draggerCursor.style.display = 'block'; + this._var.refs.draggerCursor.style.cssText = `left: ${element.offsetLeft - offsetLeft}px; display: block`; } } @@ -1012,7 +1006,7 @@ export class Grid { } else { value = item[key]; } - return value?.value ?? value; + return value?.Value ?? value; } _getRowTarget(target) { @@ -1107,6 +1101,9 @@ export class Grid { onchange: e => { const checked = e.target.checked; itemlist.querySelectorAll('.filter-content input').forEach(box => box.checked = checked); + for (let it of this._get(col.key, 'filterSource')) { + it.__checked = checked; + } } })); itemlist.appendChild(itemall); @@ -1123,26 +1120,26 @@ export class Grid { if (!Object.hasOwnProperty.call(dict, val)) { const v = item.values[col.key]; dict[val] = { - value: val, - displayValue: typeof col.filter === 'function' ? col.filter(item.values) : v?.displayValue ?? v + Value: val, + DisplayValue: typeof col.filter === 'function' ? col.filter(item.values) : v?.DisplayValue ?? v }; } } array = Object.values(dict) .sort((a, b) => { - a = a?.value ?? a; - b = b?.value ?? b; + a = a?.Value ?? a; + b = b?.Value ?? b; return a > b ? 1 : a < b ? -1 : 0; }); } array = array.map(i => { - if (Object.prototype.hasOwnProperty.call(i, 'value') && - Object.prototype.hasOwnProperty.call(i, 'displayValue')) { + if (Object.prototype.hasOwnProperty.call(i, 'Value') && + Object.prototype.hasOwnProperty.call(i, 'DisplayValue')) { return i; } return { - value: i, - displayValue: i == null ? '' : i + Value: i, + DisplayValue: i == null ? '' : i }; }); this._fillFilterList(col, itemlist, array, itemall); @@ -1152,7 +1149,7 @@ export class Grid { searchbox.addEventListener('input', e => { const key = e.currentTarget.value.toLowerCase(); const items = key.length === 0 ? array : array.filter(i => { - const displayValue = i?.displayValue ?? i; + const displayValue = i?.DisplayValue ?? i; return String(displayValue ?? '').includes(key); }); this._fillFilterList(col, itemlist, items, itemall); @@ -1168,7 +1165,7 @@ export class Grid { if (typeof col.onFilterOk === 'function') { col.onFilterOk.call(this, col, array); } else { - col.filterValues = array.map(a => a.value); + col.filterValues = array.map(a => a.Value); } this._var.colAttrs.__filtered = true; this._refreshSource(); @@ -1213,7 +1210,7 @@ export class Grid { content.style.top = `${rowHeight}px`; this._set(col.key, 'filterSource', array); for (let item of array) { - item.__checked = !Array.isArray(col.filterValues) || col.filterValues.includes(item.value ?? item); + item.__checked = !Array.isArray(col.filterValues) || col.filterValues.includes(item.Value ?? item); } if (array.length > 12) { array = array.slice(0, 12); @@ -1227,7 +1224,7 @@ export class Grid { const div = createElement('div', 'filter-item'); div.appendChild(createCheckbox({ checked: item.__checked, - label: item?.displayValue ?? item, + label: item?.DisplayValue ?? item, onchange: e => { item.__checked = e.target.checked; all.querySelector('input').checked = ![...content.querySelectorAll('input')].some(i => !i.checked); @@ -1591,8 +1588,8 @@ export class Grid { } if (enabled !== false) { const val = item[col.key]; - if (val?.value != null) { - val.value = value; + if (val?.Value != null) { + val.Value = value; } else { item[col.key] = value; }