├── .babelrc
├── .editorconfig
├── .gitignore
├── CHANGELOG.md
├── README.md
├── assets
└── vue-digital-clock.gif
├── example
├── App.vue
├── index.html
└── main.js
├── package.json
├── rollup.config.js
├── src
├── Clock.spec.js
├── Clock.vue
└── index.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/env"]
3 | }
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 |
4 | # Editor files
5 | /.idea
6 | *.suo
7 | *.ntvs*
8 | *.njsproj
9 | *.sln
10 |
11 | # Log files
12 | *.log
13 | reports
14 | coverage
15 |
16 | # Build
17 | dist
18 | .cache
19 |
20 | # Docs
21 | _book
22 | .tmp
23 | tmp*
24 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 2.0.0 / 02-01-2019
2 |
3 | - Add twelveHour prop
4 | - Distribute JS files, rather than a Vue SFC
5 |
6 | # 1.5.0 / 03-30-2017
7 |
8 | - Add displaySeconds prop
9 |
10 | # 1.4.0 / 03-30-2017
11 |
12 | - Add blink prop
13 |
14 | # 1.3.1 / 03-29-2017
15 |
16 | - Remove babel from project
17 |
18 | # 1.3.0 / 03-29-2017
19 |
20 | - Remove ES6 from Clock.vue
21 |
22 | # 1.2.0 / 03-29-2017
23 |
24 | - Remove babel-runtime plugin
25 |
26 | # 1.1.0 / 03-05-2017
27 |
28 | - Add destroyed() method to clear interval when component is destroyed
29 |
30 | # 1.0.2 / 03-02-2017
31 |
32 | - Add keywords to package.json
33 | - Update image URL
34 | - Add installation guide to README
35 |
36 | # 1.0.1 / 03-02-2017
37 |
38 | - Update image URL in README
39 |
40 | # 1.0.0 / 03-01-2017
41 |
42 | - Initial release.
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-digital-clock
2 |
3 | > A digital clock component built with Vue.js
4 |
5 | ## Installation
6 |
7 | With NPM:
8 |
9 | ```shell
10 | npm install --save vue-digital-clock
11 | ```
12 |
13 | With Yarn
14 |
15 | ```shell
16 | yarn add vue-digital-clock
17 | ```
18 |
19 | And import it into your project
20 |
21 | ```javascript
22 | import DigitalClock from "vue-digital-clock";
23 | ```
24 |
25 | ## Props
26 |
27 | | Prop | Type | Usage |
28 | | ------ | ---- | ------ |
29 | | blink | Boolean | Set as true to have the colon blink with the seconds|
30 | | displaySeconds | Boolean | Set as true to display seconds|
31 | | twelveHour | Boolean | Set as true to display times with AM/PM|
32 |
33 |
34 | ## Example
35 |
36 | ```vue
37 |
38 |
39 |
40 |
41 |
50 | ```
51 |
52 | ## Screenshot
53 |
54 | 
55 |
--------------------------------------------------------------------------------
/assets/vue-digital-clock.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eddyerburgh/vue-digital-clock/5c72db5a9e1243430ae04b9ff7536a39cf9e8cad/assets/vue-digital-clock.gif
--------------------------------------------------------------------------------
/example/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
14 |
15 |
24 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | vue-digital-clock example
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/example/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App.vue";
3 |
4 | /* eslint-disable no-new */
5 | new Vue({
6 | el: "#app",
7 | render: h => h(App),
8 | components: { App }
9 | });
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-digital-clock",
3 | "version": "2.0.0",
4 | "description": "A Vue digital clock component, for use out the box",
5 | "author": "Edd Yerburgh ",
6 | "main": "./dist/cjs/Clock.js",
7 | "module": "./dist/es/Clock.js",
8 | "files": [
9 | "dist/**/*.js"
10 | ],
11 | "scripts": {
12 | "build": "rollup -c",
13 | "dev": "parcel example/index.html",
14 | "format": "prettier --write \"{,!(.cache|dist)/**/}/*.{md,vue,js,json}\"",
15 | "format:check": "prettier --check \"{,!(.cache|dist)/**/}/*.{md,vue,js,json}\"",
16 | "prepare": "npm run build",
17 | "test:unit": "jest",
18 | "test": "npm run format:check && npm run test:unit"
19 | },
20 | "keywords": [
21 | "vue clock",
22 | "vue2 clock",
23 | "vuejs clock",
24 | "vue.js clock",
25 | "vue js clock",
26 | "vue clock component",
27 | "vue2 clock component",
28 | "vuejs clock component",
29 | "vue.js clock component",
30 | "vue js clock component",
31 | "vue digital clock",
32 | "vue2 digital clock",
33 | "vuejs digital clock",
34 | "vue.js digital clock",
35 | "vue js digital clock",
36 | "vue digital clock component",
37 | "vue2 digital clock component",
38 | "vuejs digital clock component",
39 | "vue.js digital clock component",
40 | "vue js digital clock component"
41 | ],
42 | "peerDependencies": {
43 | "vue": "^2.x"
44 | },
45 | "devDependencies": {
46 | "@babel/core": "^7.2.2",
47 | "@babel/preset-env": "^7.3.1",
48 | "avoriaz": "^1.8.2",
49 | "babel-core": "^7.0.0-bridge.0",
50 | "babel-jest": "^24.0.0",
51 | "jest": "^24.0.0",
52 | "parcel": "^1.11.0",
53 | "prettier": "^1.16.3",
54 | "rollup": "^1.1.2",
55 | "rollup-plugin-buble": "^0.19.6",
56 | "rollup-plugin-commonjs": "^9.2.0",
57 | "rollup-plugin-node-resolve": "^4.0.0",
58 | "rollup-plugin-vue": "^4.6.2",
59 | "sinon": "^7.2.3",
60 | "vue": "^2.5.22",
61 | "vue-hot-reload-api": "^2.3.1",
62 | "vue-jest": "^3.0.2",
63 | "vue-template-compiler": "^2.5.22"
64 | },
65 | "engines": {
66 | "node": ">= 4.0.0",
67 | "npm": ">= 3.0.0"
68 | },
69 | "repository": {
70 | "type": "git",
71 | "url": "git+ssh://git@github.com/eddyerburgh/vue-digital-clock.git"
72 | },
73 | "bugs": {
74 | "url": "https://github.com/eddyerburgh/vue-digital-clock/issues"
75 | },
76 | "homepage": "https://github.com/eddyerburgh/vue-digital-clock#readme",
77 | "jest": {
78 | "transform": {
79 | "^.+\\.js$": "babel-jest",
80 | "^.+\\.vue$": "vue-jest"
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import vue from 'rollup-plugin-vue'
2 | import buble from 'rollup-plugin-buble';
3 | import resolve from 'rollup-plugin-node-resolve';
4 | import commonjs from 'rollup-plugin-commonjs';
5 |
6 | export default {
7 | input: 'src/index.js',
8 | plugins: [
9 | commonjs(),
10 | resolve(),
11 | vue(),
12 | buble()
13 | ],
14 | output: [
15 | {
16 | file: 'dist/cjs/Clock.js',
17 | format: 'cjs',
18 | exports: 'default'
19 | },
20 | {
21 | file: 'dist/es/Clock.js',
22 | format: 'es'
23 | },
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/src/Clock.spec.js:
--------------------------------------------------------------------------------
1 | import { mount } from "avoriaz";
2 | import sinon from "sinon";
3 | import Clock from "./Clock.vue";
4 |
5 | const seconds = 1000;
6 | const minutes = 60 * seconds;
7 | const hours = 60 * minutes;
8 |
9 | describe("Clock.vue", () => {
10 | let clock;
11 |
12 | beforeEach(() => {
13 | clock = sinon.useFakeTimers(new Date(2016, 2, 15).getTime());
14 | });
15 |
16 | it("renders a time element", () => {
17 | expect(mount(Clock).is("time")).toBe(true);
18 | });
19 |
20 | it("renders current hour in 24 hour format", () => {
21 | clock.tick(21 * hours);
22 | const wrapper = mount(Clock);
23 | expect(wrapper.find(".clock__hour")[0].text()).toContain("21");
24 | });
25 |
26 | it("renders current hour with padded 0", () => {
27 | clock.tick(3 * hours);
28 | const wrapper = mount(Clock);
29 | expect(wrapper.find(".clock__hour")[0].text()).toContain("03");
30 | });
31 |
32 | it("Updates hours when changed", () => {
33 | clock.tick(13 * hours);
34 | const wrapper = mount(Clock);
35 | expect(wrapper.find(".clock__hour")[0].text()).toContain("13");
36 | clock.tick(3 * hours);
37 | wrapper.update();
38 | expect(wrapper.find(".clock__hour")[0].text()).toContain("16");
39 | });
40 |
41 | it("renders current minutes", () => {
42 | clock.tick(30 * minutes);
43 | const wrapper = mount(Clock);
44 | expect(wrapper.find(".clock__minutes")[0].text()).toContain("30");
45 | });
46 |
47 | it("renders current minutes with padded 0", () => {
48 | clock.tick(3 * minutes);
49 | const wrapper = mount(Clock);
50 | expect(wrapper.find(".clock__minutes")[0].text()).toContain("03");
51 | });
52 |
53 | it("updates minutes when changed", () => {
54 | clock.tick(3 * minutes);
55 | const wrapper = mount(Clock);
56 | expect(wrapper.find(".clock__minutes")[0].text()).toContain("03");
57 | clock.tick(3 * minutes);
58 | wrapper.update();
59 | expect(wrapper.find(".clock__minutes")[0].text()).toContain("06");
60 | });
61 |
62 | it("renders current seconds with padded 0 if props displaySeconds is true", () => {
63 | clock.tick(5 * seconds);
64 | const wrapper = mount(Clock, { propsData: { displaySeconds: true } });
65 | expect(wrapper.find(".clock__seconds")[0].text()).toContain("05");
66 | });
67 |
68 | it("updates seconds when changed if props displaySeconds is true", () => {
69 | clock.tick(3 * seconds);
70 | const wrapper = mount(Clock, { propsData: { displaySeconds: true } });
71 | expect(wrapper.find(".clock__seconds")[0].text()).toContain("03");
72 | clock.tick(2 * seconds);
73 | wrapper.update();
74 | expect(wrapper.find(".clock__seconds")[0].text()).toContain("05");
75 | });
76 |
77 | it("does not render seconds with if props displaySeconds is undefined", () => {
78 | clock.tick(5 * seconds);
79 | const wrapper = mount(Clock);
80 | expect(wrapper.find(".clock__seconds").length).toBe(0);
81 | });
82 |
83 | it("displays colon when not passed blink prop and seconds are even", () => {
84 | clock.tick(seconds * 2);
85 | const wrapper = mount(Clock);
86 | expect(wrapper.text()).toContain(":");
87 | });
88 |
89 | it("displays colon when not passed blink prop and seconds are odd", () => {
90 | clock.tick(seconds * 3);
91 | const wrapper = mount(Clock);
92 | expect(wrapper.text()).toContain(":");
93 | });
94 |
95 | it("displays colon when passed blink prop and seconds are even", () => {
96 | clock.tick(seconds * 2);
97 | const wrapper = mount(Clock, { propsData: { blink: true } });
98 | expect(wrapper.text()).toContain(":");
99 | });
100 |
101 | it("does not display colon when passed blink prop and seconds are even", () => {
102 | clock.tick(seconds * 3);
103 | const wrapper = mount(Clock, { propsData: { blink: true } });
104 | expect(wrapper.find(".clock__colon")[0].html()).toContain(
105 | ':'
106 | );
107 | });
108 |
109 | it("displays second colon when passed blink and displaySeconds props and seconds are even", () => {
110 | clock.tick(seconds * 2);
111 | const wrapper = mount(Clock, {
112 | propsData: { blink: true, displaySeconds: true }
113 | });
114 | expect(wrapper.find("span")[3].text()).toContain(":");
115 | });
116 |
117 | it("does not display second colon when passed blink and displaySeconds props and seconds are odd", () => {
118 | clock.tick(seconds * 3);
119 | const wrapper = mount(Clock, {
120 | propsData: { blink: true, displaySeconds: true }
121 | });
122 | expect(wrapper.find(".clock__colon")[1].html()).toContain(
123 | ':'
124 | );
125 | });
126 |
127 | it("does not display colon when passed blink prop and seconds are even", () => {
128 | clock.tick(seconds * 3);
129 | const wrapper = mount(Clock, { propsData: { blink: true } });
130 | expect(wrapper.find(".clock__colon")[0].html()).toContain(
131 | ':'
132 | );
133 | });
134 |
135 | it("Calls clear input with vm.ticker when component is destroyed", () => {
136 | const stub = jest.fn();
137 | window.clearInterval = stub;
138 | const wrapper = mount(Clock);
139 | const ticker = wrapper.vm.ticker;
140 | wrapper.destroy();
141 | expect(stub).toHaveBeenCalledWith(ticker);
142 | });
143 |
144 | it("should not display second colon by default", () => {
145 | const wrapper = mount(Clock);
146 | expect((wrapper.text().match(/:/g) || []).length).toBe(1);
147 | });
148 |
149 | it('renders an ante-meridiem time with "am" when in twelveHour mode', () => {
150 | clock.tick(7 * hours);
151 | const wrapper = mount(Clock, { propsData: { twelveHour: true } });
152 | expect(wrapper.find(".clock__hour")[0].text()).toContain("07");
153 | expect(wrapper.find(".clock__ampm")[0].text()).toContain("am");
154 | });
155 |
156 | it('renders a post-meridiem time with "pm" when in twelveHour mode', () => {
157 | clock.tick(21 * hours);
158 | const wrapper = mount(Clock, { propsData: { twelveHour: true } });
159 | expect(wrapper.find(".clock__hour")[0].text()).toContain("09");
160 | expect(wrapper.find(".clock__ampm")[0].text()).toContain("pm");
161 | });
162 | });
163 |
--------------------------------------------------------------------------------
/src/Clock.vue:
--------------------------------------------------------------------------------
1 |
2 |
26 |
27 |
79 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./Clock.vue";
2 |
--------------------------------------------------------------------------------