Skip to content

feat(popover-edit): Material version #15873

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
/src/material-experimental/mdc-menu/** @mmalerba # Note to implementer: please repossess
/src/material-experimental/mdc-radio/** @mmalerba # Note to implementer: please repossess
/src/material-experimental/mdc-slide-toggle/** @mmalerba # Note to implementer: please repossess
/src/material-experimental/popover-edit/** @kseamon @andrewseguin

# CDK experimental package
/src/cdk-experimental/** @jelbourn
Expand Down
17 changes: 17 additions & 0 deletions packages.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ MATERIAL_SCSS_LIBS = [
"//src/lib/%s:%s_scss_lib" % (p, p.replace('-', '_')) for p in MATERIAL_PACKAGES
]

MATERIAL_EXPERIMENTAL_PACKAGES = [
"popover-edit",
]

MATERIAL_EXPERIMENTAL_TARGETS = ["//src/material-experimental"] + [
"//src/material-experimental/%s" % p for p in MATERIAL_EXPERIMENTAL_PACKAGES
]

MATERIAL_EXPERIMENTAL_SCSS_LIBS = [
"//src/material-experimental/%s:%s_scss_lib" % (p, p.replace('-', '_')) for p in MATERIAL_EXPERIMENTAL_PACKAGES
]

# Each individual package uses a placeholder for the version of Angular to ensure they're
# all in-sync. This map is passed to each ng_package rule to stamp out the appropriate
# version for the placeholders.
Expand Down Expand Up @@ -114,6 +126,11 @@ ROLLUP_GLOBALS.update({
"@angular/material/%s" % p: "ng.material.%s" % p for p in MATERIAL_PACKAGES
})

# Rollup globals for material experiemental subpackages, e.g., {"@angular/material-experimental/list": "ng.materialExperimental.list"}
ROLLUP_GLOBALS.update({
"@angular/material-experiemntal/%s" % p: "ng.materialExperimental.%s" % p for p in MATERIAL_EXPERIMENTAL_PACKAGES
})

# UMD bundles for Angular packages and subpackges we depend on for development and testing.
ANGULAR_LIBRARY_UMDS = [
"@npm//node_modules/@angular/animations:bundles/animations-browser.umd.js",
Expand Down
2 changes: 1 addition & 1 deletion src/cdk-experimental/popover-edit/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ export const TABLE_SELECTOR = 'table, cdk-table, mat-table';
export const EDIT_PANE_CLASS = 'cdk-edit-pane';

/** Selector for finding the edit lens pane. */
export const EDIT_PANE_SELECTOR = '.' + EDIT_PANE_CLASS;
export const EDIT_PANE_SELECTOR = `.${EDIT_PANE_CLASS}, .mat-edit-pane`;
2 changes: 2 additions & 0 deletions src/cdk-experimental/popover-edit/edit-services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import {Injectable, NgZone} from '@angular/core';
import {FocusTrapFactory} from '@angular/cdk/a11y';
import {Directionality} from '@angular/cdk/bidi';
import {Overlay} from '@angular/cdk/overlay';
import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';

