├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── babel.config.js
├── commitlint.config.js
├── docs
├── README.md
├── _config.yml
└── simple-vue-timeline.png
├── index.d.ts
├── jest.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── src
├── App.vue
├── assets
│ ├── logo.png
│ └── scss
│ │ ├── simple-vue-timeline.scss
│ │ └── vendor.scss
├── components
│ ├── SimpleTimeline.vue
│ ├── SimpleTimelineControl.vue
│ ├── SimpleTimelineItem.vue
│ ├── index.d.ts
│ ├── index.js
│ ├── simple-timeline-control.component.ts
│ ├── simple-timeline-control.model.ts
│ ├── simple-timeline-item.component.ts
│ ├── simple-timeline-item.model.ts
│ ├── simple-timeline-status.model.ts
│ └── simple-timeline.component.ts
├── demo.ts
├── main.ts
├── plugins
│ └── bootstrap-vue.js
├── shims-tsx.d.ts
└── shims-vue.d.ts
├── tests
└── unit
│ ├── simple-timeline-item.spec.ts
│ └── simple-timeline.spec.ts
└── tsconfig.json
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 |
4 | env: {
5 | node: true
6 | },
7 |
8 | extends: ["plugin:vue/essential", "@vue/prettier", "@vue/typescript"],
9 |
10 | rules: {
11 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
12 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
13 | },
14 |
15 | parserOptions: {
16 | parser: "@typescript-eslint/parser"
17 | },
18 |
19 | overrides: [
20 | {
21 | files: [
22 | '**/__tests__/*.{j,t}s?(x)',
23 | '**/tests/unit/**/*.spec.{j,t}s?(x)'
24 | ],
25 | env: {
26 | jest: true
27 | }
28 | }
29 | ]
30 | };
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | /coverage
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 |
15 | # Editor directories and files
16 | .idea
17 | .vscode
18 | *.suo
19 | *.ntvs*
20 | *.njsproj
21 | *.sln
22 | *.sw?
23 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | target
3 | package-lock.json
4 | .git
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | # Prettier configuration
2 |
3 | printWidth: 140
4 | singleQuote: true
5 | tabWidth: 2
6 | useTabs: false
7 |
8 | # js and ts rules:
9 | arrowParens: avoid
10 |
11 | # jsx and tsx rules:
12 | jsxBracketSameLine: false
13 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "node"
4 | - "11"
5 | cache:
6 | directories:
7 | - node_modules
8 | script:
9 | - npm run test:unit
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ### [2.0.9](https://github.com/scottie34/simple-vue-timeline/compare/v2.0.8...v2.0.9) (2021-08-23)
6 |
7 | ### [2.0.8](https://github.com/scottie34/simple-vue-timeline/compare/v2.0.7...v2.0.8) (2020-09-23)
8 |
9 | ### [2.0.7](https://github.com/scottie34/simple-vue-timeline/compare/v2.0.6...v2.0.7) (2020-08-06)
10 |
11 | ### [2.0.6](https://github.com/scottie34/simple-vue-timeline/compare/v2.0.5...v2.0.6) (2020-07-26)
12 |
13 | ### [2.0.5](https://github.com/scottie34/simple-vue-timeline/compare/v2.0.4...v2.0.5) (2020-06-17)
14 |
15 | ### [2.0.4](https://github.com/scottie34/simple-vue-timeline/compare/v2.0.3...v2.0.4) (2020-04-18)
16 |
17 | ### [2.0.3](https://github.com/scottie34/simple-vue-timeline/compare/v2.0.2...v2.0.3) (2020-04-18)
18 |
19 | ### [2.0.2](https://github.com/scottie34/simple-vue-timeline/compare/v2.0.1...v2.0.2) (2020-04-17)
20 |
21 | ### [2.0.1](https://github.com/scottie34/simple-vue-timeline/compare/v2.0.0...v2.0.1) (2020-04-17)
22 |
23 | ## [2.0.0](https://github.com/scottie34/simple-vue-timeline/compare/v1.12.0...v2.0.0) (2020-04-17)
24 |
25 |
26 | ### ⚠ BREAKING CHANGES
27 |
28 | * Usage declaration of bootstrap-vue and font-awesome is now the responsability of
29 | the project in which it is used.
30 |
31 | * use vue plugin, add test and reduce package size ([cdeb498](https://github.com/scottie34/simple-vue-timeline/commit/cdeb49821a0e214ec7563a7fb1dbfecd09ce6fa8))
32 |
33 | ## 1.12.0 (2020-04-17)
34 |
35 |
36 | ### Features
37 |
38 | * 0.3.0 version ([6007c2b](https://github.com/scottie34/simple-vue-timeline/commit/6007c2b9e69bec6b1e4b8468595f5c6e1cf2cb60))
39 | * 1.0.0 version ([d65d7d0](https://github.com/scottie34/simple-vue-timeline/commit/d65d7d08c3c3b0ed96ce0853c1c2bd0d149f0078))
40 | * 1.1.0 version ([a6021d9](https://github.com/scottie34/simple-vue-timeline/commit/a6021d9aa5adeec57645dd90cf6945ad6a6b194a))
41 | * add MIT licence ([0dc3166](https://github.com/scottie34/simple-vue-timeline/commit/0dc31663897d61862c1746fcf91600270e8acbb7))
42 | * add travis ci configuration and change flex layout ([d2f00b6](https://github.com/scottie34/simple-vue-timeline/commit/d2f00b6c0b96f460fdec0b4e098a31a323004155))
43 | * demo and doc ([e8993ee](https://github.com/scottie34/simple-vue-timeline/commit/e8993ee23fce03452f92c6352fe1c3b6c738baff))
44 | * emit event from Timeline Control to App ([92b0c8a](https://github.com/scottie34/simple-vue-timeline/commit/92b0c8a89b25cf898cd65963d15ba3b02f5e467e))
45 | * enhance package.json metadata ([4f0ccd4](https://github.com/scottie34/simple-vue-timeline/commit/4f0ccd4808906fdc56161c5c88b9112ca500ad73))
46 | * initial commit ([194a799](https://github.com/scottie34/simple-vue-timeline/commit/194a799405324e4e53e6f2a88c0d6f0c09ba5afd))
47 | * manage z-index on icon ([e0319d3](https://github.com/scottie34/simple-vue-timeline/commit/e0319d3aa42c123c7963cd01833c77517f62c088))
48 | * MIT license ([8fd0d86](https://github.com/scottie34/simple-vue-timeline/commit/8fd0d8695ccf9c068cdc646032a89a5f8c92ce49))
49 | * readme.md absolute image link ([bcbcb5e](https://github.com/scottie34/simple-vue-timeline/commit/bcbcb5e8b32072a0b7066ce7041d6a9549e4082b))
50 | * several enhancements (use bootstrap icons, momentjs) ([bb493a3](https://github.com/scottie34/simple-vue-timeline/commit/bb493a371449895c4b871974b4e2df8e23927d9e))
51 | * several enhancements (use bootstrap icons, momentjs) ([7fe5c04](https://github.com/scottie34/simple-vue-timeline/commit/7fe5c04ae9648b01ef97bc1eadb9898cdc1a1fc0))
52 | * update README ([c08b39d](https://github.com/scottie34/simple-vue-timeline/commit/c08b39d31b265aede8bdfb5020d5c9a721fb5228))
53 |
54 |
55 | ### Bug Fixes
56 |
57 | * bad namespace ([454f35a](https://github.com/scottie34/simple-vue-timeline/commit/454f35a7e4e7bfe2ffe1193804422dad9b884d88))
58 | * change cast method to Item in App ([22b05d7](https://github.com/scottie34/simple-vue-timeline/commit/22b05d7c23c93572c9f86a9b62629befd9cd9fb8))
59 | * css timeline-container ([d04777b](https://github.com/scottie34/simple-vue-timeline/commit/d04777b3418a3eb0c56fa745477c353448ed82ad))
60 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 scottie34
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # simple-vue-timeline
2 | 
3 | 
4 | 
5 | 
6 |
7 | A simple but customizable and reactive timeline vue component which leverages the use of common libraries:
8 | * [bootstrap vue components](https://bootstrap-vue.js.org/),
9 | * [vue-fontawesome](https://github.com/FortAwesome/vue-fontawesome)
10 | * and [fecha](https://github.com/taylorhakes/fecha) date formatting.
11 |
12 | If you find it useful, give it a [star](https://github.com/scottie34/simple-vue-timeline) and please consider [buying me a coffee](https://www.buymeacoffee.com/scottie34).
13 |
14 | Refer to the [documentation](https://scottie34.github.io/simple-vue-timeline/) for further details.
15 |
16 | Use [github](https://github.com/scottie34/simple-vue-timeline) for any issue you encountered or to give me some feedback of your usage.
17 |
18 | 
19 |
20 |
21 | ## Getting Started
22 |
23 | ### Installation
24 | ```shell script
25 | npm install --save simple-vue-timeline
26 | ```
27 |
28 | ```ts
29 | import { Vue } from "vue";
30 | import { SimpleTimelinePlugin } from 'simple-vue-timeline';
31 |
32 | Vue.use(SimpleTimelinePlugin);
33 | ```
34 |
35 | ### Declare third party libraries usage
36 | Since 2.x version, third party usages are no more declared by the simple-vue-timeline itself.
37 | It is thus your responsibility to declare them in your vue project which uses simple-vue-timeline.
38 |
39 | #### vue-fontawesome
40 | Refer to [vue-fontawesome](https://github.com/FortAwesome/vue-fontawesome#usage) documentation.
41 | ```ts
42 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
43 | import { Vue } from "vue";
44 |
45 | Vue.component('font-awesome-icon', FontAwesomeIcon);
46 | ```
47 |
48 | #### bootstrap-vue
49 | Refer to [bootstrap-vue](https://bootstrap-vue.js.org/docs/) documentation.
50 | The following plugins must be declared:
51 | * BadgePlugin
52 | * ButtonPlugin
53 | * CardPlugin
54 | * LayoutPlugin
55 |
56 | ```ts
57 | import { Vue } from "vue";
58 | import { BadgePlugin, ButtonPlugin, CardPlugin, LayoutPlugin } from 'bootstrap-vue';
59 |
60 | Vue.use(BadgePlugin);
61 | Vue.use(ButtonPlugin);
62 | Vue.use(CardPlugin);
63 | Vue.use(LayoutPlugin);
64 | ```
65 |
66 | ### Style
67 | ```ts
68 | @import '~simple-vue-timeline/dist/simple-vue-timeline';
69 | ```
70 |
71 | You must also add the bootstrap style:
72 | ```ts
73 | @import '~bootstrap/scss/bootstrap';
74 | ```
75 |
76 | ### Template Element
77 | Add the element as follows:
78 |
79 | `template`
80 | ```vue
81 |
82 | ```
83 |
84 | Refer to the `Vue Class Component Sample` section below for a complete sample.
85 |
86 | ## Contribute
87 | Once cloned, you can run the following commands to serve the [demo.ts](https://github.com/scottie34/simple-vue-timeline/blob/master/src/demo.ts)
88 | entry point.
89 |
90 | ```shell script
91 | npm install
92 | npm run serve
93 | ```
94 |
95 | ### Commit messages
96 | Commit messages must follow the [AngularJS's commit message convention](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) also known as [conventional-changelog](https://github.com/ajoslin/conventional-changelog).
97 | This repo is [commitizen-friendly](https://github.com/commitizen/cz-cli).
98 |
99 | ### Local Test with npm link
100 | You can use [npm link](https://docs.npmjs.com/cli/link.html) to try the lib integration locally.
101 |
102 | Note that you must add a `vue.config.js` in the project using the lib with the following content
103 |
104 | ```js
105 | const path = require("path");
106 |
107 | // npm link https://github.com/vuejs/vue-cli/issues/4271#issuecomment-585299391
108 | module.exports = {
109 | configureWebpack: {
110 | resolve: {
111 | alias: {
112 | vue$: path.resolve("./node_modules/vue/dist/vue.runtime.esm.js")
113 | }
114 | }
115 | }
116 | };
117 | ```
118 |
119 | ## Vue Class Component Sample
120 |
121 | ```vue
122 |
123 |
124 |
132 |
133 |
134 |
135 |
197 | ```
198 |
199 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | [
4 | '@vue/app',
5 | {
6 | useBuiltIns: 'entry'
7 | }
8 | ]
9 | ]
10 | };
11 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = { extends: ['@commitlint/config-conventional'] };
2 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # simple-vue-timeline
2 | 
3 | 
4 | 
5 | 
6 |
7 | A simple but customizable and reactive timeline vue component which leverages the use of common libraries:
8 | * [bootstrap vue components](https://bootstrap-vue.js.org/),
9 | * [vue-fontawesome](https://github.com/FortAwesome/vue-fontawesome)
10 | * and [fecha](https://github.com/taylorhakes/fecha) date formatting.
11 |
12 | If you find it useful, give it a [star](https://github.com/scottie34/simple-vue-timeline) and please consider [buying me a coffee](https://www.buymeacoffee.com/scottie34).
13 |
14 | Use [github](https://github.com/scottie34/simple-vue-timeline) for any issue you encountered or to give me some feedback of your usage.
15 |
16 | 
17 |
18 | * TOC
19 | {:toc}
20 |
21 | ## Getting Started
22 |
23 | ### Installation
24 | ```
25 | npm install --save simple-vue-timeline
26 | ```
27 |
28 | ```ts
29 | import { Vue } from "vue";
30 | import { SimpleTimelinePlugin } from 'simple-vue-timeline';
31 |
32 | Vue.use(SimpleTimelinePlugin);
33 | ```
34 |
35 | ### Declare third party libraries usage
36 | Since 2.x version, third party usages are no more declared by the simple-vue-timeline itself.
37 | It is thus your responsibility to declare them in your vue project which uses simple-vue-timeline.
38 |
39 | #### vue-fontawesome
40 | Refer to [vue-fontawesome](https://github.com/FortAwesome/vue-fontawesome#usage) documentation.
41 | ```ts
42 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
43 | import { Vue } from "vue";
44 |
45 | Vue.component('font-awesome-icon', FontAwesomeIcon);
46 | ```
47 |
48 | #### bootstrap-vue
49 | Refer to [bootstrap-vue](https://bootstrap-vue.js.org/docs/) documentation.
50 | The following plugins must be declared:
51 | * BadgePlugin
52 | * ButtonPlugin
53 | * CardPlugin
54 | * LayoutPlugin
55 |
56 | ```ts
57 | import { Vue } from "vue";
58 | import { BadgePlugin, ButtonPlugin, CardPlugin, LayoutPlugin } from 'bootstrap-vue';
59 |
60 | Vue.use(BadgePlugin);
61 | Vue.use(ButtonPlugin);
62 | Vue.use(CardPlugin);
63 | Vue.use(LayoutPlugin);
64 | ```
65 |
66 | ### Style
67 | ```ts
68 | @import '~simple-vue-timeline/dist/simple-vue-timeline';
69 | ```
70 |
71 | You must also add the bootstrap style:
72 | ```ts
73 | @import '~bootstrap/scss/bootstrap';
74 | ```
75 |
76 | ### Template Element
77 | Add the element as follows:
78 |
79 | `template`
80 | ```vue
81 |
82 | ```
83 |
84 | Refer to the `Vue Class Component Sample` section below for a complete sample.
85 |
86 | ## Props
87 |
88 | | Name | Type | Description |
89 | | --- | --- | --- |
90 | | `items` | `Item[]` | An item array containing your timeline items |
91 | | `dateformat` | `string` | The [fecha](https://github.com/taylorhakes/fecha) pattern to use to format date |
92 | | `v-on` | `Listener[]` | This one must be set to `$listeners` to be able to react on event emitted by Control (see Controls below) |
93 | | `@timeline-` | `string` | The method to be called to react on `` events (see Controls below) |
94 |
95 | ## items
96 | Component expects an array of Items
97 |
98 | | Variable | Type | Description |
99 | | --- | --- | --- |
100 | | `id` | `number` | An unique id for your Item |
101 | | `icon` | `string` | The id of the `fontawesome` icon to use |
102 | | `status` | `Status` | A field of the Status enum related to [bootstrap color variant](https://bootstrap-vue.js.org/docs/reference/color-variants/#base-variants) (used for icon and card). |
103 | | `title` | `string` | The Item title |
104 | | `controls` | `Control[]` | An array of control for this Item (see Controls below) |
105 | | `createdDate` | `Date` | Date of your Item (`dateFormat` used to format it) |
106 | | `body` | `string` | The Item content |
107 |
108 | ## Controls
109 | It allows to add buttons on your Item.
110 |
111 | | Variable | Type | Description |
112 | | --- | --- | --- |
113 | | `method` | `string` | A method name used when emitting events |
114 | | `icon` | `string` | The id of the `fontawesome` icon to use |
115 |
116 | ### Event
117 | On button click, an event is emitting using the identifier `timeline-`.
118 |
119 | Events are emitted with the following object as parameter
120 | ```vue
121 | { eventId: this.eventId }
122 | ```
123 | (`this.eventId` matches the id of the Item).
124 |
125 | #### Example
126 | For instance adding the following control
127 | ```vue
128 | new Control("edit", "pencil-alt")
129 | ```
130 | will generate `timeline-edit` event.
131 |
132 | To react on such event, one should provide:
133 | * the following prop to the timeline component:
134 | ```vue
135 | @timeline-edit="edit"`
136 | ```
137 |
138 | * the associated `edit` method which will be called
139 | ```ts
140 | public edit(e: any) {
141 | console.log("edit " + e["eventId"]);
142 | }
143 | ```
144 |
145 | ## Contribute
146 | Once cloned, you can run the following commands to serve the [demo.ts](https://github.com/scottie34/simple-vue-timeline/blob/master/src/demo.ts)
147 | entry point.
148 |
149 | ```shell
150 | npm install
151 | npm run serve
152 | ```
153 |
154 | ### Commit messages
155 | Commit messages must follow the [AngularJS's commit message convention](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) also known as [conventional-changelog](https://github.com/ajoslin/conventional-changelog).
156 | This repo is [commitizen-friendly](https://github.com/commitizen/cz-cli).
157 |
158 | ### Local Test with npm link
159 | You can use [npm link](https://docs.npmjs.com/cli/link.html) to try the lib integration locally.
160 |
161 | Note that you must add a `vue.config.js` in the project using the lib with the following content
162 |
163 | ```js
164 | const path = require("path");
165 |
166 | // npm link https://github.com/vuejs/vue-cli/issues/4271#issuecomment-585299391
167 | module.exports = {
168 | configureWebpack: {
169 | resolve: {
170 | alias: {
171 | vue$: path.resolve("./node_modules/vue/dist/vue.runtime.esm.js")
172 | }
173 | }
174 | }
175 | };
176 | ```
177 |
178 | ## Vue Class Component Sample
179 |
180 | ```vue
181 |
182 |
183 |
191 |
192 |
193 |
194 |
256 | ```
257 |
258 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
2 | title: simple-vue-timeline
3 | description: A simple and customizable timeline vue component
4 | show_downloads: true
5 | google_analytics: UA-162059172-1
6 | markdown: kramdown
7 |
--------------------------------------------------------------------------------
/docs/simple-vue-timeline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scottie34/simple-vue-timeline/2c5dd8381a1567c13c133597c1fc334628af5dab/docs/simple-vue-timeline.png
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | export * from './src/main';
2 |
3 | declare module 'simple-vue-timeline';
4 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
3 | collectCoverage: true,
4 | collectCoverageFrom: [
5 | 'src/**/*.{vue,ts}',
6 | '!src/**/*.d.ts',
7 | '!src/App.vue',
8 | '!src/demo.ts',
9 | '!src/config/**',
10 | '!**/node_modules/**',
11 | '!dist/**',
12 | '!src/plugins/**',
13 | '!src/config/**',
14 | '!tests/unit/**'
15 | ],
16 | coverageReporters: ['lcov', 'text-summary']
17 | };
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simple-vue-timeline",
3 | "version": "2.0.9",
4 | "private": false,
5 | "description": "A timeline vue component",
6 | "scripts": {
7 | "serve": "vue-cli-service serve ./src/demo.ts",
8 | "build": "vue-cli-service build",
9 | "lint": "vue-cli-service lint",
10 | "build-bundle": "vue-cli-service build --target lib --name simple-vue-timeline ./src/main.ts --mode production",
11 | "test:unit": "vue-cli-service test:unit",
12 | "release": "standard-version"
13 | },
14 | "main": "./dist/simple-vue-timeline.common.js",
15 | "files": [
16 | "dist/*",
17 | "src/*",
18 | "public/*",
19 | "*.json",
20 | "*.js",
21 | "*.ts"
22 | ],
23 | "dependencies": {
24 | "@fortawesome/fontawesome-svg-core": "^1.2.28",
25 | "@fortawesome/free-solid-svg-icons": "^5.13.0",
26 | "@fortawesome/vue-fontawesome": "^0.1.9",
27 | "bootstrap-vue": "^2.17.3",
28 | "core-js": "^2.6.11",
29 | "fecha": "^4.2.0",
30 | "postcss-import": "^12.0.1",
31 | "postcss-url": "^8.0.0",
32 | "vue": "^2.6.12",
33 | "vue-class-component": "^7.2.6",
34 | "vue-property-decorator": "^8.4.1"
35 | },
36 | "devDependencies": {
37 | "@babel/polyfill": "^7.11.5",
38 | "@commitlint/cli": "^11.0.0",
39 | "@commitlint/config-conventional": "^11.0.0",
40 | "@types/jest": "^24.0.19",
41 | "@vue/cli-plugin-babel": "^5.0.8",
42 | "@vue/cli-plugin-eslint": "^3.12.1",
43 | "@vue/cli-plugin-typescript": "^3.12.1",
44 | "@vue/cli-plugin-unit-jest": "^5.0.8",
45 | "@vue/cli-service": "^5.0.8",
46 | "@vue/eslint-config-prettier": "^5.1.0",
47 | "@vue/eslint-config-typescript": "^4.0.0",
48 | "@vue/test-utils": "1.0.0-beta.31",
49 | "babel-eslint": "^10.1.0",
50 | "bootstrap": "^4.4.1",
51 | "cz-conventional-changelog": "^3.3.0",
52 | "eslint": "^5.16.0",
53 | "eslint-plugin-prettier": "^3.1.2",
54 | "eslint-plugin-vue": "^5.0.0",
55 | "husky": "^4.3.0",
56 | "lint-staged": "^13.1.0",
57 | "mutationobserver-shim": "^0.3.5",
58 | "node-sass": "^7.0.0",
59 | "popper.js": "^1.16.1",
60 | "portal-vue": "^2.1.7",
61 | "prettier": "^1.19.1",
62 | "sass-loader": "^7.3.1",
63 | "standard-version": "^9.0.0",
64 | "typescript": "^3.8.3",
65 | "vue-cli-plugin-bootstrap-vue": "^0.4.0",
66 | "vue-template-compiler": "^2.6.12"
67 | },
68 | "homepage": "https://scottie34.github.io/simple-vue-timeline/",
69 | "keywords": [
70 | "vue",
71 | "timeline",
72 | "bootstrap",
73 | "fontawesome"
74 | ],
75 | "license": "MIT",
76 | "lint-staged": {
77 | "*.{js,vue,ts}": [
78 | "vue-cli-service lint",
79 | "git add"
80 | ],
81 | "{,src/**/}*.{md,json,js,ts,css,scss}": [
82 | "prettier --write",
83 | "git add"
84 | ]
85 | },
86 | "husky": {
87 | "hooks": {
88 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
89 | }
90 | },
91 | "repository": {
92 | "type": "git",
93 | "url": "https://github.com/scottie34/simple-vue-timeline.git"
94 | },
95 | "config": {
96 | "commitizen": {
97 | "path": "node_modules/cz-conventional-changelog"
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | plugins: {
5 | 'postcss-import': {},
6 | 'postcss-url': {},
7 | // to edit target browsers: use "browserslist" field in package.json
8 | autoprefixer: {}
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
68 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scottie34/simple-vue-timeline/2c5dd8381a1567c13c133597c1fc334628af5dab/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/scss/simple-vue-timeline.scss:
--------------------------------------------------------------------------------
1 | .timeline {
2 | position: relative;
3 | }
4 |
5 | .timeline:before {
6 | background-color: #eee;
7 | bottom: 0;
8 | content: '';
9 | margin-left: -2px;
10 | position: absolute;
11 | top: 0;
12 | width: 4px;
13 | z-index: 1;
14 | height: 100%;
15 | }
16 |
17 | .timeline-icon {
18 | z-index: 2;
19 | }
20 |
21 | .timeline-container {
22 | text-align: center;
23 | }
24 |
--------------------------------------------------------------------------------
/src/assets/scss/vendor.scss:
--------------------------------------------------------------------------------
1 | @import '~bootstrap/scss/bootstrap';
2 |
--------------------------------------------------------------------------------
/src/components/SimpleTimeline.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/components/SimpleTimelineControl.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/components/SimpleTimelineItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ formattedDate }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 | {{ item.body }}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/components/index.d.ts:
--------------------------------------------------------------------------------
1 | import SimpleTimeline from './simple-timeline.component';
2 | import SimpleTimelineItem from './simple-timeline-item.component';
3 | import SimpleTimelineControl from './simple-timeline-control.component';
4 | import { Status } from './simple-timeline-status.model';
5 | import { Item } from './simple-timeline-item.model';
6 | import { Control } from './simple-timeline-control.model';
7 |
8 | export { SimpleTimeline, SimpleTimelineItem, SimpleTimelineControl, Status, Item, Control };
9 |
--------------------------------------------------------------------------------
/src/components/index.js:
--------------------------------------------------------------------------------
1 | import SimpleTimeline from './SimpleTimeline';
2 | import SimpleTimelineItem from './SimpleTimelineItem';
3 | import SimpleTimelineControl from './SimpleTimelineControl';
4 | import { Status } from './simple-timeline-status.model';
5 | import { Item } from './simple-timeline-item.model';
6 | import { Control } from './simple-timeline-control.model';
7 |
8 | export { SimpleTimeline, SimpleTimelineItem, SimpleTimelineControl, Status, Item, Control };
9 |
--------------------------------------------------------------------------------
/src/components/simple-timeline-control.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Prop, Vue } from 'vue-property-decorator';
2 | import { Control } from './simple-timeline-control.model';
3 |
4 | @Component({})
5 | export default class SimpleTimelineControl extends Vue {
6 | @Prop()
7 | public control!: Control;
8 |
9 | @Prop()
10 | public eventId!: number;
11 |
12 | public handleClick() {
13 | this.$parent.$emit('timeline-' + this.control.method, { eventId: this.eventId });
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/simple-timeline-control.model.ts:
--------------------------------------------------------------------------------
1 | export class Control {
2 | method: string;
3 | icon: string;
4 |
5 | constructor(method: string, icon: string) {
6 | this.method = method;
7 | this.icon = icon;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/components/simple-timeline-item.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Prop, Vue } from 'vue-property-decorator';
2 | import { Item } from './simple-timeline-item.model';
3 | import SimpleTimelineControl from './SimpleTimelineControl.vue';
4 | import { format } from 'fecha';
5 |
6 | @Component({
7 | components: {
8 | timelineControl: SimpleTimelineControl
9 | }
10 | })
11 | export default class SimpleTimelineItem extends Vue {
12 | @Prop()
13 | public item!: Item;
14 |
15 | @Prop()
16 | public dateFormat!: string;
17 |
18 | get formattedDate() {
19 | return format(this.item.createdDate, this.dateFormat);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/simple-timeline-item.model.ts:
--------------------------------------------------------------------------------
1 | import { Control } from './simple-timeline-control.model';
2 | import { Status } from './simple-timeline-status.model';
3 |
4 | export class Item {
5 | id: number;
6 | icon: string;
7 | status: Status;
8 | title: string;
9 | controls: Control[];
10 | createdDate: Date;
11 | body: string;
12 |
13 | constructor(id: number, icon: string, status: Status, title: string, controls: Control[], createdDate: Date, body: string) {
14 | this.id = id;
15 | this.icon = icon;
16 | this.status = status;
17 | this.title = title;
18 | this.controls = controls;
19 | this.createdDate = createdDate;
20 | this.body = body;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/components/simple-timeline-status.model.ts:
--------------------------------------------------------------------------------
1 | export const enum Status {
2 | PRIMARY = 'primary',
3 | SUCCESS = 'success',
4 | WARNING = 'warning',
5 | DANGER = 'danger',
6 | INFO = 'info'
7 | }
8 |
--------------------------------------------------------------------------------
/src/components/simple-timeline.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Prop, Vue } from 'vue-property-decorator';
2 | import { Item } from './simple-timeline-item.model';
3 | import SimpleTimelineItem from './SimpleTimelineItem.vue';
4 |
5 | @Component({
6 | components: {
7 | timeline: SimpleTimeline,
8 | timelineItem: SimpleTimelineItem
9 | }
10 | })
11 | export default class SimpleTimeline extends Vue {
12 | @Prop({ default: () => [] })
13 | public items!: Item[];
14 |
15 | @Prop({ default: 'DD/MM/YY' })
16 | public dateFormat!: string;
17 | }
18 |
--------------------------------------------------------------------------------
/src/demo.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './App.vue';
3 | import './assets/scss/vendor.scss';
4 | import './assets/scss/simple-vue-timeline.scss';
5 | import { SimpleTimelinePlugin } from '@/main';
6 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
7 | import { BadgePlugin, ButtonPlugin, CardPlugin, LayoutPlugin } from 'bootstrap-vue';
8 | import { library } from '@fortawesome/fontawesome-svg-core';
9 | import { faTrash } from '@fortawesome/free-solid-svg-icons/faTrash';
10 | import { faPlus } from '@fortawesome/free-solid-svg-icons/faPlus';
11 | import { faPencilAlt } from '@fortawesome/free-solid-svg-icons/faPencilAlt';
12 | import { faTasks } from '@fortawesome/free-solid-svg-icons/faTasks';
13 | import { faBell } from '@fortawesome/free-solid-svg-icons/faBell';
14 | import { faHome } from '@fortawesome/free-solid-svg-icons/faHome';
15 | import { faCalendarAlt } from '@fortawesome/free-solid-svg-icons/faCalendarAlt';
16 |
17 | Vue.config.productionTip = false;
18 |
19 | // font-awesome
20 | library.add(faTrash, faPlus, faPencilAlt, faTasks, faBell, faHome, faCalendarAlt);
21 | Vue.component('font-awesome-icon', FontAwesomeIcon);
22 |
23 | // bootstrap
24 | Vue.use(BadgePlugin);
25 | Vue.use(ButtonPlugin);
26 | Vue.use(CardPlugin);
27 | Vue.use(LayoutPlugin);
28 |
29 | // simpleTimeLine
30 | Vue.use(SimpleTimelinePlugin);
31 |
32 | new Vue({
33 | render: h => h(App)
34 | }).$mount('#app');
35 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import * as components from './components';
2 | import { VueConstructor } from 'vue';
3 | import './assets/scss/simple-vue-timeline.scss';
4 | import { Status, Item, Control } from './components';
5 |
6 | const SimpleTimelinePlugin = {
7 | install(vue: VueConstructor, options = {}) {
8 | for (const component in components) {
9 | // @ts-ignore
10 | if (vue && component && components[component]) {
11 | // @ts-ignore
12 | vue.component(component, components[component]);
13 | }
14 | }
15 | }
16 | };
17 |
18 | export { SimpleTimelinePlugin, Control, Item, Status };
19 |
20 | if (typeof window !== 'undefined' && window.Vue) {
21 | window.Vue.use(SimpleTimelinePlugin);
22 | }
23 |
--------------------------------------------------------------------------------
/src/plugins/bootstrap-vue.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 |
3 | import BootstrapVue from 'bootstrap-vue';
4 | import 'bootstrap/dist/css/bootstrap.min.css';
5 | import 'bootstrap-vue/dist/bootstrap-vue.css';
6 |
7 | Vue.use(BootstrapVue);
8 |
--------------------------------------------------------------------------------
/src/shims-tsx.d.ts:
--------------------------------------------------------------------------------
1 | import Vue, {VNode} from 'vue';
2 |
3 | declare global {
4 | namespace JSX {
5 | // tslint:disable no-empty-interface
6 | interface Element extends VNode {}
7 | // tslint:disable no-empty-interface
8 | interface ElementClass extends Vue {}
9 | interface IntrinsicElements {
10 | [elem: string]: any;
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import Vue from 'vue';
3 | export default Vue;
4 | }
5 |
--------------------------------------------------------------------------------
/tests/unit/simple-timeline-item.spec.ts:
--------------------------------------------------------------------------------
1 | import { createLocalVue, mount, Wrapper, WrapperArray } from '@vue/test-utils';
2 | import SimpleTimelineItem from '@/components/SimpleTimelineItem.vue';
3 | import { Item } from '@/components/simple-timeline-item.model';
4 | import { Status } from '@/components/simple-timeline-status.model';
5 | import { Control } from '@/components/simple-timeline-control.model';
6 | import Vue, { VueConstructor } from 'vue';
7 | import { SimpleTimelinePlugin } from '@/main';
8 | import { BadgePlugin, ButtonPlugin, CardPlugin, LayoutPlugin } from "bootstrap-vue";
9 |
10 | const localVue: VueConstructor = createLocalVue();
11 | // bootstrap
12 | Vue.use(BadgePlugin);
13 | Vue.use(ButtonPlugin);
14 | Vue.use(CardPlugin);
15 | Vue.use(LayoutPlugin);
16 |
17 | localVue.use(SimpleTimelinePlugin);
18 |
19 | describe('SimpleTimelineItem.vue', () => {
20 | it('renders passed props', () => {
21 | const title = 'Event Title';
22 | const body = 'Here is the body message of item 0';
23 | const controls = [new Control('edit', 'pencil-alt'), new Control('copy', 'plus')];
24 | const itemIcon = 'calendar-alt';
25 |
26 | const wrapper = mount(SimpleTimelineItem, {
27 | localVue,
28 | propsData: {
29 | item: new Item(0, itemIcon, Status.DANGER, title, controls, new Date(2020, 10, 8), body),
30 | dateFormat: 'YY/MM/DD'
31 | },
32 | stubs: {
33 | FontAwesomeIcon: true
34 | }
35 | });
36 | verifyIcon(wrapper.get('.timeline-icon'), itemIcon);
37 | expect(wrapper.get('.text-muted').text()).toBe('20/11/08');
38 | expect(wrapper.get('.card-header').text()).toBe(title);
39 | expect(wrapper.get('.card-body').text()).toBe(body);
40 |
41 | let wrapperArray: WrapperArray = wrapper.get('.card-footer').findAll('button');
42 | expect(wrapperArray.length).toBe(controls.length);
43 | controls.forEach((control, index) => {
44 | verifyIcon(wrapperArray.at(index), control.icon);
45 | });
46 | });
47 | });
48 |
49 | function verifyIcon(wrapper: Wrapper, icon: string) {
50 | expect(wrapper.get('fontawesomeicon-stub').attributes('icon')).toBe(icon);
51 | }
52 |
--------------------------------------------------------------------------------
/tests/unit/simple-timeline.spec.ts:
--------------------------------------------------------------------------------
1 | import { createLocalVue, mount, Wrapper, WrapperArray } from '@vue/test-utils';
2 | import { Item } from '@/components/simple-timeline-item.model';
3 | import { Status } from '@/components/simple-timeline-status.model';
4 | import { Control } from '@/components/simple-timeline-control.model';
5 | import Vue, { VueConstructor } from 'vue';
6 | import SimpleTimeline from '@/components/SimpleTimeline.vue';
7 | import { SimpleTimelinePlugin } from '@/main';
8 | import { BadgePlugin, ButtonPlugin, CardPlugin, LayoutPlugin } from "bootstrap-vue";
9 |
10 | const localVue: VueConstructor = createLocalVue();
11 | // bootstrap
12 | Vue.use(BadgePlugin);
13 | Vue.use(ButtonPlugin);
14 | Vue.use(CardPlugin);
15 | Vue.use(LayoutPlugin);
16 |
17 | localVue.use(SimpleTimelinePlugin);
18 |
19 | describe('SimpleTimeline.vue', () => {
20 | it('renders passed props to SimpleTimeline', () => {
21 | const title = 'Event Title';
22 | const body = 'Here is the body message of item 0';
23 | const controls = [new Control('edit', 'pencil-alt'), new Control('copy', 'plus')];
24 | const itemIcon = 'calendar-alt';
25 |
26 | const wrapper = mount(SimpleTimeline, {
27 | localVue,
28 | propsData: {
29 | items: [
30 | new Item(0, itemIcon, Status.DANGER, title, controls, new Date(2020, 10, 8), body),
31 | new Item(1, itemIcon, Status.INFO, title, controls, new Date(2019, 8, 12), body)
32 | ],
33 | dateFormat: 'YY/MM/DD'
34 | },
35 | stubs: {
36 | FontAwesomeIcon: true
37 | }
38 | });
39 | verifyIcon(wrapper.get('.timeline-icon'), itemIcon);
40 | expect(wrapper.get('.text-muted').text()).toBe('20/11/08');
41 | expect(wrapper.get('.card-header').text()).toBe(title);
42 | expect(wrapper.get('.card-body').text()).toBe(body);
43 |
44 | let wrapperArray: WrapperArray = wrapper.get('.card-footer').findAll('button');
45 | expect(wrapperArray.length).toBe(controls.length);
46 | controls.forEach((control, index) => {
47 | verifyIcon(wrapperArray.at(index), control.icon);
48 | });
49 | });
50 | });
51 |
52 | function verifyIcon(wrapper: Wrapper, icon: string) {
53 | expect(wrapper.get('fontawesomeicon-stub').attributes('icon')).toBe(icon);
54 | }
55 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "esnext",
5 | "strict": true,
6 | "jsx": "preserve",
7 | "importHelpers": true,
8 | "moduleResolution": "node",
9 | "experimentalDecorators": true,
10 | "esModuleInterop": true,
11 | "allowSyntheticDefaultImports": true,
12 | "sourceMap": true,
13 | "baseUrl": ".",
14 | "types": [
15 | "webpack-env",
16 | "jest"
17 | ],
18 | "paths": {
19 | "@/*": [
20 | "src/*"
21 | ]
22 | },
23 | "lib": [
24 | "esnext",
25 | "dom",
26 | "dom.iterable",
27 | "scripthost"
28 | ]
29 | },
30 | "include": [
31 | "src/**/*.ts",
32 | "src/**/*.tsx",
33 | "src/**/*.vue",
34 | "tests/**/*.ts",
35 | "tests/**/*.tsx"
36 | ],
37 | "exclude": [
38 | "node_modules"
39 | ]
40 | }
--------------------------------------------------------------------------------