From 9ab9edb44deaa59d6c30cb8305866e98f44dcb88 Mon Sep 17 00:00:00 2001 From: Tsanie Date: Thu, 25 Jan 2024 14:56:31 +0800 Subject: [PATCH] sync --- lib/app/communications/lib.js | 2 +- lib/element/schedule.js | 2 +- lib/element/style.css | 1 - lib/ui/css/dropdown.css | 1 - lib/ui/css/grid.css | 1 - lib/ui/css/grid.scss | 14 ++- lib/ui/dropdown.d.ts | 104 ++++++++++++++--- lib/ui/dropdown.js | 70 +++++++----- lib/ui/grid/column.d.ts | 207 +++++++++++++++++++++++++++++----- lib/ui/grid/column.js | 53 +++++++-- lib/ui/grid/grid.d.ts | 161 +++++++++++++++++++++++++- lib/ui/grid/grid.js | 43 +++++-- lib/ui/icon.js | 3 +- package-lock.json | 47 ++++++-- package.json | 1 + readme/Grid 控件接口文档.docx | Bin 36643 -> 38129 bytes typedoc.json | 9 +- vite.build.js | 61 ---------- 18 files changed, 594 insertions(+), 186 deletions(-) delete mode 100644 lib/element/style.css delete mode 100644 lib/ui/css/dropdown.css delete mode 100644 lib/ui/css/grid.css diff --git a/lib/app/communications/lib.js b/lib/app/communications/lib.js index 34cc3f3..bfdef7e 100644 --- a/lib/app/communications/lib.js +++ b/lib/app/communications/lib.js @@ -205,7 +205,7 @@ const SymbolDropdown = Symbol.for('ui-dropdown'); class DropdownColumn { static create(col, trigger, parent) { const drop = new Dropdown({ ...col.dropOptions, parent }); - drop.onselected = trigger; + drop.onSelected = trigger; return drop.create(); } diff --git a/lib/element/schedule.js b/lib/element/schedule.js index d96edd6..3e58465 100644 --- a/lib/element/schedule.js +++ b/lib/element/schedule.js @@ -121,7 +121,7 @@ export default class ScheduleItem { { value: '1', text: 'Weekly' }, { value: '2', text: 'Monthly' } ]; - drop.onselected = item => { + drop.onSelected = item => { container.querySelector('.schedule-item-weekly').style.display = item.value === '1' ? '' : 'none'; const monthly = item.value === '2'; container.querySelector('.schedule-item-monthly').style.display = monthly ? '' : 'none'; diff --git a/lib/element/style.css b/lib/element/style.css deleted file mode 100644 index 6e4356d..0000000 --- a/lib/element/style.css +++ /dev/null @@ -1 +0,0 @@ -.schedule-item-container fieldset{margin-top:10px;border-width:1px;border-radius:4px;border-color:var(--border-color)}.schedule-item-container fieldset legend,.schedule-item-container fieldset span{font-weight:400;font-size:var(--font-size);padding-left:8px;padding-right:6px;color:var(--color)}.schedule-item-container fieldset .ui-input{line-height:20px}.schedule-item-container fieldset .schedule-item-monthly{margin-top:5px}.schedule-item-container fieldset .schedule-item-monthly .ui-input{width:40px}.schedule-item-container fieldset.schedule-item-daily-frequency .ui-input{vertical-align:top;margin-top:5px}.schedule-item-container fieldset .schedule-item-table{width:100%}.schedule-item-container fieldset .schedule-item-line-occur-every{display:flex;align-items:flex-start}.schedule-item-container fieldset .schedule-item-line-occur-every>.schedule-item-block>.scheldule-item-line{display:flex;align-items:center;margin-top:5px}.schedule-item-container fieldset .schedule-item-line-occur-every>.schedule-item-block>.scheldule-item-line>span{flex:1 1 auto}.schedule-item-container fieldset .schedule-item-line-occur-every>.schedule-item-block>.scheldule-item-line>.ui-input{margin-top:0}.schedule-item-container fieldset .schedule-item-line-occur-every>span{line-height:36px}.schedule-item-container fieldset .schedule-item-line-occur-every .ui-input{width:70px}.schedule-item-container fieldset .schedule-item-line-duration{display:flex;align-items:center;height:36px}.schedule-item-container fieldset .schedule-item-line>.schedule-item-placeholder{flex:1 1 auto}.schedule-item-container .schedule-item-frequency{margin-top:0} \ No newline at end of file diff --git a/lib/ui/css/dropdown.css b/lib/ui/css/dropdown.css deleted file mode 100644 index 235bc92..0000000 --- a/lib/ui/css/dropdown.css +++ /dev/null @@ -1 +0,0 @@ -.ui-drop-wrapper{display:inline-block;border:none;border-radius:unset;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:relative;font-size:var(--font-size);font-family:var(--font-family)}.ui-drop-wrapper>.ui-drop-header{background-color:var(--bg-color);display:flex;height:26px;border:1px solid var(--border-color);border-radius:var(--border-radius);transition:border-color .12s ease}.ui-drop-wrapper>.ui-drop-header:focus,.ui-drop-wrapper>.ui-drop-header:focus-visible{outline:none}.ui-drop-wrapper>.ui-drop-header:focus,.ui-drop-wrapper>.ui-drop-header:hover{border-color:var(--focus-border-color)}.ui-drop-wrapper>.ui-drop-header:disabled{border-color:var(--disabled-border-color);color:var(--disabled-color);background-color:var(--disabled-bg-color)}.ui-drop-wrapper>.ui-drop-header>.ui-drop-text{flex:1 1 auto;cursor:pointer;font-size:var(--font-size);padding:0 6px;overflow:hidden;text-overflow:ellipsis;border:none;white-space:nowrap}.ui-drop-wrapper>.ui-drop-header>.ui-drop-text:focus,.ui-drop-wrapper>.ui-drop-header>.ui-drop-text:focus-visible{outline:none}.ui-drop-wrapper>.ui-drop-header>input.ui-drop-text{cursor:initial}.ui-drop-wrapper>.ui-drop-header>input.ui-drop-text::-moz-placeholder{font-size:var(--font-smaller-size);font-style:italic}.ui-drop-wrapper>.ui-drop-header>input.ui-drop-text::placeholder{font-size:var(--font-smaller-size);font-style:italic}.ui-drop-wrapper>.ui-drop-header>.ui-drop-caret{flex:0 0 auto;width:26px;display:flex;justify-content:center;align-items:center;cursor:pointer}.ui-drop-wrapper>.ui-drop-header>.ui-drop-caret::after{display:block;content:"";border-top:4px solid;border-left:4px solid rgba(0,0,0,0);border-right:4px solid rgba(0,0,0,0);height:0;width:0}.ui-drop-wrapper>.ui-drop-header.disabled{border-color:var(--disabled-border-color);background-color:var(--disabled-bg-color);color:var(--disabled-color)}.ui-drop-wrapper>.ui-drop-header.disabled:focus{border-color:var(--disabled-border-color)}.ui-drop-wrapper>.ui-drop-header.disabled>.ui-drop-text,.ui-drop-wrapper>.ui-drop-header.disabled>.ui-drop-caret{cursor:default}.ui-drop-box{position:absolute;visibility:hidden;opacity:0;transform:scaleY(0);transform-origin:top;background-color:var(--bg-color);top:28px;z-index:2;transition:transform 120ms ease,opacity 120ms ease,visibility 120ms ease;min-width:calc(100% + 2px);box-sizing:border-box;box-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);left:-1px}.ui-drop-box.slide-up{transform-origin:bottom;top:unset;bottom:28px}.ui-drop-box.active{visibility:visible;opacity:1;transform:scaleY(1)}.ui-drop-box>.ui-drop-search{box-sizing:border-box;height:36px;line-height:36px;padding:0 8px;position:relative;display:flex;align-items:center}.ui-drop-box>.ui-drop-search>input[type=text]{box-sizing:border-box;width:100%;height:26px;padding:0 6px 0 22px;color:var(--color);border:1px solid var(--border-color);border-radius:var(--border-radius);transition:border-color .12s ease}.ui-drop-box>.ui-drop-search>input[type=text]:focus,.ui-drop-box>.ui-drop-search>input[type=text]:focus-visible{outline:none}.ui-drop-box>.ui-drop-search>input[type=text]:focus,.ui-drop-box>.ui-drop-search>input[type=text]:hover{border-color:var(--focus-border-color)}.ui-drop-box>.ui-drop-search>input[type=text]:disabled{border-color:var(--disabled-border-color);color:var(--disabled-color);background-color:var(--disabled-bg-color)}.ui-drop-box>.ui-drop-search>input[type=text]::-moz-placeholder{font-style:italic}.ui-drop-box>.ui-drop-search>input[type=text]::placeholder{font-style:italic}.ui-drop-box>.ui-drop-search>svg{position:absolute;left:14px;width:13px;height:100%;cursor:text}.ui-drop-box>.ui-drop-list{margin:0;padding:0;list-style:none;max-height:210px;overflow-y:auto;font-size:var(--font-size)}.ui-drop-box>.ui-drop-list::-webkit-scrollbar{width:8px;height:8px}.ui-drop-box>.ui-drop-list::-webkit-scrollbar-thumb{background-color:rgba(168,168,168,.9);border-radius:4px}.ui-drop-box>.ui-drop-list.filtered>li:first-child{background-color:var(--hover-bg-color)}.ui-drop-box>.ui-drop-list>li{line-height:30px;height:30px;padding:0 10px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ui-drop-box>.ui-drop-list>li:hover,.ui-drop-box>.ui-drop-list>li.selected{background-color:var(--hover-bg-color)}.ui-drop-box>.ui-drop-list>li>.ui-check-wrapper{height:30px;display:flex} \ No newline at end of file diff --git a/lib/ui/css/grid.css b/lib/ui/css/grid.css deleted file mode 100644 index ed3072c..0000000 --- a/lib/ui/css/grid.css +++ /dev/null @@ -1 +0,0 @@ -.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>div>.ui-check-wrapper{height:20px}.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 .ui-grid-date-cell{line-height:22px;box-sizing:border-box;padding:var(--spacing-cell);border:none;font-size:var(--font-size);width:100%}.ui-grid>.ui-grid-wrapper>.ui-grid-table>tbody>.ui-grid-row>td .ui-grid-date-cell:invalid{color:rgba(0,0,0,.3)}.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 8507e5a..9cc4962 100644 --- a/lib/ui/css/grid.scss +++ b/lib/ui/css/grid.scss @@ -95,7 +95,7 @@ &.sticky { position: sticky; - z-index: 2; + z-index: 3; } >div { @@ -190,9 +190,9 @@ transition: background-color .12s ease; } - &:hover::after { - background-color: var(--split-border-color); - } + // &:hover::after { + // background-color: var(--split-border-color); + // } } >.dragger { @@ -241,6 +241,10 @@ padding: var(--header-filter-padding); } } + + &:hover>th>.spliter::after { + background-color: var(--split-border-color); + } } } @@ -435,7 +439,7 @@ } } - >.ui-drop-box { + ~.ui-drop-box { max-width: 300px; } diff --git a/lib/ui/dropdown.d.ts b/lib/ui/dropdown.d.ts index 6d2ec86..93d1bc5 100644 --- a/lib/ui/dropdown.d.ts +++ b/lib/ui/dropdown.d.ts @@ -1,48 +1,118 @@ -interface DropdownItem { +/** 下拉项接口 */ +export interface DropdownItem { + /** 值 */ value: string; + /** 显示文本 */ text: string; + /** 源码显示内容 */ html?: HTMLElement } +/** 下拉框选项接口 */ export interface DropdownOptions { - textkey?: string; - valuekey?: string; - htmlkey?: string; - maxlength?: Number; - multiselect?: boolean; + /** 文本关键字,默认值 text */ + textKey?: string; + /** 值关键字,默认值 value */ + valueKey?: string; + /** 源码显示的关键字,默认值 html */ + htmlKey?: string; + /** 最大输入长度,默认值 500 */ + maxLength?: Number; + /** 是否允许多选 */ + multiSelect?: boolean; + /** 选中值 */ selected?: string; - selectedlist?: Array; + /** 选中的数组 */ + selectedList?: Array; + /** 是否禁用 */ disabled?: boolean; + /** 是否支持输入 */ input?: boolean; + /** 是否支持搜索 */ search?: boolean; - searchkeys?: Array; - searchplaceholder?: string; - tabindex?: Number; + /** 搜索的关键字数组 */ + searchKeys?: Array; + /** 搜索提示文本,默认值取语言资源 searchHolder "Search..." */ + searchPlaceholder?: string; + /** 焦点索引 */ + tabIndex?: Number; + /** 输入框的提示文本 */ placeholder?: string; - slidefixed?: boolean; - parent?: HTMLElement; + /** 是否固定为向下展开 */ + slideFixed?: boolean; + /** 父元素,默认添加到头元素之后 */ + wrapper?: HTMLElement; } +/** 下拉框类 */ export class Dropdown { + /** + * 把父元素下的所有 select 元素修改为统一下拉框组件 + * @param dom 父元素 + * @returns 返回该父元素 + */ static resolve(dom?: HTMLElement): HTMLElement; + /** + * 下拉框的构造函数 + * @param options 下拉框选项 + */ constructor(options?: DropdownOptions); + /** 根据该函数返回数据源 */ sourceFilter: () => Array; - onselected: (item: DropdownItem | any) => void; - onselectedlist: (list: Array) => void; - onexpanded: () => void; + /** + * 选中时触发 + * @param item 选中的条目 + */ + onSelected: (item: DropdownItem | any) => void; + /** + * 选中多个时触发 + * @param list 选中的条目数组 + */ + onSelectedList: (list: Array) => void; + /** 下拉框展开时触发 */ + onExpanded: () => void; + /** 下拉框收缩时触发 */ + onCollapsed: () => void; + /** 获取下拉框是否禁用 */ get disabled(): boolean; + /** + * 设置下拉框禁用状态 + * @param flag 禁用状态 + */ set disabled(flag: boolean); + /** 获取数据源 */ get source(): Array; + /** + * 设置数据源 + * @param list 数据源 + */ set source(list: Array); - get multiselect(): boolean; + /** 获取是否允许多选 */ + get multiSelect(): boolean; + /** 获取选中的条目 */ get selected(): DropdownItem | any; - get selectedlist(): Array; + /** 获取选中的条目列表 */ + get selectedList(): Array; + /** + * 创建下拉框元素 + * @returns 返回创建的下拉框元素 + */ create(): HTMLElement; + /** + * 选中某个条目 + * @param selected 选中的值 + * @param silence 是否静默选中,即不触发 {@linkcode onSelected} 事件 + */ select(selected: string, silence?: boolean): void; + /** + * 选中条目列表 + * @param selectedlist 选中的值的列表 + * @param silence 是否静默选中,即不触发 {@linkcode onSelected} 事件 + */ selectlist(selectedlist: Array, silence?: boolean): void; } diff --git a/lib/ui/dropdown.js b/lib/ui/dropdown.js index 2ee73e6..26e93e3 100644 --- a/lib/ui/dropdown.js +++ b/lib/ui/dropdown.js @@ -31,8 +31,8 @@ if (dropdownGlobal == null) { continue; } const dropdown = this[dropId]; - if (dropdown?.multiselect && typeof dropdown.oncollapsed === 'function') { - dropdown.oncollapsed(); + if (dropdown?.multiSelect && typeof dropdown.onCollapsed === 'function') { + dropdown.onCollapsed(); } } } @@ -97,9 +97,10 @@ export class Dropdown { // _var.selectedList; sourceFilter; - onselectedlist; - onselected; - onexpanded; + onSelectedList; + onSelected; + onExpanded; + onCollapsed; constructor(options = {}) { options.searchPlaceholder ??= r('searchHolder', 'Search...'); @@ -173,8 +174,8 @@ export class Dropdown { return; } this._dropdown(!active); - if (!active && typeof this.onexpanded === 'function') { - setTimeout(() => this.onexpanded(), 120); + if (!active && typeof this.onExpanded === 'function') { + setTimeout(() => this.onExpanded(), 120); } }); @@ -216,7 +217,7 @@ export class Dropdown { return wrapper; } - get multiselect() { return this._var.options.multiSelect } + get multiSelect() { return this._var.options.multiSelect } get disabled() { return this._var.wrapper == null || this._var.wrapper.querySelector('.ui-drop-header.disabled') != null } @@ -257,9 +258,12 @@ export class Dropdown { get selected() { return this._var.selected } - get selectedlist() { return this._var.selectedList || [] } + get selectedList() { return this._var.selectedList || [] } select(selected, silence) { + if (typeof selected !== 'string') { + selected = String(selected); + } if (this._var.lastSelected === selected) { return false; } @@ -267,7 +271,7 @@ export class Dropdown { const valuekey = this._var.options.valueKey; const textkey = this._var.options.textKey; const htmlkey = this._var.options.htmlKey; - let item = this.source.find(it => it[valuekey] === selected); + let item = this.source.find(it => String(it[valuekey]) === selected); if (this._var.options.input) { if (item == null) { item = { [valuekey]: selected }; @@ -304,8 +308,8 @@ export class Dropdown { } } this._var.selected = item; - if (!silence && typeof this.onselected === 'function') { - this.onselected(item); + if (!silence && typeof this.onSelected === 'function') { + this.onSelected(item); } } @@ -314,10 +318,14 @@ export class Dropdown { const valuekey = this._var.options.valueKey; const textkey = this._var.options.textKey; const htmlkey = this._var.options.htmlKey; - const itemlist = selectedlist.map(v => { - let item = source.find(it => it[valuekey] === v); + const itemlist = selectedlist.map(a => { + const v = typeof a === 'string' ? a : String(a); + let item = source.find(it => String(it[valuekey]) === v); if (item == null) { - item = { [valuekey]: v, [textkey]: v }; + item = { + [valuekey]: v, + [textkey]: v + }; } return item; }); @@ -328,8 +336,8 @@ export class Dropdown { } selectItems(this._var.label, itemlist, htmlkey, textkey); this._var.selectedList = itemlist; - if (!silence && typeof this.onselectedlist === 'function') { - this.onselectedlist(itemlist); + if (!silence && typeof this.onSelectedList === 'function') { + this.onSelectedList(itemlist); } } @@ -357,7 +365,7 @@ export class Dropdown { } // list const list = createElement('ul', 'ui-drop-list'); - if (!this.multiselect) { + if (!this.multiSelect) { list.addEventListener('click', e => { let li = e.target; while (li.tagName !== 'LI') { @@ -436,7 +444,7 @@ export class Dropdown { _filllist(source) { const list = this._var.container.querySelector('.ui-drop-list'); list.replaceChildren(); - const multiselect = this.multiselect; + const multiselect = this.multiSelect; const allchecked = this._var.allChecked; if (multiselect) { list.appendChild( @@ -455,10 +463,13 @@ export class Dropdown { const textkey = this._var.options.textKey; const htmlkey = this._var.options.htmlKey; const selected = this.selected; - const selectedlist = this.selectedlist; + const selectedlist = this.selectedList; let scrolled; source.slice(0, 200).forEach((item, i) => { - const val = item[valuekey]; + let val = item[valuekey]; + if (typeof val !== 'string') { + val = String(val); + } const li = createElement('li'); li.dataset.value = val; li.setAttribute('title', item[textkey]); @@ -471,7 +482,7 @@ export class Dropdown { label.innerHTML = html; } if (multiselect) { - const selected = selectedlist.some(s => s[valuekey] === val); + const selected = selectedlist.some(s => String(s[valuekey]) === val); if (label == null) { label = createElement('span'); label.innerText = item[textkey]; @@ -492,7 +503,7 @@ export class Dropdown { } else { li.appendChild(label); } - if (selected != null && selected[valuekey] === val) { + if (selected != null && String(selected[valuekey]) === val) { scrolled = DropdownItemHeight * i; li.classList.add('selected'); } @@ -522,7 +533,10 @@ export class Dropdown { } else { const source = this.source; list = [...this._var.container.querySelectorAll('input.dataitem:checked')] - .map(c => source.find(it => it[valuekey] === c.dataset.value)) + .map(c => { + const v = c.dataset.value; + return source.find(it => String(it[valuekey]) === v); + }) .filter(it => it != null); } } else { @@ -530,9 +544,9 @@ export class Dropdown { if (this._var.allChecked) { this._var.allChecked = false; this._var.container.querySelector('input[isall="1"]').checked = false; - list = this.source.filter(it => it[valuekey] !== val); + list = this.source.filter(it => String(it[valuekey]) !== val); } else { - list = this.selectedlist.filter(it => it[valuekey] !== val); + list = this.selectedList.filter(it => String(it[valuekey]) !== val); } } if (this._var.allChecked) { @@ -541,8 +555,8 @@ export class Dropdown { selectItems(this._var.label, list, htmlkey, textkey); } this._var.selectedList = list; - if (typeof this.onselectedlist === 'function') { - this.onselectedlist(itemlist); + if (typeof this.onSelectedList === 'function') { + this.onSelectedList(itemlist); } } diff --git a/lib/ui/grid/column.d.ts b/lib/ui/grid/column.d.ts index 7e1e761..599e1a1 100644 --- a/lib/ui/grid/column.d.ts +++ b/lib/ui/grid/column.d.ts @@ -1,69 +1,220 @@ import { Grid, GridItem, GridItemWrapper, GridSourceItem } from "./grid"; -import { DropdownOptions } from "../dropdown"; +import { Dropdown, DropdownOptions } from "../dropdown"; +/** 列类型枚举 */ interface GridColumnType { + /** 通用列 */ 0: "Common"; + /** 单行文本框列 */ 1: "Input"; + /** 下拉选择列 */ 2: "Dropdown"; + /** 复选框列 */ 3: "Checkbox"; + /** 图标列 */ 4: "Icon"; + /** 多行文本列 */ 5: "Text"; + /** 日期选择列 */ + 6: "Date"; } +/** 列定义接口 */ export interface GridColumnDefinition { + /** 列关键字,默认以该关键字从行数据中提取单元格值,行数据的关键字属性值里包含 DisplayValue 则优先显示此值 */ key?: string; + /** 列的类型,可以为 {@linkcode GridColumn} 的子类,或者内置类型 {@linkcode GridColumnType} */ type?: keyof GridColumnType | typeof GridColumn; + /** 列标题文本 */ caption?: string; + /** 列标题的元素样式 */ captionStyle?: { [key: string]: string }; + /** 大于 0 则设置为该宽度,否则根据列内容自动调整列宽 */ width?: Number; + /** 列对齐方式 */ align?: "left" | "center" | "right"; + /** + * 列是否可用(可编辑),允许以下类型

+ * boolean 则直接使用该值

+ * string 则以该值为关键字从行数据中取值作为判断条件

+ * (item: GridItem | any) => boolean 则调用该函数(上下文为列定义对象),以返回值作为判断条件

+ */ enabled?: boolean | string | ((item: GridItem | any) => boolean); - css?: { [key: string]: string }; - styleFilter?: (item: GridItem | any) => { [key: string]: string }; - visible?: boolean; - resizable?: boolean; - sortable?: boolean; - orderable?: boolean; - allcheck?: boolean; - events?: { [event: string]: any }; - attrs?: { [key: string]: string } | ((item: GridItem | any) => { [key: string]: string }); - allowFilter?: boolean; + /** 单元格取值采用该方法返回的值 */ filter?: (item: GridItem | any) => any; - sortFilter?: (a: GridItem | any, b: GridItem | any) => -1 | 0 | 1; - bgFilter?: (item: GridItem | any) => string; - dropOptions?: DropdownOptions; - source?: Array | ((item: GridItem | any) => Array | Promise>); - iconType?: string; - iconClassName?: string | ((item: GridItem | any) => string); + /** 单元格以该值填充内容,忽略filter与关键字属性 */ text?: string; + /** 列是否可见 */ + visible?: boolean; + /** 列是否允许调整宽度 */ + resizable?: boolean; + /** 列是否允许排序 */ + sortable?: boolean; + /** 列是否允许重排顺序 */ + orderable?: boolean; + /** 列为复选框类型时是否在列头增加全选复选框 */ + allcheck?: boolean; + /** 单元格css样式对象(仅在重建行元素时读取) */ + css?: { [key: string]: string }; + /** 根据返回值填充单元格样式(填充行列数据时读取) */ + styleFilter?: (item: GridItem | any) => { [key: string]: string }; + /** 根据返回值设置单元格背景色 */ + bgFilter?: (item: GridItem | any) => string; + /** 给单元格元素附加事件(事件函数上下文为数据行对象) */ + events?: { [event: string]: any }; + /** 根据返回值设置单元格元素的附加属性,允许直接设置对象也支持函数返回对象 */ + attrs?: { [key: string]: string } | ((item: GridItem | any) => { [key: string]: string }); + /** 是否允许进行列头过滤 */ + allowFilter?: boolean; + /** 自定义列过滤器的数据源(函数上下文为Grid) */ + filterSource?: Array | ((col: GridColumnDefinition) => Array); + /** 自定义列排序函数 */ + sortFilter?: (a: GridItem | any, b: GridItem | any) => -1 | 0 | 1; + /** 列为下拉列表类型时以该值设置下拉框的参数 */ + dropOptions?: DropdownOptions; + /** 列为下拉列表类型时以该值设置下拉列表数据源,支持函数返回,也支持返回异步对象 */ + source?: Array | ((item: GridItem | any) => Array | Promise>); + /** 下拉列表数据源是否缓存结果(即行数据未发生变化时仅从source属性获取一次值) */ + sourceCache?: boolean; + /** 列为图标类型时以该值设置图标样式(函数上下文为列定义对象),允许值为 fa-lightfa-regularfa-solid */ + iconType?: string; + /** 列为图标类型时以该值作为单元格元素的额外样式类型(函数上下文为列定义对象) */ + iconClassName?: string | ((item: GridItem | any) => string); + /** 列为日期类型时以该值作为最小可选日期值 */ + dateMin?: string; + /** 列为日期类型时以该值作为最大可选日期值 */ + dateMax?: string; + /** 以返回值额外设置单元格的tooltip(函数上下文为列定义对象) */ tooltip?: string | ((item: GridItem | any) => string); + + /** + * 列头复选框改变时触发 + * @param this 上下文为 Grid 对象 + * @param col 列定义对象 + * @param flag 是否选中 + */ onAllChecked?: (this: Grid, col: GridColumnDefinition, flag: boolean) => void; + /** + * 单元格发生变化时触发 + * @param this 上下文为 Grid 对象 + * @param item 数据行对象 + * @param value 修改后的值 + * @param oldValue 修改前的值 + * @param e 列修改事件传递过来的任意对象 + */ onChanged?: (this: Grid, item: GridItem | any, value: boolean | any, oldValue: any, e?: any) => void; + /** + * 文本单元格在输入完成时触发的事件 + * @param this 上下文为 Grid 对象 + * @param item 数据行对象 + * @param value 修改后的文本框值 + */ + onInputEnded?: (this: Grid, item: GridItem | any, value: string) => void; + /** + * 列过滤点击OK时触发的事件 + * @param this 上下文为 Grid 对象 + * @param col 列定义对象 + * @param selected 选中的过滤项 + */ + onFilterOk?: (this: Grid, col: GridColumnDefinition, selected: Array) => void; + /** + * 列过滤后触发的事件 + * @param this 上下文为 Grid 对象 + * @param col 列定义对象 + */ + onFiltered?: (this: Grid, col: GridColumnDefinition) => void; + /** + * 列为下拉框类型时在下拉列表展开时触发的事件 + * @param this 上下文为列定义对象 + * @param item 数据行对象 + * @param drop 下拉框对象 + */ + onDropExpanded?: (this: GridColumnDefinition, item: GridItem | any, drop: Dropdown) => void; } +/** 列定义基类 */ export class GridColumn { + /** + * 创建显示单元格时调用的方法 + * @param col 列定义对象 + * @returns 返回创建的单元格元素 + */ static create(col: GridColumnDefinition): HTMLElement; + /** + * 创建编辑单元格时调用的方法

+ * 元素修改后设置行包装对象的 __editing 后,支持在离开编辑状态时及时触发 {@linkcode leaveEdit} 方法
+ * 更多例子参考代码中 {@linkcode GridDropdownColumn} 的实现。 + * @param trigger 编辑事件回调函数,e 参数会传递给 {@linkcode getValue} 方法 + * @param col 列定义对象 + * @param container 父容器元素 + * @param vals 行包装对象,其 values 属性为行数据对象 + * @returns 返回创建的编辑状态的单元格元素 + */ static createEdit(trigger: (e: any) => void, col: GridColumnDefinition, container: HTMLElement, vals: GridItemWrapper): HTMLElement; - static setValue(element: HTMLElement, val: any, vals: GridItemWrapper, col: GridColumnDefinition, grid: Grid): void; - static getValue(e: any, col: GridColumnDefinition): any; + /** + * 设置单元格值时调用的方法 + * @param element 单元格元素 + * @param val 待设置的单元格值 + * @param vals 行包装对象 + * @param col 列定义对象 + * @param grid {@linkcode Grid} 对象 + */ + static setValue(element: HTMLElement, val: string | boolean | any, vals: GridItemWrapper, col: GridColumnDefinition, grid: Grid): void; + /** + * 获取编辑状态单元格值时调用的方法 + * @param e 由 {@linkcode createEdit} 方法中 trigger 函数传递来的对象 + * @param col 列定义对象 + * @returns 返回单元格的值 + */ + static getValue(e: any, col: GridColumnDefinition): string | boolean | any; + /** + * 设置单元格样式时调用的方法 + * @param element 单元格元素 + * @param style 样式对象 + */ static setStyle(element: HTMLElement, style: { [key: string]: string }): void; + /** + * 设置单元格可用性时调用的方法 + * @param element 单元格元素 + * @param enabled 启用值,为false时代表禁用 + */ static setEnabled(element: HTMLElement, enabled?: boolean): void; -} - -export class GridInputColumn extends GridColumn { - static get editing(): boolean; -} - -export class GridTextColumn extends GridInputColumn { } - -export class GridDropdownColumn extends GridColumn { + /** + * 单元格离开编辑元素时触发,需要由行包装对象的 __editing 来确定是否触发。 + * @param element 单元格元素 + * @param container 父容器元素 + */ static leaveEdit(element: HTMLElement, container: HTMLElement): void; } +/** 单行文本列 */ +export class GridInputColumn extends GridColumn { + /** + * 设置该类型是否支持触发 {@linkcode GridColumnDefinition.onInputEnded} 方法
+ * 该属性返回 true 后,在任意事件中修改行包装对象的 __editing 值,则会在行列元素变动时及时触发 {@linkcode GridColumnDefinition.onInputEnded} 方法,避免例如文本框还未触发 onchange 事件就被移除元素而导致的问题
+ * 更多例子参考代码中 {@linkcode GridInputColumn} 的实现 + */ + static get editing(): boolean; +} + +/** 多行文本列 */ +export class GridTextColumn extends GridInputColumn { } + +/** 下拉选择列 */ +export class GridDropdownColumn extends GridColumn { } + +/** 复选框列 */ export class GridCheckboxColumn extends GridColumn { } +/** 图标列 */ export class GridIconColumn extends GridColumn { } +/** 日期选择列 */ export class GridDateColumn extends GridColumn { + /** + * 格式化日期对象为 M/d/yyyy 格式的字符串 + * @param date 日期对象 + * @returns 返回格式化后的字符串 + */ static formatDate(date: Date): string; } \ No newline at end of file diff --git a/lib/ui/grid/column.js b/lib/ui/grid/column.js index e9d5c94..ad8dbc9 100644 --- a/lib/ui/grid/column.js +++ b/lib/ui/grid/column.js @@ -105,13 +105,13 @@ export class GridTextColumn extends GridInputColumn { const SymbolDropdown = Symbol.for('ui-dropdown'); export class GridDropdownColumn extends GridColumn { - static createEdit(trigger, col, wrapper, it) { + static createEdit(trigger, col, container, it) { const drop = new Dropdown({ ...col.dropOptions, - wrapper + wrapper: container.parentElement }); - drop.onselected = trigger; - drop.onexpanded = function () { + drop.onSelected = trigger; + drop.onExpanded = function () { if (it.__editing == null) { it.__editing = { [col.key]: true @@ -211,8 +211,8 @@ export class GridDropdownColumn extends GridColumn { drop.disabled = enabled === false; } - static leaveEdit(element, wrapper) { - wrapper.querySelectorAll('.ui-drop-box.active').forEach(e => { + static leaveEdit(element, container) { + container.parentElement.querySelectorAll('.ui-drop-box.active').forEach(e => { if (e != null) { e.classList.remove('active'); } @@ -221,8 +221,8 @@ export class GridDropdownColumn extends GridColumn { if (drop == null) { return; } - if (drop?.multiselect && typeof drop.oncollapsed === 'function') { - drop.oncollapsed(); + if (drop?.multiSelect && typeof drop.onCollapsed === 'function') { + drop.onCollapsed(); } } } @@ -286,7 +286,16 @@ export class GridIconColumn extends GridColumn { } export class GridDateColumn extends GridColumn { - static createEdit(trigger, col) { + static createEdit(trigger, col, _container, vals) { + let enabled = col.enabled; + if (typeof enabled === 'string') { + enabled = vals.values[enabled]; + } else if (typeof enabled === 'function') { + enabled = col.enabled(vals.values); + } + if (enabled === false) { + return super.create(); + } const date = createElement('input', 'ui-grid-date-cell'); date.required = true; date.type = 'date'; @@ -306,25 +315,45 @@ export class GridDateColumn extends GridColumn { if (isNaN(val) || /^\d{4}-\d{2}-\d{2}$/.test(val)) { element.value = val; } else { - val = new Date((val - 621355968e9) / 10000); + val = new Date((val - 621355968e9) / 1e4); const month = String(val.getMonth() + 1).padStart(2, '0'); const date = String(val.getDate()).padStart(2, '0'); element.value = `${val.getFullYear()}-${month}-${date}`; } } else { - element.innerText = val; + element.innerText = this.formatDate(val); } } static getValue(e) { - return e.target?.value; + const date = e.target?.valueAsDate; + if (date instanceof Date && !isNaN(date)) { + const year = date.getFullYear(); + if (year < 1900 || year > 9999) { + return ''; + } + return String(date.getTime() * 1e4 + 621355968e9); + } + return ''; } static setEnabled(element, enabled) { element.disabled = enabled === false; } + static _resolveDate(s) { + if (s instanceof Date) { + return s; + } + const ticks = Number(s); + if (!isNaN(ticks) && ticks > 0) { + return new Date((ticks - 621355968e9) / 1e4); + } + return new Date(s); + } + static formatDate(date) { + date = this._resolveDate(date); if (date instanceof Date && !isNaN(date)) { return `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`; } diff --git a/lib/ui/grid/grid.d.ts b/lib/ui/grid/grid.d.ts index 2107942..70b7b33 100644 --- a/lib/ui/grid/grid.d.ts +++ b/lib/ui/grid/grid.d.ts @@ -1,93 +1,244 @@ import { GridColumnDefinition } from "./column" +/** 列数据接口 */ export interface GridItem { + /** 值 */ Value: any; + /** 显示值 */ DisplayValue: string; } +/** 列数据行包装接口 */ export interface GridItemWrapper { - values: Array; + /** 真实数据对象 */ + values: { [key: string]: GridItem | any }; + /** 下拉数据源缓存对象 */ source: { [key: string]: Array }; } +/** 下拉框列数据源接口 */ export interface GridSourceItem { + /** 值 */ value: string; + /** 显示文本 */ text: string; } +/** 列排序枚举 */ interface GridColumnDirection { + /** 倒序 */ [-1]: Number, + /** 升序 */ 1: Number } +/** 列事件枚举 */ interface GridColumnColumnEventMap { + /** 重排事件 */ "reorder": string, + /** 宽调整事件 */ "resize": string, + /** 排序事件 */ "sort": string } +/** Grid 控件基础类 */ export class Grid { + /** 列类型枚举 */ static ColumnTypes: { + /** 通用列(只读) */ Common: 0, + /** 单行文本列 */ Input: 1, + /** 下拉选择列 */ Dropdown: 2, + /** 复选框列 */ Checkbox: 3, + /** 图标列 */ Icon: 4, + /** 多行文本列 */ Text: 5, + /** 日期选择列 */ Date: 6, + /** + * 判断列是否为复选框列 + * @param type 列类型 + */ isCheckbox(type: Number): boolean; }; + /** 列定义的数组 */ columns: Array; + /** 多语言资源对象 */ langs?: { all: string, ok: string, reset: string }; + /** 行数大于等于该值则启用虚模式,默认值 100 */ virtualCount?: Number; + /** 表格行高,默认值 36 */ rowHeight?: Number; + /** 文本行高,默认值 24 */ lineHeight?: Number; + /** 列表底部留出额外行的空白,默认值 0 */ extraRows?: Number; + /** 过滤条件列表的行高,默认值 30 */ filterRowHeight?: Number; + /** 列表高度值,为 0 时列表始终显示全部内容(自增高),为非数字或者小于 0 则根据容器高度来确定虚模式的渲染行数,默认值 null */ height?: Number; + /** 列表是否为只读,默认值 false */ readonly?: boolean; + /** 是否允许多选,默认值 false */ multiSelect?: boolean; + /** 为 false 时只有点击在单元格内才会选中行,默认值 true */ fullrowClick?: boolean; + /** 单元格 tooltip 是否禁用,默认值 false */ tooltipDisabled?: boolean; + /** 列头是否显示,默认值 true */ headerVisible?: boolean; + /** 监听事件的窗口载体,默认值 window */ window?: Window + /** 排序列的索引,默认值 -1 */ sortIndex?: Number; + /** 排序方式,正数升序,负数倒序,默认值 1 */ sortDirection?: keyof GridColumnDirection; - constructor(container: HTMLElement, getText?: (id: string, def?: string) => string); + /** + * Grid 控件构造函数 + * @param container Grid 控件所在的父容器,可以是 string 表示选择器,也可以是 HTMLElement 对象

+ * 构造时可以不进行赋值,但是调用 init 函数时则必须进行赋值 + * @param getText (可选参数)获取多语言文本的函数代理 + */ + constructor(container: string | HTMLElement, getText?: (id: string, def?: string) => string); + /** + * 即将选中行时触发,返回 false、null、undefined、0 等则取消选中动作 + * @param index 即将选中的行索引 + * @param colIndex 即将选中的列索引 + */ willSelect?: (index: Number, colIndex: Number) => boolean; + /** + * 单元格单击时触发,colIndex 为 -1 则表示点击的是行的空白处,返回 false 则取消事件冒泡 + * @param index 点击的行索引 + * @param colIndex 点击的列索引 + */ cellClicked?: (index: Number, colIndex: Number) => boolean; + /** + * 选中行发生变化时触发的事件 + * @param index 选中的行索引 + */ onSelectedRowChanged?: (index?: Number) => void; + /** + * 单元格双击时触发的事件,colIndex 为 -1 则表示点击的是行的空白处 + * @param index 双击的行索引 + * @param colIndex 双击的列索引 + */ onCellDblClicked?: (index: Number, colIndex: Number) => void; + /** + * 行双击时触发的事件 + * @param index 双击的行索引 + */ onRowDblClicked?: (index: Number) => void; - onColumnChanged?: (type: K, index: Number, value: Number | keyof GridColumnDirection) => void; + /** + * 列发生变化时触发的事件 + * @param type 事件类型

+ * "reorder" 为发生列重排事件,此时 value 为目标列索引
+ * "resize" 为发生列宽调整事件,此时 value 为列宽度值
+ * "sort" 为发生列排序事件,此时 value 为 1(升序)或 -1(倒序) + * @param colIndex 发生变化事件的列索引 + * @param value 变化的值 + */ + onColumnChanged?: (type: keyof GridColumnColumnEventMap, colIndex: Number, value: Number | keyof GridColumnDirection) => void; + /** + * 列滚动时触发的事件 + * @param e 滚动事件对象 + */ onBodyScrolled?: (e: Event) => void; + /** 获取数据数组 */ get source(): Array; + /** 设置数据,并刷新列表 */ set source(list: Array); + /** 获取当前选中的行索引的数组 */ get selectedIndexes(): Array; + /** 设置当前选中的行索引的数组,并刷新列表 */ set selectedIndexes(indexes: Array); + /** 获取 Grid 当前是否处于加载状态 */ get loading(): boolean; + /** 使 Grid 进入加载状态 */ set loading(flag: boolean); + /** 获取 Grid 当前滚动的偏移量 */ get scrollTop(): Number; + /** 设置 Grid 滚动偏移量 */ set scrollTop(top: Number); - get element(): HTMLElement + /** 获取 Grid 的页面元素 */ + get element(): HTMLElement; + /** 获取当前 Grid 是否已发生改变 */ + get changed(): boolean; + /** 获取当前是否为虚模式状态 */ get virtual(): boolean; + /** 获取当前排序的列关键字,为 null 则当前无排序列 */ get sortKey(): string | undefined; + /** 获取当前选中行的索引,为 -1 则当前没有选中行 */ get selectedIndex(): Number | -1; + /** + * 初始化Grid控件 + * @param container 父容器元素,若未传值则采用构造方法中传入的父容器元素 + */ init(container?: HTMLElement): void; + /** + * 设置数据列表,该方法为 set source 属性的语法糖 + * @param source 待设置的数据列表 + */ setData(source: Array): void; + /** + * 设置单行数据 + * @param index 行索引 + * @param item 待设置的行数据值 + */ setItem(index: Number, item: GridItem | any): void; + /** + * 添加行数据 + * @param item 待添加的行数据值 + * @param index 待添加的行索引 + */ + addItem(item: GridItem | any, index?: Number): void; + /** + * 删除行数据 + * @param index 待删除的行索引 + */ + removeItem(index: Number): void; + /** + * 滚动到指定行的位置 + * @param index 待滚动至的行索引 + */ scrollToIndex(index: Number): void; - resize(force?: boolean): void; + /** + * 调整 Grid 元素的大小,一般需要在宽度变化时(如页面大小发生变化时)调用 + * @param force 是否强制reload,默认只有待渲染的行数发生变化时才会调用reload + * @param keep 是否保持当前滚动位置 + */ + resize(force?: boolean, keep?: boolean): void; + /** + * 重新计算需要渲染的行,并载入元素,一般需要在高度变化时调用 + * @param keep 是否保持当前滚动位置 + */ reload(keep?: boolean): void; + /** + * 重新填充Grid单元格数据 + */ refresh(): void; + /** + * 把所有行重置为未修改的状态 + */ resetChange(): void; + /** + * 根据当前排序字段进行列排序 + * @param reload 为 true 则在列排序后调用 reload 方法 + */ sortColumn(reload?: boolean): void; + /** + * 清除列头复选框的选中状态 + */ clearHeaderCheckbox(): void; } \ No newline at end of file diff --git a/lib/ui/grid/grid.js b/lib/ui/grid/grid.js index d80390a..b7e36a0 100644 --- a/lib/ui/grid/grid.js +++ b/lib/ui/grid/grid.js @@ -133,6 +133,14 @@ export class Grid { get element() { return this._var.el } + get changed() { + const source = this._var.source; + if (source == null) { + return false; + } + return source.filter(r => r.__changed).length > 0; + } + get source() { return this._var.source?.map(s => s.values) } set source(list) { if (this._var.el == null) { @@ -148,11 +156,32 @@ export class Grid { setItem(index, item) { if (this._var.source == null) { - return; + throw new Error('no source'); } const it = this._var.source[index]; delete it.source; it.values = item; + this.refresh(); + } + + addItem(item, index) { + if (this._var.source == null) { + throw new Error('no source'); + } + if (index >= 0) { + this._var.source.splice(index, 0, { values: item }); + } else { + this._var.source.push({ values: item }); + } + this.reload(); + } + + removeItem(index) { + if (this._var.source == null) { + throw new Error('no source'); + } + this._var.source.splice(index, 1); + this.reload(); } _refreshSource(list) { @@ -344,7 +373,7 @@ export class Grid { this._var.el.scrollTop = top; } - resize(force) { + resize(force, keep) { if (this._var.rendering || this._var.el == null) { return; } @@ -360,7 +389,7 @@ export class Grid { const count = truncate((height - 1) / (this.rowHeight + 1)) + (RedumCount * 2) + 1; if (force || count !== this._var.rowCount) { this._var.rowCount = count; - this.reload(true); + this.reload(keep); } this._var.bodyClientWidth = body.clientWidth; } @@ -760,11 +789,11 @@ export class Grid { } if (type.editing) { val = type.getValue({ target: cell.children[0] }, col); - this._onRowChanged(null, startIndex + i, col, val, cell, true); + this._onRowChanged(null, i, col, val, cell, true); } } element = selected ? - type.createEdit(e => this._onRowChanged(e, startIndex + i, col, type.getValue(e, col), cell), col, this._var.el, vals) : + type.createEdit(e => this._onRowChanged(e, i, col, type.getValue(e, col), cell), col, this._var.el, vals) : type.create(col); cell.replaceChildren(element); } else { @@ -1179,7 +1208,7 @@ export class Grid { const key = e.currentTarget.value.toLowerCase(); const items = key.length === 0 ? array : array.filter(i => { const displayValue = i?.DisplayValue ?? i; - return String(displayValue ?? '').includes(key); + return String(displayValue ?? '').toLowerCase().includes(key); }); this._fillFilterList(col, itemlist, items, itemall); }); @@ -1288,7 +1317,7 @@ export class Grid { } const content = list.querySelector('.filter-content'); content.replaceChildren(); - this._doFillFilterList(content, array, list.querySelector('.filter-all>input')); + this._doFillFilterList(content, array, list.querySelector('.filter-all')); content.style.top = `${top + rowHeight}px`; } } diff --git a/lib/ui/icon.js b/lib/ui/icon.js index a5d0eb0..a5298ff 100644 --- a/lib/ui/icon.js +++ b/lib/ui/icon.js @@ -2,7 +2,8 @@ const svgns = 'http://www.w3.org/2000/svg'; function createUse(type, id) { const c = typeof consts !== 'undefined' ? consts : {}; - const path = c.path || ''; + const netroot = typeof _network !== 'undefined' ? _network.root : ''; + const path = c.path || netroot; const ver = c.resver == null ? '' : `?${c.resver}`; const use = document.createElementNS(svgns, 'use'); use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', `${path}fonts/${type}.svg${ver}#${id}`); diff --git a/package-lock.json b/package-lock.json index c123eeb..2b2f8b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "postcss-preset-env": "^8.2.0", "sass": "^1.60.0", "typedoc": "^0.24.8", + "typedoc-theme-hierarchy": "^4.1.2", "vite": "^4.0.4", "vite-plugin-externals": "^0.6.2" } @@ -1592,9 +1593,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -1652,9 +1653,9 @@ } }, "node_modules/postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "version": "8.4.33", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", + "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", "dev": true, "funding": [ { @@ -1671,7 +1672,7 @@ } ], "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -2397,6 +2398,32 @@ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x" } }, + "node_modules/typedoc-theme-hierarchy": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/typedoc-theme-hierarchy/-/typedoc-theme-hierarchy-4.1.2.tgz", + "integrity": "sha512-X3H+zaDkg7wLNoaPJoqXs3rnMfZ9BZjmlXRwplWDciaPfn2hojHxJJ+yVKdqqmojgiHJgg7MYWGDVpOfNlOJ5A==", + "dev": true, + "dependencies": { + "fs-extra": "11.1.1" + }, + "peerDependencies": { + "typedoc": "^0.24.0 || ^0.25.0" + } + }, + "node_modules/typedoc-theme-hierarchy/node_modules/fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/typescript": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", @@ -2457,9 +2484,9 @@ "dev": true }, "node_modules/vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", + "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", "dev": true, "dependencies": { "esbuild": "^0.18.10", diff --git a/package.json b/package.json index 4ebd258..b2c8780 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "postcss-preset-env": "^8.2.0", "sass": "^1.60.0", "typedoc": "^0.24.8", + "typedoc-theme-hierarchy": "^4.1.2", "vite": "^4.0.4", "vite-plugin-externals": "^0.6.2" } diff --git a/readme/Grid 控件接口文档.docx b/readme/Grid 控件接口文档.docx index 9e3ad676ce2a9a2a6485d11c7e6288f0ca307a20..a54642520354e8cc1fce8ec4767c90b11dae04c7 100644 GIT binary patch delta 27863 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 delta 26335 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

y`why_c2*;6ji9@|+lkv35ZK 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 z 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 diff --git a/typedoc.json b/typedoc.json index cd926e9..094b740 100644 --- a/typedoc.json +++ b/typedoc.json @@ -1,17 +1,12 @@ { "entryPoints": [ - "lib/functions.d.ts", - "lib/ui/checkbox.d.ts", "lib/ui/dropdown.d.ts", - "lib/ui/icon.d.ts", - "lib/ui/popup.d.ts", - "lib/ui/tooltip.d.ts", "lib/ui/grid/column.d.ts", - "lib/ui/grid/grid.d.ts", - "lib/ui/media.d.ts" + "lib/ui/grid/grid.d.ts" ], "out": "./docs", "readme": "README.md", "name": "UI Library", + "disableSources": true, "cleanOutputDir": true } \ No newline at end of file diff --git a/vite.build.js b/vite.build.js index 3181c8c..906f2c1 100644 --- a/vite.build.js +++ b/vite.build.js @@ -23,70 +23,9 @@ const libraries = [ } }, sourcemap: true, - outDir: '../../../../IronIntel/Contractor2.0/Contractor/Site/js/lib', emptyOutDir: false } }, - { - clearScreen: false, - css: { - postcss: { - plugins: [postcssPresetEnv()] - } - }, - build: { - lib: { - entry: './lib/app.js', - name: 'lib-app', - formats: ['umd'], - fileName: (_format, name) => `${name}.min.js` - }, - rollupOptions: { - output: { - assetFileNames: info => info.name === 'style.css' ? 'app.min.css' : info.name - } - }, - sourcemap: true, - outDir: '../../../../IronIntel/Contractor2.0/Contractor/Site/js/lib', - emptyOutDir: false - }, - plugins: [ - viteExternalsPlugin({ - '../../ui': 'lib-ui', - '../../utility': 'lib-utility' - }) - ] - }, - { - clearScreen: false, - css: { - postcss: { - plugins: [postcssPresetEnv()] - } - }, - build: { - lib: { - entry: './lib/element.js', - name: 'lib-element', - formats: ['umd'], - fileName: (_format, name) => `${name}.min.js` - }, - rollupOptions: { - output: { - assetFileNames: info => info.name === 'style.css' ? 'element.min.css' : info.name - } - }, - sourcemap: true, - outDir: '../../../../IronIntel/Contractor2.0/Contractor/Site/js/lib', - emptyOutDir: false - }, - plugins: [ - viteExternalsPlugin({ - '../ui': 'lib-ui', - '../utility': 'lib-utility' - }) - ] - }, { clearScreen: false, build: {