diff --git a/.angular-cli.json b/.angular-cli.json new file mode 100644 index 0000000..6ac1526 --- /dev/null +++ b/.angular-cli.json @@ -0,0 +1,60 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "project": { + "name": "material-time-control" + }, + "apps": [ + { + "root": "demo", + "outDir": "demo-dist", + "assets": [ + "assets", + "favicon.ico" + ], + "index": "index.html", + "main": "main.ts", + "polyfills": "polyfills.ts", + "test": "test.ts", + "tsconfig": "tsconfig.app.json", + "testTsconfig": "tsconfig.spec.json", + "prefix": "app", + "styles": [ + "styles.scss" + ], + "scripts": [], + "environmentSource": "environments/environment.ts", + "environments": { + "dev": "environments/environment.ts", + "prod": "environments/environment.prod.ts" + } + } + ], + "e2e": { + "protractor": { + "config": "./protractor.conf.js" + } + }, + "lint": [ + { + "project": "src/tsconfig.app.json", + "exclude": "**/node_modules/**" + }, + { + "project": "src/tsconfig.spec.json", + "exclude": "**/node_modules/**" + }, + { + "project": "e2e/tsconfig.e2e.json", + "exclude": "**/node_modules/**" + } + ], + "test": { + "karma": { + "config": "./karma.conf.js" + } + }, + "defaults": { + "styleExt": "scss", + "component": {} + } +} diff --git a/.gitignore b/.gitignore index 198876a..5e1461c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ dist/ node_modules/ +yarn.lock +.vscode \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 00ad71f..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "typescript.tsdk": "node_modules\\typescript\\lib" -} \ No newline at end of file diff --git a/README.md b/README.md index c14a281..1dc3fe6 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,55 @@ # Material Time Control -A simple time picker component using angular/material2 (5.0.0-rc0).
-While this component only shows a 12 hour clock it can easily be extended to show 12/24 mode.
-The main focus here a button beside a normal textbox that opens a dialog to select your hour, minute and meridan. -

-I didn't focus on any responsive layouts as the only place I needed this was desktop but since it leverages flex throughout, it could be modified to change orientation in portrait phone mode. -

-See a demo with this stackblitz -> https://stackblitz.com/edit/angular-material2-time-picker -

