diff --git a/components/accordion/accordion.ts b/components/accordion/accordion.ts index db76d00dbd..983c7bcf5b 100644 --- a/components/accordion/accordion.ts +++ b/components/accordion/accordion.ts @@ -6,35 +6,27 @@ import { NgClass, ViewContainerRef, TemplateRef } from 'angular2/angular2'; -import {Ng2BootstrapConfig} from '../ng2-bootstrap-config'; - -console.log(Ng2BootstrapConfig.theme); - // todo: support template url @Component({ selector: 'accordion, [accordion]', - properties: [ - 'templateUrl', - 'bCloseOthers: closeOthers' - ] + properties: ['templateUrl', 'closeOthers'], + host: { + '[class.panel-group]': 'true' + } }) @View({ - template: ` -
- -
- ` + template: `` }) export class Accordion { private templateUrl:string; - private bCloseOthers:any; - private groups:Array = []; + private closeOthers:boolean; + private groups:Array = []; constructor() { } - public closeOthers(openGroup:AccordionGroup) { - if (!this.bCloseOthers) { + public closeOtherGroups(openGroup:AccordionGroup) { + if (!this.closeOthers) { return; } @@ -59,18 +51,18 @@ export class Accordion { @Directive({ selector: 'accordion-transclude, [accordion-transclude]', - properties: ['headingTemplate: accordion-transclude'], + properties: ['accordionTransclude'], lifecycle: [LifecycleEvent.onInit] }) export class AccordionTransclude { - private headingTemplate: TemplateRef; + private accordionTransclude:TemplateRef; - constructor(private viewRef: ViewContainerRef) { + constructor(private viewRef:ViewContainerRef) { } onInit() { - if (this.headingTemplate) { - this.viewRef.createEmbeddedView(this.headingTemplate); + if (this.accordionTransclude) { + this.viewRef.createEmbeddedView(this.accordionTransclude); } } } @@ -80,12 +72,7 @@ import {Collapse} from '../collapse/collapse'; // todo: support custom `open class` @Component({ selector: 'accordion-group, [accordion-group]', - properties: [ - 'templateUrl', - 'heading', - 'isOpen', - 'isDisabled' - ], + properties: ['templateUrl', 'heading', 'isOpen', 'isDisabled', 'panelClass'], host: { '[class.panel-open]': 'isOpen' }, @@ -93,11 +80,10 @@ import {Collapse} from '../collapse/collapse'; }) @View({ template: ` -
-
+
+

