Skip to content
This repository has been archived by the owner on May 20, 2023. It is now read-only.

Commit

Permalink
Components update (#96)
Browse files Browse the repository at this point in the history
 * Material Progress: Cleanup animations on destroy to prevent memory leaks.
 * Material Select: 
   * Support deselect item in Material dropdown select with single selection 
     model.
   * Unified template files (deleted material_select_dropdown_item.html).
   * Add support for `Selectable` `SelectionOptions`.
   * Create a `ControlValueAccessor`.
 * Add backspace and delete keys to `KeyboardHandlerMixin`.
 * Add `selectedValue` getter to `RadioGroupSingleSelectionModel`.
 * Add null check to `ObservableComposite`'s `register` method.
 * Add `totalEntitiesCountChange` getter to table selection models.
 * Add `isStandardMouseEvent` utility to test for clicks without modifier keys.
 * Add string selection sanitizing options.
 * Remove `NoopStream` in favor of `Stream.empty()` as provided by the SDK.
 * Migrate use of LazyEventController to StreamController.
 * Fix bug in lazy group creation that would cause multiple groups to be 
   created.
 * Strong mode fixes.
  • Loading branch information
nshahan authored May 24, 2017
1 parent 4518e63 commit 6efe993
Show file tree
Hide file tree
Showing 41 changed files with 372 additions and 385 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
## 0.5.2

* Material Progress: Cleanup animations on destroy to prevent memory leaks.
* Material Select:
* Support deselect item in Material dropdown select with single selection
model.
* Unified template files (deleted material_select_dropdown_item.html).
* Add support for `Selectable` `SelectionOptions`.
* Create a `ControlValueAccessor`.
* Add backspace and delete keys to `KeyboardHandlerMixin`.
* Add `selectedValue` getter to `RadioGroupSingleSelectionModel`.
* Add null check to `ObservableComposite`'s `register` method.
* Add `totalEntitiesCountChange` getter to table selection models.
* Add `isStandardMouseEvent` utility to test for clicks without modifier keys.
* Add string selection sanitizing options.
* Remove `NoopStream` in favor of `Stream.empty()` as provided by the SDK.
* Migrate use of LazyEventController to StreamController.
* Fix bug in lazy group creation that would cause multiple groups to be
created.
* Strong mode fixes.

## 0.5.1

* Glyph: Add baseline attribute.
Expand Down
1 change: 1 addition & 0 deletions lib/src/all_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export 'components/material_chips/material_chip.dart';
export 'components/material_chips/material_chips.dart';
export 'components/material_dialog/material_dialog.dart';
export 'components/material_expansionpanel/material_expansionpanel.dart';
export 'components/material_expansionpanel/material_expansionpanel_auto_dismiss.dart';
export 'components/material_expansionpanel/material_expansionpanel_set.dart';
export 'components/material_input/base_material_input.dart';
export 'components/material_input/deferred_validator.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/src/components/material_button/material_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:angular2/angular2.dart';

import '../button_decorator/button_decorator.dart';
import '../material_ripple/material_ripple.dart';
import '../theme/dark_theme.dart';

import 'material_button_base.dart';

/// Material button is a button.
Expand Down
2 changes: 1 addition & 1 deletion lib/src/components/material_button/material_fab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:angular2/angular2.dart';

import '../material_ripple/material_ripple.dart';

import 'material_button_base.dart';

/// Material FAB is a Floating Action Button. It is round, and behaves mostly
Expand Down
2 changes: 1 addition & 1 deletion lib/src/components/material_chips/material_chip.scss.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'package:intl/intl.dart';
import '../../model/action/async_action.dart';
import '../../utils/angular/managed_zone/angular_2.dart';
import '../../utils/angular/properties/properties.dart';
import '../../utils/async/async.dart';
import '../../utils/browser/dom_service/dom_service.dart';
import '../../utils/disposer/disposer.dart';
import '../button_decorator/button_decorator.dart';
Expand Down Expand Up @@ -159,13 +158,17 @@ class MaterialExpansionPanel
}

