Skip to content
This repository has been archived by the owner on Nov 6, 2024. It is now read-only.

Commit

Permalink
Implement Timepicker (#214)
Browse files Browse the repository at this point in the history
* Implement Timepicker
* Add yarn unlink to appveyor.yml
* Improve test coverage
* Add unit/view tests
* Update available components in README.md
* Handle timepicker form validation
* Fix active label when clearing value programmatically
  • Loading branch information
jfcere authored and scote committed Oct 12, 2017
1 parent dbf9544 commit 211b6b3
Show file tree
Hide file tree
Showing 30 changed files with 1,139 additions and 49 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ export class HomeModule { }
* Spinner
* Switch
* Textarea
* Timepicker
* Toast
* Tooltip

Expand Down
2 changes: 2 additions & 0 deletions demo-app/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { SidenavModule } from './sidenav/sidenav.module';
import { SpinnerModule } from './spinner/spinner.module';
import { SwitchModule } from './switch/switch.module';
import { TextareaModule } from './textarea/textarea.module';
import { TimepickerModule } from './timepicker/timepicker.module';
import { ToastModule } from './toast/toast.module';
import { TooltipModule } from './tooltip/tooltip.module';
import { ValidationModule } from './validation/validation.module';
Expand Down Expand Up @@ -75,6 +76,7 @@ import { ValidationModule } from './validation/validation.module';
SpinnerModule,
SwitchModule,
TextareaModule,
TimepickerModule,
ToastModule,
TooltipModule,
ValidationModule,
Expand Down
4 changes: 3 additions & 1 deletion demo-app/src/app/app.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { SidenavComponent } from './sidenav/sidenav.component';
import { SpinnerComponent } from './spinner/spinner.component';
import { SwitchComponent } from './switch/switch.component';
import { TextareaComponent } from './textarea/textarea.component';
import { TimepickerComponent } from './timepicker/timepicker.component';
import { ToastComponent } from './toast/toast.component';
import { TooltipComponent } from './tooltip/tooltip.component';
import { ValidationComponent } from './validation/validation.component';
Expand Down Expand Up @@ -53,8 +54,9 @@ export const ROUTES: Routes = [
{ path: 'input', component: InputComponent, data: { icon: 'textbox', text: 'Input', section: formControls } },
{ path: 'radio-button', component: RadioButtonComponent, data: { icon: 'radiobox-marked', text: 'Radio button', section: formControls } },
{ path: 'select', component: SelectComponent, data: { icon: 'menu-down-outline', text: 'Select', section: formControls } },
{ path: 'textarea', component: TextareaComponent, data: { icon: 'cursor-text', text: 'Textarea', section: formControls } },
{ path: 'switch', component: SwitchComponent, data: { icon: 'toggle-switch', text: 'Switch', section: formControls } },
{ path: 'textarea', component: TextareaComponent, data: { icon: 'cursor-text', text: 'Textarea', section: formControls } },
{ path: 'timepicker', component: TimepickerComponent, data: { icon: 'clock', text: 'Timepicker', section: formControls } },

// components routes - Layout
{ path: 'card', component: CardComponent, data: { icon: 'cards-outline', text: 'Card', section: layout } },
Expand Down
268 changes: 268 additions & 0 deletions demo-app/src/app/timepicker/timepicker.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
<h3>Timepicker</h3>

<div class="section">
<p>
Ng2-Materialize leverage the use of the native HTML input by using the <code class="language-markup">mz-timepicker</code> directive directly on the input element tag to ease the fact that you might use third party library that would ask you to add properties directly on that native input element.
</p>
</div>

<div class="section">

<h5 class="light">Basic timepicker</h5>

<div class="row m-valign-wrapper">

<mz-timepicker-container class="col s12 m6">
<input mz-timepicker
[label]="'Label'"
id="basic-timepicker"
placeholder="Placeholder"
type="text" />
</mz-timepicker-container>

<p class="col s12 m6">
Label and placeholder can be combined using both <code class="language-markup">label</code> and <code class="language-markup">placeholder</code> properties.
</p>
</div>

<div class="row m-valign-wrapper">

<mz-timepicker-container class="col s12 m6">
<input mz-timepicker
[label]="'Label as placeholder'"
id="basic-timepicker-label"
type="text" />
</mz-timepicker-container>

<p class="col s12 m6">
To use the floating label directly as a placeholder provide only the <code class="language-markup">label</code> property.
</p>
</div>

<div class="row m-valign-wrapper">

<mz-timepicker-container class="col s12 m6">
<input mz-timepicker
id="basic-timepicker-placeholder"
placeholder="Placeholder"
type="text" />
</mz-timepicker-container>

<p class="col s12 m6">
You can omit the floating label and use only a placeholder by providing only the <code class="language-markup">placeholder</code> property.
</p>
</div>
</div>

<div class="section">

<h5 class="light">Inline timepicker</h5>

<div class="row m-valign-wrapper">

<div class="col s12 m6">

Timepicker can be inline:

<mz-timepicker-container [inline]="true">
<input mz-timepicker
[label]="'Time'"
id="inline-timepicker"
type="text">
</mz-timepicker-container>
</div>

<p class="col s12 m6">
To show the input inline set <code class="language-markup">inline</code> property to <code class="language-markup">true</code> on <code class="language-markup">mz-timepicker-container</code> component.
</p>
</div>
</div>

<div class="section">

<h5 class="light">Disabled timepicker</h5>

<div class="row m-valign-wrapper">

<mz-timepicker-container class="col s12 m6">
<input mz-timepicker
[label]="'Disabled'"
id="disabled-timepicker"
type="text"
disabled>
</mz-timepicker-container>

<p class="col s12 m6">
Disable the timepicker input by using the native property <code class="language-markup">disabled</code>.
</p>
</div>
</div>

<div class="section">

<h5 class="light">Icon Prefixes</h5>

<div class="row m-valign-wrapper">

<mz-timepicker-container class="col s12 m6">
<i mz-icon-mdi mz-input-prefix
[icon]="'clock'">
</i>
<input mz-timepicker
[label]="'Time'"
id="prefix-timepicker"
type="tel" />
</mz-timepicker-container>

<p class="col s12 m6">
To use an icon prefix add the icon inside the <code class="language-markup">mz-timepicker-container</code> component with the <code class="language-markup">mz-input-prefix</code> directive on the icon tag.
</p>
</div>
</div>

<div class="section">

<h5 class="light">Timepicker options</h5>

<div class="row m-valign-wrapper">

<mz-timepicker-container class="col s12 m6">
<input mz-timepicker
[label]="'Time'"
[options]="options"
id="options-timepicker"
type="tel" />
</mz-timepicker-container>

<p class="col s12 m6">
To customize the behavior of a timepicker you can use the <code class="language-markup">options</code> input property and provide a <code class="language-markup">Options</code> object with the <code class="language-markup">mz-timepicker</code> directive.
</p>
</div>

<blockquote>
Materialize uses <code class="language-markup">ClockPicker</code> library to create the materialized time picker. You can find a complete list of available options with how to use it by following this link: <a href="https://github.com/weareoutman/clockpicker#options" target="_blank">https://github.com/weareoutman/clockpicker#options</a>.
</blockquote>

<app-code-snippet [language]="'typescript'">
public timepickerOptions: Pickadate.TimeOptions = &#123;
default: 'now', // Set default time: 'now', '1:30AM', '16:30'
fromnow: 0, // set default time to * milliseconds from now (using with default = 'now')
twelvehour: false, // Use AM/PM or 24-hour format
donetext: 'OK', // text for done-button
cleartext: 'Clear', // text for clear-button
canceltext: 'Cancel', // Text for cancel-button
autoclose: true, // automatic close timepicker
ampmclickable: true, // make AM PM clickable
aftershow: () => alert('AfterShow has been invoked.'), // function for after opening timepicker
};
</app-code-snippet>
</div>

<div class="section">

<h5 class="light">Playground</h5>

<p>
The input properties of the <code class="language-markup">mz-timepicker</code> directive makes the form-control completely dynamic. Change the configuration below and see how the timepicker reacts.
</p>

<div class="row">

<mz-timepicker-container class="col s12 m6">
<input mz-timepicker
id="timepicker"
[label]="timepickerLabel"
[placeholder]="timepickerPlaceholder"
[disabled]="timepickerDisabled"
[options]="timepickerOptions"
[(ngModel)]="timepickerValue"
type="text" />
</mz-timepicker-container>

<div class="col s12 m6">

<mz-input-container>
<input mz-input
id="timepicker-label"
[label]="'Label'"
[(ngModel)]="timepickerLabel"
type="text">
</mz-input-container>

<mz-input-container>
<input mz-input
id="timepicker-placeholder"
[label]="'Placeholder'"
[(ngModel)]="timepickerPlaceholder"
type="text">
</mz-input-container>

<mz-checkbox-container>
<input mz-checkbox
id="timepicker-disabled"
[label]="'Disabled'"
[filledIn]="true"
[(ngModel)]="timepickerDisabled"
type="checkbox">
</mz-checkbox-container>

<p>
Timepicker value: {{ timepickerValue }}
</p>
</div>
</div>
</div>

<div class="section">

<h5 class="light">HTML Structure</h5>

<p>
The input element <b>must be</b> contained inside the <code class="language-markup">mz-timepicker-container</code> component otherwise an error will be shown in the console.
</p>

<app-code-snippet>
&lt;mz-timepicker-container class="col s12">
&lt;i mz-icon-mdi mz-input-prefix
[icon]="'clock'">
&lt;/i>
&lt;input mz-timepicker
[label]="'Lunch time'"
[options]="options"
id="timepicker"
placeholder="Select lunch time"
type="text">
&lt;/mz-timepicker-container>
</app-code-snippet>
</div>

<div class="section">

<h5 class="light">Properties</h5>

<div class="section">

<h6 class="bold">mz-timepicker-container</h6>

<p>
The <code class="language-markup">mz-timepicker-container</code> component can be customized using the following properties.
</p>

<app-properties-table
[properties]="timepickerContainerProperties">
</app-properties-table>
</div>

<div class="section">

<h6 class="bold">mz-timepicker</h6>

<p>
Timepickers can be customized using the following properties on the <code class="language-markup">input</code> element when adding <code class="language-markup">mz-timepicker</code> directive.
</p>

<app-properties-table
[properties]="timepickerProperties">
</app-properties-table>
</div>
</div>
1 change: 1 addition & 0 deletions demo-app/src/app/timepicker/timepicker.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "../../_route-animation-host";
75 changes: 75 additions & 0 deletions demo-app/src/app/timepicker/timepicker.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Component } from '@angular/core';