+A simple time picker component using angular/material2 (5.0.0-rc0). +While this component only shows a 12 hour clock it can easily be extended to show 12/24 mode. +The main focus here a button beside a normal textbox that opens a dialog to select your hour, minute and meridan. + +See a demo with this stackblitz -> https://stackblitz.com/edit/material-time-control + Enjoy! -![Dialog Hours](https://github.com/SteveDunlap13/MaterialTimeControl/blob/master/src/assets/images/OpenDialog_Hours.png) -![Dialog Minutes](https://github.com/SteveDunlap13/MaterialTimeControl/blob/master/src/assets/images/OpenDialog_Minutes.png) +![Dialog Hours](./demo/assets/OpenDialog_Hours.png?raw=true) +![Dialog Minutes](./demo/assets/OpenDialog_Minutes.png?raw=true) +## Install + +``` +yarn add SteveDunlap13/MaterialTimeControl +``` +or +``` +npm install SteveDunlap13/MaterialTimeControl +``` ## Getting Started -To run this demo, npm install then np start
-webpack-dev-server will fire up on port 3000 +To run this demo, run + +``` +npm install +npm start +``` +or +``` +yarn install +yarn start +``` + +and open http://localhost:4200/ in your browser. + +## Build + +To build the module run + +``` +tsc +``` ### Prerequisites -Required:
-normal angular packages 5.0.1
-"@angular/material": "^5.0.0-rc0"
+Required: +normal angular packages 5.0.1 +"@angular/material": "^5.0.0" "@angular/flex-layout": "^2.0.0-beta.10-4905443" diff --git a/config/helpers.js b/config/helpers.js deleted file mode 100644 index 6d496f1..0000000 --- a/config/helpers.js +++ /dev/null @@ -1,10 +0,0 @@ - -const path = require('path'); -const _root = path.resolve(__dirname, '..'); - -function root(args) { - args = Array.prototype.slice.call(arguments, 0); - return path.join.apply(path, [_root].concat(args)); -} - -exports.root = root; diff --git a/config/webpack.common.js b/config/webpack.common.js deleted file mode 100644 index bed86c2..0000000 --- a/config/webpack.common.js +++ /dev/null @@ -1,93 +0,0 @@ - -const webpack = require('webpack'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const ExtractTextPlugin = require('extract-text-webpack-plugin'); -const helpers = require('./helpers'); -//const DashboardPlugin = require('webpack-dashboard/plugin'); - - - -module.exports = { - - entry: { - 'polyfills': './src/polyfills.ts', - 'vendor': './src/vendor.ts', - 'app': './src/main.ts' - }, - - resolve: { - extensions: ['.ts', '.js'] - }, - - module: { - rules: [ - { - test: /\.ts$/, - loaders: [ - { - loader: 'ng-router-loader', - options: { - /* ng-router-loader options */ - } - }, - { - loader: 'awesome-typescript-loader', - options: { configFileName: helpers.root('', 'tsconfig.json') } - }, - 'angular2-template-loader' - ] - }, - { - test: /\.json/, - use: 'json-loader' - }, - { - test: /\.html$/, - use: 'html-loader' - }, - { - test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, - use: 'file-loader?name=assets/[name].[hash].[ext]' - }, - { - test: /\.css$/, - exclude: helpers.root('src', 'app'), - use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader?sourceMap' }) - }, - { - test: /\.css$/, - include: helpers.root('src', 'app'), - use: 'raw-loader' - }, - { - test: /\.scss$/, - exclude: /node_modules/, - loaders: ['raw-loader', 'sass-loader'] - } - ] - }, - - plugins: [ - - // Workaround for angular/angular#11580 - new webpack.ContextReplacementPlugin( - // The (\\|\/) piece accounts for path separators in *nix and Windows - /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/, - helpers.root('./src'), // location of your src - {} // a map of your routes - ), - - new webpack.optimize.CommonsChunkPlugin({ - name: ['app', 'vendor', 'polyfills'] - }), - - new HtmlWebpackPlugin({ - template: 'src/index.html', - title: 'Output Management' - }) - - //new DashboardPlugin({ - // port: 3000 - //}) - ] -}; \ No newline at end of file diff --git a/config/webpack.dev.js b/config/webpack.dev.js deleted file mode 100644 index 9726c2f..0000000 --- a/config/webpack.dev.js +++ /dev/null @@ -1,25 +0,0 @@ - -const webpackMerge = require('webpack-merge'); -const ExtractTextPlugin = require('extract-text-webpack-plugin'); -const commonConfig = require('./webpack.common.js'); -const helpers = require('./helpers'); - - - -module.exports = webpackMerge(commonConfig, { - - devtool: 'cheap-module-eval-source-map', - - output: { - path: helpers.root('dist'), - publicPath: 'http://localhost:3000/', - filename: '[name].js', - chunkFilename: '[id].chunk.js' - }, - - devServer: { - historyApiFallback: true, - compress: true, - stats: 'minimal' - } -}); \ No newline at end of file diff --git a/demo/app/app.component.html b/demo/app/app.component.html new file mode 100644 index 0000000..0c005a3 --- /dev/null +++ b/demo/app/app.component.html @@ -0,0 +1,23 @@ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demo/app/app.component.scss b/demo/app/app.component.scss new file mode 100644 index 0000000..544db4d --- /dev/null +++ b/demo/app/app.component.scss @@ -0,0 +1,24 @@ +.container { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + position: relative; + margin: 1em; +} + +.demo-form { + padding: 4em; +} + +.mat-card { + padding: 0; + max-width: 600px; + margin: 3rem auto; +} \ No newline at end of file diff --git a/demo/app/app.component.ts b/demo/app/app.component.ts new file mode 100644 index 0000000..a94c1af --- /dev/null +++ b/demo/app/app.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'] +}) +export class AppComponent { + private exportTime = {hour: 7, minute: 15, meriden: 'PM'}; +} diff --git a/demo/app/app.module.ts b/demo/app/app.module.ts new file mode 100644 index 0000000..e9f72eb --- /dev/null +++ b/demo/app/app.module.ts @@ -0,0 +1,27 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NgModule } from '@angular/core'; + + +import { AppComponent } from './app.component'; + +import { MaterialTimeControlModule } from '../../src/material-time-control.module'; + +import { + MatCardModule, +} from '@angular/material'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ + BrowserModule, + BrowserAnimationsModule, + MaterialTimeControlModule, + MatCardModule + ], + providers: [], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/demo/assets/.gitkeep b/demo/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/demo/assets/OpenDialog_Hours.png b/demo/assets/OpenDialog_Hours.png new file mode 100644 index 0000000..1d1e798 Binary files /dev/null and b/demo/assets/OpenDialog_Hours.png differ diff --git a/demo/assets/OpenDialog_Minutes.png b/demo/assets/OpenDialog_Minutes.png new file mode 100644 index 0000000..3e21987 Binary files /dev/null and b/demo/assets/OpenDialog_Minutes.png differ diff --git a/demo/assets/timepicker.png b/demo/assets/timepicker.png new file mode 100644 index 0000000..6231fba Binary files /dev/null and b/demo/assets/timepicker.png differ diff --git a/demo/environments/environment.prod.ts b/demo/environments/environment.prod.ts new file mode 100644 index 0000000..3612073 --- /dev/null +++ b/demo/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true +}; diff --git a/demo/environments/environment.ts b/demo/environments/environment.ts new file mode 100644 index 0000000..b7f639a --- /dev/null +++ b/demo/environments/environment.ts @@ -0,0 +1,8 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. + +export const environment = { + production: false +}; diff --git a/src/assets/images/favicons/favicon.ico b/demo/favicon.ico similarity index 100% rename from src/assets/images/favicons/favicon.ico rename to demo/favicon.ico diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..c4fbcae --- /dev/null +++ b/demo/index.html @@ -0,0 +1,15 @@ + + + + + MaterialTimeControl + + + + + + + + + + diff --git a/demo/main.ts b/demo/main.ts new file mode 100644 index 0000000..91ec6da --- /dev/null +++ b/demo/main.ts @@ -0,0 +1,12 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.log(err)); diff --git a/demo/polyfills.ts b/demo/polyfills.ts new file mode 100644 index 0000000..d68672f --- /dev/null +++ b/demo/polyfills.ts @@ -0,0 +1,66 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following for the Reflect API. */ +// import 'core-js/es6/reflect'; + + +/** Evergreen browsers require these. **/ +// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. +import 'core-js/es7/reflect'; + + +/** + * Required to support Web Animations `@angular/platform-browser/animations`. + * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + + + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/demo/styles.scss b/demo/styles.scss new file mode 100644 index 0000000..550b41f --- /dev/null +++ b/demo/styles.scss @@ -0,0 +1,2 @@ +/* You can add global styles to this file, and also import other style files */ +@import "~@angular/material/prebuilt-themes/indigo-pink.css"; \ No newline at end of file diff --git a/demo/test.ts b/demo/test.ts new file mode 100644 index 0000000..cd612ee --- /dev/null +++ b/demo/test.ts @@ -0,0 +1,32 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/proxy.js'; +import 'zone.js/dist/sync-test'; +import 'zone.js/dist/jasmine-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. +declare const __karma__: any; +declare const require: any; + +// Prevent Karma from running prematurely. +__karma__.loaded = function () {}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); +// Finally, start Karma to run the tests. +__karma__.start(); diff --git a/demo/tsconfig.app.json b/demo/tsconfig.app.json new file mode 100644 index 0000000..39ba8db --- /dev/null +++ b/demo/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "baseUrl": "./", + "module": "es2015", + "types": [] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ] +} diff --git a/demo/tsconfig.spec.json b/demo/tsconfig.spec.json new file mode 100644 index 0000000..63d89ff --- /dev/null +++ b/demo/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "baseUrl": "./", + "module": "commonjs", + "target": "es5", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/demo/typings.d.ts b/demo/typings.d.ts new file mode 100644 index 0000000..ef5c7bd --- /dev/null +++ b/demo/typings.d.ts @@ -0,0 +1,5 @@ +/* SystemJS module definition */ +declare var module: NodeModule; +interface NodeModule { + id: string; +} diff --git a/package.json b/package.json index 09c3c2c..712e49c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,16 @@ { + "name": "material-time-control", + "version": "0.1.0", + "license": "MIT", + "private": false, + "main": "material-time-control.module.ts", "scripts": { - "start": "webpack-dev-server --color --inline --progress --port 3000" + "ng": "ng", + "start": "ng serve ./demo", + "build": "ng build", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e" }, "dependencies": { "@angular/animations": "^5.0.1", @@ -22,6 +32,14 @@ "zone.js": "0.8.18" }, "devDependencies": { + "@angular/cli": "1.6.0", + "@angular/compiler-cli": "^5.0.0", + "@angular/language-service": "^5.0.0", + "codelyzer": "^4.0.1", + "protractor": "~5.1.2", + "ts-node": "~3.2.0", + "tslint": "~5.7.0", + "typescript": "~2.4.2", "@types/node": "^8.0.51", "angular2-load-children-loader": "^0.2.1", "angular2-template-loader": "^0.6.0", @@ -43,8 +61,6 @@ "rimraf": "^2.6.2", "sass-loader": "^6.0.6", "style-loader": "^0.19.0", - "tslint": "^5.8.0", - "typescript": "^2.6.1", "webpack": "^3.8.1", "webpack-dashboard": "^1.0.2", "webpack-dev-server": "^2.9.4", diff --git a/protractor.conf.js b/protractor.conf.js new file mode 100644 index 0000000..7ee3b5e --- /dev/null +++ b/protractor.conf.js @@ -0,0 +1,28 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 11000, + specs: [ + './e2e/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome' + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function() {} + }, + onPrepare() { + require('ts-node').register({ + project: 'e2e/tsconfig.e2e.json' + }); + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; diff --git a/src/app/app.component.html b/src/app/app.component.html deleted file mode 100644 index 53ef968..0000000 --- a/src/app/app.component.html +++ /dev/null @@ -1,4 +0,0 @@ - -
- -
\ No newline at end of file diff --git a/src/app/app.component.scss b/src/app/app.component.scss deleted file mode 100644 index 307537b..0000000 --- a/src/app/app.component.scss +++ /dev/null @@ -1,20 +0,0 @@ - -html, -body, -material-app, -article { - margin: 0; - width: 100%; - height: 100%; -} - -body { - font-family: 'Roboto', Verdana, Gotham, sans-serif; - * { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } - overflow: hidden; - margin: 0; - padding: 0; -} diff --git a/src/app/app.component.ts b/src/app/app.component.ts deleted file mode 100644 index 4e98c12..0000000 --- a/src/app/app.component.ts +++ /dev/null @@ -1,14 +0,0 @@ - -import { Component, ViewEncapsulation } from '@angular/core'; - - - -@Component({ - selector: 'app', - templateUrl: './app.component.html', - styleUrls: ['./css/groot-material.scss'], - encapsulation: ViewEncapsulation.None -}) -export class AppComponent { - -} diff --git a/src/app/app.module.ts b/src/app/app.module.ts deleted file mode 100644 index fd9482a..0000000 --- a/src/app/app.module.ts +++ /dev/null @@ -1,67 +0,0 @@ - -import { NgModule, APP_INITIALIZER } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterModule } from '@angular/router'; -import { CommonModule } from '@angular/common'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { FlexLayoutModule } from '@angular/flex-layout'; - - -import 'hammerjs'; - -import { ValyrianMaterialModule } from './material.module'; - -import { AppRoutes } from './app.routes' - -import { AppComponent } from './app.component'; - -import { - DashboardComponent, - WMatTimePickerComponent, - WTimeDialogComponent, - WClockComponent -} from './ui'; - - - -@NgModule({ - imports: [ - - BrowserModule, - FlexLayoutModule, - BrowserAnimationsModule, - ValyrianMaterialModule, - CommonModule, - FormsModule, - ReactiveFormsModule, - - RouterModule.forRoot(AppRoutes) - ], - - declarations: [ - - AppComponent, - DashboardComponent, - WMatTimePickerComponent, - WTimeDialogComponent, - WClockComponent - ], - - exports: [ - - ], - - providers: [ - - ], - - entryComponents: [ - - WTimeDialogComponent - ], - - bootstrap: [AppComponent] -}) - -export class AppModule { } diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts deleted file mode 100644 index 37a6a55..0000000 --- a/src/app/app.routes.ts +++ /dev/null @@ -1,19 +0,0 @@ - -import { Routes } from '@angular/router' - -import { - DashboardComponent, -} from './ui'; - - - -export const AppRoutes: Routes = [ - - { - path: 'dashboard', - component: DashboardComponent - }, - - { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, - { path: '**', redirectTo: '/dashboard', pathMatch: 'full' } -] diff --git a/src/app/css/groot-material.scss b/src/app/css/groot-material.scss deleted file mode 100644 index a854cb7..0000000 --- a/src/app/css/groot-material.scss +++ /dev/null @@ -1,121 +0,0 @@ - -@import '~@angular/material/theming'; - - -$blue_palette: ( - 50 : #e8f2fb, - 100 : #c6ddf5, - 200 : #a0c7ef, - 300 : #7ab1e8, - 400 : #5ea0e3, - 500 : #418fde, - 600 : #3b87da, - 700 : #327cd5, - 800 : #2a72d1, - 900 : #1c60c8, - A100 : #fefeff, - A200 : #cbdeff, - A400 : #98bdff, - A700 : #7fadff, - contrast: ( - 50 : #000000, - 100 : #000000, - 200 : #000000, - 300 : #000000, - 400 : #000000, - 500 : #000000, - 600 : #ffffff, - 700 : #ffffff, - 800 : #ffffff, - 900 : #ffffff, - A100 : #000000, - A200 : #000000, - A400 : #000000, - A700 : #000000, - ) -); - -$green_palette: ( - 50 : #eff7e4, - 100 : #d7ecbc, - 200 : #bcdf90, - 300 : #a1d263, - 400 : #8cc841, - 500 : #78be20, - 600 : #70b81c, - 700 : #65af18, - 800 : #5ba713, - 900 : #48990b, - A100 : #ddffc8, - A200 : #bdff95, - A400 : #9dff62, - A700 : #8eff48, - contrast: ( - 50 : #000000, - 100 : #000000, - 200 : #000000, - 300 : #000000, - 400 : #000000, - 500 : #000000, - 600 : #000000, - 700 : #000000, - 800 : #ffffff, - 900 : #ffffff, - A100 : #000000, - A200 : #000000, - A400 : #000000, - A700 : #000000, - ) -); - -$orange_palette: ( - 50 : #fdf5e0, - 100 : #fbe5b3, - 200 : #f9d480, - 300 : #f6c34d, - 400 : #f4b626, - 500 : #f2a900, - 600 : #f0a200, - 700 : #ee9800, - 800 : #ec8f00, - 900 : #e87e00, - A100 : #ffffff, - A200 : #ffeddc, - A400 : #ffd3a9, - A700 : #ffc690, - contrast: ( - 50 : #000000, - 100 : #000000, - 200 : #000000, - 300 : #000000, - 400 : #000000, - 500 : #000000, - 600 : #000000, - 700 : #000000, - 800 : #000000, - 900 : #000000, - A100 : #000000, - A200 : #000000, - A400 : #000000, - A700 : #000000, - ) -); - - -@include mat-core(); - - -// main app styling -@import "../app.component.scss"; - - -// Default light theme -$primary-palette: mat-palette($blue_palette); -$accent-palette: mat-palette($orange_palette); -$warn-palette: mat-palette($mat-red); -$highlight-palette: mat-palette($green_palette); - -$valyrian-theme: mat-light-theme($primary-palette, $accent-palette, $warn-palette); - -// add our valyrian theme to angular material -@include angular-material-theme($valyrian-theme); diff --git a/src/app/material.module.ts b/src/app/material.module.ts deleted file mode 100644 index c676420..0000000 --- a/src/app/material.module.ts +++ /dev/null @@ -1,25 +0,0 @@ - -import { NgModule } from '@angular/core'; - - -import { - MatButtonModule, MatButtonToggleModule, - MatDialogModule, MatIconModule, MatInputModule, - MatSelectModule, MatToolbarModule, - MatFormFieldModule -} from '@angular/material'; - - -@NgModule({ - exports: [ - MatButtonModule, - MatButtonToggleModule, - MatDialogModule, - MatFormFieldModule, - MatIconModule, - MatInputModule, - MatSelectModule, - MatToolbarModule - ], -}) -export class ValyrianMaterialModule { } diff --git a/src/app/ui/dashboard/dashboard.component.html b/src/app/ui/dashboard/dashboard.component.html deleted file mode 100644 index 58e8951..0000000 --- a/src/app/ui/dashboard/dashboard.component.html +++ /dev/null @@ -1,7 +0,0 @@ -
- -
- -
- -
\ No newline at end of file diff --git a/src/app/ui/dashboard/dashboard.component.scss b/src/app/ui/dashboard/dashboard.component.scss deleted file mode 100644 index b6fdf2e..0000000 --- a/src/app/ui/dashboard/dashboard.component.scss +++ /dev/null @@ -1,23 +0,0 @@ - - -.container { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -ms-flex-direction: row; - flex-direction: row; - -webkit-box-pack: center; - -ms-flex-pack: center; - justify-content: center; - position: relative; - margin: 1em; -} - -.demo-form { - padding: 4em; - background: white; - -webkit-box-shadow: 5px 5px 5px 0px rgba(0, 0, 0, 0.4); - box-shadow: 5px 5px 5px 0px rgba(0, 0, 0, 0.4); -} diff --git a/src/app/ui/dashboard/dashboard.component.ts b/src/app/ui/dashboard/dashboard.component.ts deleted file mode 100644 index 47440b2..0000000 --- a/src/app/ui/dashboard/dashboard.component.ts +++ /dev/null @@ -1,13 +0,0 @@ - -import { Component } from '@angular/core'; - - - -@Component({ - selector: 'dashboard', - styleUrls: ['./dashboard.component.scss'], - templateUrl: './dashboard.component.html' -}) -export class DashboardComponent { - -} diff --git a/src/app/ui/index.ts b/src/app/ui/index.ts deleted file mode 100644 index 04d0c89..0000000 --- a/src/app/ui/index.ts +++ /dev/null @@ -1,6 +0,0 @@ - -export * from './dashboard/dashboard.component'; -export * from './time-control/w-mat-timepicker.component'; -export * from './time-control/w-time-dialog.component'; -export * from './time-control/w-clock.component'; - diff --git a/src/app/ui/time-control/w-clock.component.html b/src/app/ui/time-control/w-clock.component.html deleted file mode 100644 index 551b346..0000000 --- a/src/app/ui/time-control/w-clock.component.html +++ /dev/null @@ -1,21 +0,0 @@ - -
-
- - - - - - - - - - - -
-
\ No newline at end of file diff --git a/src/app/ui/time-control/w-clock.component.scss b/src/app/ui/time-control/w-clock.component.scss deleted file mode 100644 index cdf1f2f..0000000 --- a/src/app/ui/time-control/w-clock.component.scss +++ /dev/null @@ -1,201 +0,0 @@ - -.w-clock { - width: 200px; - height: 200px; - border-radius: 50%; - cursor: pointer; - padding: 24px; - background: #ededed; -} - -.w-clock .w-clock-container { - width: 100%; - height: 100%; - position: relative; - display: block; -} - -.w-clock .w-clock-center { - height: 6px; - width: 6px; - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - margin: auto; - border-radius: 50%; -} - -.w-clock .w-pointer { - width: 1px; - height: 50%; - position: absolute; - left: 0; - right: 0; - bottom: 0; - margin: 0 auto; - padding: 0; - -webkit-transform-origin: top center; - transform-origin: top center; - z-index: 0; - pointer-events: none; -} - -.w-clock .mat-button { - box-shadow: none !important; - background-color: transparent; - display: block; - position: absolute; - min-height: 32px; - width: 32px; - height: 32px; - font-size: 12px; - line-height: 32px; - margin: 0; - padding: 0; - -webkit-transform: translate(-50%, -50%); - transform: translate(-50%, -50%); -} - -.w-clock .mat-button /deep/span { - padding: 0 !important; - margin: 0 !important; -} - -.w-clock .w-clock-selected { - position: absolute; - bottom: -19px; - left: -19px; - min-width: 0; - min-height: 0; - pointer-events: none; -} - - - - -.w-clock-deg0 { - top: 0%; - left: 50%; -} - -.w-clock-deg15 { - top: 1.70370869%; - left: 62.94095226%; -} - -.w-clock-deg30 { - top: 6.69872981%; - left: 75%; -} - -.w-clock-deg45 { - top: 14.64466094%; - left: 85.35533905%; -} - -.w-clock-deg60 { - top: 25%; - left: 93.30127019%; -} - -.w-clock-deg75 { - top: 37.05904774%; - left: 98.29629131%; -} - -.w-clock-deg90 { - top: 50%; - left: 100%; -} - -.w-clock-deg105 { - top: 62.94095226%; - left: 98.29629131%; -} - -.w-clock-deg120 { - top: 75%; - left: 93.30127019%; -} - -.w-clock-deg135 { - top: 85.35533906%; - left: 85.35533906%; -} - -.w-clock-deg150 { - top: 93.30127019%; - left: 75%; -} - -.w-clock-deg165 { - top: 98.29629131%; - left: 62.94095226%; -} - -.w-clock-deg180 { - top: 100%; - left: 50%; -} - -.w-clock-deg195 { - top: 98.29629131%; - left: 37.05904774%; -} - -.w-clock-deg210 { - top: 93.30127019%; - left: 25%; -} - -.w-clock-deg225 { - top: 85.35533906%; - left: 14.64466094%; -} - -.w-clock-deg240 { - top: 75%; - left: 6.69872981%; -} - -.w-clock-deg255 { - top: 62.94095226%; - left: 1.703708686%; -} - -.w-clock-deg270 { - top: 50%; - left: 0%; -} - -.w-clock-deg285 { - top: 37.05904774%; - left: 1.703708686%; -} - -.w-clock-deg300 { - top: 25%; - left: 6.69872981%; -} - -.w-clock-deg315 { - top: 14.64466094%; - left: 14.64466094%; -} - -.w-clock-deg330 { - top: 6.69872981%; - left: 25%; -} - -.w-clock-deg345 { - top: 1.703708686%; - left: 37.05904774%; -} - -.w-clock-deg360 { - top: 0%; - left: 50%; -} \ No newline at end of file diff --git a/src/app/ui/time-control/w-mat-timepicker.component.ts b/src/app/ui/time-control/w-mat-timepicker.component.ts deleted file mode 100644 index cd008cf..0000000 --- a/src/app/ui/time-control/w-mat-timepicker.component.ts +++ /dev/null @@ -1,56 +0,0 @@ - -import { Component } from '@angular/core'; -import { MatDialog, MatDialogRef } from '@angular/material'; - -import { WTimeDialogComponent } from './w-time-dialog.component'; - -import * as moment from 'moment'; - - - -@Component({ - selector: 'w-mat-timepicker', - styleUrls: ['./w-mat-timepicker.component.scss'], - templateUrl: './w-mat-timepicker.component.html' -}) -export class WMatTimePickerComponent { - - private hour = 10; - private minute = 25; - private meridien = 'PM'; - - - constructor(private dialog: MatDialog) { } - - - private getTime(): string { - - return `${this.hour}:${this.minute} ${this.meridien}`; - } - - private showPicker($event) { - - let dialogRef = this.dialog.open(WTimeDialogComponent, { - data: { - hour: this.hour, - minute: this.minute, - meriden: this.meridien - } - }); - - dialogRef.afterClosed().subscribe(result => { - - // result will be update userTime object or -1 or undefined (closed dialog w/o clicking cancel) - if (result === undefined) { - return; - } else if (result !== -1) { - - this.hour = result.hour; - this.minute = result.minute; - this.meridien = result.meriden; - } - }); - - return false; - } -} diff --git a/src/app/ui/time-control/w-time-dialog.component.html b/src/app/ui/time-control/w-time-dialog.component.html deleted file mode 100644 index 8404061..0000000 --- a/src/app/ui/time-control/w-time-dialog.component.html +++ /dev/null @@ -1,27 +0,0 @@ - -
- - - -
- {{ userTime.hour }}: - {{ formatMinute() }} -
-
- AM - PM -
- -
- -
- - -
- - -
-
- -
- diff --git a/src/app/ui/time-control/w-time-dialog.component.scss b/src/app/ui/time-control/w-time-dialog.component.scss deleted file mode 100644 index b094105..0000000 --- a/src/app/ui/time-control/w-time-dialog.component.scss +++ /dev/null @@ -1,132 +0,0 @@ -.w-timepicker { - display: flex; - flex-direction: row; - max-height: 100%; - height: 310px; -} - -.w-timepicker .w-timepicker-time-container { - padding: 15px; - margin-right: 30px; - width: 160px; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -.w-timepicker .w-timepicker-time-container.mat-toolbar-single-row { - height: 100%; -} - -.w-timepicker .w-timepicker-selected-time { - font-size: 3rem; - display: flex; -} - -.w-timepicker .w-timepicker-selected-ampm { - display: flex; - flex-direction: column; - align-content: center; - align-items: center; - padding-top: .5em; -} - -.w-timepicker-selected-time>span, -.w-timepicker-selected-ampm>span { - outline: 0; - opacity: 0.5; -} - -.w-timepicker-selected-time>span:not(.active), -.w-timepicker-selected-ampm>span:not(.active) { - cursor: pointer; -} - -.w-timepicker-selected-time>span.active, -.w-timepicker-selected-ampm>span.active { - opacity: 1; -} - -.w-animate-next { - opacity: 0; - -webkit-transform: translate3d(50%, 0, 1px); - transform: translate3d(50%, 0, 1px); -} - -.w-animate-next-remove { - -webkit-transition: all 0.5s cubic-bezier(0.35, 0, 0.25, 1); - transition: all 0.5s cubic-bezier(0.35, 0, 0.25, 1); - opacity: 0; - -webkit-transform: translate3d(50%, 0, 1px); - transform: translate3d(50%, 0, 1px); -} - -.w-animate-next-remove-active { - opacity: 1; - -webkit-transform: translate3d(0, 0, 1px); - transform: translate3d(0, 0, 1px); -} - -.w-animate-prev { - opacity: 0; - -webkit-transform: translate3d(-50%, 0, 1px); - transform: translate3d(-50%, 0, 1px); -} - -.w-animate-prev-remove { - -webkit-transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1); - transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1); - opacity: 0; - -webkit-transform: translate3d(-50%, 0, 1px); - transform: translate3d(-50%, 0, 1px); -} - -.w-animate-prev-remove-active { - opacity: 1; - -webkit-transform: translate3d(0, 0, 1px); - transform: translate3d(0, 0, 1px); -} - -@-webkit-keyframes w-animation-bounce { - from { - opacity: 0; - -webkit-transform: scale(0.95); - transform: scale(0.95); - } - 70% { - opacity: 1; - -webkit-transform: scale(1.05); - transform: scale(1.05); - } - to { - -webkit-transform: scale(1); - transform: scale(1); - } -} - -@keyframes w-animation-bounce { - from { - opacity: 0; - -webkit-transform: scale(0.95); - transform: scale(0.95); - } - 70% { - opacity: 1; - -webkit-transform: scale(1.05); - transform: scale(1.05); - } - to { - -webkit-transform: scale(1); - transform: scale(1); - } -} - -.w-animation-zoom.ng-enter { - -webkit-transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1); - transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1); - -webkit-animation-duration: 0.3s; - animation-duration: 0.3s; - -webkit-animation-name: w-animation-bounce; - animation-name: w-animation-bounce; -} \ No newline at end of file diff --git a/src/app/ui/time-control/w-time-dialog.component.ts b/src/app/ui/time-control/w-time-dialog.component.ts deleted file mode 100644 index f3523da..0000000 --- a/src/app/ui/time-control/w-time-dialog.component.ts +++ /dev/null @@ -1,62 +0,0 @@ - -import { Component, Inject, ChangeDetectorRef } from '@angular/core'; -import { MatDialog, MatDialogRef } from '@angular/material'; -import { MAT_DIALOG_DATA } from '@angular/material'; - -import { CLOCK_TYPE } from './w-clock.component'; - - - -@Component({ - styleUrls: ['./w-time-dialog.component.scss'], - templateUrl: './w-time-dialog.component.html' -}) -export class WTimeDialogComponent { - - private userTime: any = {}; - private VIEW_HOURS = CLOCK_TYPE.HOURS; - private VIEW_MINUTES = CLOCK_TYPE.MINUTES; - private currentView: CLOCK_TYPE = this.VIEW_HOURS; - - - - constructor( - @Inject(MAT_DIALOG_DATA) private userTimeData, - private dialogRef: MatDialogRef, - private cdRef: ChangeDetectorRef) { - - this.userTime = userTimeData; - } - - - private formatMinute(): string { - - if (this.userTime.minute < 10) { - - return '0' + String(this.userTime.minute); - } else { - - return String(this.userTime.minute); - } - } - - private setCurrentView(type: CLOCK_TYPE) { - - this.currentView = type; - } - - private setMeridien(m: string) { - - this.userTime.meriden = m; - } - - private revert() { - - this.dialogRef.close(-1); - } - - private submit() { - - this.dialogRef.close(this.userTime); - } -} diff --git a/src/assets/images/DemoTimeControl.png b/src/assets/images/DemoTimeControl.png deleted file mode 100644 index 9496144..0000000 Binary files a/src/assets/images/DemoTimeControl.png and /dev/null differ diff --git a/src/assets/images/OpenDialog_Hours.png b/src/assets/images/OpenDialog_Hours.png deleted file mode 100644 index 521b5d3..0000000 Binary files a/src/assets/images/OpenDialog_Hours.png and /dev/null differ diff --git a/src/assets/images/OpenDialog_Minutes.png b/src/assets/images/OpenDialog_Minutes.png deleted file mode 100644 index ba125e3..0000000 Binary files a/src/assets/images/OpenDialog_Minutes.png and /dev/null differ diff --git a/src/index.html b/src/index.html deleted file mode 100644 index 5309510..0000000 --- a/src/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - Material Time Control Demo - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main.ts b/src/main.ts deleted file mode 100644 index 97e416a..0000000 --- a/src/main.ts +++ /dev/null @@ -1,6 +0,0 @@ - -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; - -import { AppModule } from './app/app.module'; - -platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/src/material-time-control.module.ts b/src/material-time-control.module.ts new file mode 100644 index 0000000..6124a44 --- /dev/null +++ b/src/material-time-control.module.ts @@ -0,0 +1,54 @@ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FlexLayoutModule } from '@angular/flex-layout'; + +import { + MatButtonModule, MatButtonToggleModule, + MatDialogModule, MatIconModule, MatInputModule, + MatSelectModule, MatToolbarModule, + MatFormFieldModule +} from '@angular/material'; + +import { + WMatTimePickerComponent, + WTimeDialogComponent, + WClockComponent, + WTimeComponent +} from './time-control'; + + +@NgModule({ + declarations: [ + WMatTimePickerComponent, + WTimeDialogComponent, + WClockComponent, + WTimeComponent, + ], + imports: [ + MatButtonModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatSelectModule, + MatToolbarModule, + CommonModule, + FlexLayoutModule, + ], + exports: [ + WMatTimePickerComponent, + WTimeDialogComponent, + WClockComponent, + WTimeComponent, + ], + entryComponents: [ + WMatTimePickerComponent, + WTimeDialogComponent, + WClockComponent, + WTimeComponent, + ] +}) + +export class MaterialTimeControlModule { } diff --git a/src/polyfills.ts b/src/polyfills.ts deleted file mode 100644 index 7d2761d..0000000 --- a/src/polyfills.ts +++ /dev/null @@ -1,12 +0,0 @@ - -import 'core-js/es6'; -import 'core-js/es7/reflect'; -require('zone.js/dist/zone'); - -if (process.env.ENV === 'production') { - // Production -} else { - // Development and test - Error['stackTraceLimit'] = Infinity; - require('zone.js/dist/long-stack-trace-zone'); -} diff --git a/src/time-control/index.ts b/src/time-control/index.ts new file mode 100644 index 0000000..63ac215 --- /dev/null +++ b/src/time-control/index.ts @@ -0,0 +1,5 @@ +export * from './w-mat-timepicker/w-mat-timepicker.component'; +export * from './w-time-dialog/w-time-dialog.component'; +export * from './w-clock/w-clock.component'; +export * from './w-time/w-time.component'; + diff --git a/src/time-control/w-clock/w-clock.component.html b/src/time-control/w-clock/w-clock.component.html new file mode 100644 index 0000000..5eba2e2 --- /dev/null +++ b/src/time-control/w-clock/w-clock.component.html @@ -0,0 +1,24 @@ +
+
+
+ + + + + + + + + + +
+ +
+ +
+
+
\ No newline at end of file diff --git a/src/time-control/w-clock/w-clock.component.scss b/src/time-control/w-clock/w-clock.component.scss new file mode 100644 index 0000000..fb95acc --- /dev/null +++ b/src/time-control/w-clock/w-clock.component.scss @@ -0,0 +1,189 @@ +.w-clock-wrapper { + height: 100%; + padding: 0 24px; + .w-clock { + width: 200px; + height: 200px; + border-radius: 50%; + cursor: pointer; + padding: 24px; + background: #ededed; + .w-clock-container { + width: 100%; + height: 100%; + position: relative; + display: block; + } + .w-clock-center { + height: 6px; + width: 6px; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; + border-radius: 50%; + } + .w-pointer { + box-shadow: none; + width: 1px; + height: 50%; + position: absolute; + left: 0; + right: 0; + bottom: 0; + margin: 0 auto; + padding: 0; + transform-origin: top center; + transition: transform 200ms; + z-index: 0; + pointer-events: none; + } + .w-clock-step { + display: block; + position: absolute; + transform: translate(-50%, -50%); + transition: transform 200ms; + .mat-mini-fab { + box-shadow: none; + background-color: transparent; + } + } + .w-clock-selected { + position: absolute; + bottom: -19px; + left: -19px; + min-width: 0; + min-height: 0; + pointer-events: none; + box-shadow: none; + cursor: none; + } + } +} + +.w-clock-deg0 { + top: 0%; + left: 50%; +} + +.w-clock-deg15 { + top: 1.70370869%; + left: 62.94095226%; +} + +.w-clock-deg30 { + top: 6.69872981%; + left: 75%; +} + +.w-clock-deg45 { + top: 14.64466094%; + left: 85.35533905%; +} + +.w-clock-deg60 { + top: 25%; + left: 93.30127019%; +} + +.w-clock-deg75 { + top: 37.05904774%; + left: 98.29629131%; +} + +.w-clock-deg90 { + top: 50%; + left: 100%; +} + +.w-clock-deg105 { + top: 62.94095226%; + left: 98.29629131%; +} + +.w-clock-deg120 { + top: 75%; + left: 93.30127019%; +} + +.w-clock-deg135 { + top: 85.35533906%; + left: 85.35533906%; +} + +.w-clock-deg150 { + top: 93.30127019%; + left: 75%; +} + +.w-clock-deg165 { + top: 98.29629131%; + left: 62.94095226%; +} + +.w-clock-deg180 { + top: 100%; + left: 50%; +} + +.w-clock-deg195 { + top: 98.29629131%; + left: 37.05904774%; +} + +.w-clock-deg210 { + top: 93.30127019%; + left: 25%; +} + +.w-clock-deg225 { + top: 85.35533906%; + left: 14.64466094%; +} + +.w-clock-deg240 { + top: 75%; + left: 6.69872981%; +} + +.w-clock-deg255 { + top: 62.94095226%; + left: 1.703708686%; +} + +.w-clock-deg270 { + top: 50%; + left: 0%; +} + +.w-clock-deg285 { + top: 37.05904774%; + left: 1.703708686%; +} + +.w-clock-deg300 { + top: 25%; + left: 6.69872981%; +} + +.w-clock-deg315 { + top: 14.64466094%; + left: 14.64466094%; +} + +.w-clock-deg330 { + top: 6.69872981%; + left: 25%; +} + +.w-clock-deg345 { + top: 1.703708686%; + left: 37.05904774%; +} + +.w-clock-deg360 { + top: 0%; + left: 50%; +} \ No newline at end of file diff --git a/src/app/ui/time-control/w-clock.component.ts b/src/time-control/w-clock/w-clock.component.ts similarity index 66% rename from src/app/ui/time-control/w-clock.component.ts rename to src/time-control/w-clock/w-clock.component.ts index cefad1b..a1d2164 100644 --- a/src/app/ui/time-control/w-clock.component.ts +++ b/src/time-control/w-clock/w-clock.component.ts @@ -1,56 +1,66 @@ import { Component, OnInit, Input, Output, EventEmitter, OnChanges } from '@angular/core'; - +// Current type to show export enum CLOCK_TYPE { HOURS = 1, MINUTES = 2 } +export type TimeFormat = 12 | 24; + +export interface ITime { + hour: number; + minute: number; + meriden: 'PM' | 'AM'; +}; @Component({ selector: 'w-clock', styleUrls: ['./w-clock.component.scss'], templateUrl: './w-clock.component.html' }) -export class WClockComponent implements OnChanges { +export class WClockComponent implements OnChanges, OnInit { + + @Input() public userTime: ITime; + @Output() public userTimeChange: EventEmitter = new EventEmitter(); + + @Input() public currentView: CLOCK_TYPE; + @Output() public viewChange = new EventEmitter(); - @Input() userTime: any = {}; - @Input() currentView: CLOCK_TYPE; - @Output() viewChange = new EventEmitter(); + @Input() public color: string; - private STEP_DEG = 360 / 12; - private steps = []; + public steps = new Array(); private selectedTimePart; + private format: TimeFormat = 12; + private STEP_DEG: number; - ngOnChanges() { + ngOnInit() { + + } + ngOnChanges() { + this.STEP_DEG = 360 / this.format; this.setupUI(); } private setupUI() { - - this.steps = []; - + this.steps = new Array(); switch (this.currentView) { - case CLOCK_TYPE.HOURS: - - for (let i = 1; i <= 12; i++) { - + for (let i = 1; i <= this.format; i++) { this.steps.push(i); this.selectedTimePart = this.userTime.hour || 0; - if (this.selectedTimePart > 12) { + if (this.selectedTimePart > this.format) { - this.selectedTimePart -= 12; + this.selectedTimePart -= this.format; } } break; case CLOCK_TYPE.MINUTES: - for (let i = 5; i <= 55; i += 5) { this.steps.push(i); } @@ -60,13 +70,12 @@ export class WClockComponent implements OnChanges { } } - private getPointerStyle() { - + public getPointerStyle() { let divider = 1; switch (this.currentView) { case CLOCK_TYPE.HOURS: - divider = 12; + divider = this.format; break; case CLOCK_TYPE.MINUTES: @@ -81,7 +90,7 @@ export class WClockComponent implements OnChanges { degrees = Math.round(this.userTime.minute * (360 / divider)) - 180; } - let style = { + const style = { '-webkit-transform': 'rotate(' + degrees + 'deg)', '-ms-transform': 'rotate(' + degrees + 'deg)', 'transform': 'rotate(' + degrees + 'deg)' @@ -91,8 +100,7 @@ export class WClockComponent implements OnChanges { } private getTimeValueClass(step: number, index: number) { - - let classes = 'mat-button mat-raised w-clock-deg' + (this.STEP_DEG * (index + 1)); + let classes = 'w-clock-step w-clock-deg' + (this.STEP_DEG * (index + 1)); if (this.selectedTimePart === step) { @@ -115,5 +123,6 @@ export class WClockComponent implements OnChanges { // auto switch to hours this.viewChange.emit(CLOCK_TYPE.HOURS); } + this.userTimeChange.emit(this.userTime) } } diff --git a/src/app/ui/time-control/w-mat-timepicker.component.html b/src/time-control/w-mat-timepicker/w-mat-timepicker.component.html similarity index 64% rename from src/app/ui/time-control/w-mat-timepicker.component.html rename to src/time-control/w-mat-timepicker/w-mat-timepicker.component.html index 6304c21..a12f74d 100644 --- a/src/app/ui/time-control/w-mat-timepicker.component.html +++ b/src/time-control/w-mat-timepicker/w-mat-timepicker.component.html @@ -7,11 +7,12 @@ + class="timeInput" + placeholder="Selec time" + id="time_Control" + name="time_Control" + [value]="time" + > diff --git a/src/app/ui/time-control/w-mat-timepicker.component.scss b/src/time-control/w-mat-timepicker/w-mat-timepicker.component.scss similarity index 100% rename from src/app/ui/time-control/w-mat-timepicker.component.scss rename to src/time-control/w-mat-timepicker/w-mat-timepicker.component.scss diff --git a/src/time-control/w-mat-timepicker/w-mat-timepicker.component.ts b/src/time-control/w-mat-timepicker/w-mat-timepicker.component.ts new file mode 100644 index 0000000..e74140b --- /dev/null +++ b/src/time-control/w-mat-timepicker/w-mat-timepicker.component.ts @@ -0,0 +1,70 @@ + +import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core'; +import { MatDialog } from '@angular/material'; + +import { WTimeDialogComponent } from '../w-time-dialog/w-time-dialog.component'; +import { ITime } from '../w-clock/w-clock.component'; + +@Component({ + selector: 'w-mat-timepicker', + styleUrls: ['./w-mat-timepicker.component.scss'], + templateUrl: './w-mat-timepicker.component.html' +}) + +export class WMatTimePickerComponent implements OnInit { + + @Input() userTime: ITime; + @Output() userTimeChange: EventEmitter = new EventEmitter(); + + @Input() color: string; + + constructor(private dialog: MatDialog) {} + + ngOnInit() { + if (!this.userTime) { + this.userTime = { + hour: 10, + minute: 25, + meriden: 'PM' + } + } + } + + private get time(): string { + if (!this.userTime) { + return ''; + } + return `${this.userTime.hour}:${this.userTime.minute} ${this.userTime.meriden}`; + } + + + public showPicker($event) { + + const dialogRef = this.dialog.open(WTimeDialogComponent, { + data: { + time: { + hour: this.userTime.hour, + minute: this.userTime.minute, + meriden: this.userTime.meriden + }, + color: this.color + } + }); + + dialogRef.afterClosed() + .subscribe((result: ITime | -1) => { + // result will be update userTime object or -1 or undefined (closed dialog w/o clicking cancel) + if (result === undefined) { + return; + } else if (result !== -1) { + this.userTime = result; + this.emituserTimeChange(); + } + }); + return false; + } + + private emituserTimeChange() { + this.userTimeChange.emit(this.userTime); + } +} diff --git a/src/time-control/w-time-dialog/w-time-dialog.component.html b/src/time-control/w-time-dialog/w-time-dialog.component.html new file mode 100644 index 0000000..73db8e0 --- /dev/null +++ b/src/time-control/w-time-dialog/w-time-dialog.component.html @@ -0,0 +1,5 @@ + +
+ +
+ diff --git a/src/time-control/w-time-dialog/w-time-dialog.component.scss b/src/time-control/w-time-dialog/w-time-dialog.component.scss new file mode 100644 index 0000000..7bd641c --- /dev/null +++ b/src/time-control/w-time-dialog/w-time-dialog.component.scss @@ -0,0 +1,5 @@ +.w-timepicker-dialog { + padding: 0; + margin: -24px; + width: calc(100% + 48px); +} \ No newline at end of file diff --git a/src/time-control/w-time-dialog/w-time-dialog.component.ts b/src/time-control/w-time-dialog/w-time-dialog.component.ts new file mode 100644 index 0000000..d21c239 --- /dev/null +++ b/src/time-control/w-time-dialog/w-time-dialog.component.ts @@ -0,0 +1,36 @@ + +import { Component, Inject, Input } from '@angular/core'; +import { MatDialogRef } from '@angular/material'; +import { MAT_DIALOG_DATA } from '@angular/material'; + +import { CLOCK_TYPE, ITime } from '../w-clock/w-clock.component'; + +@Component({ + styleUrls: ['./w-time-dialog.component.scss'], + templateUrl: './w-time-dialog.component.html' +}) +export class WTimeDialogComponent { + + public userTime: ITime; + private VIEW_HOURS = CLOCK_TYPE.HOURS; + private VIEW_MINUTES = CLOCK_TYPE.MINUTES; + private currentView: CLOCK_TYPE = this.VIEW_HOURS; + + constructor( + @Inject(MAT_DIALOG_DATA) private data: {time: ITime, color: string}, + @Inject(MAT_DIALOG_DATA) public color: string, + private dialogRef: MatDialogRef, + ) { + this.userTime = data.time; + this.color = data.color; + console.log('this.color', this.color); + } + + public revert() { + this.dialogRef.close(-1); + } + + public submit() { + this.dialogRef.close(this.userTime); + } +} diff --git a/src/time-control/w-time/w-time.component.html b/src/time-control/w-time/w-time.component.html new file mode 100644 index 0000000..12c4f65 --- /dev/null +++ b/src/time-control/w-time/w-time.component.html @@ -0,0 +1,23 @@ +
+ + +
+ {{ userTime.hour }}: + {{ formatMinute() }} +
+
+ AM + PM +
+ +
+ +
+ + +
+ + +
+
+
\ No newline at end of file diff --git a/src/time-control/w-time/w-time.component.scss b/src/time-control/w-time/w-time.component.scss new file mode 100644 index 0000000..2318017 --- /dev/null +++ b/src/time-control/w-time/w-time.component.scss @@ -0,0 +1,155 @@ +:host { + display: block; +} + +.w-time { + max-height: 100%; + min-height: 350px; + height: 350px; + .w-timepicker-time-container { + padding: 15px; + min-width: 160px; + width: 160px; + &.mat-toolbar-single-row { + height: 100%; + } + } + .w-timepicker-selected-time { + font-size: 3.5rem; + font-weight: 400; + display: flex; + } + .w-timepicker-selected-ampm { + font-size: 1rem; + line-height: 1.3rem; + padding-top: 2rem; + } + .w-time-content { + width: 100%; + height: 100%; + padding: 6px; + w-clock { + padding: 12px 0; + height: calc(100% - 58px); + } + } + + &.vertical-time { + height: auto; + .w-timepicker-time-container { + min-width: auto; + width: 100%; + height: 100px; + + .w-timepicker-selected-time { + + } + + .w-timepicker-selected-ampm { + padding: 0 12px; + } + } + } +} + +.w-timepicker-selected-time > span, .w-timepicker-selected-ampm > span { + outline: 0; + opacity: 0.5; +} + +.w-timepicker-selected-time > span:not(.active), .w-timepicker-selected-ampm > span:not(.active) { + cursor: pointer; +} + +.w-timepicker-selected-time > span.active, .w-timepicker-selected-ampm > span.active { + opacity: 1; +} + +.w-animate-next { + opacity: 0; + -webkit-transform: translate3d(50%, 0, 1px); + transform: translate3d(50%, 0, 1px); +} + +.w-animate-next-remove { + -webkit-transition: all 0.5s cubic-bezier(0.35, 0, 0.25, 1); + transition: all 0.5s cubic-bezier(0.35, 0, 0.25, 1); + opacity: 0; + -webkit-transform: translate3d(50%, 0, 1px); + transform: translate3d(50%, 0, 1px); +} + +.w-animate-next-remove-active { + opacity: 1; + -webkit-transform: translate3d(0, 0, 1px); + transform: translate3d(0, 0, 1px); +} + +.w-animate-prev { + opacity: 0; + -webkit-transform: translate3d(-50%, 0, 1px); + transform: translate3d(-50%, 0, 1px); +} + +.w-animate-prev-remove { + -webkit-transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1); + transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1); + opacity: 0; + -webkit-transform: translate3d(-50%, 0, 1px); + transform: translate3d(-50%, 0, 1px); +} + +.w-animate-prev-remove-active { + opacity: 1; + -webkit-transform: translate3d(0, 0, 1px); + transform: translate3d(0, 0, 1px); +} + +@-webkit-keyframes w-animation-bounce { + from { + opacity: 0; + -webkit-transform: scale(0.95); + transform: scale(0.95); + } + + 70% { + opacity: 1; + -webkit-transform: scale(1.05); + transform: scale(1.05); + } + + to { + -webkit-transform: scale(1); + transform: scale(1); + } +} + + +@keyframes w-animation-bounce { + from { + opacity: 0; + -webkit-transform: scale(0.95); + transform: scale(0.95); + } + + 70% { + opacity: 1; + -webkit-transform: scale(1.05); + transform: scale(1.05); + } + + to { + -webkit-transform: scale(1); + transform: scale(1); + } +} + + +.w-animation-zoom.ng-enter { + -webkit-transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1); + transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1); + -webkit-animation-duration: 0.3s; + animation-duration: 0.3s; + -webkit-animation-name: w-animation-bounce; + animation-name: w-animation-bounce; +} \ No newline at end of file diff --git a/src/time-control/w-time/w-time.component.spec.ts b/src/time-control/w-time/w-time.component.spec.ts new file mode 100644 index 0000000..16ea8bb --- /dev/null +++ b/src/time-control/w-time/w-time.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { WTimeComponent } from './w-time.component'; + +describe('WTimeComponent', () => { + let component: WTimeComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ WTimeComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(WTimeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/time-control/w-time/w-time.component.ts b/src/time-control/w-time/w-time.component.ts new file mode 100644 index 0000000..04973ca --- /dev/null +++ b/src/time-control/w-time/w-time.component.ts @@ -0,0 +1,75 @@ +import { Component, Input, Output, OnInit, Inject, EventEmitter } from '@angular/core'; + +import { CLOCK_TYPE, ITime } from '../w-clock/w-clock.component'; + +@Component({ + selector: 'w-time', + templateUrl: './w-time.component.html', + styleUrls: ['./w-time.component.scss'] +}) +export class WTimeComponent implements OnInit { + + @Input() userTime: ITime; + @Output() userTimeChange: EventEmitter = new EventEmitter(); + + @Input() revertLabel: string; + @Input() submitLabel: string; + + @Output() onRevert: EventEmitter = new EventEmitter(); + @Output() onSubmit: EventEmitter = new EventEmitter(); + + @Input() color: string; + + public VIEW_HOURS = CLOCK_TYPE.HOURS; + public VIEW_MINUTES = CLOCK_TYPE.MINUTES; + public currentView: CLOCK_TYPE = this.VIEW_HOURS; + + constructor() {} + + ngOnInit() { + if (!this.userTime) { + this.userTime = { + hour: 6, + minute: 0, + meriden: 'PM' + }; + } + + if (!this.revertLabel) { + this.revertLabel = 'Cancel' + } + + if (!this.submitLabel) { + this.submitLabel = 'Okay' + } + } + + public formatMinute(): string { + if (this.userTime.minute < 10) { + return '0' + String(this.userTime.minute); + } else { + return String(this.userTime.minute); + } + } + + public setCurrentView(type: CLOCK_TYPE) { + this.currentView = type; + } + + public setMeridien(m: 'PM' | 'AM') { + this.userTime.meriden = m; + } + + public revert() { + this.onRevert.emit(); + } + + public submit() { + this.onSubmit.emit(this.userTime); + } + + public emituserTimeChange(event) { + this.userTimeChange.emit(this.userTime); + } + +} diff --git a/src/vendor.ts b/src/vendor.ts deleted file mode 100644 index d770c8f..0000000 --- a/src/vendor.ts +++ /dev/null @@ -1,14 +0,0 @@ - -// Angular -import '@angular/platform-browser'; -import '@angular/platform-browser-dynamic'; -import '@angular/core'; -import '@angular/common'; -import '@angular/router'; - -// RxJS -import 'rxjs'; - -// Other vendors for example jQuery, Lodash or Bootstrap -// You can import js, ts, css, sass, ... - diff --git a/tsconfig.json b/tsconfig.json index 43822d1..a6c016b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,19 +1,19 @@ { + "compileOnSave": false, "compilerOptions": { - "target": "es2017", - "module": "commonjs", - "moduleResolution": "node", + "outDir": "./dist/out-tsc", "sourceMap": true, - "allowJs": true, + "declaration": false, + "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, - "noImplicitAny": false, - "noStrictGenericChecks": true, - "lib": ["es7", "dom"], - "suppressImplicitAnyIndexErrors": true, - "typeRoots": ["node_modules/@types/"], - "types": [ - "node" + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "dom" ] } } diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 8aa6130..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,2 +0,0 @@ - -module.exports = require('./config/webpack.dev.js'); \ No newline at end of file