From 3c1cbd51dc67f9bab7a8339d32f4a6dbaf0d42b6 Mon Sep 17 00:00:00 2001 From: hyperlife1119 <hyperlife1119@qq.com> Date: Mon, 16 Sep 2024 22:25:16 +0800 Subject: [PATCH] feat(module:space): add space compact component --- components/button/button-group.component.ts | 3 + components/button/button.component.ts | 7 +- components/button/demo/button-group.md | 4 + components/cascader/cascader.component.ts | 3 + components/core/types/size.ts | 1 + .../date-picker/date-picker.component.ts | 3 + .../input-number/input-number.component.ts | 5 +- components/input/input.directive.ts | 5 +- components/select/select.component.ts | 5 +- .../space/demo/compact-button-vertical.md | 14 ++ .../space/demo/compact-button-vertical.ts | 25 +++ components/space/demo/compact-buttons.md | 14 ++ components/space/demo/compact-buttons.ts | 86 +++++++ components/space/demo/compact.md | 14 ++ components/space/demo/compact.ts | 210 ++++++++++++++++++ components/space/demo/module | 26 ++- components/space/doc/index.en-US.md | 20 +- components/space/doc/index.zh-CN.md | 20 +- components/space/public-api.ts | 7 +- .../space/space-compact-item.directive.ts | 61 +++++ components/space/space-compact-token.ts | 11 + components/space/space-compact.component.ts | 32 +++ components/space/space-item.directive.ts | 6 +- components/space/space.component.ts | 2 +- components/space/space.module.ts | 5 +- .../time-picker/time-picker.component.ts | 7 +- .../tree-select/tree-select.component.ts | 3 + 27 files changed, 580 insertions(+), 19 deletions(-) create mode 100644 components/space/demo/compact-button-vertical.md create mode 100644 components/space/demo/compact-button-vertical.ts create mode 100644 components/space/demo/compact-buttons.md create mode 100644 components/space/demo/compact-buttons.ts create mode 100644 components/space/demo/compact.md create mode 100644 components/space/demo/compact.ts create mode 100644 components/space/space-compact-item.directive.ts create mode 100644 components/space/space-compact-token.ts create mode 100644 components/space/space-compact.component.ts diff --git a/components/button/button-group.component.ts b/components/button/button-group.component.ts index e570abe2fea..a17a86a51db 100644 --- a/components/button/button-group.component.ts +++ b/components/button/button-group.component.ts @@ -10,6 +10,9 @@ import { takeUntil } from 'rxjs/operators'; export type NzButtonGroupSize = 'large' | 'default' | 'small'; +/** + * @deprecated Will be removed in v20. Use `NzSpaceCompactComponent` instead. + */ @Component({ selector: 'nz-button-group', exportAs: 'nzButtonGroup', diff --git a/components/button/button.component.ts b/components/button/button.component.ts index 5f00a05d685..34464ad42b8 100644 --- a/components/button/button.component.ts +++ b/components/button/button.component.ts @@ -27,6 +27,7 @@ import { filter, startWith, takeUntil } from 'rxjs/operators'; import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; import { NzIconDirective, NzIconModule } from 'ng-zorro-antd/icon'; +import { NZ_SPACE_COMPACT_ITEM_TYPE, NzSpaceCompactItemDirective } from 'ng-zorro-antd/space'; export type NzButtonType = 'primary' | 'default' | 'dashed' | 'link' | 'text' | null; export type NzButtonShape = 'circle' | 'round' | null; @@ -37,6 +38,8 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'button'; @Component({ selector: 'button[nz-button], a[nz-button]', exportAs: 'nzButton', + standalone: true, + imports: [NzIconModule], preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, @@ -67,8 +70,8 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'button'; '[attr.tabindex]': 'disabled ? -1 : (tabIndex === null ? null : tabIndex)', '[attr.disabled]': 'disabled || null' }, - imports: [NzIconModule], - standalone: true + hostDirectives: [NzSpaceCompactItemDirective], + providers: [{ provide: NZ_SPACE_COMPACT_ITEM_TYPE, useValue: 'btn' }] }) export class NzButtonComponent implements OnDestroy, OnChanges, AfterViewInit, AfterContentInit, OnInit { readonly _nzModuleName: NzConfigKey = NZ_CONFIG_MODULE_NAME; diff --git a/components/button/demo/button-group.md b/components/button/demo/button-group.md index 2f1368b5a95..fdd00a31be2 100755 --- a/components/button/demo/button-group.md +++ b/components/button/demo/button-group.md @@ -11,8 +11,12 @@ title: 通过设置 `nzSize` 为 `large` `small` 分别把按钮组合设为大、小尺寸。若不设置 `nzSize`,则尺寸为中。 +警告:在 v19.0.0 中被弃用,请使用 `<nz-space-compact>` 组件替代。 + ## en-US Buttons can be grouped by placing multiple `nz-button` components into a `nz-button-group`. The `nzSize` can be set to `large`, `small` or left unset resulting in a default size. + +Warning: Deprecated in v19.0.0, use `<nz-space-compact>` instead. diff --git a/components/cascader/cascader.component.ts b/components/cascader/cascader.component.ts index f2ae6654bd4..cc5557ada40 100644 --- a/components/cascader/cascader.component.ts +++ b/components/cascader/cascader.component.ts @@ -55,6 +55,7 @@ import { getStatusClassNames, toArray } from 'ng-zorro-antd/core/util'; import { NzEmptyModule } from 'ng-zorro-antd/empty'; import { NzCascaderI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n'; import { NzIconModule } from 'ng-zorro-antd/icon'; +import { NZ_SPACE_COMPACT_ITEM_TYPE, NzSpaceCompactItemDirective } from 'ng-zorro-antd/space'; import { NzCascaderOptionComponent } from './cascader-li.component'; import { NzCascaderService } from './cascader.service'; @@ -217,6 +218,7 @@ const defaultDisplayRender = (labels: string[]): string => labels.join(' / '); useExisting: forwardRef(() => NzCascaderComponent), multi: true }, + { provide: NZ_SPACE_COMPACT_ITEM_TYPE, useValue: 'select' }, NzCascaderService, NzDestroyService ], @@ -234,6 +236,7 @@ const defaultDisplayRender = (labels: string[]): string => labels.join(' / '); '[class.ant-select-single]': 'true', '[class.ant-select-rtl]': `dir === 'rtl'` }, + hostDirectives: [NzSpaceCompactItemDirective], imports: [ OverlayModule, FormsModule, diff --git a/components/core/types/size.ts b/components/core/types/size.ts index a816a7f03be..42a7bd022d1 100644 --- a/components/core/types/size.ts +++ b/components/core/types/size.ts @@ -5,5 +5,6 @@ // TODO: replace other size with this type. export type NzSizeLDSType = 'large' | 'default' | 'small'; +export type NzSizeLMSType = 'large' | 'middle' | 'small'; export type NzSizeMDSType = 'middle' | 'default' | 'small'; export type NzSizeDSType = 'default' | 'small'; diff --git a/components/date-picker/date-picker.component.ts b/components/date-picker/date-picker.component.ts index 5d2a28479dc..2d15d361056 100644 --- a/components/date-picker/date-picker.component.ts +++ b/components/date-picker/date-picker.component.ts @@ -69,6 +69,7 @@ import { NzI18nService } from 'ng-zorro-antd/i18n'; import { NzIconModule } from 'ng-zorro-antd/icon'; +import { NZ_SPACE_COMPACT_ITEM_TYPE, NzSpaceCompactItemDirective } from 'ng-zorro-antd/space'; import { DatePickerService } from './date-picker.service'; import { DateRangePopupComponent } from './date-range-popup.component'; @@ -249,9 +250,11 @@ export type NzPlacement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight'; '[class.ant-picker-inline]': `nzInline`, '(click)': 'onClickInputBox($event)' }, + hostDirectives: [NzSpaceCompactItemDirective], providers: [ NzDestroyService, DatePickerService, + { provide: NZ_SPACE_COMPACT_ITEM_TYPE, useValue: 'picker' }, { provide: NG_VALUE_ACCESSOR, multi: true, diff --git a/components/input-number/input-number.component.ts b/components/input-number/input-number.component.ts index 3bcf56cb5e5..a322ee757e7 100644 --- a/components/input-number/input-number.component.ts +++ b/components/input-number/input-number.component.ts @@ -44,6 +44,7 @@ import { } from 'ng-zorro-antd/core/types'; import { getStatusClassNames, isNotNil } from 'ng-zorro-antd/core/util'; import { NzIconModule } from 'ng-zorro-antd/icon'; +import { NZ_SPACE_COMPACT_ITEM_TYPE, NzSpaceCompactItemDirective } from 'ng-zorro-antd/space'; @Component({ selector: 'nz-input-number', @@ -97,6 +98,7 @@ import { NzIconModule } from 'ng-zorro-antd/icon'; useExisting: forwardRef(() => NzInputNumberComponent), multi: true }, + { provide: NZ_SPACE_COMPACT_ITEM_TYPE, useValue: 'input-number' }, NzDestroyService ], changeDetection: ChangeDetectionStrategy.OnPush, @@ -113,7 +115,8 @@ import { NzIconModule } from 'ng-zorro-antd/icon'; '[class.ant-input-number-borderless]': `nzBorderless` }, imports: [NzIconModule, FormsModule, NzFormPatchModule], - standalone: true + standalone: true, + hostDirectives: [NzSpaceCompactItemDirective] }) export class NzInputNumberComponent implements ControlValueAccessor, AfterViewInit, OnChanges, OnInit, OnDestroy { private autoStepTimer?: ReturnType<typeof setTimeout>; diff --git a/components/input/input.directive.ts b/components/input/input.directive.ts index 44c4868fda1..7a9cefccc10 100644 --- a/components/input/input.directive.ts +++ b/components/input/input.directive.ts @@ -25,6 +25,7 @@ import { distinctUntilChanged, filter, takeUntil } from 'rxjs/operators'; import { NzFormItemFeedbackIconComponent, NzFormNoStatusService, NzFormStatusService } from 'ng-zorro-antd/core/form'; import { NgClassInterface, NzSizeLDSType, NzStatus, NzValidateStatus } from 'ng-zorro-antd/core/types'; import { getStatusClassNames } from 'ng-zorro-antd/core/util'; +import { NZ_SPACE_COMPACT_ITEM_TYPE, NzSpaceCompactItemDirective } from 'ng-zorro-antd/space'; @Directive({ selector: 'input[nz-input],textarea[nz-input]', @@ -39,7 +40,9 @@ import { getStatusClassNames } from 'ng-zorro-antd/core/util'; '[class.ant-input-rtl]': `dir=== 'rtl'`, '[class.ant-input-stepperless]': `nzStepperless` }, - standalone: true + standalone: true, + hostDirectives: [NzSpaceCompactItemDirective], + providers: [{ provide: NZ_SPACE_COMPACT_ITEM_TYPE, useValue: 'input' }] }) export class NzInputDirective implements OnChanges, OnInit, OnDestroy { @Input({ transform: booleanAttribute }) nzBorderless = false; diff --git a/components/select/select.component.ts b/components/select/select.component.ts index ff5523ca6e0..14564411d60 100644 --- a/components/select/select.component.ts +++ b/components/select/select.component.ts @@ -58,6 +58,7 @@ import { OnTouchedType } from 'ng-zorro-antd/core/types'; import { getStatusClassNames, isNotNil } from 'ng-zorro-antd/core/util'; +import { NZ_SPACE_COMPACT_ITEM_TYPE, NzSpaceCompactItemDirective } from 'ng-zorro-antd/space'; import { NzOptionContainerComponent } from './option-container.component'; import { NzOptionGroupComponent } from './option-group.component'; @@ -95,7 +96,8 @@ export type NzSelectSizeType = 'large' | 'default' | 'small'; provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NzSelectComponent), multi: true - } + }, + { provide: NZ_SPACE_COMPACT_ITEM_TYPE, useValue: 'select' } ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, @@ -204,6 +206,7 @@ export type NzSelectSizeType = 'large' | 'default' | 'small'; '[class.ant-select-multiple]': `nzMode !== 'default'`, '[class.ant-select-rtl]': `dir === 'rtl'` }, + hostDirectives: [NzSpaceCompactItemDirective], imports: [ NzSelectTopControlComponent, CdkOverlayOrigin, diff --git a/components/space/demo/compact-button-vertical.md b/components/space/demo/compact-button-vertical.md new file mode 100644 index 00000000000..c6109d8d757 --- /dev/null +++ b/components/space/demo/compact-button-vertical.md @@ -0,0 +1,14 @@ +--- +order: 8 +title: + zh-CN: 垂直方向紧凑布局 + en-US: Vertical Compact Mode +--- + +## zh-CN + +垂直方向的紧凑布局,目前仅支持 Button 组合。 + +## en-US + +Vertical Mode for Space.Compact, support Button only. diff --git a/components/space/demo/compact-button-vertical.ts b/components/space/demo/compact-button-vertical.ts new file mode 100644 index 00000000000..c0d5e39c2cf --- /dev/null +++ b/components/space/demo/compact-button-vertical.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-space-compact-button-vertical', + template: ` + <nz-space> + <nz-space-compact *nzSpaceItem nzDirection="vertical"> + <button nz-button>Button 1</button> + <button nz-button>Button 2</button> + <button nz-button>Button 3</button> + </nz-space-compact> + <nz-space-compact *nzSpaceItem nzDirection="vertical"> + <button nz-button nzType="dashed">Button 1</button> + <button nz-button nzType="dashed">Button 2</button> + <button nz-button nzType="dashed">Button 3</button> + </nz-space-compact> + <nz-space-compact *nzSpaceItem nzDirection="vertical"> + <button nz-button nzType="primary">Button 1</button> + <button nz-button nzType="primary">Button 2</button> + <button nz-button nzType="primary">Button 3</button> + </nz-space-compact> + </nz-space> + ` +}) +export class NzDemoSpaceCompactButtonVerticalComponent {} diff --git a/components/space/demo/compact-buttons.md b/components/space/demo/compact-buttons.md new file mode 100644 index 00000000000..b89cef2f2e3 --- /dev/null +++ b/components/space/demo/compact-buttons.md @@ -0,0 +1,14 @@ +--- +order: 7 +title: + zh-CN: Button 紧凑布局 + en-US: Button Compact Mode +--- + +## zh-CN + +Button 组件紧凑排列的示例。 + +## en-US + +Button component compact example. diff --git a/components/space/demo/compact-buttons.ts b/components/space/demo/compact-buttons.ts new file mode 100644 index 00000000000..df6ba19a83f --- /dev/null +++ b/components/space/demo/compact-buttons.ts @@ -0,0 +1,86 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-space-compact-buttons', + template: ` + <nz-space-compact nzBlock> + <button nz-button nz-tooltip nzTooltipTitle="Like"> + <span nz-icon nzType="like"></span> + </button> + <button nz-button nz-tooltip nzTooltipTitle="Comment"> + <span nz-icon nzType="comment"></span> + </button> + <button nz-button nz-tooltip nzTooltipTitle="Star"> + <span nz-icon nzType="star"></span> + </button> + <button nz-button nz-tooltip nzTooltipTitle="Heart"> + <span nz-icon nzType="heart"></span> + </button> + <button nz-button nz-tooltip nzTooltipTitle="Share"> + <span nz-icon nzType="share-alt"></span> + </button> + <button nz-button nz-tooltip nzTooltipTitle="Download"> + <span nz-icon nzType="download"></span> + </button> + <nz-dropdown-menu #menu> + <ul nz-menu> + <li nz-menu-item> + <a>1st item</a> + </li> + <li nz-menu-item> + <a>2nd item</a> + </li> + <li nz-menu-item> + <a>3rd item</a> + </li> + </ul> + </nz-dropdown-menu> + <button nz-button nz-dropdown [nzDropdownMenu]="menu"> + <span nz-icon nzType="ellipsis"></span> + </button> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <button nz-button nzType="primary">Button 1</button> + <button nz-button nzType="primary">Button 2</button> + <button nz-button nzType="primary">Button 3</button> + <button nz-button nzType="primary">Button 4</button> + <button nz-button nzType="primary" disabled nz-tooltip nzTooltipTitle="Tooltip"> + <span nz-icon nzType="download"></span> + </button> + <button nz-button nzType="primary" nz-tooltip nzTooltipTitle="Tooltip"> + <span nz-icon nzType="download"></span> + </button> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <button nz-button>Button 1</button> + <button nz-button>Button 2</button> + <button nz-button>Button 3</button> + <button nz-button disabled nz-tooltip nzTooltipTitle="Tooltip"> + <span nz-icon nzType="download"></span> + </button> + <button nz-button nz-tooltip nzTooltipTitle="Tooltip"> + <span nz-icon nzType="download"></span> + </button> + <button nz-button nzType="primary">Button 4</button> + <nz-dropdown-menu #menu> + <ul nz-menu> + <li nz-menu-item> + <a>1st item</a> + </li> + <li nz-menu-item> + <a>2nd item</a> + </li> + <li nz-menu-item> + <a>3rd item</a> + </li> + </ul> + </nz-dropdown-menu> + <button nz-button nzType="primary" nz-dropdown [nzDropdownMenu]="menu"> + <span nz-icon nzType="ellipsis"></span> + </button> + </nz-space-compact> + ` +}) +export class NzDemoSpaceCompactButtonsComponent {} diff --git a/components/space/demo/compact.md b/components/space/demo/compact.md new file mode 100644 index 00000000000..b187aebad51 --- /dev/null +++ b/components/space/demo/compact.md @@ -0,0 +1,14 @@ +--- +order: 6 +title: + zh-CN: 紧凑布局组合 + en-US: Compact Mode +--- + +## zh-CN + +使用 `<nz-space-compact>` 让表单组件之间紧凑连接且合并边框。 + +## en-US + +Compact Mode for form component. diff --git a/components/space/demo/compact.ts b/components/space/demo/compact.ts new file mode 100644 index 00000000000..65f6da9e14a --- /dev/null +++ b/components/space/demo/compact.ts @@ -0,0 +1,210 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-space-compact', + template: ` + <nz-space-compact nzBlock> + <input nz-input value="0571" [style.width.%]="20" /> + <input nz-input value="26888888" [style.width.%]="30" /> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock nzSize="small"> + <input nz-input value="https://ng.ant.design" [style.width]="'calc(100% - 200px)'" /> + <button nz-button nzType="primary">Submit</button> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <input nz-input value="https://ng.ant.design" [style.width]="'calc(100% - 200px)'" /> + <button nz-button nzType="primary">Submit</button> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <input nz-input value="git@github.com:NG-ZORRO/ng-zorro-antd.git" [style.width]="'calc(100% - 200px)'" /> + <button nz-button nz-tooltip nzTooltipTitle="copy git url"> + <span nz-icon nzType="copy"></span> + </button> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <nz-select ngModel="Zhejianggggg"> + <nz-option nzLabel="Zhejianggggg" nzValue="Zhejianggggg"></nz-option> + <nz-option nzLabel="Jiangsu" nzValue="Jiangsu"></nz-option> + </nz-select> + <input nz-input value="Xihu District, Hangzhou" [style.width.%]="50" /> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <nz-select nzMode="multiple" [ngModel]="['Zhejianggggg']" [style.width.%]="50"> + <nz-option nzLabel="Zhejianggggg" nzValue="Zhejianggggg"></nz-option> + <nz-option nzLabel="Jiangsu" nzValue="Jiangsu"></nz-option> + </nz-select> + <input nz-input value="Xihu District, Hangzhou" [style.width.%]="50" /> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <nz-select ngModel="Option1"> + <nz-option nzLabel="Option1" nzValue="Option1"></nz-option> + <nz-option nzLabel="Option2" nzValue="Option2"></nz-option> + </nz-select> + <input nz-input value="input content" [style.width.%]="50" /> + <nz-input-number [ngModel]="12" /> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <input nz-input value="input content" [style.width.%]="50" /> + <nz-date-picker [style.width.%]="50" /> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <nz-range-picker [style.width.%]="70" /> + <input nz-input value="input content" [style.width.%]="30" /> + <button nz-button nzType="primary">查询</button> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <input nz-input value="input content" [style.width.%]="30" /> + <nz-range-picker [style.width.%]="70" /> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <nz-select ngModel="Option1-1"> + <nz-option nzLabel="Option1-1" nzValue="Option1-1"></nz-option> + <nz-option nzLabel="Option2-1" nzValue="Option2-1"></nz-option> + </nz-select> + <nz-select ngModel="Option1-2"> + <nz-option nzLabel="Option1-2" nzValue="Option1-2"></nz-option> + <nz-option nzLabel="Option2-2" nzValue="Option2-2"></nz-option> + </nz-select> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <nz-select ngModel="1"> + <nz-option nzLabel="Between" nzValue="1"></nz-option> + <nz-option nzLabel="Except" nzValue="2"></nz-option> + </nz-select> + <input nz-input placeholder="Minimum" style="width: 100px; text-align: center" /> + <input + nz-input + class="site-input-split" + style=" + width: 30px; + border-left: 0; + border-right: 0; + pointer-events: none + " + placeholder="~" + disabled + /> + <input nz-input class="site-input-right" style="width: 100px; text-align: center" placeholder="Maximum" /> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <nz-select ngModel="Sign Up" [style.width.%]="30"> + <nz-option nzLabel="Sign Up" nzValue="Sign Up"></nz-option> + <nz-option nzLabel="Sign In" nzValue="Sign In"></nz-option> + </nz-select> + <nz-autocomplete #auto [nzDataSource]="['text 1', 'text 2']" /> + <input nz-input placeholder="Email" [nzAutocomplete]="auto" [style.width.%]="70" /> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <nz-time-picker [style.width.%]="70" /> + <nz-cascader [nzOptions]="cascaderOptions" nzPlaceholder="Select Address" [style.width.%]="70" /> + </nz-space-compact> + <br /> + <nz-space-compact nzBlock> + <nz-tree-select + [nzNodes]="nodes" + nzShowSearch + nzPlaceHolder="Please select" + ngModel="10010" + nzDefaultExpandAll + [style.width.%]="60" + ></nz-tree-select> + <button nz-button nzType="primary">Submit</button> + </nz-space-compact> + `, + styles: [ + ` + .site-input-split { + background-color: #fff; + } + + .site-input-right:not(.ant-input-rtl) { + border-left-width: 0; + } + + .site-input-right:not(.ant-input-rtl):hover, + .site-input-right:not(.ant-input-rtl):focus { + border-left-width: 1px; + } + + .site-input-right.ant-input-rtl { + border-right-width: 0; + } + + .site-input-right.ant-input-rtl:hover, + .site-input-right.ant-input-rtl:focus { + border-right-width: 1px; + } + ` + ] +}) +export class NzDemoSpaceCompactComponent { + cascaderOptions = [ + { + value: 'zhejiang', + label: 'Zhejiang', + children: [ + { + value: 'hangzhou', + label: 'Hangzhou', + children: [ + { + value: 'xihu', + label: 'West Lake' + } + ] + } + ] + }, + { + value: 'jiangsu', + label: 'Jiangsu', + children: [ + { + value: 'nanjing', + label: 'Nanjing', + children: [ + { + value: 'zhonghuamen', + label: 'Zhong Hua Men' + } + ] + } + ] + } + ]; + + nodes = [ + { + title: 'parent 1', + key: '100', + children: [ + { + title: 'parent 1-0', + key: '1001', + children: [ + { title: 'leaf 1-0-0', key: '10010', isLeaf: true }, + { title: 'leaf 1-0-1', key: '10011', isLeaf: true } + ] + }, + { + title: 'parent 1-1', + key: '1002', + children: [{ title: 'leaf 1-1-0', key: '10020', isLeaf: true }] + } + ] + } + ]; +} diff --git a/components/space/demo/module b/components/space/demo/module index 0ea9aa08ab1..7eaf223b61f 100644 --- a/components/space/demo/module +++ b/components/space/demo/module @@ -1,23 +1,45 @@ +import { FormsModule } from '@angular/forms'; +import { NzAutocompleteModule } from 'ng-zorro-antd/auto-complete'; import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzCardModule } from 'ng-zorro-antd/card'; +import { NzCascaderModule } from 'ng-zorro-antd/cascader'; +import { NzDatePickerModule } from 'ng-zorro-antd/date-picker'; import { NzDividerModule } from 'ng-zorro-antd/divider'; +import { NzDropDownModule } from 'ng-zorro-antd/dropdown'; import { NzIconModule } from 'ng-zorro-antd/icon'; +import { NzInputModule } from 'ng-zorro-antd/input'; +import { NzInputNumberModule } from 'ng-zorro-antd/input-number'; import { NzPopconfirmModule } from 'ng-zorro-antd/popconfirm'; import { NzRadioModule } from 'ng-zorro-antd/radio'; +import { NzSelectModule } from 'ng-zorro-antd/select'; import { NzSliderModule } from 'ng-zorro-antd/slider'; import { NzSpaceModule } from 'ng-zorro-antd/space'; +import { NzTimePickerModule } from 'ng-zorro-antd/time-picker'; +import { NzToolTipModule } from 'ng-zorro-antd/tooltip'; +import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select'; import { NzTypographyModule } from 'ng-zorro-antd/typography'; import { NzUploadModule } from 'ng-zorro-antd/upload'; export const moduleList = [ NzRadioModule, NzSliderModule, - NzUploadModule, NzButtonModule, + NzInputModule, + NzInputNumberModule, + NzSelectModule, + NzCascaderModule, + NzDatePickerModule, + NzTimePickerModule, + NzTreeSelectModule, + NzUploadModule, NzSpaceModule, NzIconModule, NzPopconfirmModule, NzCardModule, NzDividerModule, - NzTypographyModule + NzTypographyModule, + NzToolTipModule, + NzAutocompleteModule, + NzDropDownModule, + FormsModule ]; diff --git a/components/space/doc/index.en-US.md b/components/space/doc/index.en-US.md index e9f86205fc2..1b05f020fbb 100644 --- a/components/space/doc/index.en-US.md +++ b/components/space/doc/index.en-US.md @@ -22,8 +22,26 @@ import { NzSpaceModule } from 'ng-zorro-antd/space'; | Property | Description | Type | Default | Global Config | | --------------- | ------------------------------------------- | -------------------------------------------- | ------------ | ------------- | -| `[nzSize]` | The space size | `'small' \| 'middle' \| 'large' \| number` | `small` | ✅ | +| `[nzSize]` | The space size | `'small' \| 'middle' \| 'large' \| number` | `small` | ✅ | | `[nzDirection]` | The space direction | `'vertical' \| 'horizontal'` | `horizontal` | | | `[nzAlign]` | Align items | `'start' \| 'end' \| 'baseline' \| 'center'` | - | | | `[nzWrap]` | Auto wrap line, when `horizontal` effective | `boolean` | `false` | | | `[nzSplit]` | Set split | `TemplateRef` | - | | + +### nz-space-compact:standalone + +Use `<nz-space-compact>` when child form components are compactly connected and the border is collapsed. The supported components are: + +- Button +- Cascader +- DatePicker +- Input +- Select +- TimePicker +- TreeSelect +- +| 参数 | 说明 | 类型 | 默认值 | 支持全局配置 | +| --------------- | ------------------------------------------ | -------------------------------- | ------------ | ------------ | +| `[nzBlock]` | Option to fit width to its parent\'s width | `boolean` | `false` | | +| `[nzDirection]` | Set direction of layout | `'vertical' \| 'horizontal'` | `horizontal` | | +| `[nzSize]` | Set child component size | `'large' \| 'middle' \| 'small'` | `'middle'` | | diff --git a/components/space/doc/index.zh-CN.md b/components/space/doc/index.zh-CN.md index 39992fd2781..2b216ccd47d 100644 --- a/components/space/doc/index.zh-CN.md +++ b/components/space/doc/index.zh-CN.md @@ -26,8 +26,26 @@ import { NzSpaceModule } from 'ng-zorro-antd/space'; | 参数 | 说明 | 类型 | 默认值 | 支持全局配置 | | --------------- | -------------------------------------- | -------------------------------------------- | ------------ | ------------ | -| `[nzSize]` | 间距大小 | `'small' \| 'middle' \| 'large' \| number` | `'small'` | ✅ | +| `[nzSize]` | 间距大小 | `'small' \| 'middle' \| 'large' \| number` | `'small'` | ✅ | | `[nzDirection]` | 间距方向 | `'vertical' \| 'horizontal'` | `horizontal` | | | `[nzAlign]` | 对齐方式 | `'start' \| 'end' \| 'baseline' \| 'center'` | - | | | `[nzWrap]` | 是否自动换行,仅在 `horizontal` 时有效 | `boolean` | `false` | | | `[nzSplit]` | 设置分隔符 | `TemplateRef` | - | | + +### nz-space-compact:standalone + +需要表单组件之间紧凑连接且合并边框时,使用 `<nz-space-compact>`。支持的组件有: + +- Button +- Cascader +- DatePicker +- Input +- Select +- TimePicker +- TreeSelect +- +| 参数 | 说明 | 类型 | 默认值 | 支持全局配置 | +| --------------- | ---------------------------- | -------------------------------- | ------------ | ------------ | +| `[nzBlock]` | 将宽度调整为父元素宽度的选项 | `boolean` | `false` | | +| `[nzDirection]` | 指定排列方向 | `'vertical' \| 'horizontal'` | `horizontal` | | +| `[nzSize]` | 子组件大小 | `'large' \| 'middle' \| 'small'` | `'middle'` | | diff --git a/components/space/public-api.ts b/components/space/public-api.ts index f29ed924b75..1cd8b53f927 100644 --- a/components/space/public-api.ts +++ b/components/space/public-api.ts @@ -3,7 +3,10 @@ * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ -export * from './space.module'; -export * from './space.component'; +export * from './space-compact-item.directive'; +export * from './space-compact-token'; +export * from './space-compact.component'; export * from './space-item.directive'; +export * from './space.component'; +export * from './space.module'; export * from './types'; diff --git a/components/space/space-compact-item.directive.ts b/components/space/space-compact-item.directive.ts new file mode 100644 index 00000000000..70912a95476 --- /dev/null +++ b/components/space/space-compact-item.directive.ts @@ -0,0 +1,61 @@ +/** + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE + */ + +import { computed, Directive, forwardRef, inject } from '@angular/core'; + +import { NZ_SPACE_COMPACT_ITEM, NZ_SPACE_COMPACT_ITEM_TYPE } from './space-compact-token'; +import { NzSpaceCompactComponent } from './space-compact.component'; + +@Directive({ + exportAs: 'nzSpaceCompactItem', + standalone: true, + providers: [{ provide: NZ_SPACE_COMPACT_ITEM, useExisting: forwardRef(() => NzSpaceCompactItemDirective) }], + host: { + '[class]': 'class()' + } +}) +export class NzSpaceCompactItemDirective { + private spaceCompactCmp = inject(NzSpaceCompactComponent, { host: true, skipSelf: true, optional: true }); + private type = inject(NZ_SPACE_COMPACT_ITEM_TYPE); + + protected class = computed(() => { + // Only handle when the parent is space compact component + if (!this.spaceCompactCmp) return null; + + const items = this.spaceCompactCmp.items(); + const direction = this.spaceCompactCmp.nzDirection(); + const index = items.indexOf(this); + const classes = [compactItemClassOf(this.type, direction)]; + + if (index === 0) { + classes.push(compactFirstItemClassOf(this.type, direction)); + } else if (index === items.length - 1) { + classes.push(compactLastItemClassOf(this.type, direction)); + } + + return classes; + }); +} + +function generateCompactClass( + type: string, + direction: 'vertical' | 'horizontal', + position: 'item' | 'first-item' | 'last-item' +): string { + const directionPrefix = direction === 'vertical' ? 'vertical-' : ''; + return `ant-${type}-compact-${directionPrefix}${position}`; +} + +function compactItemClassOf(type: string, direction: 'vertical' | 'horizontal'): string { + return generateCompactClass(type, direction, 'item'); +} + +function compactFirstItemClassOf(type: string, direction: 'vertical' | 'horizontal'): string { + return generateCompactClass(type, direction, 'first-item'); +} + +function compactLastItemClassOf(type: string, direction: 'vertical' | 'horizontal'): string { + return generateCompactClass(type, direction, 'last-item'); +} diff --git a/components/space/space-compact-token.ts b/components/space/space-compact-token.ts new file mode 100644 index 00000000000..b4ffa23220f --- /dev/null +++ b/components/space/space-compact-token.ts @@ -0,0 +1,11 @@ +/** + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE + */ + +import { InjectionToken } from '@angular/core'; + +import type { NzSpaceCompactItemDirective } from './space-compact-item.directive'; + +export const NZ_SPACE_COMPACT_ITEM = new InjectionToken<NzSpaceCompactItemDirective>(''); +export const NZ_SPACE_COMPACT_ITEM_TYPE = new InjectionToken<string>(''); diff --git a/components/space/space-compact.component.ts b/components/space/space-compact.component.ts new file mode 100644 index 00000000000..951e145a0a7 --- /dev/null +++ b/components/space/space-compact.component.ts @@ -0,0 +1,32 @@ +/** + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE + */ + +import { NgTemplateOutlet } from '@angular/common'; +import { booleanAttribute, ChangeDetectionStrategy, Component, contentChildren, input } from '@angular/core'; + +import { NzSizeLMSType } from 'ng-zorro-antd/core/types'; + +import { NZ_SPACE_COMPACT_ITEM } from './space-compact-token'; + +@Component({ + selector: 'nz-space-compact, [nz-space-compact]', + exportAs: 'nzSpaceCompact', + standalone: true, + imports: [NgTemplateOutlet], + template: `<ng-content></ng-content>`, + host: { + class: 'ant-space-compact', + '[class.ant-space-compact-block]': `nzBlock()`, + '[class.ant-space-compact-vertical]': `nzDirection() === 'vertical'` + }, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class NzSpaceCompactComponent { + nzBlock = input(false, { transform: booleanAttribute }); + nzDirection = input<'vertical' | 'horizontal'>('horizontal'); + nzSize = input<NzSizeLMSType>('middle'); + + items = contentChildren(NZ_SPACE_COMPACT_ITEM); +} diff --git a/components/space/space-item.directive.ts b/components/space/space-item.directive.ts index 4b884c9d59d..31f20c26d17 100644 --- a/components/space/space-item.directive.ts +++ b/components/space/space-item.directive.ts @@ -6,9 +6,7 @@ import { Directive } from '@angular/core'; @Directive({ - selector: '[nzSpaceItem]', + selector: '[nzSpaceItem],[nz-space-item]', standalone: true }) -export class NzSpaceItemDirective { - constructor() {} -} +export class NzSpaceItemDirective {} diff --git a/components/space/space.component.ts b/components/space/space.component.ts index c905ff838c8..2a706620e1c 100644 --- a/components/space/space.component.ts +++ b/components/space/space.component.ts @@ -37,7 +37,7 @@ const SPACE_SIZE: { @Component({ selector: 'nz-space, [nz-space]', - exportAs: 'NzSpace', + exportAs: 'nzSpace', changeDetection: ChangeDetectionStrategy.OnPush, template: ` <ng-content></ng-content> diff --git a/components/space/space.module.ts b/components/space/space.module.ts index fe40a9ed883..de7a95c1058 100644 --- a/components/space/space.module.ts +++ b/components/space/space.module.ts @@ -5,11 +5,12 @@ import { NgModule } from '@angular/core'; +import { NzSpaceCompactComponent } from './space-compact.component'; import { NzSpaceItemDirective } from './space-item.directive'; import { NzSpaceComponent } from './space.component'; @NgModule({ - imports: [NzSpaceComponent, NzSpaceItemDirective], - exports: [NzSpaceComponent, NzSpaceItemDirective] + imports: [NzSpaceComponent, NzSpaceItemDirective, NzSpaceCompactComponent], + exports: [NzSpaceComponent, NzSpaceItemDirective, NzSpaceCompactComponent] }) export class NzSpaceModule {} diff --git a/components/time-picker/time-picker.component.ts b/components/time-picker/time-picker.component.ts index 58f5124f28b..17798ada04e 100644 --- a/components/time-picker/time-picker.component.ts +++ b/components/time-picker/time-picker.component.ts @@ -43,6 +43,7 @@ import { NgClassInterface, NzSafeAny, NzStatus, NzValidateStatus } from 'ng-zorr import { getStatusClassNames, isNil } from 'ng-zorro-antd/core/util'; import { DateHelperService, NzI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n'; import { NzIconModule } from 'ng-zorro-antd/icon'; +import { NZ_SPACE_COMPACT_ITEM_TYPE, NzSpaceCompactItemDirective } from 'ng-zorro-antd/space'; import { NzTimePickerPanelComponent } from './time-picker-panel.component'; @@ -143,8 +144,12 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'timePicker'; '[class.ant-picker-borderless]': `nzBorderless`, '(click)': 'open()' }, + hostDirectives: [NzSpaceCompactItemDirective], animations: [slideMotion], - providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: NzTimePickerComponent, multi: true }], + providers: [ + { provide: NG_VALUE_ACCESSOR, useExisting: NzTimePickerComponent, multi: true }, + { provide: NZ_SPACE_COMPACT_ITEM_TYPE, useValue: 'picker' } + ], imports: [ AsyncPipe, FormsModule, diff --git a/components/tree-select/tree-select.component.ts b/components/tree-select/tree-select.component.ts index 5f4274c6dd3..4eec5c1b0c2 100644 --- a/components/tree-select/tree-select.component.ts +++ b/components/tree-select/tree-select.component.ts @@ -63,6 +63,7 @@ import { import { getStatusClassNames, isNotNil } from 'ng-zorro-antd/core/util'; import { NzEmptyModule } from 'ng-zorro-antd/empty'; import { NzSelectModule, NzSelectSearchComponent } from 'ng-zorro-antd/select'; +import { NZ_SPACE_COMPACT_ITEM_TYPE, NzSpaceCompactItemDirective } from 'ng-zorro-antd/space'; import { NzTreeComponent, NzTreeModule } from 'ng-zorro-antd/tree'; import { NzTreeSelectService } from './tree-select.service'; @@ -215,6 +216,7 @@ const listOfPositions = [ `, providers: [ NzTreeSelectService, + { provide: NZ_SPACE_COMPACT_ITEM_TYPE, useValue: 'select' }, { provide: NzTreeHigherOrderServiceToken, useExisting: NzTreeSelectService @@ -242,6 +244,7 @@ const listOfPositions = [ '(click)': 'trigger()', '(keydown)': 'onKeydown($event)' }, + hostDirectives: [NzSpaceCompactItemDirective], imports: [ NzOverlayModule, CdkConnectedOverlay,