diff --git a/angular.json b/angular.json index 824fc936..257c0bd9 100755 --- a/angular.json +++ b/angular.json @@ -18,7 +18,6 @@ "highlight.js", "codemirror", "xss", - "enquire.js", "color", "codesandbox" ], diff --git a/devui/anchor/anchor-box.directive.ts b/devui/anchor/anchor-box.directive.ts index 06cd03de..9ab14a49 100755 --- a/devui/anchor/anchor-box.directive.ts +++ b/devui/anchor/anchor-box.directive.ts @@ -1,5 +1,5 @@ -import { ContentChildren, Directive, Input, OnDestroy, OnInit, QueryList } from '@angular/core'; -import { Subject, Subscription} from 'rxjs'; +import { ContentChildren, Directive, Input, OnDestroy, QueryList } from '@angular/core'; +import { Subject, Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; import { AnchorDirective } from './anchor.directive'; import { AnchorActiveChangeSource, IAnchorBox } from './anchor.type'; diff --git a/devui/auto-complete/auto-complete-popup.component.html b/devui/auto-complete/auto-complete-popup.component.html index c23aa329..c35608da 100755 --- a/devui/auto-complete/auto-complete-popup.component.html +++ b/devui/auto-complete/auto-complete-popup.component.html @@ -19,7 +19,12 @@
+ +
+ +
+
diff --git a/devui/auto-complete/auto-complete-popup.component.scss b/devui/auto-complete/auto-complete-popup.component.scss index 072e0acc..b5460f35 100755 --- a/devui/auto-complete/auto-complete-popup.component.scss +++ b/devui/auto-complete/auto-complete-popup.component.scss @@ -3,6 +3,60 @@ .devui-dropdown-menu { width: 100%; display: block; + + &.devui-custom-right, + &.devui-custom-left, + &.devui-custom-top { + min-width: 400px; + display: flex !important; + + & > .devui-dropdown-menu-wrap { + display: inline-block; + } + + & > .devui-select-custom-area { + display: inline-block; + overflow: auto; + } + + &:not(.devui-custom-top) > .devui-dropdown-menu-wrap { + width: calc(50% - 1px); + } + + &:not(.devui-custom-top) > .devui-select-custom-area { + width: 50%; + } + + & > .devui-select-custom-area::before { + display: none; + } + } + + &.devui-custom-top { + flex-direction: column-reverse; + } + + &.devui-custom-left > .devui-select-custom-area { + border-right: 1px solid $devui-dividing-line; + order: -1; + } + + &.devui-custom-right > .devui-select-custom-area { + border-left: 1px solid $devui-dividing-line; + } + + &.devui-custom-top > .devui-select-custom-area { + border-bottom: 1px solid $devui-dividing-line; + } +} + +.devui-select-custom-area::before { + display: block; + content: ''; + width: calc(100% - 20px); + margin: 0 10px; + height: 1px; + border-top: 1px solid $devui-dividing-line; } .devui-dropdown-menu-cdk { diff --git a/devui/auto-complete/auto-complete-popup.component.ts b/devui/auto-complete/auto-complete-popup.component.ts index 8177b17d..4040f171 100755 --- a/devui/auto-complete/auto-complete-popup.component.ts +++ b/devui/auto-complete/auto-complete-popup.component.ts @@ -3,9 +3,9 @@ import { CdkOverlayOrigin, ConnectedOverlayPositionChange, ConnectedPosition, - VerticalConnectionPos + VerticalConnectionPos, } from '@angular/cdk/overlay'; -import { Component, ElementRef, Input, TemplateRef, ViewChild } from '@angular/core'; +import { Component, ElementRef, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core'; import { ControlValueAccessor } from '@angular/forms'; import { fadeInOut } from 'ng-devui/utils'; import { AutoCompleteConfig } from './auto-complete-config'; @@ -34,6 +34,8 @@ export class AutoCompletePopupComponent implements ControlValueAccessor { @Input() overview: string; @Input() itemTemplate: TemplateRef; @Input() noResultItemTemplate: TemplateRef; + @Input() customViewTemplate: TemplateRef; + @Input() customViewDirection: 'bottom' | 'right' | 'left' | 'top' = 'bottom'; @Input() searchingTemplate: TemplateRef; @Input() isSearching = false; @Input() formatter: (item: any) => string; @@ -44,6 +46,7 @@ export class AutoCompletePopupComponent implements ControlValueAccessor { @Input() cdkOverlayOffsetY = 0; @Input() origin: CdkOverlayOrigin | undefined; @Input() showAnimation = true; + @Output() hoverItem: EventEmitter = new EventEmitter(); @ViewChild('selectMenuElement') selectMenuElement: ElementRef; @ViewChild('dropdownUl') dropdownUl: ElementRef; @ViewChild(CdkConnectedOverlay) connectedOverlay: CdkConnectedOverlay; @@ -176,4 +179,8 @@ export class AutoCompletePopupComponent implements ControlValueAccessor { onPositionChange(position: ConnectedOverlayPositionChange) { this.popPosition = position.connectionPair.originY; } + + onMouseOver(event: MouseEvent, item: any) { + this.hoverItem.emit(item); + } } diff --git a/devui/auto-complete/auto-complete.directive.ts b/devui/auto-complete/auto-complete.directive.ts index 8a315da3..6f64e1d3 100755 --- a/devui/auto-complete/auto-complete.directive.ts +++ b/devui/auto-complete/auto-complete.directive.ts @@ -102,6 +102,8 @@ export class AutoCompleteDirective implements OnInit, OnDestroy, OnChanges, Cont */ @Input() enableLazyLoad = false; @Input() allowEmptyValueSearch = false; // 在value为空时,是否允许进行搜索 + @Input() customViewTemplate: TemplateRef; + @Input() customViewDirection: 'bottom' | 'right' | 'left' | 'top' = 'bottom'; @Output() loadMore = new EventEmitter(); @Output() selectValue = new EventEmitter(); @Output() transInputFocusEmit = new EventEmitter(); // input状态传给父组件函数 @@ -110,6 +112,7 @@ export class AutoCompleteDirective implements OnInit, OnDestroy, OnChanges, Cont */ @Output() changeDropDownStatus = new EventEmitter(); @Output() toggleChange = new EventEmitter(); + @Output() hoverItem: EventEmitter = new EventEmitter(); KEYBOARD_EVENT_NOT_REFRESH = ['escape', 'enter', 'arrowup', 'arrowdown', /* ie 10 edge */ 'esc', 'up', 'down']; popupRef: ComponentRef; @@ -136,9 +139,7 @@ export class AutoCompleteDirective implements OnInit, OnDestroy, OnChanges, Cont private changeDetectorRef: ChangeDetectorRef, private i18n: I18nService, private devConfigService: DevConfigService - ) { - - } + ) {} ngOnInit() { this.init(); @@ -150,6 +151,7 @@ export class AutoCompleteDirective implements OnInit, OnDestroy, OnChanges, Cont // 动态的创建了popup组件, const factory = this.componentFactoryResolver.resolveComponentFactory(AutoCompletePopupComponent); this.popupRef = this.viewContainerRef.createComponent(factory, this.viewContainerRef.length, this.injector); + this.popupRef.instance.hoverItem.subscribe((item) => this.hoverItem.emit(item)); this.fillPopup(this.source); if (!this.searchFn) { @@ -463,6 +465,8 @@ export class AutoCompleteDirective implements OnInit, OnDestroy, OnChanges, Cont 'position', 'overview', 'showAnimation', + 'customViewTemplate', + 'customViewDirection', ].forEach((key) => { if (this[key] !== undefined) { pop[key] = this[key]; diff --git a/devui/button/demo/danger/danger.component.html b/devui/button/demo/danger/danger.component.html index a562d718..637ba67d 100644 --- a/devui/button/demo/danger/danger.component.html +++ b/devui/button/demo/danger/danger.component.html @@ -1 +1 @@ -Buy +Delete diff --git a/devui/card/demo/card-demo.module.ts b/devui/card/demo/card-demo.module.ts index bbf5ae6d..9bdf100a 100644 --- a/devui/card/demo/card-demo.module.ts +++ b/devui/card/demo/card-demo.module.ts @@ -11,9 +11,9 @@ import { TranslateModule } from '@ngx-translate/core'; import { DDemoNavModule } from 'devui-commons/src/demo-nav/d-demo-nav.module'; import { BasicComponent } from './basic/basic.component'; import { CardDemoComponent } from './card-demo.component'; +import { CardInteractiveComponent } from './card-interactive/card-interactive.component'; import { CustomComponent } from './custom/custom.component'; import { WithMediaComponent } from './with-media/with-media.component'; -import { CardInteractiveComponent } from './card-interactive/card-interactive.component'; @NgModule({ declarations: [CardDemoComponent, BasicComponent, CustomComponent, WithMediaComponent, CardInteractiveComponent], diff --git a/devui/cascader/cascader-li.component.html b/devui/cascader/cascader-li.component.html index 2e340e2f..54a3bb3a 100644 --- a/devui/cascader/cascader-li.component.html +++ b/devui/cascader/cascader-li.component.html @@ -67,7 +67,7 @@ diff --git a/devui/cascader/cascader.component.ts b/devui/cascader/cascader.component.ts index bc51a9ae..f30caca1 100644 --- a/devui/cascader/cascader.component.ts +++ b/devui/cascader/cascader.component.ts @@ -119,6 +119,7 @@ export class CascaderComponent implements OnInit, OnDestroy, OnChanges, ControlV this.cascaderSrv.initOptions(this.options); this.cascaderSrv.isMultiple = this.multiple; this.cascaderSrv.isLazyLoad = this.isLazyLoad; + this.cascaderSrv.checkboxRelation = this.checkboxRelation; this.initObservale(); this.initI18n(); } @@ -247,6 +248,7 @@ export class CascaderComponent implements OnInit, OnDestroy, OnChanges, ControlV tagEvent.event.stopPropagation(); this.cascaderSrv.updateOptionCheckedStatus(option.value, false, this.checkboxRelation.upward, this.checkboxRelation.downward); this.multipleValueList = this.multipleValueList.filter(t => t.value !== option.value); + this.onChange(this.cascaderSrv.currentMultipleValue); // 当taglist变化导致input高度变化时,更新相对位置 setTimeout(() => { this.mainDropdown.updateCdkConnectedOverlayOrigin(); @@ -287,9 +289,11 @@ export class CascaderComponent implements OnInit, OnDestroy, OnChanges, ControlV const targetList = []; valueList.forEach(value => { let cur: CascaderItem; + let cacheTarget: CascaderItem; let list = this.cascaderSrv.options; for (let i = 0; i < value.length; i++) { cur = list.find(l => l.value === value[i]); + cacheTarget = cur; if (this.isLazyLoad && cur && !cur.children?.length && !cur.isLeaf) { this.cascaderSrv.lazyloadMultipleChild(cur, i); break; @@ -299,9 +303,16 @@ export class CascaderComponent implements OnInit, OnDestroy, OnChanges, ControlV } if (cur && cur.isLeaf) { targetList.push(cur); + cacheTarget = null; this.cascaderSrv.updateOptionCheckedStatus(cur.value, true, this.checkboxRelation.upward, this.checkboxRelation.downward); } + + if (cacheTarget) { + targetList.push(cacheTarget); + this.cascaderSrv.updateOptionCheckedStatus(cacheTarget.value, true, this.checkboxRelation.upward, this.checkboxRelation.downward); + } }); + return targetList; } @@ -309,7 +320,7 @@ export class CascaderComponent implements OnInit, OnDestroy, OnChanges, ControlV getLabelFromValue(value: Array): string { let cur; let list = this.cascaderSrv.options; - value.map(item => { + value.forEach(item => { cur = list.find(t => t.value === item) || ''; list = cur.children || []; }); @@ -323,7 +334,7 @@ export class CascaderComponent implements OnInit, OnDestroy, OnChanges, ControlV let cur; let list = this.cascaderSrv.options; - value.map((item, index) => { + value.forEach((item, index) => { cur = list.find(t => t.value === item) || ''; if (cur) { path = path === '' ? path + cur.label : path + ' / ' + cur.label; @@ -385,7 +396,7 @@ export class CascaderComponent implements OnInit, OnDestroy, OnChanges, ControlV const width = this.dropdownComp.overlay.overlayRef?.overlayElement.clientWidth; const offsetX = this.dropdownComp.overlay.overlayRef?.overlayElement.offsetLeft; const offsetRight = window.innerWidth - width - offsetX - 20; - this.subMenuDirections.map(t => {t.offsetX = offsetRight < 0 ? offsetRight : 0;}); + this.subMenuDirections.forEach(t => {t.offsetX = offsetRight < 0 ? offsetRight : 0;}); this.dropdownComp.reposition(); }, 0); } diff --git a/devui/cascader/cascader.service.ts b/devui/cascader/cascader.service.ts index 93fd4049..8523bc36 100644 --- a/devui/cascader/cascader.service.ts +++ b/devui/cascader/cascader.service.ts @@ -21,6 +21,7 @@ export class CascaderService implements OnDestroy { isLazyLoad = false; lazyloadCache = {}; + checkboxRelation = { upward: true, downward: true }; loadChildrenFn: (value: CascaderItem) => Promise | Observable; @@ -274,16 +275,22 @@ export class CascaderService implements OnDestroy { } getMultipleValue(value, option: CascaderItem[]): void { + const isNoRelation = !this.checkboxRelation.downward || !this.checkboxRelation.upward; option.forEach(item => { const _value = [...value]; + _value.push(item.value); if (item.children && item.children.length && (item.checked || item.halfChecked)) { - _value.push(item.value); this.getMultipleValue(_value, item.children); + if (isNoRelation) { + this.multipleValue.push(_value); + } } else if (item.checked) { - _value.push(item.value); this.multipleValue.push(_value); + } else if (isNoRelation && item.children?.length) { + this.getMultipleValue(_value, item.children); } }); + } closeAllDropdown(): void { diff --git a/devui/cascader/demo/parent-select-cascader/parent-select-cascader.component.ts b/devui/cascader/demo/parent-select-cascader/parent-select-cascader.component.ts index 5d78e946..b133693b 100644 --- a/devui/cascader/demo/parent-select-cascader/parent-select-cascader.component.ts +++ b/devui/cascader/demo/parent-select-cascader/parent-select-cascader.component.ts @@ -106,7 +106,7 @@ export class ParentSelectCascaderComponent { ]; value1: Array[] = []; - value2: Array[] = [[1, 4, 8], [1, 4, 9, 81], [1, 41]]; + value2: Array[] = [ [1], [2], [1, 4]]; value3: Array[] = [[1, 4, 8], [1, 4, 9, 81], [1, 41]]; value4: Array[] = [[1, 4, 8], [1, 4, 9, 81], [1, 41]]; diff --git a/devui/category-search/category-search.component.html b/devui/category-search/category-search.component.html index 01fc7184..f10d08af 100644 --- a/devui/category-search/category-search.component.html +++ b/devui/category-search/category-search.component.html @@ -335,8 +335,7 @@ #dDatepickerPro [isRangeType]="true" [showTime]="tagOption.showTime" - [ngModel]="tagOption.value.value" - (ngModelChange)="dateValueChange(tagOption, dDatepickerPro)" + [(ngModel)]="tagOption.value.value" > -
- - +
+
-
+
-
{{ i18nCommonText?.noRecordsFound }}
+
{{ i18nCommonText?.noRecordsFound }}
- {{ i18nCategorySearchText?.confirm }} + {{ i18nCategorySearchText?.confirm }} {{ i18nCategorySearchText?.cancel }}
diff --git a/devui/category-search/category-search.component.scss b/devui/category-search/category-search.component.scss index 9b64f3d6..e1761e91 100644 --- a/devui/category-search/category-search.component.scss +++ b/devui/category-search/category-search.component.scss @@ -398,11 +398,18 @@ d-tag { } } + .devui-search-container { + max-width: 232px; + } + .devui-category-search-tree-container { overflow-y: auto; - max-height: 270px; - margin-bottom: -8px; - padding: 4px 0 4px 8px; + max-height: 264px; + padding: 12px; + } + + .devui-no-data-tip { + padding: 12px; } .devui-yearOption, diff --git a/devui/category-search/category-search.component.ts b/devui/category-search/category-search.component.ts index 82562e76..d9756236 100644 --- a/devui/category-search/category-search.component.ts +++ b/devui/category-search/category-search.component.ts @@ -18,7 +18,6 @@ import { ViewChildren } from '@angular/core'; import { NgForm } from '@angular/forms'; -import { DatepickerProCalendarComponent } from 'ng-devui/datepicker-pro'; import { DropDownDirective } from 'ng-devui/dropdown'; import { DValidateRules } from 'ng-devui/form'; import { I18nInterface, I18nService } from 'ng-devui/i18n'; @@ -48,9 +47,9 @@ import { DefaultTemplateDirective } from './default-template.directive'; }) export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewInit, AfterContentInit { static ID_SEED = 0; - @Input() category: Array; + @Input() category: ICategorySearchTagItem[]; @Input() defaultSearchField = []; - @Input() selectedTags: Array = []; + @Input() selectedTags: ICategorySearchTagItem[] = []; @Input() allowClear = true; @Input() allowSave = true; @Input() allowShowMore = false; @@ -60,7 +59,7 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI @Input() inputReadOnly = false; @Input() showSearchCategory: SearchConfig | boolean = true; // 配置是否显示搜索相关下拉选项 @Input() categoryInGroup = false; // 是否按组别显示分类下拉列表 - @Input() groupOrderConfig: Array; // 用户配置组顺序 + @Input() groupOrderConfig: string[]; // 用户配置组顺序 @Input() customGroupNameTemplate: TemplateRef; // 用户自定义组名称显示模板 @Input() tagMaxWidth: number; @Input() textConfig = { @@ -79,31 +78,33 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI @ViewChild('InputEle', { static: true }) inputEle: ElementRef; @ViewChild('ScrollBarContainer', { static: true }) scrollBarContainer: ElementRef; @ViewChild('PrimeContainer', { static: true }) primeContainer: ElementRef; + @ViewChild('OperableTree') treeInstance: OperableTreeComponent; @ViewChildren('selectedDropdown') selectedDropdownList: QueryList; - @ViewChildren(DatepickerProCalendarComponent, { read: ElementRef }) datePickerElements: QueryList; @ViewChildren(DefaultTemplateDirective) defaultTemplates: QueryList; @ContentChildren(ContentTemplateDirective) contentTemplates: QueryList; - public currentSelectTag = undefined; - public currentTag: ICategorySearchTagItem; - public searchField; - public id: number; + + id: number; + searchField: ICategorySearchTagItem[]; + categoryDisplay: ICategorySearchTagItem[]; + currentSearchCategory: ICategorySearchTagItem[]; + currentSelectTag: ICategorySearchTagItem; dateConverter: DateConverter; - filterName = ''; + treeResetFlag: boolean; treeSearchKey = ''; + filterName = ''; searchKeyCache = ''; enterSearch = false; isShowSavePanel = false; isSearchCategory = false; isHover = false; isFocus = false; - noRecord = false; + treeNoRecord = false; showNoDataTips = false; icons = DefaultIcons; destroy$ = new Subject(); i18nCommonText: I18nInterface['common']; i18nCategorySearchText: I18nInterface['categorySearch']; - currentSearchCategory: Array; - categoryDisplay: Array; + showSearchConfig: SearchConfig; currentOpenDropdown: DropDownDirective; currentScrollTagIndex: number; // 当前要滚动至的标签索引 blurTimer: any; // 失焦关闭下拉延时器,失焦后立刻展开下拉需清除该延时 @@ -115,7 +116,6 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI customTemplates = {}; // 按field标记的自定义模板集合 joinLabelTypes = ['checkbox', 'label']; valueIsArrayTypes = ['numberRange', 'treeSelect']; - showSearchConfig: SearchConfig; document: Document; get showFilterNameClear() { @@ -334,6 +334,9 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI result = this.joinLabelTypes.includes(item.type) ? this.getItemValue(item.value.value, item.filterKey || 'label') : ''; } item.title = this.setTitle(item, item.type, result); + if (item.type === 'label' && item.options[0] && !item.options[0].$label) { + this.mergeToLabel(item); + } } else { item = this.initCategoryItem(item); } @@ -487,7 +490,7 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI field.title = this.setTitle(field, 'radio', value); } if (field.type === 'label') { - if (!field.options[0]?.$label) { + if (field.options[0] && !field.options[0].$label) { this.mergeToLabel(field); } result[colorKey] = COLORS[Math.floor(COLORS.length * Math.random())]; @@ -579,8 +582,10 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI this.closeMenu(inputDropdown); return; } - const tag = this.selectedTags[this.selectedTags.length - 1]; - this.removeTag(tag); + if (this.selectedTags.length) { + const tag = this.selectedTags[this.selectedTags.length - 1]; + this.removeTag(tag); + } this.closeMenu(inputDropdown); } @@ -682,7 +687,6 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI } /* 各类型模板调用方法 */ - // radio 单选 处理选中项方法 chooseItem(tag: ICategorySearchTagItem, chooseItem: ITagOption) { this.afterDropdownClosed(); @@ -705,21 +709,6 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI this.updateSelectedTags(tag); } - dateValueChange(tag: ICategorySearchTagItem, datepickerPro: DatepickerProCalendarComponent) { - if (datepickerPro.dateValue.length) { - if (tag.value.value && !datepickerPro.dateValue.includes('')) { - const date = datepickerPro.curActiveDate; - const index = datepickerPro.currentActiveInput === 'start' ? 0 : 1; - const value = tag.value.value[index]; - tag.value.value = value ? [value, date] : [date, value]; - } else { - tag.value.value = [datepickerPro.curActiveDate]; - } - } else { - tag.value.value = []; - } - } - // checkbox | label 多选 处理选中项方法 chooseItems(tag: ICategorySearchTagItem) { this.afterDropdownClosed(); @@ -763,10 +752,19 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI this.clearCurrentSelectTagFromSearch(); this.currentOpenDropdown = undefined; this.showNoDataTips = false; + if (tag.type === 'treeSelect') { + setTimeout(() => { + this.treeSearch(''); + this.treeResetFlag = false; + }, this.DELAY); + } return; } if (tag) { this.scrollToTailFlag = false; + if (tag.type === 'treeSelect') { + this.treeResetFlag = true; + } if (!isEqual(tag.value.value, tag.value.cache)) { tag.value.value = cloneDeep(tag.value.cache); this.handleAccordingType(tag.type, tag.value.options); @@ -781,7 +779,7 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI showCurrentSearchCategory(tag: ICategorySearchTagItem, inputDropdown: DropDownDirective) { this.isSearchCategory = true; - this.clearSearchKey(); + this.searchKey = ''; this.closeMenu(inputDropdown); this.chooseCategory(tag, inputDropdown); setTimeout(() => this.checkInputSearching(), this.DELAY); @@ -796,7 +794,7 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI } } - handleAccordingType(type: string, options: Array) { + handleAccordingType(type: string, options: any[]) { switch (type) { case 'treeSelect': options = cloneDeep(options); @@ -855,7 +853,7 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI } // treeSelect 树 处理选中项方法 - getTreeValue(tag: ICategorySearchTagItem, tree: OperableTreeComponent) { + getTreeValue(tag: ICategorySearchTagItem) { this.afterDropdownClosed(); const result = []; const selectedIds = []; @@ -871,7 +869,7 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI tag.title = this.setTitle(tag, 'treeSelect'); if (tag.multiple) { const halfCheckedIds = []; - tree.nodes.forEach((item) => item.data.halfChecked && halfCheckedIds.push(item.id)); + this.treeInstance.nodes.forEach((item) => item.data.halfChecked && halfCheckedIds.push(item.id)); this.updateTreeData(tag, tag.value.options, selectedIds, halfCheckedIds); } this.updateSelectedTags(tag); @@ -903,23 +901,28 @@ export class CategorySearchComponent implements OnChanges, OnDestroy, AfterViewI } } - onOperableNodeSelected(selectedNode: ITreeItem, tag: ICategorySearchTagItem, tree: OperableTreeComponent) { + onOperableNodeSelected(selectedNode: ITreeItem, tag: ICategorySearchTagItem) { if (tag.multiple || (tag.leafOnly && selectedNode.data.isParent)) { return; } if (selectedNode.data.isActive) { tag.value.value = [selectedNode.data.originItem]; - this.getTreeValue(tag, tree); + this.getTreeValue(tag); } else { selectedNode.data.isActive = true; } } - treeSearch(tree: OperableTreeComponent, value: string) { - tree.operableTree.treeFactory.searchTree(value, true); - } - - clearSearchKey() { - this.searchKey = ''; + treeSearch(value: string) { + this.treeSearchKey = value; + if (this.treeInstance) { + const searchRes = this.treeInstance.treeFactory.searchTree(this.treeSearchKey, true); + if (typeof searchRes === 'boolean') { + this.treeNoRecord = searchRes; + } else if (Array.isArray(searchRes)) { + this.treeNoRecord = searchRes.every((res) => !res); + } + this.treeInstance.treeFactory.getFlattenNodes(); + } } } diff --git a/devui/category-search/category-search.type.ts b/devui/category-search/category-search.type.ts index 152158e9..bbf97043 100644 --- a/devui/category-search/category-search.type.ts +++ b/devui/category-search/category-search.type.ts @@ -52,8 +52,8 @@ export interface ICategorySearchTagItem { */ value?: { label?: string; - value?: string | ITagOption | Array; - cache?: string | ITagOption | Array; + value?: string | ITagOption | Array; + cache?: string | ITagOption | Array; [propName: string]: any; }; [propName: string]: any; diff --git a/devui/category-search/demo/demo-data.ts b/devui/category-search/demo/demo-data.ts index 18817c51..c3701b94 100644 --- a/devui/category-search/demo/demo-data.ts +++ b/devui/category-search/demo/demo-data.ts @@ -180,6 +180,8 @@ export const demoData: ICategorySearchTagItem[] = [ field: 'module', type: 'treeSelect', group: 'User-defined', + searchable: true, + searchPlaceholder: 'Search Input', options: [ { title: 'parent 1', diff --git a/devui/category-search/doc/api-cn.md b/devui/category-search/doc/api-cn.md index 2facc7c6..aa795582 100644 --- a/devui/category-search/doc/api-cn.md +++ b/devui/category-search/doc/api-cn.md @@ -89,8 +89,8 @@ export interface ICategorySearchTagItem { */ value?: { label: string; // 用于显示选中值,如果指定了 filterKey 则使用该值为属性名,例如 basic demo 中的状态 - value: string | ITagOption | Array; // 下拉列表的选择值 - cache: string | ITagOption | Array; // 下拉列表展开时用于重置选择值的缓存数据 + value: string | ITagOption | Array; // 下拉列表的选择值 + cache: string | ITagOption | Array; // 下拉列表展开时用于重置选择值的缓存数据 }; /** * dateRange 类型是否显示时分秒 diff --git a/devui/category-search/doc/api-en.md b/devui/category-search/doc/api-en.md index 57cd8ca3..7864de96 100644 --- a/devui/category-search/doc/api-en.md +++ b/devui/category-search/doc/api-en.md @@ -88,8 +88,8 @@ export interface ICategorySearchTagItem { */ value?: { label: string; // Used to display the selected value, or the property name if filterKey is specified, such as the status in basic demo. - value: string | ITagOption | Array; // Selected value from the drop-down list box - cache: string | ITagOption | Array; // Cached data used to reset the selection value when the drop-down list expands + value: string | ITagOption | Array; // Selected value from the drop-down list box + cache: string | ITagOption | Array; // Cached data used to reset the selection value when the drop-down list expands }; /** * Indicates whether to display hour, minute, and second for the dateRange type. diff --git a/devui/common/safe-null.pipe.ts b/devui/common/safe-null.pipe.ts index e94ca5ed..ec795699 100644 --- a/devui/common/safe-null.pipe.ts +++ b/devui/common/safe-null.pipe.ts @@ -4,7 +4,7 @@ import { Pipe, PipeTransform } from '@angular/core'; name: 'dSafeNullPipe', }) export class SafeNullPipe implements PipeTransform { - transform(value: unknown, replace: string = '--'): unknown { + transform(value: unknown, replace = '--'): unknown { if (typeof value === 'undefined' || value === null || value === '') { return replace; } diff --git a/devui/data-table/data-table-body.component.html b/devui/data-table/data-table-body.component.html index 33bb4f7f..56447fa9 100755 --- a/devui/data-table/data-table-body.component.html +++ b/devui/data-table/data-table-body.component.html @@ -93,7 +93,7 @@ - + { - if (event === 'cancel' || (!this.cellRef.nativeElement.contains(event.target) && !this.clickInTd)) { + const containTarget = !this.cellRef.nativeElement.contains(event.target) && !this.clickInTd; + const flag = this.dt.beforeCellEditEnd && containTarget ? this.dt.beforeCellEditEnd(this.rowItem, this.column) : true; + if ((event === 'cancel' || containTarget) && flag) { this.ngZone.run(() => { this.finishCellEdit(); }); @@ -299,7 +301,9 @@ export class DataTableCellComponent implements OnInit, OnChanges, OnDestroy { ); this.cellEditorClickSubscription = this.dt.cellEditorClickEvent.subscribe( event => { - if (!this.cellRef.nativeElement.contains(event.target)) { + const containTarget = this.cellRef.nativeElement.contains(event.target); + const flag = (this.dt.beforeCellEditEnd && !containTarget) ? this.dt.beforeCellEditEnd(this.rowItem, this.column) : true; + if (!containTarget && flag) { this.finishCellEdit(); } } diff --git a/devui/data-table/data-table-row.component.html b/devui/data-table/data-table-row.component.html index 14925f84..77ed76ae 100755 --- a/devui/data-table/data-table-row.component.html +++ b/devui/data-table/data-table-row.component.html @@ -1,8 +1,7 @@ diff --git a/devui/data-table/data-table-row.component.scss b/devui/data-table/data-table-row.component.scss index da678b7a..31c114f4 100755 --- a/devui/data-table/data-table-row.component.scss +++ b/devui/data-table/data-table-row.component.scss @@ -83,3 +83,12 @@ svg.svg-icon-arrow > g > polygon { background: $devui-list-item-hover-bg; } } + +.expand-icon-wrapper { + display: flex; + justify-content: left; + + polygon { + fill: $devui-icon-fill; + } +} diff --git a/devui/data-table/data-table.component.html b/devui/data-table/data-table.component.html index a80a92fa..d3fb3dac 100755 --- a/devui/data-table/data-table.component.html +++ b/devui/data-table/data-table.component.html @@ -1,5 +1,12 @@
-
+
tr > td { + padding: 0; + padding-left: 18px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: $devui-font-size-sm; + } + + thead > tr > th.devui-checkable-cell { + padding: 0; + padding-left: 18px; + } + + thead tr th .title { + line-height: 24px; + font-size: $devui-font-size-sm; + } + + thead tr th .header-container { + padding-left: 0; + } + } } .devui-table.table-striped ::ng-deep { @@ -717,6 +744,12 @@ $devui-table-inset-shadow-right: var(--devui-table-inset-shadow-right, -8px 0 8p } } } + + tr.table-row-selected { + .devui-last-sticky-left-cell { + background: linear-gradient(to left, transparent, $devui-list-item-selected-bg 10px); + } + } } :host ::ng-deep .devui-talbe-scorll-middle, @@ -738,6 +771,12 @@ $devui-table-inset-shadow-right: var(--devui-table-inset-shadow-right, -8px 0 8p } } } + + tr.table-row-selected { + .devui-first-sticky-right-cell { + background: linear-gradient(to right, transparent, $devui-list-item-selected-bg 10px); + } + } } :host ::ng-deep .gu-unselectable { diff --git a/devui/data-table/data-table.component.ts b/devui/data-table/data-table.component.ts index 2fb3d4e0..d8465a4d 100755 --- a/devui/data-table/data-table.component.ts +++ b/devui/data-table/data-table.component.ts @@ -189,6 +189,10 @@ export class DataTableComponent implements OnDestroy, OnInit, OnChanges, AfterCo * 表格单元格开始编辑前的拦截事件 */ @Input() beforeCellEdit: (rowItem: any, column: any) => Promise; + /** + * 表格单元格开始编辑后的拦截事件 + */ + @Input() beforeCellEditEnd: (rowItem: any, column: any) => boolean; /** * 表格单元格开始编辑事件 */ @@ -291,7 +295,7 @@ export class DataTableComponent implements OnDestroy, OnInit, OnChanges, AfterCo /** * 表格尺寸,sm对应行高40px, md对应行高48px,lg对应行高56px */ - @Input() size: 'xs' | 'sm' | 'md' | 'lg' = 'sm'; + @Input() size: 'mini' | 'xs' | 'sm' | 'md' | 'lg' = 'sm'; @Input() shadowType: 'normal' | 'embed' = 'embed'; diff --git a/devui/data-table/data-table.module.ts b/devui/data-table/data-table.module.ts index f2db100f..15fdb4b0 100755 --- a/devui/data-table/data-table.module.ts +++ b/devui/data-table/data-table.module.ts @@ -8,11 +8,13 @@ import { DCommonModule } from 'ng-devui/common'; import { DatepickerModule } from 'ng-devui/datepicker'; import { DragDropModule } from 'ng-devui/dragdrop'; import { DropDownModule } from 'ng-devui/dropdown'; -import { InputNumberComponent, InputNumberModule } from 'ng-devui/input-number'; +import { InputNumberModule } from 'ng-devui/input-number'; import { PaginationModule } from 'ng-devui/pagination'; -import { SelectComponent, SelectModule } from 'ng-devui/select'; +import { SearchModule } from 'ng-devui/search'; +import { SelectModule } from 'ng-devui/select'; +import { ToggleModule } from 'ng-devui/toggle'; import { TooltipModule } from 'ng-devui/tooltip'; -import { TreeSelectComponent, TreeSelectModule } from 'ng-devui/tree-select'; +import { TreeSelectModule } from 'ng-devui/tree-select'; import { LazyLoadModule, SafePipeModule } from 'ng-devui/utils'; import { WindowRefModule } from 'ng-devui/window-ref'; import { DataTableBodyComponent } from './data-table-body.component'; @@ -22,6 +24,8 @@ import { DataTableRowComponent } from './data-table-row.component'; import { DataTableComponent } from './data-table.component'; import { DisPlayCellValuePipe } from './display-cell-value.pipe'; import { EditorDirective } from './editor-host.directive'; +import { TableOptionModalComponent } from './table-option-modal.component'; +import { TableOptionToggleComponent } from './table-option-toggle.component'; import { TableTbodyComponent } from './table/body/tbody.component'; import { TableTdComponent } from './table/body/td/td.component'; import { TableTdService } from './table/body/td/td.service'; @@ -55,7 +59,9 @@ import { DataTableHeadCellTmplComponent } from './tmpl/data-table-head-cell-tmpl SafePipeModule, TooltipModule, DragDropModule, - LazyLoadModule + LazyLoadModule, + ToggleModule, + SearchModule ], exports: [ DataTableComponent, @@ -74,7 +80,9 @@ import { DataTableHeadCellTmplComponent } from './tmpl/data-table-head-cell-tmpl TableTheadComponent, TableTrComponent, TableTbodyComponent, - TableTdComponent + TableTdComponent, + TableOptionToggleComponent, + TableOptionModalComponent ], declarations: [ DataTableComponent, @@ -95,7 +103,9 @@ import { DataTableHeadCellTmplComponent } from './tmpl/data-table-head-cell-tmpl TableTheadComponent, TableTrComponent, TableTbodyComponent, - TableTdComponent + TableTdComponent, + TableOptionToggleComponent, + TableOptionModalComponent ], providers: [ TableTdService ], diff --git a/devui/data-table/demo/basic/data-table-demo-basic.component.html b/devui/data-table/demo/basic/data-table-demo-basic.component.html index 027ed9c2..3aac22de 100755 --- a/devui/data-table/demo/basic/data-table-demo-basic.component.html +++ b/devui/data-table/demo/basic/data-table-demo-basic.component.html @@ -9,7 +9,7 @@
- diff --git a/devui/data-table/demo/data-table-demo.component.html b/devui/data-table/demo/data-table-demo.component.html index f3f61812..a0319f58 100755 --- a/devui/data-table/demo/data-table-demo.component.html +++ b/devui/data-table/demo/data-table-demo.component.html @@ -24,6 +24,12 @@ +
+
{{ 'components.datatable.dynamicColDemo.title' | translate }}
+ + + +
{{ 'components.datatable.asyncDemo.title' | translate }}
{{ 'components.datatable.asyncDemo.description' | translate }}
diff --git a/devui/data-table/demo/data-table-demo.component.ts b/devui/data-table/demo/data-table-demo.component.ts index be0c60f2..9208e48b 100755 --- a/devui/data-table/demo/data-table-demo.component.ts +++ b/devui/data-table/demo/data-table-demo.component.ts @@ -20,13 +20,11 @@ export class DataTableDemoComponent implements OnInit, OnDestroy { interactionColumnSource: Array = [ { title: 'HTML', language: 'xml', code: require('./interaction-column/interaction-column.component.html?raw') }, { title: 'TS', language: 'typescript', code: require('./interaction-column/interaction-column.component.ts?raw') }, - { title: 'SCSS', language: 'css', code: require('./interaction-column/interaction-column.component.scss?raw') }, { title: 'mock-data', language: 'typescript', code: require('./mock-data?raw') }, ]; interactionSource: Array = [ { title: 'HTML', language: 'xml', code: require('./interaction/interaction.component.html?raw') }, { title: 'TS', language: 'typescript', code: require('./interaction/interaction.component.ts?raw') }, - { title: 'SCSS', language: 'css', code: require('./interaction/interaction.component.scss?raw') }, { title: 'mock-data', language: 'typescript', code: require('./mock-data?raw') }, ]; checkOptionSource: Array = [ @@ -132,7 +130,11 @@ export class DataTableDemoComponent implements OnInit, OnDestroy { mutilStyles: Array = [ { title: 'HTML', language: 'xml', code: require('./mutil-styles/mutil-styles.component.html?raw') }, { title: 'TS', language: 'typescript', code: require('./mutil-styles/mutil-styles.component.ts?raw') }, - { title: 'SCSS', language: 'css', code: require('./mutil-styles/mutil-styles.component.scss?raw') }, + { title: 'mock-data', language: 'typescript', code: require('./mock-data?raw') }, + ]; + dynamicColStyles: Array = [ + { title: 'HTML', language: 'xml', code: require('./dynamic-cols/dynamic-cols-demo.component.html?raw') }, + { title: 'TS', language: 'typescript', code: require('./dynamic-cols/dynamic-cols-demo.component.ts?raw') }, { title: 'mock-data', language: 'typescript', code: require('./mock-data?raw') }, ]; fixHeightVirtualScrollSource: Array = [ @@ -168,6 +170,7 @@ export class DataTableDemoComponent implements OnInit, OnDestroy { this.navItems = [ { dAnchorLink: 'basic-usage', value: values['basic-usage'] }, { dAnchorLink: 'mutil-styles', value: values['mutil-styles'] }, + { dAnchorLink: 'dynamic-cols', value: values['dynamic-cols'] }, { dAnchorLink: 'async-loading', value: values['async-loading'] }, { dAnchorLink: 'table-interaction', value: values['table-interaction'] }, { dAnchorLink: 'table-check-options', value: values['table-check-options'] }, diff --git a/devui/data-table/demo/data-table-demo.module.ts b/devui/data-table/demo/data-table-demo.module.ts index 080595d8..ff3dc0a9 100755 --- a/devui/data-table/demo/data-table-demo.module.ts +++ b/devui/data-table/demo/data-table-demo.module.ts @@ -24,6 +24,7 @@ import { CheckOptionsComponent } from './check-options/check-options.component'; import { DataTableDemoComponent } from './data-table-demo.component'; import { DragColumnComponent } from './drag-column/drag-column.component'; import { DragRowComponent } from './drag-row/drag-row.component'; +import { DynamicColsDemoComponent } from './dynamic-cols/dynamic-cols-demo.component'; import { EditableOldComponent } from './editable-old/editable-old.component'; import { DatatableDemoEditableComponent } from './editable/data-table-demo-editable.component'; import { ExpandRowOldComponent } from './expand-row-old/expand-row-old.component'; @@ -95,7 +96,8 @@ import { VirtualScrollComponent } from './virtual-scroll/virtual-scroll.componen InteractionColumnComponent, VirtualScrollComponent, MutilStylesComponent, - FixHeightVirtualScrollComponent + FixHeightVirtualScrollComponent, + DynamicColsDemoComponent, ], providers: [], }) diff --git a/devui/data-table/demo/dynamic-cols/dynamic-cols-demo.component.html b/devui/data-table/demo/dynamic-cols/dynamic-cols-demo.component.html new file mode 100644 index 00000000..4477e0b9 --- /dev/null +++ b/devui/data-table/demo/dynamic-cols/dynamic-cols-demo.component.html @@ -0,0 +1,52 @@ +

+ 下拉模式,数据变更在每次操作都会触发,列数较少时推荐使用: + + + +

+ +

+ 弹窗编辑模式,数据变更在点击确定时触发,建议列数多余10列时使用时: + + 弹窗配置 + +

+ +
+ + + + + + + + + + + + diff --git a/devui/data-table/demo/dynamic-cols/dynamic-cols-demo.component.ts b/devui/data-table/demo/dynamic-cols/dynamic-cols-demo.component.ts new file mode 100644 index 00000000..20b11022 --- /dev/null +++ b/devui/data-table/demo/dynamic-cols/dynamic-cols-demo.component.ts @@ -0,0 +1,139 @@ +import { Component, OnInit } from '@angular/core'; +import { TableWidthConfig, TableStyleData } from 'ng-devui/data-table'; +import { originSource, SourceType } from '../mock-data'; + +@Component({ + selector: 'd-dynamic-cols-demo', + templateUrl: './dynamic-cols-demo.component.html' +}) +export class DynamicColsDemoComponent implements OnInit { + basicDataSource: Array = JSON.parse(JSON.stringify(originSource.slice(0, 6))); + allColumns = [ + { + field: 'id', + header: 'id', + fieldType: 'text', + width: '50px', + checked: true + }, + { + field: 'firstName', + header: 'First Name', + fieldType: 'text', + width: '150px', + checked: true + }, + { + field: 'lastName', + header: 'Last Name', + fieldType: 'text', + width: '150px', + checked: true + }, + { + field: 'gender', + header: 'Gender', + fieldType: 'text', + width: '150px', + checked: true + }, + { + field: 'dob', + header: 'Date of birth', + fieldType: 'date', + width: '150px', + checked: true + }, + { + field: 'description', + header: 'description', + fieldType: 'text', + width: '150px', + checked: true + }, + ]; + dataTableOptions: any = { + columns: [ + { + field: 'id', + header: 'id', + fieldType: 'text' + }, + { + field: 'firstName', + header: 'First Name', + fieldType: 'text' + }, + { + field: 'lastName', + header: 'Last Name', + fieldType: 'text' + }, + { + field: 'gender', + header: 'Gender', + fieldType: 'text' + }, + { + field: 'dob', + header: 'Date of birth', + fieldType: 'date' + }, + { + field: 'description', + header: 'description', + fieldType: 'text' + }, + ] + }; + + tableWidthConfig: TableWidthConfig[] = [ + { + field: 'id', + width: '50px' + }, + { + field: 'firstName', + width: '150px' + }, + { + field: 'lastName', + width: '150px' + }, + { + field: 'gender', + width: '150px' + }, + { + field: 'dob', + width: '150px' + }, + { + field: 'description', + width: '150px' + } + ]; + + + styleSetting: TableStyleData = { + size: 'sm', + borderType: '', + striped: false, + shadowType: 'embed' + }; + + ngOnInit() { + console.log(this.basicDataSource); + } + + onColsChanges(e) { + this.allColumns = e; + this.tableWidthConfig = []; + this.dataTableOptions.columns = this.allColumns.filter(t => t.checked); + this.tableWidthConfig = this.dataTableOptions.columns; + } + + onStyleChanges(e) { + this.styleSetting = e; + } +} diff --git a/devui/data-table/demo/editable-old/editable-old.component.html b/devui/data-table/demo/editable-old/editable-old.component.html index 7330fdb3..07971ef4 100644 --- a/devui/data-table/demo/editable-old/editable-old.component.html +++ b/devui/data-table/demo/editable-old/editable-old.component.html @@ -2,6 +2,7 @@ #dataTable [dataSource]="basicDataSource" [beforeCellEdit]="beforeCellEdit" + [beforeCellEditEnd]="beforeCellEditEnd" (cellEditEnd)="thisCellEditEnd($event)" [scrollable]="true" [tableOverflowType]="'overlay'" diff --git a/devui/data-table/demo/editable-old/editable-old.component.ts b/devui/data-table/demo/editable-old/editable-old.component.ts index 0300401b..9d58a965 100644 --- a/devui/data-table/demo/editable-old/editable-old.component.ts +++ b/devui/data-table/demo/editable-old/editable-old.component.ts @@ -33,6 +33,14 @@ export class EditableOldComponent implements OnInit { }); }; + beforeCellEditEnd = (rowItem, column) => { + console.log('before edit end:', rowItem, column); + if (column.field === "lastName" && rowItem[column.field].length < 3) { + return false; + } + return true; + }; + finishEdit() { this.dataTable.cancelEditingStatus(); } diff --git a/devui/data-table/demo/expand-row-old/expand-row-old.component.html b/devui/data-table/demo/expand-row-old/expand-row-old.component.html index d25f95ba..30d00d8c 100644 --- a/devui/data-table/demo/expand-row-old/expand-row-old.component.html +++ b/devui/data-table/demo/expand-row-old/expand-row-old.component.html @@ -24,8 +24,9 @@
- - Create new data + + Create new data +
diff --git a/devui/data-table/demo/expand-row/expand-row.component.html b/devui/data-table/demo/expand-row/expand-row.component.html index 2edc82be..aa8fc19d 100755 --- a/devui/data-table/demo/expand-row/expand-row.component.html +++ b/devui/data-table/demo/expand-row/expand-row.component.html @@ -20,8 +20,9 @@
diff --git a/devui/data-table/demo/interaction-column/interaction-column.component.ts b/devui/data-table/demo/interaction-column/interaction-column.component.ts index 2ca21550..eb8308f7 100644 --- a/devui/data-table/demo/interaction-column/interaction-column.component.ts +++ b/devui/data-table/demo/interaction-column/interaction-column.component.ts @@ -93,7 +93,7 @@ export class InteractionColumnComponent implements OnInit { } const filterList = $event.name; const dataDisplay = []; - JSON.parse(JSON.stringify(originSource.slice(0, 6))).map(item => { + JSON.parse(JSON.stringify(originSource.slice(0, 6))).forEach(item => { if (filterList.includes(item.gender)) { dataDisplay.push(item); } @@ -104,7 +104,7 @@ export class InteractionColumnComponent implements OnInit { filterChangeMultiple($event) { const filterList = $event.map(item => item.name); const dataDisplay = []; - JSON.parse(JSON.stringify(originSource.slice(0, 6))).map(item => { + JSON.parse(JSON.stringify(originSource.slice(0, 6))).forEach(item => { if (filterList.includes(item.firstName)) { dataDisplay.push(item); } diff --git a/devui/data-table/demo/interaction/interaction.component.ts b/devui/data-table/demo/interaction/interaction.component.ts index 0cb81e9d..a44d63a7 100644 --- a/devui/data-table/demo/interaction/interaction.component.ts +++ b/devui/data-table/demo/interaction/interaction.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; -import { DataTableComponent, SortDirection, SortEventArg, TableWidthConfig } from 'ng-devui/data-table'; +import { DataTableComponent, SortDirection, SortEventArg, tableResizeFunc, TableWidthConfig } from 'ng-devui/data-table'; import { originSource, SourceType } from '../mock-data'; @Component({ @@ -83,10 +83,6 @@ export class InteractionComponent implements OnInit { } ]; - _totalWidth = 0; - lastWidth = 0; - firstResize = true; - lastNameSortDirection = SortDirection.ASC; genderSortDirection = SortDirection.default; sortParams = {field: 'lastName', direction: this.lastNameSortDirection}; @@ -111,38 +107,7 @@ export class InteractionComponent implements OnInit { }; } - onResize({ width, beforeWidth }, field) { - const index = this.tableWidthConfig.findIndex((config) => { - return config.field === field; - }); - if (index > -1) { - if (this.firstResize) { - this.firstResize = false; - const ratio = beforeWidth / parseInt(this.tableWidthConfig[index].width, 10); - this.tableWidthConfig.forEach(t => { - t.width = parseInt(t.width, 10) * ratio + 'px'; - }); - this._totalWidth = this.ele.nativeElement.querySelector('.table-wrap').offsetWidth; - this.lastWidth = parseInt(this.tableWidthConfig.slice(-1)[0].width); - } - this.tableWidthConfig[index].width = width + 'px'; - - let newWidthTotal = 0; - this.tableWidthConfig.forEach(t => { - newWidthTotal += parseInt(t.width, 10); - }); - - const lastCol = this.tableWidthConfig[this.tableWidthConfig.length - 1]; - const lastColWidth = parseInt(lastCol.width, 10); - const changeValue = newWidthTotal - this._totalWidth; - if (changeValue < 0) { - lastCol.width = lastColWidth + this._totalWidth - newWidthTotal + 'px'; - } else if (lastColWidth > this.lastWidth) { - const lastChange = (lastColWidth - this.lastWidth) > changeValue ? changeValue : (lastColWidth - this.lastWidth); - lastCol.width = lastColWidth - lastChange + 'px'; - } - } - } + onResize = tableResizeFunc(this.tableWidthConfig, this.ele); filterChangeRadio($event) { if ($event.name === 'Clear') { @@ -151,7 +116,7 @@ export class InteractionComponent implements OnInit { } const filterList = $event.name; const dataDisplay = []; - JSON.parse(JSON.stringify(originSource.slice(0, 6))).map(item => { + JSON.parse(JSON.stringify(originSource.slice(0, 6))).forEach(item => { if (filterList.includes(item.gender)) { dataDisplay.push(item); } @@ -162,7 +127,7 @@ export class InteractionComponent implements OnInit { onFirstFilterChange($event) { const filterList = $event.map(item => item.name); const dataDisplay = []; - JSON.parse(JSON.stringify(originSource.slice(0, 6))).map(item => { + JSON.parse(JSON.stringify(originSource.slice(0, 6))).forEach(item => { if (filterList.includes(item.firstName)) { dataDisplay.push(item); } diff --git a/devui/data-table/demo/muti-drag-row/muti-drag-row.component.html b/devui/data-table/demo/muti-drag-row/muti-drag-row.component.html index 8224acda..b48ee2c8 100644 --- a/devui/data-table/demo/muti-drag-row/muti-drag-row.component.html +++ b/devui/data-table/demo/muti-drag-row/muti-drag-row.component.html @@ -6,7 +6,6 @@ [switchWhileCrossEdge]="true" [dropScope]="'mutiple-group'" (dropEvent)="onDrop($event)" - [tableOverflowType]="'overlay'" > diff --git a/devui/data-table/demo/mutil-styles/mutil-styles.component.ts b/devui/data-table/demo/mutil-styles/mutil-styles.component.ts index 9e10a854..37a7eb42 100644 --- a/devui/data-table/demo/mutil-styles/mutil-styles.component.ts +++ b/devui/data-table/demo/mutil-styles/mutil-styles.component.ts @@ -41,6 +41,10 @@ export class MutilStylesComponent implements OnInit { activeSizeTab: any = 'sm'; sizeItems = [ + { + id: 'mini', + title: 'Mini' + }, { id: 'xs', title: 'Small' diff --git a/devui/data-table/demo/virtual-scroll/virtual-scroll.component.ts b/devui/data-table/demo/virtual-scroll/virtual-scroll.component.ts index 0d04d393..899bd352 100644 --- a/devui/data-table/demo/virtual-scroll/virtual-scroll.component.ts +++ b/devui/data-table/demo/virtual-scroll/virtual-scroll.component.ts @@ -47,5 +47,4 @@ export class VirtualScrollComponent implements OnInit { this.dataSource = this.dataSource.concat(tmp); } } - } diff --git a/devui/data-table/doc/api-cn.md b/devui/data-table/doc/api-cn.md index 303fbe72..19eca8b9 100644 --- a/devui/data-table/doc/api-cn.md +++ b/devui/data-table/doc/api-cn.md @@ -23,7 +23,7 @@ import { DataTableModule } from 'ng-devui/data-table'; | maxWidth | `string px` | -- | 可选,限制表格最大宽度,默认撑满父容器 | | maxHeight | `string px` | -- | 可选,限制最大高度,默认 | [表头固定](demo#table-fixing) | | minHeight | `string px` | -- | 可选,限制最小高度 | -- | -| size | `'sm'\|'md'\|'lg'` | 'sm' | 可选,表格大小,分别对应行高40px,48px,56px |[表格样式](demo#mutil-styles) | +| size | `'mini'\| 'xs' \|'sm'\|'md'\|'lg'` | 'sm' | 可选,表格大小 |[表格样式](demo#mutil-styles) | | rowHoveredHighlight | `boolean` | true | 可选,鼠标悬浮行时是否高亮,默认高亮认 | | generalRowHoveredData | `boolean` | false | 可选,使用配置column方式实现table,鼠标悬浮行时$hovered是否记录到rowItem中,默认不记录 | | cssClass | `string` | -- | 可选,自定义表格样式 | @@ -57,6 +57,7 @@ import { DataTableModule } from 'ng-devui/data-table'; | timeout | `number` | 300 | 可选,同时绑定单击、双击事件时,用于区分点击的时间间隔, 默认300`ms`,两个事件不同时使用可以指定为0 | | headerExpandConfig | [`TableExpandConfig`](#tableexpandconfig) | -- | 可选,配置header下的额外内容 | [扩展行](demo#expand-row) | | beforeCellEdit | `(rowItem: any, column: any) => Promise` | -- | 可选,单元格编辑前的拦截方法,
resolve(extraOptions)将更新该列的extraOptions | [编辑单元格](demo#edit-cell) | +| beforeCellEditEnd | `(rowItem: any, column: any) => boolean` | -- | 可选,单元格编辑结束时的拦截方法,返回true结束编辑,用于添加编辑校验规则,暂不支持异步校验 | [编辑单元格](demo#edit-cell) | | headerBg | `boolean` | false | 可选,表头是否显示背景色 | [表格样式](demo#mutil-styles) | | tableLayout | `'fixed'\|'auto'` | 'fixed' | 可选,表格布局 | [表格样式](demo#mutil-styles) | | borderType | `''\|'bordered'\|'borderless'` | '' | 可选,表格边框类型,默认有行边框,bordered:全边框,borderless:无边框 | [表格样式](demo#mutil-styles) | @@ -76,7 +77,7 @@ import { DataTableModule } from 'ng-devui/data-table'; | multiSortChange | `EventEmitter` | 多列选择Change事件,用来更新多列选择数组,返回单元格信息, 仅column模式下生效 | [表格交互](demo#table-interaction) | | cellClick | `EventEmitter` | 表格单元格点击事件,返回单元格信息 | [表格交互](demo#table-interaction) | | cellDBClick | `EventEmitter` | 表格单元格双击事件,返回单元格信息 | [表格交互](demo#table-interaction) | -| rowClick | `EventEmitter` | 表格行点击事件,返回行信息 | [表格交互](demo#table-interaction) | +| rowClick | `EventEmitter` | 表格行点击事件,返回行信息, 左右键都会触发, 如果有单元格内点击元素需要拦截触发,需要拦截mouseup事件 | [表格交互](demo#table-interaction) | | rowDBClick | `EventEmitter` | 表格行双击事件,返回行信息 | [表格交互](demo#table-interaction) | | detialToggle | `EventEmitter` | 使用配置column方式时扩展行展开收起事件,返回行状态信息 | [扩展行](demo#expand-row)| | cellEditStart | `EventEmitter` | 表格单元格开始编辑事件,返回单元格信息 | @@ -332,6 +333,48 @@ export enum SortDirection { } ``` +# d-table-option-toggle + +动态列及样式配置器,数据驱动,返回配置生成的数据; +## d-table-option-toggle 参数 + +| 参数名 | 类型 | 默认值 | 描述 | 跳转 Demo | +| :-------------: | :-----------------------------: | :----- | :------------------------------------------------------------: | :------------------------------------------------- | +| columnsData | `Array` | [] | 必选,配置列表头数据 | [动态列及样式](demo#dynamic-cols) | +| colSort | `boolean` | true | 可选,是否允许列排序 | [动态列及样式](demo#dynamic-cols) | +| styleSetting | `TableStyleData` | {} | 可选,添加相应样式配置及初始值 | [动态列及样式](demo#dynamic-cols) | +| toggleMode | `'dropdown' \| 'modal'` | 'dropdown' | 触发类型,下拉或者弹窗,列数过多建议使用弹窗 | [动态列及样式](demo#dynamic-cols) | +| modalWidth | `string` | '600px' | 弹窗宽度 | [动态列及样式](demo#dynamic-cols) | + +## d-table-option-toggle 事件 + +| 事件 | 类型 | 描述 | 跳转 Demo | +| :-------------------: | :-------: | :-----------------------------------------------------: | :------------------------------------------------- | +| colChanges | `EventEmitter>` | 列状态变化 | [动态列及样式](demo#dynamic-cols) | +| styleChanges | `EventEmitter` | 表格样式变化返回 | [动态列及样式](demo#dynamic-cols) | + +## ColData + +```ts +export interface ColData { + header: string; + checked: boolean; + category?: string; + [prop: string]: any; +} +``` + +## TableStyleData + +```ts +export interface TableStyleData { + size?: 'xs' | 'sm' | 'md'; + borderType?: '' | 'borderless'; + striped?: boolean; + shadowType?: 'embed' | 'normal'; +} +``` + # 以下为通过配置column来实现table时的才有的参数和方法 ## d-column 参数 diff --git a/devui/data-table/doc/api-en.md b/devui/data-table/doc/api-en.md index f899ac24..884a9bd4 100644 --- a/devui/data-table/doc/api-en.md +++ b/devui/data-table/doc/api-en.md @@ -23,7 +23,7 @@ On the page: | maxWidth | `string px` | -- | Optional. Limit the maximum table width. By default, the parent container is full. | | maxHeight | `string px` | -- | Optional. The maximum height is limited. The default value is | [fixed table header](demo#table-fixing) | | minHeight | `string px` | -- | Optional, limit the minimum height | -- | -| size | `'sm'\|'md'\|'lg'`| 'sm' | Optional. Specifies the table size, which corresponds to 40 px, 48 px, and 56 px respectively | [Table style](demo#mutil-styles) | +| size | `'mini'\| 'xs' \|'sm'\|'md'\|'lg'` | 'sm' | Optional. Specifies the table size | [Table style](demo#mutil-styles) | | rowHoveredHighlight | `boolean` | true | Optional. Indicating whether to highlight a line when the cursor is hovering. The default value is highlighted. | | generalRowHoveredData | `boolean` | false | Optional. It is used to configure columns to implement the table. When the cursor is moved to a row, $hovered is recorded to the row item. By default, $hovered is not recorded. | | cssClass | `string` | -- | Optional. Customize the table style | @@ -58,6 +58,7 @@ On the page: | headerExpandConfig | [`TableExpandConfig`](#tableexpandconfig) | -- | Optional. Extra content under the header | [Extended line](demo#expand-row) | | beforeCellEdit | `(rowItem: any, column: any) => Promise` | -- | Optional. Interception method before cell editing.
resolve(extraOptions) updates extraOptions of the column. | [edit cell](demo#edit-cell) | | headerBg | `boolean` | false | Optional. Indicating whether to display the background color in the table header | [Table style](demo#mutil-styles) | +| beforeCellEditEnd | `(rowItem: any, column: any) => boolean` | -- | is optional. This parameter indicates the interception method when cell editing ends. If true is returned, the editing ends. This parameter is used to add editing validation rules. Asynchronous validation is not supported currently. | [edit cell](demo#edit-cell) | | tableLayout | `'fixed'\|'auto'` | 'fixed' | Optional. Table layout | [Table style](demo#mutil-styles) | | borderType | `''\|'bordered'\|'borderless'` | '' | Optional. Table border type. The default value is row border. The options are bordered (full border) and borderless (no border). | [Table style](demo#mutil-styles) | | striped | `boolean` | false | Optional. Whether to display the table with zebra stripes. | [Table style](demo#mutil-styles) | @@ -76,7 +77,7 @@ On the page: | multiSortChange | `EventEmitter` | Change event, which is used to update the multi-column selection array and return cell information.This parameter is valid only in column mode. | [Table interaction](demo#table-interaction) | | cellClick | `EventEmitter` | Cell Click Event, Returning Cell Information | [Table Interaction](demo#table-interaction) | | cellDBClick | `EventEmitter` | Cell Double-click Event, Returning Cell Information | [Table Interaction](demo#table-interaction) | -| rowClick | `EventEmitter` | Table row click event, which returns row information | [Table interaction](demo#table-interaction) | +| rowClick | `EventEmitter` | The mouseup event is triggered when a row is clicked in the table. The row information is returned. The mouseup event needs to be intercepted if an element is clicked in a cell. | [Table interaction](demo#table-interaction) | | rowDBClick | `EventEmitter` | Double-clicking a table row. Row information is returned. | [Table interaction](demo#table-interaction) | | detialToggle | `EventEmitter` | Extended row expansion/collapse event. The row status information is returned. | | cellEditStart | `EventEmitter` | Cell Editing Start Event, Returning Cell Information | @@ -330,6 +331,48 @@ export enum SortDirection { } ``` +# d-table-option-toggle + +Dynamic column and style configurator, which is data-driven and returns the data generated by configuration. +## d-table-option-toggle parameter + +| Parameter name | Type | Default value | Description | Jump to Demo | +| :-------------: | :-----------------------------: | :----- | :------------------------------------------------------------: | :------------------------------------------------- | +| columnsData | `Array` | [] | is mandatory. This parameter is used to configure the column header data.|[Dynamic Column and Style](demo#dynamic-cols)| +| colSort | `boolean` | true | (Optional) Indicates whether to allow column sorting. | [Dynamic Columns and Styles] (demo#dynamic-cols) | +| styleSetting | `TableStyleData` | {} | Optional. Add style configurations and initial values. | [Dynamic columns and styles] (demo#dynamic-cols) | +| toggleMode | `dropdown' \| 'modal' ` | 'dropdown' | Trigger type, drop-down or pop-up window. If there are too many columns, pop-up windows are recommended. | [Dynamic Columns and Styles] (demo#dynamic-cols) | +| modalWidth | `string` | '600px' | Pop-up window width | [Dynamic column and style] (demo#dynamic-cols) | + +## d-table-option-toggle event + +| Event | Type | Description | Jump to Demo | +| :-------------------: | :-------: | :-----------------------------------------------------: | :------------------------------------------------- | +| colChanges | `EventEmitter>` | column status change | [Dynamic column and style] (demo#dynamic-cols) | +| styleChanges | `EventEmitter` | Table Style Change Return | [Dynamic Columns and Styles] (demo#dynamic-cols) | + +## ColData + +```ts +export interface ColData { +header: string; +checked: boolean; +category?: string; +[prop: string]: any; +} +``` + +## TableStyleData + +```ts +export interface TableStyleData { +size?:'xs' |'sm' |'md'; +borderType?: ''|'borderless'; +striped?: boolean; +shadowType?:'embed' |'normal'; +} +``` + # The following table describes the parameters and methods that are available only when a table is implemented by configuring columns. ## d-column parameter diff --git a/devui/data-table/public-api.ts b/devui/data-table/public-api.ts index ee70c1de..ac22535b 100755 --- a/devui/data-table/public-api.ts +++ b/devui/data-table/public-api.ts @@ -9,6 +9,8 @@ export * from './data-table.module'; export * from './data-table.token'; export * from './display-cell-value.pipe'; export * from './editor-host.directive'; +export * from './table-option-modal.component'; +export * from './table-option-toggle.component'; export * from './table/body/tbody.component'; export * from './table/body/td/td.component'; export * from './table/body/td/td.service'; diff --git a/devui/data-table/table-option-modal.component.html b/devui/data-table/table-option-modal.component.html new file mode 100644 index 00000000..53b24416 --- /dev/null +++ b/devui/data-table/table-option-modal.component.html @@ -0,0 +1,192 @@ +
+
+
+

{{ data.i18nText?.tableSetting }}

+ + +

{{ data.i18nText?.colCanSelect }}

+ + + + + +
+ +
+
+
+
+

{{ data.i18nText?.styles }}

+
+
+ + + + + + +

{{ data.i18nText?.compact }}

+
+
+ + + + + + +

{{ data.i18nText?.standard }}

+
+
+ + + + + + +

{{ data.i18nText?.loose }}

+
+
+
+ {{ data.i18nText?.divideLine }} + +
+ +
+ {{ data.i18nText?.striped }} + +
+ +
+ {{ data.i18nText?.tableShadow }} + +
+
+
+
+

{{ data.i18nText?.colSelected }}

+ +
+
+ +
+
+
+
+ +
+
+
+
+
+
+ +
+ + + + + + + + + + {{ colsData.header }} + diff --git a/devui/data-table/table-option-modal.component.scss b/devui/data-table/table-option-modal.component.scss new file mode 100644 index 00000000..3616e733 --- /dev/null +++ b/devui/data-table/table-option-modal.component.scss @@ -0,0 +1,81 @@ +@import '../style/theme/color'; +@import '../style/theme/shadow'; +@import '../style/theme/corner'; +@import '../style/core/_font'; + +.devui-option-modal { + position: relative; + + &-body { + height: 550px; + display: flex; + + .devui-option-modal-selected-col { + flex: 1; + padding: 20px; + + d-checkbox { + display: inline-block; + width: 30%; + height: 36px; + margin-right: 8px; + overflow: hidden; + } + } + + .devui-option-modal-style { + width: 280px; + background: $devui-global-bg; + border-radius: 0 $devui-border-radius-card 0 0; + } + + .devui-option-title { + font-size: $devui-font-size-card-title; + color: $devui-text; + font-weight: bold; + margin-bottom: 16px; + } + + .devui-option-subtitle { + color: $devui-text; + font-size: $devui-font-size; + font-weight: bold; + margin-bottom: 12px; + } + } + + &-footer { + height: 72px; + text-align: center; + padding: 16px 0; + position: relative; + + &::before { + content: ''; + width: 100%; + height: 20px; + opacity: 0.04; + position: absolute; + top: -20px; + left: 0; + background-image: linear-gradient(180deg, transparent, $devui-base-bg-dark); + } + } + + .devui-option-panel { + padding-bottom: 0; + height: 100%; + flex-direction: column; + display: flex; + + .devui-option-panel-col-drag { + flex: 1; + overflow: hidden; + + &:hover { + overflow-y: auto; + overflow-y: overlay; + } + } + } +} diff --git a/devui/data-table/table-option-modal.component.ts b/devui/data-table/table-option-modal.component.ts new file mode 100644 index 00000000..23ab2c61 --- /dev/null +++ b/devui/data-table/table-option-modal.component.ts @@ -0,0 +1,88 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; +import { ColData } from './table-option-toggle.component'; + +@Component({ + selector: 'd-table-option-modal', + templateUrl: './table-option-modal.component.html', + styleUrls: ['./table-option-modal.component.scss', './table-option-toggle.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TableOptionModalComponent implements OnInit { + @Input() data: any; + + get showStyleSetting() { + return !!Object.keys(this.data.styleSetting).length; + } + + get selectedCols() { + return this._columnsData.filter(t => t.checked); + } + + _columnsData: Array = []; + columnsCache: Array = []; + _styleSetting: any = {}; + + filterKey = ''; + + constructor( + private cdr: ChangeDetectorRef + ) {} + + judgeNameFIlter(name: string) { + return name.toUpperCase().includes(this.filterKey.toUpperCase()); + } + + onSearch(value: string) { + this.filterKey = value; + this.cdr.detectChanges(); + } + + ngOnInit(): void { + this._columnsData = this.data.columnsData; + this.columnsCache = [...this._columnsData]; + this._styleSetting = this.data.styleSetting; + } + + searchIndex(col) { + return this.data.columnsData.findIndex(t => t.header === col.header); + } + + onDrop(e) { + let index = this.searchIndex(this.selectedCols[e.dropIndex]); + const fromIndex = this.searchIndex(this.selectedCols[e.dragFromIndex]); + if (-1 !== index) { + if (-1 !== fromIndex && index > fromIndex) { + index--; + } + this._columnsData.splice(index, 0, fromIndex === -1 ? e.dragData : this._columnsData.splice(fromIndex, 1)[0]); + } else { + this._columnsData.push(e.dragData); + } + } + + onCardActiveChanges(active: boolean, status: 'xs' | 'sm' | 'md') { + this._styleSetting['size'] = active ? status : 'none'; + } + + styleSettingChanges(checked, type: 'border' | 'striped' | 'shadow') { + switch (type) { + case 'border': + this._styleSetting['borderType'] = checked ? '' : 'borderless'; + break; + case 'shadow': + this._styleSetting['shadowType'] = checked ? 'normal' : 'embed'; + break; + case 'striped': + this._styleSetting['striped'] = checked; + break; + } + } + + close() { + this.data.onClose(); + } + + ensure() { + this.data.onEnsure(this._columnsData, this._styleSetting); + } +} diff --git a/devui/data-table/table-option-toggle.component.html b/devui/data-table/table-option-toggle.component.html new file mode 100644 index 00000000..07fdcd59 --- /dev/null +++ b/devui/data-table/table-option-toggle.component.html @@ -0,0 +1,171 @@ +
+
+ +
+
+

{{ i18nText?.tableSetting }}

+
+
+

{{ i18nText?.styles }}

+
+
+ + + + + + +

{{ i18nText?.compact }}

+
+
+ + + + + + +

{{ i18nText?.standard }}

+
+
+ + + + + + +

{{ i18nText?.loose }}

+
+
+
+ {{ i18nText?.divideLine }} + +
+ +
+ {{ i18nText?.striped }} + +
+ +
+ {{ i18nText?.tableShadow }} + +
+
+
+
+

{{ i18nText?.colCanSelect }}

+ +
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+ +
+ + + + + + + + + + + + + {{ colsData.header }} + + diff --git a/devui/data-table/table-option-toggle.component.scss b/devui/data-table/table-option-toggle.component.scss new file mode 100644 index 00000000..420d2a9a --- /dev/null +++ b/devui/data-table/table-option-toggle.component.scss @@ -0,0 +1,147 @@ +@import '../style/theme/color'; +@import '../style/theme/shadow'; +@import '../style/theme/corner'; +@import '../style/core/_font'; + +.devui-option-toggle { + cursor: pointer; +} + +.devui-option-panel { + width: 280px; + padding: 20px; + + .devui-option-title { + font-size: $devui-font-size-card-title; + color: $devui-text; + font-weight: bold; + margin-bottom: 16px; + } + + .devui-option-subtitle { + color: $devui-text; + font-size: $devui-font-size; + font-weight: bold; + margin-bottom: 12px; + } + + &-col-select { + display: inline-block; + } + + &-style-setting { + display: inline-block; + width: 100%; + padding-bottom: 20px; + } + + .devui-option-size-wrapper { + display: flex; + justify-content: space-between; + + .devui-option-size-card { + width: 72px; + height: 72px; + border-radius: $devui-border-radius-card; + padding: 8px 22px 8px 20px; + box-shadow: $devui-shadow-length-base $devui-light-shadow; + cursor: pointer; + position: relative; + color: $devui-aide-text; + + p { + width: 72px; + margin-left: -20px; + text-align: center; + } + + d-checkbox { + position: absolute; + right: 4px; + top: 4px; + display: none; + } + + &.devui-option-item-active { + box-shadow: $devui-shadow-length-hover $devui-light-shadow; + font-weight: bold; + color: $devui-text; + + d-checkbox { + display: block; + } + } + + &:hover { + box-shadow: $devui-shadow-length-hover $devui-light-shadow; + + d-checkbox { + display: block; + } + } + + svg { + transform: scale(2); + transform-origin: 0 0; + + path { + fill: $devui-waiting; + } + } + } + + ::ng-deep d-checkbox .devui-checkbox-default-background { + border-radius: 50%; + } + } + + .devui-option-form { + margin-top: 18px; + display: flex; + justify-content: space-between; + } + + .devui-option-panel-col-drag { + .devui-option-drag-item { + margin: 0 -8px; + height: 36px; + padding: 10px 8px; + display: flex; + align-items: center; + cursor: pointer; + border-radius: $devui-border-radius; + + svg { + margin-right: 12px; + + path { + fill: $devui-icon-text; + } + } + + d-checkbox { + display: none; + } + + d-checkbox.devui-option-item-active { + display: block; + } + + &:hover { + background-color: $devui-list-item-hover-bg; + + d-checkbox { + display: block; + } + } + } + + .devui-option-drag-label { + flex: 1; + } + + ::ng-deep d-checkbox .devui-checkbox-default-background { + border-radius: 50%; + } + } +} diff --git a/devui/data-table/table-option-toggle.component.ts b/devui/data-table/table-option-toggle.component.ts new file mode 100644 index 00000000..87d13eaa --- /dev/null +++ b/devui/data-table/table-option-toggle.component.ts @@ -0,0 +1,163 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { I18nInterface, I18nService } from 'ng-devui/i18n'; +import { ModalService } from 'ng-devui/modal'; +import { cloneDeep } from 'lodash-es'; +import { Subscription } from 'rxjs'; +import { TableOptionModalComponent } from './table-option-modal.component'; + +export interface ColData { + header: string; + checked: boolean; + category?: string; + [prop: string]: any; +} + +export interface TableStyleData { + size?: 'xs' | 'sm' | 'md'; + borderType?: '' | 'borderless'; + striped?: boolean; + shadowType?: 'embed' | 'normal'; +} + +@Component({ + selector: 'd-table-option-toggle', + templateUrl: './table-option-toggle.component.html', + styleUrls: ['./table-option-toggle.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TableOptionToggleComponent implements OnInit, OnDestroy{ + @Input() set columnsData(value: Array) { + this._columnsData = cloneDeep(value); + }; + @Input() showCategory: boolean; + @Input() colSort = true; + @Input() styleSetting: TableStyleData = {}; + @Input() toggleMode: 'dropdown' | 'modal' = 'dropdown'; + @Input() modalWidth = '600px'; + + @Output() colChanges: EventEmitter> = new EventEmitter>(); + @Output() styleChanges: EventEmitter = new EventEmitter(); + + _columnsData = []; + + checkedList; + + get showStyleSetting() { + return !!Object.keys(this.styleSetting).length; + } + + get sizeStatus() { + return (this.styleSetting as any)?.size; + } + + set sizeStatus(value) { + if(!this.styleSetting) { + this.styleSetting = {}; + } + this.styleSetting['size'] = value; + } + + i18nText: I18nInterface['datatable']; + i18nLocale: I18nInterface['locale']; + i18nSubscription: Subscription; + + constructor( + private modalService: ModalService, + private cdr: ChangeDetectorRef, + private i18n: I18nService + ){} + + ngOnInit(): void { + this.i18nText = this.i18n.getI18nText().datatable; + this.i18nLocale = this.i18n.getI18nText().locale; + this.i18nSubscription = this.i18n.langChange().subscribe((data) => { + this.i18nText = data.datatable; + this.i18nLocale = data.locale; + this.cdr.markForCheck(); + }); + } + + onToggle(event) { + console.log(event); + } + + toggleActive(item) { + item.checked = !item.checked; + this.emitData(); + } + + onCardActiveChanges(active: boolean, status: 'xs' | 'sm' | 'md') { + this.sizeStatus = active ? status : 'none'; + } + + emitStyles() { + this.styleChanges.emit(this.styleSetting as TableStyleData); + } + + emitData() { + this.colChanges.emit(this._columnsData); + } + + styleSettingChanges(checked, type: 'border' | 'striped' | 'shadow') { + switch (type) { + case 'border': + this.styleSetting.borderType = checked ? '' : 'borderless'; + break; + case 'shadow': + this.styleSetting.shadowType = checked ? 'normal' : 'embed'; + break; + case 'striped': + this.styleSetting.striped = checked; + break; + } + + this.emitStyles(); + } + + onDrop(e) { + let index = e.dropIndex; + const fromIndex = e.dragFromIndex; + if (-1 !== index) { + if (-1 !== fromIndex && index > fromIndex) { + index--; + } + this._columnsData.splice(index, 0, fromIndex === -1 ? e.dragData : this._columnsData.splice(fromIndex, 1)[0]); + } else { + this._columnsData.push(e.dragData); + } + + this.colChanges.emit(this._columnsData); + } + + openModal() { + const results = this.modalService.open({ + id: 'modal-modal', + width: this.modalWidth, + backdropCloseable: true, + component: TableOptionModalComponent, + data: { + columnsData: this._columnsData, + showCategory: this.showCategory, + styleSetting: cloneDeep(this.styleSetting), + colSort: this.colSort, + i18nText: this.i18nText, + onClose: () => { + results.modalInstance.hide(); + }, + onEnsure: (columnsData, styleSetting) => { + this._columnsData = columnsData; + this.colChanges.emit(columnsData); + this.styleChanges.emit(styleSetting); + results.modalInstance.hide(); + this.cdr.detectChanges(); + }, + }, + }); + } + + ngOnDestroy(): void { + if (this.i18nSubscription) { + this.i18nSubscription.unsubscribe(); + } + } +} diff --git a/devui/data-table/table/body/tbody.component.scss b/devui/data-table/table/body/tbody.component.scss index c730fd42..ec8fbaf5 100644 --- a/devui/data-table/table/body/tbody.component.scss +++ b/devui/data-table/table/body/tbody.component.scss @@ -1,4 +1,4 @@ -@import '../../../style/theme/color'; +@import '../../../style/core/_color'; @import '../../../style/core/_font'; $devui-table-expand-area-bg: var(--devui-table-expand-area-bg, #f7f8fa); diff --git a/devui/data-table/table/head/th/filter/filter.component.html b/devui/data-table/table/head/th/filter/filter.component.html index 35f61942..cc8362d3 100644 --- a/devui/data-table/table/head/th/filter/filter.component.html +++ b/devui/data-table/table/head/th/filter/filter.component.html @@ -10,7 +10,7 @@ diff --git a/devui/data-table/utils/utils.ts b/devui/data-table/utils/utils.ts index dea12693..45472e40 100644 --- a/devui/data-table/utils/utils.ts +++ b/devui/data-table/utils/utils.ts @@ -1,3 +1,6 @@ +import { ElementRef } from "@angular/core"; +import { TableWidthConfig } from '../data-table.model'; + export const simDeepClone = obj => { if (obj === null) { return null; } if (typeof obj === 'object') { @@ -13,6 +16,44 @@ export const simDeepClone = obj => { } }; +export function tableResizeFunc(tableWidthConfig: TableWidthConfig[], ele: ElementRef) { + let _totalWidth = 0; + let lastWidth = 0; + let firstResize = true; + return function onResize({ width, beforeWidth }, field) { + const index = tableWidthConfig.findIndex((config) => { + return config.field === field; + }); + if (index > -1) { + if (firstResize) { + firstResize = false; + const ratio = beforeWidth / parseInt(tableWidthConfig[index].width, 10); + tableWidthConfig.forEach(t => { + t.width = parseInt(t.width, 10) * ratio + 'px'; + }); + _totalWidth = ele.nativeElement.querySelector('.table-wrap').offsetWidth; + lastWidth = parseInt(tableWidthConfig.slice(-1)[0].width); + } + tableWidthConfig[index].width = width + 'px'; + + let newWidthTotal = 0; + tableWidthConfig.forEach(t => { + newWidthTotal += parseInt(t.width, 10); + }); + + const lastCol = tableWidthConfig[tableWidthConfig.length - 1]; + const lastColWidth = parseInt(lastCol.width, 10); + const changeValue = newWidthTotal - _totalWidth; + if (changeValue < 0) { + lastCol.width = lastColWidth + _totalWidth - newWidthTotal + 'px'; + } else if (lastColWidth > lastWidth) { + const lastChange = (lastColWidth - lastWidth) > changeValue ? changeValue : (lastColWidth - lastWidth); + lastCol.width = lastColWidth - lastChange + 'px'; + } + } + }; +} + export const highPerformanceFilter = (arr, func) => { let res = []; const arrLength = arr.length; diff --git a/devui/datepicker-pro/datepicker-pro-calendar.component.ts b/devui/datepicker-pro/datepicker-pro-calendar.component.ts index 75353018..c86f1770 100644 --- a/devui/datepicker-pro/datepicker-pro-calendar.component.ts +++ b/devui/datepicker-pro/datepicker-pro-calendar.component.ts @@ -284,10 +284,6 @@ export class DatepickerProCalendarComponent implements OnInit, AfterViewInit, On return; } - if (value.find(t => !this.pickerSrv.dateInRange(t))) { - return; - } - this.dateValue = value.map(d => { return d ? this.datepickerConvert.format(d, this.curFormat) : ''; }); @@ -300,7 +296,7 @@ export class DatepickerProCalendarComponent implements OnInit, AfterViewInit, On } writeSingleValue(value: Date) { - if (!value || !this.pickerSrv.dateInRange(new Date(value))) { + if (!value) { this.clear(); return; } diff --git a/devui/datepicker-pro/datepicker-pro.component.ts b/devui/datepicker-pro/datepicker-pro.component.ts index c0eb93c4..dfc4a363 100644 --- a/devui/datepicker-pro/datepicker-pro.component.ts +++ b/devui/datepicker-pro/datepicker-pro.component.ts @@ -289,7 +289,7 @@ export class DatepickerProComponent implements OnInit, AfterViewInit, OnDestroy, } writeValue(value: Date) { - if (!value || !this.pickerSrv.dateInRange(new Date(value))) { + if (!value) { this.clear(); return; } diff --git a/devui/datepicker-pro/lib/calendar-panel.component.ts b/devui/datepicker-pro/lib/calendar-panel.component.ts index 060ebd3f..7a3d3263 100644 --- a/devui/datepicker-pro/lib/calendar-panel.component.ts +++ b/devui/datepicker-pro/lib/calendar-panel.component.ts @@ -159,7 +159,10 @@ export class CalendarPanelComponent implements OnInit, OnDestroy { this.goToDate(this.selectedRangeDate[0] || this.selectedRangeDate[1] || new Date()); } else { if (!this.selectedRangeDate[1] && this.selectedRangeDate[0]) { - this.updateRangeDate([this.selectedRangeDate[0], this.selectedRangeDate[0]]); + this.updateRangeDate([ + this.selectedRangeDate[0], + new Date(new Date(this.selectedRangeDate[0].getTime()).setHours(23, 59, 59)) + ]); } this.goToDate(this.selectedRangeDate[1] || this.selectedRangeDate[0] || new Date()); } diff --git a/devui/datepicker-pro/range-datepicker-pro.component.ts b/devui/datepicker-pro/range-datepicker-pro.component.ts index c36b2455..94578257 100644 --- a/devui/datepicker-pro/range-datepicker-pro.component.ts +++ b/devui/datepicker-pro/range-datepicker-pro.component.ts @@ -415,10 +415,6 @@ export class RangeDatepickerProComponent implements OnInit, OnDestroy, AfterView return; } - if (value.find(t => !this.pickerSrv.dateInRange(t))) { - return; - } - this.dateValue = value.map(d => { return d ? this.datepickerConvert.format(d, this.curFormat) : ''; }); diff --git a/devui/datepicker/datepicker.component.ts b/devui/datepicker/datepicker.component.ts index 2b1d810e..777fbd61 100755 --- a/devui/datepicker/datepicker.component.ts +++ b/devui/datepicker/datepicker.component.ts @@ -461,15 +461,15 @@ export class DatepickerComponent implements OnInit, OnChanges, OnDestroy, Contro }); if (this.currentYear < this.minDate.getFullYear() || this.currentYear > this.maxDate.getFullYear()) { - all.map(month => {month.disabled = true; }); + all.forEach(month => {month.disabled = true; }); } if (this.currentYear === this.minDate.getFullYear()) { - all.map(month => {month.disabled = month.index < this.minDate.getMonth(); }); + all.forEach(month => {month.disabled = month.index < this.minDate.getMonth(); }); } if (this.currentYear === this.maxDate.getFullYear()) { - all.map(month => {month.disabled = month.index > this.maxDate.getMonth(); }); + all.forEach(month => {month.disabled = month.index > this.maxDate.getMonth(); }); } return all; } diff --git a/devui/design-token/animation/demo/animation/animation.component.ts b/devui/design-token/animation/demo/animation/animation.component.ts index 0e79f0d5..be35939c 100644 --- a/devui/design-token/animation/demo/animation/animation.component.ts +++ b/devui/design-token/animation/demo/animation/animation.component.ts @@ -11,58 +11,50 @@ export class AnimationComponent implements OnInit, OnDestroy { themeService: ThemeService; subs: Subscription = new Subscription(); animation = []; + i18nText: any; + + constructor(private translate: TranslateService) {this.setI18n(); } - constructor(private translate: TranslateService) { } ngOnInit() { if (typeof window !== undefined) { - this.setI18n(); + this.themeService = window['devuiThemeService']; + this.changeValueInTable(); + if (this.themeService.eventBus) { + this.themeService.eventBus.add('themeChanged', this.changeValueInTable); + } } } + changeValueInTable = () => { + const theme = this.themeService.currentTheme; + for (const key in theme.data) { + if (key.includes('devui-animation')) { + const obj = { + name: '$' + key, + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.animation.push(obj); + } + } + }; + setI18n() { this.subs.add( this.translate.get('components.design-animation.AnimationDemo.instance').subscribe((res) => { - this.setValues(res); + this.i18nText = res['animation']; }) ); this.subs.add( this.translate.onLangChange.subscribe((event: TranslationChangeEvent) => { const values = this.translate.instant('components.design-animation.AnimationDemo.instance'); - this.setValues(values); + this.i18nText = values['animation']; }) ); } - setValues(values) { - this.animation = [ - { name: '$devui-animation-duration-slow', value: '300ms', description: values.animation['devui-animation-duration-slow'] }, - { name: '$devui-animation-duration-base', value: '200ms', description: values.animation['devui-animation-duration-base'] }, - { name: '$devui-animation-duration-fast', value: '100ms', description: values.animation['devui-animation-duration-fast'] }, - { - name: '$devui-animation-ease-out', value: 'cubic-bezier(0.16, 0.75, 0.5, 1)', - description: values.animation['devui-animation-ease-out'] - }, - { - name: '$devui-animation-ease-in-out', value: 'cubic-bezier(0.5, 0.05, 0.5, 0.95)', - description: values.animation['devui-animation-ease-in-out'] - }, - { - name: '$devui-animation-ease-in', value: 'cubic-bezier(0.5, 0, 0.84, 0.25)', - description: values.animation['devui-animation-ease-in'] - }, - { - name: '$devui-animation-ease-in-out-smooth', value: 'cubic-bezier(0.645, 0.045, 0.355, 1)', - description: values.animation['devui-animation-ease-in-out-smooth'] - }, - { - name: '$devui-animation-linear', value: 'cubic-bezier(0, 0, 1, 1)', - description: values.animation['devui-animation-linear'] - } - ]; - } - ngOnDestroy() { if (this.subs) { this.subs.unsubscribe(); diff --git a/devui/design-token/border-radius/demo/border-radius/border-radius.component.html b/devui/design-token/border-radius/demo/border-radius/border-radius.component.html index 518ae1c9..7ce5462f 100644 --- a/devui/design-token/border-radius/demo/border-radius/border-radius.component.html +++ b/devui/design-token/border-radius/demo/border-radius/border-radius.component.html @@ -7,7 +7,7 @@

{{ 'components.design-border-radius.cornerDemo.instan > diff --git a/devui/design-token/border-radius/demo/border-radius/border-radius.component.ts b/devui/design-token/border-radius/demo/border-radius/border-radius.component.ts index 4c7e9def..3cb414e4 100644 --- a/devui/design-token/border-radius/demo/border-radius/border-radius.component.ts +++ b/devui/design-token/border-radius/demo/border-radius/border-radius.component.ts @@ -1,7 +1,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { devuiLightTheme, ThemeService } from 'ng-devui/theme'; +import { ThemeService } from 'ng-devui/theme'; import { TranslateService, TranslationChangeEvent } from '@ngx-translate/core'; -import { cloneDeep } from 'lodash-es'; import { Subscription } from 'rxjs'; @Component({ @@ -12,74 +11,49 @@ export class BorderRadiusComponent implements OnInit, OnDestroy { themeService: ThemeService; subs: Subscription = new Subscription(); borderRadius = []; + i18nText: any; - constructor(private translate: TranslateService) { } + constructor(private translate: TranslateService) { this.setI18n(); } ngOnInit() { if (typeof window !== undefined) { this.themeService = window['devuiThemeService']; + this.changeValueInTable(); if (this.themeService.eventBus) { this.themeService.eventBus.add('themeChanged', this.changeValueInTable); } - this.setI18n(); } } changeValueInTable = () => { const theme = this.themeService.currentTheme; - this.borderRadius.map((obj) => { - const nameArr = obj.name.split('$'); - if (nameArr.length === 2) { - const match = theme.data[nameArr[1]]; - if (match) { - obj.themeValue = match; - } else { - obj.themeValue = obj.value; - } + for (const key in theme.data) { + if (key.includes('devui-border-radius')) { + const obj = { + name: '$' + key, + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.borderRadius.push(obj); } - }); - this.borderRadius = cloneDeep(this.borderRadius); + } }; setI18n() { this.subs.add( this.translate.get('components.design-border-radius.cornerDemo.instance').subscribe((res) => { - this.setValues(res); + this.i18nText = res['borderRadius']; }) ); this.subs.add( this.translate.onLangChange.subscribe((event: TranslationChangeEvent) => { const values = this.translate.instant('components.design-border-radius.cornerDemo.instance'); - this.setValues(values); + this.i18nText = values['borderRadius']; }) ); } - setValues(values) { - this.borderRadius = [ - { - name: '$devui-border-radius', - value: devuiLightTheme.data['devui-border-radius'], - description: values.borderRadius['devui-border-radius'] - }, - { - name: '$devui-border-radius-feedback', - value: devuiLightTheme.data['devui-border-radius-feedback'], - description: values.borderRadius['devui-border-radius-feedback'] - }, - { - name: '$devui-border-radius-card', - value: devuiLightTheme.data['devui-border-radius-card'], - description: values.borderRadius['devui-border-radius-card'] - }, - ]; - - if (this.themeService) { - this.changeValueInTable(); - } - } - ngOnDestroy() { if (this.subs) { this.subs.unsubscribe(); diff --git a/devui/design-token/color/demo/color/color.component.html b/devui/design-token/color/demo/color/color.component.html index 7231a296..f5d74da6 100644 --- a/devui/design-token/color/demo/color/color.component.html +++ b/devui/design-token/color/demo/color/color.component.html @@ -9,155 +9,47 @@

{{ 'components.design-color.colorDemo.instance.title'
- - - -
-
{{ tableNameList[index] }}
- -

- - - - - - - - - - - - - - - - - - -
- {{ 'components.design-color.colorDemo.instance.formColor' | translate }} -
-
-
-
-
{{ '$devui-' + col + '-' + block }}
-
{{ colorList[index][idx] }}
-
-
- {{ col }} +
+
+ {{ 'components.design-color.colorDemo.instance.catalogs.' + table.key | translate }} +
+ +
+ + + + + + + + + + + + + + + + + +
+ {{ 'components.design-color.colorDemo.instance.formColor' | translate }} +
+
+
+
+
{{ '$devui-' + col + '-' + block }}
+
{{ swatchesList['devui-' + col + '-' + block] }}
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- {{ cellItem }} -
-
-
-
-
- - - -
- {{ cellItem }} -
-
-
-
-
- - -
-
-
- + {{ col }} + + +
+ diff --git a/devui/design-token/color/demo/color/color.component.scss b/devui/design-token/color/demo/color/color.component.scss index 52ae97e4..668ea2ee 100644 --- a/devui/design-token/color/demo/color/color.component.scss +++ b/devui/design-token/color/demo/color/color.component.scss @@ -56,6 +56,12 @@ table { text-align: left; } +.devui-table-catalog { + font-size: $devui-font-size-page-title; + font-weight: bold; + padding: 8px 0 0 8px; +} + .color-cube { height: 20px; width: 20px; diff --git a/devui/design-token/color/demo/color/color.component.ts b/devui/design-token/color/demo/color/color.component.ts index d31128af..3ff69b3c 100644 --- a/devui/design-token/color/demo/color/color.component.ts +++ b/devui/design-token/color/demo/color/color.component.ts @@ -1,14 +1,14 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { TableExpandConfig } from 'ng-devui/data-table'; -import { devuiDarkTheme, devuiLightTheme, ThemeService } from 'ng-devui/theme'; +import { ThemeService } from 'ng-devui/theme'; +import { devuiSwatches } from 'ng-devui/theme-collection'; import { TranslateService, TranslationChangeEvent } from '@ngx-translate/core'; import { Subscription } from 'rxjs'; -export interface CatalogConfig { +export interface colorItemConfig { name: string; + value: string; type: string; - expand?: boolean; - [propName: string]: any; + description: string; } @Component({ @@ -19,662 +19,138 @@ export interface CatalogConfig { export class ColorComponent implements OnInit, OnDestroy { themeService: ThemeService; subs: Subscription = new Subscription(); - headerExpandConfig: TableExpandConfig; - activeTab: string | number = 'tab1'; - colorSource = []; - textColorSource = []; - borderColorSource = []; - backgroundColorSource = []; - statusColorSource = []; - themeColorSource = []; - catalogs: CatalogConfig[] = []; - catalogsList: CatalogConfig[] = []; - tableList: CatalogConfig[][] = []; colorTypeList = ['blue', 'sky', 'green', 'lime', 'yellow', 'orange', 'red', 'magenta', 'purple']; - // TODO: 灰色类变量用于文字,边框,背景,暂不支持开发直接使用灰色变量 - colorTypeSecList = ['gray', 'slate', 'zinc', 'dark-gray', 'dark-slate', 'dark-zinc']; - colorNumberList = ['5', '10' ,'20', '30', '40', '50', '60', '70', '80', '90', '100']; + colorNumberList = ['5', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100']; + // 通用匹配规则为包含shadowColorKey中关键字 + shadowColorKey = ['devui-shadow', 'devui-light-shadow', 'devui-connected-overlay-shadow', 'devui-feedback-overlay-shadow']; + // 通用匹配规则为包含bg关键字,以及在bgColorKey中的特殊背景色名称 + bgColorKey = ['devui-block', 'devui-area', 'devui-float-block-shadow', 'devui-highlight-overlay', 'devui-primary-disabled']; + // 通用匹配规则为包含textColorKey中关键字 + textColorKey = ['placeholder', 'link', 'icon', 'text']; + // 通用匹配规则为包含borderColorKey中关键字 + borderColorKey = ['line']; + // 通用匹配规则为包含statusColorKey中关键字 + statusColorKey = ['danger', 'warning', 'success', 'waiting', 'info', 'initial', 'unavailable', 'primary', 'contrast', 'default']; + // 通用匹配规则为包含brandKey中关键字 + brandKey = ['brand']; colorList = []; - tableNameList = []; + dataSource = new Map(); + i18nText; + swatchesList = {}; + colors = []; - constructor(private translate: TranslateService) {} + constructor(private translate: TranslateService) { + this.setI18n(); + } ngOnInit() { if (typeof window !== undefined) { this.themeService = window['devuiThemeService']; + this.changeValueInTable(); if (this.themeService.eventBus) { this.themeService.eventBus.add('themeChanged', this.changeValueInTable); } - this.setI18n(); } + this.swatchesList = devuiSwatches; } changeValueInTable = () => { const theme = this.themeService.currentTheme; - if(this.activeTab === 'tab1') { - this.catalogs.forEach(item => { - this.changeVal(item, theme); - }); + for (const key in theme.data) { + if (!(theme.data[key].startsWith('#') || theme.data[key].startsWith('rgba'))) { + continue; + } + if (key.includes('bg') || this.bgColorKey.some(item => key.includes(item))) { + const obj = { + name: '$' + key, + type: 'background', + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.colorList.push(obj); + } else if (this.shadowColorKey.some(item => key.includes(item))) { + const obj = { + name: key, + type: 'shadow', + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.colorList.push(obj); + } else if (this.textColorKey.some(item => key.includes(item))) { + const obj = { + name: key, + type: 'text', + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.colorList.push(obj); + } else if (this.borderColorKey.some(item => key.includes(item))) { + const obj = { + name: key, + type: 'border', + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.colorList.push(obj); + } else if (this.statusColorKey.some(item => key.includes(item))) { + const obj = { + name: key, + type: 'status', + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.colorList.push(obj); + } else if (this.brandKey.some(item => key.includes(item))) { + const obj = { + name: key, + type: 'brand', + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.colorList.push(obj); + } else { + const obj = { + name: key, + type: 'others', + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.colorList.push(obj); + } } + this.transferDataSource(); }; - changeVal(val, theme) { - val.map((obj) => { - const nameArr = obj.name.split('$'); - if (nameArr.length === 2) { - const match = theme.data[nameArr[1]]; - if (match) { - obj.themeValue = match; - } else { - obj.themeValue = obj.value; - } + preserveOrder(a, b) { + return 1; + } + + transferDataSource() { + this.colorList.forEach((item) => { + if (this.dataSource.has(item.type)) { + this.dataSource.get(item.type).push(item); + } else { + this.dataSource.set(item.type, [item]); } }); - }; - - toggleExpand(rowItem, index) { - rowItem.expand = !rowItem.expand; - if (rowItem.expand) { - const insertItems = this.colorSource.filter((color) => color.type === rowItem.type); - this.catalogs.splice(index + 1, 0, ...insertItems); - } else { - const itemLength = this.colorSource.filter((color) => color.type === rowItem.type).length; - this.catalogs.splice(index + 1, itemLength); - } } setI18n() { this.subs.add( this.translate.get('components.design-color.colorDemo.instance').subscribe((res) => { - this.setValues(res); + this.i18nText = res['colorSource']; }) ); this.subs.add( this.translate.onLangChange.subscribe((event: TranslationChangeEvent) => { const values = this.translate.instant('components.design-color.colorDemo.instance'); - this.setValues(values); + this.i18nText = values['colorSource']; }) ); } - setValues(values) { - this.tableNameList = []; - Object.values(values.catalogsList).forEach(item => { - this.tableNameList.push(item); - }); - - this.colorSource = [ - { - type: 'background', - name: '$devui-global-bg', - description: values.colorSource['devui-global-bg'] - }, - { - type: 'background', - name: '$devui-global-bg-normal', - description: values.colorSource['devui-global-bg-normal'], - }, - { - type: 'background', - name: '$devui-base-bg', - description: values.colorSource['devui-global-bg-normal'], - }, - { - type: 'background', - name: '$devui-base-bg-dark', - description: values.colorSource['devui-base-bg-dark'], - }, - { type: 'theme', name: '$devui-brand', light: '#5e7ce0', dark: '#5e7ce0', description: values.colorSource['devui-brand'] }, - { type: 'theme', name: '$devui-brand-foil', light: '#859bff', dark: '#313a61', description: values.colorSource['devui-brand-foil'] }, - { - type: 'theme', - name: '$devui-brand-hover', - description: values.colorSource['devui-brand-hover'], - }, - { - type: 'theme', - name: '$devui-brand-active', - description: values.colorSource['devui-brand-active'], - }, - { - type: 'theme', - name: '$devui-brand-active-focus', - description: values.colorSource['devui-brand-active-focus'], - }, - { type: 'theme', name: '$devui-contrast', description: values.colorSource['devui-contrast'] }, - { type: 'text', name: '$devui-text', description: values.colorSource['devui-text'] }, - { type: 'text', name: '$devui-text-weak', description: values.colorSource['devui-text-weak'] }, - { type: 'text', name: '$devui-aide-text', description: values.colorSource['devui-aide-text'] }, - { - type: 'text', - name: '$devui-aide-text-hover', - description: values.colorSource['devui-aide-text-hover'], - }, - { - type: 'text', - name: '$devui-aide-text-stress', - description: values.colorSource['devui-aide-text-stress'], - }, - { - type: 'text', - name: '$devui-placeholder', - description: values.colorSource['devui-placeholder'], - }, - { type: 'text', name: '$devui-light-text', description: values.colorSource['devui-light-text'] }, - { type: 'text', name: '$devui-dark-text', description: values.colorSource['devui-dark-text'] }, - { type: 'text', name: '$devui-link', description: values.colorSource['devui-link'] }, - { - type: 'text', - name: '$devui-link-active', - description: values.colorSource['devui-link-active'], - }, - { type: 'text', name: '$devui-link-light', description: values.colorSource['devui-link-light'] }, - { - type: 'text', - name: '$devui-link-light-active', - description: values.colorSource['devui-link-light-active'], - }, - { type: 'border', name: '$devui-line', description: values.colorSource['devui-line'] }, - { - type: 'border', - name: '$devui-dividing-line', - description: values.colorSource['devui-dividing-line'], - }, - { type: 'background', name: '$devui-block', description: values.colorSource['devui-block'] }, - { type: 'background', name: '$devui-area', description: values.colorSource['devui-area'] }, - { type: 'status', name: '$devui-danger', description: values.colorSource['devui-danger'] }, - { type: 'status', name: '$devui-warning', description: values.colorSource['devui-warning'] }, - { type: 'status', name: '$devui-waiting', description: values.colorSource['devui-waiting'] }, - { type: 'status', name: '$devui-success', description: values.colorSource['devui-success'] }, - { type: 'status', name: '$devui-info', description: values.colorSource['devui-info'] }, - { type: 'status', name: '$devui-initial', description: values.colorSource['devui-initial'] }, - { - type: 'status', - name: '$devui-unavailable', - description: values.colorSource['devui-unavailable'], - }, - { - type: 'status', - name: '$devui-shadow', - description: values.colorSource['devui-shadow'], - }, - { - type: 'status', - name: '$devui-light-shadow', - description: values.colorSource['devui-light-shadow'], - }, - - { type: 'text', name: '$devui-icon-text', description: values.colorSource['devui-icon-text'] }, - { type: 'background', name: '$devui-icon-bg', description: values.colorSource['devui-icon-bg'] }, - { type: 'status', name: '$devui-icon-fill', description: values.colorSource['devui-icon-fill'] }, - { - type: 'status', - name: '$devui-icon-fill-hover', - description: values.colorSource['devui-icon-fill-hover'], - }, - { - type: 'status', - name: '$devui-icon-fill-active', - description: values.colorSource['devui-icon-fill-active'], - }, - { - type: 'status', - name: '$devui-icon-fill-active-hover', - description: values.colorSource['evui-icon-fill-active-hover'], - }, - - { - type: 'border', - name: '$devui-form-control-line', - description: values.colorSource['devui-form-control-line'], - }, - { - type: 'border', - name: '$devui-form-control-line-hover', - description: values.colorSource['devui-form-control-line-hover'], - }, - { - type: 'border', - name: '$devui-form-control-line-active', - description: values.colorSource['devui-form-control-line-active'], - }, - { - type: 'border', - name: '$devui-form-control-line-active-hover', - description: values.colorSource['devui-form-control-line-active-hover'], - }, - - { - type: 'background', - name: '$devui-list-item-active-bg', - description: values.colorSource['devui-list-item-active-bg'], - }, - { - type: 'text', - name: '$devui-list-item-active-text', - description: values.colorSource['devui-list-item-active-text'], - }, - { - type: 'background', - name: '$devui-list-item-active-hover-bg', - description: values.colorSource['devui-list-item-active-hover-bg'], - }, - { - type: 'background', - name: '$devui-list-item-hover-bg', - description: values.colorSource['$devui-list-item-hover-bg'], - }, - { - type: 'text', - name: '$devui-list-item-hover-text', - description: values.colorSource['devui-list-item-hover-text'], - }, - { - type: 'background', - name: '$devui-list-item-selected-bg', - description: values.colorSource['devui-list-item-selected-bg'], - }, - { - type: 'background', - name: '$devui-list-item-strip-bg', - description: values.colorSource['devui-list-item-strip-bg'], - }, - - { - type: 'background', - name: '$devui-disabled-bg', - description: values.colorSource['devui-disabled-bg'], - }, - { - type: 'border', - name: '$devui-disabled-line', - description: values.colorSource['devui-disabled-line'], - }, - { - type: 'text', - name: '$devui-disabled-text', - description: values.colorSource['devui-disabled-text'], - }, - { - type: 'text', - name: '$devui-primary-disabled', - description: values.colorSource['devui-primary-disabled'], - }, - { - type: 'status', - name: '$devui-icon-fill-active-disabled', - description: values.colorSource['devui-icon-fill-active-disabled'], - }, - - { - type: 'background', - name: '$devui-label-bg', - description: values.colorSource['devui-label-bg'], - }, - { - type: 'background', - name: '$devui-connected-overlay-bg', - description: values.colorSource['devui-connected-overlay-bg'], - }, - { - type: 'border', - name: '$devui-connected-overlay-line', - description: values.colorSource['devui-connected-overlay-line'], - }, - { - type: 'background', - name: '$devui-fullscreen-overlay-bg', - description: values.colorSource['devui-fullscreen-overlay-bg'], - }, - { - type: 'background', - name: '$devui-feedback-overlay-bg', - description: values.colorSource['devui-feedback-overlay-bg'], - }, - { - type: 'text', - name: '$devui-feedback-overlay-text', - description: values.colorSource['devui-feedback-overlay-text'], - }, - { - type: 'background', - name: '$devui-embed-search-bg', - description: values.colorSource['devui-embed-search-bg'], - }, - { - type: 'background', - name: '$devui-embed-search-bg-hover', - description: values.colorSource['devui-embed-search-bg-hover'], - }, - { - type: 'background', - name: '$devui-float-block-shadow', - description: values.colorSource['devui-float-block-shadow'], - }, - { - type: 'background', - name: '$devui-highlight-overlay', - description: values.colorSource['devui-highlight-overlay'], - }, - { - type: 'background', - name: '$devui-range-item-hover-bg', - description: values.colorSource['devui-range-item-hover-bg'], - }, - - { type: 'status', name: '$devui-primary', light: '#5e7ce0', dark: '#5e7ce0', description: values.colorSource['devui-primary'] }, - { - type: 'status', - name: '$devui-primary-hover', - description: values.colorSource['devui-primary-hover'], - }, - { - type: 'status', - name: '$devui-primary-active', - description: values.colorSource['devui-primary-active'], - }, - { - type: 'status', - name: '$devui-contrast-hover', - description: values.colorSource['devui-contrast-hover'], - }, - { - type: 'status', - name: '$devui-contrast-active', - description: values.colorSource['devui-contrast-active'], - }, - - { - type: 'status', - name: '$devui-danger-line', - description: values.colorSource['devui-danger-line'], - }, - { type: 'status', name: '$devui-danger-bg', description: values.colorSource['devui-danger-bg'] }, - { - type: 'status', - name: '$devui-warning-line', - description: values.colorSource['devui-warning-line'], - }, - { type: 'status', name: '$devui-warning-bg', description: values.colorSource['devui-warning-bg'] }, - { type: 'status', name: '$devui-info-line', description: values.colorSource['devui-info-line'] }, - { type: 'status', name: '$devui-info-bg', description: values.colorSource['devui-info-bg'] }, - { - type: 'status', - name: '$devui-success-line', - description: values.colorSource['devui-success-line'], - }, - { type: 'status', name: '$devui-success-bg', description: values.colorSource['devui-success-bg'] }, - { - type: 'status', - name: '$devui-primary-line', - description: values.colorSource['devui-primary-line'], - }, - { type: 'status', name: '$devui-primary-bg', description: values.colorSource['devui-primary-bg'] }, - { - type: 'status', - name: '$devui-default-line', - description: values.colorSource['devui-default-line'], - }, - { type: 'status', name: '$devui-default-bg', description: values.colorSource['devui-default-bg'] }, - ]; - - this.catalogsList = [ - { name: values.catalogsList.theme, type: 'theme', expand: true }, - { name: values.catalogsList.text, type: 'text', expand: true }, - { name: values.catalogsList.border, type: 'border', expand: true }, - { name: values.catalogsList.background, type: 'background', expand: true }, - { name: values.catalogsList.status, type: 'status', expand: true }, - ]; - - this.colors = [ - { name: '$global-bg', newName: '$devui-global-bg', description: values.colors['global-bg'] }, - { name: '$bg-white', newName: '$devui-base-bg', description: values.colors['bg-white'] }, - { - name: '$base-bg-white', - newName: '$devui-global-bg-normal', - description: values.colors['base-bg-white'], - }, - { name: '$block-bg-white', newName: '$devui-block', description: values.colors['block-bg-white'] }, - { name: '$brand-1', newName: '$devui-brand', description: values.colors['brand-1'] }, - { name: '$brand-2', newName: '$devui-brand-active-focus', description: values.colors['brand-2'] }, - { - name: '$brand-3', - newName: '$devui-list-item-selected-bg', - description: values.colors['brand-3'], - }, - { name: '$brand-4', newName: '$devui-brand-foil', description: values.colors['brand-4'] }, - - { name: '$dark-1', newName: '$devui-text', description: values.colors['dark-1'] }, - { name: '$dark-2', newName: '$devui-aide-text', description: values.colors['dark-2'] }, - { name: '$dark-3', newName: '$devui-placeholder', description: values.colors['dark-3'] }, - { - name: '$dark-1-boxshadow-light', - newName: '$devui-light-shadow', - description: values.colors['dark-1-boxshadow-light'], - }, - { - name: '$dark-1-boxshadow', - newName: '$devui-shadow', - description: values.colors['dark-1-boxshadow'], - }, - { name: '$dark-1-3', newName: '废弃', light: '#252b3a', dark: '#d1d4da', description: values.colors['dark-1-3'] }, - { name: '$dividing', newName: '$devui-dividing-line', description: values.colors['dividing'] }, - { - name: '$dropdown-overlay', - newName: '$devui-connected-overlay-bg', - light: '#ffffff', - dark: '#2F2F2F', - description: values.colors['dropdown-overlay'], - }, - { name: '$font-dark', newName: '$devui-dark-text', description: values.colors['font-dark'] }, - { name: '$font-white', newName: '$devui-light-text', description: values.colors['font-white'] }, - { - name: '$full-screen-overlay', - newName: '$devui-fullscreen-overlay-bg', - light: '#ffffff', - dark: '#4C4C4C', - description: values.colors['full-screen-overlay'], - }, - { name: '$gray-1', newName: '$devui-line', description: values.colors['gray-1'] }, - { name: '$gray-2', newName: '$devui-dividing-line', description: values.colors['gray-2'] }, - { name: '$gray-3', newName: '$devui-area', description: values.colors['gray-3'] }, - { - name: '$highlight-overlay', - newName: '$devui-highlight-overlay', - description: values.colors['highlight-overlay'], - }, - { - name: '$hover-control', - newName: '$devui-brand-active', - description: values.colors['hover-control'], - }, - { - name: '$hover-control-light', - newName: '$devui-link-light-active', - description: values.colors['hover-control-light'], - }, - { - name: '$hover-content', - newName: '$devui-list-item-hover-bg', - description: values.colors['hover-content'], - }, - { name: '$huawei-bg', newName: '$devui-base-bg-dark', description: values.colors['huawei-bg'] }, - { name: '$huawei-red', newName: '$devui-contrast', description: values.colors['huawei-red'] }, - { name: '$icon-gray-bg', newName: '$devui-icon-fill', description: values.colors['icon-gray-bg'] }, - { name: '$link', newName: '$devui-link', description: values.colors['link'] }, - { name: '$link-light', newName: '$devui-link-light', description: values.colors['link-light'] }, - { name: '$status-red', newName: '$devui-danger', description: values.colors['status-red'] }, - { name: '$status-yellow', newName: '$devui-warning', description: values.colors['status-yellow'] }, - { - name: '$status-waiting', - newName: '$devui-waiting', - description: values.colors['status-waiting'], - }, - { name: '$status-green', newName: '$devui-success', description: values.colors['status-green'] }, - { name: '$status-blue', newName: '$devui-info', description: values.colors['status-blue'] }, - { - name: '$status-initial', - newName: '$devui-initial', - description: values.colors['status-initial'], - }, - { - name: '$status-unavaliable', - newName: '$devui-unavailable', - description: values.colors['status-unavaliable'], - }, - { - name: '$strip-color', - newName: '$devui-list-item-strip-bg', - description: values.colors['strip-color'], - }, - { - name: '$tag-label-bgcolor', - newName: '$devui-label-bg', - description: values.colors['tag-label-bgcolor'], - }, - { - name: '$hwc-status-danger-border', - newName: '$devui-danger-line', - description: values.colors['hwc-status-danger-border'], - }, - { - name: '$hwc-status-danger-background', - newName: '$devui-danger-bg', - description: values.colors['hwc-status-danger-background'], - }, - { - name: '$hwc-status-warning-border', - newName: '$devui-warning-line', - description: values.colors['hwc-status-warning-border'], - }, - { - name: '$hwc-status-warning-background', - newName: '$devui-warning-bg', - description: values.colors['hwc-status-warning-background'], - }, - { - name: '$hwc-status-info-border', - newName: '$devui-info-line', - description: values.colors['hwc-status-info-border'], - }, - { - name: '$hwc-status-info-background', - newName: '$devui-info-bg', - description: values.colors['hwc-status-info-background'], - }, - { - name: '$hwc-status-success-border', - newName: '$devui-success-line', - description: values.colors['hwc-status-success-border'], - }, - { - name: '$hwc-status-success-background', - newName: '$devui-success-bg', - description: values.colors['hwc-status-success-background'], - }, - { - name: '$hwc-feedback-overlay-background', - newName: '$devui-feedback-overlay-bg', - description: values.colors['hwc-feedback-overlay-background'], - }, - { - name: '$hwc-feedback-overlay-font-color', - newName: '$devui-feedback-overlay-text', - description: values.colors['hwc-feedback-overlay-font-color'], - }, - { - name: '$color-bg-primary', - newName: '$devui-primary', - description: values.colors['color-bg-primary'], - }, - { - name: '$color-bg-primary-hover', - newName: '$devui-primary-hover', - description: values.colors['color-bg-primary-hover'], - }, - { - name: '$color-bg-primary-active', - newName: '$devui-primary-active', - description: values.colors['color-bg-primary-active'], - }, - { - name: '$hwc-drop-down-search', - newName: '$devui-embed-search-bg', - description: values.colors['hwc-drop-down-search'], - }, - { - name: '$hwc-drop-down-search-hover', - newName: '$devui-embed-search-bg-hover', - description: values.colors['hwc-drop-down-search-hover'], - }, - { name: '$disabled-bg', newName: '$devui-disabled-bg', description: values.colors['disabled-bg'] }, - { - name: '$disabled-border', - newName: '$devui-disabled-line', - description: values.colors['disabled-border'], - }, - { - name: '$disabled-content', - newName: '$devui-disabled-text', - description: values.colors['disabled-content'], - }, - ]; - - this.colorList = [ - ['#f2f5fc', '#e9edfa', '#beccfa', '#96adfa', '#7693f5', '#5e7ce0', '#526ecc', '#465eb8', '#3c51a6', '#344899', '#2a3c85'], - ['#ebf6ff', '#d1ebff', '#b8e0ff', '#9ed5ff', '#85caff', '#6cbfff', '#4ea6e6', '#3590cc', '#207ab3', '#0f6999', '#035880'], - ['#edfff9', '#cffcee', '#acf2dc', '#8be8cb', '#6ddebb', '#50d4ab', '#3ac295', '#27b080', '#169e6c', '#088c58', '#007a45'], - ['#f0ffe6', '#e5ffd4', '#d8fcc0', '#c5f2a7', '#b3e890', '#a6dd82', '#92cc68', '#7eba50', '#6ca83b', '#5e9629', '#518519'], - ['#fffbf0', '#fff1c2', '#ffe794', '#ffdc66', '#ffd138', '#fac20a', '#e3aa00', '#cc9600', '#b58200', '#9e6f00', '#875c00'], - ['#fff3e8', '#ffe1c7', '#ffd0a6', '#ffbf85', '#ffad63', '#fa9841', '#e37d29', '#cc6414', '#b54e04', '#9e3f00', '#873400'], - ['#ffeeed', '#ffd5d4', '#ffbcba', '#ffa4a1', '#ff8b87', '#f66f6a', '#de504e', '#c73636', '#b02121', '#991111', '#820404'], - ['#ffedf3', '#ffd4e3', '#ffbad2', '#ffa1c2', '#fc86b0', '#f3689a', '#db4d83', '#c4356e', '#ad215b', '#96114d', '#800440'], - ['#f5f0ff', '#e7d9ff', '#d8c2ff', '#caabff', '#bc94ff', '#a97af8', '#8a5ce0', '#6f42c9', '#572db3', '#3f1a9c', '#2a0c85'], - ]; - - this.generateColorData(); - this.setDataList(); - } - - generateColorData() { - const lightData = devuiLightTheme.data; - const darkData = devuiDarkTheme.data; - this.colorSource.forEach((item) => { - const colorName = item.name.slice(1); - item.light = lightData[colorName]; - item.dark = darkData[colorName]; - }); - this.colors.forEach((item) => { - if(item.newName !== '废弃') { - const colorName = item.newName.slice(1); - item.light = lightData[colorName]; - item.dark = darkData[colorName]; - } - }); - } - - setDataList() { - if(this.activeTab === 'tab1') { - const result = []; - this.tableList = []; - this.catalogsList.forEach((catalog, catalogIndex) => { - if (catalog.expand && !Object.prototype.hasOwnProperty.call( - this.catalogsList[catalogIndex + 1] || {}, 'description')) { - const insertItems = this.colorSource.filter((color) => color.type === catalog.type); - this[`${insertItems[0].type}ColorSource`] = insertItems; - this.tableList.push(this[`${insertItems[0].type}ColorSource`]); - result.push(this[`${insertItems[0].type}ColorSource`]); - } - }); - this.catalogs = result; - } - if (this.themeService) { - this.changeValueInTable(); - } - } - ngOnDestroy() { if (this.subs) { this.subs.unsubscribe(); diff --git a/devui/design-token/font/demo/font/font.component.html b/devui/design-token/font/demo/font/font.component.html index 6c0ec9f8..f898f36e 100644 --- a/devui/design-token/font/demo/font/font.component.html +++ b/devui/design-token/font/demo/font/font.component.html @@ -8,45 +8,15 @@

{{ 'components.design-font.fontDemo.instance.title' |

{{ 'components.design-font.fontDemo.instance.tableTitle' | translate }}

- - - - - - - - - - - - - - - - - - - - - - + + + + + + + + diff --git a/devui/design-token/font/demo/font/font.component.ts b/devui/design-token/font/demo/font/font.component.ts index 81b55657..60eae245 100644 --- a/devui/design-token/font/demo/font/font.component.ts +++ b/devui/design-token/font/demo/font/font.component.ts @@ -1,9 +1,13 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ThemeService } from 'ng-devui/theme'; import { TranslateService, TranslationChangeEvent } from '@ngx-translate/core'; -import { cloneDeep } from 'lodash-es'; import { Subscription } from 'rxjs'; +export interface fontItemConfig { + name: string; + value: string; + description: string; +} @Component({ selector: 'd-font', templateUrl: './font.component.html', @@ -13,105 +17,50 @@ export class FontComponent implements OnInit, OnDestroy { themeService: ThemeService; subs: Subscription = new Subscription(); fonts = []; + i18nText: any; + fontKey = ['devui-font-size', 'devui-font-content-weight', 'devui-line-height']; - oldFonts = []; - - activeTab: string | number = 'curFont'; - - constructor(private translate: TranslateService) {} + constructor(private translate: TranslateService) { this.setI18n(); } ngOnInit() { if (typeof window !== undefined) { this.themeService = window['devuiThemeService']; + this.changeValueInTable(); if (this.themeService.eventBus) { this.themeService.eventBus.add('themeChanged', this.changeValueInTable); } - this.setI18n(); } } changeValueInTable = () => { const theme = this.themeService.currentTheme; - this.fonts.map((obj) => { - const nameArr = obj.name.split('$'); - if (nameArr.length === 2) { - const match = theme.data[nameArr[1]]; - if (match) { - obj.themeValue = match; - } else { - obj.themeValue = obj.value; - } + for (const key in theme.data) { + if (this.fontKey.some(item => key.includes(item))) { + const obj = { + name: '$' + key, + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.fonts.push(obj); } - }); - this.fonts = cloneDeep(this.fonts); + } }; setI18n() { this.subs.add( this.translate.get('components.design-font.fontDemo.instance').subscribe((res) => { - this.setValues(res); + this.i18nText = res['fonts']; }) ); this.subs.add( this.translate.onLangChange.subscribe((event: TranslationChangeEvent) => { const values = this.translate.instant('components.design-font.fontDemo.instance'); - this.setValues(values); + this.i18nText = values['fonts']; }) ); } - setValues(values) { - this.fonts = [ - { name: '$devui-font-size-data-overview', value: '24px', description: values.fonts['devui-font-size-data-overview'] }, - { name: '$devui-font-size-price', value: '20px', description: values.fonts['devui-font-size-price'] }, - { name: '$devui-font-size-modal-title', value: '18px', description: values.fonts['devui-font-size-modal-title'] }, - { name: '$devui-font-size-page-title', value: '16px', description: values.fonts['devui-font-size-page-title'] }, - { name: '$devui-font-size-card-title', value: '14px', description: values.fonts['devui-font-size-card-title'] }, - { name: '$devui-font-size', value: '12px', description: values.fonts['devui-font-size'] }, - { name: '$devui-font-size-icon', value: '16px', description: values.fonts['devui-font-size-icon'] }, - { name: '$devui-font-size-sm', value: '12px', description: values.fonts['devui-font-size-sm'] }, - { name: '$devui-font-size-md', value: '12px', description: values.fonts['devui-font-size-md'] }, - { name: '$devui-font-size-lg', value: '14px', description: values.fonts['devui-font-size-lg'] }, - { name: '$devui-font-title-weight', value: 'bold', description: values.fonts['devui-font-title-weight'] }, - { name: '$devui-font-content-weight', value: 'normal', description: values.fonts['devui-font-content-weight'] }, - { name: '$devui-line-height-base', value: '1.5', description: values.fonts['devui-line-height-base'] }, - ]; - - this.oldFonts = [ - { - name: '$font-size-modal-title', - newName: '$devui-font-size-modal-title', - value: '18px', - description: values.oldFonts['font-size-modal-title'], - }, - { - name: '$font-size-primary', - newName: '$devui-font-size-page-title', - value: '16px', - description: values.oldFonts['font-size-primary'], - }, - { - name: '$font-size-secondary-card-title', - newName: '$devui-font-size-card-title', - value: '14px', - description: values.oldFonts['font-size-secondary-card-title'], - }, - { name: '$font-size-base', value: '12px', newName: '$devui-font-size', description: values.oldFonts['font-size-base'] }, - { name: '$font-title-weight', value: 'bold', newName: '$devui-font-title-weight', description: values.oldFonts['font-title-weight'] }, - { - name: '$font-content-weight', - value: 'normal', - newName: '$devui-font-content-weight', - description: values.oldFonts['font-content-weight'], - }, - { name: '$line-height-base', value: '1.5', newName: '$devui-line-height-base', description: values.oldFonts['line-height-base'] }, - ]; - - if (this.themeService) { - this.changeValueInTable(); - } - } ngOnDestroy() { if (this.subs) { diff --git a/devui/design-token/shadow/demo/shadow/shadow.component.html b/devui/design-token/shadow/demo/shadow/shadow.component.html index 1a73d524..ca810c07 100644 --- a/devui/design-token/shadow/demo/shadow/shadow.component.html +++ b/devui/design-token/shadow/demo/shadow/shadow.component.html @@ -3,64 +3,33 @@

{{ 'components.design-shadow.shadowDemo.instance.titl box-shadow: $devui-shadow-length-base $devui-shadow;

{{ 'components.design-shadow.shadowDemo.instance.description' | translate }}

- - - - - - - - - - - - - - - - - - - - - - + + + + + + + + +

{{ 'components.design-shadow.shadowDemo.instance.description2' | translate }}

- - @@ -71,21 +40,9 @@

{{ 'components.design-shadow.shadowDemo.instance.desc

- - diff --git a/devui/design-token/shadow/demo/shadow/shadow.component.ts b/devui/design-token/shadow/demo/shadow/shadow.component.ts index be3bf90e..5e15f688 100644 --- a/devui/design-token/shadow/demo/shadow/shadow.component.ts +++ b/devui/design-token/shadow/demo/shadow/shadow.component.ts @@ -1,7 +1,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { devuiDarkTheme, devuiLightTheme, ThemeService } from 'ng-devui/theme'; +import { ThemeService } from 'ng-devui/theme'; import { TranslateService, TranslationChangeEvent } from '@ngx-translate/core'; -import { cloneDeep } from 'lodash-es'; import { Subscription } from 'rxjs'; @Component({ @@ -13,211 +12,64 @@ export class ShadowComponent implements OnInit, OnDestroy { themeService: ThemeService; subs: Subscription = new Subscription(); shadows = []; - oldShadows = []; shadowColor = []; + shadowKey = ['devui-shadow-length']; + shadowColorKey = ['shadow']; + i18nText: any; - activeTab: string | number = 'curShadow'; - - constructor(private translate: TranslateService) {} + constructor(private translate: TranslateService) { this.setI18n(); } ngOnInit() { if (typeof window !== undefined) { this.themeService = window['devuiThemeService']; + this.changeValueInTable(); if (this.themeService.eventBus) { this.themeService.eventBus.add('themeChanged', this.changeValueInTable); } - this.setI18n(); + } } changeValueInTable = () => { - this.changeValue('shadows'); - this.changeValue('shadowColor'); - }; - - changeValue(type) { const theme = this.themeService.currentTheme; - this[type].map((obj) => { - const nameArr = obj.name.split('$'); - if (nameArr.length === 2) { - const match = theme.data[nameArr[1]]; - if (match) { - obj.themeValue = match; - } else { - obj.themeValue = obj.value; + for (const key in theme.data) { + if (Object.prototype.hasOwnProperty.call(theme.data, key)) { + if (this.shadowKey.some(item => key.includes(item))) { + const obj = { + name: '$' + key, + value: theme.data[key], + description: this.i18nText ? this.i18nText['shadows'][key] : '' + }; + this.shadows.push(obj); + } + if (this.shadowColorKey.some(item => key.includes(item)) && theme.data[key].startsWith('rgba')) { + const obj = { + name: '$' + key, + value: theme.data[key], + description: this.i18nText ? this.i18nText['shadowColor'][key] : '' + }; + this.shadowColor.push(obj); } } - }); - this[type] = cloneDeep(this[type]); - } + + } + }; setI18n() { this.subs.add( this.translate.get('components.design-shadow.shadowDemo.instance').subscribe((res) => { - this.setValues(res); + this.i18nText = res; }) ); this.subs.add( this.translate.onLangChange.subscribe((event: TranslationChangeEvent) => { const values = this.translate.instant('components.design-shadow.shadowDemo.instance'); - this.setValues(values); + this.i18nText = values; }) ); } - setValues(values) { - this.shadows = [ - { - name: '$devui-shadow-length-base', - value: devuiLightTheme.data['devui-shadow-length-base'], - description: values.shadows['devui-shadow-length-base'] - }, - { - name: '$devui-shadow-length-slide-left', - value: devuiLightTheme.data['devui-shadow-length-slide-left'], - description: values.shadows['devui-shadow-length-slide-left'] - }, - { - name: '$devui-shadow-length-slide-right', - value: devuiLightTheme.data['devui-shadow-length-slide-right'], - description: values.shadows['devui-shadow-length-slide-right'] - }, - { - name: '$devui-shadow-length-connected-overlay', - value: devuiLightTheme.data['devui-shadow-length-connected-overlay'], - description: values.shadows['devui-shadow-length-connected-overlay'], - }, - { - name: '$devui-shadow-length-hover', - value: devuiLightTheme.data['devui-shadow-length-hover'], - description: values.shadows['devui-shadow-length-hover'] - }, - { - name: '$devui-shadow-length-feedback-overlay', - value: devuiLightTheme.data['devui-shadow-length-feedback-overlay'], - description: values.shadows['devui-shadow-length-feedback-overlay'], - }, - { - name: '$devui-shadow-length-fullscreen-overlay', - value: devuiLightTheme.data['devui-shadow-length-fullscreen-overlay'], - description: values.shadows['devui-shadow-length-fullscreen-overlay'], - }, - ]; - - this.oldShadows = [ - { - name: '$hwc-shadow-1', - newName: '$devui-shadow-length-base $devui-light-shadow', - value: '0 1px 3px 0 rbga(0, 0, 0, 0.1)', - description: values.oldShadows['hwc-shadow-1'], - }, - { - name: '$hwc-shadow-2', - newName: '$devui-shadow-length-connected-overlay $devui-shadow', - value: '0 2px 5px 0 rgba(0, 0, 0, 0.2)', - description: values.oldShadows['hwc-shadow-2'], - }, - { - name: '$hwc-shadow-3', - newName: '$devui-shadow-length-feedback-overlay $devui-shadow', - value: '0 4px 8px 0 rgba(0, 0, 0, 0.2)', - description: values.oldShadows['hwc-shadow-3'], - }, - { - name: '$hwc-shadow-4', - newName: '$devui-shadow-length-hover $devui-shadow', - value: '0 2px 8px 0 rgba(94, 124, 224, 0.3)', - description: values.oldShadows['hwc-shadow-4'], - }, - { - name: '$hwc-shadow-5', - newName: '$devui-shadow-length-connected-overlay $devui-light-shadow', - value: '0 0 6px 0 rgba(0, 0, 0, 0.1)', - description: values.oldShadows['hwc-shadow-5'], - }, - { - name: '$hwc-shadow-6', - newName: '$devui-shadow-length-base $devui-light-shadow', - value: '0 8px 6px -4px rgba(199, 54, 54, 0.4)', - description: values.oldShadows['hwc-shadow-6'], - }, - { - name: '$hwc-shadow-7', - newName: '$devui-shadow-length-fullscreen-overlay $devui-light-shadow', - value: '0 10px 40px 0 rgba(0, 0, 0, 0.1)', - description: values.oldShadows['hwc-shadow-7'], - }, - { - name: '$hwc-shadow-8', - newName: '$devui-shadow-length-base $devui-light-shadow', - value: '0 1px 2px 0 rgba(57, 71, 166, 0.5)', - description: values.oldShadows['hwc-shadow-8'], - }, - { - name: '$hwc-shadow-error', - newName: '$devui-shadow-length-base $devui-danger', - value: '0 1px 3px 0 rgba(199, 54, 54, 0.25)', - description: values.oldShadows['hwc-shadow-error'], - }, - { - name: '$hwc-shadow-warn', - newName: '$devui-shadow-length-base $devui-warning', - value: ' 0 1px 3px 0 rgba(204, 100, 20, 0.25)', - description: values.oldShadows['hwc-shadow-warn'], - }, - { - name: '$hwc-shadow-prompt', - newName: '$devui-shadow-length-base $devui-info', - value: '0 1px 3px 0 rgba(70, 94, 184, 0.25)', - description: values.oldShadows['hwc-shadow-prompt'], - }, - { - name: '$hwc-shadow-success', - newName: '$devui-shadow-length-base $devui-success', - value: '0 1px 3px 0 rgba(39, 176, 128, 0.25)', - description: values.oldShadows['hwc-shadow-success'], - }, - { - name: '$hwc-shadow-dark', - newName: '$devui-shadow-length-feedback-overlay $devui-shadow', - value: '0 5px 8px 0 rgba(70, 77, 110, 0.25)', - description: values.oldShadows['hwc-shadow-dark'], - }, - ]; - - this.shadowColor = [ - { - name: '$devui-shadow', - light: devuiLightTheme.data['devui-shadow'], - dark: devuiDarkTheme.data['devui-shadow'], - description: values.shadowColor['devui-shadow'], - }, - { - name: '$devui-light-shadow', - light: devuiLightTheme.data['devui-light-shadow'], - dark: devuiDarkTheme.data['devui-light-shadow'], - description: values.shadowColor['devui-light-shadow'], - }, - { - name: '$devui-connected-overlay-shadow', - light: devuiLightTheme.data['devui-connected-overlay-shadow'], - dark: devuiDarkTheme.data['devui-connected-overlay-shadow'], - description: values.shadowColor['devui-connected-overlay-shadow'], - }, - { - name: '$devui-feedback-overlay-shadow', - light: devuiLightTheme.data['devui-feedback-overlay-shadow'], - dark: devuiDarkTheme.data['devui-feedback-overlay-shadow'], - description: values.shadowColor['devui-feedback-overlay-shadow'], - } - ]; - - if (this.themeService) { - this.changeValueInTable(); - } - } - ngOnDestroy() { if (this.subs) { this.subs.unsubscribe(); diff --git a/devui/design-token/z-index/demo/z-index/z-index.component.ts b/devui/design-token/z-index/demo/z-index/z-index.component.ts index 2310cf46..08a87d21 100644 --- a/devui/design-token/z-index/demo/z-index/z-index.component.ts +++ b/devui/design-token/z-index/demo/z-index/z-index.component.ts @@ -11,40 +11,49 @@ export class ZIndexComponent implements OnInit, OnDestroy { themeService: ThemeService; subs: Subscription = new Subscription(); zIndex = []; + i18nText: any; - constructor(private translate: TranslateService) { } + constructor(private translate: TranslateService) { this.setI18n(); } ngOnInit() { if (typeof window !== undefined) { - this.setI18n(); + if (typeof window !== undefined) { + this.themeService = window['devuiThemeService']; + this.changeValueInTable(); + if (this.themeService.eventBus) { + this.themeService.eventBus.add('themeChanged', this.changeValueInTable); + } + } } } setI18n() { this.subs.add( this.translate.get('components.design-z-index.ZIndexDemo.instance').subscribe((res) => { - this.setValues(res); + this.i18nText = res['zIndex']; }) ); this.subs.add( this.translate.onLangChange.subscribe((event: TranslationChangeEvent) => { const values = this.translate.instant('components.design-z-index.ZIndexDemo.instance'); - this.setValues(values); + this.i18nText = values['zIndex']; }) ); } - - setValues(values) { - this.zIndex = [ - { name: '$devui-z-index-full-page-overlay', value: '1080', description: values.zIndex['devui-z-index-full-page-overlay'] }, - { name: '$devui-z-index-pop-up', value: '1060', description: values.zIndex['devui-z-index-pop-up'] }, - { name: '$devui-z-index-dropdown', value: '1052', description: values.zIndex['devui-z-index-dropdown'] }, - { name: '$devui-z-index-modal', value: '1050', description: values.zIndex['devui-z-index-modal'] }, - { name: '$devui-z-index-drawer', value: '1040', description: values.zIndex['devui-z-index-drawer'] }, - { name: '$devui-z-index-framework', value: '1000', description: values.zIndex['devui-z-index-framework'] }, - ]; - } + changeValueInTable = () => { + const theme = this.themeService.currentTheme; + for (const key in theme.data) { + if (key.includes('devui-z-index')) { + const obj = { + name: '$' + key, + value: theme.data[key], + description: this.i18nText ? this.i18nText[key] : '' + }; + this.zIndex.push(obj); + } + } + }; ngOnDestroy() { if (this.subs) { diff --git a/devui/devui.module.ts b/devui/devui.module.ts index 577ce9c4..7dd02f2d 100755 --- a/devui/devui.module.ts +++ b/devui/devui.module.ts @@ -62,6 +62,7 @@ import { TransferModule } from 'ng-devui/transfer'; import { TreeModule } from 'ng-devui/tree'; import { TreeSelectModule } from 'ng-devui/tree-select'; import { UploadModule } from 'ng-devui/upload'; +import { UserGuideModule } from 'ng-devui/user-guide'; import { WindowRefModule } from 'ng-devui/window-ref'; export * from 'ng-devui/accordion'; export * from 'ng-devui/alert'; @@ -126,6 +127,7 @@ export * from 'ng-devui/transfer'; export * from 'ng-devui/tree'; export * from 'ng-devui/tree-select'; export * from 'ng-devui/upload'; +export * from 'ng-devui/user-guide'; export * from 'ng-devui/window-ref'; export * from './version'; @@ -178,6 +180,7 @@ export * from './version'; TimeAxisModule, TreeModule, UploadModule, + UserGuideModule, InputNumberModule, SliderModule, SplitterModule, diff --git a/devui/dragdrop/directives/drop-scroll-enhance.directive.ts b/devui/dragdrop/directives/drop-scroll-enhance.directive.ts index 3bcaaef6..d9d3bb26 100644 --- a/devui/dragdrop/directives/drop-scroll-enhance.directive.ts +++ b/devui/dragdrop/directives/drop-scroll-enhance.directive.ts @@ -193,7 +193,7 @@ export class DropScrollEnhancedDirective implements AfterViewInit, OnDestroy { createScrollArea(direction: DropScrollDirection, orientation: DropScrollOrientation) { const area = this.document.createElement('div'); - area.className = 'dropover-scroll-area ' + 'dropover-scroll-area-' + this.getCriticalEdge(direction, orientation); + area.className = `dropover-scroll-area dropover-scroll-area-${this.getCriticalEdge(direction, orientation)}`; // 处理大小 area.classList.add('active'); this.setAreaSize(area, direction, orientation); diff --git a/devui/dragdrop/directives/droppable.directive.ts b/devui/dragdrop/directives/droppable.directive.ts index 16d189dd..f323f8a1 100755 --- a/devui/dragdrop/directives/droppable.directive.ts +++ b/devui/dragdrop/directives/droppable.directive.ts @@ -613,7 +613,8 @@ export class DroppableDirective implements OnInit, AfterViewInit, OnDestroy { } private calcPositionOutside(event: any, targetElement: any) { - const rect = this.getBoundingRectAndRealPosition(targetElement); // targetElement.getBoundingClientRect(); + // targetElement 获取 getBoundingClientRect + const rect = this.getBoundingRectAndRealPosition(targetElement); const relY = event.clientY - (rect.y || rect.top); const relX = event.clientX - (rect.x || rect.left); diff --git a/devui/editable-select/demo/custom-area/custom-area.component.html b/devui/editable-select/demo/custom-area/custom-area.component.html new file mode 100644 index 00000000..4d1ec595 --- /dev/null +++ b/devui/editable-select/demo/custom-area/custom-area.component.html @@ -0,0 +1,18 @@ + + +
{{ (selectItem | json) || 'No language select' }}
+ + +
You hoverd {{ hoverItem }}
+
diff --git a/devui/editable-select/demo/custom-area/custom-area.component.scss b/devui/editable-select/demo/custom-area/custom-area.component.scss new file mode 100644 index 00000000..eda99b46 --- /dev/null +++ b/devui/editable-select/demo/custom-area/custom-area.component.scss @@ -0,0 +1,3 @@ +.custom-wrapper { + padding: 8px; +} diff --git a/devui/editable-select/demo/custom-area/custom-area.component.ts b/devui/editable-select/demo/custom-area/custom-area.component.ts new file mode 100644 index 00000000..fc920d65 --- /dev/null +++ b/devui/editable-select/demo/custom-area/custom-area.component.ts @@ -0,0 +1,35 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'd-editable-select-custom-area', + templateUrl: './custom-area.component.html', + styleUrls: ['./custom-area.component.scss'], +}) +export class CustomAreaComponent implements OnInit { + selectItem: any; + languages = [ + 'C#', + 'C', + 'C++', + 'CPython', + 'Java', + 'JavaScript', + 'Go', + 'Python', + 'Ruby', + 'F#', + 'TypeScript', + 'SQL', + 'LiveScript', + 'CoffeeScript', + ]; + hoverItem: any; + + constructor() {} + + ngOnInit(): void {} + + onHoverItem(event) { + this.hoverItem = event; + } +} diff --git a/devui/editable-select/demo/editable-select-demo.component.html b/devui/editable-select/demo/editable-select-demo.component.html index ac347082..b891c1f6 100755 --- a/devui/editable-select/demo/editable-select-demo.component.html +++ b/devui/editable-select/demo/editable-select-demo.component.html @@ -35,4 +35,14 @@ + +
+
{{ 'components.editable-select.customAreaDemo.title' | translate }}
+
+ {{ 'components.editable-select.customAreaDemo.description' | translate }} +
+ + + +
diff --git a/devui/editable-select/demo/editable-select-demo.component.ts b/devui/editable-select/demo/editable-select-demo.component.ts index e44dcc20..b871a127 100755 --- a/devui/editable-select/demo/editable-select-demo.component.ts +++ b/devui/editable-select/demo/editable-select-demo.component.ts @@ -9,6 +9,12 @@ import { Subscription } from 'rxjs'; styleUrls: ['./editable-select-demo.component.scss'], }) export class EditableSelectDemoComponent implements OnInit, OnDestroy { + customAreaSourceData: Array = [ + { title: 'HTML', language: 'xml', code: require('./custom-area/custom-area.component.html?raw') }, + { title: 'TS', language: 'typescript', code: require('./custom-area/custom-area.component.ts?raw') }, + { title: 'SCSS', language: 'scss', code: require('./custom-area/custom-area.component.scss?raw') }, + ]; + BasicSource: Array = [ { title: 'HTML', language: 'xml', code: require('./basic/with-source.component.html?raw') }, { title: 'TS', language: 'typescript', code: require('./basic/with-source.component.ts?raw') }, @@ -55,6 +61,7 @@ export class EditableSelectDemoComponent implements OnInit, OnDestroy { { dAnchorLink: 'with-search-function', value: values['with-search-function'] }, { dAnchorLink: 'async-data-with-function', value: values['async-data-with-function'] }, { dAnchorLink: 'lazy-load', value: values['lazy-load'] }, + { dAnchorLink: 'custom-area-usage', value: values['custom-area-usage'] }, ]; } diff --git a/devui/editable-select/demo/editable-select-demo.module.ts b/devui/editable-select/demo/editable-select-demo.module.ts index 755b3418..49683934 100755 --- a/devui/editable-select/demo/editable-select-demo.module.ts +++ b/devui/editable-select/demo/editable-select-demo.module.ts @@ -12,6 +12,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { DDemoNavModule } from 'devui-commons/src/demo-nav/d-demo-nav.module'; import { AsyncDataWithFunctionComponent } from './async-data-function/async-data-with-function.component'; import { WithSourceComponent } from './basic/with-source.component'; +import { CustomAreaComponent } from './custom-area/custom-area.component'; import { DisableDataWithSourceComponent } from './disable-data/disable-data-with-source.component'; import { EditableSelectDemoComponent } from './editable-select-demo.component'; import { LazyLoadComponent } from './lazy-load/lazy-load.component'; @@ -49,6 +50,7 @@ import { WithSearchFunctionComponent } from './search-function/with-search-funct WithSearchFunctionComponent, WithSourceComponent, LazyLoadComponent, + CustomAreaComponent, ], providers: [], }) diff --git a/devui/editable-select/editable-select.component.html b/devui/editable-select/editable-select.component.html index 7f4d54ee..679140c7 100755 --- a/devui/editable-select/editable-select.component.html +++ b/devui/editable-select/editable-select.component.html @@ -30,9 +30,12 @@ [formatter]="formatter" [valueParser]="valueParser" [showAnimation]="showAnimation" + [customViewTemplate]="customViewTemplate" + [customViewDirection]="customViewDirection" (toggleChange)="toggleChangeHandler($event)" (loadMore)="loadMoreEvent($event)" (selectValue)="selectValue()" + (hoverItem)="onHoverItem($event)" />
- + - - + + - + - - + + @@ -48,6 +52,7 @@ [content]="rowItem.$checkBoxTips" [position]="['top', 'right', 'bottom', 'left']" [showAnimation]="false" + (mouseup)="$event.stopPropagation()" >
{{ rowIndex + 1 }} + {{ colOption.fieldType === 'date' ? (rowItem[colOption.field] | i18nDate: 'short':false) : rowItem[colOption.field] }}
{{ colOption.header }}
+ {{ colOption.fieldType === 'date' ? (rowItem[colOption.field] | i18nDate: 'short':false) : rowItem[colOption.field] }} +
- - Create new data + + Create new data +
@@ -37,9 +38,9 @@
-
- - +
+ +
{{ rowIndex + 1 }}
{{ 'components.design-color.colorDemo.instance.defaultTable.colorVar' | translate }}{{ 'components.design-color.colorDemo.instance.defaultTable.themeValue' | translate }}{{ 'components.design-color.colorDemo.instance.defaultTable.description' | translate }}
-
- - -
-
{{ rowItem?.name }} -
- {{ rowItem?.themeValue }} -
-
-
{{ rowItem?.description }}
{{ 'components.design-color.colorDemo.instance.defaultTable.colorVar' | translate }}{{ 'components.design-color.colorDemo.instance.defaultTable.themeValue' | translate }}{{ 'components.design-color.colorDemo.instance.defaultTable.description' | translate }}
{{ rowItem?.name }} +
+ {{ rowItem?.value }}
- -
+
+
{{ rowItem?.description }}
{{ 'components.design-color.colorDemo.instance.defaultTable.colorVar' | translate }}{{ 'components.design-color.colorDemo.instance.defaultTable.normalColor' | translate }}{{ 'components.design-color.colorDemo.instance.defaultTable.darkColor' | translate }}{{ 'components.design-color.colorDemo.instance.defaultTable.themeValue' | translate }}{{ 'components.design-color.colorDemo.instance.defaultTable.description' | translate }}
-
- - -
-
{{ rowItem?.name }} -
- {{ rowItem?.light }} -
-
-
-
- {{ rowItem?.dark }} -
-
-
-
- {{ rowItem?.themeValue }} -
-
-
{{ rowItem?.description }}
{{ 'components.design-shadow.shadowDemo.instance.colorTable.colorVar' | translate }}{{ 'components.design-shadow.shadowDemo.instance.colorTable.normalColor' | translate }}{{ 'components.design-shadow.shadowDemo.instance.colorTable.darkColor' | translate }} {{ 'components.design-shadow.shadowDemo.instance.colorTable.themeValue' | translate }} {{ 'components.design-shadow.shadowDemo.instance.colorTable.description' | translate }}
{{ rowItem?.name }}
- {{ rowItem?.light }} -
-
-
-
- {{ rowItem?.dark }} -
-
-
-
- {{ rowItem?.themeValue }} + {{ rowItem?.value }}
-
+
{{ rowItem?.description }}