├── fuel-ui.ts ├── src ├── components │ ├── Slider │ │ ├── Slider.html │ │ ├── readme.md │ │ └── Slider.ts │ ├── TableSortable │ │ ├── TableSortableSorting.ts │ │ ├── TableSortableColumn.ts │ │ ├── TableSortable.html │ │ ├── TableSortable.scss │ │ ├── readme.md │ │ ├── TableSortable.ts │ │ └── TableSortable.Demo.ts │ ├── Pagination │ │ ├── Pagination.scss │ │ ├── readme.md │ │ ├── Pagination.html │ │ └── Pagination.ts │ ├── Tag │ │ ├── Tag.scss │ │ ├── TagSet.html │ │ ├── TagSet.ts │ │ ├── readme.md │ │ └── Tag.ts │ ├── Modal │ │ ├── Modal.scss │ │ ├── Modal.html │ │ ├── readme.md │ │ ├── Modal.ts │ │ └── Modal.Demo.ts │ ├── Dropdown │ │ ├── readme.md │ │ ├── Dropdown.html │ │ ├── Dropdown.ts │ │ └── Dropdown.Demo.ts │ ├── TimePicker │ │ ├── TimePicker.scss │ │ ├── readme.md │ │ └── TimePicker.html │ ├── Accordion │ │ ├── AccordionItem.html │ │ ├── Accordion.scss │ │ ├── readme.md │ │ ├── Accordion.ts │ │ └── AccordionItem.ts │ ├── Alert │ │ ├── Alert.scss │ │ ├── Alert.html │ │ ├── readme.md │ │ ├── Alert.ts │ │ └── Alert.Demo.ts │ ├── DatePicker │ │ ├── DateRangePickerDate.html │ │ ├── DatePickerProviders.ts │ │ ├── DatePickerCalendar.html │ │ ├── readme.md │ │ ├── DatePicker.html │ │ ├── DatePickerField.ts │ │ ├── DatePickerCalendar.scss │ │ ├── DateRangePicker.html │ │ ├── DatePicker.scss │ │ ├── DatePickerCalendar.ts │ │ └── DatePicker.Demo.ts │ ├── Carousel │ │ ├── carousel.scss │ │ ├── carousel.html │ │ └── Carousel.Demo.ts │ ├── TextExpander │ │ ├── TextExpander.html │ │ └── TextExpander.ts │ ├── OffCanvasMenu │ │ ├── OffCanvasMenu.html │ │ ├── readme.md │ │ ├── OffCanvasMenu.scss │ │ └── OffCanvasMenu.ts │ ├── Tab │ │ ├── TabSet.html │ │ ├── readme.md │ │ ├── Tab.ts │ │ └── TabSet.ts │ ├── Progress │ │ ├── readme.md │ │ └── Progress.Demo.ts │ ├── InfiniteScroller │ │ └── readme.md │ ├── components.ts │ └── demoComponents.ts ├── styles │ ├── _bourbon.scss │ ├── _framework.scss │ ├── fuel-ui.scss │ ├── _variables.scss │ ├── _animation.scss │ ├── slider_pips.scss │ ├── slider.scss │ └── _media_queries.scss ├── animations │ ├── animations.ts │ ├── demoAnimations.ts │ └── Collapse │ │ ├── readme.md │ │ ├── Collapse.ts │ │ └── Collapse.Demo.ts ├── utilities │ ├── utilities.ts │ ├── StringUtils.ts │ ├── DateUtils.ts │ ├── AnimationUtils.ts │ ├── DetectionUtils.ts │ ├── DateRange.ts │ ├── demoUtilities.ts │ └── ElementUtils.ts ├── fuel-ui.ts ├── fuel-ui-demo.ts ├── directives │ ├── Tooltip │ │ ├── readme.md │ │ └── Tooltip.ts │ ├── directives.ts │ ├── CodeHighlighter │ │ ├── CodeHighlighter.ts │ │ ├── readme.md │ │ └── CodeHighlighter.Demo.ts │ ├── demoDirectives.ts │ └── Animation │ │ ├── readme.md │ │ ├── Animation.ts │ │ └── Animation.Demo.ts ├── pipes │ ├── MapToIterable │ │ ├── MapToIterable.ts │ │ ├── readme.md │ │ └── MapToIterable.Demo.ts │ ├── pipes.ts │ ├── Range │ │ ├── Range.ts │ │ ├── readme.md │ │ └── Range.Demo.ts │ ├── demoPipes.ts │ ├── Format │ │ ├── readme.md │ │ └── Format.ts │ └── OrderBy │ │ ├── readme.md │ │ └── OrderBy.ts └── demo.routes.ts ├── images └── carouselImages │ ├── beach.png │ ├── river.jpg │ └── windmill.jpg ├── typings ├── index.d.ts ├── modules │ └── es6-promise │ │ ├── typings.json │ │ └── index.d.ts └── globals │ ├── core-js │ └── typings.json │ └── hammerjs │ └── typings.json ├── fuel-ui.d.ts ├── typings.json ├── tsconfig.json ├── fuel-ui.js ├── config.js ├── bower.json ├── index.html ├── package.json └── .gitignore /fuel-ui.ts: -------------------------------------------------------------------------------- 1 | export * from './src/fuel-ui'; -------------------------------------------------------------------------------- /src/components/Slider/Slider.html: -------------------------------------------------------------------------------- 1 | 2 |
-------------------------------------------------------------------------------- /src/styles/_bourbon.scss: -------------------------------------------------------------------------------- 1 | @import "../../node_modules/bourbon/app/assets/stylesheets/bourbon"; -------------------------------------------------------------------------------- /images/carouselImages/beach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmx/fuel-ui/master/images/carouselImages/beach.png -------------------------------------------------------------------------------- /images/carouselImages/river.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmx/fuel-ui/master/images/carouselImages/river.jpg -------------------------------------------------------------------------------- /images/carouselImages/windmill.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmx/fuel-ui/master/images/carouselImages/windmill.jpg -------------------------------------------------------------------------------- /src/styles/_framework.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | @import "slider"; 3 | @import "slider_pips"; 4 | @import "hint"; -------------------------------------------------------------------------------- /src/components/TableSortable/TableSortableSorting.ts: -------------------------------------------------------------------------------- 1 | export class TableSortableSorting { 2 | constructor(public column: string, public descending: boolean) {} 3 | } -------------------------------------------------------------------------------- /src/animations/animations.ts: -------------------------------------------------------------------------------- 1 | import {Collapse} from "./Collapse/Collapse"; 2 | 3 | export var FUELUI_ANIMATION_PROVIDERS = [ 4 | Collapse() 5 | ]; 6 | export * from "./Collapse/Collapse"; -------------------------------------------------------------------------------- /typings/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /src/components/Pagination/Pagination.scss: -------------------------------------------------------------------------------- 1 | .fuel-ui-pagination { 2 | a{ 3 | cursor: pointer; 4 | 5 | &:hover { 6 | text-decoration: none; 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /src/utilities/utilities.ts: -------------------------------------------------------------------------------- 1 | export * from './DateRange'; 2 | export * from './DateUtils'; 3 | export * from './DetectionUtils'; 4 | export * from './ElementUtils'; 5 | export * from './StringUtils'; -------------------------------------------------------------------------------- /src/components/Tag/Tag.scss: -------------------------------------------------------------------------------- 1 | .fuel-ui-tag-label { 2 | margin: 0 .25em; 3 | 4 | &.disabled { 5 | cursor: not-allowed; 6 | background: #818a91; 7 | color: darkgray; 8 | } 9 | } -------------------------------------------------------------------------------- /src/fuel-ui.ts: -------------------------------------------------------------------------------- 1 | export * from "./animations/animations"; 2 | export * from "./components/components"; 3 | export * from "./directives/directives"; 4 | export * from "./pipes/pipes"; 5 | export * from './utilities/utilities'; -------------------------------------------------------------------------------- /fuel-ui.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./src/animations/animations"; 2 | export * from "./src/components/components"; 3 | export * from "./src/directives/directives"; 4 | export * from "./src/pipes/pipes"; 5 | export * from './src/utilities/utilities'; 6 | -------------------------------------------------------------------------------- /src/fuel-ui-demo.ts: -------------------------------------------------------------------------------- 1 | export * from "./animations/demoAnimations"; 2 | export * from "./components/demoComponents"; 3 | export * from "./directives/demoDirectives"; 4 | export * from "./pipes/demoPipes"; 5 | export * from "./utilities/demoUtilities"; -------------------------------------------------------------------------------- /src/animations/demoAnimations.ts: -------------------------------------------------------------------------------- 1 | import {COLLAPSE_DEMO_PROVIDERS, CollapseDemo} from "./Collapse/Collapse.Demo"; 2 | 3 | export var FUELUI_DEMO_ANIMATION_PROVIDERS = [ 4 | COLLAPSE_DEMO_PROVIDERS 5 | ]; 6 | 7 | export * from "./Collapse/Collapse.Demo"; -------------------------------------------------------------------------------- /src/styles/fuel-ui.scss: -------------------------------------------------------------------------------- 1 | @import "framework"; 2 | @import "../components/**/*"; 3 | @import "../directives/**/*"; 4 | 5 | .fuel-ui-clickable { 6 | cursor: pointer; 7 | 8 | &.disabled { 9 | cursor: not-allowed; 10 | } 11 | } -------------------------------------------------------------------------------- /src/components/Modal/Modal.scss: -------------------------------------------------------------------------------- 1 | @import "../../styles/bourbon"; 2 | 3 | $duration: 1s; 4 | 5 | .fuel-ui-modal-fade-in{ 6 | @include animation-name(fadeInDown); 7 | @include animation-duration($duration); 8 | @include animation-timing-function(ease); 9 | } -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fuel-ui", 3 | "dependencies": { 4 | "es6-promise": "registry:npm/es6-promise#3.0.0+20160211003958" 5 | }, 6 | "globalDependencies": { 7 | "core-js": "registry:dt/core-js#0.0.0+20160317120654", 8 | "hammerjs": "registry:dt/hammerjs#2.0.4+20160417130828" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/components/Dropdown/readme.md: -------------------------------------------------------------------------------- 1 | ### Dropdown Selector 2 | `dropdown` - `` 3 | 4 | ### dropdown Settings 5 | 6 | * `label` _- string - 7 | Dropdown label 8 | 9 | ### Dropdown Example 10 | ```javascript 11 | label: string = "Dropdown Label"; 12 | ``` 13 | 14 | ```html 15 | 17 | 18 | ``` -------------------------------------------------------------------------------- /src/components/Tag/TagSet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "noImplicitAny": false, 6 | "sourceMap": false, 7 | "experimentalDecorators": true, 8 | "emitDecoratorMetadata": true, 9 | "outDir": "dist" 10 | }, 11 | "filesGlob": [ 12 | "./**/*.ts", 13 | "./typings/index.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /src/components/TimePicker/TimePicker.scss: -------------------------------------------------------------------------------- 1 | .fuel-ui-timepicker { 2 | 3 | &.has-error { 4 | border: 1px red solid; 5 | } 6 | 7 | .fuel-ui-time{ 8 | 9 | &.has-error { 10 | input { 11 | border: 1px red solid; 12 | } 13 | } 14 | 15 | input { 16 | width: 50px; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/components/Dropdown/Dropdown.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/styles/_variables.scss: -------------------------------------------------------------------------------- 1 | @import "../../node_modules/bootstrap/scss/_variables.scss"; 2 | 3 | $defaultAnimationSpeed: .3s; 4 | 5 | $enable-flex: false !default; 6 | $enable-rounded: true !default; 7 | $enable-shadows: true !default; 8 | $enable-gradients: false !default; 9 | $enable-transitions: true !default; 10 | $enable-hover-media-query: false !default; -------------------------------------------------------------------------------- /src/components/Accordion/AccordionItem.html: -------------------------------------------------------------------------------- 1 |
2 | {{heading}} 3 | 4 | 5 |
6 |
7 | 8 |
-------------------------------------------------------------------------------- /src/directives/Tooltip/readme.md: -------------------------------------------------------------------------------- 1 | This directive shows text on hover, and supports string interpolation. 2 | 3 | ### Tooltip Selector 4 | `[tooltip]` - `` 5 | 6 | ### Tooltip Example 7 | ```javascript 8 | text: string = "But don't forget about me!"; 9 | ``` 10 | 11 | ```html 12 | 13 | ``` -------------------------------------------------------------------------------- /typings/modules/es6-promise/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/typed-typings/npm-es6-promise/fb04188767acfec1defd054fc8024fafa5cd4de7/typings.json", 5 | "raw": "registry:npm/es6-promise#3.0.0+20160211003958", 6 | "main": "dist/es6-promise.d.ts", 7 | "global": false, 8 | "name": "es6-promise", 9 | "type": "typings" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/components/Alert/Alert.scss: -------------------------------------------------------------------------------- 1 | @import "../../styles/bourbon"; 2 | 3 | $duration: 1s; 4 | 5 | .fuel-ui-alert-fade-in { 6 | @include animation-name(fadeIn); 7 | @include animation-duration($duration); 8 | @include animation-timing-function(ease); 9 | } 10 | 11 | .fuel-ui-alert-fade-out { 12 | @include animation-name(fadeOut); 13 | @include animation-duration($duration); 14 | @include animation-timing-function(ease); 15 | } -------------------------------------------------------------------------------- /src/components/DatePicker/DateRangePickerDate.html: -------------------------------------------------------------------------------- 1 |
3 | 6 | 7 | 8 | 9 |
-------------------------------------------------------------------------------- /typings/globals/core-js/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/core-js/core-js.d.ts", 5 | "raw": "registry:dt/core-js#0.0.0+20160317120654", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/core-js/core-js.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /typings/globals/hammerjs/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/de8e80dfe5360fef44d00c41257d5ef37add000a/hammerjs/hammerjs.d.ts", 5 | "raw": "registry:dt/hammerjs#2.0.4+20160417130828", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/de8e80dfe5360fef44d00c41257d5ef37add000a/hammerjs/hammerjs.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /fuel-ui.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function __export(m) { 3 | for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; 4 | } 5 | __export(require("./dist/animations/animations")); 6 | __export(require("./dist/components/components")); 7 | __export(require("./dist/directives/directives")); 8 | __export(require("./dist/pipes/pipes")); 9 | __export(require('./dist/utilities/utilities')); 10 | 11 | //# sourceMappingURL=./dist/fuel-ui.js.map 12 | -------------------------------------------------------------------------------- /src/utilities/StringUtils.ts: -------------------------------------------------------------------------------- 1 | export class StringHelper { 2 | static entityMap:any = { 3 | "<": "<", 4 | ">": ">", 5 | '"': '"', 6 | "'": ''', 7 | "/": '/' 8 | }; 9 | 10 | static escapeHtml(html:string): string { 11 | var that = this; 12 | return String(html).replace(/[<>"'\/]/g, function (s) { 13 | return that.entityMap[s]; 14 | }); 15 | } 16 | } -------------------------------------------------------------------------------- /src/utilities/DateUtils.ts: -------------------------------------------------------------------------------- 1 | export class DateUtils { 2 | public static isValidDate(value: any): boolean { 3 | return Object.prototype.toString.call(value) === "[object Date]" 4 | && !isNaN((value).valueOf()) && (value).getTime() != 0; 5 | } 6 | 7 | public static handleDateInput(value: any): Date { 8 | if (DateUtils.isValidDate(value)) 9 | return value; 10 | 11 | return new Date(value); 12 | } 13 | } -------------------------------------------------------------------------------- /src/components/Carousel/carousel.scss: -------------------------------------------------------------------------------- 1 | @import "../../styles/bourbon"; 2 | @import "../../styles/variables"; 3 | 4 | .carousel { 5 | background-color: $gray-light; 6 | } 7 | 8 | .carousel-item { 9 | position: absolute !important; 10 | left: 0; 11 | top: 0; 12 | width: 100%; 13 | display: block !important; 14 | overflow: hidden; 15 | 16 | .item-content img { 17 | width: 100%; 18 | pointer-events: none; 19 | } 20 | } -------------------------------------------------------------------------------- /src/directives/directives.ts: -------------------------------------------------------------------------------- 1 | import {Animation} from './Animation/Animation'; 2 | import {TOOLTIP_PROVIDERS, Tooltip} from "./Tooltip/Tooltip"; 3 | import {CodeHighlighter} from "./CodeHighlighter/CodeHighlighter"; 4 | 5 | export var FUELUI_DIRECTIVE_PROVIDERS = [ 6 | TOOLTIP_PROVIDERS, 7 | Animation, 8 | CodeHighlighter 9 | ]; 10 | export * from './Animation/Animation'; 11 | export * from "./Tooltip/Tooltip"; 12 | export * from "./CodeHighlighter/CodeHighlighter"; -------------------------------------------------------------------------------- /src/components/TableSortable/TableSortableColumn.ts: -------------------------------------------------------------------------------- 1 | export class TableSortableColumn { 2 | public display: string; 3 | public variable: string; 4 | public filter: string; 5 | public sortable: boolean = true; 6 | 7 | constructor(display: string, variable: string, filter: string, sortable?: boolean){ 8 | this.display = display; 9 | this.variable = variable; 10 | this.filter = filter; 11 | this.sortable = sortable != null ? sortable : true; 12 | } 13 | } -------------------------------------------------------------------------------- /src/pipes/MapToIterable/MapToIterable.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'mapToIterable' 5 | }) 6 | export class MapToIterablePipe implements PipeTransform { 7 | transform(dict:any, args:any = []): any { 8 | var a:any[] = []; 9 | for (var key in dict) { 10 | if (dict.hasOwnProperty(key)) { 11 | a.push({key: key, val: dict[key]}); 12 | } 13 | } 14 | return a; 15 | } 16 | } 17 | 18 | export var MAPTOITERABLE_PROVIDERS = [ 19 | MapToIterablePipe 20 | ]; -------------------------------------------------------------------------------- /src/components/Alert/Alert.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Dropdown/Dropdown.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | import {CORE_DIRECTIVES} from '@angular/common'; 3 | 4 | @Component({ 5 | selector: "dropdown", 6 | templateUrl: 'components/Dropdown/Dropdown.html' 7 | }) 8 | 9 | export class Dropdown { 10 | @Input() label: string; 11 | dropdownOpen: boolean = false; 12 | 13 | public toggleDropdown() : void{ 14 | this.dropdownOpen = !this.dropdownOpen; 15 | } 16 | } 17 | 18 | export var DROPDOWN_COMPONENT_PROVIDERS = [ 19 | Dropdown 20 | ]; -------------------------------------------------------------------------------- /src/directives/CodeHighlighter/CodeHighlighter.ts: -------------------------------------------------------------------------------- 1 | import {Directive, ElementRef, AfterViewInit} from '@angular/core'; 2 | import {StringHelper} from '../../utilities/StringUtils'; 3 | 4 | declare var Prism: any; 5 | 6 | @Directive({ 7 | selector: '[code-highlight]' 8 | }) 9 | export class CodeHighlighter implements AfterViewInit{ 10 | 11 | constructor(private _el: ElementRef) {} 12 | 13 | ngAfterViewInit(): void { 14 | if(this._el && this._el.nativeElement){ 15 | Prism.highlightElement(this._el.nativeElement); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/components/TextExpander/TextExpander.html: -------------------------------------------------------------------------------- 1 | 2 | {{text | slice : 0 : (expanded ? text.length : amountOfCharacters())}} 3 | 4 | 5 | 6 | {{expandText}} 7 | 8 | 9 | 10 | 11 | {{shrinkText}} 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/components/Accordion/Accordion.scss: -------------------------------------------------------------------------------- 1 | .fuel-ui-accordion { 2 | background-color: #fff; 3 | border: 1px solid #ddd; 4 | border-radius: 4px; 5 | 6 | .fuel-ui-accordion-heading { 7 | background-color: #f5f5f5; 8 | border-bottom: 1px solid #ddd; 9 | border-top-left-radius: 3px; 10 | border-top-right-radius: 3px; 11 | color: #333; 12 | padding: 10px 15px; 13 | 14 | &.text-muted { 15 | color: #818a91 !important; 16 | } 17 | } 18 | 19 | .fuel-ui-accordion-body { 20 | padding: 15px; 21 | } 22 | } -------------------------------------------------------------------------------- /src/directives/demoDirectives.ts: -------------------------------------------------------------------------------- 1 | import {ANIMATION_DEMO_PROVIDERS, AnimationDemo} from "./Animation/Animation.Demo"; 2 | import {TOOLTIP_DEMO_PROVIDERS, TooltipDemo} from "./Tooltip/Tooltip.Demo"; 3 | import {CODEHIGHLIGHTER_DEMO_PROVIDERS, CodeHighlighterDemo} from "./CodeHighlighter/CodeHighlighter.Demo"; 4 | 5 | export var FUELUI_DEMO_DIRECTIVE_PROVIDERS = [ 6 | ANIMATION_DEMO_PROVIDERS, 7 | TOOLTIP_DEMO_PROVIDERS, 8 | CODEHIGHLIGHTER_DEMO_PROVIDERS, 9 | ]; 10 | 11 | export * from "./Animation/Animation.Demo"; 12 | export * from "./Tooltip/Tooltip.Demo"; 13 | export * from "./CodeHighlighter/CodeHighlighter.Demo"; -------------------------------------------------------------------------------- /src/pipes/pipes.ts: -------------------------------------------------------------------------------- 1 | import {FORMAT_PROVIDERS, FormatPipe} from "./Format/Format"; 2 | import {MAPTOITERABLE_PROVIDERS, MapToIterablePipe} from "./MapToIterable/MapToIterable"; 3 | import {ORDERBY_PROVIDERS, OrderByPipe} from "./OrderBy/OrderBy"; 4 | import {RANGE_PROVIDERS, RangePipe} from "./Range/Range"; 5 | 6 | export var FUELUI_PIPE_PROVIDERS = [ 7 | FORMAT_PROVIDERS, 8 | MAPTOITERABLE_PROVIDERS, 9 | ORDERBY_PROVIDERS, 10 | RANGE_PROVIDERS 11 | ]; 12 | export * from "./Format/Format"; 13 | export * from "./MapToIterable/MapToIterable"; 14 | export * from "./OrderBy/OrderBy"; 15 | export * from "./Range/Range"; -------------------------------------------------------------------------------- /src/components/OffCanvasMenu/OffCanvasMenu.html: -------------------------------------------------------------------------------- 1 |
3 | 4 |
11 | 12 |
-------------------------------------------------------------------------------- /src/utilities/AnimationUtils.ts: -------------------------------------------------------------------------------- 1 | export class AnimationUtils { 2 | //http://codepen.io/branneman/pen/tCdHa 3 | // 4 | // http://easings.net/#easeInOutQuart 5 | // time: current time 6 | // beginning: beginning value 7 | // change: change in value 8 | // duration: duration 9 | // 10 | static easeInOutQuart(time: number, beginning: number, change: number, duration: number): number { 11 | if ((time /= duration / 2) < 1) 12 | return change / 2 * time * time * time * time + beginning; 13 | return -change / 2 * ((time -= 2) * time * time * time - 2) + beginning; 14 | } 15 | } -------------------------------------------------------------------------------- /src/components/TableSortable/TableSortable.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
6 | {{column.display}} 7 |
16 |
-------------------------------------------------------------------------------- /src/pipes/Range/Range.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Example use 3 | * Basic Array of single type: *ngFor="let n of someBlankArray | 0 : 9" 4 | */ 5 | 6 | import {Pipe, PipeTransform} from '@angular/core'; 7 | 8 | @Pipe({ 9 | name: 'range', 10 | pure: false 11 | }) 12 | export class RangePipe implements PipeTransform { 13 | transform(value:any, min: number = 0, max: number = 4, step: number = 1){ 14 | 15 | var newValue:any[] = []; 16 | 17 | for (var i = min; i <= max; i += step) 18 | newValue.push(i); 19 | 20 | return newValue; 21 | } 22 | } 23 | 24 | export var RANGE_PROVIDERS = [ 25 | RangePipe 26 | ]; -------------------------------------------------------------------------------- /src/components/TableSortable/TableSortable.scss: -------------------------------------------------------------------------------- 1 | .fuel-ui-table-sortable > thead > tr > th:not(.fuel-ui-not-sortable) { 2 | cursor: pointer; 3 | position: relative; 4 | background-image: none; 5 | white-space: nowrap; 6 | 7 | &:after, .sort-desc:after, .sort-asc:after{ 8 | font-family: FontAwesome; 9 | padding-left: 5px; 10 | } 11 | 12 | &:after{ 13 | content: "\f0dc"; 14 | color: #ddd; 15 | } 16 | 17 | &.sort-asc:after{ 18 | content: "\f0de"; 19 | color: #767676; 20 | } 21 | 22 | &.sort-desc:after{ 23 | content: "\f0dd"; 24 | color: #767676; 25 | } 26 | } -------------------------------------------------------------------------------- /src/directives/CodeHighlighter/readme.md: -------------------------------------------------------------------------------- 1 | CodeHighlighter uses [PrismJS](http://prismjs.com/) is applied to a code element with [code-highlight] directive. The `` should have a style class having "language-" prefix to specify the language to highlight. See [PrismJS](http://prismjs.com/#languages-list) docs for the list of available languages. An example block with css code would be as follows. 2 | 3 | ### Tooltip Selector 4 | `[code-highlight]` - `` 5 | 6 | ### Tooltip Example 7 | ```html 8 |
 9 |     
10 |         #titanic { 
11 |             float: none;
12 |         }
13 |     
14 | 
15 | ``` -------------------------------------------------------------------------------- /src/components/Tab/TabSet.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 |
-------------------------------------------------------------------------------- /src/pipes/MapToIterable/readme.md: -------------------------------------------------------------------------------- 1 | This pipe is used to to make a custom object iterable over its keys 2 | 3 | ### MapToIterable Pipe 4 | `format` - `{{data | mapToIterable}}` 5 | 6 | ### MapToIterable Example 7 | ```javascript 8 | data: any[] = [ 9 | { 10 | Any: "foo", 11 | Keys: "foo", 12 | At: "foo", 13 | All: "foo" 14 | }, 15 | { 16 | Any: "bar", 17 | Keys: "bar", 18 | At: "bar", 19 | All: "bar" 20 | } 21 | ] 22 | ``` 23 | 24 | ```html 25 |
    26 |
  • 27 | {{keyValuePair.key}}: {{keyValuePair.val}} 28 |
  • 29 |
30 | ``` -------------------------------------------------------------------------------- /src/pipes/demoPipes.ts: -------------------------------------------------------------------------------- 1 | import {FORMAT_DEMO_PROVIDERS, FormatDemo} from "./Format/Format.Demo"; 2 | import {MAPTOITERABLE_DEMO_PROVIDERS, MapToIterableDemo} from "./MapToIterable/MapToIterable.Demo"; 3 | import {ORDERBY_DEMO_PROVIDERS, OrderByDemo} from "./OrderBy/OrderBy.Demo"; 4 | import {RANGE_DEMO_PROVIDERS, RangeDemo} from "./Range/Range.Demo"; 5 | 6 | export var FUELUI_DEMO_PIPE_PROVIDERS = [ 7 | FORMAT_DEMO_PROVIDERS, 8 | MAPTOITERABLE_DEMO_PROVIDERS, 9 | ORDERBY_DEMO_PROVIDERS, 10 | RANGE_DEMO_PROVIDERS 11 | ]; 12 | 13 | export * from "./Format/Format.Demo"; 14 | export * from "./MapToIterable/MapToIterable.Demo"; 15 | export * from "./OrderBy/OrderBy.Demo"; 16 | export * from "./Range/Range.Demo"; -------------------------------------------------------------------------------- /src/pipes/Range/readme.md: -------------------------------------------------------------------------------- 1 | This pipe creates an array of numbers based on a given min and max. It will overwrite whatever value is connected to the pipe. 2 | 3 | ### Range Pipe 4 | `range` - `{{someVar | range : min : max : step}}` 5 | 6 | ### Range Parameters 7 | * `min` _- number_ - 8 | Beginning number of array 9 | * `max` _- number_ - 10 | Ending number of array 11 | * `step` _- number_ - (Default: `1`)(Optional)_ - 12 | The amount of step between each number within the array 13 | 14 | ### Range Example 15 | ```javascript 16 | emptyArray: Array = []; 17 | ``` 18 | 19 | ```html 20 | 23 | ``` -------------------------------------------------------------------------------- /src/components/Pagination/readme.md: -------------------------------------------------------------------------------- 1 | ### Pagination Selector 2 | `pagination` - `` 3 | 4 | ### Pagination Settings 5 | 6 | * `[(currentPage)]` _- number_ - 7 | A two way binding of the currently selected page 8 | * `[totalPages]` _- number - (Default: `10`)(Optional)_ - 9 | The total amount of pages listed 10 | * `[pagesAtOnce]` _- number - (Default: `5`)(Optional)_ - 11 | The total number of pages displayed at a time 12 | 13 | ### Pagination Example 14 | ```javascript 15 | currentPage: number = 1; 16 | totalPages: number = 100; 17 | pagesAtOnce: number = 9; 18 | ``` 19 | 20 | ```html 21 | 25 | 26 | ``` -------------------------------------------------------------------------------- /src/animations/Collapse/readme.md: -------------------------------------------------------------------------------- 1 | ### Collapse Selector 2 | `@collapse` - `` 3 | 4 | ### Collapse Import 5 | ```javascript 6 | import {Collapse} from 'fuel-ui/fuel-ui'; 7 | 8 | @Component({ 9 | animations: [Collapse(300)] 10 | }) 11 | ``` 12 | 13 | ### Collapse Parameter 14 | 15 | * `duration` _- number - 16 | Number of milliseconds for how long the open/close animation takes 17 | 18 | ### Collapse Example 19 | ```javascript 20 | collapsed: boolean = false; 21 | ``` 22 | 23 | ```html 24 |
25 |

All of your content

26 |
    27 |
  • That you wish
  • 28 |
  • to be able
  • 29 |
  • to collapse
  • 30 |
31 |

At any time!

32 |
33 | ``` -------------------------------------------------------------------------------- /src/components/DatePicker/DatePickerProviders.ts: -------------------------------------------------------------------------------- 1 | export {DatePickerCalendar} from "./DatePickerCalendar"; 2 | export {DatePicker} from "./DatePicker"; 3 | export {DatePickerField, DatePickerFieldStyler} from "./DatePickerField"; 4 | export {DateRangePicker, StartDateField, EndDateField} from "./DateRangePicker"; 5 | 6 | import {DatePickerCalendar} from "./DatePickerCalendar"; 7 | import {DatePicker} from "./DatePicker"; 8 | import {DatePickerField, DatePickerFieldStyler} from "./DatePickerField"; 9 | import {DateRangePicker, StartDateField, EndDateField} from "./DateRangePicker"; 10 | 11 | export var DATE_PICKER_PROVIDERS = [ 12 | DatePickerCalendar, 13 | DatePicker, 14 | DateRangePicker, 15 | DatePickerField, 16 | StartDateField, 17 | EndDateField, 18 | DatePickerFieldStyler 19 | ]; 20 | 21 | -------------------------------------------------------------------------------- /src/directives/Animation/readme.md: -------------------------------------------------------------------------------- 1 | This directive indicates that the element has animations attached to it. The directive adds listeners for animation start and end, and emit events when they fire respectively. 2 | 3 | ### Animation Listener Selector 4 | `.animated` - `` 5 | 6 | ### Animation Listener Settings 7 | 8 | * `(animationStart)` _- function_ - 9 | A function to fire when any animation starts 10 | * `(animationEnd)` _- function_ - 11 | A function to fire when any animation ends 12 | 13 | ### Animation Listener Example 14 | ```javascript 15 | fired($event:any){ 16 | console.log('Event fired: ', $event); 17 | } 18 | ``` 19 | 20 | ```html 21 |
24 |
25 | ``` -------------------------------------------------------------------------------- /src/components/DatePicker/DatePickerCalendar.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 8 | 9 | 10 | 19 | 20 | 21 |
6 | {{currentMonth | date:'MMMM yyyy'}} 7 |
17 | {{day}} 18 |
22 |
-------------------------------------------------------------------------------- /src/utilities/DetectionUtils.ts: -------------------------------------------------------------------------------- 1 | export class MobileDetection { 2 | 3 | static isAndroid(): boolean { 4 | return navigator.userAgent.match(/Android/i) != null; 5 | } 6 | 7 | static isBlackBerry(): boolean { 8 | return navigator.userAgent.match(/BlackBerry/i) != null; 9 | } 10 | 11 | static isIOS(): boolean { 12 | return navigator.userAgent.match(/iPhone|iPad|iPod/i) != null; 13 | } 14 | 15 | static isOpera(): boolean { 16 | return navigator.userAgent.match(/Opera Mini/i) != null; 17 | } 18 | 19 | static isWindows(): boolean { 20 | return navigator.userAgent.match(/IEMobile|WPDesktop/i) != null; 21 | } 22 | 23 | static isAny(): boolean { 24 | return (this.isAndroid() || this.isBlackBerry() || this.isIOS() || this.isOpera() || this.isWindows()); 25 | } 26 | } -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | System.config({ 2 | packages: { 3 | '@angular/common': { 4 | main: 'index' 5 | }, 6 | '@angular/compiler': { 7 | main: 'index' 8 | }, 9 | '@angular/core': { 10 | main: 'index' 11 | }, 12 | '@angular/forms': { 13 | main: 'index' 14 | }, 15 | '@angular/http': { 16 | main: 'index' 17 | }, 18 | '@angular/platform-browser-dynamic': { 19 | main: 'index' 20 | }, 21 | '@angular/platform-browser': { 22 | main: 'index' 23 | }, 24 | '@angular/router': { 25 | main: 'index' 26 | }, 27 | "rxjs": { 28 | defaultExtension: 'js' 29 | }, 30 | 'dist': { 31 | defaultExtension: 'js' 32 | }, 33 | }, 34 | paths: { 35 | '@angular/*': 'node_modules/@angular/*', 36 | "rxjs/*": "node_modules/rxjs/*", 37 | "reflect-metadata": "node_modules/reflect-metadata" 38 | }, 39 | map: { 40 | "rxjs": "node_modules/rxjs" 41 | } 42 | }); -------------------------------------------------------------------------------- /src/components/Tag/TagSet.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit, OnDestroy, Input, Output} from '@angular/core'; 2 | import {NgClass} from '@angular/common'; 3 | import {Tag} from './Tag'; 4 | 5 | @Component({ 6 | selector: 'tagset', 7 | directives: [NgClass], 8 | templateUrl: 'components/Tag/TagSet.html' 9 | }) 10 | export class TagSet implements OnDestroy { 11 | 12 | @Input() public tags:Array = []; 13 | private destroyed:boolean; 14 | 15 | public ngOnDestroy():void { 16 | this.destroyed = true; 17 | } 18 | 19 | public addTag(tag:Tag):void { 20 | this.tags.push(tag); 21 | } 22 | 23 | public removeTag(tag:Tag):void { 24 | let index = this.tags.indexOf(tag); 25 | if (index === -1 || this.destroyed || tag.disabled) { 26 | return; 27 | } 28 | 29 | tag.remove.next(tag); 30 | this.tags.splice(index, 1); 31 | } 32 | } -------------------------------------------------------------------------------- /src/pipes/Format/readme.md: -------------------------------------------------------------------------------- 1 | This pipe is used to format any string into a type by an identifying string. This is good for when you know the format of the output, but don't necessarily know the input type 2 | 3 | ### Range Pipe 4 | `format` - `{{someVar | format : 'number : 2'}}` 5 | 6 | ### Range Parameters 7 | * `type` _- string_ - (Default: `text`)_ - 8 | The type of data you want the input to be output as 9 | 10 | ### DataTypes supported 11 | * Text 12 | * Decimal/Number (Supports ': decimalPlaces') 13 | * Percentage (Supports ': decimalPlaces') 14 | * Date/DateTime (Supports ': dateFormatting' IE: 'MMM d, y h:mm:ss a') 15 | 16 | ### Range Example 17 | ```javascript 18 | someNumberVar: string = '435.23528'; 19 | someTimestamp: number = 1442187616000; 20 | ``` 21 | 22 | ```html 23 | {{someNumberVar | format : 'number : 2'}} Outputs: 435.24 24 | {{someTimestamp | format : 'dateTime'}} Outputs: Sep 13, 2015, 7:40:16 PM 25 | ``` -------------------------------------------------------------------------------- /src/styles/_animation.scss: -------------------------------------------------------------------------------- 1 | @import "../../bower_components/animatewithsass/animate.scss"; 2 | @import "../../bower_components/animatewithsass/properties"; 3 | @import "../../bower_components/animatewithsass/_fading-entrances/fading-entrances.scss"; 4 | 5 | @include keyframes(slideInLeft) { 6 | 0% { 7 | @include transform(translateX(100%)); 8 | } 9 | 100% { 10 | @include transform(translateX(0)); 11 | } 12 | } 13 | 14 | @include keyframes(slideInRight) { 15 | 0% { 16 | @include transform(translateX(-100%)); 17 | } 18 | 100% { 19 | @include transform(translateX(0)); 20 | } 21 | } 22 | 23 | @include keyframes(slideOutLeft) { 24 | 0% { 25 | @include transform(translateX(0)); 26 | } 27 | 100% { 28 | @include transform(translateX(-100%)); 29 | } 30 | } 31 | 32 | @include keyframes(slideOutRight) { 33 | 0% { 34 | @include transform(translateX(0)); 35 | } 36 | 100% { 37 | @include transform(translateX(100%)); 38 | } 39 | } -------------------------------------------------------------------------------- /src/components/Progress/readme.md: -------------------------------------------------------------------------------- 1 | ### Progress Selector 2 | `progress` - `` 3 | 4 | ### Progress Settings 5 | 6 | * `[value]` _- number_ - 7 | A binding to the progress value 8 | * `[min]` _- number - (Default: `0`)(Optional)_ - 9 | The lowest value that can be given to the progress 10 | * `[max]` _- number - (Default: `1`)(Optional)_ - 11 | The highest value that can be given to the progress 12 | 13 | #### Browser Support 14 | This is simply an example of using the HTML5 Progress tag in Angular 2. This tag is supported in IE10+, but if you need to support older browsers, please take a look into adding [this polyfill](https://github.com/LeaVerou/HTML5-Progress-polyfill) to your project 15 | 16 | ### Progress Example 17 | ```javascript 18 | progressValue: number = 1; 19 | ``` 20 | 21 | ```html 22 | {{progressValue}}% 23 | ``` -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fuel-ui", 3 | "version": "0.0.1", 4 | "homepage": "https://github.com/fuelinteractive/fuel-ui", 5 | "authors": [ 6 | "stacygay <@stacygay>", 7 | "coryshaw1 <@coryshaw1>" 8 | ], 9 | "description": "A set of ui components for use with Angular 2 and Bootstrap 4", 10 | "main": [ 11 | "fuelui.ts" 12 | ], 13 | "keywords": [ 14 | "angular2", 15 | "bootstrap4", 16 | "fuel-ui" 17 | ], 18 | "ignore": [ 19 | "**/.*", 20 | "node_modules", 21 | "bower_components", 22 | "jspm_packages", 23 | "test", 24 | "tests" 25 | ], 26 | "_release": "0.0.1", 27 | "_resolution": { 28 | "type": "version", 29 | "tag": "0.0.1", 30 | "commit": "96a96cd1d7ded336f33c9660387f41f46962c4f1" 31 | }, 32 | "_source": "git://github.com/fuelinteractive/fuel-ui", 33 | "_target": "~0.0.1", 34 | "_originalSource": "fuel-ui", 35 | "_direct": true, 36 | "dependencies": { 37 | "animatewithsass": "~3.2.1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/components/TimePicker/readme.md: -------------------------------------------------------------------------------- 1 | ### TimePicker Selector 2 | `timepicker` - `` 3 | 4 | ### TimePicker Example 5 | ```javascript 6 | date: Date = new Date(); 7 | minDate: Date = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 0, 0, 0); 8 | maxDate: Date = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 23, 59, 59); 9 | hourStep: number = 1; 10 | minuteStep: number = 1; 11 | readonly: boolean = false; 12 | disabled: boolean = false; 13 | showSeconds: boolean = true; 14 | showSpinners: boolean = true; 15 | showMeridian: boolean = true; 16 | ``` 17 | 18 | ```html 19 | 30 | 31 | ``` -------------------------------------------------------------------------------- /src/components/Tab/readme.md: -------------------------------------------------------------------------------- 1 | ### TabSet Selector 2 | `tabset` - `` 3 | 4 | ### Tabs Example 5 | ```javascript 6 | tabs:any[] = [ 7 | {title: 'Dynamic Title 1', content: 'Dynamic content 1', active: true}, 8 | {title: 'Dynamic Title 2', content: 'Dynamic content 2'}, 9 | {title: 'Dynamic Title 3', content: 'Dynamic content 3'}, 10 | {title: 'Dynamic Title 4', content: 'Dynamic content 4', removable: true} 11 | ]; 12 | ``` 13 | 14 | ```html 15 | 16 | 23 | {{theTab?.content}} 24 | 25 | 26 | 27 | 28 | Vertical content 1 29 | Vertical content 2 30 | 31 | ``` -------------------------------------------------------------------------------- /src/components/OffCanvasMenu/readme.md: -------------------------------------------------------------------------------- 1 | ### OffCanvasMenu Selector 2 | `alert` - `` 3 | 4 | ### OffCanvasMenu Settings 5 | 6 | * `[origin]` _- "left" | "top" | "right" | "bottom" - 7 | direction to extend content from 8 | * `[width]` _- string - (Default: `25% / 100%`)(Optional)_ - 9 | Width of the extended content, forced to 100% when origin is top or bottom 10 | * `[height]` _- string - (Default: `25% / 100%`)(Optional)_ - 11 | Height of the extended content, forced to 100% when origin is left or right 12 | 13 | ### OffCanvasMenu inner content 14 | * What is displayed in the body of the extended content 15 | 16 | ### OffCanvasMenu Example 17 | 18 | ```html 19 | 20 |
21 |

Menu

22 | 23 |
24 |
25 | 26 | ``` -------------------------------------------------------------------------------- /src/components/Modal/Modal.html: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /src/components/Accordion/readme.md: -------------------------------------------------------------------------------- 1 | ### Accordion Selector 2 | `accordion` - `` 3 | 4 | ### Tags Example 5 | ```javascript 6 | oneAtATime:boolean = true; 7 | duration:number = 250; 8 | firstOpen:boolean = true; 9 | firstDisabled:boolean = false; 10 | lastOpen:boolean = false; 11 | ``` 12 | 13 | ```html 14 | 15 | 18 | This content is showing on start 19 | 20 | 21 | 22 | Markup Here! 23 | 25 | 26 | What amazing content! 27 | 28 | 29 | ``` -------------------------------------------------------------------------------- /src/animations/Collapse/Collapse.ts: -------------------------------------------------------------------------------- 1 | import {trigger, state, style, transition, animate, keyframes} from '@angular/core'; 2 | 3 | export function Collapse(duration: number = 300) { 4 | return trigger('collapse', [ 5 | state('collapsed, true, void', style({ 6 | height: '0', 7 | opacity: '0', 8 | overflow: 'hidden' 9 | })), 10 | state('expanded, false', style({ 11 | height: '*', 12 | opacity: '1', 13 | overflow: 'hidden' 14 | })), 15 | transition('true => false, collapsed => expanded', [ 16 | animate(duration+'ms ease', keyframes([ 17 | style({opacity: '1'}), 18 | style({height: '*'}) 19 | ])) 20 | ]), 21 | transition('false => true, expanded => collapsed', [ 22 | animate(duration+'ms ease', style({height: '0'})) 23 | ]) 24 | ]) 25 | } 26 | 27 | export var COLLAPSE_PROVIDERS = [ 28 | Collapse 29 | ]; -------------------------------------------------------------------------------- /src/components/Tag/readme.md: -------------------------------------------------------------------------------- 1 | ### TagSet Selector 2 | `tagset` - `` 3 | 4 | ### Tags Example 5 | ```javascript 6 | tags:any[] = [ 7 | {title: 'Default'}, 8 | {title: 'Primary', color: 'primary', pill: true, removable: true, value: 'Some great value'}, 9 | {title: 'Info', color: 'info', pill: true, removable: true, value: false}, 10 | {title: 'Success', color: 'success', pill: true, removable: true, value: 1234567890}, 11 | {title: 'Danger', color: 'danger', pill: false, removable: true, value: {some: 'great', value: true}}, 12 | {title: 'Warning', color: 'warning', pill: false, removable: true, value: true} 13 | ]; 14 | 15 | removeLog(tag: Tag):void { 16 | console.log('Removed:', tag.title, '-', tag.value); 17 | } 18 | ``` 19 | 20 | ```html 21 | 22 | 29 | 30 | 31 | ``` -------------------------------------------------------------------------------- /src/components/Carousel/carousel.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Accordion/Accordion.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | import {AccordionItem} from './AccordionItem'; 3 | import {Collapse} from '../../animations/Collapse/Collapse'; 4 | 5 | @Component({ 6 | selector: 'accordion', 7 | template: ``, 8 | animations: [Collapse(350)] 9 | }) 10 | export class Accordion { 11 | @Input() public closeOthers:boolean = true; 12 | @Input() public duration:number = 250; 13 | 14 | private items:Array = []; 15 | 16 | public closeOtherItems(openItem:AccordionItem):void { 17 | if (!this.closeOthers) return; 18 | 19 | this.items.forEach((item:AccordionItem) => { 20 | if (item !== openItem) { 21 | item.open = false; 22 | item.openChange.next(item.open); 23 | } 24 | }); 25 | } 26 | 27 | public addItem(item:AccordionItem):void { 28 | this.items.push(item); 29 | } 30 | 31 | public removeItem(item:AccordionItem):void { 32 | let index = this.items.indexOf(item); 33 | if (index !== -1) { 34 | this.items.splice(index, 1); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/components/OffCanvasMenu/OffCanvasMenu.scss: -------------------------------------------------------------------------------- 1 | @import "../../styles/variables"; 2 | @import "../../styles/bourbon"; 3 | @import "../../styles/media_queries"; 4 | 5 | .off-canvas-menu-overlay { 6 | display: block; 7 | position: fixed; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | left: 0; 12 | z-index: 900; 13 | 14 | background-color: $gray; 15 | opacity: 0; 16 | } 17 | 18 | .off-canvas-menu { 19 | display: block; 20 | position: fixed; 21 | z-index: 1000; 22 | background-color: $body-bg; 23 | 24 | &.off-canvas-menu-left { 25 | top: 0; 26 | left: 0; 27 | bottom: 0; 28 | transform: translate(-100%,0); 29 | width: 75%; 30 | } 31 | 32 | &.off-canvas-menu-right { 33 | top: 0; 34 | right: 0; 35 | bottom: 0; 36 | transform: translate(100%,0); 37 | width: 75%; 38 | } 39 | 40 | &.off-canvas-menu-top { 41 | top: 0; 42 | left: 0; 43 | right: 0; 44 | transform: translate(0,-100%); 45 | height: 75%; 46 | } 47 | 48 | &.off-canvas-menu-bottom { 49 | left: 0; 50 | right: 0; 51 | bottom: 0; 52 | transform: translate(0,100%); 53 | height: 75%; 54 | } 55 | } -------------------------------------------------------------------------------- /src/components/Alert/readme.md: -------------------------------------------------------------------------------- 1 | ### Alert Selector 2 | `alert` - `` 3 | 4 | ### Alert Settings 5 | 6 | * `[(displayed)]` _- boolean_ - 7 | A two way binding that causes the `alert` to be displayed 8 | * `[closeButton]` _- boolean - (Default: `true`)(Optional)_ - 9 | Takes a boolean that causes the close button to be displayed in the top right corner 10 | * `[type]` _- string - (Default: `success`)(Optional)_ - 11 | Defines the type of the alert. Go to Bootstrap 4's [alert page](http://v4-alpha.getbootstrap.com/components/#alerts) to see the type of alerts available. 12 | 13 | ### Alert inner content 14 | * What is displayed in the body of the alert box 15 | * *Note:* To use dynamic html from a class property, use `[innerHtml]` within a `span` of the inner content 16 | 17 | ### Alert Example 18 | ```javascript 19 | showAlert: boolean = true; 20 | alertType: string = 'success'; 21 | ``` 22 | 23 | ```html 24 | 25 | Success success message 26 | 27 | ``` 28 | 29 | ### Alert Example with Dynamic Content 30 | ```javascript 31 | showAlert: boolean = true; 32 | alertType: string = 'danger'; 33 | alertBody: string = 'Error error message'; 34 | ``` 35 | 36 | ```html 37 | 38 | 39 | 40 | ``` -------------------------------------------------------------------------------- /src/utilities/DateRange.ts: -------------------------------------------------------------------------------- 1 | export class DateRange { 2 | public start: Date; 3 | public end: Date; 4 | 5 | constructor(start: Date, end: Date) { 6 | this.start = start; 7 | this.end = end; 8 | } 9 | 10 | containsDate(date: Date): boolean { 11 | return date >= this.start && date <= this.end; 12 | } 13 | 14 | numberOfNights(): number { 15 | return Math.ceil(Math.abs(this.start.getTime() - this.end.getTime()) / (1000 * 3600 * 24)); 16 | } 17 | 18 | dateArray(): Date[] { 19 | if(this.end < this.start) 20 | return []; 21 | 22 | var dateArr: Date[] = []; 23 | var currDate = new Date(this.start.toDateString()); 24 | while(currDate <= this.end) { 25 | dateArr.push(currDate); 26 | currDate = new Date(currDate.getTime() + 24 * 60 * 60 * 1000); 27 | } 28 | 29 | return dateArr; 30 | } 31 | 32 | weekArray(): Date[][] { 33 | if(this.end < this.start) 34 | return []; 35 | 36 | var weekArr: Date[][] = []; 37 | var currDate = new Date(this.start.toDateString()); 38 | while(currDate <= this.end) { 39 | let dateArr: Date[] = []; 40 | let dowNumber = currDate.getDay(); 41 | do { 42 | dateArr.push(currDate); 43 | ++dowNumber; 44 | currDate = new Date(currDate.toDateString()); 45 | currDate.setDate(currDate.getDate()+1); 46 | } while(currDate <= this.end && dowNumber < 7); 47 | weekArr.push(dateArr); 48 | } 49 | 50 | return weekArr; 51 | } 52 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fuel-UI Demos 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | Loading... 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/utilities/demoUtilities.ts: -------------------------------------------------------------------------------- 1 | import {TableSortableColumn, TableSortableSorting} from '../components/TableSortable/TableSortable'; 2 | 3 | 4 | export class Attribute { 5 | public Name:string; 6 | public Type:string; 7 | public Default:string; 8 | public Description:string; 9 | 10 | public constructor(Name:string, Type:string, Default:string, Description:string){ 11 | this.Name = Name; 12 | this.Type = Type; 13 | this.Default = Default; 14 | this.Description = Description; 15 | } 16 | } 17 | export var AttributeColumns = [ 18 | new TableSortableColumn('Name', 'Name', 'string'), 19 | new TableSortableColumn('Type', 'Type', 'html'), 20 | new TableSortableColumn('Default', 'Default', 'html'), 21 | new TableSortableColumn('Description', 'Description', 'html') 22 | ]; 23 | export var AttributesDefaultSort = new TableSortableSorting('Name', false); 24 | 25 | export class Event { 26 | public Name:string; 27 | public EventObject:string; 28 | public Description:string; 29 | 30 | public constructor(Name:string, EventObject:string, Description:string){ 31 | this.Name = Name; 32 | this.EventObject = EventObject; 33 | this.Description = Description; 34 | } 35 | } 36 | export var EventColumns = [ 37 | new TableSortableColumn('Name', 'Name', 'string'), 38 | new TableSortableColumn('Event Object', 'EventObject', 'html'), 39 | new TableSortableColumn('Description', 'Description', 'html') 40 | ]; 41 | export var EventsDefaultSort = new TableSortableSorting('Name', false); -------------------------------------------------------------------------------- /src/utilities/ElementUtils.ts: -------------------------------------------------------------------------------- 1 | import {AnimationUtils} from "./AnimationUtils"; 2 | 3 | export class ElementUtils { 4 | static outerHeight(el: Element): number { 5 | var height = el.clientHeight; 6 | var style = getComputedStyle(el); 7 | height += parseInt(style.marginTop) + parseInt(style.marginBottom); 8 | height += parseInt(style.borderTopWidth) + parseInt(style.borderBottomWidth); 9 | return height; 10 | } 11 | 12 | static outerWidth(el: Element): number { 13 | var width = el.clientWidth; 14 | var style = getComputedStyle(el); 15 | width += parseInt(style.marginLeft) + parseInt(style.marginRight); 16 | width += parseInt(style.borderLeftWidth) + parseInt(style.borderRightWidth); 17 | return width; 18 | } 19 | 20 | static scrollTo(element: HTMLElement, to: number, duration: number): Promise { 21 | if (duration <= 0) return; 22 | 23 | var startTime = new Date().getTime(); 24 | var from = element.scrollTop; 25 | 26 | return new Promise((resolve, reject) => { 27 | var timer = setInterval(() => { 28 | var time = new Date().getTime() - startTime; 29 | var scrollTo = AnimationUtils.easeInOutQuart(time, from, to-from, duration); 30 | 31 | element.scrollTop = scrollTo; 32 | if(time >= duration) { 33 | element.scrollTop = to; 34 | clearInterval(timer); 35 | resolve(); 36 | } 37 | }, 1000 / 60); 38 | }); 39 | } 40 | } -------------------------------------------------------------------------------- /src/pipes/OrderBy/readme.md: -------------------------------------------------------------------------------- 1 | This pipe orders any given array based numerically or alphabetically. Supports multi-dimensional arrays and ascending/descending sorting per property. 2 | 3 | ### Order By Pipe 4 | `orderBy` - `{{someArray | orderBy : orderingConfig}}` 5 | 6 | ### Order By Parameters 7 | * `orderingConfig` _- string or Array - (Default: `+`)(Optional)_ - 8 | A string of `'+'` or `'-'` for the direction of the sort. Or an array of property names with prepended with `'-'` property needs to be sorted descending. 9 | 10 | ### Order By Example 11 | ```javascript 12 | numberArray: Array = [23,76,123,1,53]; 13 | fruitArray: Array = ['orange', 'banana', 'apple', 'pineapple']; 14 | todos: Array = [ 15 | new Todo('complete','Eat'), 16 | new Todo('incomplete', 'Sleep'), 17 | new Todo('complete', 'Code') 18 | ]; 19 | 20 | class Todo{ 21 | name: string; 22 | status: string; 23 | 24 | constructor(name: string, status: string){ 25 | this.name = name; 26 | this.status = status; 27 | } 28 | } 29 | ``` 30 | 31 | ```html 32 | Basic Array of single type 33 | {{n}} 34 | {{fruit}} 35 | 36 | Multidimensional Array Sort on single column 37 | {{todo.name}} - {{todo.status}} 38 | {{todo.name}} - {{todo.status}} 39 | 40 | Multidimensional Array Sort on multiple columns 41 | {{todo.name}} - {{todo.status}} 42 | ``` -------------------------------------------------------------------------------- /src/components/Accordion/AccordionItem.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit, OnDestroy, Input, Output, EventEmitter} from '@angular/core'; 2 | import {NgClass} from '@angular/common'; 3 | import {Collapse} from '../../animations/Collapse/Collapse'; 4 | import {Accordion} from './Accordion'; 5 | 6 | @Component({ 7 | selector: 'accordion-item, [accordion-item]', 8 | directives: [NgClass], 9 | templateUrl: 'components/Accordion/AccordionItem.html', 10 | animations: [Collapse(350)] 11 | }) 12 | export class AccordionItem implements OnInit, OnDestroy { 13 | @Input() heading:string; 14 | @Input() disabled:boolean = false; 15 | 16 | @Input() 17 | public get open():boolean { 18 | return this._open; 19 | } 20 | public set open(value:boolean) { 21 | this._open = value; 22 | if (value) { 23 | this.accordion.closeOtherItems(this); 24 | } 25 | } 26 | private _open:boolean = false; 27 | 28 | accordion:Accordion; 29 | 30 | @Output() openChange = new EventEmitter(); 31 | 32 | public constructor(accordion:Accordion) { 33 | this.accordion = accordion; 34 | } 35 | 36 | public ngOnInit():any { 37 | this.accordion.addItem(this); 38 | } 39 | 40 | public ngOnDestroy():any { 41 | this.accordion.removeItem(this); 42 | } 43 | 44 | public toggleOpen(event:MouseEvent):any { 45 | event.preventDefault(); 46 | if (!this.disabled) { 47 | this.open = !this.open; 48 | this.openChange.next(this.open); 49 | } 50 | } 51 | } 52 | 53 | export var ACCORDION_PROVIDERS = [ 54 | Accordion, 55 | AccordionItem 56 | ]; -------------------------------------------------------------------------------- /src/components/TableSortable/readme.md: -------------------------------------------------------------------------------- 1 | ### TableSortable Selector 2 | `TableSortable` - `` 3 | 4 | ### TableSortable Settings 5 | 6 | * `[columns]` _- TableSortableColumn[] - (Default: `null`)_ - 7 | Array of all columns to be displayed and how to format them for ordering 8 | * `[rows]` _- any[]_ - 9 | Any arbitrary array of objects 10 | * `[sorting]` _- TableSortableSorting - (Default: `null`)_ - 11 | Which column to sort on and which direction (ascending or descending) 12 | 13 | ### TableSortable Example 14 | ```javascript 15 | rows: any[] = [ 16 | { 17 | Name: 'Data 1', 18 | Amount: 100.23, 19 | Date: 1441588216000 20 | }, 21 | { 22 | Name: 'Data 2', 23 | Amount: 0.875623, 24 | Date: 1442387616000 25 | }, 26 | { 27 | Name: 'Data 3', 28 | Amount: .010123, 29 | Date: 1442187616000 30 | } 31 | ]; 32 | columns: TableSortableColumn[] = [ 33 | { 34 | display: 'Column 1', //The text to display 35 | variable: 'Name', //The name of the key that's apart of the data array 36 | filter: 'text' //The type data type of the column (number, text, date, etc.) 37 | }, 38 | new TableSortableColumn('Column 2', 'Amount', 'decimal : 1.0-2'), 39 | new TableSortableColumn('Column 3', 'Date', 'dateTime') 40 | ]; 41 | sorting: TableSortableSorting = { 42 | column: 'Name', //to match the variable of one of the columns 43 | descending: false 44 | }; 45 | ``` 46 | 47 | ```html 48 | 52 | Loading table... 53 | 54 | ``` -------------------------------------------------------------------------------- /src/components/InfiniteScroller/readme.md: -------------------------------------------------------------------------------- 1 | # Infinite Scroller 2 | 3 | A component to facilitate a constant model update while scrolling through a container. 4 | This component also defines styles to allow infinite scrolling within a self contained element. 5 | 6 | ### Selector 7 | `infinite-scroller` - `` 8 | 9 | 10 | ### Settings 11 | 12 | * `(next)` - _callback_ - 13 | function to be called when scrolling down below the distance threshold 14 | * `(prev)` - _callback_ - 15 | function to be called when scrolling up above the distance threshold 16 | * `[height]` _- string - (Default: `auto`)(Optional)_ - 17 | Defines the height of the container with scrolling content 18 | * `[distance]` _- number - (Default: `100`)(Optional)_ - 19 | Distance in pixels from the top or bottom of the container before enacting a next or prev event 20 | * `[hideScrollbar]` _- boolean - (Default: `false`)(Optional)_ - 21 | Determines wether or not to hide the scrollbar of the container 22 | 23 | ### Inner content 24 | * Content to be scrolled, typically containing an iterated model using *ngFor 25 | * Mark individual items to be added to the content with the scroll-item class 26 | 27 | ### Example 28 | ```html 29 | 35 |
36 |
37 |

Some Item

38 |

{{item}}

39 |
40 |
41 |
42 | ``` -------------------------------------------------------------------------------- /src/components/TableSortable/TableSortable.ts: -------------------------------------------------------------------------------- 1 | import {Component, ChangeDetectionStrategy, Input} from '@angular/core' 2 | import {CORE_DIRECTIVES, JsonPipe} from '@angular/common' 3 | import {OrderByPipe} from "../../pipes/OrderBy/OrderBy" 4 | import {FormatPipe} from "../../pipes/Format/Format" 5 | import {TableSortableColumn} from "./TableSortableColumn"; 6 | import {TableSortableSorting} from "./TableSortableSorting"; 7 | 8 | @Component({ 9 | selector: 'table-sortable', 10 | templateUrl: 'components/TableSortable/TableSortable.html', 11 | directives: [CORE_DIRECTIVES], 12 | pipes: [OrderByPipe, JsonPipe, FormatPipe] 13 | }) 14 | export class TableSortable { 15 | 16 | @Input() columns: TableSortableColumn[]; 17 | @Input() data: any[]; 18 | @Input() sort: TableSortableSorting; 19 | 20 | constructor() {} 21 | 22 | selectedClass(column: TableSortableColumn): string{ 23 | if(!column.sortable) return 'fuel-ui-not-sortable'; 24 | 25 | return column.variable == this.sort.column ? 'sort-' + (this.sort.descending ? 'desc' : 'asc') : ''; 26 | } 27 | 28 | changeSorting(column: TableSortableColumn): void{ 29 | if(!column.sortable) return; 30 | 31 | var sort = this.sort; 32 | if (sort.column == column.variable) { 33 | sort.descending = !sort.descending; 34 | } else { 35 | sort.column = column.variable; 36 | sort.descending = false; 37 | } 38 | } 39 | 40 | convertSorting(): string{ 41 | return this.sort.descending ? '-' + this.sort.column : this.sort.column; 42 | } 43 | } 44 | 45 | export var TABLESORTABLE_PROVIDERS = [ 46 | TableSortable 47 | ]; 48 | export {TableSortableColumn} from "./TableSortableColumn"; 49 | export {TableSortableSorting} from "./TableSortableSorting"; 50 | -------------------------------------------------------------------------------- /src/styles/slider_pips.scss: -------------------------------------------------------------------------------- 1 | 2 | /* Base; 3 | * 4 | */ 5 | .noUi-pips, 6 | .noUi-pips * { 7 | -moz-box-sizing: border-box; 8 | box-sizing: border-box; 9 | } 10 | .noUi-pips { 11 | position: absolute; 12 | color: #999; 13 | } 14 | 15 | /* Values; 16 | * 17 | */ 18 | .noUi-value { 19 | width: 40px; 20 | position: absolute; 21 | text-align: center; 22 | } 23 | .noUi-value-sub { 24 | color: #ccc; 25 | font-size: 10px; 26 | } 27 | 28 | /* Markings; 29 | * 30 | */ 31 | .noUi-marker { 32 | position: absolute; 33 | background: #CCC; 34 | } 35 | .noUi-marker-sub { 36 | background: #AAA; 37 | } 38 | .noUi-marker-large { 39 | background: #AAA; 40 | } 41 | 42 | /* Horizontal layout; 43 | * 44 | */ 45 | .noUi-pips-horizontal { 46 | padding: 10px 0; 47 | height: 50px; 48 | top: 100%; 49 | left: 0; 50 | width: 100%; 51 | } 52 | .noUi-value-horizontal { 53 | margin-left: -20px; 54 | padding-top: 20px; 55 | } 56 | .noUi-value-horizontal.noUi-value-sub { 57 | padding-top: 15px; 58 | } 59 | 60 | .noUi-marker-horizontal.noUi-marker { 61 | margin-left: -1px; 62 | width: 2px; 63 | height: 5px; 64 | } 65 | .noUi-marker-horizontal.noUi-marker-sub { 66 | height: 10px; 67 | } 68 | .noUi-marker-horizontal.noUi-marker-large { 69 | height: 15px; 70 | } 71 | 72 | /* Vertical layout; 73 | * 74 | */ 75 | .noUi-pips-vertical { 76 | padding: 0 10px; 77 | height: 100%; 78 | top: 0; 79 | left: 100%; 80 | } 81 | .noUi-value-vertical { 82 | width: 15px; 83 | margin-left: 20px; 84 | margin-top: -5px; 85 | } 86 | 87 | .noUi-marker-vertical.noUi-marker { 88 | width: 5px; 89 | height: 2px; 90 | margin-top: -1px; 91 | } 92 | .noUi-marker-vertical.noUi-marker-sub { 93 | width: 10px; 94 | } 95 | .noUi-marker-vertical.noUi-marker-large { 96 | width: 15px; 97 | } 98 | -------------------------------------------------------------------------------- /src/directives/CodeHighlighter/CodeHighlighter.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {CodeHighlighter} from './CodeHighlighter'; 3 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 4 | 5 | @Component({ 6 | template: ` 7 |
8 |
9 |
10 |

CodeHighlighter

11 |

CodeHighlighter is a custom directive to highlight code blocks using PrismJS

12 |
13 |
14 |
15 | 16 |
17 | 
18 | #titanic {
19 |     float: none;
20 | }
21 | 
22 | 
23 | 24 |
25 |

Import

26 |
27 | 
28 | import {CodeHighlighter} from 'fuel-ui/fuel-ui';
29 | 
30 | 
31 | 32 |

Getting Started

33 |

CodeHighlighter is applied to a code element with [code-highlight] directive. The <code> should have a style class having "language-" prefix to specify the language to highlight. See Prismjs docs for the list of available languages. An example block with css code would be as follows.

34 | 35 |

Usage

36 | 37 | 38 |
39 | 
40 | <code class="language-css" code-highlight>
41 |     #titanic { 
42 |         float: none;
43 |     }
44 | </code>
45 | 
46 | 
47 |
48 |
49 |
`, 50 | directives: [CodeHighlighter, TAB_PROVIDERS] 51 | }) 52 | export class CodeHighlighterDemo { 53 | 54 | } 55 | 56 | export var CODEHIGHLIGHTER_DEMO_PROVIDERS = [ 57 | CodeHighlighterDemo 58 | ]; -------------------------------------------------------------------------------- /src/components/Alert/Alert.ts: -------------------------------------------------------------------------------- 1 | import {Component, ElementRef, Input, Output, EventEmitter, OnChanges} from '@angular/core'; 2 | import {CORE_DIRECTIVES} from '@angular/common'; 3 | 4 | @Component({ 5 | selector: 'alert', 6 | templateUrl: 'components/Alert/Alert.html', 7 | directives: [CORE_DIRECTIVES] 8 | }) 9 | export class Alert extends OnChanges { 10 | @Input() displayed: boolean = false; 11 | @Input() closeButton: boolean = true; 12 | @Input() type: string = 'success'; 13 | @Input() closeDelay: number = 0; 14 | @Output() displayedChange = new EventEmitter(); 15 | 16 | constructor(private _el:ElementRef){ 17 | super(); 18 | } 19 | 20 | ngOnChanges(event: any): void { 21 | if(this.displayed && this._el.nativeElement.querySelector('.alert')){ 22 | let classes = this._el.nativeElement.querySelector('.alert').className; 23 | classes = classes.replace('fuel-ui-alert-fade-out', 'fuel-ui-alert-fade-in'); 24 | this._el.nativeElement.querySelector('.alert').className = classes; 25 | } 26 | 27 | if(this.closeDelay > 0) { 28 | setTimeout(() => { 29 | this.close(); 30 | }, this.closeDelay); 31 | } 32 | } 33 | 34 | close():void{ 35 | if(this._el.nativeElement.querySelector('.alert')){ 36 | let classes = this._el.nativeElement.querySelector('.alert').className; 37 | classes = classes.replace('fuel-ui-alert-fade-in', 'fuel-ui-alert-fade-out'); 38 | this._el.nativeElement.querySelector('.alert').className = classes; 39 | } 40 | setTimeout(() => { 41 | this.displayed = false; 42 | this.displayedChange.next(null); 43 | }, 1000); 44 | } 45 | } 46 | 47 | export var ALERT_PROVIDERS = [ 48 | Alert 49 | ]; -------------------------------------------------------------------------------- /src/components/DatePicker/readme.md: -------------------------------------------------------------------------------- 1 | ### DatePicker Selector 2 | `DatePicker` - `` 3 | 4 | ### DatePicker Settings 5 | * `label` _- string_ - 6 | String to be used in field placeholder text 7 | * `minDate` _- string / Date_ - 8 | Minimum allowable calendar date 9 | * `maxDate` _- string / Date_ - 10 | Maximum allowable calendar date 11 | * `[dateFilter]` _- function(date): boolean_ - 12 | Optional method for determining calendar date eligability 13 | * `[(value)]` _- Date_ - 14 | Date selected from datePicker 15 | 16 | 17 | ### DatePicker Example 18 | ```html 19 | 25 | 26 | ``` 27 | 28 | 29 | 30 | ### DateRangePicker Selector 31 | `DateRangePicker` - `` 32 | 33 | ### DateRangePicker Settings 34 | * `startLabel` _- string_ - 35 | String to be used in start date field placeholder text 36 | * `endLabel` _- string_ - 37 | String to be used in end date field placeholder text 38 | * `minDate` _- string / Date_ - 39 | Minimum allowable calendar date 40 | * `maxDate` _- string / Date_ - 41 | Maximum allowable calendar date 42 | * `[dateFilter]` _- function(date): boolean_ - 43 | Optional method for determining calendar date eligability 44 | * `[(value)]` _- DateRange_ - 45 | Object containing start and end Date properties 46 | * `[(startDate)]` _- Date_ - 47 | Selected start Date 48 | * `[(endDate)]` _- Date_ - 49 | Selected end Date 50 | 51 | 52 | ### DateRangePicker Example 53 | ```html 54 | 61 | 62 | ``` 63 | -------------------------------------------------------------------------------- /src/components/Tag/Tag.ts: -------------------------------------------------------------------------------- 1 | import {Directive, OnInit, OnDestroy, Input, Output, EventEmitter} from '@angular/core'; 2 | import {TagSet} from './TagSet'; 3 | 4 | @Directive({ 5 | selector: 'tag, [tag]' 6 | }) 7 | export class Tag implements OnInit, OnDestroy { 8 | @Input() public title:string; 9 | @Input() public value:any; 10 | @Input() public removable:boolean = false; 11 | 12 | @Input() 13 | public get pill():boolean { return this._pill;}; 14 | public set pill(value:boolean) { 15 | this._pill = value; 16 | this.setClassMap(); 17 | } 18 | protected _pill:boolean; 19 | 20 | @Input() 21 | public get color():string {return this._color;}; 22 | public set color(value:string) { 23 | this._color = value; 24 | this.setClassMap(); 25 | } 26 | protected _color:string; 27 | 28 | @Input() 29 | public get disabled():boolean {return this._disabled;}; 30 | public set disabled(value:boolean) { 31 | this._disabled = value; 32 | this.setClassMap(); 33 | } 34 | protected _disabled:boolean; 35 | 36 | @Output() public remove:EventEmitter = new EventEmitter(false); 37 | 38 | private classMap:any = {}; 39 | public tagset:TagSet; 40 | 41 | public constructor(tagset:TagSet) { 42 | this.tagset = tagset; 43 | this.tagset.addTag(this); 44 | } 45 | 46 | public ngOnInit():void { 47 | this.color = this.color !== 'undefined' ? this.color : 'default'; 48 | } 49 | 50 | public ngOnDestroy():void { 51 | this.remove.next(this); 52 | this.tagset.removeTag(this); 53 | } 54 | 55 | private setClassMap():void { 56 | this.classMap = { 57 | 'disabled': this.disabled, 58 | 'label-pill': this.pill, 59 | ['label-' + ((this.color && this.color.toLowerCase()) || 'default')]: true 60 | }; 61 | } 62 | } 63 | 64 | export var TAG_PROVIDERS = [ 65 | Tag, 66 | TagSet 67 | ]; -------------------------------------------------------------------------------- /src/pipes/Format/Format.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | import {DatePipe, DecimalPipe} from '@angular/common'; 3 | import {StringHelper} from '../../utilities/StringUtils'; 4 | 5 | @Pipe({ 6 | name: 'format' 7 | }) 8 | export class FormatPipe implements PipeTransform { 9 | 10 | datePipe: DatePipe = new DatePipe(); 11 | decimalPipe: DecimalPipe = new DecimalPipe(); 12 | 13 | constructor(){} 14 | 15 | transform(input:string, args:any): any { 16 | var format = ''; 17 | var parsedFloat = 0; 18 | var pipeArgs = args.split(':'); 19 | for(var i = 0; i < pipeArgs.length; i++){ 20 | pipeArgs[i] = pipeArgs[i].trim(' '); 21 | } 22 | 23 | //Escape all html if not explicitly set 24 | if(pipeArgs[0].toLowerCase() !== 'html') 25 | input = StringHelper.escapeHtml(input); 26 | 27 | switch(pipeArgs[0].toLowerCase()) { 28 | case 'text': 29 | return input; 30 | case 'decimal': 31 | case 'number': 32 | parsedFloat = !isNaN(parseFloat(input)) ? parseFloat(input) : 0; 33 | format = pipeArgs.length > 1 ? pipeArgs[1] : null; 34 | return this.decimalPipe.transform(parsedFloat, format); 35 | case 'percentage': 36 | parsedFloat = !isNaN(parseFloat(input)) ? parseFloat(input) : 0; 37 | format = pipeArgs.length > 1 ? pipeArgs[1] : null; 38 | return this.decimalPipe.transform(parsedFloat, format) + '%'; 39 | case 'date': 40 | case 'datetime': 41 | var date = !isNaN(parseInt(input)) ? parseInt(input) : new Date(input); 42 | format = 'MMM d, y h:mm:ss a'; 43 | if(pipeArgs.length > 1) 44 | { 45 | format = ''; 46 | for(var i = 1; i < pipeArgs.length; i++){ 47 | format += pipeArgs[i]; 48 | } 49 | } 50 | return this.datePipe.transform(date, format); 51 | default: 52 | return input; 53 | } 54 | } 55 | } 56 | 57 | export var FORMAT_PROVIDERS = [ 58 | FormatPipe 59 | ]; -------------------------------------------------------------------------------- /src/components/Pagination/Pagination.html: -------------------------------------------------------------------------------- 1 | 32 | 33 |
34 | Jump to: 35 | 38 |
-------------------------------------------------------------------------------- /src/components/Tab/Tab.ts: -------------------------------------------------------------------------------- 1 | import {Directive, OnDestroy, Input, Output, HostBinding, EventEmitter} from '@angular/core'; 2 | import {TabSet} from './TabSet'; 3 | 4 | @Directive({ 5 | selector: 'tab, [tab]' 6 | }) 7 | export class Tab implements OnDestroy { 8 | @Input() heading:string; 9 | @Input() disabled:boolean; 10 | @Input() removable:boolean; 11 | 12 | /** tab active state toggle */ 13 | @HostBinding('class.active') 14 | @Input() 15 | public get active():boolean { 16 | return this._active; 17 | } 18 | public set active(active:boolean) { 19 | if (this.disabled && active || !active) { 20 | 21 | //Only emit deselect event when changing 22 | if(this._active && this._active != active) { 23 | this.deselect.next(this); 24 | } 25 | 26 | if (!active) { 27 | this._active = active; 28 | } 29 | 30 | this.activeChange.next(this._active); 31 | return; 32 | } 33 | 34 | //Only emit select event when changing 35 | if(this._active != active){ 36 | this.select.next(this); 37 | } 38 | 39 | this._active = active; 40 | this.activeChange.next(this._active); 41 | this.tabset.tabs.forEach((tab:Tab) => { 42 | if (tab !== this) { 43 | tab.active = false; 44 | tab.activeChange.next(false); 45 | } 46 | }); 47 | } 48 | 49 | @Output() activeChange:EventEmitter = new EventEmitter(false); 50 | @Output() select:EventEmitter = new EventEmitter(false); 51 | @Output() deselect:EventEmitter = new EventEmitter(false); 52 | @Output() remove:EventEmitter = new EventEmitter(false); 53 | 54 | @HostBinding('class.tab-pane') addClass:boolean = true; 55 | 56 | public tabset:TabSet; 57 | private _active:boolean; 58 | 59 | public constructor(tabset:TabSet) { 60 | this.tabset = tabset; 61 | this.tabset.addTab(this); 62 | } 63 | 64 | public ngOnDestroy():void { 65 | this.tabset.removeTab(this); 66 | } 67 | } 68 | 69 | export var TAB_PROVIDERS = [ 70 | Tab, 71 | TabSet 72 | ]; -------------------------------------------------------------------------------- /src/components/Modal/readme.md: -------------------------------------------------------------------------------- 1 | ### Modal Selector 2 | `modal` - `` 3 | 4 | ### Open/Close Modal 5 | Use the component's `showModal(displayed: boolean)` method to properly trigger the modal's display. Reference the modal using in your view to have access to the method to use. 6 | 7 | ### Modal Settings 8 | 9 | * `[closeButton]` _- boolean - (Default: `true`)(Optional)_ - 10 | Takes a boolean that causes the close button to be displayed in the top right corner 11 | * `[closeOnUnfocus]` _- boolean - (Default: `true`)(Optional)_- 12 | Takes a boolean that causes the modal to close when a user clicks outside of the modal 13 | * `[modalTitle]` _- string - (Default: `null`)(Optional)_ - 14 | The heading of the modal 15 | 16 | ### Modal inner content 17 | * What is displayed below the header of the modal 18 | 19 | ### Modal Example 20 | ```javascript 21 | closeButton: boolean = true; 22 | closeOnUnfocus: boolean = true; 23 | modalTitle: string = 'This is a Modal'; 24 | ``` 25 | 26 | ```html 27 | 31 | 34 | 41 | 42 | ``` 43 | 44 | ### Close/Open Model from a Class 45 | ```javascript 46 | closeButton: boolean = true; 47 | closeOnUnfocus: boolean = true; 48 | modalTitle: string = 'This is a Modal'; 49 | 50 | toggleModal(modal:any){ 51 | modal.showModal(); 52 | } 53 | ``` 54 | 55 | ```html 56 | 60 | 63 | 70 | 71 | 72 | 77 | ``` -------------------------------------------------------------------------------- /src/components/Modal/Modal.ts: -------------------------------------------------------------------------------- 1 | import {Component, ElementRef, Input, Output, EventEmitter} from '@angular/core'; 2 | import {CORE_DIRECTIVES} from '@angular/common'; 3 | import {Animation} from "../../directives/Animation/Animation"; 4 | 5 | @Component({ 6 | selector: 'modal', 7 | host:{ 8 | '(click)': 'clickElement($event)' 9 | }, 10 | templateUrl: 'components/Modal/Modal.html', 11 | directives: [CORE_DIRECTIVES, Animation] 12 | }) 13 | export class Modal { 14 | private _el:HTMLElement; 15 | displayed: boolean = false; 16 | @Input() closeOnUnfocus:boolean = true; 17 | @Input() closeButton:boolean = true; 18 | @Input() modalTitle:string = ''; 19 | @Input() size:string = ''; 20 | @Output() close:EventEmitter = new EventEmitter(); 21 | @Output() open:EventEmitter = new EventEmitter(); 22 | 23 | constructor(el: ElementRef) { 24 | this._el = el.nativeElement; 25 | } 26 | 27 | clickElement(e: any){ 28 | if(this.closeOnUnfocus){ 29 | if((e.target && (e.target.className == 'modal customFadeIn' || e.target.className == 'modal-dialog')) 30 | || (e.srcElement && (e.srcElement.className == 'modal customFadeIn' || e.srcElement.className == 'modal-dialog'))) 31 | this.closeModal(); 32 | } 33 | } 34 | 35 | getElement(): HTMLElement{ 36 | return this._el; 37 | } 38 | 39 | closeModal(): boolean { 40 | this.showModal(false); 41 | this.close.next(null); 42 | return false; 43 | } 44 | 45 | showModal(isDisplayed: boolean): boolean { 46 | var body = document.body; 47 | 48 | if(isDisplayed === undefined){ 49 | this.displayed = !this.displayed; 50 | } 51 | else{ 52 | this.displayed = isDisplayed; 53 | } 54 | 55 | if(this.displayed){ 56 | body.classList.add('modal-open'); 57 | this.open.next(null); 58 | } 59 | else{ 60 | body.classList.remove('modal-open'); 61 | 62 | if(this.closeOnUnfocus){ 63 | this._el.childNodes[0].removeEventListener('click', (e: Event) => { 64 | if((e.target && (e.srcElement.className == 'modal customFadeIn' || e.srcElement.className == 'modal-dialog')) 65 | || (e.srcElement && (e.srcElement.className == 'modal customFadeIn' || e.srcElement.className == 'modal-dialog'))) 66 | this.showModal(false); 67 | }); 68 | } 69 | } 70 | 71 | return false; 72 | } 73 | } 74 | 75 | export var MODAL_PROVIDERS = [ 76 | Modal 77 | ]; -------------------------------------------------------------------------------- /src/demo.routes.ts: -------------------------------------------------------------------------------- 1 | import { provideRouter, RouterConfig } from '@angular/router'; 2 | import {DemoHome, InstallationComponent} from './demo.only'; 3 | import {AccordionDemo, AlertDemo, CarouselDemo, CollapseDemo, DatePickerDemo, DateRangePickerDemo, DropdownDemo, 4 | InfiniteScrollerDemo, ModalDemo, OffCanvasMenuDemo, PaginationDemo, ProgressDemo, TableSortableDemo, AnimationDemo, CodeHighlighterDemo, 5 | TooltipDemo, FormatDemo, MapToIterableDemo, OrderByDemo, RangeDemo, SliderDemo, TabDemo, TagDemo, TimePickerDemo, TextExpanderDemo} from './fuel-ui-demo'; 6 | 7 | const routes: RouterConfig = [ 8 | { path: '', component: DemoHome }, 9 | { path: 'installation', component: InstallationComponent}, 10 | { path: 'animation/collapse', component: CollapseDemo }, 11 | { path: 'component/accordion', component: AccordionDemo }, 12 | { path: 'component/alert', component: AlertDemo }, 13 | { path: 'component/carousel', component: CarouselDemo }, 14 | { path: 'component/datepicker', component: DatePickerDemo }, 15 | { path: 'component/daterangepicker', component: DateRangePickerDemo }, 16 | { path: 'component/dropdown', component: DropdownDemo }, 17 | { path: 'component/infinitescroller', component: InfiniteScrollerDemo }, 18 | { path: 'component/modal', component: ModalDemo }, 19 | { path: 'component/offCanvasMenu', component: OffCanvasMenuDemo }, 20 | { path: 'component/pagination', component: PaginationDemo }, 21 | { path: 'component/progress', component: ProgressDemo }, 22 | { path: 'component/slider', component: SliderDemo }, 23 | { path: 'component/tab', component: TabDemo }, 24 | { path: 'component/tablesortable', component: TableSortableDemo }, 25 | { path: 'component/tag', component: TagDemo }, 26 | { path: 'component/textexpander', component: TextExpanderDemo }, 27 | { path: 'component/timepicker', component: TimePickerDemo }, 28 | { path: 'directive/animation', component: AnimationDemo }, 29 | { path: 'directive/codehighlighter', component: CodeHighlighterDemo }, 30 | { path: 'directive/tooltip', component: TooltipDemo }, 31 | { path: 'pipe/format', component: FormatDemo }, 32 | { path: 'pipe/maptoiterable', component: MapToIterableDemo }, 33 | { path: 'pipe/orderby', component: OrderByDemo }, 34 | { path: 'pipe/range', component: RangeDemo} 35 | ]; 36 | 37 | export const APP_ROUTER_PROVIDERS = [ 38 | provideRouter(routes) 39 | ]; -------------------------------------------------------------------------------- /src/components/Pagination/Pagination.ts: -------------------------------------------------------------------------------- 1 | import {Component, ElementRef, Input, Output, EventEmitter, OnChanges, ChangeDetectionStrategy} from '@angular/core'; 2 | import {CORE_DIRECTIVES, SlicePipe} from '@angular/common'; 3 | import {RangePipe} from '../../pipes/Range/Range'; 4 | 5 | @Component({ 6 | selector: 'pagination', 7 | changeDetection: ChangeDetectionStrategy.OnPush, 8 | properties: [ 9 | "totalPages: total-pages", 10 | "pagesAtOnce: pages-at-once" 11 | ], 12 | templateUrl: 'components/Pagination/Pagination.html', 13 | directives: [CORE_DIRECTIVES], 14 | pipes: [SlicePipe, RangePipe] 15 | }) 16 | export class Pagination implements OnChanges { 17 | @Input() currentPage: number = 1; 18 | @Input() pagesAtOnce: number = 5; 19 | @Input() totalPages: number = 10; 20 | @Input() showSteps: boolean = true; 21 | @Input() showEnds: boolean = true; 22 | @Input() showSelect: boolean = true; 23 | @Output() currentPageChange = new EventEmitter(); 24 | pagesBlank:Array = []; 25 | startingIndex:number; 26 | endingIndex:number; 27 | 28 | constructor(){ 29 | this.setPage(this.currentPage); 30 | } 31 | 32 | ngOnChanges(changes:any):void{ 33 | this.setPage(this.currentPage); 34 | } 35 | 36 | setPage(newPage:number):void{ 37 | if(newPage < 1 || newPage > this.totalPages) return; 38 | 39 | this.currentPage = newPage; 40 | 41 | //Shift pagination stuffs 42 | if(this.currentPage - Math.ceil(this.pagesAtOnce / 2) < 0 || this.totalPages - this.pagesAtOnce <= 0){ 43 | this.startingIndex = 0; 44 | this.endingIndex = this.pagesAtOnce; 45 | } 46 | else if(this.totalPages - this.currentPage <= this.pagesAtOnce - Math.ceil(this.pagesAtOnce / 2)) { 47 | this.startingIndex = this.totalPages - this.pagesAtOnce; 48 | this.endingIndex = this.totalPages; 49 | } 50 | else { 51 | this.startingIndex = this.currentPage - Math.ceil(this.pagesAtOnce / 2); 52 | this.endingIndex = this.startingIndex + this.pagesAtOnce < this.totalPages 53 | ? this.startingIndex + this.pagesAtOnce 54 | : this.totalPages; 55 | } 56 | 57 | this.currentPageChange.next(this.currentPage); 58 | } 59 | } 60 | 61 | export var PAGINATION_PROVIDERS = [ 62 | Pagination 63 | ]; -------------------------------------------------------------------------------- /src/components/Dropdown/Dropdown.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {DROPDOWN_COMPONENT_PROVIDERS} from './Dropdown'; 3 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 4 | import {TableSortable, TableSortableColumn, TableSortableSorting} from '../../components/TableSortable/TableSortable'; 5 | import {Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 6 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 7 | 8 | @Component({ 9 | template: ` 10 |
11 |
12 |
13 |

Dropdown

14 |

Dropdown is a custom component to display informational messages

15 |
16 |
17 |
18 | 19 | 20 | Link 1 21 | Link 2 22 | Link 3 23 | 24 | 25 |
26 |

Import

27 |
28 | 
29 | import {Dropdown} from 'fuel-ui/fuel-ui';
30 | 
31 | 
32 | 33 |

Getting Started

34 |

Dropdown is a custom element to programmatically create dropdowns

35 | 36 |

Usage

37 | 38 | 39 |
40 | 
41 | <dropdown label="test dropdown label">
42 |     <a href="#" class="dropdown-item">Link 1</a>
43 |     <a href="#" class="dropdown-item">Link 2</a>
44 |     <a href="#" class="dropdown-item">Link 3</a>
45 | </dropdown>
46 | 
47 | 
48 |
49 |
50 | 51 |

Attributes

52 | 56 | Loading table... 57 | 58 | 59 |
`, 60 | directives: [DROPDOWN_COMPONENT_PROVIDERS, CodeHighlighter, TableSortable, TAB_PROVIDERS] 61 | }) 62 | export class DropdownDemo { 63 | attributes:any[] = [ 64 | new Attribute('label', 'string', 'null', 'Dropdown button text') 65 | ]; 66 | attributesColumns:TableSortableColumn[] = AttributeColumns; 67 | attributesSort:TableSortableSorting = AttributesDefaultSort; 68 | } 69 | 70 | export var DROPDOWN_DEMO_PROVIDERS = [ 71 | DropdownDemo 72 | ]; -------------------------------------------------------------------------------- /src/components/DatePicker/DatePicker.html: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 | 8 | 9 |
12 |
13 |
14 | 18 |
19 | 21 |
22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
SMTWTFS
39 |
40 |
41 | 47 | 54 | {{i}} 55 | 56 | 57 |
58 |
59 |
60 |
61 | -------------------------------------------------------------------------------- /src/components/Progress/Progress.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 3 | import {TableSortable, TableSortableColumn, TableSortableSorting} from '../../components/TableSortable/TableSortable'; 4 | import {Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 5 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 6 | 7 | @Component({ 8 | template: ` 9 |
10 |
11 |
12 |

Progress

13 |

Progress is a custom component to display an overall progress based on percentage

14 |
15 |
16 |
17 | 18 |
19 |
20 |
21 | 22 |
23 | 24 |
25 |
26 |
27 | {{progress}}% 28 |
29 | 30 |
31 |

Getting Started

32 |

Progress is an HTML5 Bootstrap element that displays a graphical progress bar

33 | 34 |

Usage

35 | 36 | 37 |
38 | 
39 | <progress 
40 |     class="progress progress-striped progress-animated"
41 |     [value]="progress" 
42 |     max="100">
43 |         {
{
progress}}% 44 | </progress> 45 |
46 |
47 |
48 |
49 | 50 |

Attributes

51 | 55 | Loading table... 56 | 57 | 58 |
`, 59 | directives: [CodeHighlighter, TableSortable, TAB_PROVIDERS] 60 | }) 61 | export class ProgressDemo { 62 | progress: number = 25; 63 | 64 | attributes:Attribute[] = [ 65 | new Attribute('value', 'number', '0', 'Percentage of progress bar that is filled'), 66 | new Attribute('max', 'number', '1', 'The number to fill the progress bar completely') 67 | ]; 68 | attributesColumns:TableSortableColumn[] = AttributeColumns; 69 | attributesSort:TableSortableSorting = AttributesDefaultSort; 70 | } 71 | 72 | export var PROGRESS_DEMO_PROVIDERS = [ 73 | ProgressDemo 74 | ]; -------------------------------------------------------------------------------- /src/components/DatePicker/DatePickerField.ts: -------------------------------------------------------------------------------- 1 | import {Component, Directive, Input, Output, HostBinding, HostListener, OnInit, EventEmitter} from "@angular/core"; 2 | import {DateUtils} from "../../utilities/utilities"; 3 | 4 | @Directive({ 5 | selector: "[dateField], .date-field" 6 | }) 7 | export class DatePickerField implements OnInit { 8 | private _date = new Date(); 9 | 10 | @HostBinding("value") 11 | _value = ""; 12 | 13 | @Input() 14 | set value(value: string) { 15 | if(value == this._value) 16 | return; 17 | 18 | this._value = value; 19 | this._date = DateUtils.handleDateInput(value); 20 | this.valueChange.next(value); 21 | this.ngModelChange.next(value); 22 | this.dateChange.next(this._date); 23 | } 24 | get value(): string {return this._value;} 25 | 26 | @Output() valueChange = new EventEmitter(); 27 | 28 | @Input() 29 | set ngModel(value: any) { 30 | this.value = value; 31 | } 32 | 33 | @Output() 34 | ngModelChange = new EventEmitter(); 35 | 36 | @Input() 37 | set date(date: Date) { 38 | if(date.getTime() == this._date.getTime()) 39 | return; 40 | 41 | this._date = date; 42 | this._value = date.toLocaleDateString(); 43 | this.dateChange.next(date); 44 | this.ngModelChange.next(this._value); 45 | this.valueChange.next(this._value); 46 | } 47 | get date(): Date {return this._date;} 48 | @Output() dateChange = new EventEmitter(); 49 | 50 | @HostListener("input", ["$event.target.value"]) 51 | inputChange(value: any): void { 52 | this.value = value; 53 | } 54 | 55 | @HostListener("focus", ["$event"]) 56 | focused(event: Event): void { 57 | this.select.next(event); 58 | } 59 | 60 | @Output() select = new EventEmitter(); 61 | @HostListener("click", ["$event"]) 62 | selected(event: MouseEvent): void { 63 | this.select.next(event); 64 | } 65 | 66 | ngOnInit(): void { 67 | this.date = DateUtils.handleDateInput(this.value); 68 | } 69 | } 70 | 71 | @Component({ 72 | selector: ".date-picker-input-group", 73 | template: ` 74 |
75 | 76 | 77 | 78 | 79 |
` 80 | }) 81 | export class DatePickerFieldStyler { 82 | selectEvent = new EventEmitter(); 83 | 84 | select(event: Event): void { 85 | this.selectEvent.next(event); 86 | } 87 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fuel-ui", 3 | "version": "0.3.9", 4 | "description": "A set of utilities and Angular2 components implementing Twitter's Bootstrap 4 components", 5 | "main": "fuel-ui.js", 6 | "typings": "fuel-ui.d.ts", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "postinstall": "bower install && typings install", 10 | "prepublish": "gulp build" 11 | }, 12 | "keywords": [ 13 | "angular", 14 | "angular2", 15 | "bootstrap", 16 | "bootstrap4", 17 | "component", 18 | "components" 19 | ], 20 | "author": "Fuel Travel", 21 | "license": "ISC", 22 | "repository": { 23 | "type": "git", 24 | "url": "git+ssh://git@github.com/FuelInteractive/fuel-ui.git" 25 | }, 26 | "devDependencies": { 27 | "bourbon": "^4.2.6", 28 | "del": "^2.2.0", 29 | "gulp": "^3.9.0", 30 | "gulp-cache-bust": "^1.0.1", 31 | "gulp-concat": "^2.6.0", 32 | "gulp-inline-ng2-template": "^2.0.4", 33 | "gulp-minify-css": "^1.2.4", 34 | "gulp-rename": "^1.2.2", 35 | "gulp-sass": "^2.0.4", 36 | "gulp-sass-glob": "^1.0.6", 37 | "gulp-server-livereload": "^1.7.0", 38 | "gulp-sourcemaps": "^1.6.0", 39 | "gulp-typescript": "^2.13.6", 40 | "gulp-webserver": "^0.9.1", 41 | "merge2": "^1.0.2", 42 | "path": "^0.12.7", 43 | "prismjs": "^1.5.1", 44 | "run-sequence": "^1.1.5", 45 | "systemjs-builder": "^0.15.23", 46 | "typescript": "^1.9.0-dev.20160615-1.0", 47 | "typings": "^1.3.1", 48 | "vinyl-buffer": "^1.0.0", 49 | "vinyl-paths": "^2.1.0", 50 | "vinyl-source-stream": "^1.1.0" 51 | }, 52 | "peerDependencies": { 53 | "@angular/common": "2.0.0-rc.4", 54 | "@angular/compiler": "2.0.0-rc.4", 55 | "@angular/core": "2.0.0-rc.4", 56 | "@angular/http": "2.0.0-rc.4", 57 | "@angular/platform-browser": "2.0.0-rc.4", 58 | "@angular/platform-browser-dynamic": "2.0.0-rc.4", 59 | "bootstrap": "^4.0.0-alpha.2", 60 | "font-awesome": "^4.6.3", 61 | "rxjs": "5.0.0-beta.6", 62 | "zone.js": "0.6.12" 63 | }, 64 | "dependencies": { 65 | "@angular/common": "2.0.0-rc.4", 66 | "@angular/compiler": "2.0.0-rc.4", 67 | "@angular/core": "2.0.0-rc.4", 68 | "@angular/forms": "^0.2.0", 69 | "@angular/http": "2.0.0-rc.4", 70 | "@angular/platform-browser": "2.0.0-rc.4", 71 | "@angular/platform-browser-dynamic": "2.0.0-rc.4", 72 | "@angular/router": "3.0.0-beta.2", 73 | "bootstrap": "^4.0.0-alpha.2", 74 | "core-js": "^2.2.1", 75 | "es6-shim": "^0.35.1", 76 | "font-awesome": "^4.6.3", 77 | "hammerjs": "^2.0.8", 78 | "reflect-metadata": "^0.1.3", 79 | "rxjs": "5.0.0-beta.6", 80 | "systemjs": "^0.19.31", 81 | "zone.js": "0.6.12" 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/components/TextExpander/TextExpander.ts: -------------------------------------------------------------------------------- 1 | import {Component, ElementRef, Input, Output, EventEmitter} from '@angular/core'; 2 | import {CORE_DIRECTIVES, SlicePipe} from '@angular/common'; 3 | 4 | @Component({ 5 | selector: 'text-expander', 6 | templateUrl: 'components/TextExpander/TextExpander.html', 7 | directives: [CORE_DIRECTIVES], 8 | pipes: [SlicePipe] 9 | }) 10 | export class TextExpander { 11 | @Input() expanded: boolean = false; 12 | @Input() ellipsis: boolean = true; 13 | @Input() text: string = null; 14 | @Input() characters: number = 50; 15 | @Input() words: number = 0; 16 | @Input() expandText: string = "show more"; 17 | @Input() shrinkText: string = "show less"; 18 | @Output() expandedChange = new EventEmitter() 19 | 20 | toggleExpand(): void{ 21 | this.expanded = !this.expanded; 22 | this.expandedChange.next(this.expanded); 23 | } 24 | 25 | amountOfCharacters(): number{ 26 | if(this.words > 0) 27 | return this.getCharactersUpToNumberOfWords(this.words); 28 | 29 | return this.characters; 30 | } 31 | 32 | getCharactersUpToNumberOfWords(words: number): number{ 33 | //make copy of text to remove multiple spaces between words 34 | let textCopy = this.text; 35 | textCopy = textCopy.replace(/(^\s*)|(\s*$)/gi,""); 36 | textCopy = textCopy.replace(/[ ]{2,}/gi," "); 37 | textCopy = textCopy.replace(/\n /,"\n"); 38 | 39 | //get all words of new string 40 | let wordsArr = textCopy.split(' '); 41 | 42 | //show the entire text if requested words is higher or equal to actual 43 | if(words >= wordsArr.length - 1) 44 | return this.text.length; 45 | 46 | //split array up to the number of words needed 47 | wordsArr = wordsArr.splice(0, words); 48 | 49 | //get the last word that will be showing 50 | let lastWordToShow = wordsArr[wordsArr.length - 1]; 51 | 52 | //find the number of times that word is in the new array 53 | let occurencesOfLastWord = wordsArr.filter((str) => {return str === lastWordToShow}).length; 54 | 55 | //word only shows once so get the location in original text and add the length of the word 56 | if(occurencesOfLastWord == 1) 57 | return this.text.split(lastWordToShow)[0].length + lastWordToShow.length; 58 | 59 | //loop over each occurence of the last word and sum up characters 60 | let charactersUntilLastWord = 0; 61 | for(let i = 0; i < occurencesOfLastWord; i++){ 62 | charactersUntilLastWord += this.text.split(lastWordToShow)[i].length; 63 | } 64 | 65 | return charactersUntilLastWord + lastWordToShow.length; 66 | } 67 | } 68 | 69 | export var TEXTEXPANDER_PROVIDERS = [ 70 | TextExpander 71 | ]; -------------------------------------------------------------------------------- /src/directives/Animation/Animation.ts: -------------------------------------------------------------------------------- 1 | import {Directive, Input, Output, EventEmitter, ElementRef, OnInit, OnChanges} from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[animation]', 5 | host: { 6 | '(animationstart)': 'animationStarted($event)', 7 | '(webkitAnimationStart)': 'animationStarted($event)', 8 | '(oanimationstart)': 'animationStarted($event)', 9 | '(MSAnimationStart)': 'animationStarted($event)', 10 | '(animationend)': 'animationEnded($event)', 11 | '(webkitAnimationEnd)': 'animationEnded($event)', 12 | '(oanimationend)': 'animationEnded($event)', 13 | '(MSAnimationEnd)': 'animationEnded($event)' 14 | } 15 | }) 16 | export class Animation implements OnInit, OnChanges { 17 | @Output() onAnimationStart = new EventEmitter(); 18 | @Output() onAnimationEnd = new EventEmitter(); 19 | 20 | @Input('animation') animationClasses: string = ''; 21 | @Input() play: boolean = false; 22 | @Input() id: string = ''; // use for query filtering 23 | @Input() group: string = ''; // use for query filtering 24 | 25 | _animationQueue: string[] = []; 26 | _callbacks: (() => void)[] = []; 27 | element: Element; 28 | 29 | constructor(element: ElementRef) { 30 | this.element = element.nativeElement; 31 | } 32 | 33 | ngOnChanges(): void { 34 | this.setup(); 35 | } 36 | 37 | ngOnInit(): void { 38 | this.setup(); 39 | } 40 | 41 | addAnimation(animationClasses: string): Animation { 42 | animationClasses.split(' ') 43 | .map(c => this._animationQueue.push(c)); 44 | this.animationClasses += " " + animationClasses; 45 | return this; 46 | } 47 | 48 | setup(): Animation { 49 | this._animationQueue = this.animationClasses 50 | .split(" ") 51 | .filter((c) => c.length > 0); 52 | 53 | if(this.play && this._animationQueue.length > 0) 54 | this.startAnimation(); 55 | return this; 56 | } 57 | 58 | startAnimation(callback: () => void = null): Animation { 59 | if(callback != null) 60 | this._callbacks.push(callback); 61 | 62 | this._animationQueue.shift() 63 | .split('.') 64 | .filter((c) => c.length > 0) 65 | .map((c) => this.element.classList.add(c)); 66 | return this; 67 | } 68 | 69 | cleanAnimation(): Animation { 70 | this.animationClasses 71 | .replace('.', ' ') 72 | .split(' ') 73 | .filter((c) => c.length > 0) 74 | .map((c) => { 75 | this.element.classList.remove(c) 76 | }); 77 | return this; 78 | } 79 | 80 | animationStarted(event: Event): void { 81 | this.onAnimationStart.next(null); 82 | } 83 | 84 | animationEnded(event: Event): void { 85 | this.cleanAnimation(); 86 | if(this._animationQueue.length > 0){ 87 | this.startAnimation(); 88 | return; 89 | } 90 | 91 | while(this._callbacks.length > 0) 92 | this._callbacks.shift()(); 93 | 94 | this.onAnimationEnd.next(null); 95 | } 96 | } -------------------------------------------------------------------------------- /src/components/components.ts: -------------------------------------------------------------------------------- 1 | import {ACCORDION_PROVIDERS, AccordionItem} from "./Accordion/AccordionItem"; 2 | import {Accordion} from "./Accordion/Accordion"; 3 | import {ALERT_PROVIDERS, Alert} from "./Alert/Alert"; 4 | import {CAROUSEL_PROVIDERS, Carousel, CarouselItem} from "./Carousel/Carousel"; 5 | import {DATE_PICKER_PROVIDERS, DatePickerCalendar, DatePicker, DateRangePicker, StartDateField, EndDateField, DatePickerField, DatePickerFieldStyler} from "./DatePicker/DatePickerProviders"; 6 | import {MODAL_PROVIDERS, Modal} from "./Modal/Modal"; 7 | import {PAGINATION_PROVIDERS, Pagination} from "./Pagination/Pagination"; 8 | import {INFINITE_SCROLLER_PROVIDERS, InfiniteScroller, ScrollItem} from "./InfiniteScroller/InfiniteScroller"; 9 | import {DROPDOWN_COMPONENT_PROVIDERS, Dropdown} from "./Dropdown/Dropdown"; 10 | import {TAB_PROVIDERS, Tab} from "./Tab/Tab"; 11 | import {TabSet} from "./Tab/TabSet"; 12 | import {TAG_PROVIDERS, Tag} from "./Tag/Tag"; 13 | import {TagSet} from "./Tag/TagSet"; 14 | import {TABLESORTABLE_PROVIDERS, TableSortable} from "./TableSortable/TableSortable"; 15 | import {TableSortableColumn} from "./TableSortable/TableSortableColumn"; 16 | import {TableSortableSorting} from "./TableSortable/TableSortableSorting"; 17 | import {SLIDER_COMPONENT_PROVIDERS, Slider} from "./Slider/Slider"; 18 | import {TIMEPICKER_PROVIDERS, TimePicker} from "./TimePicker/TimePicker"; 19 | import {TEXTEXPANDER_PROVIDERS, TextExpander} from "./TextExpander/TextExpander"; 20 | import {OFF_CANVAS_MENU_PROVIDERS, OffCanvasMenu, OffCanvasMenuClose} from "./OffCanvasMenu/OffCanvasMenu"; 21 | 22 | export var FUELUI_COMPONENT_PROVIDERS = [ 23 | ACCORDION_PROVIDERS, 24 | ALERT_PROVIDERS, 25 | CAROUSEL_PROVIDERS, 26 | DATE_PICKER_PROVIDERS, 27 | MODAL_PROVIDERS, 28 | PAGINATION_PROVIDERS, 29 | INFINITE_SCROLLER_PROVIDERS, 30 | DROPDOWN_COMPONENT_PROVIDERS, 31 | TABLESORTABLE_PROVIDERS, 32 | SLIDER_COMPONENT_PROVIDERS, 33 | TAB_PROVIDERS, 34 | TAG_PROVIDERS, 35 | TEXTEXPANDER_PROVIDERS, 36 | TIMEPICKER_PROVIDERS, 37 | OFF_CANVAS_MENU_PROVIDERS 38 | ]; 39 | 40 | export * from "./Accordion/Accordion"; 41 | export * from "./Accordion/AccordionItem"; 42 | export * from "./Alert/Alert"; 43 | export * from "./Carousel/Carousel"; 44 | export * from "./DatePicker/DatePickerProviders"; 45 | export * from "./Modal/Modal"; 46 | export * from "./Pagination/Pagination"; 47 | export * from "./InfiniteScroller/InfiniteScroller"; 48 | export * from "./Dropdown/Dropdown"; 49 | export * from "./Tab/Tab"; 50 | export * from "./Tab/TabSet"; 51 | export * from "./TableSortable/TableSortable"; 52 | export * from "./TableSortable/TableSortableColumn"; 53 | export * from "./TableSortable/TableSortableSorting"; 54 | export * from "./Tag/Tag"; 55 | export * from "./Tag/TagSet"; 56 | export * from "./Slider/Slider"; 57 | export * from "./TimePicker/TimePicker"; 58 | export * from "./TextExpander/TextExpander"; 59 | export * from "./OffCanvasMenu/OffCanvasMenu"; -------------------------------------------------------------------------------- /src/components/demoComponents.ts: -------------------------------------------------------------------------------- 1 | import {ACCORDION_DEMO_PROVIDERS, AccordionDemo} from "./Accordion/Accordion.Demo"; 2 | import {ALERT_DEMO_PROVIDERS, AlertDemo} from "./Alert/Alert.Demo"; 3 | import {CAROUSEL_DEMO_PROVIDERS, CarouselDemo} from "./Carousel/Carousel.Demo"; 4 | import {DATEPICKER_DEMO_PROVIDERS, DatePickerDemo} from "./DatePicker/DatePicker.Demo"; 5 | import {DATERANGEPICKER_DEMO_PROVIDERS, DateRangePickerDemo} from "./DatePicker/DateRangePicker.Demo"; 6 | import {DROPDOWN_DEMO_PROVIDERS, DropdownDemo} from "./Dropdown/Dropdown.Demo"; 7 | import {INFINITESCROLLER_DEMO_PROVIDERS, InfiniteScrollerDemo} from "./InfiniteScroller/InfiniteScroller.Demo"; 8 | import {MODAL_DEMO_PROVIDERS, ModalDemo} from "./Modal/Modal.Demo"; 9 | import {OFFCANVASMENU_DEMO_PROVIDERS, OffCanvasMenuDemo} from "./OffCanvasMenu/OffCanvasMenu.Demo"; 10 | import {PAGINATION_DEMO_PROVIDERS, PaginationDemo} from "./Pagination/Pagination.Demo"; 11 | import {PROGRESS_DEMO_PROVIDERS, ProgressDemo} from "./Progress/Progress.Demo"; 12 | import {TABLESORTABLE_DEMO_PROVIDERS, TableSortableDemo} from "./TableSortable/TableSortable.Demo"; 13 | import {SLIDER_DEMO_PROVIDERS, SliderDemo} from "./Slider/Slider.Demo"; 14 | import {TAB_DEMO_PROVIDERS, TabDemo} from "./Tab/Tab.Demo"; 15 | import {TAG_DEMO_PROVIDERS, TagDemo} from "./Tag/Tag.Demo"; 16 | import {TIMEPICKER_DEMO_PROVIDERS, TimePickerDemo} from "./TimePicker/TimePicker.Demo"; 17 | import {TEXTEXPANDER_DEMO_PROVIDERS, TextExpanderDemo} from "./TextExpander/TextExpander.Demo"; 18 | 19 | export var FUELUI_DEMO_COMPONENT_PROVIDERS = [ 20 | ACCORDION_DEMO_PROVIDERS, 21 | ALERT_DEMO_PROVIDERS, 22 | CAROUSEL_DEMO_PROVIDERS, 23 | DATEPICKER_DEMO_PROVIDERS, 24 | DATERANGEPICKER_DEMO_PROVIDERS, 25 | DROPDOWN_DEMO_PROVIDERS, 26 | INFINITESCROLLER_DEMO_PROVIDERS, 27 | MODAL_DEMO_PROVIDERS, 28 | OFFCANVASMENU_DEMO_PROVIDERS, 29 | PAGINATION_DEMO_PROVIDERS, 30 | PROGRESS_DEMO_PROVIDERS, 31 | TABLESORTABLE_DEMO_PROVIDERS, 32 | SLIDER_DEMO_PROVIDERS, 33 | TAB_DEMO_PROVIDERS, 34 | TAG_DEMO_PROVIDERS, 35 | TEXTEXPANDER_DEMO_PROVIDERS, 36 | TIMEPICKER_DEMO_PROVIDERS 37 | ]; 38 | 39 | export * from "./Accordion/Accordion.Demo"; 40 | export * from "./Alert/Alert.Demo"; 41 | export * from "./Carousel/Carousel.Demo"; 42 | export * from "./DatePicker/DatePicker.Demo"; 43 | export * from "./DatePicker/DateRangePicker.Demo"; 44 | export * from "./Dropdown/Dropdown.Demo"; 45 | export * from "./InfiniteScroller/InfiniteScroller.Demo"; 46 | export * from "./Modal/Modal.Demo"; 47 | export * from "./OffCanvasMenu/OffCanvasMenu.Demo"; 48 | export * from "./Pagination/Pagination.Demo"; 49 | export * from "./Progress/Progress.Demo"; 50 | export * from "./TableSortable/TableSortable.Demo"; 51 | export * from "./Slider/Slider.Demo"; 52 | export * from "./Tab/Tab.Demo"; 53 | export * from "./Tag/Tag.Demo"; 54 | export * from "./TimePicker/TimePicker.Demo"; 55 | export * from "./TextExpander/TextExpander.Demo"; -------------------------------------------------------------------------------- /src/components/DatePicker/DatePickerCalendar.scss: -------------------------------------------------------------------------------- 1 | @import "../../styles/variables"; 2 | @import "../../styles/bourbon"; 3 | @import "../../styles/media_queries"; 4 | 5 | .fuel-ui-datepicker-calendar { 6 | .table { 7 | font-size: .75rem; 8 | border: none; 9 | border-top: 1px solid $table-border-color; 10 | background-color: $body-bg; 11 | border-collapse: collapse; 12 | 13 | .calendar-date { 14 | z-index: 200; 15 | background-color: transparent; 16 | } 17 | 18 | tr { 19 | border: none; 20 | } 21 | 22 | th, td { 23 | text-align: center; 24 | vertical-align: middle; 25 | font-size: .75rem; 26 | padding: .1rem; 27 | height: 1.75rem; 28 | border: none; 29 | position: relative; 30 | 31 | @include mobile-only { 32 | padding: .5rem; 33 | font-size: 1rem; 34 | } 35 | } 36 | 37 | td { 38 | &.selectable { 39 | cursor: pointer !important; 40 | 41 | &:hover { 42 | background-color: $brand-primary; 43 | color: $body-bg; 44 | } 45 | } 46 | 47 | &.selected { 48 | background-color: desaturate(lighten($brand-primary, 33%), 33%); 49 | color: $body-bg; 50 | } 51 | 52 | &.disabled { 53 | color: desaturate(lighten($btn-link-disabled-color, 25%), 25%); 54 | } 55 | 56 | &.startDate, &.endDate { 57 | background-color: $brand-primary; 58 | color: $body-bg; 59 | } 60 | 61 | &.startDate:after { 62 | content: ''; 63 | position: absolute; 64 | top: 0; 65 | bottom: 0; 66 | width: 0; 67 | right: 0; 68 | background-color: transparent; 69 | border-left: 1em solid transparent; 70 | border-top: 1.1em solid desaturate(lighten($brand-primary, 33%), 33%); 71 | border-bottom: 1.1em solid desaturate(lighten($brand-primary, 33%), 33%); 72 | } 73 | 74 | &.endDate:before { 75 | content: ''; 76 | position: absolute; 77 | top: 0; 78 | bottom: 0; 79 | width: 0; 80 | left: 0; 81 | background-color: transparent; 82 | border-right: 1em solid transparent; 83 | border-top: 1.1em solid desaturate(lighten($brand-primary, 33%), 33%); 84 | border-bottom: 1.1em solid desaturate(lighten($brand-primary, 33%), 33%); 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/components/Tab/TabSet.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit, OnDestroy, Input, Output} from '@angular/core'; 2 | import {NgClass} from '@angular/common'; 3 | import {Tab} from './Tab'; 4 | 5 | @Component({ 6 | selector: 'tabset', 7 | directives: [NgClass], 8 | templateUrl: 'components/Tab/TabSet.html' 9 | }) 10 | export class TabSet implements OnInit, OnDestroy { 11 | 12 | @Input() 13 | public get vertical():boolean { return this._vertical;}; 14 | public set vertical(value:boolean) { 15 | this._vertical = value; 16 | this.setClassMap(); 17 | } 18 | protected _vertical:boolean; 19 | 20 | @Input() 21 | public get type():string {return this._type;}; 22 | public set type(value:string) { 23 | this._type = value; 24 | this.setClassMap(); 25 | } 26 | protected _type:string; 27 | 28 | public tabs:Array = []; 29 | private destroyed:boolean; 30 | private classMap:any = {}; 31 | 32 | public ngOnInit():void { 33 | this.type = this.type !== 'undefined' ? this.type : 'tabs'; 34 | } 35 | 36 | public ngOnDestroy():void { 37 | this.destroyed = true; 38 | } 39 | 40 | public addTab(tab:Tab):void { 41 | this.tabs.push(tab); 42 | tab.active = this.tabs.length === 1 && tab.active !== false; 43 | } 44 | 45 | public removeTab(tab:Tab):void { 46 | let index = this.tabs.indexOf(tab); 47 | if (index === -1 || this.destroyed) { 48 | return; 49 | } 50 | 51 | if (tab.active && this.hasAvailableTabs(index)) { 52 | let newActiveIndex = this.getClosestTabIndex(index); 53 | this.tabs[newActiveIndex].active = true; 54 | } 55 | 56 | tab.remove.next(tab); 57 | this.tabs.splice(index, 1); 58 | } 59 | 60 | private getClosestTabIndex(index:number):number { 61 | let tabsLength = this.tabs.length; 62 | if (!tabsLength) { 63 | return -1; 64 | } 65 | 66 | for (let step = 1; step <= tabsLength; step += 1) { 67 | let prevIndex = index - step; 68 | let nextIndex = index + step; 69 | if (this.tabs[prevIndex] && !this.tabs[prevIndex].disabled) { 70 | return prevIndex; 71 | } 72 | if (this.tabs[nextIndex] && !this.tabs[nextIndex].disabled) { 73 | return nextIndex; 74 | } 75 | } 76 | return -1; 77 | } 78 | 79 | private hasAvailableTabs(index:number):boolean { 80 | let tabsLength = this.tabs.length; 81 | if (!tabsLength) { 82 | return false; 83 | } 84 | 85 | for (let i = 0; i < tabsLength; i += 1) { 86 | if (!this.tabs[i].disabled && i !== index) { 87 | return true; 88 | } 89 | } 90 | return false; 91 | } 92 | 93 | private setClassMap():void { 94 | this.classMap = { 95 | 'nav-stacked': this.vertical, 96 | ['nav-' + (this.type || 'tabs')]: true 97 | }; 98 | } 99 | } -------------------------------------------------------------------------------- /src/components/Slider/readme.md: -------------------------------------------------------------------------------- 1 | ### Slider Selector 2 | `Slider` - `` 3 | 4 | ### Description 5 | This is the NoUiSlider (from Refreshless.com), wrapped in an Angular2 component 6 | 7 | ### Slider Settings 8 | 9 | * `[background]` _- string - (Default: `'#E24932'`)_ - 10 | Background color of the area of the slider that counts toward the value 11 | * `[behavior]` _- string_ - (Default: `'tap'`)_ - 12 | The way a user can interact with the slider. Can use "tap" or "fixed". "tap" allows for tapping and dragging. "fixed" disables the slider without greying it out. 13 | * `[decimals]` _- number - (Default: `0`)_ - 14 | Number of decimals on the value(s) and pips 15 | * `[direction]` _- string - (Default: `'ltr'`)_ - 16 | The direction of the values on the slider when the orientation is "horizontal", can be "ltr" for left to right or "rtl" for right to left 17 | * `[height]` _- string - (Default: `null` or `'200px'`)_ - 18 | Height of the slider element. Is _REQUIRED_ when orientation is set to "vertical". Defaults to "200px" when using vertical slider 19 | * `[margin]` _- number - (Default: `10`)_ - 20 | The least amount of distance between the first and second values 21 | * `[maxValue]` _- number - (Default: `100`)_ - 22 | The maximum value allowed on the entire slider 23 | * `[minValue]` _- number - (Default: `rangeStart`)_ - 24 | The minimum value allowed on the entire slider 25 | * `[orientation]` _- string - (Default: `'horizontal'`)_ - 26 | The orientation of the slider, can be "horizontal" or "vertical" 27 | * `[pips]` _- number - (Default: `5`)_ - 28 | The number of numbers on the legend, `including the min and max numbers`. They are spread out evenly, so in the case of 5 pips: 0% (min), 25%, 50%, 75%, and 100% (max) numbers are on the legend. 2 pips would mean only the min and the max are showing. 29 | * `[(secondValue)]` _- number - (Default: `null`)_ - 30 | The value of the second number of the slider. When set to null the second handle will not display. 31 | * `[step]` _- number - (Default: `10`)_ - 32 | Slider increment on dragging 33 | * `[(value)]` _- number - (Default: `0`)_ - 34 | The value of the first number of the slider 35 | * `[width]` _- string - (Default: `null`)_ - 36 | Width of the slider element 37 | 38 | ### Slider Example 39 | ```javascript 40 | sliderValue: number = 50; 41 | secondSliderValue: number = 250; 42 | minValue: number = 0; 43 | maxValue: number = 400; 44 | ``` 45 | 46 | ```html 47 | 48 | 50 | 51 | 52 | 53 | 56 | 57 | 58 | 59 | 61 | 62 | 63 | 64 | 67 | 68 | ``` 69 | -------------------------------------------------------------------------------- /src/pipes/MapToIterable/MapToIterable.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {CORE_DIRECTIVES} from '@angular/common'; 3 | import {MAPTOITERABLE_PROVIDERS} from './MapToIterable'; 4 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 5 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 6 | 7 | @Component({ 8 | template: ` 9 |
10 |
11 |
12 |

MapToIterable

13 |

MapToIterable is a custom pipe to make a custom object iterable over its keys

14 |
15 |
16 |
17 | 18 |
19 |
    20 |
  • 21 | {{keyValuePair.key}}: {{keyValuePair.val}} 22 |
  • 23 |
24 |
25 | 26 |

Reasoning

27 |
28 |

According to Miško Hevery (reference):

29 | 30 |
31 |

Maps have no orders in keys and hence they iteration is unpredictable. This was supported in ng1, but we think it was a mistake and will not be supported in NG2

32 | 33 |

The plan is to have a mapToIterable pipe

34 | 35 | *ngFor"#item of map | mapToIterable" 36 |
37 |
38 | 39 |
40 |

Import

41 |
 42 | 
 43 | import {MapToIterablePipe} from 'fuel-ui/fuel-ui';
 44 | 
 45 | 
46 | 47 |

Getting Started

48 |

MapToIterable pipe is used to make custom objects that have no orders iterable by their keys 49 |

50 | 51 |

Usage

52 | 53 | 54 |
 55 | 
 56 | <ul *ngFor="#object of data">
 57 |     <li *ngFor="#keyValuePair of object | mapToIterable">
 58 |         {
{
keyValuePair.key}}: {
{
keyValuePair.val}} 59 | </li> 60 | </ul> 61 |
62 |
63 |
64 | 65 |
 66 | 
 67 | export class MapToIterableExample {
 68 |     data: any[] = [
 69 |         {
 70 |             Any: "foo",
 71 |             Keys: "foo",
 72 |             At: "foo",
 73 |             All: "foo"
 74 |         },
 75 |         {
 76 |             Any: "bar",
 77 |             Keys: "bar",
 78 |             At: "bar",
 79 |             All: "bar"
 80 |         }
 81 |     ]
 82 | }
 83 | 
 84 | 
85 |
86 |
87 | 88 |
`, 89 | directives: [CORE_DIRECTIVES, CodeHighlighter, TAB_PROVIDERS], 90 | pipes: [MAPTOITERABLE_PROVIDERS] 91 | }) 92 | export class MapToIterableDemo { 93 | data: any[] = [ 94 | { 95 | Any: "foo", 96 | Keys: "foo", 97 | At: "foo", 98 | All: "foo" 99 | }, 100 | { 101 | Any: "bar", 102 | Keys: "bar", 103 | At: "bar", 104 | All: "bar" 105 | } 106 | ] 107 | } 108 | 109 | export var MAPTOITERABLE_DEMO_PROVIDERS = [ 110 | MapToIterableDemo 111 | ]; -------------------------------------------------------------------------------- /src/components/DatePicker/DateRangePicker.html: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 | 8 | 9 |
11 |
12 |
13 | 17 |
18 | 23 | - 24 | 29 |
30 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
SMTWTFS
47 |
48 |
49 | 55 | 66 | {{i}} 67 | 68 | 69 |
70 |
71 |
72 | 73 |
-------------------------------------------------------------------------------- /src/components/OffCanvasMenu/OffCanvasMenu.ts: -------------------------------------------------------------------------------- 1 | import {Component, Directive, Input, Output, QueryList, ContentChildren} from "@angular/core"; 2 | import {HostListener, EventEmitter} from "@angular/core"; 3 | import {OnInit, OnDestroy, AfterContentInit} from "@angular/core"; 4 | import {trigger, state, style, transition, animate, keyframes} from '@angular/core'; 5 | import {CORE_DIRECTIVES} from "@angular/common"; 6 | 7 | @Directive({ 8 | selector: "[offCanvasMenuClose], .off-canvas-menu-close" 9 | }) 10 | export class OffCanvasMenuClose { 11 | @Output() 12 | close = new EventEmitter(); 13 | 14 | @HostListener("click", ["$event"]) 15 | onClick(e: any): void { 16 | this.close.next(null); 17 | } 18 | } 19 | 20 | @Component({ 21 | selector: "off-canvas-menu", 22 | templateUrl: "components/OffCanvasMenu/OffCanvasMenu.html", 23 | styleUrls: ["components/OffCanvasMenu/OffCanvasMenu.css"], 24 | directives: [CORE_DIRECTIVES, OffCanvasMenuClose], 25 | animations: [ 26 | trigger("open", [ 27 | state("open", style({transform: "translate(0,0)"})), 28 | transition("void => open", [animate("200ms ease")]), 29 | transition("open => void", [animate("200ms ease")]) 30 | ]), 31 | trigger("fade", [ 32 | state("in", style({opacity: ".75"})), 33 | transition("void => in", [animate("200ms ease")]), 34 | transition("in => void", [animate("200ms ease")]) 35 | ]) 36 | ] 37 | }) 38 | export class OffCanvasMenu implements OnInit, OnDestroy, AfterContentInit { 39 | @Input() 40 | origin: "left" | "top" | "right" | "bottom" = "left"; 41 | 42 | @Input() 43 | width = "25%"; 44 | 45 | @Input() 46 | height = "25%"; 47 | 48 | @Output() 49 | close:EventEmitter = new EventEmitter(); 50 | @Output() 51 | open:EventEmitter = new EventEmitter(); 52 | 53 | computedWidth = this.width; 54 | computedHeight = this.height; 55 | 56 | @ContentChildren(OffCanvasMenuClose) 57 | closeButtons: QueryList; 58 | 59 | isOpen = false; 60 | 61 | overlayState: "in" = null; 62 | openState: "open" = null; 63 | 64 | constructor() { 65 | 66 | } 67 | 68 | ngOnInit(): void { 69 | 70 | } 71 | 72 | ngAfterContentInit(): void { 73 | this.closeButtons.map(b => b.close.subscribe(() => this.toggleMenu())); 74 | } 75 | 76 | ngOnDestroy(): void { 77 | 78 | } 79 | 80 | toggleMenu(): void { 81 | this.isOpen = !this.isOpen; 82 | 83 | if(this.isOpen) { 84 | this.overlayState = "in"; 85 | this.openState = "open"; 86 | this.open.next(null); 87 | } else { 88 | this.overlayState = null; 89 | this.openState = null; 90 | this.close.next(null); 91 | } 92 | 93 | if(this.origin == "left" || this.origin == "right") { 94 | this.computedHeight = "100%"; 95 | this.computedWidth = this.width; 96 | } 97 | else if(this.origin == "top" || this.origin == "bottom") { 98 | this.computedWidth = "100%"; 99 | this.computedHeight = this.height; 100 | } 101 | } 102 | } 103 | 104 | export let OFF_CANVAS_MENU_PROVIDERS = [ 105 | OffCanvasMenu, 106 | OffCanvasMenuClose 107 | ] 108 | -------------------------------------------------------------------------------- /src/animations/Collapse/Collapse.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component, trigger, state, style, transition, animate, group, keyframes} from '@angular/core'; 2 | import {Collapse} from './Collapse'; 3 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 4 | import {TableSortable, TableSortableColumn, TableSortableSorting} from '../../components/TableSortable/TableSortable'; 5 | import {Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 6 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 7 | 8 | @Component({ 9 | template: ` 10 |
11 |
12 |
13 |

Collapse

14 |

Collapse is a custom animation to display and hide content

15 |
16 |
17 |
18 | 19 | 20 | 28 |
29 |

All of your content

30 |
    31 |
  • That you wish
  • 32 |
  • to be able
  • 33 |
  • to collapse
  • 34 |
35 |

At any time!

36 |
37 | 38 |
39 |

Import

40 |
 41 | 
 42 | import {Collapse} from 'fuel-ui/fuel-ui';
 43 | 
 44 | @Component({
 45 |     animations: [Collapse(300)]
 46 | })
 47 | 
 48 | 
49 | 50 |

Getting Started

51 |

Collapse allows you to toggle content on the page with a nice sliding animation. Import the Collapse function from 'fuel-ui/fuel-ui', and add the function to your animations array of any component. You can optionally add a duration number as a parameter.

52 | 53 |

Usage

54 | 55 | 56 |
 57 | 
 58 | <div @collapse="collapsed ? 'true' : 'false'">
 59 |     <h2>All of your content</h2>
 60 |     <ul>
 61 |         <li>That you wish</li>
 62 |         <li>to be able</li>
 63 |         <li>to collapse</li>
 64 |     </ul>
 65 |     <p>At any time!</p>
 66 | </div>
 67 | 
 68 | 
69 |
70 | 71 |
 72 | 
 73 | export class CollapseExample { 
 74 |     collapsed: boolean = false;
 75 | }
 76 | 
 77 | 
78 |
79 |
80 | 81 |

Parameters

82 | 86 | Loading table... 87 | 88 | 89 |
`, 90 | animations: [ 91 | Collapse(300) 92 | ], 93 | directives: [CodeHighlighter, TableSortable, TAB_PROVIDERS] 94 | }) 95 | export class CollapseDemo { 96 | collapsed: boolean = false; 97 | 98 | attributes:any[] = [ 99 | new Attribute('duration', 'number', '300', 'Number of milliseconds for how long the open/close animation takes') 100 | ]; 101 | attributesColumns:TableSortableColumn[] = AttributeColumns; 102 | attributesSort:TableSortableSorting = AttributesDefaultSort; 103 | } 104 | 105 | export var COLLAPSE_DEMO_PROVIDERS = [ 106 | CollapseDemo 107 | ]; -------------------------------------------------------------------------------- /src/directives/Tooltip/Tooltip.ts: -------------------------------------------------------------------------------- 1 | import {Directive, ElementRef, Input, Output, EventEmitter, ViewContainerRef, OnInit, OnChanges} from '@angular/core'; 2 | import {CORE_DIRECTIVES} from '@angular/common'; 3 | 4 | @Directive({ 5 | selector: '[tooltip]', 6 | properties: [ 7 | 'text: tooltip', 8 | 'position: position', 9 | 'color: color', 10 | 'size: size', 11 | 'rounded: rounded', 12 | 'always: always' 13 | ], 14 | host: { 15 | '(mouseover)': 'show()', 16 | '(mouseout)': 'hide()', 17 | '(focus)': 'show()', 18 | '(unfocus)': 'hide()' 19 | } 20 | }) 21 | export class Tooltip implements OnInit, OnChanges{ 22 | text:string = ''; 23 | position:string = 'top'; 24 | color:string = 'none'; 25 | size:string = 'auto'; 26 | rounded:boolean = false; 27 | always:boolean = false; 28 | private _el:HTMLElement; 29 | 30 | constructor(el: ElementRef) { 31 | this._el = el.nativeElement; 32 | } 33 | 34 | ngOnInit() { 35 | if(this.always){ 36 | this._el.classList.add("hint--always"); 37 | this.show(); 38 | } 39 | } 40 | 41 | ngOnChanges() { 42 | for (var i = 0; i < this._el.classList.length; i++) { 43 | var currentClass = this._el.classList[i]; 44 | if(currentClass.startsWith("hint--")) 45 | this._el.classList.remove(currentClass) 46 | } 47 | 48 | if(this.always){ 49 | this._el.classList.add("hint--always"); 50 | this.show(); 51 | } 52 | } 53 | 54 | show() { 55 | if(!this.text || this.text.length == 0) return; 56 | 57 | this.hide(); 58 | 59 | this._el.setAttribute("data-hint", this.text); 60 | 61 | for (var i = 0; i < this._el.classList.length; i++) { 62 | var currentClass = this._el.classList[i]; 63 | if(currentClass.startsWith("hint")) 64 | this._el.classList.remove(currentClass) 65 | } 66 | 67 | if(this.always){ 68 | this._el.classList.add("hint--always"); 69 | } 70 | 71 | this._el.classList.add("hint--" + this.position); 72 | 73 | switch(this.color) { 74 | case "error": 75 | this._el.classList.add("hint--error"); 76 | break; 77 | case "warning": 78 | this._el.classList.add("hint--warning"); 79 | break; 80 | case "info": 81 | this._el.classList.add("hint--info"); 82 | break; 83 | case "success": 84 | this._el.classList.add("hint--success"); 85 | break; 86 | default: 87 | 88 | } 89 | 90 | switch(this.size) { 91 | case "small": 92 | this._el.classList.add("hint--small"); 93 | break; 94 | case "medium": 95 | this._el.classList.add("hint--medium"); 96 | break; 97 | case "large": 98 | this._el.classList.add("hint--large"); 99 | break; 100 | default: 101 | } 102 | 103 | if(this.rounded) 104 | this._el.classList.add("hint--rounded"); 105 | } 106 | 107 | hide() { 108 | if(this.always) return; 109 | 110 | this._el.removeAttribute("data-hint"); 111 | } 112 | } 113 | 114 | export var TOOLTIP_PROVIDERS = [ 115 | Tooltip 116 | ]; -------------------------------------------------------------------------------- /src/styles/slider.scss: -------------------------------------------------------------------------------- 1 | 2 | /* Functional styling; 3 | * These styles are required for noUiSlider to function. 4 | * You don't need to change these rules to apply your design. 5 | */ 6 | .noUi-target, 7 | .noUi-target * { 8 | -webkit-touch-callout: none; 9 | -webkit-user-select: none; 10 | -ms-touch-action: none; 11 | touch-action: none; 12 | -ms-user-select: none; 13 | -moz-user-select: none; 14 | user-select: none; 15 | -moz-box-sizing: border-box; 16 | box-sizing: border-box; 17 | } 18 | .noUi-target { 19 | position: relative; 20 | direction: ltr; 21 | } 22 | .noUi-base { 23 | width: 100%; 24 | height: 100%; 25 | position: relative; 26 | z-index: 1; /* Fix 401 */ 27 | } 28 | .noUi-origin { 29 | position: absolute; 30 | right: 0; 31 | top: 0; 32 | left: 0; 33 | bottom: 0; 34 | } 35 | .noUi-handle { 36 | position: relative; 37 | z-index: 1; 38 | } 39 | .noUi-stacking .noUi-handle { 40 | /* This class is applied to the lower origin when 41 | its values is > 50%. */ 42 | z-index: 10; 43 | } 44 | .noUi-state-tap .noUi-origin { 45 | -webkit-transition: left 0.3s, top 0.3s; 46 | transition: left 0.3s, top 0.3s; 47 | } 48 | .noUi-state-drag * { 49 | cursor: inherit !important; 50 | } 51 | 52 | /* Painting and performance; 53 | * Browsers can paint handles in their own layer. 54 | */ 55 | .noUi-base, 56 | .noUi-handle { 57 | -webkit-transform: translate3d(0,0,0); 58 | transform: translate3d(0,0,0); 59 | } 60 | 61 | /* Slider size and handle placement; 62 | */ 63 | .noUi-horizontal { 64 | height: 18px; 65 | } 66 | .noUi-horizontal .noUi-handle { 67 | width: 34px; 68 | height: 28px; 69 | left: -17px; 70 | top: -6px; 71 | } 72 | .noUi-vertical { 73 | width: 18px; 74 | } 75 | .noUi-vertical .noUi-handle { 76 | width: 28px; 77 | height: 34px; 78 | left: -6px; 79 | top: -17px; 80 | } 81 | 82 | /* Styling; 83 | */ 84 | .noUi-background { 85 | background: #FAFAFA; 86 | box-shadow: inset 0 1px 1px #f0f0f0; 87 | } 88 | .noUi-connect { 89 | background: #3FB8AF; 90 | box-shadow: inset 0 0 3px rgba(51,51,51,0.45); 91 | -webkit-transition: background 450ms; 92 | transition: background 450ms; 93 | } 94 | .noUi-origin { 95 | border-radius: 2px; 96 | } 97 | .noUi-target { 98 | border-radius: 4px; 99 | border: 1px solid #D3D3D3; 100 | box-shadow: inset 0 1px 1px #F0F0F0, 0 3px 6px -5px #BBB; 101 | } 102 | .noUi-target.noUi-connect { 103 | box-shadow: inset 0 0 3px rgba(51,51,51,0.45), 0 3px 6px -5px #BBB; 104 | } 105 | 106 | /* Handles and cursors; 107 | */ 108 | .noUi-draggable { 109 | cursor: w-resize; 110 | } 111 | .noUi-vertical .noUi-draggable { 112 | cursor: n-resize; 113 | } 114 | .noUi-handle { 115 | border: 1px solid #D9D9D9; 116 | border-radius: 3px; 117 | background: #FFF; 118 | cursor: default; 119 | box-shadow: inset 0 0 1px #FFF, 120 | inset 0 1px 7px #EBEBEB, 121 | 0 3px 6px -3px #BBB; 122 | } 123 | .noUi-active { 124 | box-shadow: inset 0 0 1px #FFF, 125 | inset 0 1px 7px #DDD, 126 | 0 3px 6px -3px #BBB; 127 | } 128 | 129 | /* Handle stripes; 130 | */ 131 | .noUi-handle:before, 132 | .noUi-handle:after { 133 | content: ""; 134 | display: block; 135 | position: absolute; 136 | height: 14px; 137 | width: 1px; 138 | background: #E8E7E6; 139 | left: 14px; 140 | top: 6px; 141 | } 142 | .noUi-handle:after { 143 | left: 17px; 144 | } 145 | .noUi-vertical .noUi-handle:before, 146 | .noUi-vertical .noUi-handle:after { 147 | width: 14px; 148 | height: 1px; 149 | left: 6px; 150 | top: 14px; 151 | } 152 | .noUi-vertical .noUi-handle:after { 153 | top: 17px; 154 | } 155 | 156 | /* Disabled state; 157 | */ 158 | [disabled].noUi-connect, 159 | [disabled] .noUi-connect { 160 | background: #B8B8B8; 161 | } 162 | [disabled].noUi-origin, 163 | [disabled] .noUi-handle { 164 | cursor: not-allowed; 165 | } -------------------------------------------------------------------------------- /src/components/TimePicker/TimePicker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 32 | 33 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 51 | 52 | 57 | 58 | 59 | 60 | 61 |
5 | 6 | 7 | 8 |   11 | 12 | 13 | 14 |   17 | 18 | 19 | 20 |   
26 | 27 | : 30 | 31 | : 34 | 35 |  
41 | 42 | 43 | 44 |   47 | 48 | 49 | 50 |   53 | 54 | 55 | 56 |   
-------------------------------------------------------------------------------- /src/pipes/Range/Range.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {CORE_DIRECTIVES} from '@angular/common'; 3 | import {RANGE_PROVIDERS} from './Range'; 4 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 5 | import {TableSortable, TableSortableColumn, TableSortableSorting} from '../../components/TableSortable/TableSortable'; 6 | import {Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 7 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 8 | 9 | @Component({ 10 | template: ` 11 |
12 |
13 |
14 |

Range

15 |

Range is a custom pipe to dynamically create an array of numbers based on a given range

16 |
17 |
18 |
19 | 20 |

21 | *ngFor="let number of numbers | range : {{startNumber}} : {{endNumber}} : {{stepNumber}}"
22 |

23 | 24 |

Output: {{number | range : startNumber : endNumber : stepNumber | json}}

25 | 26 |
27 | 28 |
29 | 30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 | 40 |
41 | 42 |
43 |
44 | 45 |
46 |

Import

47 |
 48 | 
 49 | import {RangePipe} from 'fuel-ui/fuel-ui';
 50 | 
 51 | 
52 | 53 |

Getting Started

54 |

Range is a pipe that simply takes in 3 arguments, a start number, end number, and step number.

55 | 56 |

Usage

57 | 58 | 59 |
 60 | 
 61 | *ngFor="let number of numbers | range : start : end : step"
 62 | 
 63 | 
64 |
65 | 66 |
 67 | 
 68 | export class RangeExample {
 69 |     numbers:number[] = [];
 70 |     start:number = 0;
 71 |     end:number = 5;
 72 |     step:number = 1;
 73 | }
 74 | 
 75 | 
76 |
77 |
78 | 79 |

Parameters

80 | 84 | Loading table... 85 | 86 | 87 |
`, 88 | directives: [CORE_DIRECTIVES, CodeHighlighter, TableSortable, TAB_PROVIDERS], 89 | pipes: [RANGE_PROVIDERS] 90 | }) 91 | export class RangeDemo { 92 | numbers:number[] = []; 93 | startNumber:number = 0; 94 | endNumber:number = 5; 95 | stepNumber:number = 1; 96 | 97 | parameters:Attribute[] = [ 98 | new Attribute('start', 'number', '0', 'The starting number of the array'), 99 | new Attribute('end', 'number', '4', 'The largest possible number of the array'), 100 | new Attribute('step', 'number', '1', 'The amount of step between each number within the array') 101 | ]; 102 | parametersColumns:TableSortableColumn[] = AttributeColumns; 103 | parametersSort:TableSortableSorting = AttributesDefaultSort; 104 | } 105 | 106 | export var RANGE_DEMO_PROVIDERS = [ 107 | RangeDemo 108 | ]; -------------------------------------------------------------------------------- /src/components/DatePicker/DatePicker.scss: -------------------------------------------------------------------------------- 1 | @import "../../styles/variables"; 2 | @import "../../styles/bourbon"; 3 | @import "../../styles/media_queries"; 4 | 5 | .date-picker-overlay { 6 | background-color: rgba(0,0,0,0); 7 | display: block; 8 | position: fixed; 9 | top: 0; 10 | right: 0; 11 | bottom: 0; 12 | left: 0; 13 | z-index: 900; 14 | 15 | @include mobile-only { 16 | background-color: $gray; 17 | opacity: .75; 18 | } 19 | } 20 | 21 | .date-picker-content { 22 | position: relative; 23 | top: 0; 24 | left: 0; 25 | } 26 | 27 | .fuel-ui-datepicker-input-group { 28 | input:read-only, .form-control[readonly] { 29 | background-color: $input-bg !important; 30 | } 31 | 32 | .input-group-addon { 33 | background-color: $input-bg !important; 34 | } 35 | } 36 | 37 | .date-picker-component { 38 | border: 1px solid $table-border-color; 39 | z-index: 1000; 40 | background-color: $body-bg; 41 | font-size: .75rem; 42 | position: absolute; 43 | width: 350px; 44 | height: auto; 45 | top: 0; 46 | left: 0; 47 | overflow: hidden; 48 | @if $enable-rounded { 49 | border-radius: $border-radius-lg; 50 | } 51 | 52 | @include transition(all .1s ease); 53 | 54 | @include mobile-only { 55 | width: 90%; 56 | height: 90%; 57 | position: fixed; 58 | top: 5%; 59 | left: 5%; 60 | } 61 | 62 | .input-group { 63 | z-index: 110; 64 | } 65 | 66 | .container { 67 | height: 100%; 68 | 69 | .calendar-container { 70 | @include mobile-only { 71 | height: 91%; 72 | } 73 | } 74 | 75 | header { 76 | position: relative; 77 | top: 0; 78 | left: 0; 79 | vertical-align: middle; 80 | background-color: $input-bg; 81 | 82 | .days-of-week { 83 | background-color: $brand-primary; 84 | color: $btn-primary-color; 85 | } 86 | 87 | table{ 88 | border-top: none !important; 89 | 90 | th, td { 91 | text-align: center; 92 | } 93 | } 94 | 95 | button { 96 | border: none; 97 | border-radius: 0; 98 | color: $brand-primary; 99 | background-color: $input-bg; 100 | width: 15%; 101 | 102 | &:active { 103 | background-color: $input-bg-disabled; 104 | } 105 | 106 | &.button-disable { 107 | color: $input-bg-disabled; 108 | cursor: default; 109 | } 110 | } 111 | 112 | .date-range { 113 | width: 70%; 114 | 115 | span { 116 | background-color: $gray-lighter; 117 | border-left: none; 118 | border-right: none; 119 | } 120 | } 121 | 122 | .input-group-addon { 123 | border: none; 124 | background-color: $input-bg !important; 125 | } 126 | 127 | input { 128 | border: none; 129 | display: inline-block; 130 | margin: 1px auto 0 auto; 131 | cursor: pointer; 132 | background-color: $input-bg !important; 133 | } 134 | 135 | input:read-only, .form-control[readonly] { 136 | background-color: $body-bg !important; 137 | } 138 | 139 | input.target { 140 | color: $brand-primary; 141 | @include placeholder { 142 | color: $brand-primary; 143 | } 144 | } 145 | } 146 | } 147 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ####################################################################### 2 | # 3 | # Git Ignore File 4 | # 5 | # from www.gitignore.io modified for use for Fuel / Guestdesk 6 | # 7 | ####################################################################### 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | !Guestdesk.Core/Debug/ 12 | [Dd]ebugPublic/ 13 | [Rr]elease/ 14 | [Rr]eleases/ 15 | [Rr]eleaseDLL/ 16 | [Dd]ebugDLL/ 17 | x64/ 18 | x86/ 19 | build/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Tt]mp/ 24 | 25 | 26 | # Excluded File Filters 27 | 28 | *.tmp 29 | *.bak 30 | *.swp 31 | *~* 32 | *.launch 33 | *.suo 34 | *.user 35 | *.sln.docstates 36 | *_i.c 37 | *_p.c 38 | *.ilk 39 | *.meta 40 | *.obj 41 | *.pch 42 | *.pdb 43 | *.pgc 44 | *.pgd 45 | *.rsp 46 | *.sbr 47 | *.tlb 48 | *.tli 49 | *.tlh 50 | *.vspscc 51 | *.vssscc 52 | *.scc 53 | *.aps 54 | *.ncb 55 | *.opensdf 56 | *.sdf 57 | *.ipch 58 | *.cvsignore 59 | *.log 60 | *.svclog 61 | _ReSharper* 62 | UpgradeLog*.XML 63 | UpgradeLog*.htm 64 | 65 | # Chutzpah Test files 66 | _Chutzpah* 67 | 68 | # Visual Studio 2015 cache/options directory 69 | .vs/ 70 | 71 | # Visual C++ cache files 72 | ipch/ 73 | *.aps 74 | *.ncb 75 | *.opensdf 76 | *.sdf 77 | *.cachefile 78 | 79 | # Visual Studio profiler 80 | *.psess 81 | *.vsp 82 | *.vspx 83 | 84 | # TFS 2012 Local Workspace 85 | $tf/ 86 | 87 | # Guidance Automation Toolkit 88 | *.gpState 89 | 90 | # ReSharper is a .NET coding add-in 91 | _ReSharper*/ 92 | *.[Rr]e[Ss]harper 93 | *.DotSettings.user 94 | 95 | # JustCode is a .NET coding addin-in 96 | .JustCode 97 | 98 | # TeamCity is a build add-in 99 | _TeamCity* 100 | 101 | # DotCover is a Code Coverage Tool 102 | *.dotCover 103 | 104 | # NCrunch 105 | _NCrunch_* 106 | .*crunch*.local.xml 107 | 108 | # MightyMoose 109 | *.mm.* 110 | AutoTest.Net/ 111 | 112 | # Web workbench (sass) 113 | .sass-cache/ 114 | 115 | # Installshield output folder 116 | [Ee]xpress/ 117 | 118 | # DocProject is a documentation generator add-in 119 | DocProject/buildhelp/ 120 | DocProject/Help/*.HxT 121 | DocProject/Help/*.HxC 122 | DocProject/Help/*.hhc 123 | DocProject/Help/*.hhk 124 | DocProject/Help/*.hhp 125 | DocProject/Help/Html2 126 | DocProject/Help/html 127 | 128 | # Click-Once directory 129 | publish/ 130 | 131 | # Publish Web Output 132 | *.[Pp]ublish.xml 133 | *.azurePubxml 134 | # TODO: Comment the next line if you want to checkin your web deploy settings 135 | # but database connection strings (with potential passwords) will be unencrypted 136 | *.pubxml 137 | *.publishproj 138 | 139 | # NuGet Packages 140 | *.nupkg 141 | # The packages folder can be ignored because of Package Restore 142 | **/packages/* 143 | # except build/, which is used as an MSBuild target. 144 | !**/packages/build/ 145 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 146 | #!**/packages/repositories.config 147 | !Guestdesk.Core/Packages/* 148 | 149 | # Windows Azure Build Output 150 | csx/ 151 | *.build.csdef 152 | 153 | # Windows Store app package directory 154 | AppPackages/ 155 | 156 | # Others 157 | sql/ 158 | *.Cache 159 | ClientBin/ 160 | [Ss]tyle[Cc]op.* 161 | ~$* 162 | *~ 163 | *.dbmdl 164 | *.dbproj.schemaview 165 | *.pfx 166 | *.publishsettings 167 | node_modules/ 168 | **/jspm_packages/ 169 | jspm_packages/ 170 | CVS/ 171 | bower_components/ 172 | ipch/ 173 | _UpgradeReport_Files/ 174 | .settings/ 175 | **/wwwroot/lib/ 176 | dist/ 177 | .idea/ 178 | .vscode/ 179 | 180 | # RIA/Silverlight projects 181 | Generated_Code/ 182 | 183 | # Backup & report files from converting an old project file 184 | # to a newer Visual Studio version. Backup files are not needed, 185 | # because we have git ;-) 186 | _UpgradeReport_Files/ 187 | Backup*/ 188 | UpgradeLog*.XML 189 | UpgradeLog*.htm 190 | 191 | # SQL Server files 192 | *.mdf 193 | *.ldf 194 | 195 | # Business Intelligence projects 196 | *.rdl.data 197 | *.bim.layout 198 | *.bim_*.settings 199 | 200 | # Diagnostics Tracelog 201 | TraceLog.svclog 202 | 203 | # Microsoft Fakes 204 | FakesAssemblies/ 205 | 206 | # Excluded Files 207 | 208 | Thumbs.db 209 | Desktop.ini 210 | .project 211 | .metadata 212 | local.properties 213 | .classpath 214 | .loadpath 215 | .buildpath 216 | .DS_Store 217 | project.lock.json 218 | /FuelUi/src 219 | -------------------------------------------------------------------------------- /src/components/Carousel/Carousel.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {CAROUSEL_PROVIDERS} from './Carousel'; 3 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 4 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 5 | import {TableSortable, TableSortableColumn, TableSortableSorting} from '../../components/TableSortable/TableSortable'; 6 | import {Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 7 | 8 | @Component({ 9 | template: ` 10 |
11 |
12 |
13 |

Carousel

14 |

Carousel is a custom component to display content in a rotating manner

15 |
16 |
17 |
18 | 19 |
20 | 21 | 24 | 25 | 26 | 27 | 34 | 35 |
36 | 37 |
38 |

Import

39 |
 40 | 
 41 | import {CAROUSEL_PROVIDERS} from 'fuel-ui/fuel-ui';
 42 | 
 43 | 
44 | 45 |

Getting Started

46 |

Carousel is a custom element to display a slideshow of cycling elements

47 |

Swipe left and swipe right events are supported if hammerjs has been included.

48 | 49 |

Usage

50 | 51 | 52 |
 53 | 
 54 | <carousel>
 55 |     <div class="carousel-item">
 56 |         <img src="image1.jpg" class="carousel-item" />
 57 |     </div>
 58 |     <div class="carousel-item">
 59 |         <img src="image2.jpg" class="carousel-item" />
 60 |     </div>
 61 |     <div class="carousel-item">
 62 |         <img src="image3.jpg" class="carousel-item" />
 63 |     </div>
 64 | </carousel>
 65 | 
 66 | 
67 |
68 | 69 |
 70 | 
 71 | <carousel>
 72 |     <div class="carousel-item">
 73 |         <img src="image1.jpg" />
 74 |         <div class="carousel-caption">
 75 |             <h3>Some Title 1</h3>
 76 |             <p>Some caption 1</p>
 77 |         </div>
 78 |     </div>
 79 |     <div class="carousel-item">
 80 |         <img src="image2.jpg" />
 81 |         <div class="carousel-caption">
 82 |             <h3>Some Title 2</h3>
 83 |             <p>Some caption 2</p>
 84 |         </div>
 85 |     </div>
 86 | </carousel>
 87 | 
 88 | 
89 |
90 |
91 | 92 |

Attributes

93 | 97 | Loading table... 98 | 99 |
`, 100 | directives: [CAROUSEL_PROVIDERS, CodeHighlighter, TAB_PROVIDERS, TableSortable] 101 | }) 102 | export class CarouselDemo { 103 | carouselImages: string[] = [ 104 | "images/carouselImages/beach.png", 105 | "images/carouselImages/river.jpg", 106 | "images/carouselImages/windmill.jpg" 107 | ]; 108 | 109 | attributes:any[] = [ 110 | new Attribute('interval', 'number', '0', 'Time in ms before auto-advancing slide. If set to 0 slides will not auto-advance') 111 | ]; 112 | 113 | attributesColumns:TableSortableColumn[] = AttributeColumns; 114 | attributesSort:TableSortableSorting = AttributesDefaultSort; 115 | } 116 | 117 | export var CAROUSEL_DEMO_PROVIDERS = [ 118 | CarouselDemo 119 | ]; -------------------------------------------------------------------------------- /src/components/Alert/Alert.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {ALERT_PROVIDERS} from './Alert'; 3 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 4 | import {TableSortable, TableSortableColumn, TableSortableSorting} from '../../components/TableSortable/TableSortable'; 5 | import {Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 6 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 7 | 8 | @Component({ 9 | template: ` 10 |
11 |
12 |
13 |

Alert

14 |

Alert is a custom component to display informational messages

15 |
16 |
17 |
18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |

Import

31 |
 32 | 
 33 | import {Alert} from 'fuel-ui/fuel-ui';
 34 | 
 35 | 
36 | 37 |

Getting Started

38 |

Alert is a custom element to programmatically display feedback messages typically for user actions

39 | 40 |

Usage

41 | 42 | 43 |
 44 | 
 45 | <alert [(displayed)]="showAlert" type="success" [closeButton]="false">
 46 |     <strong>Success!</strong> Your alert is showing!
 47 | </alert>
 48 | 
 49 | 
50 |
51 | 52 |
 53 | 
 54 | export class AlertExample {
 55 |     showAlert: boolean = false;
 56 | }
 57 | 
 58 | 
59 |
60 |
61 | 62 |

Attributes

63 | 67 | Loading table... 68 | 69 | 70 |
`, 71 | directives: [ALERT_PROVIDERS, CodeHighlighter, TableSortable, TAB_PROVIDERS] 72 | }) 73 | export class AlertDemo { 74 | showAlert: boolean = false; 75 | closeDelay: number = 0; 76 | alertType: string = "success"; 77 | alertBody: string = "Some alert success message or something"; 78 | 79 | showSuccess(): void { 80 | this.closeDelay = 0; 81 | this.alertType = "success"; 82 | this.alertBody = "Some alert success message or something"; 83 | this.showAlert = true; 84 | } 85 | 86 | showError(): void { 87 | this.closeDelay = 0; 88 | this.alertType = "danger"; 89 | this.alertBody = "Something went wrong error message or something"; 90 | this.showAlert = true; 91 | } 92 | 93 | showDelay(): void { 94 | this.closeDelay = 5000; 95 | this.alertType = "info"; 96 | this.alertBody = "Nice! This will close in 5 seconds..."; 97 | this.showAlert = true; 98 | } 99 | 100 | test(): void{ 101 | console.log("changed"); 102 | } 103 | 104 | attributes:any[] = [ 105 | new Attribute('displayed', 'boolean', 'false', 'Two-way binding to display the alert'), 106 | new Attribute('closeButton', 'boolean', 'true', "Option to display the 'X' in the right hand corner to close the alert"), 107 | new Attribute('closeDelay', 'number', '0', 'Number in milliseconds until the alert automatically closes. When set to 0, the alert will stay open until manually closed'), 108 | new Attribute('type', 'string', 'success', 'The type of alert to display. Default types include success, info, warning, and danger. More info here...'), 109 | ]; 110 | attributesColumns:TableSortableColumn[] = AttributeColumns; 111 | attributesSort:TableSortableSorting = AttributesDefaultSort; 112 | } 113 | 114 | export var ALERT_DEMO_PROVIDERS = [ 115 | AlertDemo 116 | ]; -------------------------------------------------------------------------------- /src/styles/_media_queries.scss: -------------------------------------------------------------------------------- 1 | // Media Queries in Sass 3.2 2 | // 3 | // These mixins make media queries a breeze with Sass. 4 | // The media queries from mobile up until desktop all 5 | // trigger at different points along the way 6 | // 7 | // And important point to remember is that and width 8 | // over the portrait width is considered to be part of the 9 | // landscape width. This allows us to capture widths of devices 10 | // that might not fit the dimensions exactly. This means the break 11 | // points are seamless. 12 | 13 | $mq-mobile-portrait : 320px !default; 14 | $mq-mobile-landscape : 480px !default; 15 | $mq-tablet-portrait : 768px !default; 16 | $mq-tablet-landscape : 1024px !default; 17 | $mq-desktop : 1382px !default; 18 | 19 | // Both portrait and landscape 20 | @mixin mobile-only { 21 | @media (max-width : $mq-mobile-landscape), screen and (max-device-width : $mq-mobile-landscape) { 22 | @content; 23 | } 24 | } 25 | 26 | // Everything up to and including the portrait width of the phone 27 | // Since it's the smallest query it doesn't need a min 28 | @mixin mobile-portrait-only { 29 | @media (max-width : $mq-mobile-portrait) { 30 | @content; 31 | } 32 | } 33 | 34 | // Everything up to and including the mobile portrait 35 | @mixin mobile-portrait-and-below { 36 | @media (max-width : $mq-mobile-portrait) { 37 | @content; 38 | } 39 | } 40 | 41 | // Everything above and including the mobile portrait 42 | @mixin mobile-portrait-and-up { 43 | @media (min-width : $mq-mobile-portrait) { 44 | @content; 45 | } 46 | } 47 | 48 | // Everthing larger than a portrait mobile up until mobile landscape 49 | @mixin mobile-landscape-only { 50 | @media only screen and (min-width : $mq-mobile-portrait + 1) and (max-width : $mq-mobile-landscape) { 51 | @content; 52 | } 53 | } 54 | 55 | // Everything up to and including the mobile landscape width 56 | @mixin mobile-landscape-and-below { 57 | @media only screen and (max-width : $mq-mobile-landscape) { 58 | @content; 59 | } 60 | } 61 | 62 | // Everything above and including the mobile landscape width 63 | @mixin mobile-landscape-and-up { 64 | @media only screen and (min-width : $mq-mobile-portrait + 1) { 65 | @content; 66 | } 67 | } 68 | 69 | // Both the portrait and landscape width of the tablet 70 | // Larger than a landscape mobile but less than or equal to a landscape tablet 71 | @mixin tablet-only { 72 | @media only screen and (min-width : $mq-mobile-landscape + 1) and (max-width : $mq-tablet-landscape) { 73 | @content; 74 | } 75 | } 76 | 77 | // Everything larger than mobile landscape up until the portrait width of the tablet 78 | @mixin tablet-portrait-only { 79 | @media only screen and (min-width : $mq-mobile-landscape + 1) and (max-width : $mq-tablet-portrait) { 80 | @content; 81 | } 82 | } 83 | 84 | // Everything below and including the portrait width of the tablet 85 | @mixin tablet-portrait-and-below { 86 | @media only screen and (max-width : $mq-tablet-portrait) { 87 | @content; 88 | } 89 | } 90 | 91 | // Everything above and including the portrait width of the tablet 92 | @mixin tablet-portrait-and-up { 93 | @media only screen and (min-width : $mq-mobile-landscape + 1) { 94 | @content; 95 | } 96 | } 97 | 98 | // Larger than portrait but less than or equal to the landscape width 99 | @mixin tablet-landscape-only { 100 | @media only screen and (min-width : $mq-tablet-portrait + 1) and (max-width : $mq-tablet-landscape) { 101 | @content; 102 | } 103 | } 104 | 105 | // Up to and including the tablet landscape 106 | @mixin tablet-landscape-and-below { 107 | @media only screen and (max-width : $mq-tablet-landscape) { 108 | @content; 109 | } 110 | } 111 | 112 | // Everything larger than portrait tablet 113 | @mixin tablet-landscape-and-up { 114 | @media only screen and (min-width : $mq-tablet-portrait + 1) { 115 | @content; 116 | } 117 | } 118 | 119 | // Everything larger than a landscape tablet 120 | @mixin desktop-and-up { 121 | @media only screen and (min-width : $mq-tablet-landscape + 1) { 122 | @content; 123 | } 124 | } 125 | 126 | // Everything below and including the desktop 127 | @mixin desktop-and-below { 128 | @media only screen and (max-width : $mq-desktop) { 129 | @content; 130 | } 131 | } 132 | 133 | // Everything larger than a landscape tablet but less than or equal to the desktop 134 | @mixin desktop-only { 135 | @media only screen and (min-width : $mq-tablet-landscape + 1) and (max-width : $mq-desktop) { 136 | @content; 137 | } 138 | } 139 | 140 | // Retina screens have a 1.5 pixel ratio, not 2 141 | @mixin retina { 142 | @media only screen and (-webkit-min-device-pixel-ratio : 1.5), only screen and (min-device-pixel-ratio : 1.5) { 143 | @content; 144 | } 145 | } -------------------------------------------------------------------------------- /src/directives/Animation/Animation.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Animation} from './Animation'; 3 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 4 | import {TableSortable, TableSortableColumn, TableSortableSorting} from '../../components/TableSortable/TableSortable'; 5 | import {Event, EventColumns, EventsDefaultSort, Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 6 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 7 | 8 | @Component({ 9 | template: ` 10 |
11 |
12 |
13 |

Animation Helper

14 |

Animation Helper is a directive that adds events to the element to bind to

15 |
16 |
17 |
18 | 19 |
20 |
25 | 26 |
Playing: {{play}}

27 |
28 |

Animation Log

29 |
30 | ({{event.time | date : 'mediumTime'}}) {{event.animationName}}: {{event.type}} 31 |
32 |
33 |
34 | 35 |
36 |

Import

37 |
 38 | 
 39 | import {Animation} from 'fuel-ui/fuel-ui';
 40 | 
 41 | 
42 | 43 |

Getting Started

44 |

Animation helper is a directive that adds events to bind to on elements that are animated. It gives information about the animation that is happening and an ability to start and stop the animation. Can be used to combine animations synchronously.

45 | 46 |

Usage

47 | 48 | 49 |
 50 | 
 51 | <div class="some-animation-class"
 52 |     animation="test-animation-a"
 53 |     [play]="play"
 54 |     (animationstart)="logStart($event)"
 55 |     (animationend)="logEnd($event)"></div>
 56 | <button class="btn btn-primary" (click)="start()">Play</button>
 57 | 
 58 | 
59 |
60 | 61 |
 62 | 
 63 | export class AnimationExample {
 64 |     play:boolean = false;
 65 |     animationLog:any[] = [];
 66 |     
 67 |     start(): void{
 68 |         this.play = true;
 69 |     }
 70 |     
 71 |     logStart($event: any): void {
 72 |         this.animationLog.push($event);
 73 |     }
 74 | 
 75 |     logEnd($event: any): void {
 76 |         this.play = false;
 77 |         this.animationLog.push($event);
 78 |     }
 79 | }
 80 | 
 81 | 
82 |
83 |
84 | 85 |

Attributes

86 | 90 | Loading table... 91 | 92 | 93 |

Events

94 | 98 | Loading table... 99 | 100 | 101 |
`, 102 | directives: [Animation, CodeHighlighter, TableSortable, TAB_PROVIDERS] 103 | }) 104 | export class AnimationDemo { 105 | play:boolean = false; 106 | animationLog:any[] = []; 107 | 108 | start(): void{ 109 | this.play = true; 110 | } 111 | 112 | logStart($event: any): void { 113 | $event.time = new Date().getTime(); 114 | this.animationLog.push($event); 115 | } 116 | 117 | logEnd($event: any): void { 118 | this.play = false; 119 | $event.time = new Date().getTime(); 120 | this.animationLog.push($event); 121 | } 122 | 123 | attributes:Attribute[] = [ 124 | new Attribute('play', 'boolean', 'false', 'Start the animation') 125 | ]; 126 | attributesColumns:TableSortableColumn[] = AttributeColumns; 127 | attributesSort:TableSortableSorting = AttributesDefaultSort; 128 | events:Event[] = [ 129 | new Event('animationstart', 'Animation Object', 'Information about the animation when it starts'), 130 | new Event('animationend', 'Animation Object', 'Information about the animation when it ends') 131 | ]; 132 | eventsColumns:TableSortableColumn[] = EventColumns; 133 | eventsSort:TableSortableSorting = EventsDefaultSort; 134 | } 135 | 136 | export var ANIMATION_DEMO_PROVIDERS = [ 137 | AnimationDemo 138 | ]; -------------------------------------------------------------------------------- /src/pipes/OrderBy/OrderBy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Example use 3 | * Basic Array of single type: *ngFor="let todo of todoService.todos | orderBy : '-'" 4 | * Multidimensional Array Sort on single column: *ngFor="let todo of todoService.todos | orderBy : ['-status']" 5 | * Multidimensional Array Sort on multiple columns: *ngFor="let todo of todoService.todos | orderBy : ['status', '-title']" 6 | */ 7 | 8 | import {Pipe, PipeTransform} from '@angular/core'; 9 | 10 | @Pipe({name: 'orderBy', pure: false}) 11 | export class OrderByPipe implements PipeTransform { 12 | 13 | value:string[] =[]; 14 | 15 | static _orderByComparator(a:any, b:any):number{ 16 | 17 | if(a === null || typeof a === 'undefined') a = 0; 18 | if(b === null || typeof b === 'undefined') b = 0; 19 | 20 | if((isNaN(parseFloat(a)) || !isFinite(a)) || (isNaN(parseFloat(b)) || !isFinite(b))){ 21 | //Isn't a number so lowercase the string to properly compare 22 | if(a.toLowerCase() < b.toLowerCase()) return -1; 23 | if(a.toLowerCase() > b.toLowerCase()) return 1; 24 | } 25 | else{ 26 | //Parse strings as numbers to compare properly 27 | if(parseFloat(a) < parseFloat(b)) return -1; 28 | if(parseFloat(a) > parseFloat(b)) return 1; 29 | } 30 | 31 | return 0; //equal each other 32 | } 33 | 34 | transform(input:any, config:string = '+'): any { 35 | 36 | //invalid input given 37 | if(!input) return input; 38 | 39 | //make a copy of the input's reference 40 | this.value = [...input]; 41 | let value = this.value; 42 | 43 | if(!Array.isArray(value)) return value; 44 | 45 | if(!Array.isArray(config) || (Array.isArray(config) && config.length == 1)){ 46 | let propertyToCheck:string = !Array.isArray(config) ? config : config[0]; 47 | let desc = propertyToCheck.substr(0, 1) == '-'; 48 | 49 | //Basic array 50 | if(!propertyToCheck || propertyToCheck == '-' || propertyToCheck == '+'){ 51 | return !desc ? value.sort() : value.sort().reverse(); 52 | } 53 | else { 54 | let property:string = propertyToCheck.substr(0, 1) == '+' || propertyToCheck.substr(0, 1) == '-' 55 | ? propertyToCheck.substr(1) 56 | : propertyToCheck; 57 | 58 | return value.sort(function(a:any,b:any){ 59 | let aValue = a[property]; 60 | let bValue = b[property]; 61 | 62 | let propertySplit = property.split('.'); 63 | 64 | if(typeof aValue === 'undefined' && typeof bValue === 'undefined' && propertySplit.length > 1){ 65 | aValue = a; 66 | bValue = b; 67 | for(let j = 0; j < propertySplit.length; j++) { 68 | aValue = aValue[propertySplit[j]]; 69 | bValue = bValue[propertySplit[j]]; 70 | } 71 | } 72 | 73 | return !desc 74 | ? OrderByPipe._orderByComparator(aValue, bValue) 75 | : -OrderByPipe._orderByComparator(aValue, bValue); 76 | }); 77 | } 78 | } 79 | else { 80 | //Loop over property of the array in order and sort 81 | return value.sort(function(a:any,b:any){ 82 | for(let i:number = 0; i < config.length; i++){ 83 | let desc = config[i].substr(0, 1) == '-'; 84 | let property = config[i].substr(0, 1) == '+' || config[i].substr(0, 1) == '-' 85 | ? config[i].substr(1) 86 | : config[i]; 87 | 88 | let aValue = a[property]; 89 | let bValue = b[property]; 90 | 91 | let propertySplit = property.split('.'); 92 | 93 | if(typeof aValue === 'undefined' && typeof bValue === 'undefined' && propertySplit.length > 1){ 94 | aValue = a; 95 | bValue = b; 96 | for(let j = 0; j < propertySplit.length; j++) { 97 | aValue = aValue[propertySplit[j]]; 98 | bValue = bValue[propertySplit[j]]; 99 | } 100 | } 101 | 102 | let comparison = !desc 103 | ? OrderByPipe._orderByComparator(aValue, bValue) 104 | : -OrderByPipe._orderByComparator(aValue, bValue); 105 | 106 | //Don't return 0 yet in case of needing to sort by next property 107 | if(comparison != 0) return comparison; 108 | } 109 | 110 | return 0; //equal each other 111 | }); 112 | } 113 | } 114 | } 115 | 116 | export let ORDERBY_PROVIDERS = [ 117 | OrderByPipe 118 | ]; -------------------------------------------------------------------------------- /src/components/DatePicker/DatePickerCalendar.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {Input, Output, EventEmitter, OnInit} from "@angular/core"; 3 | import {CORE_DIRECTIVES, FORM_DIRECTIVES} from "@angular/common"; 4 | import {DateUtils} from "../../utilities/utilities"; 5 | 6 | @Component({ 7 | selector: "date-picker-calendar", 8 | templateUrl: "components/DatePicker/DatePickerCalendar.html", 9 | directives: [CORE_DIRECTIVES, FORM_DIRECTIVES] 10 | }) 11 | export class DatePickerCalendar implements OnInit { 12 | weeks: string[][]; 13 | @Input() currentMonth: Date; 14 | @Input() selectedDate: Date; 15 | @Output() selectedDateChange = new EventEmitter(); 16 | 17 | @Input() dateTarget: boolean = null; 18 | @Input() startDate: Date; 19 | @Input() endDate: Date; 20 | 21 | @Input() minDate: Date; 22 | @Input() maxDate: Date; 23 | @Input() dateFilter: (d: Date) => boolean; 24 | 25 | @Input() showMonth: boolean = true; 26 | 27 | constructor() { 28 | } 29 | 30 | ngOnInit(): void { 31 | this.buildWeeks(this.currentMonth || new Date()); 32 | } 33 | 34 | checkSelectable(date: string): boolean { 35 | var dateNumber = parseInt(date); 36 | if (isNaN(dateNumber)) 37 | return false; 38 | 39 | var compareDate = 40 | new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth(), dateNumber); 41 | 42 | if (typeof this.dateFilter == "function" && !this.dateFilter(compareDate)) 43 | return false; 44 | 45 | return compareDate >= this.minDate && compareDate <= this.maxDate; 46 | } 47 | 48 | checkSelectedDate(date: string): boolean { 49 | if (this.selectedDate == null) 50 | return false; 51 | 52 | if (this.startDate != null && this.endDate != null) { 53 | let compareDate = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth(), parseInt(date)); 54 | return compareDate >= this.startDate && compareDate <= this.endDate; 55 | } 56 | 57 | return this.selectedDate.getFullYear() == this.currentMonth.getFullYear() 58 | && this.selectedDate.getMonth() == this.currentMonth.getMonth() 59 | && this.selectedDate.getDate().toString() == date; 60 | } 61 | 62 | checkStartDate(date: string): boolean { 63 | if (this.endDate == null || !DateUtils.isValidDate(this.startDate) || !DateUtils.isValidDate(this.endDate)) 64 | return false; 65 | 66 | if (this.startDate.getFullYear() == this.endDate.getFullYear() 67 | && this.startDate.getMonth() == this.endDate.getMonth() 68 | && this.startDate.getDate().toString() == this.endDate.getDate().toString()) 69 | return false; 70 | 71 | return this.startDate.getFullYear() == this.currentMonth.getFullYear() 72 | && this.startDate.getMonth() == this.currentMonth.getMonth() 73 | && this.startDate.getDate().toString() == date; 74 | } 75 | 76 | checkEndDate(date: string): boolean { 77 | if (this.endDate == null || !DateUtils.isValidDate(this.startDate) || !DateUtils.isValidDate(this.endDate)) 78 | return false; 79 | 80 | if (this.startDate.getFullYear() == this.endDate.getFullYear() 81 | && this.startDate.getMonth() == this.endDate.getMonth() 82 | && this.startDate.getDate().toString() == this.endDate.getDate().toString()) 83 | return false; 84 | 85 | return this.endDate.getFullYear() == this.currentMonth.getFullYear() 86 | && this.endDate.getMonth() == this.currentMonth.getMonth() 87 | && this.endDate.getDate().toString() == date; 88 | } 89 | 90 | selectDate(date: string): void { 91 | if (!this.checkSelectable(date)) 92 | return; 93 | 94 | var dateNumber = parseInt(date); 95 | this.selectedDate = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth(), dateNumber); 96 | this.selectedDateChange.next(this.selectedDate); 97 | } 98 | 99 | buildWeeks(date: Date): void { 100 | this.currentMonth = date; 101 | var currentDay = new Date(this.currentMonth.toDateString()); 102 | currentDay.setDate(1); 103 | currentDay.setDate(currentDay.getDate() - currentDay.getDay()); 104 | 105 | var lastDay = 106 | new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() + 1, 0); 107 | lastDay.setDate(lastDay.getDate() + (6 - lastDay.getDay())); 108 | 109 | this.weeks = []; 110 | var currentWeek: string[] = []; 111 | while (currentDay <= lastDay) { 112 | if (currentDay.getMonth() == this.currentMonth.getMonth()) 113 | currentWeek.push(currentDay.getDate().toLocaleString()); 114 | else 115 | currentWeek.push(""); 116 | 117 | currentDay.setDate(currentDay.getDate() + 1); 118 | if (currentDay.getDay() == 0) { 119 | this.weeks.push(currentWeek); 120 | currentWeek = []; 121 | } 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /src/components/Slider/Slider.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, AfterViewInit, ElementRef, Output, EventEmitter, OnChanges} from '@angular/core'; 2 | import {CORE_DIRECTIVES} from '@angular/common'; 3 | import "./NoUiSlider"; 4 | import {noUiSlider} from "nouislider"; 5 | 6 | @Component({ 7 | selector: "slider", 8 | templateUrl: 'components/Slider/Slider.html' 9 | }) 10 | 11 | export class Slider implements AfterViewInit, OnChanges { 12 | @Input() background: string = "#E24932"; 13 | @Input() height: string = ""; 14 | @Input() width: string = ""; 15 | @Input() orientation: string = "horizontal"; 16 | @Input() direction: string = "ltr"; 17 | @Input() behavior: string = "tap"; 18 | @Input() pips: number = 5; 19 | @Input() pipDensity: number = 5; 20 | @Input() step: number = 1; 21 | @Input() decimals: number = 0; 22 | @Input() minValue: number = 0; 23 | @Input() maxValue: number = 100; 24 | @Input() margin: number = 10; 25 | @Input() value: number = 0; 26 | @Input() secondValue: number = null; 27 | @Input() debounceTime: number = 150; 28 | @Output() valueChange = new EventEmitter(); 29 | @Output() secondValueChange = new EventEmitter(); 30 | private _sliderElement: any; 31 | private _slider: any; 32 | 33 | timeout: any = null; 34 | 35 | constructor(private _element: ElementRef) {} 36 | 37 | update(val: any[]): any{ 38 | this.value = parseInt(val[0]); 39 | this.secondValue = val.length > 1 ? parseInt(val[1]) : null; 40 | this.valueChange.next(this.value); 41 | this.secondValueChange.next(this.secondValue); 42 | 43 | this.timeout = null; 44 | }; 45 | 46 | ngAfterViewInit(){ 47 | this._sliderElement = this._element.nativeElement.children[0]; 48 | 49 | if(this.orientation == 'vertical') 50 | this._sliderElement.style.height = this.height.length > 0 51 | ? this.height 52 | : "200px"; 53 | 54 | if(this.orientation == 'horizontal') 55 | this._sliderElement.style.width = this.width.length > 0 56 | ? this.width 57 | : null; //full width 58 | 59 | this._slider = noUiSlider.create(this._sliderElement, { 60 | start: this.secondValue != null ? [this.value, this.secondValue] : this.value, // Handle start position 61 | step: parseInt(this.step.toString()), // Slider increment 62 | margin: this.margin, // Handles must be more than '10' apart 63 | connect: this.secondValue != null ? true : 'lower', // Display a colored bar between the handles 64 | direction: this.direction, // 'ltr': left to right, 'rtl': right to left 65 | orientation: this.orientation, // horizontal or vertical 66 | behaviour: this.behavior, // "tap" or "fixed" 67 | range: { // Slider can select min to max 68 | 'min': parseInt(this.minValue.toString()), 69 | 'max': parseInt(this.maxValue.toString()) 70 | }, 71 | pips: { // Show a scale with the slider 72 | mode: 'count', 73 | values: this.pips, 74 | density: this.pipDensity 75 | }, 76 | format: { 77 | to: ( value:string ) => { 78 | return parseFloat(value).toFixed(this.decimals) 79 | }, 80 | from: ( value:string ) => { 81 | return parseFloat(value).toFixed(this.decimals); 82 | } 83 | } 84 | }); 85 | 86 | if(!(this._element.nativeElement).disabled){ 87 | var noUI:HTMLCollection = this._element.nativeElement.getElementsByClassName('noUi-connect'); 88 | 89 | //convert HTMLCollection to array to loop 90 | [].slice.call(noUI).forEach((el:HTMLElement) => { 91 | el.style.background = this.background; 92 | }); 93 | } 94 | 95 | this._sliderElement.noUiSlider.on('slide', (val: number[]) => { 96 | if(this.timeout) 97 | clearTimeout(this.timeout); 98 | 99 | this.timeout = setTimeout(() => { 100 | this.update(val); 101 | }, this.debounceTime); 102 | }); 103 | 104 | this._sliderElement.noUiSlider.on('end', (val: number[]) => { 105 | if(this.timeout) 106 | clearTimeout(this.timeout); 107 | 108 | this.update(val); 109 | }); 110 | } 111 | 112 | ngOnChanges(changes:any):void{ 113 | if(this._sliderElement && typeof changes.value !== 'undefined') 114 | this._sliderElement.noUiSlider.set([changes.value.currentValue, this.secondValue]); 115 | 116 | if(this._sliderElement && typeof changes.secondValue !== 'undefined') 117 | this._sliderElement.noUiSlider.set([this.value, changes.secondValue.currentValue]); 118 | } 119 | } 120 | 121 | export var SLIDER_COMPONENT_PROVIDERS = [ 122 | Slider 123 | ]; 124 | -------------------------------------------------------------------------------- /src/components/DatePicker/DatePicker.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {DATE_PICKER_PROVIDERS} from './DatePickerProviders'; 3 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 4 | import {TableSortable, TableSortableColumn, TableSortableSorting} from '../../components/TableSortable/TableSortable'; 5 | import {Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 6 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 7 | 8 | @Component({ 9 | template: ` 10 |
11 |
12 |
13 |

DatePicker

14 |

DatePicker is a custom component to select a single date on a calendar

15 |
16 |
17 |
18 | 19 |
20 |
21 |
22 | 23 | 28 |
29 | 30 |
31 |
32 |
33 |
34 |
35 | date-picker value: {{datePickerValue}}
36 | input ngModel: {{datePickerFieldValue}} 37 |
38 |
39 | 40 |
41 |

Import

42 |
 43 | 
 44 | import {DATE_PICKER_PROVIDERS} from 'fuel-ui/fuel-ui';
 45 | 
 46 | 
47 | 48 |

Getting Started

49 |

DatePicker is a custom element to select a date on a calendar. It supports filtering of dates so that you can disable dates programmatically. Also supports min and max dates

50 | 51 |

Usage

52 | 53 | 54 |
 55 | 
 56 | <div class="form-group">
 57 |     <label for="date">Pick a Date</label>
 58 |     <date-picker
 59 |         minDate="11/1/2015"
 60 |         maxDate="11/12/2016" 
 61 |         [dateFilter]="dateFilter"
 62 |         (valueChange)="datePickerValue">
 63 |         <div class="date-picker-input-group">
 64 |             <input name="date" dateField class="form-control" value="5/6/2016" placeholder="pick a date" />
 65 |         </div>
 66 |     </date-picker>
 67 | </div>
 68 | 
 69 | 
70 |
71 | 72 |
 73 | 
 74 | export class DatePickerExample { 
 75 |     datePickerValue: Date;
 76 |     
 77 |     dateFilter(d: Date): boolean {
 78 |         
 79 |         //every Tuesday
 80 |         if([2].indexOf(d.getDay()) > -1)
 81 |             return false;
 82 |         
 83 |         return true;
 84 |     }
 85 | }
 86 | 
 87 | 
88 |
89 |
90 | 91 |

Attributes

92 | 96 | Loading table... 97 | 98 | 99 |

DateField Attributes

100 | 104 | Loading table... 105 | 106 | 107 |
`, 108 | directives: [DATE_PICKER_PROVIDERS, CodeHighlighter, TableSortable, TAB_PROVIDERS] 109 | }) 110 | export class DatePickerDemo { 111 | datePickerValue = new Date(2016,7,6); 112 | datePickerFieldValue = "8/6/2016"; 113 | dateFilter(d: Date): boolean { 114 | if([2].indexOf(d.getDay()) > -1) 115 | return false; 116 | 117 | return true; 118 | } 119 | 120 | attributes:any[] = [ 121 | new Attribute('minDate', 'string|Date', 'new Date(1900,0,1)', 'Minimum selectable date'), 122 | new Attribute('maxDate', 'string|Date', 'new Date(2200,0,1)', 'Maximum selectable date'), 123 | new Attribute('dateFilter', 'function(date): boolean', 'null', 'Filter to disable dates. A return of false will disable the day'), 124 | new Attribute('value', 'Date', 'null', 'Two-way binding of the selected DateRange') 125 | ]; 126 | 127 | dateFieldAttributes:any[] = [ 128 | new Attribute('date', 'Date', 'null', 'Two-way binding of the selected date'), 129 | new Attribute('value', 'string|Date', 'null', 'Two-way binding of the selected date'), 130 | new Attribute('ngModel', 'string', 'null', 'Two-way binding of the result input string'), 131 | ]; 132 | 133 | attributesColumns:TableSortableColumn[] = AttributeColumns; 134 | attributesSort:TableSortableSorting = AttributesDefaultSort; 135 | } 136 | 137 | export var DATEPICKER_DEMO_PROVIDERS = [ 138 | DatePickerDemo 139 | ]; -------------------------------------------------------------------------------- /src/components/TableSortable/TableSortable.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {TABLESORTABLE_PROVIDERS, TableSortableColumn, TableSortableSorting} from './TableSortable'; 3 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 4 | import {Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 5 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 6 | 7 | @Component({ 8 | template: ` 9 |
10 |
11 |
12 |

TableSortable

13 |

TableSortable is a custom element to display any arbitrary data in a sortable data table

14 |
15 |
16 |
17 | 18 |
19 |
20 | 24 | Loading table... 25 | 26 |
27 |
28 | 29 |
30 |

Import

31 |
 32 | 
 33 | import {TableSortable, TableSortableColumn, TableSortableSorting} from 'fuel-ui/fuel-ui';
 34 | 
 35 | 
36 | 37 |

Getting Started

38 |

TableSortable is a custom element to display any arbitrary data in a sortable table

39 | 40 |

Usage

41 | 42 | 43 |
 44 | 
 45 | <table-sortable
 46 |     [columns]="columns"
 47 | 	[data]="rows"
 48 | 	[sort]="sorting">
 49 |   Loading table...
 50 | </table-sortable>
 51 | 
 52 | 
53 |
54 | 55 |
 56 | 
 57 | export class TableSortableExample {
 58 |     rows: any[] = [
 59 |     {
 60 |       Name: 'Data 1',
 61 |       Amount: 100.23,
 62 |       Date: 1441588216000,
 63 |       Desc: "You can't sort"
 64 |     },
 65 |     {
 66 |       Name: 'Data 2',
 67 |       Amount: 0.875623,
 68 |       Date: 1442387616000,
 69 |       Desc: "On this"
 70 |     },
 71 |     {
 72 |       Name: 'Data 3',
 73 |       Amount: .010123,
 74 |       Date: 1442187616000,
 75 |       Desc: "Table column"
 76 |     }
 77 |   ];
 78 |   columns: TableSortableColumn[] = [
 79 |     {
 80 |       display: 'Column 1', //The text to display
 81 |       variable: 'Name', //The name of the key that's apart of the data array
 82 |       filter: 'text', //The type data type of the column (number, text, date, etc.)
 83 |       sortable: true //Whether the user can sort on the column
 84 |     },
 85 |     new TableSortableColumn('Column 2', 'Amount', 'decimal : 1.0-2'),
 86 |     new TableSortableColumn('Column 3', 'Date', 'dateTime'),
 87 |     new TableSortableColumn('Column 4', 'Desc', 'text', false)
 88 |   ];
 89 |   sorting: TableSortableSorting = {
 90 |     column: 'Name', //to match the variable of one of the columns
 91 |     descending: false
 92 |   };
 93 | }
 94 | 
 95 | 
96 |
97 |
98 | 99 |

Attributes

100 | 104 | Loading table... 105 | 106 | 107 |
`, 108 | directives: [TABLESORTABLE_PROVIDERS, CodeHighlighter, TAB_PROVIDERS] 109 | }) 110 | export class TableSortableDemo { 111 | rows: any[] = [ 112 | { 113 | Name: 'Data 1', 114 | Amount: 100.23, 115 | Date: 1441588216000, 116 | Desc: "You can't sort" 117 | }, 118 | { 119 | Name: 'Data 2', 120 | Amount: 0.875623, 121 | Date: 1442387616000, 122 | Desc: "On this" 123 | }, 124 | { 125 | Name: 'Data 3', 126 | Amount: .010123, 127 | Date: 1442187616000, 128 | Desc: "Table column" 129 | } 130 | ]; 131 | columns: TableSortableColumn[] = [ 132 | { 133 | display: 'Column 1', //The text to display 134 | variable: 'Name', //The name of the key that's apart of the data array 135 | filter: 'text', //The type data type of the column (number, text, date, etc.) 136 | sortable: true //Whether the user can sort on the column 137 | }, 138 | new TableSortableColumn('Column 2', 'Amount', 'decimal : 1.0-2'), 139 | new TableSortableColumn('Column 3', 'Date', 'dateTime'), 140 | new TableSortableColumn('Column 4', 'Desc', 'text', false) 141 | ]; 142 | sorting: TableSortableSorting = { 143 | column: 'Name', //to match the variable of one of the columns 144 | descending: false 145 | }; 146 | 147 | attributes:Attribute[] = [ 148 | new Attribute('columns', 'TableSortableColumn[]', 'null', 'Array of all columns to be displayed and how to format them for ordering'), 149 | new Attribute('data', 'any[]', 'null', 'Any arbitrary array of objects'), 150 | new Attribute('sort', 'TableSortableSorting', 'null', 'Which column to sort on and which direction (ascending or descending)') 151 | ]; 152 | attributesColumns:TableSortableColumn[] = AttributeColumns; 153 | attributesSort:TableSortableSorting = AttributesDefaultSort; 154 | } 155 | 156 | export var TABLESORTABLE_DEMO_PROVIDERS = [ 157 | TableSortableDemo 158 | ]; -------------------------------------------------------------------------------- /typings/modules/es6-promise/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/typed-typings/npm-es6-promise/fb04188767acfec1defd054fc8024fafa5cd4de7/dist/es6-promise.d.ts 3 | declare module '~es6-promise/dist/es6-promise' { 4 | export interface Thenable { 5 | then (onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Thenable; 6 | then (onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => void): Thenable; 7 | } 8 | 9 | export class Promise implements Thenable { 10 | /** 11 | * If you call resolve in the body of the callback passed to the constructor, 12 | * your promise is fulfilled with result object passed to resolve. 13 | * If you call reject your promise is rejected with the object passed to resolve. 14 | * For consistency and debugging (eg stack traces), obj should be an instanceof Error. 15 | * Any errors thrown in the constructor callback will be implicitly passed to reject(). 16 | */ 17 | constructor (callback: (resolve : (value?: R | Thenable) => void, reject: (error?: any) => void) => void); 18 | 19 | /** 20 | * onFulfilled is called when/if "promise" resolves. onRejected is called when/if "promise" rejects. 21 | * Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called. 22 | * Both callbacks have a single parameter , the fulfillment value or rejection reason. 23 | * "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after being passed through Promise.resolve. 24 | * If an error is thrown in the callback, the returned promise rejects with that error. 25 | * 26 | * @param onFulfilled called when/if "promise" resolves 27 | * @param onRejected called when/if "promise" rejects 28 | */ 29 | then (onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Promise; 30 | then (onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => void): Promise; 31 | 32 | /** 33 | * Sugar for promise.then(undefined, onRejected) 34 | * 35 | * @param onRejected called when/if "promise" rejects 36 | */ 37 | catch (onRejected?: (error: any) => U | Thenable): Promise; 38 | 39 | /** 40 | * Make a new promise from the thenable. 41 | * A thenable is promise-like in as far as it has a "then" method. 42 | */ 43 | static resolve (): Promise; 44 | static resolve (value: R | Thenable): Promise; 45 | 46 | /** 47 | * Make a promise that rejects to obj. For consistency and debugging (eg stack traces), obj should be an instanceof Error 48 | */ 49 | static reject (error: any): Promise; 50 | 51 | /** 52 | * Make a promise that fulfills when every item in the array fulfills, and rejects if (and when) any item rejects. 53 | * the array passed to all can be a mixture of promise-like objects and other objects. 54 | * The fulfillment value is an array (in order) of fulfillment values. The rejection value is the first rejection value. 55 | */ 56 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable, T7 | Thenable, T8 | Thenable, T9 | Thenable, T10 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; 57 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable, T7 | Thenable, T8 | Thenable, T9 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; 58 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable, T7 | Thenable, T8 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; 59 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable, T7 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; 60 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6]>; 61 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable]): Promise<[T1, T2, T3, T4, T5]>; 62 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable ]): Promise<[T1, T2, T3, T4]>; 63 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable]): Promise<[T1, T2, T3]>; 64 | static all(values: [T1 | Thenable, T2 | Thenable]): Promise<[T1, T2]>; 65 | static all(values: [T1 | Thenable]): Promise<[T1]>; 66 | static all(values: Array>): Promise; 67 | 68 | /** 69 | * Make a Promise that fulfills when any item fulfills, and rejects if any item rejects. 70 | */ 71 | static race (promises: (R | Thenable)[]): Promise; 72 | } 73 | 74 | /** 75 | * The polyfill method will patch the global environment (in this case to the Promise name) when called. 76 | */ 77 | export function polyfill (): void; 78 | } 79 | declare module 'es6-promise/dist/es6-promise' { 80 | export * from '~es6-promise/dist/es6-promise'; 81 | } 82 | declare module 'es6-promise' { 83 | export * from '~es6-promise/dist/es6-promise'; 84 | } 85 | -------------------------------------------------------------------------------- /src/components/Modal/Modal.Demo.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {MODAL_PROVIDERS} from './Modal'; 3 | import {CodeHighlighter} from '../../directives/CodeHighlighter/CodeHighlighter'; 4 | import {TableSortable, TableSortableColumn, TableSortableSorting} from '../../components/TableSortable/TableSortable'; 5 | import {Event, EventColumns, EventsDefaultSort, Attribute, AttributeColumns, AttributesDefaultSort} from '../../utilities/demoUtilities'; 6 | import {TAB_PROVIDERS} from '../../components/Tab/Tab'; 7 | 8 | @Component({ 9 | template: ` 10 |
11 |
12 |
13 |

Modal

14 |

Modal is a custom component to display a popup

15 |
16 |
17 |
18 | 19 |
20 | 21 |
22 | 27 |
28 |
29 | 30 | 37 | 44 | 49 | 50 | 51 |
52 |

Import

53 |
 54 | 
 55 | import {Modal} from 'fuel-ui/fuel-ui';
 56 | 
 57 | 
58 | 59 |

Getting Started

60 |

Modal is a custom element to create a popup

61 | 62 |

Usage

63 | 64 | 65 |
 66 | 
 67 | <button class="btn btn-primary" (click)="modal.showModal()">Toggle Modal</button>
 68 | <modal #modal
 69 |     modalTitle="Modal Title"
 70 |     [closeButton]="true"
 71 |     [closeOnUnfocus]="true"
 72 |     size="lg"
 73 |     (close)="onClose()"
 74 |     (open)="onOpen()">
 75 |     <div class="modal-body">
 76 |         <ul>
 77 |             <li>Any</li>
 78 |             <li>Html</li>
 79 |             <li>Here</li>
 80 |         </ul>
 81 |     </div>
 82 |     <div class="modal-footer">
 83 |         <button type="button" class="btn btn-primary" (click)="modal.closeModal()">
 84 |             <i class="fa fa-chevron-left"></i> Go Back
 85 |         </button>
 86 |     </div>
 87 | </modal>
 88 | 
 89 | 
90 |
91 | 92 |
 93 | 
 94 | export class ModalExample {
 95 |     onClose(){
 96 |         console.log("Modal has been closed!");
 97 |     }
 98 |     onOpen(){
 99 |         console.log("Modal has been opened!");
100 |     }
101 | }
102 | 
103 | 
104 |
105 |
106 | 107 |

Attributes

108 | 112 | Loading table... 113 | 114 | 115 |

Events

116 | 120 | Loading table... 121 | 122 | 123 |
`, 124 | directives: [MODAL_PROVIDERS, CodeHighlighter, TableSortable, TAB_PROVIDERS] 125 | }) 126 | export class ModalDemo { 127 | closeText: string = "Cancel"; 128 | size: string = ""; 129 | 130 | onClose(){ 131 | console.log("Modal has been closed!"); 132 | } 133 | onOpen(){ 134 | console.log("Modal has been opened!"); 135 | } 136 | 137 | attributes:any[] = [ 138 | new Attribute('closeOnUnfocus', 'boolean', 'true', 'Closes the opened modal when the user clicks off of it'), 139 | new Attribute('closeButton', 'boolean', 'true', "Option to display an 'X' close button in the corner of the modal"), 140 | new Attribute('modalTitle', 'string', 'null', 'Text to display in modal header'), 141 | new Attribute('size', 'string', 'null', "Change the size of the modal. Supports 'sm' and 'small' for small size and 'lg' and 'large' for large. Null or empty will keep the default size") 142 | ]; 143 | attributesColumns:TableSortableColumn[] = AttributeColumns; 144 | attributesSort:TableSortableSorting = AttributesDefaultSort; 145 | events:Event[] = [ 146 | new Event('close', 'null', 'When the modal is closed'), 147 | new Event('open', 'null', 'When the modal is opened') 148 | ]; 149 | eventsColumns:TableSortableColumn[] = EventColumns; 150 | eventsSort:TableSortableSorting = EventsDefaultSort; 151 | } 152 | 153 | export var MODAL_DEMO_PROVIDERS = [ 154 | ModalDemo 155 | ]; --------------------------------------------------------------------------------