Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: allow custom styling - fixes #93 #116

Merged
merged 10 commits into from
Aug 3, 2017
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,56 @@ you can use `[headers]` directive like this.

`[clearButtonCaption]="'Clear'"` - Text shown on the "Clear" button. Default is "**Clear**".

#### CSS Class

`[class]="'customClass'"` - Set custom class for this component. It is set on parent level element `<image-upload>` which can be customized as follow :

:host >>> .custom-class{
background-color: #dd3;
border-radius: 5px;
margin:5px;
width: 500px;
}
:host >>> .custom-class .img-ul-upload{
background-color: #000;
}
:host >>> .custom-class .img-ul-clear{
background-color: #B819BB;
}
:host >>> .custom-class .img-ul-drag-box-msg {
color: purple;
}
:host >>> .custom-class .img-ul-container{
background-color: #FF6CAD;
}

**Note:** `.img-ul-*` classes which are overridden with new styles.

#### Custom Style


`[style]="'customStyle'"` - Set custom style properties for this component. `customStyle` is typescript object defined in your component.

customStyle = {
selectButton: {
"color": "white",
"background-color": "purple",
},
clearButton: {
"color": "white",
"background-color": "yellow",
},
layout: {
"background-color": "black",
"color": "red",
"font-size": "15px",
},
previewPanel: {
"background-color": "red",
}

**Note:** `selectButton`, `clearButton`, `layout` and `previewPanel` are optional properties.

#### Events

`(uploadFinished)="onUploadFinished($event)"`. If `[url]` is specified this event is fired when component gets a response from the server, also in this case event has field `serverResponse` which contains the status code and response from the server `{status, response}`. If `[url]` is not specified it's fired immediately after an image(s) dropped into file-drop zone of choosed in file browser. So what you can do, is not specify `[url]` to handle upload yourself, for exapmple send the image into firebase storage. To get file use `event.file`.
Expand All @@ -83,6 +133,7 @@ In the final state it should look something like this:
[buttonCaption]="'Select Images!'"
[dropBoxMessage]="'Drop your images here!'"
[extensions]="['jpg','png','gif']"
[class]="'customClass'"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about style directive?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can add [style] directive but it will mislead user. Good to apply either [class] or [style] because [style] overrides [class]. Do you still want me to add? @aberezkin

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No since we have it in the demo, it's ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah 👍

(removed)="onRemoved($event)"
(uploadFinished)="onUploadFinished($event)"
(uploadStateChanged)="onUploadStateChanged($event)">
Expand Down
1 change: 1 addition & 0 deletions demo/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ <h1 class="display-3">
<div class="mt-3"></div>
<events></events>
<div class="mt-5"></div>
<styles></styles>
</div>
4 changes: 3 additions & 1 deletion demo/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import { BasicExampleComponent } from './basic/basic.component';
import { FilterExampleComponent } from './filter/filter.component';
import { CustomiseComponent } from './customise/customise.component';
import { EventsComponent } from './events/events.component';
import { StyleComponent } from './style/style.component';

@NgModule({
declarations: [
AppComponent,
BasicExampleComponent,
FilterExampleComponent,
CustomiseComponent,
EventsComponent
EventsComponent,
StyleComponent
],
imports: [
BrowserModule,
Expand Down
18 changes: 18 additions & 0 deletions demo/src/app/style/style.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.customClass{
background-color: #dd3;
border-radius: 5px;
margin:5px;
width: 500px;
}
.customClass .img-ul-upload{
background-color: #000 !important;
}
.customClass .img-ul-clear{
background-color: #B819BB !important;
}
.customClass .img-ul-drag-box-msg {
color: purple !important;
}
.customClass .img-ul-container{
background-color: #FF6CAD !important;
}
61 changes: 61 additions & 0 deletions demo/src/app/style/style.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<h4 class="mb-3 mt-5">Styles</h4>

<h5 class="mb-3 mt-3">Custom CSS Class</h5>

<image-upload url="https://httpbin.org/status/200" class="customClass"></image-upload>

<pre><code class="language-markup"><![CDATA[<image-upload url="https://httpbin.org/status/200" class="customClass"></image-upload>]]></code></pre>

<pre><code class="language-css"><![CDATA[.customClass{
background-color: #dd3;
border-radius: 5px;
margin:5px;
width: 500px;
}
.customClass .img-ul-upload{
background-color: #000 !important;
}
.customClass .img-ul-clear{
background-color: #B819BB !important;
}
.customClass .img-ul-drag-box-msg {
color: purple !important;
}
.customClass .img-ul-container{
background-color: #FF6CAD !important;
}
]]></code></pre>

<h5 class="mb-3 mt-3">Custom Style</h5>

<image-upload url="https://httpbin.org/status/200" [style]="customStyle"></image-upload>

<pre><code class="language-markup"><![CDATA[<image-upload url="https://httpbin.org/status/200" [style]="customStyle"></image-upload>]]></code></pre>

<pre><code class="language-typescript"><![CDATA[customStyle = {
selectButton: {
"background-color": "yellow",
"border-radius": "25px",
"color": "#000"
},
clearButton: {
"background-color": "#FFF",
"border-radius": "25px",
"color": "#000",
"margin-left": "10px"
},
layout: {
"background-color": "purple",
"border-radius": "25px",
"color": "#FFF",
"font-size": "15px",
"margin": "10px",
"padding-top": "5px",
"width": "500px"
},
previewPanel: {
"background-color": "#894489",
"border-radius": "0 0 25px 25px",
}
}
]]></code></pre>
40 changes: 40 additions & 0 deletions demo/src/app/style/style.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
selector: 'styles',
templateUrl: './style.component.html',
styleUrls: ['./style.component.css'],
encapsulation: ViewEncapsulation.None
})
export class StyleComponent {

constructor() { }

customStyle = {
selectButton: {
"background-color": "yellow",
"border-radius": "25px",
"color": "#000"
},
clearButton: {
"background-color": "#FFF",
"border-radius": "25px",
"color": "#000",
"margin-left": "10px"
},
layout: {
"background-color": "purple",
"border-radius": "25px",
"border": "none",
"color": "#FFF",
"font-size": "15px",
"margin": "10px",
"padding-top": "5px",
"width": "500px"
},
previewPanel: {
"background-color": "#894489",
"border-radius": "0 0 25px 25px",
}
}
}
12 changes: 6 additions & 6 deletions src/image-upload/image-upload.component.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
.img-ul {
--active-color: #3C9;
--common-radius: 3px;
background-color: #f8f8f8;
border-radius: var(--common-radius);
border: #d0d0d0 dashed 1px;
font-family: sans-serif;
position: relative;
color: #9b9b9b;
}

.img-ul-file-is-over {
Expand All @@ -17,13 +19,11 @@
display: table;
}

.img-ul-file-upload {
background-color: #f8f8f8;
.img-ul-file-upload {
padding: 16px;
}

.img-ul-drag-box-msg {
color: #9b9b9b;
.img-ul-drag-box-msg {
display: inline-block;
font-weight: 600;
margin-left: 12px;
Expand Down Expand Up @@ -109,9 +109,9 @@ label.img-ul-button input[type=file] {
background-color: #FFF;
border-radius: 2px;
content: '';
height: 16px;
height: 15px;
position: absolute;
top: 2px;
top: 0;
width: 2px;
}

Expand Down
14 changes: 8 additions & 6 deletions src/image-upload/image-upload.component.html
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
<div class="img-ul"
<div
fileDrop
[accept]="supportedExtensions"
(fileOver)="onFileOver($event)"
(fileDrop)="onFileChange($event)"
[ngClass]="{'img-ul-file-is-over': fileOver}"
[ngClass]="cssClass"
[ngClass]="{'img-ul-file-is-over': fileOver}"
[ngStyle]="style?.layout"
>
<div class="img-ul-file-upload img-ul-hr-inline-group">
<label class="img-ul-upload img-ul-button">
<div class="img-ul-file-upload img-ul-hr-inline-group">
<label class="img-ul-upload img-ul-button" [ngStyle]="style?.selectButton">
<span [innerText]="buttonCaption"></span>
<input
type="file"
[accept]="supportedExtensions"
multiple (change)="onFileChange(input.files)"
#input>
</label>
<label *ngIf="fileCounter > 0" class="img-ul-clear img-ul-button" (click)="deleteAll()">
<label *ngIf="fileCounter > 0" class="img-ul-clear img-ul-button" (click)="deleteAll()" [ngStyle]="style?.clearButton">
<span [innerText]="clearButtonCaption"></span>
</label>
<div class="img-ul-drag-box-msg" [innerText]="dropBoxMessage"></div>
</div>

<p class="img-ul-file-too-large" *ngIf="showFileTooLargeMessage" [innerText]="fileTooLargeMessage"></p>

<div *ngIf="preview" class="img-ul-container img-ul-hr-inline-group">
<div *ngIf="preview" class="img-ul-container img-ul-hr-inline-group" [ngStyle]="style?.previewPanel">
<div
class="img-ul-image"
*ngFor="let file of files"
Expand Down
11 changes: 6 additions & 5 deletions src/image-upload/image-upload.component.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { Headers } from '@angular/http';
import { UploadMetadata } from './before-upload.interface';

import { ImageService } from './image.service';
import { Style } from "./style";
import { UploadMetadata } from './before-upload.interface';

export class FileHolder {
public pending: boolean = false;
public serverResponse: { status: number, response: any };

constructor(public src: string, public file: File) {
}
constructor(public src: string, public file: File) { }
}

@Component({
Expand All @@ -26,6 +26,7 @@ export class ImageUploadComponent implements OnInit {

@Input() beforeUpload: (UploadMetadata) => UploadMetadata | Promise<UploadMetadata> = data => data;
@Input() buttonCaption: string = 'Select Images';
@Input('class') cssClass: string = 'img-ul';
@Input() clearButtonCaption: string = 'Clear';
@Input() dropBoxMessage: string = 'Drop your images here!';
@Input() fileTooLargeMessage: string;
Expand All @@ -34,6 +35,7 @@ export class ImageUploadComponent implements OnInit {
@Input() maxFileSize: number;
@Input() preview: boolean = true;
@Input() partName: string;
@Input() style: Style;
@Input('extensions') supportedExtensions: string[];
@Input() url: string;
@Input() withCredentials: boolean = false;
Expand All @@ -45,8 +47,7 @@ export class ImageUploadComponent implements OnInit {
private inputElement: ElementRef;
private pendingFilesCounter: number = 0;

constructor(private imageService: ImageService) {
}
constructor(private imageService: ImageService) { }

ngOnInit() {
if (!this.fileTooLargeMessage) {
Expand Down
53 changes: 53 additions & 0 deletions src/image-upload/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* @internal
*/
export type StyleProps = { [key: string]: string }
/**
* @whatItDoes Represents custom style for various elements and controls.
*/
export interface Style {
/**
* Sets custom style for select button.
*
* ```
* selectButton: {
* "background-color": "#800080",
* "color": "#FFF"
* }
* ```
*/
selectButton?: StyleProps;
/**
* Sets custom style for clear button.
*
* ```
* clearButton: {
* "background-color": "#FFFF00",
* "color": "#FFF"
* }
* ```
*/
clearButton?: StyleProps;
/**
* Sets custom style for entire layout.
*
* ```
* layout: {
* "border": "#d0d0d0 dashed 1px",
* "margin": "5px"
* }
* ```
*/
layout?: StyleProps;
/**
* Sets custom style for entire layout.
*
* ```
* previewPanel: {
* "background-color": "#FFFF00",
* "padding": "5px"
* }
* ```
*/
previewPanel?: StyleProps;
}