import { ROUTE_ANIMATION, ROUTE_ANIMATION_HOST } from '../app.routing.animation';
import { IPropertyRow } from '../shared/properties-table/properties-table.component';

@Component({
selector: 'app-timepicker',
templateUrl: './timepicker.component.html',
styleUrls: ['./timepicker.component.scss'],
host: ROUTE_ANIMATION_HOST, // tslint:disable-line:use-host-property-decorator
animations: [ROUTE_ANIMATION],
})
export class TimepickerComponent {
// options example
options: any = {
default: 'now',
fromnow: 0,
twelvehour: true,
donetext: 'OK',
cleartext: 'Clear',
canceltext: 'Cancel',
autoclose: true,
ampmclickable: true,
afterShow: () => alert('AfterShow has been invoked.'),
};

// playground
timepickerValue: string;
timepickerLabel = 'Label';
timepickerPlaceholder = 'Placeholder';
timepickerDisabled = false;
timepickerOptions: any = {
default: 'now',
fromnow: 0,
twelvehour: true,
donetext: 'OK',
cleartext: 'Clear',
canceltext: 'Cancel',
autoclose: true,
ampmclickable: true,
};

// table properties
timepickerContainerProperties: IPropertyRow[] = [
{ name: 'inline',
mandatory: false,
type: 'boolean',
description: 'Show timepicker inline',
defaultValue: 'false',
},
];

timepickerProperties: IPropertyRow[] = [
{ name: 'id',
mandatory: true,
type: 'string',
description: `Id of the input`,
},
{ name: 'label',
mandatory: false,
type: 'string',
description: `Floating label`,
},
{ name: 'options',
mandatory: false,
type: 'Pickadate.TimeOptions',
description: `Timepicker options`,
},
{ name: 'placeholder',
mandatory: false,
type: 'string',
description: `Placeholder text`,
},
];
}
Loading

0 comments on commit 211b6b3

Please sign in to comment.