├── .codeclimate.yml ├── .editorconfig ├── .ember-cli ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .template-lintrc.js ├── .travis.yml ├── .watchmanconfig ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── addon ├── .gitkeep ├── components │ └── ui-calendar.js └── templates │ └── components │ └── ui-calendar.hbs ├── app ├── .gitkeep └── components │ └── ui-calendar.js ├── config ├── ember-try.js ├── environment.js └── release.js ├── ember-cli-build.js ├── index.js ├── package.json ├── testem.js ├── tests ├── dummy │ ├── app │ │ ├── app.js │ │ ├── components │ │ │ ├── .gitkeep │ │ │ ├── controls-segment.js │ │ │ └── ui-calendar-moment.js │ │ ├── controllers │ │ │ ├── .gitkeep │ │ │ ├── clear-button-examples.js │ │ │ ├── custom-trigger-examples.js │ │ │ ├── index.js │ │ │ ├── moment-examples.js │ │ │ └── range-examples.js │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── index.html │ │ ├── models │ │ │ └── .gitkeep │ │ ├── resolver.js │ │ ├── router.js │ │ ├── routes │ │ │ ├── .gitkeep │ │ │ ├── clear-button-examples.js │ │ │ ├── custom-trigger-examples.js │ │ │ ├── index.js │ │ │ ├── moment-examples.js │ │ │ └── range-examples.js │ │ ├── styles │ │ │ └── app.css │ │ └── templates │ │ │ ├── application.hbs │ │ │ ├── clear-button-examples.hbs │ │ │ ├── components │ │ │ ├── .gitkeep │ │ │ └── controls-segment.hbs │ │ │ ├── custom-trigger-examples.hbs │ │ │ ├── index.hbs │ │ │ ├── moment-examples.hbs │ │ │ └── range-examples.hbs │ ├── config │ │ ├── environment.js │ │ ├── optional-features.json │ │ └── targets.js │ └── public │ │ ├── ember-logo.svg │ │ └── robots.txt ├── helpers │ └── .gitkeep ├── index.html ├── integration │ ├── .gitkeep │ └── components │ │ └── ui-calendar-test.js ├── test-helper.js └── unit │ └── .gitkeep ├── vendor ├── .gitkeep ├── ember-semantic-ui-calendar.css └── ember-semantic-ui-calendar.min.css ├── yarn.lock └── yuidoc.json /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | languages: 2 | JavaScript: true 3 | exclude_paths: 4 | - "tests/*" 5 | - "config/*" 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.hbs] 17 | insert_final_newline = false 18 | 19 | [*.{diff,md}] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # unconventional js 2 | /blueprints/*/files/ 3 | /vendor/ 4 | 5 | # compiled output 6 | /dist/ 7 | /tmp/ 8 | 9 | # dependencies 10 | /bower_components/ 11 | /node_modules/ 12 | 13 | # misc 14 | /coverage/ 15 | !.* 16 | 17 | # ember-try 18 | /.node_modules.ember-try/ 19 | /bower.json.ember-try 20 | /package.json.ember-try 21 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | ecmaVersion: 2017, 5 | sourceType: 'module' 6 | }, 7 | plugins: [ 8 | 'ember' 9 | ], 10 | extends: [ 11 | 'eslint:recommended', 12 | 'plugin:ember/recommended' 13 | ], 14 | env: { 15 | browser: true 16 | }, 17 | rules: { 18 | 'ember/avoid-leaking-state-in-ember-objects': 0, 19 | 'ember/closure-actions': 0 20 | }, 21 | overrides: [ 22 | // node files 23 | { 24 | files: [ 25 | '.eslintrc.js', 26 | '.template-lintrc.js', 27 | 'ember-cli-build.js', 28 | 'index.js', 29 | 'testem.js', 30 | 'blueprints/*/index.js', 31 | 'config/**/*.js', 32 | 'tests/dummy/config/**/*.js' 33 | ], 34 | excludedFiles: [ 35 | 'addon/**', 36 | 'addon-test-support/**', 37 | 'app/**', 38 | 'tests/dummy/app/**' 39 | ], 40 | parserOptions: { 41 | sourceType: 'script', 42 | ecmaVersion: 2015 43 | }, 44 | env: { 45 | browser: false, 46 | node: true 47 | }, 48 | plugins: ['node'], 49 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, { 50 | // add your custom rules and overrides for node files here 51 | }) 52 | } 53 | ] 54 | }; 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist/ 5 | /tmp/ 6 | 7 | # dependencies 8 | /bower_components/ 9 | /node_modules/ 10 | 11 | # misc 12 | /.env* 13 | /.pnp* 14 | /.sass-cache 15 | /connect.lock 16 | /coverage/ 17 | /libpeerconnection.log 18 | /npm-debug.log* 19 | /testem.log 20 | /yarn-error.log 21 | 22 | # ember-try 23 | /.node_modules.ember-try/ 24 | /bower.json.ember-try 25 | /package.json.ember-try 26 | 27 | # IDEs 28 | /nbproject 29 | /.vscode 30 | /jsconfig.json 31 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /bower_components/ 7 | 8 | # misc 9 | /.bowerrc 10 | /.editorconfig 11 | /.ember-cli 12 | /.env* 13 | /.eslintignore 14 | /.eslintrc.js 15 | /.gitignore 16 | /.template-lintrc.js 17 | /.travis.yml 18 | /.watchmanconfig 19 | /bower.json 20 | /config/ember-try.js 21 | /ember-cli-build.js 22 | /testem.js 23 | /tests/ 24 | /yarn.lock 25 | .gitkeep 26 | /nbproject 27 | 28 | # ember-try 29 | /.node_modules.ember-try/ 30 | /bower.json.ember-try 31 | /package.json.ember-try 32 | -------------------------------------------------------------------------------- /.template-lintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | extends: 'recommended', 5 | rules: { 6 | 'no-invalid-interactive': false, 7 | 'attribute-indentation': { 'open-invocation-max-len': 120, 'indentation': 2 } 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | # we recommend testing addons with the same minimum supported node version as Ember CLI 5 | # so that your addon works for all apps 6 | - "8" 7 | 8 | sudo: false 9 | dist: trusty 10 | 11 | addons: 12 | chrome: stable 13 | 14 | cache: 15 | yarn: true 16 | 17 | env: 18 | global: 19 | # See https://git.io/vdao3 for details. 20 | - JOBS=1 21 | 22 | matrix: 23 | - EMBER_TRY_SCENARIO=ember-lts-2.18 24 | - EMBER_TRY_SCENARIO=ember-lts-3.4 25 | - EMBER_TRY_SCENARIO=ember-lts-3.8 26 | - EMBER_TRY_SCENARIO=ember-release 27 | - EMBER_TRY_SCENARIO=ember-beta 28 | - EMBER_TRY_SCENARIO=ember-canary 29 | 30 | matrix: 31 | fast_finish: true 32 | allow_failures: 33 | - env: EMBER_TRY_SCENARIO=ember-beta 34 | - env: EMBER_TRY_SCENARIO=ember-canary 35 | 36 | install: 37 | - yarn install --non-interactive 38 | 39 | script: 40 | - yarn run lint:js 41 | - yarn run lint:hbs 42 | # Usually, it's ok to finish the test scenario without reverting 43 | # to the addon's original dependency state, skipping "cleanup". 44 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO --skip-cleanup 45 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 3.0.0 (2019-05-10) 4 | 5 | * [[#77](https://github.com/quantosobra/ember-semantic-ui-calendar/pull/77)] Update to ember-cli-babel 7.x 6 | 7 | ## 2.1.0 (2019-02-06) 8 | 9 | * [[#58](https://github.com/quantosobra/ember-semantic-ui-calendar/pull/58)] Add support for custom calendar trigger 10 | 11 | ## 2.0.0 (2018-12-05) 12 | 13 | * [[#7](https://github.com/quantosobra/ember-semantic-ui-calendar/pull/17)] Update Ember CLI 14 | 15 | ## 1.0.0 (2018-04-20) 16 | 17 | * [[#11](https://github.com/quantosobra/ember-semantic-ui-calendar/pull/11)] Update Semantic UI 18 | 19 | ## 0.2.0 (2017-06-14) 20 | 21 | * [[#6](https://github.com/quantosobra/ember-semantic-ui-calendar/pull/6)] Add support for keyboard events 22 | * [[#7](https://github.com/quantosobra/ember-semantic-ui-calendar/pull/7)] Add support for focus and blur events 23 | 24 | ## 0.1.0 (2017-05-24) 25 | 26 | * [[#1](https://github.com/quantosobra/ember-semantic-ui-calendar/pull/1)] Add option to show a button to clear the selected date 27 | 28 | ## 0.0.3 (2017-02-22) 29 | 30 | * Add lodash.merge as dependency instead of devDependency 31 | 32 | ## 0.0.2 (2017-01-26) 33 | 34 | * Add missing method in default blueprint 35 | 36 | ## 0.0.1 (2017-01-26) 37 | 38 | * Initial release 39 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2019 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-semantic-ui-calendar 2 | 3 | [![Build Status](https://travis-ci.org/quantosobra/ember-semantic-ui-calendar.svg)](https://travis-ci.org/quantosobra/ember-semantic-ui-calendar) 4 | [![npm version](https://badge.fury.io/js/ember-semantic-ui-calendar.svg)](http://badge.fury.io/js/ember-semantic-ui-calendar) 5 | [![Ember Observer Score](http://emberobserver.com/badges/ember-semantic-ui-calendar.svg)](http://emberobserver.com/addons/ember-semantic-ui-calendar) 6 | [![Code Climate](https://codeclimate.com/github/quantosobra/ember-semantic-ui-calendar/badges/gpa.svg)](https://codeclimate.com/github/quantosobra/ember-semantic-ui-calendar) 7 | [![Dependency Status](https://david-dm.org/quantosobra/ember-semantic-ui-calendar.svg)](https://david-dm.org/quantosobra/ember-semantic-ui-calendar) 8 | 9 | ## Features 10 | 11 | This addon integrates [Semantic UI Calendar](https://github.com/mdehoog/Semantic-UI-Calendar) into Ember. 12 | 13 | ## Compatibility 14 | 15 | * Ember.js v2.18 or above 16 | * Ember CLI v2.13 or above 17 | 18 | ## Installation 19 | 20 | ``` 21 | ember install ember-semantic-ui-calendar 22 | ``` 23 | 24 | ## Helpful Links 25 | 26 | - ### [Live Demo](http://quantosobra.github.io/ember-semantic-ui-calendar) 27 | 28 | - ### [Changelog](CHANGELOG.md) 29 | 30 | ## Looking for help? 31 | 32 | If it is a bug [please open an issue on GitHub](https://github.com/quantosobra/ember-semantic-ui-calendar/issues). 33 | 34 | ## Usage 35 | 36 | You can see usage examples in the [demo page](http://quantosobra.github.io/ember-semantic-ui-calendar). 37 | 38 | ## Development 39 | 40 | To release and publish a new version, use the commands: 41 | 42 | ``` 43 | ember release (--major|--minor|--patch) 44 | yarn publish 45 | ``` 46 | 47 | ## License 48 | 49 | This project is developed at [QuantoSobra](https://www.quantosobra.com.br) and licensed under the MIT license. 50 | See the [LICENSE.md](LICENSE.md) file for the full license text. 51 | 52 | QuantoSobra © 2017-2019 53 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/addon/.gitkeep -------------------------------------------------------------------------------- /addon/components/ui-calendar.js: -------------------------------------------------------------------------------- 1 | import Component from '@ember/component'; 2 | import { computed } from '@ember/object'; 3 | import { isEmpty } from '@ember/utils'; 4 | import Base from 'semantic-ui-ember/mixins/base'; 5 | import { invokeAction } from 'ember-invoke-action'; 6 | import layout from '../templates/components/ui-calendar'; 7 | 8 | /** 9 | * @class UiCalendar 10 | * @extends Ember.Component 11 | * @namespace Semantic 12 | * @see https://github.com/mdehoog/Semantic-UI-Calendar 13 | */ 14 | export default Component.extend(Base, { 15 | layout, 16 | 17 | module: 'calendar', 18 | classNames: ['ui', 'calendar'], 19 | ignorableAttrs: ['date', 'icon', 'placeholder'], 20 | 21 | /** 22 | * Name of an icon to display in the input. You can pass `false` to not show an icon. 23 | * 24 | * @property icon 25 | * @type String|Boolean 26 | * @default 'calendar' 27 | * @public 28 | * @see http://semantic-ui.com/elements/icon.html 29 | */ 30 | icon: 'calendar', 31 | 32 | /** 33 | * Placeholder for the input. 34 | * 35 | * @property placeholder 36 | * @type String 37 | * @default '' 38 | * @public 39 | */ 40 | placeholder: '', 41 | 42 | /** 43 | * If the user can clear the value using a clear button inside the input. 44 | * 45 | * @property allowClear 46 | * @type Boolean 47 | * @default false 48 | * @public 49 | */ 50 | allowClear: false, 51 | 52 | /** 53 | * Name of the icon to use as a button the clear the input value. 54 | * 55 | * @property clearIcon 56 | * @type String 57 | * @default 'clear' 58 | * @public 59 | */ 60 | clearIcon: 'remove', 61 | 62 | /** 63 | * @property showClearButton 64 | * @type Boolean 65 | * @private 66 | */ 67 | showClearButton: computed('date', 'allowClear', function() { 68 | let { date, allowClear } = this.getProperties('date', 'allowClear'); 69 | let showClearButton = (allowClear && !isEmpty(date)); 70 | return showClearButton; 71 | }), 72 | 73 | /** 74 | * Class names used in .ui.input element to configure icon visibility. 75 | * 76 | * @property inputIconsClassNames 77 | * @type String 78 | * @private 79 | */ 80 | inputIconsClassNames: computed('icon', 'showClearButton', function() { 81 | let { icon, showClearButton } = this.getProperties('icon', 'showClearButton'); 82 | let hasLeftIcon = !isEmpty(icon) && icon !== false; 83 | let classNames = []; 84 | 85 | if (hasLeftIcon) { 86 | classNames.push('left'); 87 | } 88 | 89 | if (showClearButton) { 90 | classNames.push('right'); 91 | } 92 | 93 | if (hasLeftIcon || showClearButton) { 94 | classNames.push('icon'); 95 | } 96 | 97 | return classNames.join(' '); 98 | }), 99 | 100 | /** 101 | * Action executed when the user presses the `enter` key when the input is focused. 102 | * 103 | * @event onEnter 104 | * @param {Event} event 105 | */ 106 | onEnter: null, 107 | 108 | /** 109 | * Action executed when the user presses the `escape` key when the input is focused. 110 | * 111 | * @event onEscape 112 | * @param {Event} event 113 | */ 114 | onEscape: null, 115 | 116 | /** 117 | * Action executed when the user presses the any key when the input is focused. 118 | * 119 | * @event onKeyDown 120 | * @param {Event} event 121 | */ 122 | onKeyDown: null, 123 | 124 | /** 125 | * Action executed when the date input is focused. 126 | * 127 | * @event onFocusIn 128 | * @param {Event} event 129 | */ 130 | onFocusIn: null, 131 | 132 | /** 133 | * Action executed when the date input looses focus. 134 | * 135 | * @event onFocusOut 136 | * @param {Event} event 137 | */ 138 | onFocusOut: null, 139 | 140 | didInitSemantic() { 141 | this._super(...arguments); 142 | 143 | let date = this.get('date'); 144 | if (date) { 145 | this.$().calendar('set date', date); 146 | } 147 | }, 148 | 149 | didUpdateAttrs() { 150 | this._super(...arguments); 151 | this.execute('set date', this.get('date'), true, false); 152 | }, 153 | 154 | actions: { 155 | handleInputFocus(event) { 156 | invokeAction(this, 'onFocusIn', event); 157 | }, 158 | 159 | handleInputBlur(event) { 160 | invokeAction(this, 'onFocusOut', event); 161 | }, 162 | 163 | handleInputKeyDown(event) { 164 | invokeAction(this, 'onKeyDown', event); 165 | 166 | switch (event.keyCode) { 167 | case 13: 168 | invokeAction(this, 'onEnter', event); 169 | break; 170 | case 27: 171 | invokeAction(this, 'onEscape', event); 172 | break; 173 | } 174 | } 175 | } 176 | }); 177 | -------------------------------------------------------------------------------- /addon/templates/components/ui-calendar.hbs: -------------------------------------------------------------------------------- 1 | {{#if hasBlock}} 2 | {{yield (action "execute")}} 3 | {{else}} 4 |
5 | {{#if icon}} 6 | 7 | {{/if}} 8 | 15 | {{#if showClearButton}} 16 | 17 | {{/if}} 18 |
19 | {{/if}} 20 | -------------------------------------------------------------------------------- /app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/app/.gitkeep -------------------------------------------------------------------------------- /app/components/ui-calendar.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-semantic-ui-calendar/components/ui-calendar'; -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const getChannelURL = require('ember-source-channel-url'); 4 | 5 | module.exports = function() { 6 | return Promise.all([ 7 | getChannelURL('release'), 8 | getChannelURL('beta'), 9 | getChannelURL('canary') 10 | ]).then((urls) => { 11 | return { 12 | useYarn: true, 13 | scenarios: [ 14 | { 15 | name: 'ember-lts-2.16', 16 | npm: { 17 | devDependencies: { 18 | 'ember-source': '~2.16.0' 19 | } 20 | } 21 | }, 22 | { 23 | name: 'ember-lts-2.18', 24 | npm: { 25 | devDependencies: { 26 | 'ember-source': '~2.18.0' 27 | } 28 | } 29 | }, 30 | { 31 | name: 'ember-lts-3.4', 32 | npm: { 33 | devDependencies: { 34 | 'ember-source': '~3.4.0' 35 | } 36 | } 37 | }, 38 | { 39 | name: 'ember-lts-3.8', 40 | npm: { 41 | devDependencies: { 42 | 'ember-source': '~3.8.0' 43 | } 44 | } 45 | }, 46 | { 47 | name: 'ember-release', 48 | npm: { 49 | devDependencies: { 50 | 'ember-source': urls[0] 51 | } 52 | } 53 | }, 54 | { 55 | name: 'ember-beta', 56 | npm: { 57 | devDependencies: { 58 | 'ember-source': urls[1] 59 | } 60 | } 61 | }, 62 | { 63 | name: 'ember-canary', 64 | npm: { 65 | devDependencies: { 66 | 'ember-source': urls[2] 67 | } 68 | } 69 | } 70 | ] 71 | }; 72 | }); 73 | }; 74 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /config/release.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | var execSync = require('child_process').execSync; 3 | 4 | // For details on each option run `ember help release` 5 | module.exports = { 6 | publish: true, 7 | afterPush: function(project, versions) { 8 | runCommand('ember github-pages:commit --message "Released ' + versions.next + '"'); 9 | runCommand('git push origin gh-pages:gh-pages'); 10 | } 11 | }; 12 | 13 | function runCommand(command) { 14 | console.log('running: ' + command); 15 | var output = execSync(command, { encoding: 'utf8' }); 16 | console.log(output); 17 | } 18 | -------------------------------------------------------------------------------- /ember-cli-build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 4 | const path = require('path'); 5 | 6 | module.exports = function(defaults) { 7 | let app = new EmberAddon(defaults, { 8 | // Add options here 9 | snippetSearchPaths: ['tests/dummy/app'] 10 | }); 11 | 12 | /* 13 | This build file specifies the options for the dummy test app of this 14 | addon, located in `/tests/dummy` 15 | This build file does *not* influence how the addon or the app using it 16 | behave. You most likely want to be modifying `./index.js` or app's build file 17 | */ 18 | 19 | const semanticFontsSource = 'node_modules/semantic-ui-css/themes/default/assets/fonts'; 20 | const semanticFontsDestination = 'assets/themes/default/assets/fonts'; 21 | const fontExtensions = ['.eot', '.svg', '.ttf', '.woff', '.woff2']; 22 | for (let ext of fontExtensions) { 23 | app.import(path.join(semanticFontsSource, 'brand-icons' + ext), { destDir: semanticFontsDestination }); 24 | app.import(path.join(semanticFontsSource, 'outline-icons' + ext), { destDir: semanticFontsDestination }); 25 | } 26 | 27 | return app.toTree(); 28 | }; 29 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const merge = require('lodash.merge'); 5 | 6 | let defaults = { 7 | import: { 8 | css: true, 9 | javascript: true 10 | }, 11 | source: { 12 | css: 'node_modules/semantic-ui-calendar/dist', 13 | javascript: 'node_modules/semantic-ui-calendar/dist' 14 | } 15 | }; 16 | 17 | module.exports = { 18 | name: require('./package').name, 19 | 20 | included: function (app) { 21 | let options = merge({}, defaults, app.options['ember-semantic-ui-calendar']); 22 | 23 | if (options.import.css) { 24 | app.import({ 25 | development: path.join(options.source.css, 'calendar.css'), 26 | production: path.join(options.source.css, 'calendar.min.css') 27 | }); 28 | 29 | app.import({ 30 | development: 'vendor/ember-semantic-ui-calendar.css', 31 | production: 'vendor/ember-semantic-ui-calendar.min.css' 32 | }); 33 | } 34 | 35 | if (options.import.javascript) { 36 | app.import({ 37 | development: path.join(options.source.javascript, 'calendar.js'), 38 | production: path.join(options.source.javascript, 'calendar.min.js') 39 | }); 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-semantic-ui-calendar", 3 | "version": "3.0.0", 4 | "description": "Semantic UI Calendar component for Ember.", 5 | "keywords": [ 6 | "ember-addon", 7 | "semantic-ui", 8 | "calendar", 9 | "datepicker" 10 | ], 11 | "repository": { 12 | "type": "git", 13 | "url": "git@github.com:quantosobra/ember-semantic-ui-calendar.git" 14 | }, 15 | "license": "MIT", 16 | "author": "QuantoSobra ", 17 | "directories": { 18 | "doc": "doc", 19 | "test": "tests" 20 | }, 21 | "scripts": { 22 | "build": "ember build", 23 | "lint:hbs": "ember-template-lint .", 24 | "lint:js": "eslint .", 25 | "start": "ember serve", 26 | "test": "ember test", 27 | "test:all": "ember try:each" 28 | }, 29 | "dependencies": { 30 | "ember-cli-babel": "^7.7.3", 31 | "ember-cli-htmlbars": "^3.0.0", 32 | "ember-invoke-action": "^1.5.1", 33 | "lodash.merge": "^4.6.0", 34 | "semantic-ui-calendar": "^0.0.8" 35 | }, 36 | "devDependencies": { 37 | "@ember/jquery": "^0.6.0", 38 | "@ember/optional-features": "^1.0.0", 39 | "broccoli-asset-rev": "^3.0.0", 40 | "ember-ajax": "^5.0.0", 41 | "ember-cli": "~3.12.0", 42 | "ember-cli-code-coverage": "0.4.2", 43 | "ember-cli-dependency-checker": "^3.1.0", 44 | "ember-cli-eslint": "^5.0.0", 45 | "ember-cli-github-pages": "0.2.2", 46 | "ember-cli-htmlbars-inline-precompile": "^3.0.0", 47 | "ember-cli-inject-live-reload": "^2.0.1", 48 | "ember-cli-moment-shim": "3.7.1", 49 | "ember-cli-release": "^1.0.0-beta.2", 50 | "ember-cli-sri": "^2.1.1", 51 | "ember-cli-template-lint": "^1.0.0-beta.1", 52 | "ember-cli-uglify": "^3.0.0", 53 | "ember-cli-yuidoc": "0.8.8", 54 | "ember-code-snippet": "2.4.0", 55 | "ember-disable-prototype-extensions": "^1.1.3", 56 | "ember-export-application-global": "^2.0.0", 57 | "ember-load-initializers": "^2.0.0", 58 | "ember-maybe-import-regenerator": "^0.1.6", 59 | "ember-moment": "8.0.0", 60 | "ember-native-dom-helpers": "0.6.3", 61 | "ember-qunit": "^4.2.0", 62 | "ember-resolver": "^5.0.1", 63 | "ember-source": "~3.12.0", 64 | "ember-source-channel-url": "^2.0.1", 65 | "ember-try": "^1.0.0", 66 | "eslint-plugin-ember": "^7.0.0", 67 | "eslint-plugin-node": "^10.0.0", 68 | "loader.js": "^4.7.0", 69 | "qunit-dom": "^0.9.0", 70 | "semantic-ui-ember": "^3.0.0", 71 | "yuidoc-theme-quantosobra": "github:quantosobra/yuidoc-theme-quantosobra" 72 | }, 73 | "peerDependencies": { 74 | "semantic-ui-ember": "^3.0.0" 75 | }, 76 | "engines": { 77 | "node": "6.* || 8.* || >= 10.*" 78 | }, 79 | "ember-addon": { 80 | "configPath": "tests/dummy/config", 81 | "versionCompatibility": { 82 | "ember": ">=2.16.0" 83 | }, 84 | "demoURL": "http://quantosobra.github.io/ember-semantic-ui-calendar" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /testem.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_page: 'tests/index.html?hidepassed', 3 | disable_watching: true, 4 | launch_in_ci: [ 5 | 'Chrome' 6 | ], 7 | launch_in_dev: [ 8 | 'Chrome' 9 | ], 10 | browser_args: { 11 | Chrome: { 12 | ci: [ 13 | // --no-sandbox is needed when running Chrome inside a container 14 | process.env.CI ? '--no-sandbox' : null, 15 | '--headless', 16 | '--disable-gpu', 17 | '--disable-dev-shm-usage', 18 | '--disable-software-rasterizer', 19 | '--mute-audio', 20 | '--remote-debugging-port=0', 21 | '--window-size=1440,900' 22 | ].filter(Boolean) 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Application from '@ember/application'; 2 | import Resolver from './resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from './config/environment'; 5 | 6 | const App = Application.extend({ 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix, 9 | Resolver 10 | }); 11 | 12 | loadInitializers(App, config.modulePrefix); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/tests/dummy/app/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/components/controls-segment.js: -------------------------------------------------------------------------------- 1 | import Component from '@ember/component'; 2 | import layout from '../templates/components/controls-segment'; 3 | 4 | export default Component.extend({ 5 | layout, 6 | classNames: ['ui', 'segments'], 7 | 8 | date: null, 9 | reset: null 10 | }); 11 | -------------------------------------------------------------------------------- /tests/dummy/app/components/ui-calendar-moment.js: -------------------------------------------------------------------------------- 1 | // BEGIN-SNIPPET components-ui-calendar-moment 2 | import { inject as service } from '@ember/service'; 3 | 4 | import { computed } from '@ember/object'; 5 | import { merge } from '@ember/polyfills'; 6 | import moment from 'moment'; 7 | import UiCalendarComponent from 'ember-semantic-ui-calendar/components/ui-calendar'; 8 | 9 | const UiCalendarMoment = UiCalendarComponent.extend({ 10 | // See below 11 | }); 12 | 13 | export default UiCalendarMoment; 14 | // END-SNIPPET components-ui-calendar-moment 15 | 16 | // BEGIN-SNIPPET components-ui-calendar-moment-binding 17 | UiCalendarMoment.reopen({ 18 | // Store the moment object for the selected date 19 | momentValue: null, 20 | 21 | // Provide the Date object that is used by ui-calendar 22 | date: computed('momentValue', function() { 23 | let momentValue = this.get('momentValue'); 24 | return momentValue ? momentValue.toDate() : null; 25 | }).readOnly(), 26 | 27 | willInitSemantic(settings) { 28 | this._super(...arguments); 29 | 30 | merge(settings, { 31 | onChange(date) { 32 | // Wraps the Date in a moment object an triggers the onChange action 33 | this.get('onChange')(date ? moment(date) : null); 34 | } 35 | }); 36 | } 37 | }); 38 | // END-SNIPPET components-ui-calendar-moment-binding 39 | 40 | // BEGIN-SNIPPET components-ui-calendar-moment-locale 41 | UiCalendarMoment.reopen({ 42 | moment: service('moment'), 43 | 44 | init() { 45 | this._super(...arguments); 46 | 47 | this.get('moment').on('localeChanged', () => this.momentLocaleChanged()); 48 | }, 49 | 50 | localizedText: computed('moment.locale', function() { 51 | return { 52 | days: moment.weekdaysMin(), 53 | months: moment.months(), 54 | monthsShort: moment.monthsShort() 55 | // You can also add translations for `today` and `now` here, using an 56 | // addon like ember-i18n or ember-intl. 57 | }; 58 | }), 59 | 60 | momentLocaleChanged() { 61 | // Update translations 62 | this.execute('setting', 'text', this.get('localizedText')); 63 | 64 | // Refresh the calendar in popup 65 | this.execute('refresh'); 66 | 67 | // Refresh the input 68 | this.execute('set date', this.get('date'), true, false); 69 | }, 70 | 71 | willInitSemantic(settings) { 72 | this._super(...arguments); 73 | merge(settings, { 74 | text: this.get('localizedText'), 75 | formatter: { 76 | date(date) { 77 | return date ? moment(date).format('L') : ''; 78 | }, 79 | time(date) { 80 | return date ? moment(date).format('LT') : ''; 81 | } 82 | } 83 | }); 84 | } 85 | }); 86 | // END-SNIPPET components-ui-calendar-moment-locale 87 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/tests/dummy/app/controllers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/clear-button-examples.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | 3 | export default Controller.extend({ 4 | date: null, 5 | 6 | actions: { 7 | resetDate() { 8 | this.set('date', new Date()); 9 | } 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/custom-trigger-examples.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | 3 | export default Controller.extend({ 4 | date: null, 5 | 6 | actions: { 7 | onSelectedDate(date) { 8 | this.set('date', date.toDateString()); 9 | } 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/index.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | 3 | export default Controller.extend({ 4 | date: null, 5 | 6 | actions: { 7 | resetDate() { 8 | this.set('date', new Date()); 9 | } 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/moment-examples.js: -------------------------------------------------------------------------------- 1 | import { inject as service } from '@ember/service'; 2 | import Controller from '@ember/controller'; 3 | import moment from 'moment'; 4 | 5 | export default Controller.extend({ 6 | moment: service('moment'), 7 | 8 | date: null, 9 | 10 | actions: { 11 | resetDate() { 12 | this.set('date', moment()); 13 | }, 14 | 15 | changeLocale(locale) { 16 | this.get('moment').setLocale(locale); 17 | } 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/range-examples.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | 3 | export default Controller.extend({ 4 | startDate: null, 5 | endDate: null 6 | }); 7 | -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/tests/dummy/app/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Ember Semantic UI Calendar 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | 12 | 13 | 14 | 15 | {{content-for "head-footer"}} 16 | 17 | 18 | {{content-for "body"}} 19 | 20 | 21 | 22 | 23 | {{content-for "body-footer"}} 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/tests/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import EmberRouter from '@ember/routing/router'; 2 | import config from './config/environment'; 3 | 4 | const Router = EmberRouter.extend({ 5 | location: config.locationType, 6 | rootURL: config.rootURL 7 | }); 8 | 9 | Router.map(function() { 10 | this.route('moment-examples'); 11 | this.route('clear-button-examples'); 12 | this.route('range-examples'); 13 | this.route('custom-trigger-examples'); 14 | }); 15 | 16 | export default Router; 17 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/tests/dummy/app/routes/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/routes/clear-button-examples.js: -------------------------------------------------------------------------------- 1 | import Route from '@ember/routing/route'; 2 | 3 | export default Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/custom-trigger-examples.js: -------------------------------------------------------------------------------- 1 | import Route from '@ember/routing/route'; 2 | 3 | export default Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/index.js: -------------------------------------------------------------------------------- 1 | import Route from '@ember/routing/route'; 2 | 3 | export default Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/moment-examples.js: -------------------------------------------------------------------------------- 1 | import Route from '@ember/routing/route'; 2 | 3 | export default Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/range-examples.js: -------------------------------------------------------------------------------- 1 | import Route from '@ember/routing/route'; 2 | 3 | export default Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- 1 | .ui.red.inverted.menu { 2 | background-color: #dd6a58; 3 | } 4 | 5 | .ui.red.inverted.menu .header.item { 6 | padding: 6px 12px; 7 | } 8 | 9 | .ui.red.inverted.menu .header.item img.ui.image { 10 | height: 30px; 11 | margin-right: 5px; 12 | } 13 | 14 | .ui.main.container { 15 | margin-top: 64px; 16 | padding: 32px 0; 17 | position: relative; 18 | } 19 | 20 | .ui.left.dividing.rail { 21 | padding-top: 60px; 22 | } 23 | 24 | .ui.vertical.menu { 25 | text-align: right; 26 | } 27 | 28 | .ui.secondary.segment > .hljs { 29 | background-color: transparent; 30 | } 31 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 | 28 | 29 |
30 | {{outlet}} 31 |
32 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/clear-button-examples.hbs: -------------------------------------------------------------------------------- 1 | {{controls-segment date=date reset=(action "resetDate")}} 2 | 3 |
4 |
5 |

Clear button

6 |
7 |
8 | {{! BEGIN-SNIPPET clear-button }} 9 | {{ui-calendar date=date onChange=(action (mut date)) allowClear=true placeholder="Select date and time"}} 10 | {{! END-SNIPPET clear-button }} 11 |
12 |
13 | {{code-snippet name="clear-button.hbs"}} 14 |
15 |
16 | 17 |
18 |
19 |

Clear button with custom icon

20 |
21 |
22 | {{! BEGIN-SNIPPET custom-clear-button }} 23 | {{ui-calendar 24 | date=date 25 | onChange=(action (mut date)) 26 | allowClear=true 27 | clearIcon="ban" 28 | placeholder="Select date and time" 29 | }} 30 | {{! END-SNIPPET custom-clear-button }} 31 |
32 |
33 | {{code-snippet name="custom-clear-button.hbs"}} 34 |
35 |
36 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/tests/dummy/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/controls-segment.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Controls

3 |
4 |
5 |

All examples below use the same date object.

6 |

Current value is: {{date}}

7 |

8 |
9 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/custom-trigger-examples.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Custom triggers

4 |
5 |
6 | {{! BEGIN-SNIPPET example-custom-triggers }} 7 |
8 |
9 |
10 |
11 | 12 |
13 |
14 |
15 | {{#ui-calendar type="date" onChange=(action "onSelectedDate") }} 16 | 19 | {{/ui-calendar}} 20 |
21 |
22 |
23 | {{! END-SNIPPET example-custom-triggers }} 24 |
25 |
26 | {{code-snippet name="example-custom-triggers.hbs"}} 27 |
28 |
-------------------------------------------------------------------------------- /tests/dummy/app/templates/index.hbs: -------------------------------------------------------------------------------- 1 | {{controls-segment date=date reset=(action "resetDate")}} 2 | 3 |
4 |
5 |

Date & Time

6 |
7 |
8 | {{! BEGIN-SNIPPET date-and-time }} 9 | {{ui-calendar date=date onChange=(action (mut date)) placeholder="Select date and time"}} 10 | {{! END-SNIPPET date-and-time }} 11 |
12 |
13 | {{code-snippet name="date-and-time.hbs"}} 14 |
15 |
16 | 17 |
18 |
19 |

Date only

20 |
21 |
22 | {{! BEGIN-SNIPPET date-only }} 23 | {{ui-calendar type="date" date=date onChange=(action (mut date)) placeholder="Select date"}} 24 | {{! END-SNIPPET date-only }} 25 |
26 |
27 | {{code-snippet name="date-only.hbs"}} 28 |
29 |
30 | 31 |
32 |
33 |

Time only

34 |
35 |
36 | {{! BEGIN-SNIPPET time-only }} 37 | {{ui-calendar type="time" icon="time" date=date onChange=(action (mut date)) placeholder="Select time"}} 38 | {{! END-SNIPPET time-only }} 39 |
40 |
41 | {{code-snippet name="time-only.hbs"}} 42 |
43 |
44 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/moment-examples.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Moment.js required

4 |
5 |
6 | This addon does NOT include ember-moment. To use the examples in this page 7 | in your application, you will need to install ember-moment yourself. 8 |
9 |
10 |
ember install ember-moment
11 |
12 |
13 | 14 |
15 |
16 |

Extend default component

17 |
18 |
19 | To use moment with ember-semantic-ui-calendar, you should extend the 20 | ui-calendar component class and add moment specific code inside the new 21 | component (you can use the same component name if you want). 22 |
23 |
24 | {{code-snippet name="components-ui-calendar-moment.js"}} 25 |
26 |
27 | 28 |
29 |
30 |

Binding to moment

31 |
32 |
33 | By default, the ui-calendar component only accepts Date objects as value. 34 | You can change this to accept a moment object, and trigger the onChange 35 | action with the selected date as a moment value. 36 |
37 |
38 | {{code-snippet name="components-ui-calendar-moment-binding.js"}} 39 |
40 |
41 | 42 |
43 |
44 |

Support for localization

45 |
46 |
47 | You can also use moment to add localization support to 48 | ember-semantic-ui-calendar. 49 |
50 |
51 | {{code-snippet name="components-ui-calendar-moment-locale.js"}} 52 |
53 |
54 | 55 |
56 |
57 |

Controls

58 |
59 |
60 |

All examples below use the same date object.

61 |

Current value is: {{date}}

62 |

63 |

64 | Change locale 65 | 66 | 67 |

68 |
69 |
70 | 71 |
72 |
73 |

Date & Time

74 |
75 |
76 | {{! BEGIN-SNIPPET moment-date-and-time }} 77 | {{ui-calendar-moment momentValue=date onChange=(action (mut date)) placeholder="Select date and time"}} 78 | {{! END-SNIPPET moment-date-and-time }} 79 |
80 |
81 | {{code-snippet name="moment-date-and-time.hbs"}} 82 |
83 |
84 | 85 |
86 |
87 |

Date only

88 |
89 |
90 | {{! BEGIN-SNIPPET moment-date-only }} 91 | {{ui-calendar-moment type="date" momentValue=date onChange=(action (mut date)) placeholder="Select date"}} 92 | {{! END-SNIPPET moment-date-only }} 93 |
94 |
95 | {{code-snippet name="moment-date-only.hbs"}} 96 |
97 |
98 | 99 |
100 |
101 |

Time only

102 |
103 |
104 | {{! BEGIN-SNIPPET moment-time-only }} 105 | {{ui-calendar-moment type="time" icon="time" momentValue=date onChange=(action (mut date)) placeholder="Select time"}} 106 | {{! END-SNIPPET moment-time-only }} 107 |
108 |
109 | {{code-snippet name="moment-time-only.hbs"}} 110 |
111 |
112 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/range-examples.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Range

4 |
5 |
6 | {{! BEGIN-SNIPPET range }} 7 |
8 |
9 |
10 | 11 | {{ui-calendar 12 | type="date" 13 | endDate=endDate 14 | date=startDate 15 | onChange=(action (mut startDate)) 16 | placeholder="Start date" 17 | }} 18 |
19 | 20 |
21 | 22 | {{ui-calendar 23 | type="date" 24 | startDate=startDate 25 | date=endDate 26 | onChange=(action (mut endDate)) 27 | placeholder="End date" 28 | }} 29 |
30 |
31 |
32 | {{! END-SNIPPET range }} 33 |
34 |
35 | {{code-snippet name="range.hbs"}} 36 |
37 |
38 | -------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(environment) { 4 | let ENV = { 5 | modulePrefix: 'dummy', 6 | environment, 7 | rootURL: '/', 8 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true 13 | }, 14 | EXTEND_PROTOTYPES: { 15 | // Prevent Ember Data from overriding Date.parse. 16 | Date: false 17 | } 18 | }, 19 | 20 | APP: { 21 | // Here you can pass flags/options to your application instance 22 | // when it is created 23 | } 24 | }; 25 | 26 | ENV.moment = { 27 | includeLocales: true 28 | }; 29 | 30 | if (environment === 'development') { 31 | // ENV.APP.LOG_RESOLVER = true; 32 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 33 | // ENV.APP.LOG_TRANSITIONS = true; 34 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 35 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 36 | } 37 | 38 | if (environment === 'test') { 39 | // Testem prefers this... 40 | ENV.locationType = 'none'; 41 | 42 | // keep test console output quieter 43 | ENV.APP.LOG_ACTIVE_GENERATION = false; 44 | ENV.APP.LOG_VIEW_LOOKUPS = false; 45 | 46 | ENV.APP.rootElement = '#ember-testing'; 47 | ENV.APP.autoboot = false; 48 | } 49 | 50 | if (environment === 'production') { 51 | ENV.locationType = 'hash'; 52 | ENV.rootURL = '/ember-semantic-ui-calendar/'; 53 | 54 | } 55 | 56 | return ENV; 57 | }; 58 | -------------------------------------------------------------------------------- /tests/dummy/config/optional-features.json: -------------------------------------------------------------------------------- 1 | { 2 | "jquery-integration": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/dummy/config/targets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const browsers = [ 4 | 'last 1 Chrome versions', 5 | 'last 1 Firefox versions', 6 | 'last 1 Safari versions' 7 | ]; 8 | 9 | const isCI = !!process.env.CI; 10 | const isProduction = process.env.EMBER_ENV === 'production'; 11 | 12 | if (isCI || isProduction) { 13 | browsers.push('ie 11'); 14 | } 15 | 16 | module.exports = { 17 | browsers 18 | }; 19 | -------------------------------------------------------------------------------- /tests/dummy/public/ember-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /tests/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/tests/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy Tests 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | {{content-for "test-head"}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for "head-footer"}} 18 | {{content-for "test-head-footer"}} 19 | 20 | 21 | {{content-for "body"}} 22 | {{content-for "test-body"}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{content-for "body-footer"}} 31 | {{content-for "test-body-footer"}} 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/tests/integration/.gitkeep -------------------------------------------------------------------------------- /tests/integration/components/ui-calendar-test.js: -------------------------------------------------------------------------------- 1 | import { module, test } from 'qunit'; 2 | import { setupRenderingTest } from 'ember-qunit'; 3 | import { render, find, findAll, click, triggerKeyEvent } from '@ember/test-helpers'; 4 | import { focus, blur } from 'ember-native-dom-helpers'; 5 | import hbs from 'htmlbars-inline-precompile'; 6 | 7 | module('Integration | Component | ui calendar', function(hooks) { 8 | setupRenderingTest(hooks); 9 | 10 | hooks.beforeEach(function() { 11 | this.actions = {}; 12 | this.send = (actionName, ...args) => this.actions[actionName].apply(this, args); 13 | }); 14 | 15 | test('it renders', async function(assert) { 16 | assert.expect(2); 17 | 18 | await render(hbs`{{ui-calendar}}`); 19 | 20 | assert.ok(findAll('.ui.calendar').length, 'Container has .ui.calendar classes'); 21 | assert.ok(findAll('.ui.calendar input').length, 'Input is rendered inside the container'); 22 | }); 23 | 24 | test('it renders initially selected date', async function(assert) { 25 | assert.expect(1); 26 | 27 | this.set('date', new Date(2017, 0, 1)); 28 | await render(hbs`{{ui-calendar type="date" date=date}}`); 29 | 30 | assert.equal(find('.ui.calendar input').value, 'January 1, 2017'); 31 | }); 32 | 33 | test('it renders default icon', async function(assert) { 34 | assert.expect(3); 35 | 36 | await render(hbs`{{ui-calendar}}`); 37 | 38 | assert.ok(find('.ui.calendar .input').classList.contains('left'), 'Input has `left` class'); 39 | assert.ok(find('.ui.calendar .input').classList.contains('icon'), 'Input has `icon` class'); 40 | assert.ok(find('.ui.calendar .input > .icon').classList.contains('calendar'), 'Default icon is calendar'); 41 | }); 42 | 43 | test('it renders custom icon', async function(assert) { 44 | assert.expect(3); 45 | 46 | await render(hbs`{{ui-calendar icon="time"}}`); 47 | 48 | assert.ok(find('.ui.calendar .input').classList.contains('left'), 'Input has `left` class'); 49 | assert.ok(find('.ui.calendar .input').classList.contains('icon'), 'Input has `icon` class'); 50 | assert.ok(find('.ui.calendar .input > .icon').classList.contains('time'), 'Custom icon is rendered'); 51 | }); 52 | 53 | test('it renders without icon', async function(assert) { 54 | assert.expect(3); 55 | 56 | await render(hbs`{{ui-calendar icon=false}}`); 57 | 58 | assert.notOk(find('.ui.calendar .input').classList.contains('left'), 'Input does not have `left` class'); 59 | assert.notOk(find('.ui.calendar .input').classList.contains('icon'), 'Input does not have `icon` class'); 60 | assert.equal(findAll('.ui.calendar .input > .icon').length, 0, 'No icon is rendered'); 61 | }); 62 | 63 | test('it renders without clear button by default', async function(assert) { 64 | assert.expect(2); 65 | 66 | await render(hbs`{{ui-calendar clearIcon="remove"}}`); 67 | 68 | assert.notOk(find('.ui.calendar .input').classList.contains('right'), 'Input does not have `right` class'); 69 | assert.equal(findAll('.ui.calendar .input > .remove.icon').length, 0); 70 | }); 71 | 72 | test('it renders the clear button when `allowClear` is true and has a value', async function(assert) { 73 | assert.expect(2); 74 | 75 | this.set('date', new Date(2017, 0, 1)); 76 | await render(hbs`{{ui-calendar type="date" date=date allowClear=true clearIcon="remove"}}`); 77 | 78 | assert.ok(find('.ui.calendar .input').classList.contains('right'), 'Input has `right` class'); 79 | assert.equal(findAll('.ui.calendar .input > .remove.icon').length, 1); 80 | }); 81 | 82 | test('it does not renders the clear button when `allowClear` is true but it does not have a value', async function(assert) { 83 | assert.expect(2); 84 | 85 | this.set('date', null); 86 | await render(hbs`{{ui-calendar type="date" date=date allowClear=true clearIcon="remove"}}`); 87 | 88 | assert.notOk(find('.ui.calendar .input').classList.contains('right'), 'Input does not have `right` class'); 89 | assert.equal(findAll('.ui.calendar .input > .remove.icon').length, 0); 90 | }); 91 | 92 | test('it renders default icon with clear button', async function(assert) { 93 | assert.expect(5); 94 | 95 | this.set('date', new Date(2017, 0, 1)); 96 | await render(hbs`{{ui-calendar date=date allowClear=true clearIcon="remove"}}`); 97 | 98 | assert.ok(find('.ui.calendar .input').classList.contains('left'), 'Input has `left` class'); 99 | assert.ok(find('.ui.calendar .input').classList.contains('right'), 'Input has `right` class'); 100 | assert.ok(find('.ui.calendar .input').classList.contains('icon'), 'Input has `icon` class'); 101 | assert.equal(findAll('.ui.calendar .input > .calendar.icon').length, 1, 'Calendar icon is rendered'); 102 | assert.equal(findAll('.ui.calendar .input > .remove.icon').length, 1, 'Remove icon is rendered'); 103 | }); 104 | 105 | test('it renders custom icon with clear button', async function(assert) { 106 | assert.expect(5); 107 | 108 | this.set('date', new Date(2017, 0, 1)); 109 | await render(hbs`{{ui-calendar date=date icon="time" allowClear=true clearIcon="remove"}}`); 110 | 111 | assert.ok(find('.ui.calendar .input').classList.contains('left'), 'Input has `left` class'); 112 | assert.ok(find('.ui.calendar .input').classList.contains('right'), 'Input has `right` class'); 113 | assert.ok(find('.ui.calendar .input').classList.contains('icon'), 'Input has `icon` class'); 114 | assert.equal(findAll('.ui.calendar .input > .time.icon').length, 1, 'Time icon is rendered'); 115 | assert.equal(findAll('.ui.calendar .input > .remove.icon').length, 1, 'Remove icon is rendered'); 116 | }); 117 | 118 | test('it renders without icon and with clear button', async function(assert) { 119 | assert.expect(5); 120 | 121 | this.set('date', new Date(2017, 0, 1)); 122 | await render(hbs`{{ui-calendar date=date icon=false allowClear=true clearIcon="remove"}}`); 123 | 124 | assert.notOk(find('.ui.calendar .input').classList.contains('left'), 'Input does not have `left` class'); 125 | assert.ok(find('.ui.calendar .input').classList.contains('right'), 'Input has `right` class'); 126 | assert.ok(find('.ui.calendar .input').classList.contains('icon'), 'Input has `icon` class'); 127 | assert.equal(findAll('.ui.calendar .input > .calendar.icon').length, 0, 'Calendar icon is not rendered'); 128 | assert.equal(findAll('.ui.calendar .input > .remove.icon').length, 1, 'Remove icon is rendered'); 129 | }); 130 | 131 | test('it clears the input value when clear button is clicked', async function(assert) { 132 | assert.expect(2); 133 | 134 | this.set('date', new Date(2017, 0, 1)); 135 | await render( 136 | hbs`{{ui-calendar type="date" date=date onChange=(action (mut date)) allowClear=true clearIcon="remove"}}` 137 | ); 138 | 139 | assert.ok(this.get('date'), 'Selected date is empty'); 140 | await click('.ui.calendar .input > .remove.icon'); 141 | assert.notOk(this.get('date'), 'Selected date is empty'); 142 | }); 143 | 144 | test('it triggers actions on keyboard events - onEnter', async function(assert) { 145 | assert.expect(2); 146 | 147 | this.set('onEnter', (event) => assert.ok(event)); 148 | this.set('onKeyDown', (event) => assert.ok(event)); 149 | 150 | await render(hbs`{{ui-calendar onEnter=onEnter onKeyDown=onKeyDown}}`); 151 | 152 | triggerKeyEvent('input', 'keydown', 13); 153 | }); 154 | 155 | test('it triggers actions on keyboard events - onEscape', async function(assert) { 156 | assert.expect(2); 157 | 158 | this.set('onEscape', (event) => assert.ok(event)); 159 | this.set('onKeyDown', (event) => assert.ok(event)); 160 | 161 | await render(hbs`{{ui-calendar onEscape=onEscape onKeyDown=onKeyDown}}`); 162 | 163 | triggerKeyEvent('input', 'keydown', 27); 164 | }); 165 | 166 | test('it triggers actions on keyboard events - onKeyDown', async function(assert) { 167 | assert.expect(1); 168 | 169 | this.set('onKeyDown', (event) => assert.ok(event)); 170 | 171 | await render(hbs`{{ui-calendar onKeyDown=onKeyDown}}`); 172 | 173 | triggerKeyEvent('input', 'keydown', 32); 174 | }); 175 | 176 | test('it triggers input events - onFocusIn', async function(assert) { 177 | assert.expect(1); 178 | 179 | this.actions.focusIn = () => assert.ok(true); 180 | 181 | await render(hbs`{{ui-calendar onFocusIn=(action "focusIn")}}`); 182 | 183 | focus('input'); 184 | }); 185 | 186 | test('it triggers input events - onFocusOut', async function(assert) { 187 | assert.expect(1); 188 | 189 | this.actions.focusOut = () => assert.ok(true); 190 | 191 | await render(hbs`{{ui-calendar onFocusOut=(action "focusOut")}}`); 192 | 193 | focus('input'); 194 | blur('input'); 195 | }); 196 | 197 | test('it works with custom trigger', async function(assert) { 198 | assert.expect(1); 199 | 200 | this.set('change', () => assert.ok(true)); 201 | 202 | await render(hbs` 203 | {{#ui-calendar type="date" onChange=(action change)}} 204 | 205 | {{/ui-calendar}} 206 | `); 207 | 208 | await click('.ui.calendar .ui.button'); 209 | await click('.link.today'); 210 | }); 211 | 212 | test('a custom trigger can execute module behaviors', async function(assert) { 213 | assert.expect(1); 214 | 215 | this.set('change', (date) => { 216 | this.set('date', date); 217 | }); 218 | 219 | await render(hbs` 220 | {{#ui-calendar type="date" onChange=(action change) date=date as |execute|}} 221 | 222 | 223 | {{/ui-calendar}} 224 | `); 225 | 226 | focus('input'); 227 | await click('.link.today'); 228 | await click('.ui.calendar .ui.button'); 229 | 230 | assert.notOk(this.get('date'), 'date should be empty'); 231 | }); 232 | }); 233 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import Application from '../app'; 2 | import config from '../config/environment'; 3 | import { setApplication } from '@ember/test-helpers'; 4 | import { start } from 'ember-qunit'; 5 | 6 | setApplication(Application.create(config.APP)); 7 | 8 | start(); 9 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/tests/unit/.gitkeep -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantosobra/ember-semantic-ui-calendar/b2dee3b8fa41c8c9a80e0cf16d1e8a155336aee3/vendor/.gitkeep -------------------------------------------------------------------------------- /vendor/ember-semantic-ui-calendar.css: -------------------------------------------------------------------------------- 1 | .ui[class*="left right icon"].input > i.left.icon { 2 | right: inherit; 3 | } 4 | 5 | .ui[class*="left right icon"].input > input { 6 | padding-left: 2.67142857em !important; 7 | padding-right: 2.67142857em !important; 8 | } 9 | -------------------------------------------------------------------------------- /vendor/ember-semantic-ui-calendar.min.css: -------------------------------------------------------------------------------- 1 | .ui[class*="left right icon"].input>i.left.icon{right:inherit}.ui[class*="left right icon"].input>input{padding-left:2.67142857em!important;padding-right:2.67142857em!important} 2 | -------------------------------------------------------------------------------- /yuidoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-semantic-ui-calendar", 3 | "description": "", 4 | "url": "http://github.com/quantosobra/ember-semantic-ui-calendar", 5 | "options": { 6 | "enabledEnvironments": ["production"], 7 | "themedir" : "node_modules/yuidoc-theme-quantosobra", 8 | "paths": [ 9 | "app", 10 | "addon" 11 | ], 12 | "external": { 13 | "data": [{ 14 | "base": "http://emberjs.com/api/", 15 | "json": "http://builds.emberjs.com/tags/v2.4.0/ember-docs.json" 16 | }] 17 | }, 18 | "exclude": "vendor", 19 | "outdir": "docs", 20 | "linkNatives": true, 21 | "quiet": true, 22 | "parseOnly": false, 23 | "lint": false, 24 | "nocode": false 25 | } 26 | } 27 | --------------------------------------------------------------------------------