- + {{heading}} @@ -114,16 +100,17 @@ import {Collapse} from '../collapse/collapse'; }) export class AccordionGroup { private templateUrl:string; + private panelClass:string; private _isOpen:boolean; public isDisabled:boolean; - public headingTemplate:any; - // public templateRef: any; + public headingTemplate:TemplateRef; constructor(private accordion:Accordion) { } onInit() { + this.panelClass = this.panelClass || 'panel-default'; this.accordion.addGroup(this); } @@ -145,7 +132,7 @@ export class AccordionGroup { public set isOpen(value:boolean) { this._isOpen = value; if (value) { - this.accordion.closeOthers(this); + this.accordion.closeOtherGroups(this); } } } @@ -154,11 +141,9 @@ export class AccordionGroup { selector: 'accordion-heading, [accordion-heading]' }) export class AccordionHeading { - constructor(private group:AccordionGroup, private templateRef: TemplateRef) { + constructor(private group:AccordionGroup, private templateRef:TemplateRef) { group.headingTemplate = templateRef; } } -export const accordion:Array = [ - Accordion, AccordionGroup, - AccordionHeading, AccordionTransclude]; +export const accordion:Array = [Accordion, AccordionGroup, AccordionHeading]; diff --git a/components/accordion/readme.md b/components/accordion/readme.md index 7d850b95f2..0be13a963a 100644 --- a/components/accordion/readme.md +++ b/components/accordion/readme.md @@ -1,19 +1,49 @@ -The **accordion directive** builds on top of the collapse directive to provide a list of items, with collapsible bodies that are collapsed or expanded by clicking on the item's header. +### Usage +```typescript +import {accordion} from 'ng2-bootstrap'; +``` -We can control whether expanding an item will cause the other items to close, using the `close-others` attribute on accordion. +### Annotations +```typescript +// class Accordion +@Component({ + selector: 'accordion, [accordion]', + properties: ['templateUrl', 'closeOthers'], + host: { + '[class.panel-group]': 'true' + } +}) -The body of each accordion group is transcluded in to the body of the collapsible element. +// class AccordionGroup +@Component({ + selector: 'accordion-group, [accordion-group]', + properties: ['templateUrl', 'heading', 'isOpen', 'isDisabled', 'panelClass'], + host: { + '[class.panel-open]': 'isOpen' + }, + lifecycle: [LifecycleEvent.onInit, LifecycleEvent.onDestroy] +}) -### Accordion Settings ### +// class AccordionHeading +@Directive({ + selector: 'accordion-heading, [accordion-heading]' +}) - * `is-open` (Defaults: false) : - Whether accordion group is open or closed. - * `template-url` (Defaults: `template/accordion/accordion.html`) : - Add ability to override the template url used -### Accordion Group Settings ### +export const accordion:Array = [Accordion, AccordionGroup, AccordionHeading]; +``` - * `panel-class` (Defaults: `panel-default`) : - Add ability to use Bootstrap's contextual panel classes (panel-primary, panel-success, panel-info, etc...) or your own. This must be a string. - * `template-url` (Defaults: `template/accordion/accordion-group.html`) : - Add ability to override the template url used. Note that this must be a string +### Accordion properties + - `close-others` (`?boolean=false`) - if `true` expanding one item will close all others + - `template-url` (*not yet supported*) - allows to override the template url of component (default: `components/accordion/accordion.html`) + +### Accordion Group properties + - `heading` (`?string=''`) - clickable text in accordion's group header + - `is-open` (`?boolean=false`) - is accordion group open or closed + - `is-disabled` (`?boolean=false`) - if `true` disables accordion group + - `panel-class` (`?string='panel-default'`) - provides an ability to use Bootstrap's contextual panel classes (`panel-primary`, `panel-success`, `panel-info`, etc...). List of all available classes [link](http://getbootstrap.com/components/#panels-alternatives) + - `template-url` (*not yet supported*) - allows to override the template url of component (default: `components/accordion/accordion-group.html`) + +### Accordion heading + +Instead of the `heading` attribute on the `accordion-group`, you can use an `accordion-heading` attribute on `template` element inside a group that will be used as the group's header. diff --git a/components/accordion/title.md b/components/accordion/title.md new file mode 100644 index 0000000000..6a5218df2b --- /dev/null +++ b/components/accordion/title.md @@ -0,0 +1,3 @@ +The **accordion component** builds on top of the collapse directive to provide a list of items, with collapsible bodies that are collapsed or expanded by clicking on the item's header. + +Base specifications: [bootstrap 3](http://getbootstrap.com/javascript/#collapse-example-accordion) or [bootstrap 4](http://v4-alpha.getbootstrap.com/components/collapse/#accordion-example) diff --git a/components/alert/alert.ts b/components/alert/alert.ts index 9373cad7b3..cb355fda8a 100644 --- a/components/alert/alert.ts +++ b/components/alert/alert.ts @@ -10,7 +10,7 @@ import { // TODO: templateUrl @Component({ selector: 'alert', - properties: ['type', 'dismissOnTimeout: dismiss-on-timeout'], + properties: ['type', 'dismissible', 'dismissOnTimeout'], events: ['close'], lifecycle: [LifecycleEvent.onInit] }) @@ -35,8 +35,15 @@ export class Alert { private closeable:boolean; private classes:Array = []; + private set dismissible(v:boolean){ + this.closeable = v; + } + private get dismissible():boolean{ + return this.closeable; + } + constructor(public el:ElementRef) { - this.closeable = el.nativeElement.getAttribute('(close)'); + this.closeable = this.closeable || el.nativeElement.getAttribute('(close)'); } onInit() { @@ -55,8 +62,8 @@ export class Alert { } // todo: mouse event + touch + pointer - onClose($event: MouseEvent) { - this.close.next($event); + onClose() { + this.close.next(this); this.closed = true; } } diff --git a/components/alert/readme.md b/components/alert/readme.md new file mode 100644 index 0000000000..50dc91e2f0 --- /dev/null +++ b/components/alert/readme.md @@ -0,0 +1,29 @@ +### Usage +```typescript +import {Alert} from 'ng2-bootstrap'; +``` + +### Annotations +```typescript +// class Alert +@Component({ + selector: 'alert', + properties: ['type', 'dismissible', 'dismissOnTimeout'], + events: ['close'], + lifecycle: [LifecycleEvent.onInit] +}) +``` + +### Alert properties +- `type` (`?:string='warning'`) - provide one of the four supported contextual classes: +`success`,`info`, `warning`, `danger` +- `dismissible` (`?:boolean=false`) - determines if an inline close button is displayed +- `dismiss-on-timeout` (`?number=0`) - number of milliseconds, if specified sets a timeout duration, after which the alert will be closed +- `template-url` (*not yet supported*) - allows to provide message template + +### Alert events +- `close` - fired when `alert` closed with inline button or by timeout, `$event` is an instance of `Alert` component + +*Will be deprecated*: The presence of the `(close)` event handler determines +if a close button is displayed, use `dismissible` instead + diff --git a/components/alert/title.md b/components/alert/title.md new file mode 100644 index 0000000000..2558835abd --- /dev/null +++ b/components/alert/title.md @@ -0,0 +1,5 @@ +Provides contextual feedback messages for typical user actions with the handful of available and flexible alert messages. + +Base specifications: [bootstrap 3](http://getbootstrap.com/components/#alerts) or [bootstrap 4](http://v4-alpha.getbootstrap.com/components/alerts/) + +This directive can be used to generate alerts from the dynamic model data (using the `ng-for` directive). diff --git a/components/buttons/button-checkbox.ts b/components/buttons/button-checkbox.ts index dbb13b615a..bef4d9f752 100644 --- a/components/buttons/button-checkbox.ts +++ b/components/buttons/button-checkbox.ts @@ -8,19 +8,10 @@ import { @Directive({ - selector: '[ng-model][btn-checkbox]', - properties: [ - 'btnCheckboxTrue: btn-checkbox-true', - 'btnCheckboxFalse: btn-checkbox-false' - ], + selector: '[btn-checkbox][ng-model]', + properties: ['btnCheckboxTrue', 'btnCheckboxFalse'], host: { '(click)': 'onClick()', - '[class.ng-untouched]': 'ngClassUntouched', - '[class.ng-touched]': 'ngClassTouched', - '[class.ng-pristine]': 'ngClassPristine', - '[class.ng-dirty]': 'ngClassDirty', - '[class.ng-valid]': 'ngClassValid', - '[class.ng-invalid]': 'ngClassInvalid', '[class.active]': 'state' }, lifecycle: [LifecycleEvent.onInit] @@ -35,16 +26,16 @@ export class ButtonCheckbox extends DefaultValueAccessor { super(cd, renderer, elementRef); } - private get trueValue(){ - return typeof this.btnCheckboxTrue !== 'undefined' ? this.btnCheckboxTrue : true; + onInit() { + this.toggle(this.trueValue === this.value); } - private get falseValue(){ - return typeof this.btnCheckboxFalse !== 'undefined' ? this.btnCheckboxFalse : false; + private get trueValue() { + return typeof this.btnCheckboxTrue !== 'undefined' ? this.btnCheckboxTrue : true; } - onInit() { - this.toggle(this.trueValue === this.value); + private get falseValue() { + return typeof this.btnCheckboxFalse !== 'undefined' ? this.btnCheckboxFalse : false; } toggle(state:boolean) { @@ -54,6 +45,7 @@ export class ButtonCheckbox extends DefaultValueAccessor { // model -> view writeValue(value:any) { + this.state = this.trueValue === value; this.value = value; } diff --git a/components/buttons/button-radio.ts b/components/buttons/button-radio.ts index cc5e9e6033..a3a65a2908 100644 --- a/components/buttons/button-radio.ts +++ b/components/buttons/button-radio.ts @@ -1,39 +1,35 @@ /// import { Directive, - DefaultValueAccessor, + DefaultValueAccessor, LifecycleEvent, Self, NgModel, Renderer, ElementRef } from 'angular2/angular2'; @Directive({ - selector: '[ng-model][btn-radio]', - properties: [ - 'btnRadio: btn-radio' - ], + selector: '[btn-radio][ng-model]', + properties: ['btnRadio', 'uncheckable'], host: { '(click)': 'onClick()', - '[class.ng-untouched]': 'ngClassUntouched', - '[class.ng-touched]': 'ngClassTouched', - '[class.ng-pristine]': 'ngClassPristine', - '[class.ng-dirty]': 'ngClassDirty', - '[class.ng-valid]': 'ngClassValid', - '[class.ng-invalid]': 'ngClassInvalid', '[class.active]': 'isActive' - } + }, + lifecycle: [LifecycleEvent.onInit] }) export class ButtonRadio extends DefaultValueAccessor { - private btnRadio:any; - uncheckable:any; - cd: NgModel; + private btnRadio:string; + private uncheckable:boolean; + cd:NgModel; constructor(@Self() cd:NgModel, renderer:Renderer, elementRef:ElementRef) { super(cd, renderer, elementRef); - this.uncheckable = elementRef.nativeElement.getAttribute('uncheckable') != null; + } + + onInit() { + this.uncheckable = typeof this.uncheckable !== 'undefined'; } private get isActive() { - return typeof this.btnRadio !== 'undefined' ? (this.btnRadio === this.value) : false; + return this.btnRadio === this.value; } // hack view model! diff --git a/components/buttons/readme.md b/components/buttons/readme.md new file mode 100644 index 0000000000..9e1ee07e1c --- /dev/null +++ b/components/buttons/readme.md @@ -0,0 +1,36 @@ +### Usage +```typescript +import {ButtonRadio, ButtonCheckbox} from 'ng2-bootstrap'; +``` +### Annotations +```typescript +// class ButtonRadio +@Directive({ + selector: '[btn-radio][ng-model]', + properties: ['btnRadio', 'uncheckable'], + host: { + '(click)': 'onClick()', + '[class.active]': 'isActive' + }, + lifecycle: [LifecycleEvent.onInit] +}) + +// class ButtonCheckbox +@Directive({ + selector: '[btn-checkbox][ng-model]', + properties: ['btnCheckboxTrue', 'btnCheckboxFalse'], + host: { + '(click)': 'onClick()', + '[class.active]': 'state' + }, + lifecycle: [LifecycleEvent.onInit] +}) +``` + +### Radio button properties + - `btn-radio` (`string`) - radio button value, will be set to `ng-model` + - `uncheckable` (`?boolean=false`) - if `true` radio button can be unchecked and `null` will be set to `ng-model` + +### Checkbox button properties + - `btn-checkbox-true` (`?any=true`) - truthy value + - `btn-checkbox-false` (`?any=false`) - falsy value diff --git a/components/buttons/title.md b/components/buttons/title.md new file mode 100644 index 0000000000..becfc1a3f7 --- /dev/null +++ b/components/buttons/title.md @@ -0,0 +1,3 @@ +There are two directives that can make a group of buttons behave like a set of checkboxes, radio buttons, or a hybrid where radio buttons can be unchecked. + +Base specifications: [bootstrap 3](http://getbootstrap.com/javascript/#buttons) or [bootstrap 4](http://v4-alpha.getbootstrap.com/components/buttons/#checkbox-and-radio-buttons) diff --git a/components/carousel/carousel.ts b/components/carousel/carousel.ts index f42f0d3c97..a406fe4a04 100644 --- a/components/carousel/carousel.ts +++ b/components/carousel/carousel.ts @@ -7,14 +7,13 @@ import { CORE_DIRECTIVES, NgClass } from 'angular2/angular2'; -import {Ng2BootstrapConfig} from '../ng2-bootstrap-config'; +import {Ng2BootstrapConfig, Ng2BootstrapTheme} from '../ng2-bootstrap-config'; export enum Direction {UNKNOWN, NEXT, PREV} - // todo: add animate const NAVIGATION = { - bs4: ` + [Ng2BootstrapTheme.BS4]: ` Previous @@ -24,7 +23,7 @@ const NAVIGATION = { Next `, - bs3: ` + [Ng2BootstrapTheme.BS3]: ` @@ -36,12 +35,7 @@ const NAVIGATION = { @Component({ selector: 'carousel, [carousel]', - properties: [ - 'interval', - 'noTransition', - 'noPause', - 'noWrap' - ], + properties: ['interval', 'noTransition', 'noPause', 'noWrap'], lifecycle: [LifecycleEvent.onDestroy] }) // todo: @@ -53,7 +47,7 @@ const NAVIGATION = {
  • - ${NAVIGATION[Ng2BootstrapConfig.theme] || NAVIGATION.bs3} + ${NAVIGATION[Ng2BootstrapConfig.theme]}

    `, directives: [CORE_DIRECTIVES, NgClass] @@ -81,7 +75,7 @@ export class Carousel { this.restartTimer(); } - public select(nextSlide:Slide, direction?:Direction = Direction.UNKNOWN) { + public select(nextSlide:Slide, direction:Direction = Direction.UNKNOWN) { let nextIndex = nextSlide.index; if (direction === Direction.UNKNOWN) { direction = nextIndex > this.getCurrentIndex() ? Direction.NEXT : Direction.PREV; @@ -212,11 +206,7 @@ export class Carousel { @Component({ selector: 'slide, [slide]', - properties: [ - 'direction', - 'active', - 'index' - ], + properties: ['direction', 'active', 'index'], host: { '[class.active]': 'active', '[class.item]': 'true', @@ -226,7 +216,9 @@ export class Carousel { }) @View({ template: ` -
    +
    + +
    `, directives: [NgClass] }) diff --git a/components/carousel/readme.md b/components/carousel/readme.md new file mode 100644 index 0000000000..c066260998 --- /dev/null +++ b/components/carousel/readme.md @@ -0,0 +1,45 @@ +### Usage +```typescript +import {carousel} from 'ng2-bootstrap'; +``` + +### Annotations +```typescript +// class Carousel +@Component({ + selector: 'carousel, [carousel]', + properties: ['interval', 'noTransition', 'noPause', 'noWrap'], + lifecycle: [LifecycleEvent.onDestroy] +}) + +// class Slide +@Component({ + selector: 'slide, [slide]', + properties: ['direction', 'active', 'index'], + host: { + '[class.active]': 'active', + '[class.item]': 'true', + '[class.carousel-item]': 'true' + }, + lifecycle: [LifecycleEvent.onInit, LifecycleEvent.onDestroy] +}) + +export const carousel:Array = [Carousel, Slide]; +``` + +### Carousel properties +- `interval` (`?number=5000`) - amount of time in milliseconds to delay between automatically cycling an item. If `false`, carousel will not automatically cycle +- `no-transition` (`?boolean=false`) - if `true` will disable transitions on the carousel +- `no-pause` (`?boolean=false`) - if `true` will disable pausing on carousel mouse hover +- `no-wrap` (`?boolean=false`) - if `true` the carousel will not cycle continuously and will have hard stops (prevent looping) +- `pause` (*not yet supported*) (`?string='hover'`) - event group name which pauses the cycling of the carousel, if `hover` pauses on mouseenter and resumes on mouseleave +- `keyboard` (*not yet supported*) (`?boolean=true`) - if `false` carousel will not react to keyboard events +- `template-url` (*not yet supported*) - allows to override the template url of component (default: `components/carousel/carousel.html`) +- *note*: swiping not yet supported + +### Slide properties +- `active` (`?boolean=false`) - currently active slide +- `index` (`?number`) - index of slide in carousel's slides +- `direction` (`?string`) (*not yet supported*) +- `actual` (*not yet supported*) (`?any`) - will be bind to slider context, to be used from template +- `template-url` (*not yet supported*) (`?string='hover'`) - allows to override the template url of component (default: `components/carousel/slide.html`) diff --git a/components/carousel/title.md b/components/carousel/title.md new file mode 100644 index 0000000000..5b40c0c3f9 --- /dev/null +++ b/components/carousel/title.md @@ -0,0 +1,3 @@ +A slideshow component for cycling through elements—images or slides of text—like a carousel. *Nested carousels are not supported.* + +Base specifications: [bootstrap 3](http://getbootstrap.com/javascript/#carousel) or [bootstrap 4](http://v4-alpha.getbootstrap.com/components/carousel/) diff --git a/components/collapse/collapse.ts b/components/collapse/collapse.ts index de770e4e1a..7670d0dbdc 100644 --- a/components/collapse/collapse.ts +++ b/components/collapse/collapse.ts @@ -10,9 +10,7 @@ import { // todo: add init and on change @Directive({ selector: '[collapse]', - properties: [ - 'collapse' - ], + properties: ['collapse'], host: { '[class.in]': 'isExpanded', '[class.collapse]': 'isCollapse', diff --git a/components/collapse/readme.md b/components/collapse/readme.md new file mode 100644 index 0000000000..7e15820d66 --- /dev/null +++ b/components/collapse/readme.md @@ -0,0 +1,24 @@ +### Usage +```typescript +import {Collapse} from 'ng2-bootstrap'; +``` + +### Annotations +```typescript +// class Collapse +@Directive({ + selector: '[collapse]', + properties: ['collapse'], + host: { + '[class.in]': 'isExpanded', + '[class.collapse]': 'isCollapse', + '[class.collapsing]': 'isCollapsing', + '[attr.aria-expanded]': 'isExpanded', + '[attr.aria-hidden]': 'isCollapsed', + '[style.height]': 'height' + } +}) +``` + +### Collapse properties +- `collapse` (`boolean=false`) - if `true` collapse block will be expanded diff --git a/components/collapse/title.md b/components/collapse/title.md new file mode 100644 index 0000000000..7bfc0cea44 --- /dev/null +++ b/components/collapse/title.md @@ -0,0 +1,4 @@ +Collapse component allows you to toggle content on your pages with a bit of JavaScript and some classes. Flexible component that utilizes a handful of classes (from the **required transitions component**(*not yet implemented*)) for easy toggle behavior. + +Base specifications: [bootstrap 3](http://getbootstrap.com/javascript/#collapse) or [bootstrap 4](http://v4-alpha.getbootstrap.com/components/collapse/) + diff --git a/components/dropdown/dropdown-keyboard-nav.ts b/components/dropdown/dropdown-keyboard-nav.ts index 919aa950a7..b03b59d7c0 100644 --- a/components/dropdown/dropdown-keyboard-nav.ts +++ b/components/dropdown/dropdown-keyboard-nav.ts @@ -12,7 +12,7 @@ import {Dropdown} from './dropdown'; export class KeyboardNav { constructor(private dd:Dropdown, private el:ElementRef) { console.warn('keyboard-nav deprecated'); - dd.keynavEnabled = true; + dd.keyboardNav = true; } onKeydown(event:KeyboardEvent) { diff --git a/components/dropdown/dropdown-menu.ts b/components/dropdown/dropdown-menu.ts index 942536522c..a272bc7339 100644 --- a/components/dropdown/dropdown-menu.ts +++ b/components/dropdown/dropdown-menu.ts @@ -5,9 +5,7 @@ import {Dropdown} from './dropdown'; @Directive({ selector: '[dropdown-menu], .dropdown-menu', - host: { - '[attr.templateUrl]': 'templateUrl' - }, + properties: ['templateUrl'], lifecycle: [LifecycleEvent.onInit] }) export class DropdownMenu { diff --git a/components/dropdown/dropdown-service.ts b/components/dropdown/dropdown-service.ts index 3d827fdf04..1ac0fa2817 100644 --- a/components/dropdown/dropdown-service.ts +++ b/components/dropdown/dropdown-service.ts @@ -66,7 +66,7 @@ export class DropdownService { return; } - if (this.openScope.keynavEnabled && this.openScope.isOpen && + if (this.openScope.keyboardNav && this.openScope.isOpen && (event.which === 38 || event.which === 40)) { event.preventDefault(); event.stopPropagation(); diff --git a/components/dropdown/dropdown.ts b/components/dropdown/dropdown.ts index 2ea7cdbfad..0dd2218674 100644 --- a/components/dropdown/dropdown.ts +++ b/components/dropdown/dropdown.ts @@ -10,15 +10,8 @@ import {dropdownService, ALWAYS} from './dropdown-service'; @Directive({ selector: '[dropdown]', - properties: [ - 'isOpen', - 'autoClose', - 'keynavEnabled: keyboardNav', - 'dropdownAppendToBody' - ], - events: [ - 'onToggle' - ], + properties: ['isOpen', 'autoClose', 'keyboardNav', 'dropdownAppendToBody'], + events: ['onToggle'], lifecycle: [LifecycleEvent.onInit, LifecycleEvent.onDestroy], host: { '[class.dropdown]': 'true', @@ -32,7 +25,7 @@ export class Dropdown { private onToggle:EventEmitter = new EventEmitter(); public autoClose:string; - public keynavEnabled:boolean; + public keyboardNav:boolean; // index of selected element public selectedOption:number; // drop menu html @@ -48,7 +41,7 @@ export class Dropdown { onInit() { this.autoClose = this.autoClose || ALWAYS; - this.keynavEnabled = typeof this.keynavEnabled !== 'undefined'; + this.keyboardNav = typeof this.keyboardNav !== 'undefined'; this.dropdownAppendToBody = typeof this.dropdownAppendToBody !== 'undefined'; if (this.isOpen) { // todo: watch for event get-is-open? @@ -61,7 +54,7 @@ export class Dropdown { } } - public set dropDownMenu(dropdownMenu:DropdownMenuInterface){ + public set dropDownMenu(dropdownMenu:DropdownMenuInterface) { // init drop down menu this.menuEl = dropdownMenu.el; @@ -74,7 +67,7 @@ export class Dropdown { } } - public set dropDownToggle(dropdownToggle: DropdownToggleInterface){ + public set dropDownToggle(dropdownToggle:DropdownToggleInterface) { // init toggle element this.toggleEl = dropdownToggle.el; } diff --git a/components/dropdown/readme.md b/components/dropdown/readme.md new file mode 100644 index 0000000000..59a5d9f7ee --- /dev/null +++ b/components/dropdown/readme.md @@ -0,0 +1,72 @@ +### Usage +```typescript +import {dropdown} from 'ng2-bootstrap'; +``` + +```html + +
    + +
    + +
    + +
    +
    +``` + +### Annotations +```typescript +// class Dropdown +@Directive({ + selector: '[dropdown]', + properties: ['isOpen', 'autoClose', 'keyboardNav', 'dropdownAppendToBody'], + events: ['onToggle'], + lifecycle: [LifecycleEvent.onInit, LifecycleEvent.onDestroy], + host: { + '[class.dropdown]': 'true', + '[class.open]': 'isOpen' + } +}) + +// class DropdownToggle +@Directive({ + selector: '[dropdown-toggle]', + properties: ['disabled'], + host: { + '(click)': 'toggleDropdown($event)', + '[class.dropdown-toggle]': 'true', + '[class.disabled]': 'disabled', + '[attr.aria-haspopup]': 'true', + '[attr.aria-expanded]': 'isOpen' + }, + lifecycle: [LifecycleEvent.onInit] +}) + +// class DropdownMenu +@Directive({ + selector: '[dropdown-menu], .dropdown-menu', + properties: ['templateUrl'], + lifecycle: [LifecycleEvent.onInit] +}) + +export const dropdown: Array = [Dropdown, DropdownMenu, DropdownToggle]; +``` + +### Dropdown properties +- `is-open` (`?boolean=false`) - if `true` dropdown will be opened +- `auto-close` (`?string='always'`) - behaviour vary: + * `always` - (default) automatically closes the dropdown when any of its elements is clicked + * `outsideClick` - closes the dropdown automatically only when the user clicks any element outside the dropdown + * `disabled` - disables the auto close. You can then control the open/close status of the dropdown manually, by using `is-open`. Please notice that the dropdown will still close if the toggle is clicked, the `esc` key is pressed or another dropdown is open +- `keyboard-nav` (`?boolean=false`) - if `true` will enable navigation of dropdown list elements with the arrow keys +- `dropdown-append-to-body` (*not yet tested*) (`?boolean=false`) - if `true` `dropdown-menu` content will be appended to the body. This is useful when the dropdown button is inside a div with `overflow: hidden`, and the menu would otherwise be hidden + +### Dropdown events +- `on-toggle` - fired when `dropdown` toggles, `$event:boolean` equals dropdown `is-open` state + +### Dropdown toggle properties +- `disabled` (`?boolean=false`) - if `true` dropdown toggle will be disabled + +### Dropdown menu properties +- `template-url` (*not yet supported*) - allows to provide dropdown menu template diff --git a/components/dropdown/title.md b/components/dropdown/title.md new file mode 100644 index 0000000000..eb2036896b --- /dev/null +++ b/components/dropdown/title.md @@ -0,0 +1,4 @@ +Dropdowns are toggleable, contextual overlays for displaying lists of links and more. They’re made interactive with the included dropdown directives. + +Base specifications: [bootstrap 3](http://getbootstrap.com/javascript/#dropdowns) or [bootstrap 4](http://v4-alpha.getbootstrap.com/components/dropdowns/) + diff --git a/components/ng2-bootstrap-config.ts b/components/ng2-bootstrap-config.ts index 94e97753f9..b3f999c669 100644 --- a/components/ng2-bootstrap-config.ts +++ b/components/ng2-bootstrap-config.ts @@ -1,16 +1,16 @@ -export enum Theme {BS3 = 'bs3', BS4 = 'bs4'} - -interface Window { - __theme: string; -} - +export enum Ng2BootstrapTheme {BS3 = 1, BS4 = 2} export class Ng2BootstrapConfig { - private static _theme: Theme; - static get theme():Theme { - return this._theme || window.__theme === 'bs4' ? Theme.BS4 : Theme.BS3; + private static _theme: Ng2BootstrapTheme; + static get theme():Ng2BootstrapTheme { + // hack as for now + let w: any = window; + if (w && w.__theme === 'bs4') { + return Ng2BootstrapTheme.BS4; + } + return (this._theme || Ng2BootstrapTheme.BS3); } - static set theme(v:Theme){ + static set theme(v:Ng2BootstrapTheme){ this._theme = v; } } diff --git a/components/pagination/pagination.ts b/components/pagination/pagination.ts index 626185c3f8..28d6287bae 100644 --- a/components/pagination/pagination.ts +++ b/components/pagination/pagination.ts @@ -29,19 +29,12 @@ const paginationConfig = { }; @Component({ - selector: 'pagination, [pagination]', + selector: 'pagination[ng-model], [pagination][ng-model]', properties: [ - 'maxSize', - 'rotate', - 'boundaryLinks', - 'totalItems', - 'firstText', - 'previousText', - 'nextText', - 'lastText', - 'disabled', - 'directionLinks', - 'itemsPerPage' + 'rotate', 'disabled', + 'totalItems', 'itemsPerPage', 'maxSize', + 'boundaryLinks', 'directionLinks', + 'firstText', 'previousText', 'nextText', 'lastText' ], events: ['numPages'], lifecycle: [LifecycleEvent.onInit] @@ -80,7 +73,7 @@ const paginationConfig = { export class Pagination extends DefaultValueAccessor { public config:any; - private classMap: string; + private classMap:string; private maxSize:number; private rotate:boolean; private boundaryLinks:any; @@ -108,7 +101,7 @@ export class Pagination extends DefaultValueAccessor { this.totalPages = this.calculateTotalPages(); } - private get totalItems() { + private get totalItems():number { return this._totalItems; } @@ -121,10 +114,10 @@ export class Pagination extends DefaultValueAccessor { return this._totalPages; } - private set totalPages(v: number) { + private set totalPages(v:number) { this._totalPages = v; this.numPages.next(v); - if (this.page > v) { + if (this.page > v) { this.selectPage(v); } } @@ -262,26 +255,29 @@ const pagerConfig = { }; @Component({ - selector: 'pager, [pager]', + selector: 'pager[ng-model], [pager][ng-model]', properties: [ - 'align', 'totalItems', 'previousText', 'nextText', 'itemsPerPage' + 'align', + 'totalItems', 'itemsPerPage', + 'previousText', 'nextText', ], lifecycle: [LifecycleEvent.onInit] }) @View({ template: ` `, directives: [NgClass] }) export class Pager extends Pagination { + private align: boolean = pagerConfig.align; + public config = pagerConfig; constructor(@Self() cd:NgModel, renderer:Renderer, elementRef:ElementRef) { - this.config = pagerConfig; super(cd, renderer, elementRef); } } -export const pagination = [Pagination, Pager]; +export const pagination:Array = [Pagination, Pager]; diff --git a/components/pagination/readme.md b/components/pagination/readme.md new file mode 100644 index 0000000000..57c9392332 --- /dev/null +++ b/components/pagination/readme.md @@ -0,0 +1,61 @@ +### Usage +```typescript +import {pagination} from 'ng2-bootstrap'; +``` + +### Annotations +```typescript +// class Pagination +@Component({ + selector: 'pagination[ng-model], [pagination][ng-model]', + properties: [ + 'rotate', 'disabled', + 'totalItems', 'itemsPerPage', 'maxSize', + 'boundaryLinks', 'directionLinks', + 'firstText', 'previousText', 'nextText', 'lastText' + ], + events: ['numPages'], + lifecycle: [LifecycleEvent.onInit] +}) + +// class Pager +@Component({ + selector: 'pager[ng-model], [pager][ng-model]', + properties: [ + 'align', + 'totalItems', 'itemsPerPage', + 'previousText', 'nextText', + ], + lifecycle: [LifecycleEvent.onInit] +}) + +export const pagination:Array = [Pagination, Pager]; +``` +### Pagination properties + - `rotate` (`?boolean=true`) - if `true` current page will in the middle of pages list + - `disabled` (`?boolean=false`) - if `true` pagination component will be disabled + - `total-items` (`number`) - total number of items in all pages + - `items-per-page` (`?number=10`) - maximum number of items per page. If value less than 1 will display all items on one page + - `max-size` (`?number=undefined`) - limit number for page links in pager + - `boundary-links` (`?boolean=true`) - if `false` first and last buttons will be hidden + - `direction-links` (`?boolean=true`) - if `false` previous and next buttons will be hidden + - `previous-text` (`?string='Previous'`) - previous button text + - `next-text` (`?string='Next'`) - next button text + - `first-text` (`?string='First'`) - first button text + - `last-text` (`?string='Last'`) - last button text + - `template-url`(*not yet supported*) (`?string`) - allows to override the template url of component (default: `components/pagination/pagination.html`) + +### Pagination events +- `num-pages` - fired when total pages count changes, `$event:number` equals to total pages count + +### Pager properties + - `align` (`?boolean=true`) - if `true` aligns each link to the sides of pager + - `disabled` (`?boolean=false`) - if `true` pagination component will be disabled + - `total-items` (`number`) - total number of items in all pages + - `items-per-page` (`?number=10`) - maximum number of items per page. If value less than 1 will display all items on one page + - `previous-text` (`?string='Previous'`) - previous button text + - `next-text` (`?string='Next'`) - next button text + - `template-url`(*not yet supported*) (`?string`) - allows to override the template url of component (default: `components/pagination/pager.html`) + +### Pager events + - `num-pages` - fired when total pages count changes, `$event:number` equals to total pages count diff --git a/components/pagination/title.md b/components/pagination/title.md new file mode 100644 index 0000000000..3f45c9e934 --- /dev/null +++ b/components/pagination/title.md @@ -0,0 +1,6 @@ +**Pagination** - provide pagination links for your site or app with the multi-page pagination component, or the simpler pager alternative. + +**Pager** - quick previous and next links for simple pagination implementations with light markup and styles. It's great for simple sites like blogs or magazines. + +Base specifications: [bootstrap 3](http://getbootstrap.com/components/#pagination) or [bootstrap 4](http://v4-alpha.getbootstrap.com/components/pagination/) + diff --git a/components/progressbar/progressbar.ts b/components/progressbar/progressbar.ts index 9558ca4ae4..846857e826 100644 --- a/components/progressbar/progressbar.ts +++ b/components/progressbar/progressbar.ts @@ -70,9 +70,7 @@ export class Progress { // todo: use query from progress? @Component({ selector: 'bar, [bar]', - properties: [ - 'type', 'value' - ], + properties: ['type', 'value'], lifecycle: [LifecycleEvent.onInit, LifecycleEvent.onDestroy] }) @View({ diff --git a/components/progressbar/readme.md b/components/progressbar/readme.md new file mode 100644 index 0000000000..2f67b62446 --- /dev/null +++ b/components/progressbar/readme.md @@ -0,0 +1,39 @@ +### Usage +```typescript +import {progressbar} from 'ng2-bootstrap'; +``` + +### Annotations +```typescript +// class Progress +@Directive({ + selector: 'bs-progress, [progress]', + properties: ['animate', 'max'], + host: { + 'class': 'progress', + '[attr.max]': 'max' + }, + lifecycle: [LifecycleEvent.onInit] +}) + +// class Bar +@Component({ + selector: 'bar, [bar]', + properties: ['type', 'value'], + lifecycle: [LifecycleEvent.onInit, LifecycleEvent.onDestroy] +}) + +// class Progressbar +@Component({ + selector: 'progressbar, [progressbar]', + properties: ['animate', 'max', 'type', 'value'] +}) +``` + +### Properties +**Note**: all components have same meaning of properties + - `value` (`*number`) - current value of progress bar + - `type` (`*string`) - provide one of the four supported contextual classes: + `success`,`info`, `warning`, `danger` + - `max` (`?number=100`) - maximum total value of progress element + - `animate` (`?boolean=true`) - if `true` changing `value` of progress bar will be animated (*note*: not supported by Bootstrap 4) diff --git a/components/progressbar/title.md b/components/progressbar/title.md new file mode 100644 index 0000000000..7bb2a4ef81 --- /dev/null +++ b/components/progressbar/title.md @@ -0,0 +1,3 @@ +Provide up-to-date feedback on the progress of a workflow or action with simple yet flexible progress bars. + +Base specifications: [bootstrap 3](http://getbootstrap.com/components/#progress) or [bootstrap 4](http://v4-alpha.getbootstrap.com/components/progress/) diff --git a/components/rating/rating.ts b/components/rating/rating.ts index 2b591715c2..f28599db63 100644 --- a/components/rating/rating.ts +++ b/components/rating/rating.ts @@ -9,7 +9,7 @@ import { // TODO: templateUrl @Component({ - selector: 'rating', + selector: 'rating[ng-model]', properties: [ 'max', 'readonly', 'titles', 'stateOn', 'stateOff', @@ -102,7 +102,7 @@ export class Rating extends DefaultValueAccessor { private reset() { this.value = this.preValue; - this.onLeave.next(null); + this.onLeave.next(this.value); } private onKeydown(event:KeyboardEvent) { diff --git a/components/rating/readme.md b/components/rating/readme.md new file mode 100644 index 0000000000..1367a93a14 --- /dev/null +++ b/components/rating/readme.md @@ -0,0 +1,34 @@ +### Usage +```typescript +import {Rating} from 'ng2-bootstrap'; +``` + +### Annotations +```typescript +// class Rating +@Component({ + selector: 'rating[ng-model]', + properties: [ + 'max', 'readonly', 'titles', + 'stateOn', 'stateOff', + 'ratingStates' + ], + events: ['onHover', 'onLeave'], + host: { + '(keydown)': 'onKeydown($event)' + }, + lifecycle: [LifecycleEvent.onInit] +}) +``` + +### Rating properties + - `max` (`?number=5`) - number of icons + - `readonly` (`?boolean=false`) - if `true` will not react on any user events + - `titles` (`?Array`) - array of icons titles, default: (`["one", "two", "three", "four", "five"]`) + - `state-on` (`?string='glyphicon-star'`) - selected icon class + - `state-off` (`?string='glyphicon-star-empty'`) - unselected icon class + - `rating-states` (`?Array<{stateOn:string, stateOff:string}>`) - array of custom icons classes + +### Rating events + - `on-hover` - fired when icon selected, `$event:number` equals to selected rating + - `on-leave` - fired when icon selected, `$event:number` equals to previous rating value diff --git a/components/rating/title.md b/components/rating/title.md new file mode 100644 index 0000000000..39acb3afa2 --- /dev/null +++ b/components/rating/title.md @@ -0,0 +1,3 @@ +Rating component that will take care of visualising a star rating bar + +*Note*: Bootstrap 4 do not include glyphicons anymore, so if you want to continue use this font, you will need to add a link to [`glyphicons.css`](https://github.com/valor-software/ng2-bootstrap/blob/master/demo/assets/css/glyphicons.css) diff --git a/components/tabs/readme.md b/components/tabs/readme.md new file mode 100644 index 0000000000..6101f529fc --- /dev/null +++ b/components/tabs/readme.md @@ -0,0 +1,60 @@ +### Usage +```typescript +import {tabs} from 'ng2-bootstrap'; +``` + +```html + + Tab 1 content + + + Tab 2 content + + +``` + +### Annotations +```typescript +// class Tabset +@Component({ + selector: 'tabset', + properties: ['vertical', 'justified', 'type'], + lifecycle: [LifecycleEvent.onInit] +}) + +// class Tab +@Directive({ + selector: 'tab, [tab]', + properties: ['active', 'disable', 'disabled', 'heading'], + events: ['select', 'deselect'], + host: { + '[class.tab-pane]': 'true', + '[class.active]': 'active' + }, + lifecycle: [LifecycleEvent.onInit, LifecycleEvent.onDestroy, + LifecycleEvent.onCheck] +}) + +// class TabHeading +@Directive({selector: '[tab-heading]'}) + +export const tabs:Array = [Tab, TabHeading, Tabset]; +``` + +### Tabset properties + - `vertical` (`?boolean=false`) - if `true` tabs will be placed vertically + - `justified` (`?boolean=false`) - if `true` tabs fill the container and have a consistent width + - `type` (`?string='tabs'`) - navigation context class: 'tabs' or 'pills' + +### Tab properties + - `heading` (`string`) - tab header text + - `active` (`?boolean=false`) - if tab is active equals true, or set `true` to activate tab + - `disabled` (`?boolean=false`) - if `true` tab can not be activated + - `disable` (**note: deprecated**) - mirrors `disabled` property + +### Tab events + - `select` - fired when `tab` became active, `$event:Tab` equals to selected instance of `Tab` component + - `deselect` - fired when `tab` became inactive, `$event:Tab` equals to deselected instance of `Tab` component + +### Tab heading +Should be used to mark `