3 | @ngez/core is a library for Angular applications, which consists mostly of directives and other utilities,
4 | although our few components can still easily be overridden with new styles. This way you're not constrained
5 | by the theme of a component framework. Instead you can focus on how the view should look with your own styles, and we'll take care of the functionality.
6 |
7 |
8 | Tested on Chrome, Firefox and IE11.
9 |
10 |
Installation
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Something went wrong while loading the code.
20 |
21 |
22 |
23 |
24 |
25 | Core depends on the @angular/cdk, so install it if you haven't already:
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Something went wrong while loading the code.
36 |
37 |
3 | Html and components are rendered until they've actually entered the viewport.
4 |
5 |
Features
6 |
7 |
Lazy load images.
8 |
Components are instantiated until they've entered the viewport, thus delaying their lifecycle hooks.
9 |
10 |
Demo
11 |
12 | Open your devtools and scroll down. Notice how the component's ngOnInit method is called until it enters the viewport. Go to the network tab and the image was also lazily loaded.
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
Import
24 |
25 | Begin by importing the module like this:
26 |
27 |
28 | import {{'{'}} NgEzLazyRendererModule {{'}'}} from '@ngez/core';
29 |
30 |
Usage
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | Something went wrong while loading the code.
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | Something went wrong while loading the code.
54 |
55 |
Light and dark theme, although you can easily add your own.
8 |
Copy to clipboard.
9 |
Pass the code as a string or a url to get an actual file and display its text.
10 |
Display "loading" and "error" components when getting the code asynchronously.
11 |
12 |
Demo
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Something went wrong while loading the code.
22 |
23 |
24 |
25 |
26 |
Import
27 |
28 | Begin by importing the module like this:
29 |
30 |
31 | import {{'{'}} NgEzCodePrettifyModule {{'}'}} from '@ngez/core';
32 |
33 |
Usage
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | Something went wrong while loading the code.
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Something went wrong while loading the code.
57 |
58 |
59 |
60 |
61 |
Styling
62 |
You can create your own theme, or overwrite the existing ones with new colors quite easily:
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | Something went wrong while loading the code.
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "arrow-return-shorthand": true,
7 | "callable-types": true,
8 | "class-name": true,
9 | "comment-format": [
10 | true,
11 | "check-space"
12 | ],
13 | "curly": true,
14 | "deprecation": {
15 | "severity": "warn"
16 | },
17 | "eofline": true,
18 | "forin": true,
19 | "import-blacklist": [
20 | true,
21 | "rxjs/Rx"
22 | ],
23 | "import-spacing": true,
24 | "indent": [
25 | true,
26 | "spaces"
27 | ],
28 | "interface-over-type-literal": true,
29 | "label-position": true,
30 | "max-line-length": [
31 | true,
32 | 140
33 | ],
34 | "member-access": false,
35 | "member-ordering": [
36 | true,
37 | {
38 | "order": [
39 | "static-field",
40 | "instance-field",
41 | "static-method",
42 | "instance-method"
43 | ]
44 | }
45 | ],
46 | "no-arg": true,
47 | "no-bitwise": true,
48 | "no-console": [
49 | true,
50 | "debug",
51 | "info",
52 | "time",
53 | "timeEnd",
54 | "trace"
55 | ],
56 | "no-construct": true,
57 | "no-debugger": true,
58 | "no-duplicate-super": true,
59 | "no-empty": false,
60 | "no-empty-interface": true,
61 | "no-eval": true,
62 | "no-inferrable-types": [
63 | true,
64 | "ignore-params"
65 | ],
66 | "no-misused-new": true,
67 | "no-non-null-assertion": true,
68 | "no-shadowed-variable": true,
69 | "no-string-literal": false,
70 | "no-string-throw": true,
71 | "no-switch-case-fall-through": true,
72 | "no-trailing-whitespace": true,
73 | "no-unnecessary-initializer": true,
74 | "no-unused-expression": true,
75 | "no-use-before-declare": true,
76 | "no-var-keyword": true,
77 | "object-literal-sort-keys": false,
78 | "one-line": [
79 | true,
80 | "check-open-brace",
81 | "check-catch",
82 | "check-else",
83 | "check-whitespace"
84 | ],
85 | "prefer-const": true,
86 | "quotemark": [
87 | true,
88 | "single"
89 | ],
90 | "radix": true,
91 | "semicolon": [
92 | true,
93 | "always"
94 | ],
95 | "triple-equals": [
96 | true,
97 | "allow-null-check"
98 | ],
99 | "typedef-whitespace": [
100 | true,
101 | {
102 | "call-signature": "nospace",
103 | "index-signature": "nospace",
104 | "parameter": "nospace",
105 | "property-declaration": "nospace",
106 | "variable-declaration": "nospace"
107 | }
108 | ],
109 | "unified-signatures": true,
110 | "variable-name": false,
111 | "whitespace": [
112 | true,
113 | "check-branch",
114 | "check-decl",
115 | "check-operator",
116 | "check-separator",
117 | "check-type"
118 | ],
119 | "no-output-on-prefix": true,
120 | "use-input-property-decorator": true,
121 | "use-output-property-decorator": true,
122 | "use-host-property-decorator": true,
123 | "no-input-rename": true,
124 | "no-output-rename": true,
125 | "use-life-cycle-interface": true,
126 | "use-pipe-transform-interface": true,
127 | "component-class-suffix": true,
128 | "directive-class-suffix": true
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/projects/io/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/
22 | import 'core-js/es6/symbol';
23 | import 'core-js/es6/object';
24 | import 'core-js/es6/function';
25 | import 'core-js/es6/parse-int';
26 | import 'core-js/es6/parse-float';
27 | import 'core-js/es6/number';
28 | import 'core-js/es6/math';
29 | import 'core-js/es6/string';
30 | import 'core-js/es6/date';
31 | import 'core-js/es6/array';
32 | import 'core-js/es6/regexp';
33 | import 'core-js/es6/map';
34 | import 'core-js/es6/weak-map';
35 | import 'core-js/es6/set';
36 |
37 | /**
38 | * If the application will be indexed by Google Search, the following is required.
39 | * Googlebot uses a renderer based on Chrome 41.
40 | * https://developers.google.com/search/docs/guides/rendering
41 | **/
42 | import 'core-js/es6/array';
43 |
44 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
45 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
46 |
47 | /** IE10 and IE11 requires the following for the Reflect API. */
48 | import 'core-js/es6/reflect';
49 |
50 | /**
51 | * Web Animations `@angular/platform-browser/animations`
52 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
53 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
54 | **/
55 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
56 |
57 | /**
58 | * By default, zone.js will patch all possible macroTask and DomEvents
59 | * user can disable parts of macroTask/DomEvents patch by setting following flags
60 | */
61 |
62 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
63 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
64 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
65 |
66 | /*
67 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
68 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
69 | */
70 | // (window as any).__Zone_enable_cross_context_check = true;
71 |
72 | /***************************************************************************************************
73 | * Zone JS is required by default for Angular itself.
74 | */
75 | import 'zone.js/dist/zone'; // Included with Angular CLI.
76 |
77 |
78 | /***************************************************************************************************
79 | * APPLICATION IMPORTS
80 | */
81 |
--------------------------------------------------------------------------------
/projects/core/src/nested-nav/nav-list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ContentChildren, QueryList, AfterContentInit, OnInit, OnDestroy, OnChanges, ViewEncapsulation } from "@angular/core";
2 | import { faAngleUp, faAngleDown, IconDefinition } from '@fortawesome/free-solid-svg-icons';
3 | import { RouterLink, RouterLinkWithHref, Router, NavigationEnd } from "@angular/router";
4 | import { Subscription } from "rxjs";
5 | import { filter } from "rxjs/operators";
6 |
7 | @Component({
8 | selector: 'ngez-nav-list',
9 | templateUrl: './nav-list.component.html',
10 | styleUrls: ['./nav-list.component.scss'],
11 | encapsulation: ViewEncapsulation.None
12 | })
13 | export class NgEzNavListComponent implements OnChanges, OnInit, AfterContentInit, OnDestroy {
14 |
15 | @Input() title: string;
16 |
17 | @Input() routerLinkActiveOptions: { exact: boolean } = { exact: false };
18 |
19 | @ContentChildren(NgEzNavListComponent) lists: QueryList;
20 |
21 | @ContentChildren(RouterLink) links: QueryList;
22 |
23 | @ContentChildren(RouterLinkWithHref) linksWithHrefs: QueryList;
24 |
25 | faAngleUp: IconDefinition = faAngleUp;
26 |
27 | faAngleDown: IconDefinition = faAngleDown;
28 |
29 | open: boolean = false;
30 |
31 | active: boolean = false;
32 |
33 | navigationSubscription: Subscription;
34 |
35 | linksQueryListChangesSubscription: Subscription;
36 |
37 | linksWithHrefsQueryListChangesSubscription: Subscription;
38 |
39 | constructor(private router: Router) { }
40 |
41 | ngOnChanges() {
42 | this.update();
43 | }
44 |
45 | ngOnInit() {
46 | this.navigationSubscription = this.router.events
47 | .pipe(filter(e => e instanceof NavigationEnd))
48 | .subscribe(e => this.update())
49 | }
50 |
51 | ngAfterContentInit() {
52 | this.linksQueryListChangesSubscription =
53 | this.links.changes.subscribe((c) => this.update());
54 | this.linksWithHrefsQueryListChangesSubscription =
55 | this.linksWithHrefs.changes.subscribe((c) => this.update());
56 | this.update();
57 | }
58 |
59 | ngOnDestroy() {
60 | if(this.navigationSubscription)
61 | this.navigationSubscription.unsubscribe();
62 | if(this.linksQueryListChangesSubscription)
63 | this.linksQueryListChangesSubscription.unsubscribe();
64 | if(this.linksWithHrefsQueryListChangesSubscription)
65 | this.linksWithHrefsQueryListChangesSubscription.unsubscribe();
66 | }
67 |
68 | onToggle() {
69 | this.open = !this.open;
70 | }
71 |
72 | private update(){
73 | if(!this.links || !this.linksWithHrefs || !this.router.navigated)
74 | return;
75 | this.active = this.hasActiveLinks();
76 |
77 | if(!this.open)
78 | this.open = this.active;
79 | }
80 |
81 | private isLinkActive(router: Router): (link: (RouterLink | RouterLinkWithHref)) => boolean {
82 | return (link: RouterLink | RouterLinkWithHref) =>
83 | router.isActive(link.urlTree, this.exact);
84 | }
85 |
86 | private hasActiveLinks(): boolean {
87 | return this.links.some(this.isLinkActive(this.router)) ||
88 | this.linksWithHrefs.some(this.isLinkActive(this.router));
89 | }
90 |
91 | private get exact(): boolean {
92 | return this.routerLinkActiveOptions ? this.routerLinkActiveOptions.exact : false;
93 | }
94 | }
--------------------------------------------------------------------------------
/projects/core/src/autocomplete/autocomplete.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component,
3 | OnInit,
4 | TemplateRef,
5 | ViewChild,
6 | QueryList,
7 | ContentChildren,
8 | EventEmitter,
9 | Output,
10 | ElementRef,
11 | Input
12 | } from '@angular/core';
13 | import { ActiveDescendantKeyManager } from "@angular/cdk/a11y";
14 | import { NgEzAutocompleteOptionComponent } from './autocomplete-option.component';
15 | import { UP_ARROW, DOWN_ARROW, ENTER, TAB } from '@angular/cdk/keycodes';
16 | import { merge, Subscription, Observable } from 'rxjs';
17 | import { NgEzAutocompleteConfig, defaultConfig } from "./models";
18 |
19 | @Component({
20 | selector: 'ngez-autocomplete',
21 | templateUrl: './autocomplete.component.html',
22 | styleUrls: ['./autocomplete.component.scss'],
23 | host: {
24 | 'style.max-height.px': `config.maxHeight`
25 | }
26 | })
27 | export class NgEzAutocompleteComponent {
28 |
29 | defaultConfig = defaultConfig;
30 |
31 | @Input() config: NgEzAutocompleteConfig
32 |
33 | @Output() opened = new EventEmitter();
34 |
35 | @Output() closed = new EventEmitter();
36 |
37 | @ViewChild(TemplateRef) template: TemplateRef;
38 |
39 | @ViewChild('panel') panel: ElementRef;
40 |
41 | @ContentChildren(NgEzAutocompleteOptionComponent, { descendants: true }) options: QueryList;
42 |
43 | keyboardEventsManager: ActiveDescendantKeyManager;
44 |
45 | subscription: Subscription;
46 |
47 | optionEventEmitters: Observable>;
48 |
49 | ngAfterViewInit() {
50 | this.keyboardEventsManager =
51 | new ActiveDescendantKeyManager(this.options).withWrap(true);
52 | }
53 |
54 | reset() {
55 | this.keyboardEventsManager.setActiveItem(-1);
56 | }
57 |
58 | handleKeyDown(event: KeyboardEvent) {
59 | event.stopImmediatePropagation();
60 | if (this.keyboardEventsManager) {
61 | if (event.keyCode === DOWN_ARROW || event.keyCode === UP_ARROW || event.keyCode === TAB) {
62 | // passing the event to key manager so we get a change fired
63 | this.keyboardEventsManager.onKeydown(event);
64 | return false;
65 | } else if (event.keyCode === ENTER) {
66 | // when we hit enter, the keyboardManager should call the selectItem method of the `ListItemComponent`
67 | this.keyboardEventsManager.activeItem.onSelect();
68 | return false;
69 | }
70 | }
71 | }
72 |
73 | getScrollTop() {
74 | const index = this.keyboardEventsManager.activeItemIndex;
75 | const option = this.keyboardEventsManager.activeItem;
76 | const offset =
77 | this.options.toArray().slice(0, index + 1).reduce((offset, option) => offset + option.getOffsetHeight(), 0);
78 | const currentScrollPosition = this.panel.nativeElement.scrollTop;
79 |
80 | if (offset - option.getOffsetHeight() < currentScrollPosition)
81 | return offset - option.getOffsetHeight() + 3;
82 |
83 | const optionHeight = option.getOffsetHeight();
84 |
85 | const panelHeight = this.panel.nativeElement.getBoundingClientRect().height;
86 |
87 | if(offset > currentScrollPosition + panelHeight)
88 | return Math.max(0, offset - panelHeight);
89 |
90 | return currentScrollPosition;
91 | }
92 |
93 | setScrollTop() {
94 | if (!this.panel)
95 | return;
96 |
97 | const scrollTop = this.getScrollTop();
98 |
99 | this.panel.nativeElement.scrollTop = scrollTop;
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at ngezplatform@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/projects/io/src/theme.scss:
--------------------------------------------------------------------------------
1 | @import '~@angular/material/theming';
2 | // Plus imports for other components in your app.
3 |
4 | // Include the common styles for Angular Material. We include this here so that you only
5 | // have to load a single css file for Angular Material in your app.
6 | // Be sure that you only ever include this mixin once!
7 | @include mat-core();
8 |
9 | // Define the palettes for your theme using the Material Design palettes available in palette.scss
10 | // (imported above). For each palette, you can optionally specify a default, lighter, and darker
11 | // hue. Available color palettes: https://www.google.com/design/spec/style/color.html
12 | $custom-primary: (
13 | 50 : #e0e2e5,
14 | 100 : #b3b6bf,
15 | 200 : #808594,
16 | 300 : #4d5469,
17 | 400 : #263049,
18 | 500 : #000b29,
19 | 600 : #000a24,
20 | 700 : #00081f,
21 | 800 : #000619,
22 | 900 : #00030f,
23 | A100 : #5252ff,
24 | A200 : #1f1fff,
25 | A400 : #0000eb,
26 | A700 : #0000d1,
27 | contrast: (
28 | 50 : #000000,
29 | 100 : #000000,
30 | 200 : #000000,
31 | 300 : #ffffff,
32 | 400 : #ffffff,
33 | 500 : #ffffff,
34 | 600 : #ffffff,
35 | 700 : #ffffff,
36 | 800 : #ffffff,
37 | 900 : #ffffff,
38 | A100 : #ffffff,
39 | A200 : #ffffff,
40 | A400 : #ffffff,
41 | A700 : #ffffff,
42 | )
43 | );
44 |
45 | $custom-accent: (
46 | 50 : #fae0e5,
47 | 100 : #f3b3be,
48 | 200 : #eb8093,
49 | 300 : #e34d67,
50 | 400 : #dd2647,
51 | 500 : #d70026,
52 | 600 : #d30022,
53 | 700 : #cd001c,
54 | 800 : #c70017,
55 | 900 : #be000d,
56 | A100 : #ffe6e7,
57 | A200 : #ffb3b5,
58 | A400 : #ff8084,
59 | A700 : #ff676b,
60 | contrast: (
61 | 50 : #000000,
62 | 100 : #000000,
63 | 200 : #000000,
64 | 300 : #ffffff,
65 | 400 : #ffffff,
66 | 500 : #ffffff,
67 | 600 : #ffffff,
68 | 700 : #ffffff,
69 | 800 : #ffffff,
70 | 900 : #ffffff,
71 | A100 : #000000,
72 | A200 : #000000,
73 | A400 : #000000,
74 | A700 : #000000,
75 | )
76 | );
77 |
78 | $custom-warn: (
79 | 50 : #fdf6e8,
80 | 100 : #faeac5,
81 | 200 : #f6dc9e,
82 | 300 : #f2cd77,
83 | 400 : #f0c35a,
84 | 500 : #edb83d,
85 | 600 : #ebb137,
86 | 700 : #e8a82f,
87 | 800 : #e5a027,
88 | 900 : #e0911a,
89 | A100 : #ffffff,
90 | A200 : #fff2e0,
91 | A400 : #ffdcad,
92 | A700 : #ffd194,
93 | contrast: (
94 | 50 : #000000,
95 | 100 : #000000,
96 | 200 : #000000,
97 | 300 : #000000,
98 | 400 : #000000,
99 | 500 : #000000,
100 | 600 : #000000,
101 | 700 : #000000,
102 | 800 : #000000,
103 | 900 : #000000,
104 | A100 : #000000,
105 | A200 : #000000,
106 | A400 : #000000,
107 | A700 : #000000,
108 | )
109 | );
110 |
111 |
112 | $app-primary: mat-palette($custom-primary);
113 | $app-accent: mat-palette($custom-accent);
114 |
115 | // The warn palette is optional (defaults to red).
116 | $app-warn: mat-palette($custom-warn);
117 |
118 | // Create the theme object (a Sass map containing all of the palettes).
119 | $app-theme: mat-light-theme($app-primary, $app-accent, $app-warn);
120 |
121 | // Include theme styles for core and each component used in your app.
122 | // Alternatively, you can import and @include the theme mixins for each component
123 | // that you are using.
124 | @include angular-material-theme($app-theme);
--------------------------------------------------------------------------------
/projects/io/src/app/core/pages/file-dropzone/file-dropzone.page.html:
--------------------------------------------------------------------------------
1 |
File Dropzone
2 |
3 | Turn any element into a file dropzone and you decide how you want to render
4 | the files. The control's value will be the File[].
5 |
6 |
Features
7 |
8 |
Works with FormsModule and ReactiveFormsModule.
9 |
Dropping a folder will extract the files.
10 |
Easily style the dropzone while dropping files.
11 |
12 |
Caveat
13 |
14 | Internet Explorer doesn't allow dropping folders or extracting the files from
15 | a folder, so if the dropped files contain at least one folder, it'll return an
16 | empty array. Works as expected on Edge.
17 |