├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── feature_request.md
│ └── questions.md
├── .gitignore
├── .gitmodules
├── .storybook
├── addons.js
└── config.js
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── bili.config.js
├── docs
├── .nojekyll
├── README.md
├── _coverpage.md
├── _sidebar.md
├── assets
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon.png
│ ├── browserconfig.xml
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── mstile-150x150.png
│ ├── osiris.css
│ ├── osiris.svg
│ ├── safari-pinned-tab.svg
│ └── site.webmanifest
├── button.md
├── checkbox.md
├── color.md
├── form.md
├── icon.md
├── index.html
├── input.md
├── layout.md
├── quick-start.md
├── radio.md
└── typography.md
├── osiris.svg
├── out730
└── favicon.ico
├── package-lock.json
├── package.json
└── src
├── __snapshots__
└── storyshots.spec.js.snap
├── button
├── __snapshots__
│ └── button.spec.js.snap
├── button.spec.js
├── button.stories.js
├── button.vue
└── index.js
├── checkbox
├── checkbox.spec.js
├── checkbox.stories.js
├── checkbox.vue
└── index.js
├── col
├── __snapshots__
│ └── col.spec.js.snap
├── col.spec.js
├── col.stories.js
├── col.vue
└── index.js
├── form
├── form.stories.js
├── form.vue
└── index.js
├── formItem
├── formItem.vue
└── index.js
├── icons
└── icons.stories.js
├── index.js
├── input
├── __snapshots__
│ └── input.spec.js.snap
├── index.js
├── input.spec.js
├── input.stories.js
└── input.vue
├── mixins
└── dispatch.js
├── radio
├── index.js
├── radio.spec.js
├── radio.stories.js
└── radio.vue
├── row
├── __snapshots__
│ └── row.spec.js.snap
├── index.js
├── row.spec.js
├── row.stories.js
└── row.vue
├── select
├── Select.vue
├── index.js
├── select.spec.js
└── select.stories.js
└── storyshots.spec.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["lodash"],
3 | "presets": [
4 | ["env", { "modules": false }]
5 | ],
6 | "env": {
7 | "test": {
8 | "presets": [
9 | ["env", { "targets": { "node": "current" }}]
10 | ]
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_size = 2
6 | indent_style = space
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | /node_modules/*
2 | /src/osiris-style/*
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | parser: 'babel-eslint',
5 | },
6 | env: {
7 | browser: true,
8 | node: true,
9 | jest: true,
10 | },
11 | extends: [
12 | 'plugin:vue/recommended',
13 | 'airbnb-base',
14 | ],
15 | // required to lint *.vue files
16 | plugins: [
17 | 'vue',
18 | ],
19 | // add your custom rules here
20 | rules: {
21 | 'import/extensions': 0,
22 | 'global-require': 0,
23 | "no-param-reassign": 0,
24 | 'import/no-unresolved': 0,
25 | 'no-underscore-dangle': 0,
26 | 'no-array-constructor': 0,
27 | 'no-new-object': 0,
28 | 'func-names': 1,
29 | 'linebreak-style': 0,
30 | 'import/no-extraneous-dependencies': 0,
31 | 'vue/require-default-prop': 0,
32 | },
33 | globals: {},
34 | }
35 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | **Describe the bug**
8 | A clear and concise description of what the bug is.
9 |
10 | **To Reproduce**
11 | Steps to reproduce the behavior:
12 | 1. Go to '...'
13 | 2. Click on '....'
14 | 3. Scroll down to '....'
15 | 4. See error
16 |
17 | **Expected behavior**
18 | A clear and concise description of what you expected to happen.
19 |
20 | **Screenshots**
21 | If applicable, add screenshots to help explain your problem.
22 |
23 | **Desktop (please complete the following information):**
24 | - OS: [e.g. iOS]
25 | - Browser [e.g. chrome, safari]
26 | - Version [e.g. 22]
27 |
28 | **Smartphone (please complete the following information):**
29 | - Device: [e.g. iPhone6]
30 | - OS: [e.g. iOS8.1]
31 | - Browser [e.g. stock browser, safari]
32 | - Version [e.g. 22]
33 |
34 | **Additional context**
35 | Add any other context about the problem here.
36 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | **Is your feature request related to a problem? Please describe.**
8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Describe alternatives you've considered**
14 | A clear and concise description of any alternative solutions or features you've considered.
15 |
16 | **Additional context**
17 | Add any other context or screenshots about the feature request here.
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/questions.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Questions
3 | about: Ask any question
4 |
5 | ---
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
63 | dist/
64 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/osiris-style"]
2 | path = src/osiris-style
3 | url = https://github.com/osiris-ui/osiris-style.git
4 | branch = master
5 |
--------------------------------------------------------------------------------
/.storybook/addons.js:
--------------------------------------------------------------------------------
1 | import '@storybook/addon-knobs/register';
2 |
--------------------------------------------------------------------------------
/.storybook/config.js:
--------------------------------------------------------------------------------
1 | import { configure } from '@storybook/vue';
2 | import Vue from 'vue';
3 |
4 | import '../src/osiris-style/dist/osiris-style.css';
5 |
6 | // Import your custom components.
7 |
8 | // Install Vue plugins.
9 | // Vue.use(Vuex);
10 |
11 | function loadStories() {
12 | const req = require.context('../src', true, /\.stories\.js$/);
13 | req.keys().forEach(filename => req(filename));
14 | }
15 |
16 |
17 | configure(loadStories, module);
18 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "lts/*"
4 | git:
5 | submodules: false
6 | cache:
7 | directories:
8 | "node_modules"
9 | before_script:
10 | - npm run build
11 | after_success:
12 | - bash <(curl -s https://codecov.io/bash) -e TRAVIS_NODE_VERSION
13 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Osiris UI Contributing Guide
2 |
3 | In order to maintain the lib organized, please follow this steps before send any pull requests.
4 |
5 | 1) Create an issue or grab an issue before send your PR's (for beginners see [good first issues](https://github.com/osiris-ui/osiris/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)).
6 | 2) Fork the repository to your Github's account.
7 | 3) Go to the repository folder and run `npm install`.
8 | 4) If your change's *doens't* envolve any css files, follow this commands:
9 | - Run these commands
10 | ```sh
11 | git submodule update --init --recursive
12 | ```
13 | 5) If your change *envolves* any css file, please follow this commands
14 | - Fork the [osiris-style](https://github.com/osiris-ui/osiris-style) repo.
15 | - In the `osiris` repo, run these commands
16 | ```sh
17 | git submodule update --init --recursive
18 | ```
19 | - Go to `src/osiris-style`
20 | - Run `git remote rename origin upstream`
21 | - Run `git remote add origin YOUR-FORK-GIT-LINK`
22 | - Run `npm install`
23 | - Run `npm run dev`
24 | - Modify the sass files (they will be compiled in real time)
25 | - Push the modifications to your fork (git push origin master) and open a PR
26 | 6) Run the project with `npm run dev`, the storybook will be available at `http://localhost:9001`
27 | 7) If you need to change any doc file and want to preview, you need `docsify` installed
28 | ```
29 |
30 | If you have any question please, [open a issue](https://github.com/osiris-ui/osiris/issues)!
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Cotabox
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 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | > A Vue.js 2.0 universal responsive UI component library..
15 |
16 | ### 🚧 Only for study purposes, do not use in production
17 |
18 | ## Docs
19 |
20 | * [**Home Page**](https://osiris-ui.github.io/osiris/#/)
21 | * [**Storybook**](https://osiris.netlify.com/)
22 |
23 | ## Getting Started
24 |
25 | Check out the [Quick Start](https://osiris-ui.github.io/osiris/#/quick-start) documentation to get started.
26 |
27 | ## Contributing
28 |
29 | Check out the [Contributing Guide](CONTRIBUTING.md) for more details.
30 |
31 | ### Credits
32 |
33 | Osiris UI is a open source project that originally follow the free styleguide created by Wagner Ramos, that you can [see here](https://dribbble.com/shots/4828637--Osiris-UI-Kit-Free-Sketch-Resource), we also have inspiration in the [UIDE Kit](https://dribbble.com/shots/3366725-UIDE-Kit-Style-Guide-Template-FREEBIE), that is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0).
34 |
35 | All modifications and new features does not need necessarely to follow one of theses two styleguides, they just inpired us to built a beauty UI lib.
36 |
--------------------------------------------------------------------------------
/bili.config.js:
--------------------------------------------------------------------------------
1 | const vue = require('rollup-plugin-vue');
2 |
3 | module.exports = {
4 | outDir: 'dist',
5 | babel: {
6 | babelrc: false,
7 | },
8 |
9 | formats: ['es', 'umd', 'umd-min'],
10 |
11 | banner: true,
12 | css: true,
13 |
14 | plugins: [
15 | vue({ css: true }),
16 | ],
17 | };
18 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osiris-ui/osiris/503636369aaaa41c11d74dda93248b81ed6bc59b/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Osiris UI
2 |
3 | > A Vue.js 2.0 universal responsive UI component library
4 |
5 | ### 🚧 Under development, we working to release 1.0.0 very soon :fire:
6 |
7 | ## Docs
8 |
9 | * [**Home Page**](https://osiris-ui.github.io/osiris/#/)
10 | * [**Storybook**](https://osiris.netlify.com/)
11 |
12 | ## Getting Started
13 |
14 | Check out the [Quick Start](quick-start.md) documentation to get started.
15 |
16 | ## Contributing
17 |
18 | Check out the [Contributing Guide](https://github.com/osiris-ui/osiris/blob/master/CONTRIBUTING.md) for more details.
19 |
20 | ### Credits
21 |
22 | Osiris UI is a open source project that originally follow the free styleguide created by Wagner Ramos, that you can [see here](https://dribbble.com/shots/4828637--Osiris-UI-Kit-Free-Sketch-Resource), we also have inspiration in the [UIDE Kit](https://dribbble.com/shots/3366725-UIDE-Kit-Style-Guide-Template-FREEBIE), that is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0).
23 |
24 | All modifications and new features does not need necessarely to follow one of theses two styleguides, they just inpired us to built a beauty UI lib.
25 |
--------------------------------------------------------------------------------
/docs/_coverpage.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | > A Vue.js 2.0 universal responsive UI component library.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | [Github](https://github.com/osiris-ui/osiris)
18 | [Get Started](README.md)
19 |
20 |
21 | 
22 |
--------------------------------------------------------------------------------
/docs/_sidebar.md:
--------------------------------------------------------------------------------
1 | - Getting Started
2 | - [Overview](README.md)
3 | - [Quick Start](quick-start.md)
4 |
5 | - Basic
6 | - [Layout](layout.md)
7 | - [Color](color.md)
8 | - [Typography](typography.md)
9 | - [Button](button.md)
10 | - [Icon](icon.md)
11 |
12 | - Form
13 | - [Form](form.md)
14 | - [Input](input.md)
15 | - [Radio](radio.md)
16 | - [Checkbox](checkbox.md)
17 |
18 | - [Contributing](CONTRIBUTING.md)
19 |
--------------------------------------------------------------------------------
/docs/assets/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osiris-ui/osiris/503636369aaaa41c11d74dda93248b81ed6bc59b/docs/assets/android-chrome-192x192.png
--------------------------------------------------------------------------------
/docs/assets/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osiris-ui/osiris/503636369aaaa41c11d74dda93248b81ed6bc59b/docs/assets/android-chrome-512x512.png
--------------------------------------------------------------------------------
/docs/assets/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osiris-ui/osiris/503636369aaaa41c11d74dda93248b81ed6bc59b/docs/assets/apple-touch-icon.png
--------------------------------------------------------------------------------
/docs/assets/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #ff2f54
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/assets/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osiris-ui/osiris/503636369aaaa41c11d74dda93248b81ed6bc59b/docs/assets/favicon-16x16.png
--------------------------------------------------------------------------------
/docs/assets/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osiris-ui/osiris/503636369aaaa41c11d74dda93248b81ed6bc59b/docs/assets/favicon-32x32.png
--------------------------------------------------------------------------------
/docs/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osiris-ui/osiris/503636369aaaa41c11d74dda93248b81ed6bc59b/docs/assets/favicon.ico
--------------------------------------------------------------------------------
/docs/assets/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osiris-ui/osiris/503636369aaaa41c11d74dda93248b81ed6bc59b/docs/assets/mstile-150x150.png
--------------------------------------------------------------------------------
/docs/assets/osiris.css:
--------------------------------------------------------------------------------
1 | /* LAYOUT CLASSES */
2 |
3 | .box-1, .box-2 {
4 | padding: 10px 0;
5 | margin-bottom: 5px;
6 | width: 100%;
7 | border-radius: 5px;
8 | }
9 |
10 | .box-1 {
11 | background-color: rgba(0, 153, 249, .5);
12 | }
13 |
14 | .box-2 {
15 | background-color: rgba(38, 93, 127, .5);
16 | }
17 |
18 |
19 | /* COLORS CLASSES */
20 |
21 | .color-demobox {
22 | padding: 10px;
23 | text-align: center;
24 | display: inline-block;
25 | margin-right: 5px;
26 | vertical-align: top;
27 | width: 102px;
28 | border: 1px solid #dfe6ee;
29 | }
30 |
31 | .color-demobox .box {
32 | width: 80px;
33 | height: 80px;
34 | margin-bottom: 5px;
35 | }
36 |
37 | .color-demobox p {
38 | margin: 0;
39 | /*color: #313541;*/
40 | }
41 |
42 | /* ICONS CLASSES */
43 |
44 | .icon-demobox {
45 | padding: 10px;
46 | text-align: center;
47 | margin-right: 5px;
48 | vertical-align: top;
49 | border: 1px solid #dfe6ee;
50 | width: 24%;
51 | box-sizing: border-box;
52 | margin-top: 10px;
53 | }
54 |
55 | .icon-demobox .box {
56 | margin-bottom: 5px;
57 | }
58 |
59 | .icon-demobox p {
60 | margin: 0;
61 | /*color: #313541;*/
62 | }
63 |
--------------------------------------------------------------------------------
/docs/assets/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 | Created by potrace 1.11, written by Peter Selinger 2001-2013
9 |
10 |
12 |
166 |
168 |
170 |
172 |
174 |
176 |
178 |
180 |
182 |
184 |
186 |
188 |
190 |
193 |
196 |
199 |
202 |
205 |
208 |
210 |
212 |
213 |
214 |
--------------------------------------------------------------------------------
/docs/assets/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "short_name": "",
4 | "icons": [
5 | {
6 | "src": "android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/docs/button.md:
--------------------------------------------------------------------------------
1 | # Button
2 |
3 | | Attribute | Description | Type | Accepted Value | Default |
4 | |--|--|--|--|--|
5 | | size | size of button | String | large/normal/small/mini | normal |
6 | | type | button visual type | String | default/primary/secondary/tertiary /success/warning/danger/text | default |
7 | | plain | whether a plain button | Boolean | true/false | false |
8 | | round | whether a round button | Boolean | true/false | false |
9 | | circle | whether a circle button | Boolean | true/false | false |
10 | | disabled | if button is disabled | Boolean | true/false | false |
11 | | nativeType | same as native button type | String | button/submit | button |
12 |
13 | ## Types
14 | ```html
15 | /*vue*/
16 |
17 |
18 |
19 |
Default
20 |
Primary
21 |
Secondary
22 |
Tertiary
23 |
24 | Success
25 | Warning
26 | Danger
27 | Text
28 |
29 |
30 |
31 |
32 |
35 | ```
36 |
37 | ## Plain
38 | ```html
39 | /*vue*/
40 |
41 |
42 |
43 |
Default
44 |
Primary
45 |
Secondary
46 |
Tertiary
47 |
48 | Success
49 | Warning
50 | Danger
51 |
52 |
53 |
54 |
55 |
58 | ```
59 |
60 | ## Disabled
61 | ```html
62 | /*vue*/
63 |
64 |
65 |
66 |
67 |
Default
68 |
Primary
69 |
Secondary
70 |
Tertiary
71 |
72 | Success
73 | Warning
74 | Danger
75 | Text
76 |
77 |
78 |
79 |
Default
80 |
Primary
81 |
Secondary
82 |
Tertiary
83 |
84 | Success
85 | Warning
86 | Danger
87 | Text
88 |
89 |
90 |
91 |
92 |
93 |
96 | ```
97 |
98 | ## Sizes
99 | ```html
100 | /*vue*/
101 |
102 |
103 |
104 |
105 | Large
106 | Normal
107 | Small
108 | Mini
109 |
110 |
111 | Large
112 | Normal
113 | Small
114 | Mini
115 |
116 |
117 | Large
118 | Normal
119 | Small
120 | Mini
121 |
122 |
123 | Large
124 | Normal
125 | Small
126 | Mini
127 |
128 |
129 | Large
130 | Normal
131 | Small
132 | Mini
133 |
134 |
135 | Large
136 | Normal
137 | Small
138 | Mini
139 |
140 |
141 | Large
142 | Normal
143 | Small
144 | Mini
145 |
146 |
147 | Large
148 | Normal
149 | Small
150 | Mini
151 |
152 |
153 |
154 |
155 |
158 | ```
159 | ## Round
160 | ```html
161 | /*vue*/
162 |
163 |
164 |
165 |
Default
166 |
Primary
167 |
Secondary
168 |
Tertiary
169 |
170 | Success
171 | Warning
172 | Danger
173 |
174 |
175 |
176 |
177 |
180 | ```
181 |
182 | ## Circle
183 |
184 | ```html
185 | /*vue*/
186 |
187 |
188 |
189 | D
190 | P
191 | S
192 | T
193 | SC
194 | W
195 | D
196 |
197 |
198 |
199 |
202 | ```
203 |
--------------------------------------------------------------------------------
/docs/checkbox.md:
--------------------------------------------------------------------------------
1 | # Checkbox
2 |
3 | ## Basic Usage
4 | ```html
5 | /*vue*/
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 | ```
24 |
25 | ## Disabled
26 |
27 | ```html
28 | /*vue*/
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
46 | ```
47 |
--------------------------------------------------------------------------------
/docs/color.md:
--------------------------------------------------------------------------------
1 | # Color
2 |
3 | This are the set of colors used in all Atlas components.
4 |
5 | ## Main Color
6 |
7 |
8 |
9 |
Primary
10 |
#FF2F54
11 |
12 |
13 |
14 |
15 |
Secondary
16 |
#141334
17 |
18 |
19 | ## Additional
20 |
21 |
22 |
23 |
Info
24 |
#2B9FEA
25 |
26 |
27 |
28 |
29 |
30 |
Success
31 |
#17C671
32 |
33 |
34 |
35 |
36 |
37 |
Warning
38 |
#FFB400
39 |
40 |
41 |
42 |
43 |
44 |
Danger
45 |
#C4183C
46 |
47 |
48 | ## Lines, borders and shadows
49 |
50 |
54 |
55 |
59 |
60 |
64 |
65 |
69 |
70 |
74 |
75 | ## Text colors
76 |
77 |
81 |
82 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/docs/form.md:
--------------------------------------------------------------------------------
1 | # Form
2 |
3 | We created a integrated form validation system, heavily inspired on [Element](https://element.eleme.io) validation. The validation system works on top of [Validate.js](https://validatejs.org), a free and open source validation library.
4 |
5 | ## Basic Usage
6 |
7 | ```html
8 | /* vue */
9 |
10 |
11 |
16 |
17 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
32 | Yes
33 | No
34 |
35 |
36 |
39 | Javascript
40 | PHP
41 | Python
42 | Ruby
43 |
44 |
45 | Validate
46 | Clear validation
47 |
48 |
49 |
50 |
114 | ```
115 |
116 | ## Form Attrs
117 |
118 | | Attribute | Description | Type | Accepted Value | Default |
119 | |--|--|--|--|--|
120 | | model | The form object from data | type Object | | |
121 | | rules | Global rules usage | Object | | |
122 | | labelPosition | position of label | String | top/left/right | top |
123 | | labelWitdh | width of label | String | | 100px |
124 | | width | form width | String | | 100% |
125 |
126 |
127 | ## Form Item Attrs
128 |
129 | | Attribute | Description | Type | Accepted Value | Default |
130 | |--|--|--|--|--|
131 | | label | Label content | String | | |
132 | | prop | A key property from form model | String | | |
133 | | rules | Rules for this formItem (if not provided in the main form) | | | | |
134 |
135 |
136 | ## Form Events
137 |
138 | | Event Name | Description | Params |
139 | | -- | -- | -- |
140 | | submit | same as native submit | | |
141 |
142 | ## Form Methods
143 |
144 | | Method Name | Description | Params |
145 | | -- | -- | -- |
146 | | validate | Trigger this method to validate all fields | | |
147 |
148 | ## FormItem Methods
149 | | Method Name | Description | Params |
150 | | -- | -- | -- |
151 | | validate | Trigger this method to validate the Form Item content | value (non required) |
152 |
--------------------------------------------------------------------------------
/docs/icon.md:
--------------------------------------------------------------------------------
1 | # Icon
2 |
3 | For icons we choose a free open source solution called [Feather Icons](https://feathericons.com/) through a fork from [AT-UI](https://github.com/AT-UI/feather-font).
4 |
5 | ## Basic Usage
6 | ```html
7 | /*vue*/
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 | ```
20 |
21 | ## Full list
22 |
23 | ```html
24 | /*vue*/
25 |
26 |
27 |
28 |
29 |
30 |
36 |
37 |
38 |
39 |
40 |
41 |
{{icon}}
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
308 | ```
309 |
310 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Osiris - A Vue.js 2.0 universal responsive UI component library
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/docs/input.md:
--------------------------------------------------------------------------------
1 | ## Input
2 |
3 | | Attribute | Description | Type | Accepted Value | Default |
4 | |--|--|--|--|--|
5 | | width | width of input | String | | '300px' |
6 | | prefixIcon | wheather has a prefix icon | String | | |
7 | | suffixIcon | wheather has a suffix icon | String | | |
8 | | size | size of input | String | large/normal/small/mini | normal |
9 | | readonly | whether is a readonly input | Boolean | true/false | false |
10 | | disabled | if input is disabled | Boolean | true/false | false |
11 | | isSuccess | whether has a success status | Boolean | true/false | false |
12 | | isError | whether has a error status | Boolean | true/false | false |
13 | | name | same as native name attr | String | | |
14 | | placeholder | same as native placeholder attr | String | | |
15 | | type | same as native type attr | String | | text |
16 |
17 | ## Basic Usage
18 |
19 | ```html
20 | /*vue*/
21 |
22 |
23 |
24 |
25 |
26 |
29 | ```
30 |
31 | ## Custom width
32 |
33 | ```html
34 | /*vue*/
35 |
36 |
37 |
38 |
39 |
40 |
43 | ```
44 |
45 | ## With icon
46 |
47 | ```html
48 | /*vue*/
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
60 | ```
61 |
62 | ## With status
63 |
64 | ```html
65 | /*vue*/
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
77 | ```
78 |
79 | ## Sizes
80 |
81 | ```html
82 | /*vue*/
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
100 | ```
101 |
102 |
103 | ## Disabled
104 |
105 | ```html
106 | /*vue*/
107 |
108 |
109 |
110 |
111 |
112 |
115 | ```
116 |
117 | ## Readonly
118 |
119 | ```html
120 | /*vue*/
121 |
122 |
123 |
124 |
125 |
126 |
129 | ```
130 |
131 |
--------------------------------------------------------------------------------
/docs/layout.md:
--------------------------------------------------------------------------------
1 | # Layout
2 |
3 | We use a flex based grid system with 24 columns with a 20px gutter by default.
4 |
5 | ### Row Attributes
6 |
7 | | Attribute | Description | Type | Accepted Value | Default |
8 | |--|--|--|--|--|
9 | | gutter | grid spacing | number | - | 20 |
10 | | direction | direction of layout | string | row/row-reverse/column/column-reverse | row |
11 | | wrap | how content will wrap | string | wrap/nowrap/wrap-reverse | wrap |
12 | | justify | horizontal alignment | string | flex-start/flex-end/center/space-around/space-between/space-evenly | flex-start |
13 | | align | vertical alignment | string | flex-start/flex-end/center/baseline/stretch | flex-start |
14 | | content | content alignment | string | flex-start/flex-end/center/space-between/space-around/stretch | flex-start |
15 |
16 |
17 | ### Col Attributes
18 |
19 | | Attribute | Description | Type | Accepted Value | Default |
20 | |--|--|--|--|--|
21 | | span | column width | number | 0-24 | 24 |
22 | | offset | column spacing | number | 0-24 | 0 |
23 | | xs | column width for `<768px` | number/object (e.g { span: 4, offset: 4 }) | 0-24/object | - |
24 | | sm | column width for `≥768px` | number/object (e.g { span: 4, offset: 4 }) | 0-24/object | - |
25 | | md | column width for `≥992px` | number/object (e.g { span: 4, offset: 4 }) | 0-24/object | - |
26 | | lg | column width for `≥1200px` | number/object (e.g { span: 4, offset: 4 }) | 0-24/object | - |
27 | | xl | column width for `≥1920px` | number/object (e.g { span: 4, offset: 4 }) | 0-24/object | - |
28 |
29 | ## Basic Usage
30 |
31 | ```html
32 | /*vue*/
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
71 | ```
72 |
--------------------------------------------------------------------------------
/docs/quick-start.md:
--------------------------------------------------------------------------------
1 | # Quick Start
2 |
3 | To get started with Osiris UI is pretty simple, the only dependency is `vue`, we always recommend use in the newest version possible.
4 |
5 | ## Installation
6 |
7 | There are many ways on how to use Osiris UI, follow those who better fits your need's.
8 |
9 | ### CDN
10 |
11 | ```html
12 |
13 |
14 |
15 |
16 |
17 | ```
18 |
19 |
20 | ### ES Module
21 |
22 | There's a few ways on how to use in a node.js project
23 |
24 | #### Using as plugin
25 |
26 | ``` js
27 | import Vue from 'vue';
28 | import Osiris from '@osiris-ui/osiris';
29 |
30 | Vue.use(Osiris);
31 | ```
32 |
33 | #### Using as component
34 |
35 | ``` js
36 | import { button as OButton } from '@osiris-ui/osiris';
37 | ```
38 |
39 | #### Importing globally only few components
40 | ```js
41 | import Vue from 'vue';
42 | import { button, input } from '@osiris-ui/osiris';
43 |
44 | Vue.component(button.name, button);
45 | Vue.component(input.name, input);
46 | ```
47 |
48 | *Don't forget to include the Osiris css theme*
49 |
50 |
51 | ## Custom Theme
52 |
53 | Osiris theme use sass as pre-processor. To customize themes and colors, you gonna need follow this steps:
54 |
55 | - Install the Osiris Theme running: `npm install --save @osiris-ui/style`
56 | - Install `node-sass` and `sass-loader`: `npm install --save node-sass sass-loader`
57 | - Create two files: `app.scss` and `variables.scss` (You can set any name and put these files in any folder that you find better).
58 | - In `variables.scss`, copy all the content from `@osiris-ui/style/src/variables.scss`, this is the main file you need to customize with the colors and others visual things.
59 | - In `app.scss`, copy all the content from `@osiris-ui/style/src/index.scss`, and replace the path to the respective destination in your `node_modules`, like:
60 |
61 | ```scss
62 | @import '../node_modules/@osiris-ui/style/src/reset';
63 | @import '../node_modules/@osiris-ui/style/src/icons';
64 | @import '../node_modules/@osiris-ui/style/src/row';
65 | @import '../node_modules/@osiris-ui/style/src/col';
66 | @import '../node_modules/@osiris-ui/style/src/button';
67 | @import '../node_modules/@osiris-ui/style/src/input';
68 | @import '../node_modules/@osiris-ui/style/src/radio';
69 | @import '../node_modules/@osiris-ui/style/src/form';
70 | /* ETC... */
71 | ```
72 | - Finally, you can import the `app.scss` in your application
73 | - If you use a CDN project, you need to compile the scss files to a css file, create a simple project that has node-sass and sass-loader as dependencies and finally create a script that run node-sass, like this: `node-sass --include-path $PATH $PATH/app.scss dist/osiris-style.css --output-style compressed`
74 |
75 | In the future we plan to create a more easily tool for customizing all variables, colors and other stuffs of Osiris UI.
76 |
--------------------------------------------------------------------------------
/docs/radio.md:
--------------------------------------------------------------------------------
1 | # Radio
2 |
3 | ## Basic Usage
4 | ```html
5 | /*vue*/
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 | ```
24 |
25 | ## Disabled
26 |
27 | ```html
28 | /*vue*/
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
46 | ```
47 |
--------------------------------------------------------------------------------
/docs/typography.md:
--------------------------------------------------------------------------------
1 | # Typography
2 |
3 | The font chosen was Lato, which is avaiable at [Google Fonts](https://fonts.google.com/specimen/Lato). Check out the application and sizes:
4 |
5 |
6 | ## Headings
7 |
8 | > H1
9 |
10 | We used to look up at the sky and wonder at our place in the stars. Now we just look down, and worry about our place in the dirt.
11 |
12 | > H2
13 |
14 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nam expedita dolorum doloribus voluptatum quia ea, natus non earum sequi.
15 |
16 | > H3
17 |
18 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nam expedita dolorum doloribus voluptatum quia ea, natus non earum sequi.
19 |
20 | > H4
21 |
22 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nam expedita dolorum doloribus voluptatum quia ea, natus non earum sequi.
23 |
24 | > H5
25 |
26 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nam expedita dolorum doloribus voluptatum quia ea, natus non earum sequi.
27 |
28 | > H6
29 |
30 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nam expedita dolorum doloribus voluptatum quia ea, natus non earum sequi.
31 |
32 | ## Paragraphs
33 |
34 | > p
35 |
36 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Recusandae ut facere rerum, asperiores debitis, culpa blanditiis ratione at tempora beatae eaque maxime magni reprehenderit! Voluptates in, amet consectetur dignissimos natus suscipit veniam, possimus qui excepturi impedit sapiente illo. Quae ab voluptatibus nulla ratione. Nulla doloribus animi similique libero mollitia maxime!
37 |
38 | > p.small
39 |
40 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur quos sunt soluta odit magni fugiat libero quasi optio dolor ut minima iure, fugit voluptatum eum debitis reiciendis ad accusantium. Minus nam eos officia iure dicta provident est dolores accusamus obcaecati pariatur ratione, sed, quas nulla ad voluptatum aliquam veniam ex?
41 |
42 | > small
43 |
44 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit, quo!
45 |
46 | > small.small
47 |
48 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit, quo!
49 |
--------------------------------------------------------------------------------
/out730/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osiris-ui/osiris/503636369aaaa41c11d74dda93248b81ed6bc59b/out730/favicon.ico
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@osiris-ui/osiris",
3 | "version": "0.9.0",
4 | "description": "A Vue.js 2.0 universal responsive UI component library",
5 | "main": "dist/osiris.js",
6 | "module": "dist/osiris.es.js",
7 | "unpkg": "dist/osiris.min.js",
8 | "files": [
9 | "dist"
10 | ],
11 | "scripts": {
12 | "dev": "start-storybook -p 9001 -c .storybook",
13 | "deploy-storybook": "storybook-to-ghpages",
14 | "build": "rm -rf ./dist && bili",
15 | "tdd": "jest --watch",
16 | "test": "jest",
17 | "coverage": "codecov",
18 | "test:newsnapshot": "npm run test -- -u",
19 | "lint": "eslint --ext .vue --ext .js src/",
20 | "lint:fix": "npm run lint --fix"
21 | },
22 | "repository": {
23 | "type": "git",
24 | "url": "git+https://github.com/osiris-ui/osiris.git"
25 | },
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/osiris-ui/osiris/issues"
29 | },
30 | "homepage": "https://github.com/osiris-ui/osiris#readme",
31 | "devDependencies": {
32 | "@storybook/addon-knobs": "^3.4.10",
33 | "@storybook/addon-storyshots": "^3.4.10",
34 | "@storybook/addon-storysource": "^3.4.8",
35 | "@storybook/storybook-deployer": "^2.3.0",
36 | "@storybook/vue": "^3.4.8",
37 | "@vue/test-utils": "^1.0.0-beta.24",
38 | "babel-core": "^6.26.3",
39 | "babel-eslint": "^8.2.6",
40 | "babel-jest": "^23.4.2",
41 | "babel-plugin-lodash": "^3.3.4",
42 | "babel-preset-env": "^1.7.0",
43 | "bili": "^3.1.2",
44 | "css-loader": "^1.0.0",
45 | "eslint": "^4.19.1",
46 | "eslint-config-airbnb": "^17.0.0",
47 | "eslint-config-airbnb-base": "^13.0.0",
48 | "eslint-config-postcss": "^3.0.3",
49 | "eslint-friendly-formatter": "^4.0.1",
50 | "eslint-loader": "^2.1.0",
51 | "eslint-plugin-import": "^2.13.0",
52 | "eslint-plugin-vue": "^4.7.1",
53 | "file-loader": "^1.1.11",
54 | "husky": "^1.0.0-rc.13",
55 | "identity-obj-proxy": "^3.0.0",
56 | "jest": "^23.4.2",
57 | "jest-serializer-vue": "^2.0.2",
58 | "rollup-plugin-vue": "^3.0.0",
59 | "vue-jest": "^2.6.0",
60 | "vue-loader": "^14.2.2",
61 | "vue-template-compiler": "^2.5.16"
62 | },
63 | "dependencies": {
64 | "codecov": "^3.0.4",
65 | "lodash": "^4.17.10",
66 | "popper.js": "^1.14.4",
67 | "validate.js": "^0.12.0",
68 | "vue": "^2.5.16",
69 | "vue-click-outside": "^1.0.7",
70 | "vue2-transitions": "^0.2.3"
71 | },
72 | "jest": {
73 | "verbose": true,
74 | "testURL": "http://localhost/",
75 | "collectCoverage": true,
76 | "coverageDirectory": "./coverage/",
77 | "collectCoverageFrom": [
78 | "src/**/*.{js,vue}",
79 | "!**/node_modules/**"
80 | ],
81 | "moduleFileExtensions": [
82 | "js",
83 | "json",
84 | "vue"
85 | ],
86 | "transform": {
87 | ".*\\.(vue)$": "vue-jest",
88 | "^.+\\.js$": "/node_modules/babel-jest"
89 | },
90 | "snapshotSerializers": [
91 | "/node_modules/jest-serializer-vue"
92 | ],
93 | "testMatch": [
94 | "/(src/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))"
95 | ],
96 | "transformIgnorePatterns": [
97 | "/node_modules/(?!(@storybook/.*\\.vue$))"
98 | ],
99 | "moduleNameMapper": {
100 | "\\.(css|less|scss|sass)$": "identity-obj-proxy"
101 | }
102 | },
103 | "husky": {
104 | "hooks": {
105 | "pre-push": "npm run lint && npm test"
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/button/__snapshots__/button.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button should be a circle button 1`] = ` `;
4 |
5 | exports[`Button should be a danger button 1`] = ` `;
6 |
7 | exports[`Button should be a default button at startup 1`] = ` `;
8 |
9 | exports[`Button should be a info button 1`] = ` `;
10 |
11 | exports[`Button should be a large button 1`] = ` `;
12 |
13 | exports[`Button should be a mini button 1`] = ` `;
14 |
15 | exports[`Button should be a normal button 1`] = ` `;
16 |
17 | exports[`Button should be a plain button 1`] = ` `;
18 |
19 | exports[`Button should be a primary button 1`] = ` `;
20 |
21 | exports[`Button should be a round button 1`] = ` `;
22 |
23 | exports[`Button should be a secondary button 1`] = ` `;
24 |
25 | exports[`Button should be a small button 1`] = ` `;
26 |
27 | exports[`Button should be a success button 1`] = ` `;
28 |
29 | exports[`Button should be a text button 1`] = ` `;
30 |
31 | exports[`Button should be a warning button 1`] = ` `;
32 |
33 | exports[`Button should be disabled 1`] = ` `;
34 |
35 | exports[`Button should have a nativeType submit 1`] = ` `;
36 |
--------------------------------------------------------------------------------
/src/button/button.spec.js:
--------------------------------------------------------------------------------
1 | import { mount } from '@vue/test-utils';
2 | import Button from './button.vue';
3 |
4 | describe('Button', () => {
5 | let wrapper;
6 |
7 | const reset = () => wrapper.setProps({
8 | type: 'default',
9 | nativeType: 'button',
10 | size: 'normal',
11 | round: false,
12 | circle: false,
13 | disabled: false,
14 | });
15 |
16 | beforeAll(() => {
17 | wrapper = mount(Button);
18 | });
19 |
20 | afterEach(reset);
21 |
22 | it('should be a default button at startup', () => {
23 | const defaultClasses = ['o-button', 'o-button--default', 'o-button--normal'];
24 |
25 | expect(wrapper.html()).toMatchSnapshot();
26 | expect(wrapper.classes()).toEqual(defaultClasses);
27 | });
28 |
29 | it('should be a primary button', () => {
30 | wrapper.setProps({
31 | type: 'primary',
32 | });
33 |
34 | expect(wrapper.html()).toMatchSnapshot();
35 | expect(wrapper.classes()).toContain('o-button--primary');
36 | });
37 |
38 | it('should be a secondary button', () => {
39 | wrapper.setProps({
40 | type: 'secondary',
41 | });
42 |
43 | expect(wrapper.html()).toMatchSnapshot();
44 | expect(wrapper.classes()).toContain('o-button--secondary');
45 | });
46 |
47 | it('should be a info button', () => {
48 | wrapper.setProps({
49 | type: 'info',
50 | });
51 |
52 | expect(wrapper.html()).toMatchSnapshot();
53 | expect(wrapper.classes()).toContain('o-button--info');
54 | });
55 |
56 | it('should be a success button', () => {
57 | wrapper.setProps({
58 | type: 'success',
59 | });
60 |
61 | expect(wrapper.html()).toMatchSnapshot();
62 | expect(wrapper.classes()).toContain('o-button--success');
63 | });
64 |
65 | it('should be a warning button', () => {
66 | wrapper.setProps({
67 | type: 'warning',
68 | });
69 |
70 | expect(wrapper.html()).toMatchSnapshot();
71 | expect(wrapper.classes()).toContain('o-button--warning');
72 | });
73 |
74 | it('should be a danger button', () => {
75 | wrapper.setProps({
76 | type: 'danger',
77 | });
78 |
79 | expect(wrapper.html()).toMatchSnapshot();
80 | expect(wrapper.classes()).toContain('o-button--danger');
81 | });
82 |
83 | it('should be a text button', () => {
84 | wrapper.setProps({
85 | type: 'text',
86 | });
87 |
88 | expect(wrapper.html()).toMatchSnapshot();
89 | expect(wrapper.classes()).toContain('o-button--text');
90 | });
91 |
92 | it('should be a mini button', () => {
93 | wrapper.setProps({
94 | size: 'mini',
95 | });
96 |
97 | expect(wrapper.html()).toMatchSnapshot();
98 | expect(wrapper.classes()).toContain('o-button--mini');
99 | });
100 |
101 | it('should be a small button', () => {
102 | wrapper.setProps({
103 | size: 'small',
104 | });
105 |
106 | expect(wrapper.html()).toMatchSnapshot();
107 | expect(wrapper.classes()).toContain('o-button--small');
108 | });
109 |
110 | it('should be a normal button', () => {
111 | wrapper.setProps({
112 | size: 'normal',
113 | });
114 |
115 | expect(wrapper.html()).toMatchSnapshot();
116 | expect(wrapper.classes()).toContain('o-button--normal');
117 | });
118 |
119 | it('should be a large button', () => {
120 | wrapper.setProps({
121 | size: 'large',
122 | });
123 |
124 | expect(wrapper.html()).toMatchSnapshot();
125 | expect(wrapper.classes()).toContain('o-button--large');
126 | });
127 |
128 | it('should be a round button', () => {
129 | wrapper.setProps({
130 | round: true,
131 | });
132 |
133 | expect(wrapper.html()).toMatchSnapshot();
134 | expect(wrapper.classes()).toContain('is-round');
135 | });
136 |
137 | it('should be a circle button', () => {
138 | wrapper.setProps({
139 | circle: true,
140 | });
141 |
142 | expect(wrapper.html()).toMatchSnapshot();
143 | expect(wrapper.classes()).toContain('is-circle');
144 | });
145 |
146 | it('should be a plain button', () => {
147 | wrapper.setProps({
148 | plain: true,
149 | });
150 |
151 | expect(wrapper.html()).toMatchSnapshot();
152 | expect(wrapper.classes()).toContain('is-plain');
153 | });
154 |
155 | it('should have a nativeType submit', () => {
156 | wrapper.setProps({
157 | nativeType: 'submit',
158 | });
159 |
160 | expect(wrapper.html()).toMatchSnapshot();
161 | expect(wrapper.attributes().type).toBe('submit');
162 | });
163 |
164 | it('should be disabled', () => {
165 | wrapper.setProps({
166 | disabled: true,
167 | });
168 |
169 | expect(wrapper.html()).toMatchSnapshot();
170 | expect(wrapper.attributes().disabled).toBeTruthy();
171 | });
172 |
173 | it('should emit click event', () => {
174 | wrapper.findAll('button').trigger('click');
175 | expect(wrapper.emitted().click).toBeTruthy();
176 | });
177 |
178 | it('should render default slot', () => {
179 | wrapper = mount(Button, {
180 | slots: {
181 | default: 'Default Button',
182 | },
183 | });
184 |
185 | expect(wrapper.text()).toBe('Default Button');
186 | });
187 | });
188 |
--------------------------------------------------------------------------------
/src/button/button.stories.js:
--------------------------------------------------------------------------------
1 | import { storiesOf } from '@storybook/vue';
2 |
3 | import OButton from './button.vue';
4 |
5 | storiesOf('Button', module)
6 | // .add('default', () => 'simple row ');
7 | .add('types', () => ({
8 | components: { OButton },
9 | template: `
10 |
11 |
Default
12 |
Primary
13 |
Secondary
14 |
Info
15 |
Success
16 |
Warning
17 |
18 | Danger
19 | Text
20 |
21 |
22 | `,
23 | }))
24 | .add('plain', () => ({
25 | components: { OButton },
26 | template: `
27 |
28 |
Default
29 |
Primary
30 |
Secondary
31 |
Info
32 |
Success
33 |
Warning
34 |
35 | Danger
36 |
37 |
38 | `,
39 | }))
40 | .add('disabled', () => ({
41 | components: { OButton },
42 | template: `
43 |
44 |
45 |
Default
46 |
Primary
47 |
Secondary
48 |
Info
49 |
Success
50 |
Warning
51 |
52 | Danger
53 | Text
54 |
55 |
56 |
57 |
Default
58 |
Primary
59 |
Secondary
60 |
Info
61 |
Success
62 |
Warning
63 |
64 | Danger
65 | Text
66 |
67 |
68 |
69 | `,
70 | }))
71 | .add('sizes', () => ({
72 | components: { OButton },
73 | template: `
74 |
75 |
76 | Default Large
77 | Default Normal
78 | Default Small
79 | Default Mini
80 |
81 |
82 | Primary Large
83 | Primary Normal
84 | Primary Small
85 | Primary Mini
86 |
87 |
88 | Secondary Large
89 | Secondary Normal
90 | Secondary Small
91 | Secondary Mini
92 |
93 |
94 | Info Large
95 | Info Normal
96 | Info Small
97 | Info Mini
98 |
99 |
100 | Success Large
101 | Success Normal
102 | Success Small
103 | Success Mini
104 |
105 |
106 | Warning Large
107 | Warning Normal
108 | Warning Small
109 | Warning Mini
110 |
111 |
112 | Danger Large
113 | Danger Normal
114 | Danger Small
115 | Danger Mini
116 |
117 |
118 | Text Large
119 | Text Normal
120 | Text Small
121 | Text Mini
122 |
123 |
124 | `,
125 | }))
126 | .add('round', () => ({
127 | components: { OButton },
128 | template: `
129 |
130 |
Default
131 |
Primary
132 |
Secondary
133 |
Info
134 |
Success
135 |
Warning
136 |
137 | Danger
138 |
139 |
140 | `,
141 | }))
142 | .add('circle', () => ({
143 | components: { OButton },
144 | template: `
145 |
146 | D
147 | P
148 | S
149 | I
150 | SC
151 | W
152 | D
153 |
154 | `,
155 | }));
156 |
--------------------------------------------------------------------------------
/src/button/button.vue:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
69 |
--------------------------------------------------------------------------------
/src/button/index.js:
--------------------------------------------------------------------------------
1 | import button from './button.vue';
2 |
3 | export default button;
4 |
--------------------------------------------------------------------------------
/src/checkbox/checkbox.spec.js:
--------------------------------------------------------------------------------
1 | import { mount } from '@vue/test-utils';
2 | import checkbox from './checkbox.vue';
3 |
4 | describe('checkbox', () => {
5 | let wrapper;
6 |
7 | beforeEach(() => {
8 | wrapper = mount(checkbox);
9 | wrapper.setProps({
10 | size: 'medium',
11 | });
12 | });
13 |
14 | describe('when is default', () => {
15 | it('should have expected classes', () => {
16 | expect(wrapper.classes())
17 | .toEqual(['o-checkbox', 'o-checkbox--medium']);
18 | });
19 | });
20 |
21 | describe('when have default params filled', () => {
22 | beforeEach(() => {
23 | wrapper.setProps({
24 | value: '1',
25 | modelValue: '1',
26 | label: 'label',
27 | name: 'name',
28 | });
29 | });
30 |
31 | it('should have a name attr', () => {
32 | const { name } = wrapper.find('input')
33 | .attributes();
34 | expect(name).toEqual('name');
35 | });
36 |
37 | it('should have a value attr', () => {
38 | const input = wrapper.find('input');
39 | const { value } = input.attributes();
40 | expect(value).toEqual('1');
41 | });
42 |
43 | it('should have a label', () => {
44 | const label = wrapper.find('.o-checkbox__label');
45 | expect(label.text()).toEqual('label');
46 | });
47 | });
48 |
49 | describe('when is disabled', () => {
50 | beforeEach(() => {
51 | wrapper.setProps({
52 | disabled: true,
53 | });
54 | });
55 |
56 | it('should have is-disabled class', () => {
57 | expect(wrapper.classes())
58 | .toEqual(expect.arrayContaining(['is-disabled']));
59 | });
60 | });
61 |
62 | describe('when is checked', () => {
63 | beforeEach(() => {
64 | wrapper.setProps({
65 | modelValue: '1',
66 | value: '1',
67 | });
68 | });
69 |
70 | it('should have is-checked class', () => {
71 | expect(wrapper.classes())
72 | .toEqual(expect.arrayContaining(['is-checked']));
73 | });
74 | });
75 |
76 | describe('when have another size', () => {
77 | beforeEach(() => {
78 | wrapper.setProps({
79 | size: 'large',
80 | });
81 | });
82 |
83 | it('should have o-checkbox--large class', () => {
84 | expect(wrapper.classes())
85 | .toEqual(expect.arrayContaining(['o-checkbox', 'o-checkbox--large']));
86 | });
87 | });
88 | });
89 |
--------------------------------------------------------------------------------
/src/checkbox/checkbox.stories.js:
--------------------------------------------------------------------------------
1 | import { storiesOf } from '@storybook/vue';
2 | import OCheckbox from './checkbox.vue';
3 |
4 | storiesOf('Checkbox', module)
5 | .add('default', () => ({
6 | components: { OCheckbox },
7 | data() {
8 | return {
9 | modelValue: 1,
10 | };
11 | },
12 | template: `
13 |
14 |
Selected Value: {{modelValue}}
15 |
16 |
17 | `,
18 | }))
19 | .add('with a disabled', () => ({
20 | components: {
21 | OCheckbox,
22 | },
23 | data() {
24 | return {
25 | modelValue: 2,
26 | };
27 | },
28 | template: `
29 |
36 | `,
37 | }))
38 | .add('with model being an array', () => ({
39 | components: {
40 | OCheckbox,
41 | },
42 | data() {
43 | return {
44 | modelValue: [],
45 | };
46 | },
47 | template: `
48 |
49 |
Model Value: {{modelValue}}
50 |
56 |
62 |
63 | `,
64 | }));
65 |
--------------------------------------------------------------------------------
/src/checkbox/checkbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
21 |
22 |
23 | {{ label }}
24 |
25 |
26 |
27 |
28 |
29 |
96 |
--------------------------------------------------------------------------------
/src/checkbox/index.js:
--------------------------------------------------------------------------------
1 | import Checkbox from './checkbox.vue';
2 |
3 | export default Checkbox;
4 |
--------------------------------------------------------------------------------
/src/col/__snapshots__/col.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Col when pass no prop should match with the snapshot 1`] = `
`;
4 |
5 | exports[`Col when pass some props and the props are {"span":1,"xs":2,"sm":3,"md":4,"lg":5,"xl":6,"offset":7} should match with the snapshot 1`] = `
`;
6 |
7 | exports[`Col when pass some props and the props are another tag like section should match with the snapshot 1`] = ``;
8 |
--------------------------------------------------------------------------------
/src/col/col.spec.js:
--------------------------------------------------------------------------------
1 | import { shallowMount } from '@vue/test-utils';
2 | import Col from './col.vue';
3 |
4 | describe('Col', () => {
5 | let wrapper;
6 | describe('when pass no prop', () => {
7 | beforeEach(() => {
8 | wrapper = shallowMount(Col);
9 | });
10 |
11 | it('should match with the snapshot', () => {
12 | expect(wrapper.html()).toMatchSnapshot();
13 | });
14 |
15 | it('should have default classList', () => {
16 | const expected = ['o-col-24', 'o-col-offset-0'];
17 | expect(wrapper.vm.classList).toEqual(expected);
18 | });
19 | });
20 |
21 | describe('when pass some props', () => {
22 | const props = {
23 | span: 1,
24 | xs: 2,
25 | sm: 3,
26 | md: 4,
27 | lg: 5,
28 | xl: 6,
29 | offset: 7,
30 | };
31 |
32 | describe(`and the props are ${JSON.stringify(props)}`, () => {
33 | beforeEach(() => {
34 | wrapper = shallowMount(Col, {
35 | propsData: {
36 | ...props,
37 | },
38 | });
39 | });
40 |
41 | it('should match with the snapshot', () => {
42 | expect(wrapper.html()).toMatchSnapshot();
43 | });
44 |
45 | it('should have exactly expected classList', () => {
46 | const expected = [
47 | 'o-col-1',
48 | 'o-col-offset-7',
49 | 'o-col-xs-2',
50 | 'o-col-sm-3',
51 | 'o-col-md-4',
52 | 'o-col-lg-5',
53 | 'o-col-xl-6',
54 | ];
55 |
56 | expect(wrapper.vm.classList).toEqual(expected);
57 | });
58 | });
59 |
60 | describe('and the props are another tag like section', () => {
61 | beforeEach(() => {
62 | wrapper = shallowMount(Col, {
63 | propsData: {
64 | tag: 'section',
65 | },
66 | });
67 | });
68 |
69 | it('should match with the snapshot', () => {
70 | expect(wrapper.html()).toMatchSnapshot();
71 | });
72 | });
73 | });
74 | });
75 |
--------------------------------------------------------------------------------
/src/col/col.stories.js:
--------------------------------------------------------------------------------
1 | import { storiesOf } from '@storybook/vue';
2 |
3 | import ORow from '../row/row.vue';
4 | import OCol from './col.vue';
5 |
6 | storiesOf('Col', module)
7 | // .add('default', () => 'simple row ');
8 | .add('default', () => ({
9 | components: { ORow, OCol },
10 | template: `
11 | a
12 | b
13 | c
14 | d
15 | e
16 | f
17 | `,
18 | }))
19 | .add('offset', () => ({
20 | components: { ORow, OCol },
21 | template: `
22 | a
23 | b
24 | c
25 | d
26 | e
27 | f
28 | `,
29 | }))
30 | .add('responsive', () => ({
31 | components: { ORow, OCol },
32 | template: `
33 | a
34 | a
35 | a
36 | a
37 | a
38 | a
39 | `,
40 | }));
41 |
--------------------------------------------------------------------------------
/src/col/col.vue:
--------------------------------------------------------------------------------
1 |
93 |
--------------------------------------------------------------------------------
/src/col/index.js:
--------------------------------------------------------------------------------
1 | import col from './col.vue';
2 |
3 | export default col;
4 |
--------------------------------------------------------------------------------
/src/form/form.stories.js:
--------------------------------------------------------------------------------
1 | import { storiesOf } from '@storybook/vue';
2 | import {
3 | withKnobs,
4 | select,
5 | text,
6 | } from '@storybook/addon-knobs/vue';
7 |
8 | import OForm from './form.vue';
9 | import OFormItem from '../formItem';
10 | import OInput from '../input';
11 | import OButton from '../button';
12 | import ORadio from '../radio';
13 | import OCheckbox from '../checkbox';
14 | import OSelect from '../select';
15 |
16 | const POSITION = {
17 | top: 'top',
18 | left: 'left',
19 | right: 'right',
20 | };
21 |
22 | storiesOf('Form', module)
23 | // .add('default', () => 'simple row ');
24 | .addDecorator(withKnobs)
25 | .add('basic usage', () => ({
26 | components: {
27 | OForm,
28 | OFormItem,
29 | OInput,
30 | OButton,
31 | ORadio,
32 | OCheckbox,
33 | OSelect,
34 | },
35 | data() {
36 | return {
37 | form: {
38 | name: '',
39 | email: '',
40 | isReal: '',
41 | country: '',
42 | cities: [],
43 | languages: [],
44 | },
45 |
46 | rules: {
47 | name: {
48 | presence: {
49 | allowEmpty: false,
50 | message: 'Please, tell us your name',
51 | },
52 | trigger: 'blur',
53 | },
54 |
55 | email: {
56 | email: {
57 | message: 'This is not a valid email',
58 | },
59 | trigger: 'blur',
60 | },
61 |
62 | isReal: {
63 | presence: {
64 | message: 'Are you really a real person?',
65 | },
66 |
67 | validator(value) {
68 | if (value !== true) return 'You must be a real person';
69 |
70 | return undefined;
71 | },
72 |
73 | trigger: 'change',
74 | },
75 |
76 | languages: {
77 | presence: {
78 | allowEmpty: false,
79 | message: 'Please, select a least one',
80 | },
81 |
82 | trigger: 'change',
83 | },
84 |
85 | country: {
86 | presence: {
87 | allowEmpty: false,
88 | message: 'Please, select your country',
89 | },
90 |
91 | trigger: 'change',
92 | },
93 |
94 | cities: {
95 | presence: {
96 | allowEmpty: false,
97 | message: 'Please, select at least 1 city',
98 | },
99 |
100 | trigger: 'change',
101 | },
102 | },
103 | };
104 | },
105 |
106 | methods: {
107 | validate() {
108 | return this.$refs.form.validate();
109 | },
110 |
111 | clearValidation() {
112 | return this.$refs.form.clearValidation();
113 | },
114 | },
115 |
116 | template: `
117 |
124 |
125 |
128 |
129 |
130 |
131 |
134 |
135 |
136 |
137 |
140 | Yes
141 | No
142 |
143 |
144 |
147 | Javascript
148 | PHP
149 | Python
150 | Ruby
151 |
152 |
153 |
156 |
185 |
186 |
187 |
188 |
191 |
225 |
226 |
227 |
228 | Validate
229 | Clear validation
230 |
231 | `,
232 | }));
233 |
--------------------------------------------------------------------------------
/src/form/form.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
82 |
--------------------------------------------------------------------------------
/src/form/index.js:
--------------------------------------------------------------------------------
1 | import form from './form.vue';
2 |
3 | export default form;
4 |
--------------------------------------------------------------------------------
/src/formItem/formItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
32 |
33 |
34 |
165 |
--------------------------------------------------------------------------------
/src/formItem/index.js:
--------------------------------------------------------------------------------
1 | import formItem from './formItem.vue';
2 |
3 | export default formItem;
4 |
--------------------------------------------------------------------------------
/src/icons/icons.stories.js:
--------------------------------------------------------------------------------
1 | import { storiesOf } from '@storybook/vue';
2 |
3 | storiesOf('Icons', module)
4 | // .add('default', () => 'simple row ');
5 | .add('default', () => ({
6 | template: `
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 | `,
237 | }));
238 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import Row from './row';
2 | import Col from './col';
3 | import Button from './button';
4 | import Input from './input';
5 | import Radio from './radio';
6 | import Form from './form';
7 | import FormItem from './formItem';
8 | import Checkbox from './checkbox';
9 | import Select from './select';
10 |
11 | const components = [
12 | Row,
13 | Col,
14 | Button,
15 | Input,
16 | Radio,
17 | Form,
18 | FormItem,
19 | Checkbox,
20 | Select,
21 | ];
22 |
23 | function install(Vue) {
24 | components.forEach((component) => {
25 | Vue.component(component.name, component);
26 | });
27 | }
28 |
29 | if (typeof window !== 'undefined' && window.Vue) {
30 | install(window.Vue);
31 | }
32 |
33 | export default {
34 | install,
35 | Row,
36 | Col,
37 | Button,
38 | Input,
39 | Radio,
40 | Form,
41 | FormItem,
42 | Checkbox,
43 | Select,
44 | };
45 |
--------------------------------------------------------------------------------
/src/input/__snapshots__/input.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Input should be a default input at startup 1`] = `
4 |
5 |
6 |
7 |
8 |
9 | `;
10 |
11 | exports[`Input should be a large input 1`] = `
12 |
13 |
14 |
15 |
16 |
17 | `;
18 |
19 | exports[`Input should be a mini input 1`] = `
20 |
21 |
22 |
23 |
24 |
25 | `;
26 |
27 | exports[`Input should be a small input 1`] = `
28 |
29 |
30 |
31 |
32 |
33 | `;
34 |
35 | exports[`Input should be disabled 1`] = `
36 |
37 |
38 |
39 |
40 |
41 | `;
42 |
43 | exports[`Input should be readonly 1`] = `
44 |
45 |
46 |
47 |
48 |
49 | `;
50 |
51 | exports[`Input should have a error status 1`] = `
52 |
53 |
54 |
55 |
56 |
57 | `;
58 |
59 | exports[`Input should have a prefix icon through slot 1`] = `
60 |
61 |
62 |
63 |
64 |
65 |
66 | `;
67 |
68 | exports[`Input should have a prefixIcon 1`] = `
69 |
70 |
71 |
72 |
73 |
74 | `;
75 |
76 | exports[`Input should have a success status 1`] = `
77 |
78 |
79 |
80 |
81 |
82 | `;
83 |
84 | exports[`Input should have a suffix icon through slot 1`] = `
85 |
86 |
87 |
88 |
89 |
90 |
91 | `;
92 |
93 | exports[`Input should have a suffixIcon 1`] = `
94 |
95 |
96 |
97 |
98 |
99 | `;
100 |
--------------------------------------------------------------------------------
/src/input/index.js:
--------------------------------------------------------------------------------
1 | import input from './input.vue';
2 |
3 | export default input;
4 |
--------------------------------------------------------------------------------
/src/input/input.spec.js:
--------------------------------------------------------------------------------
1 | import { mount } from '@vue/test-utils';
2 | import Input from './input.vue';
3 |
4 | describe('Input', () => {
5 | let wrapper;
6 |
7 | const reset = () => wrapper.setProps({
8 | name: '',
9 | placeholder: '',
10 | width: '300px',
11 | type: 'text',
12 | size: 'normal',
13 | value: '',
14 | readonly: false,
15 | autofocus: false,
16 | disabled: false,
17 | maxlength: Infinity,
18 | minlength: 0,
19 | max: Infinity,
20 | min: 0,
21 | prefixIcon: '',
22 | suffixIcon: '',
23 | isSuccess: false,
24 | isError: false,
25 | });
26 |
27 | beforeAll(() => {
28 | wrapper = mount(Input);
29 | });
30 |
31 | afterEach(reset);
32 |
33 | it('should be a default input at startup', () => {
34 | const defaultClasses = ['o-input', 'o-input--normal'];
35 |
36 | expect(wrapper.html()).toMatchSnapshot();
37 | expect(wrapper.classes()).toEqual(defaultClasses);
38 | });
39 |
40 | it('should be a large input', () => {
41 | wrapper.setProps({
42 | size: 'large',
43 | });
44 |
45 | expect(wrapper.html()).toMatchSnapshot();
46 | expect(wrapper.classes()).toContain('o-input--large');
47 | });
48 |
49 | it('should be a small input', () => {
50 | wrapper.setProps({
51 | size: 'small',
52 | });
53 |
54 | expect(wrapper.html()).toMatchSnapshot();
55 | expect(wrapper.classes()).toContain('o-input--small');
56 | });
57 |
58 | it('should be a mini input', () => {
59 | wrapper.setProps({
60 | size: 'mini',
61 | });
62 |
63 | expect(wrapper.html()).toMatchSnapshot();
64 | expect(wrapper.classes()).toContain('o-input--mini');
65 | });
66 |
67 | it('should be disabled', () => {
68 | wrapper.setProps({
69 | disabled: true,
70 | });
71 |
72 | expect(wrapper.html()).toMatchSnapshot();
73 | expect(wrapper.classes()).toContain('is-disabled');
74 | expect(wrapper.html()).toContain('disabled=');
75 | });
76 |
77 | it('should be readonly', () => {
78 | wrapper.setProps({
79 | readonly: true,
80 | });
81 |
82 | expect(wrapper.html()).toMatchSnapshot();
83 | expect(wrapper.html()).toContain('readonly=');
84 | });
85 |
86 | it('should have a prefixIcon', () => {
87 | wrapper.setProps({
88 | prefixIcon: 'o-icon o-icon-search',
89 | });
90 |
91 | expect(wrapper.html()).toMatchSnapshot();
92 | expect(wrapper.html()).toContain('o-input__prefix');
93 | expect(wrapper.html()).toContain(' {
97 | wrapper.setProps({
98 | suffixIcon: 'o-icon o-icon-search',
99 | });
100 |
101 | expect(wrapper.html()).toMatchSnapshot();
102 | expect(wrapper.classes()).toContain('o-input__suffix');
103 | expect(wrapper.html()).toContain(' {
107 | wrapper.setProps({
108 | isSuccess: true,
109 | });
110 |
111 | expect(wrapper.html()).toMatchSnapshot();
112 | expect(wrapper.classes()).toContain('is-success');
113 | expect(wrapper.html()).toContain(' {
117 | wrapper.setProps({
118 | isError: true,
119 | });
120 |
121 | expect(wrapper.html()).toMatchSnapshot();
122 | expect(wrapper.classes()).toContain('is-error');
123 | expect(wrapper.html()).toContain(' {
127 | wrapper.findAll('input').trigger('focus');
128 |
129 | expect(wrapper.emitted().focus).toBeTruthy();
130 | });
131 |
132 | it('should emit a blur event', () => {
133 | wrapper.findAll('input').trigger('blur');
134 |
135 | expect(wrapper.emitted().blur).toBeTruthy();
136 | });
137 |
138 | it('should emit a input event', () => {
139 | wrapper.setProps({
140 | value: 'abc',
141 | });
142 | wrapper.findAll('input').trigger('input');
143 |
144 | expect(wrapper.vm.$data.currentValue).toBe('abc');
145 | expect(wrapper.emitted().input).toBeTruthy();
146 | });
147 |
148 | it('should have a suffix icon through slot', () => {
149 | wrapper = mount(Input, {
150 | slots: {
151 | suffix: ' ',
152 | },
153 | });
154 |
155 | expect(wrapper.html()).toMatchSnapshot();
156 | expect(wrapper.classes()).toContain('o-input__suffix');
157 | expect(wrapper.html()).toContain(' {
161 | wrapper = mount(Input, {
162 | slots: {
163 | prefix: ' ',
164 | },
165 | });
166 |
167 | expect(wrapper.html()).toMatchSnapshot();
168 | expect(wrapper.classes()).toContain('o-input__prefix');
169 | expect(wrapper.html()).toContain(' 'simple row ');
7 | .add('default', () => ({
8 | components: { OInput },
9 | template: ' ',
10 | }))
11 | .add('with icon', () => ({
12 | components: { OInput },
13 | template: `
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | `,
28 | }))
29 | .add('with status', () => ({
30 | components: { OInput },
31 | template: `
32 |
33 |
34 |
35 |
36 | `,
37 | }))
38 | .add('sizes', () => ({
39 | components: { OInput },
40 | template: `
41 |
42 |
43 |
44 |
45 |
46 |
47 | `,
48 | }))
49 | .add('disabled', () => ({
50 | components: { OInput },
51 | template: ' ',
52 | }))
53 | .add('readonly', () => ({
54 | components: { OInput },
55 | template: ' ',
56 | }));
57 |
--------------------------------------------------------------------------------
/src/input/input.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
26 |
27 |
31 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
211 |
--------------------------------------------------------------------------------
/src/mixins/dispatch.js:
--------------------------------------------------------------------------------
1 | export default {
2 | methods: {
3 | dispatch(componentName, eventName, data) {
4 | let parent = this.$parent || this.$root;
5 | let { name } = parent.$options;
6 |
7 | while (parent && (!name || name !== componentName)) {
8 | parent = parent.$parent;
9 |
10 | if (parent) {
11 | const newName = parent.$options.name;
12 | name = newName;
13 | }
14 | }
15 |
16 | if (parent) {
17 | parent.$emit(eventName, data);
18 | }
19 | },
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/src/radio/index.js:
--------------------------------------------------------------------------------
1 | import Radio from './radio.vue';
2 |
3 | export default Radio;
4 |
--------------------------------------------------------------------------------
/src/radio/radio.spec.js:
--------------------------------------------------------------------------------
1 | import { mount } from '@vue/test-utils';
2 | import Radio from './radio.vue';
3 |
4 | describe('Radio', () => {
5 | let wrapper;
6 |
7 | beforeEach(() => {
8 | wrapper = mount(Radio);
9 | wrapper.setProps({
10 | size: 'medium',
11 | });
12 | });
13 |
14 | describe('when is default', () => {
15 | it('should have expected classes', () => {
16 | expect(wrapper.classes()).toEqual(['o-radio', 'o-radio--medium']);
17 | });
18 | });
19 |
20 | describe('when have default params filled', () => {
21 | beforeEach(() => {
22 | wrapper.setProps({
23 | value: '1',
24 | modelValue: '1',
25 | label: 'label',
26 | name: 'name',
27 | });
28 | });
29 |
30 | it('should have a name attr', () => {
31 | const { name } = wrapper.find('input')
32 | .attributes();
33 | expect(name).toEqual('name');
34 | });
35 |
36 | it('should have a value attr', () => {
37 | const input = wrapper.find('input');
38 | const { value } = input.attributes();
39 | expect(value).toEqual('1');
40 | });
41 |
42 | it('should have a label', () => {
43 | const label = wrapper.find('.o-radio__label');
44 | expect(label.text()).toEqual('label');
45 | });
46 | });
47 |
48 | describe('when is clicked', () => {
49 | beforeEach(() => {
50 | wrapper.setProps({
51 | modelValue: '0',
52 | value: '1',
53 | });
54 | });
55 |
56 | it('should change isChecked to true', () => {
57 | wrapper.find('input').trigger('change');
58 | wrapper.vm.$nextTick(() => {
59 | expect(wrapper.vm.isChecked).toBeTruthy();
60 | });
61 | });
62 | });
63 |
64 | describe('when is disabled', () => {
65 | beforeEach(() => {
66 | wrapper.setProps({
67 | disabled: true,
68 | });
69 | });
70 |
71 | it('should have is-disabled class', () => {
72 | expect(wrapper.classes())
73 | .toEqual(expect.arrayContaining(['is-disabled']));
74 | });
75 | });
76 |
77 | describe('when is checked', () => {
78 | beforeEach(() => {
79 | wrapper.setProps({
80 | modelValue: '1',
81 | value: '1',
82 | });
83 | });
84 |
85 | it('should have is-checked class', () => {
86 | expect(wrapper.classes())
87 | .toEqual(expect.arrayContaining(['is-checked']));
88 | });
89 | });
90 |
91 | describe('when have another size', () => {
92 | beforeEach(() => {
93 | wrapper.setProps({
94 | size: 'large',
95 | });
96 | });
97 |
98 | it('should have o-radio--large class', () => {
99 | expect(wrapper.classes())
100 | .toEqual(expect.arrayContaining(['o-radio', 'o-radio--large']));
101 | });
102 | });
103 | });
104 |
--------------------------------------------------------------------------------
/src/radio/radio.stories.js:
--------------------------------------------------------------------------------
1 | import { storiesOf } from '@storybook/vue';
2 | import {
3 | withKnobs,
4 | select,
5 | } from '@storybook/addon-knobs/vue';
6 |
7 | import ORadio from './radio.vue';
8 |
9 | const SIZES = {
10 | small: 'small',
11 | medium: 'medium',
12 | large: 'large',
13 | };
14 |
15 | storiesOf('Radio', module)
16 | .add('default', () => ({
17 | components: { ORadio },
18 | data() {
19 | return {
20 | modelValue: 1,
21 | };
22 | },
23 | template: `
24 |
25 |
Selected Value: {{modelValue}}
26 |
27 |
28 |
29 | `,
30 | }))
31 | .add('with a disabled', () => ({
32 | components: {
33 | ORadio,
34 | },
35 | data() {
36 | return {
37 | modelValue: 2,
38 | };
39 | },
40 | template: `
41 |
42 |
Selected Value: {{modelValue}}
43 |
44 |
45 |
46 | `,
47 | }))
48 | .addDecorator(withKnobs)
49 | .add('with editable size', () => ({
50 | components: {
51 | ORadio,
52 | },
53 | template: `
54 | `,
60 | }));
61 |
--------------------------------------------------------------------------------
/src/radio/radio.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
21 |
22 |
23 | {{ label }}
24 |
25 |
26 |
27 |
28 |
29 |
67 |
--------------------------------------------------------------------------------
/src/row/__snapshots__/row.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Row when pass no props should match with the snapshot 1`] = `
`;
4 |
5 | exports[`Row when pass some props and the prop is another tag like section should match with the snapshot 1`] = ``;
6 |
7 | exports[`Row when pass some props and the props are {"justify":"flex-end","align":"flex-end","content":"center","direction":"column","wrap":"no-wrap"} should match with the snapshot 1`] = `
`;
8 |
--------------------------------------------------------------------------------
/src/row/index.js:
--------------------------------------------------------------------------------
1 | import row from './row.vue';
2 |
3 | export default row;
4 |
--------------------------------------------------------------------------------
/src/row/row.spec.js:
--------------------------------------------------------------------------------
1 | import { shallowMount } from '@vue/test-utils';
2 | import Row from './row.vue';
3 |
4 | describe('Row', () => {
5 | let wrapper;
6 |
7 | describe('when pass no props', () => {
8 | beforeEach(() => {
9 | wrapper = shallowMount(Row);
10 | });
11 |
12 | it('should match with the snapshot', () => {
13 | expect(wrapper.html()).toMatchSnapshot();
14 | });
15 |
16 | it('should have expected classList', () => {
17 | const expected = [
18 | 'o-row',
19 | 'is-justify-flex-start',
20 | 'is-align-flex-start',
21 | 'is-content-flex-start',
22 | 'is-direction-row',
23 | 'is-wrap',
24 | ];
25 | expect(wrapper.vm.classList).toEqual(expected);
26 | });
27 | });
28 |
29 | describe('when pass some props', () => {
30 | const props = {
31 | justify: 'flex-end',
32 | align: 'flex-end',
33 | content: 'center',
34 | direction: 'column',
35 | wrap: 'no-wrap',
36 | };
37 |
38 | describe(`and the props are ${JSON.stringify(props)}`, () => {
39 | beforeEach(() => {
40 | wrapper = shallowMount(Row, {
41 | propsData: props,
42 | });
43 | });
44 |
45 | it('should match with the snapshot', () => {
46 | expect(wrapper.html()).toMatchSnapshot();
47 | });
48 |
49 | it('should have an expected classList', () => {
50 | const expected = [
51 | 'o-row',
52 | 'is-justify-flex-end',
53 | 'is-align-flex-end',
54 | 'is-content-center',
55 | 'is-direction-column',
56 | 'is-no-wrap',
57 | ];
58 |
59 | expect(wrapper.vm.classList).toEqual(expected);
60 | });
61 | });
62 |
63 | describe('and the prop is another tag like section', () => {
64 | beforeEach(() => {
65 | wrapper = shallowMount(Row, {
66 | propsData: { tag: 'section' },
67 | });
68 | });
69 |
70 | it('should match with the snapshot', () => {
71 | expect(wrapper.html()).toMatchSnapshot();
72 | });
73 | });
74 | });
75 | });
76 |
--------------------------------------------------------------------------------
/src/row/row.stories.js:
--------------------------------------------------------------------------------
1 | import { storiesOf } from '@storybook/vue';
2 | import {
3 | withKnobs,
4 | text,
5 | number,
6 | select,
7 | } from '@storybook/addon-knobs/vue';
8 |
9 | import ORow from './row.vue';
10 |
11 | const justifyOptions = {
12 | center: 'center',
13 | flexStart: 'flex-start',
14 | flexEnd: 'flex-end',
15 | baseline: 'baseline',
16 | };
17 |
18 | const alignOptions = {
19 | center: 'center',
20 | flexStart: 'flex-start',
21 | flexEnd: 'flex-end',
22 | };
23 |
24 | storiesOf('Row', module)
25 | .addDecorator(withKnobs)
26 | .add('default', () => ({
27 | components: { ORow },
28 | template: `${text('text', 'simple row')} `,
29 | }))
30 | .add('justify center', () => ({
31 | components: { ORow },
32 | template: `
34 | ${text('text', 'simple row')}
35 | `,
36 | }))
37 | .add('justify and align center', () => ({
38 | components: { ORow },
39 | template: `
42 |
43 | ${text('box1 text', 'box 1')}
44 |
45 |
46 | ${text('box2 text', 'box 2')}
47 |
48 | `,
49 | }));
50 |
--------------------------------------------------------------------------------
/src/row/row.vue:
--------------------------------------------------------------------------------
1 |
70 |
--------------------------------------------------------------------------------
/src/select/Select.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
19 |
22 | {{ label }}
23 |
24 |
25 |
26 |
30 | {{ findLabel(option) }}
31 |
32 |
35 |
36 |
37 |
38 |
39 |
40 |
43 | {{ placeholder }}
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
58 |
59 |
60 |
61 |
62 |
69 |
70 |
71 |
75 | {{ findLabel(option) }}
76 |
77 |
80 |
81 |
82 |
83 |
84 |
85 |
99 |
100 |
103 |
104 |
108 |
109 |
110 |
111 |
112 |
116 |
117 |
122 |
131 | {{ option.label }}
132 |
133 |
134 |
137 | {{ emptyText }}
138 |
139 |
142 | {{ emptySearch }}
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
405 |
--------------------------------------------------------------------------------
/src/select/index.js:
--------------------------------------------------------------------------------
1 | import Select from './Select.vue';
2 |
3 | export default Select;
4 |
--------------------------------------------------------------------------------
/src/select/select.spec.js:
--------------------------------------------------------------------------------
1 | import { mount } from '@vue/test-utils';
2 | import Select from './Select.vue';
3 |
4 | describe('Select', () => {
5 | let wrapper;
6 |
7 | const reset = () => {
8 | wrapper.setProps({
9 | options: [
10 | {
11 | label: 'São Paulo',
12 | value: 'São Paulo',
13 | }, {
14 | label: 'New York',
15 | value: 'New York',
16 | }, {
17 | label: 'New York',
18 | value: 'Berlin',
19 | }],
20 | multiple: false,
21 | filterable: false,
22 | value: '',
23 | clearable: false,
24 | });
25 |
26 | wrapper.setData({
27 | currentValue: '',
28 | });
29 | };
30 |
31 | beforeAll(() => {
32 | wrapper = mount(Select);
33 | });
34 |
35 | afterEach(reset);
36 |
37 | it('should be a default select at startup', () => {
38 | const defaultClasses = ['o-select', 'o-select--normal'];
39 | const options = wrapper.findAll('.o-select__list-item');
40 |
41 | expect(options.length).toEqual(0);
42 | expect(wrapper.classes()).toEqual(defaultClasses);
43 | expect(wrapper.isVisible()).toEqual(true);
44 | });
45 |
46 | it('should select appear options when trigger space', () => {
47 | wrapper.trigger('keydown.space');
48 | const options = wrapper.findAll('.o-select__list-item');
49 | expect(options.length).toEqual(3);
50 | });
51 |
52 | it('should select appear options when trigger click', () => {
53 | wrapper.trigger('click');
54 | const options = wrapper.findAll('.o-select__list-item');
55 | expect(options.length).toEqual(3);
56 | });
57 |
58 | it('should select São Paulo when using keydown events', () => {
59 | wrapper.trigger('click');
60 | wrapper.find('.o-select__list-item').trigger('click');
61 | expect(wrapper.vm.$data.currentValue).toEqual('São Paulo');
62 | });
63 |
64 | it('should emit change event', () => {
65 | wrapper.trigger('click');
66 | wrapper.find('.o-select__list-item').trigger('click');
67 | expect(wrapper.emitted().change).toBeTruthy();
68 | });
69 | });
70 |
--------------------------------------------------------------------------------
/src/select/select.stories.js:
--------------------------------------------------------------------------------
1 | import { storiesOf } from '@storybook/vue';
2 |
3 | import OSelect from './Select.vue';
4 |
5 |
6 | storiesOf('Select', module)
7 | .add('Basic Usage', () => ({
8 | components: { OSelect },
9 | data() {
10 | return {
11 | options: [
12 | {
13 | label: 'São Paulo',
14 | value: 'São Paulo',
15 | },
16 | {
17 | label: 'London',
18 | value: 'London',
19 | },
20 | {
21 | label: 'Berlin',
22 | value: 'Berlin',
23 | },
24 | {
25 | label: 'New York',
26 | value: 'New York',
27 | },
28 | ],
29 | };
30 | },
31 | template: `
32 | `,
33 | }))
34 | .add('Multiple Selection', () => ({
35 | components: { OSelect },
36 | data() {
37 | return {
38 | options: [
39 | {
40 | label: 'São Paulo',
41 | value: 'São Paulo',
42 | },
43 | {
44 | label: 'London',
45 | value: 'London',
46 | },
47 | {
48 | label: 'Berlin',
49 | value: 'Berlin',
50 | },
51 | {
52 | label: 'New York',
53 | value: 'New York',
54 | },
55 | ],
56 | };
57 | },
58 | template: ' ',
59 | }))
60 | .add('Filterable', () => ({
61 | components: { OSelect },
62 | data() {
63 | return {
64 | options: [
65 | {
66 | label: 'São Paulo',
67 | value: 'São Paulo',
68 | },
69 | {
70 | label: 'London',
71 | value: 'London',
72 | },
73 | {
74 | label: 'Berlin',
75 | value: 'Berlin',
76 | },
77 | {
78 | label: 'New York',
79 | value: 'New York',
80 | },
81 | ],
82 | };
83 | },
84 | template: ' ',
85 | }))
86 | .add('Clearable', () => ({
87 | components: { OSelect },
88 | data() {
89 | return {
90 | options: [
91 | {
92 | label: 'São Paulo',
93 | value: 'São Paulo',
94 | },
95 | {
96 | label: 'London',
97 | value: 'London',
98 | },
99 | {
100 | label: 'Berlin',
101 | value: 'Berlin',
102 | },
103 | {
104 | label: 'New York',
105 | value: 'New York',
106 | },
107 | ],
108 | };
109 | },
110 | template: ' ',
111 | }));
112 |
--------------------------------------------------------------------------------
/src/storyshots.spec.js:
--------------------------------------------------------------------------------
1 | import initStoryshots from '@storybook/addon-storyshots';
2 |
3 | initStoryshots();
4 |
--------------------------------------------------------------------------------