@Output('expandedChange')
final isExpandedChange = new LazyEventEmitter<bool>.broadcast();
Stream<bool> get isExpandedChange => _isExpandedChange.stream;
final _isExpandedChange = new StreamController<bool>.broadcast(sync: true);

@Output('expandedChangeByUser')
final isExpandedChangeByUserAction = new LazyEventEmitter<bool>.broadcast();
Stream<bool> get isExpandedChangeByUserAction =>
_isExpandedChangeByUserAction.stream;
final _isExpandedChangeByUserAction =
new StreamController<bool>.broadcast(sync: true);

@override
LazyEventEmitter<bool> get contentVisible => isExpandedChange;
Stream<bool> get contentVisible => isExpandedChange;

/// Whether a different panel in the set is currently expanded.
///
Expand Down Expand Up @@ -379,8 +382,8 @@ class MaterialExpansionPanel
actionCtrl.execute(() {
if (closeOnSave) {
_isExpanded = false;
isExpandedChange.add(false);
isExpandedChangeByUserAction.add(false);
_isExpandedChange.add(false);
_isExpandedChangeByUserAction.add(false);
_changeDetector.markForCheck();
}
return true;
Expand All @@ -399,8 +402,8 @@ class MaterialExpansionPanel
_changeDetector.markForCheck();
actionCtrl.execute(() {
_isExpanded = false;
isExpandedChange.add(false);
isExpandedChangeByUserAction.add(false);
_isExpandedChange.add(false);
_isExpandedChangeByUserAction.add(false);
_changeDetector.markForCheck();
return true;
}, valueOnCancel: false);
Expand All @@ -424,8 +427,8 @@ class MaterialExpansionPanel
stream.add(actionCtrl.action);
actionCtrl.execute(() {
_isExpanded = expand;
isExpandedChange.add(expand);
if (byUserAction) isExpandedChangeByUserAction.add(expand);
_isExpandedChange.add(expand);
if (byUserAction) _isExpandedChangeByUserAction.add(expand);
_changeDetector.markForCheck();
if (expand && autoFocusChild != null) {
_domService.scheduleWrite(() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import 'dart:html';

import 'package:angular2/angular2.dart';

import '../../../laminate/overlay/module.dart' show overlayContainerToken;
import '../material_expansionpanel.dart';
import '../../laminate/overlay/module.dart' show overlayContainerToken;
import './material_expansionpanel.dart';

/// A directive that automatically collapses [MaterialExpansionPanel].
///
Expand Down
12 changes: 11 additions & 1 deletion lib/src/components/material_progress/material_progress.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const Map<String, double> _indeterminateTiming = const {
templateUrl: 'material_progress.html',
styleUrls: const ['material_progress.scss.css'],
changeDetection: ChangeDetectionStrategy.OnPush)
class MaterialProgressComponent implements AfterViewInit {
class MaterialProgressComponent implements AfterViewInit, OnDestroy {
final HtmlElement _element;

/// The current progress value.
Expand Down Expand Up @@ -106,6 +106,16 @@ class MaterialProgressComponent implements AfterViewInit {
if (indeterminate) _tryFancyAnimation();
}

@override
void ngOnDestroy() {
_primaryAnimation?.cancel();
_secondaryAnimation?.cancel();
_primaryAnimation = null;
_secondaryAnimation = null;
_primaryIndicator = null;
_secondaryIndicator = null;
}

/// Sets up the "indeterminate" animation using the animation API.
void _tryFancyAnimation() {
// Only set this up if we support the animation API and if the component's
Expand Down
47 changes: 39 additions & 8 deletions lib/src/components/material_select/material_dropdown_select.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import '../../model/selection/selection_model.dart';
import '../../model/selection/selection_options.dart';
import '../../model/ui/has_renderer.dart';
import '../../model/ui/template_support.dart';
import '../../utils/async/async.dart';
import '../../utils/id_generator/id_generator.dart';
import '../annotations/rtl_annotation.dart';
import '../content/deferred_content.dart';
Expand Down Expand Up @@ -90,6 +89,8 @@ import './shift_click_selection.dart';
/// as wide as the select width.
/// - `slide: String` -- Direction of popup scaling. Valid values are `x`, `y`,
/// or `null`.
/// - `deselectLabel: String` -- Text label for select item that deselects
/// the current selection.
@Component(
selector: 'material-dropdown-select',
inputs: const [
Expand Down Expand Up @@ -168,6 +169,10 @@ class MaterialDropdownSelectComponent extends MaterialSelectBase
/// instead of the implementation of this class.
final PopupSizeProvider _popupSizeDelegate;

/// Text label for select item that deselects the current selection.
@Input()
String deselectLabel;

MaterialDropdownSelectComponent(
@Optional() IdGenerator idGenerator,
@Optional() @SkipSelf() this._popupSizeDelegate,
Expand All @@ -188,28 +193,32 @@ class MaterialDropdownSelectComponent extends MaterialSelectBase
set options(SelectionOptions newOptions) {
super.options = newOptions;

activeModel.items = options?.optionsList ?? [];
_updateActiveModel();
_setInitialActiveItem();

_optionsListener?.cancel();
_optionsListener = options?.stream?.listen((_) {
activeModel.items = options.optionsList;
_updateActiveModel();
_setInitialActiveItem();
});
}

@Output()
LazyEventEmitter<FocusEvent> focus = new LazyEventEmitter<FocusEvent>();
Stream<FocusEvent> get focus => _focus.stream;
StreamController<FocusEvent> _focus =
new StreamController<FocusEvent>.broadcast(sync: true);

@Output()
LazyEventEmitter<FocusEvent> blur = new LazyEventEmitter<FocusEvent>();
Stream<FocusEvent> get blur => _blur.stream;
StreamController<FocusEvent> _blur =
new StreamController<FocusEvent>.broadcast(sync: true);

void onFocus(FocusEvent event) {
focus.add(event);
_focus.add(event);
}

void onBlur(FocusEvent event) {
blur.add(event);
_blur.add(event);
}

@override
Expand All @@ -228,6 +237,14 @@ class MaterialDropdownSelectComponent extends MaterialSelectBase
});
}

void _updateActiveModel() {
var items = options?.optionsList?.toList() ?? [];
if (showDeselectItem) {
items.insert(0, deselectLabel);
}
activeModel.items = items;
}

void _setInitialActiveItem() {
if (selection == null || selection.selectedValues.isEmpty) {
activeModel.activate(null);
Expand Down Expand Up @@ -289,7 +306,9 @@ class MaterialDropdownSelectComponent extends MaterialSelectBase
} else {
var item = activeModel.activeItem;
if (item != null && selection != null) {
if (selection.isSelected(item)) {
if (item == deselectLabel) {
deselectCurrentSelection();
} else if (selection.isSelected(item)) {
selection.deselect(item);
} else {
selection.select(item);
Expand Down Expand Up @@ -372,6 +391,18 @@ class MaterialDropdownSelectComponent extends MaterialSelectBase
}
return false;
}

/// Whether to show select item that deselects the current selection.
bool get showDeselectItem =>
!isMultiSelect && deselectLabel?.isNotEmpty == true;

bool get isDeselectItemSelected => selection.isEmpty;

void deselectCurrentSelection() {
if (selection.isNotEmpty) {
selection.deselect(selection.selectedValues.single);
}
}
}

// TODO(google): Move it to a common home to increase reusability.
Expand Down
52 changes: 32 additions & 20 deletions lib/src/components/material_select/material_dropdown_select.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@
(trigger)="handleClick($event)"
popupSource
#source="popupSource">
<ng-content select="[buttonContent]"></ng-content>
<ng-content select="[buttonContent]"></ng-content>
</dropdown-button>
<material-popup enforceSpaceConstraints
[preferredPositions]="preferredPositions"
[matchMinSourceWidth]="popupMatchInputWidth"
[slide]="slide"
[source]="source"
[autoDismiss]="autoDismiss"
[trackLayoutChanges]="trackLayoutChanges"
[visible]="visible"
(visibleChange)="onVisible($event)">
[preferredPositions]="preferredPositions"
[matchMinSourceWidth]="popupMatchInputWidth"
[slide]="slide"
[source]="source"
[autoDismiss]="autoDismiss"
[trackLayoutChanges]="trackLayoutChanges"
[visible]="visible"
(visibleChange)="onVisible($event)">
<div header
(keydown)="onKeyDown($event)"
(keypress)="onKeyPress($event)"
Expand All @@ -46,21 +46,33 @@
(mouseout)="activeModel.activate(null)">
<ng-content></ng-content>
<div class="options-wrapper" *ngIf="options != null">
<div *ngFor="let group of options.optionGroups trackBy trackByIndexFn" group
[class.empty]="group.isEmpty && !group.hasEmptyLabel">
<material-select-dropdown-item
*ngIf="showDeselectItem"
[class.empty]="options.optionGroups.length == 1"
keyboardOnlyFocusIndicator
[selected]="isDeselectItemSelected"
[value]="deselectLabel"
(trigger)="deselectCurrentSelection()"
[active]="activeModel.isActive(deselectLabel)"
[attr.id]="activeModel.id(deselectLabel)"
(mouseenter)="activeModel.activate(deselectLabel)">
</material-select-dropdown-item>
<div *ngFor="let group of options.optionGroups trackBy trackByIndexFn"
group
[class.empty]="group.isEmpty && !group.hasEmptyLabel">
<template [ngIf]="group.isNotEmpty || group.hasEmptyLabel">
<span *ngIf="group.hasLabel" label>{{group.uiDisplayName}}</span>
<template [ngIf]="group.isNotEmpty">
<material-select-dropdown-item *ngFor="let item of group"
keyboardOnlyFocusIndicator
[itemRenderer]="itemRenderer"
[componentRenderer]="componentRenderer"
[selection]="selection"
[disabled]="isOptionDisabled(item)"
[value]="item"
[active]="activeModel.isActive(item)"
[attr.id]="activeModel.id(item)"
(mouseenter)="activeModel.activate(item)">
keyboardOnlyFocusIndicator
[itemRenderer]="itemRenderer"
[componentRenderer]="componentRenderer"
[selection]="selection"
[disabled]="isOptionDisabled(item)"
[value]="item"
[active]="activeModel.isActive(item)"
[attr.id]="activeModel.id(item)"
(mouseenter)="activeModel.activate(item)">
</material-select-dropdown-item>
</template>
<material-select-dropdown-item
Expand Down
11 changes: 11 additions & 0 deletions lib/src/components/material_select/material_select.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'dart:async';

import 'package:angular2/angular2.dart';

import '../../model/selection/select.dart';
import '../../model/selection/selection_container.dart';
import '../../model/selection/selection_model.dart';
import '../../model/ui/has_renderer.dart';
Expand Down Expand Up @@ -68,6 +69,16 @@ class MaterialSelectComponent extends MaterialSelectBase implements OnDestroy {
@override
SelectionModel get selection => super.selection;

/// If selectionOptions implements Selectable, it is called to decided
/// whether an item is disabled.
bool isOptionDisabled(Object item) {
if (options is Selectable) {
return (options as Selectable).getSelectable(item) !=
SelectableOption.Selectable;
}
return false;
}

@Input()
set disabled(value) {
_disabled = getBool(value);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/components/material_select/material_select.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<span *ngIf="group.hasLabel" label>{{group.uiDisplayName}}</span>
<material-select-item *ngFor="let item of group"
[itemRenderer]="itemRenderer"
[disabled]="disabled"
[disabled]="disabled || isOptionDisabled(item)"
[componentRenderer]="componentRenderer"
[selection]="selection"
[value]="item">
Expand Down
Loading

0 comments on commit 6efe993

Please sign in to comment.