Expand All @@ -24,6 +25,7 @@ import {PopoverEditPositionStrategyFactory} from './popover-edit-position-strate
@Injectable()
export class EditServices {
constructor(
readonly directionality: Directionality,
readonly editEventDispatcher: EditEventDispatcher, readonly focusDispatcher: FocusDispatcher,
readonly focusTrapFactory: FocusTrapFactory, readonly ngZone: NgZone,
readonly overlay: Overlay, readonly positionFactory: PopoverEditPositionStrategyFactory,
Expand Down
17 changes: 11 additions & 6 deletions src/cdk-experimental/popover-edit/lens-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import {ReplaySubject} from 'rxjs';
import {Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
import {Directive, ElementRef, EventEmitter, OnDestroy, OnInit} from '@angular/core';
import {EDIT_PANE_SELECTOR} from './constants';
import {closest} from './polyfill';
import {EditRef} from './edit-ref';
Expand All @@ -30,6 +30,12 @@ export type PopoverEditClickOutBehavior = 'close' | 'submit' | 'noop';
'(keyup.escape)': 'close()',
'(document:click)': 'handlePossibleClickOut($event)',
},
inputs: [
'clickOutBehavior: cdkEditControlClickOutBehavior',
'preservedFormValue: cdkEditControlPreservedFormValue',
'ignoreSubmitUnlessValid: cdkEditControlIgnoreSubmitUnlessValid',
],
outputs: ['preservedFormValueChange: cdkEditControlPreservedFormValueChange'],
providers: [EditRef],
})
export class CdkEditControl<FormValue> implements OnDestroy, OnInit {
Expand All @@ -39,22 +45,21 @@ export class CdkEditControl<FormValue> implements OnDestroy, OnInit {
* Specifies what should happen when the user clicks outside of the edit lens.
* The default behavior is to close the lens without submitting the form.
*/
@Input('cdkEditControlClickOutBehavior') clickOutBehavior: PopoverEditClickOutBehavior = 'close';
clickOutBehavior: PopoverEditClickOutBehavior = 'close';

/**
* A two-way binding for storing unsubmitted form state. If not provided
* then form state will be discarded on close. The PeristBy directive is offered
* as a convenient shortcut for these bindings.
*/
@Input('cdkEditControlPreservedFormValue') preservedFormValue?: FormValue;
@Output('cdkEditControlPreservedFormValueChange') readonly preservedFormValueChange =
new EventEmitter<FormValue>();
preservedFormValue?: FormValue;
readonly preservedFormValueChange = new EventEmitter<FormValue>();

/**
* Determines whether the lens will close on form submit if the form is not in a valid
* state. By default the lens will remain open.
*/
@Input('cdkEditControlIgnoreSubmitUnlessValid') ignoreSubmitUnlessValid = true;
ignoreSubmitUnlessValid = true;

constructor(protected readonly elementRef: ElementRef, readonly editRef: EditRef<FormValue>) {}

Expand Down
53 changes: 34 additions & 19 deletions src/cdk-experimental/popover-edit/table-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
Directive,
ElementRef,
EmbeddedViewRef,
Input,
NgZone,
OnDestroy,
TemplateRef,
Expand Down Expand Up @@ -110,34 +109,42 @@ export class CdkEditable implements AfterViewInit, OnDestroy {
}
}

const POPOVER_EDIT_HOST_BINDINGS = {
'tabIndex': '0',
'class': 'cdk-popover-edit-cell',
'[attr.aria-haspopup]': 'true',
};

const POPOVER_EDIT_INPUTS = [
'template: cdkPopoverEdit',
'context: cdkPopoverEditContext',
'colspan: cdkPopoverEditColspan',
];

/**
* Attaches an ng-template to a cell and shows it when instructed to by the
* EditEventDispatcher service.
* Makes the cell focusable.
*/
@Directive({
selector: '[cdkPopoverEdit]:not([cdkPopoverEditTabOut])',
host: {
'tabIndex': '0',
'class': 'cdk-popover-edit-cell',
'[attr.aria-haspopup]': 'true',
}
host: POPOVER_EDIT_HOST_BINDINGS,
inputs: POPOVER_EDIT_INPUTS,
})
export class CdkPopoverEdit<C> implements AfterViewInit, OnDestroy {
/** The edit lens template shown over the cell on edit. */
@Input('cdkPopoverEdit') template: TemplateRef<any>|null = null;
template: TemplateRef<any>|null = null;

/**
* Implicit context to pass along to the template. Can be omitted if the template
* is defined within the cell.
*/
@Input('cdkPopoverEditContext') context?: C;
context?: C;

/**
* Specifies that the popup should cover additional table cells before and/or after
* this one.
*/
@Input('cdkPopoverEditColspan')
get colspan(): CdkPopoverEditColspan {
return this._colspan;
}
Expand Down Expand Up @@ -184,6 +191,10 @@ export class CdkPopoverEdit<C> implements AfterViewInit, OnDestroy {
this.services.editEventDispatcher.doneEditingCell(this.elementRef.nativeElement!);
}

protected panelClass(): string {
return EDIT_PANE_CLASS;
}

private _startListeningToEditEvents(): void {
this.services.editEventDispatcher.editingCell(this.elementRef.nativeElement!)
.pipe(takeUntil(this.destroyed))
Expand All @@ -207,7 +218,7 @@ export class CdkPopoverEdit<C> implements AfterViewInit, OnDestroy {
private _createEditOverlay(): void {
this.overlayRef = this.services.overlay.create({
disposeOnNavigation: true,
panelClass: EDIT_PANE_CLASS,
panelClass: this.panelClass(),
positionStrategy: this._getPositionStrategy(),
scrollStrategy: this.services.overlay.scrollStrategies.reposition(),
});
Expand Down Expand Up @@ -276,12 +287,9 @@ export class CdkPopoverEdit<C> implements AfterViewInit, OnDestroy {
* Makes the cell focusable.
*/
@Directive({
selector: '[cdkPopoverEdit] [cdkPopoverEditTabOut]',
host: {
'tabIndex': '0',
'class': 'cdk-popover-edit-cell',
'[attr.aria-haspopup]': 'true',
}
selector: '[cdkPopoverEdit][cdkPopoverEditTabOut]',
host: POPOVER_EDIT_HOST_BINDINGS,
inputs: POPOVER_EDIT_INPUTS,
})
export class CdkPopoverEditTabOut<C> extends CdkPopoverEdit<C> {
protected focusTrap?: FocusEscapeNotifier;
Expand Down Expand Up @@ -324,9 +332,6 @@ export class CdkPopoverEditTabOut<C> extends CdkPopoverEdit<C> {
*/
@Directive({
selector: '[cdkRowHoverContent]',
host: {
'[attr.aria-hidden]': 'true',
}
})
export class CdkRowHoverContent implements AfterViewInit, OnDestroy {
protected readonly destroyed = new ReplaySubject<void>();
Expand All @@ -350,6 +355,14 @@ export class CdkRowHoverContent implements AfterViewInit, OnDestroy {
}
}

protected initElement(element: HTMLElement): void;
protected initElement(): void {
}

protected prepareElement(element: HTMLElement): void;
protected prepareElement(): void {
}

private _listenForHoverEvents(): void {
this.services.editEventDispatcher.hoveringOnRow(this.elementRef.nativeElement!)
.pipe(takeUntil(this.destroyed))
Expand All @@ -360,9 +373,11 @@ export class CdkRowHoverContent implements AfterViewInit, OnDestroy {
// Not doing any positioning in CDK version. Material version
// will absolutely position on right edge of cell.
this.viewRef = this.viewContainerRef.createEmbeddedView(this.templateRef, {});
this.initElement(this.elementRef.nativeElement!.nextSibling as HTMLElement);
} else {
this.viewContainerRef.insert(this.viewRef);
}
this.prepareElement(this.elementRef.nativeElement!.nextSibling as HTMLElement);
} else if (this.viewRef) {
this.viewContainerRef.detach(this.viewContainerRef.indexOf(this.viewRef));
}
Expand Down
6 changes: 3 additions & 3 deletions src/dev-app/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package(default_visibility=["//visibility:public"])

load("@io_bazel_rules_sass//:defs.bzl", "sass_binary")
load("//:packages.bzl", "MATERIAL_TARGETS", "CDK_TARGETS", "CDK_EXPERIMENTAL_TARGETS")
load("//:packages.bzl", "MATERIAL_TARGETS", "CDK_TARGETS", "CDK_EXPERIMENTAL_TARGETS", "MATERIAL_EXPERIMENTAL_TARGETS", "MATERIAL_EXPERIMENTAL_SCSS_LIBS")
load("//tools:defaults.bzl", "ng_module")
load("//tools:sass_generate_binaries.bzl", "sass_generate_binaries")

Expand Down Expand Up @@ -32,7 +32,7 @@ ng_module(
"//src/material-experimental/mdc-radio",
"//src/material-experimental/mdc-slide-toggle",
"//src/material-examples:examples",
] + CDK_TARGETS + CDK_EXPERIMENTAL_TARGETS + MATERIAL_TARGETS
] + CDK_TARGETS + CDK_EXPERIMENTAL_TARGETS + MATERIAL_TARGETS + MATERIAL_EXPERIMENTAL_TARGETS
)

sass_binary(
Expand All @@ -50,5 +50,5 @@ sass_binary(
"//src/material-experimental/mdc-menu:menu_scss_lib",
"//src/material-experimental/mdc-radio:radio_scss_lib",
"//src/material-experimental/mdc-slide-toggle:slide_toggle_scss_lib",
]
] + MATERIAL_EXPERIMENTAL_SCSS_LIBS
)
1 change: 1 addition & 0 deletions src/dev-app/popover-edit/assets/edit-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/dev-app/system-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ System.config({
'dist/packages/material-experimental/mdc-slide-toggle/index.js',
'@angular/material-experimental/mdc-helpers':
'dist/packages/material-experimental/mdc-helpers/index.js',
'@angular/material-experimental/popover-edit':
'dist/packages/material-experimental/popover-edit/index.js',
},
packages: {
// Set the default extension for the root package, because otherwise the dev-app can't
Expand Down
5 changes: 4 additions & 1 deletion src/dev-app/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@import '../material-experimental/mdc-menu/mdc-menu';
@import '../material-experimental/mdc-radio/mdc-radio';
@import '../material-experimental/mdc-slide-toggle/mdc-slide-toggle';
@import '../material-experimental/popover-edit/popover-edit';

// Plus imports for other components in your app.

Expand Down Expand Up @@ -33,7 +34,8 @@ $candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent);
@include mat-menu-theme-mdc($candy-app-theme);
@include mat-radio-theme-mdc($candy-app-theme);
@include mat-slide-toggle-theme-mdc($candy-app-theme);

@include mat-edit-theme($candy-app-theme);
@include mat-edit-typography(mat-typography-config());

// Define an alternate dark theme.
$dark-primary: mat-palette($mat-blue-grey);
Expand All @@ -53,4 +55,5 @@ $dark-theme: mat-dark-theme($dark-primary, $dark-accent, $dark-warn);
@include mat-menu-theme-mdc($dark-theme);
@include mat-radio-theme-mdc($dark-theme);
@include mat-slide-toggle-theme-mdc($dark-theme);
@include mat-edit-theme($dark-theme);
}
4 changes: 2 additions & 2 deletions src/material-examples/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package(default_visibility=["//visibility:public"])

load("//:packages.bzl", "CDK_TARGETS", "CDK_EXPERIMENTAL_TARGETS", "MATERIAL_TARGETS", "ROLLUP_GLOBALS")
load("//:packages.bzl", "CDK_TARGETS", "CDK_EXPERIMENTAL_TARGETS", "MATERIAL_TARGETS", "MATERIAL_EXPERIMENTAL_TARGETS", "ROLLUP_GLOBALS")
load("//tools:defaults.bzl", "ng_module", "ng_package")
load("//tools/highlight-files:index.bzl", "highlight_files")
load("//tools/package-docs-content:index.bzl", "package_docs_content")
Expand All @@ -17,7 +17,7 @@ ng_module(
"@npm//@angular/forms",
"@npm//moment",
"//src/material-moment-adapter",
] + CDK_TARGETS + CDK_EXPERIMENTAL_TARGETS + MATERIAL_TARGETS,
] + CDK_TARGETS + CDK_EXPERIMENTAL_TARGETS + MATERIAL_TARGETS + MATERIAL_EXPERIMENTAL_TARGETS,
# Specify the tsconfig that is also used by Gulp. We need to explicitly use this tsconfig
# because in order to import Moment with TypeScript, some specific options need to be set.
tsconfig = ":tsconfig-build.json",
Expand Down
3 changes: 3 additions & 0 deletions src/material-examples/material-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {CdkTableModule} from '@angular/cdk/table';
import {CdkTreeModule} from '@angular/cdk/tree';
import {DragDropModule} from '@angular/cdk/drag-drop';
import {CdkStepperModule} from '@angular/cdk/stepper';
import {MatPopoverEditModule} from '@angular/material-experimental/popover-edit';
import {PortalModule} from '@angular/cdk/portal';
import {
MatAutocompleteModule, MatBadgeModule, MatBottomSheetModule, MatButtonModule,
Expand Down Expand Up @@ -46,6 +47,7 @@ import {
MatListModule,
MatMenuModule,
MatPaginatorModule,
MatPopoverEditModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
Expand Down Expand Up @@ -92,6 +94,7 @@ import {
MatListModule,
MatMenuModule,
MatPaginatorModule,
MatPopoverEditModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.example-table {
width: 100%;
}

.example-table th {
text-align: left;
}

.example-table td,
.example-table th {
min-width: 300px;
width: 25%;
}

.example-input-container {
display: flex;
justify-content: stretch;
}

.example-input-container mat-form-field {
flex: 1;
}
Loading