├── .babelrc ├── logo.png ├── cypress.json ├── src ├── utils │ ├── enableClick.js │ ├── generateId.js │ └── hyphenToPascal.js ├── components │ ├── Fetch │ │ ├── index.js │ │ ├── src │ │ │ └── Fetch.vue │ │ └── README.md │ ├── Toggle │ │ ├── index.js │ │ ├── src │ │ │ └── Toggle.vue │ │ └── README.md │ ├── Storage │ │ ├── index.js │ │ ├── src │ │ │ └── Storage.vue │ │ └── README.md │ ├── SmartList │ │ ├── index.js │ │ ├── src │ │ │ └── SmartList.vue │ │ └── README.md │ ├── MediaQuery │ │ ├── index.js │ │ ├── src │ │ │ └── MediaQuery.vue │ │ └── README.md │ ├── SimpleList │ │ ├── index.js │ │ ├── src │ │ │ └── SimpleList.vue │ │ └── README.md │ ├── ErrorBoundary │ │ ├── index.js │ │ ├── src │ │ │ └── ErrorBoundary.vue │ │ └── README.md │ ├── Carousel │ │ ├── index.js │ │ ├── src │ │ │ ├── CarouselSlide.vue │ │ │ └── Carousel.vue │ │ └── README.md │ ├── Listbox │ │ ├── index.js │ │ ├── src │ │ │ ├── ListboxItem.vue │ │ │ └── Listbox.vue │ │ └── README.md │ ├── Tabs │ │ ├── src │ │ │ ├── TabPane.vue │ │ │ ├── TabPanes.vue │ │ │ ├── TabList.vue │ │ │ ├── Tabs.vue │ │ │ └── Tab.vue │ │ ├── index.js │ │ └── README.md │ ├── index.js │ └── Expandable │ │ ├── src │ │ ├── ExpandableItem.vue │ │ ├── ExpandableBody.vue │ │ ├── ExpandableTitle.vue │ │ └── Expandable.vue │ │ ├── index.js │ │ └── README.md └── index.js ├── .postcssrc.js ├── public ├── favicon.ico └── index.html ├── .eslintrc.js ├── tests ├── unit │ ├── .eslintrc.js │ └── SmartList.spec.js └── e2e │ ├── .eslintrc │ ├── specs │ └── test.js │ ├── plugins │ └── index.js │ └── support │ ├── index.js │ └── commands.js ├── .editorconfig ├── playground ├── App.vue └── main.js ├── .gitignore ├── jest.config.js ├── .github ├── FEATURE_REQUEST_TEMPLATE.md ├── ISSUE_TEMPLATE.md ├── CONTRIBUTING.md └── CODE_OF_CONDUCT.md ├── README.md ├── LICENSE └── package.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@vue/app" 4 | ] 5 | } -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/banshee-ui/banshee/HEAD/logo.png -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginsFile": "tests/e2e/plugins/index.js" 3 | } 4 | -------------------------------------------------------------------------------- /src/utils/enableClick.js: -------------------------------------------------------------------------------- 1 | export default fn => Object.assign({}, { click: fn }) 2 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/banshee-ui/banshee/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/utils/generateId.js: -------------------------------------------------------------------------------- 1 | export default () => `_${Math.random().toString(36).substr(2, 9)}` 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 'extends': [ 4 | 'plugin:vue/essential', 5 | '@vue/standard' 6 | ] 7 | } -------------------------------------------------------------------------------- /tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | }, 5 | rules: { 6 | 'import/no-extraneous-dependencies': 'off' 7 | } 8 | } -------------------------------------------------------------------------------- /src/utils/hyphenToPascal.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default str => 3 | str.replace(/(\-|^)([a-z])/gi, (match, delimter, hyphenated) => hyphenated.toUpperCase()) 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*{js, vue}] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /playground/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 14 | -------------------------------------------------------------------------------- /src/components/Fetch/index.js: -------------------------------------------------------------------------------- 1 | import BansheeFetch from './src/Fetch' 2 | 3 | BansheeFetch.install = function (Vue) { 4 | Vue.component(BansheeFetch.name, BansheeFetch) 5 | } 6 | 7 | export default BansheeFetch 8 | -------------------------------------------------------------------------------- /tests/e2e/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "cypress" 4 | ], 5 | "env": { 6 | "mocha": true, 7 | "cypress/globals": true 8 | }, 9 | "rules": { 10 | "strict": "off" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/components/Toggle/index.js: -------------------------------------------------------------------------------- 1 | import BansheeToggle from './src/Toggle' 2 | 3 | BansheeToggle.install = function (Vue) { 4 | Vue.component(BansheeToggle.name, BansheeToggle) 5 | } 6 | 7 | export default BansheeToggle 8 | -------------------------------------------------------------------------------- /src/components/Storage/index.js: -------------------------------------------------------------------------------- 1 | import BansheeStorage from './src/Storage' 2 | 3 | BansheeStorage.install = function (Vue) { 4 | Vue.component(BansheeStorage.name, BansheeStorage) 5 | } 6 | 7 | export default BansheeStorage 8 | -------------------------------------------------------------------------------- /src/components/SmartList/index.js: -------------------------------------------------------------------------------- 1 | import BansheeSmartList from './src/SmartList' 2 | 3 | BansheeSmartList.install = function (Vue) { 4 | Vue.component(BansheeSmartList.name, BansheeSmartList) 5 | } 6 | 7 | export default BansheeSmartList 8 | -------------------------------------------------------------------------------- /src/components/MediaQuery/index.js: -------------------------------------------------------------------------------- 1 | import BansheeMediaQuery from './src/MediaQuery' 2 | 3 | BansheeMediaQuery.install = function (Vue) { 4 | Vue.component(BansheeMediaQuery.name, BansheeMediaQuery) 5 | } 6 | 7 | export default BansheeMediaQuery 8 | -------------------------------------------------------------------------------- /src/components/SimpleList/index.js: -------------------------------------------------------------------------------- 1 | import BansheeSimpleList from './src/SimpleList' 2 | 3 | BansheeSimpleList.install = function (Vue) { 4 | Vue.component(BansheeSimpleList.name, BansheeSimpleList) 5 | } 6 | 7 | export default BansheeSimpleList 8 | -------------------------------------------------------------------------------- /playground/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import Banshee from '../src/' 4 | 5 | Vue.config.productionTip = false 6 | 7 | Vue.use(Banshee) 8 | 9 | new Vue({ 10 | render: h => h(App) 11 | }).$mount('#app') 12 | -------------------------------------------------------------------------------- /tests/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | describe('My First Test', () => { 4 | it('Visits the app root url', () => { 5 | cy.visit('/') 6 | cy.contains('h1', 'Welcome to Your Vue.js App') 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /src/components/ErrorBoundary/index.js: -------------------------------------------------------------------------------- 1 | import BansheeErrorBoundary from './src/ErrorBoundary' 2 | 3 | BansheeErrorBoundary.install = function (Vue) { 4 | Vue.component(BansheeErrorBoundary.name, BansheeErrorBoundary) 5 | } 6 | 7 | export default BansheeErrorBoundary 8 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import * as BansheeComponents from './components' 2 | 3 | const Banshee = { 4 | install (Vue) { 5 | Object.values(BansheeComponents).forEach(component => { 6 | Vue.use(component) 7 | }) 8 | } 9 | } 10 | 11 | if (typeof window !== 'undefined' && window.Vue) { 12 | window.Vue.use(Banshee) 13 | } 14 | 15 | export default Banshee 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | /tests/e2e/videos/ 6 | /tests/e2e/screenshots/ 7 | 8 | # local env files 9 | .env.local 10 | .env.*.local 11 | 12 | # Log files 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw* 25 | -------------------------------------------------------------------------------- /src/components/Carousel/index.js: -------------------------------------------------------------------------------- 1 | import Carousel from './src/Carousel' 2 | import Slide from './src/CarouselSlide' 3 | 4 | Carousel.install = function (Vue) { 5 | Vue.component(Carousel.name, Carousel) 6 | } 7 | 8 | Slide.install = function (Vue) { 9 | Vue.component(Slide.name, Slide) 10 | } 11 | 12 | export const BansheeCarousel = Carousel 13 | export const BansheeCarouselSlide = Slide 14 | -------------------------------------------------------------------------------- /src/components/Listbox/index.js: -------------------------------------------------------------------------------- 1 | import Listbox from './src/Listbox' 2 | import ListboxItem from './src/ListboxItem' 3 | 4 | Listbox.install = function (Vue) { 5 | Vue.component(Listbox.name, Listbox) 6 | } 7 | 8 | ListboxItem.install = function (Vue) { 9 | Vue.component(ListboxItem.name, ListboxItem) 10 | } 11 | 12 | export const BansheeListbox = Listbox 13 | export const BansheeListboxItem = ListboxItem 14 | -------------------------------------------------------------------------------- /src/components/Tabs/src/TabPane.vue: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /tests/e2e/plugins/index.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/guides/guides/plugins-guide.html 2 | 3 | module.exports = (on, config) => { 4 | return Object.assign({}, config, { 5 | fixturesFolder: 'tests/e2e/fixtures', 6 | integrationFolder: 'tests/e2e/specs', 7 | screenshotsFolder: 'tests/e2e/screenshots', 8 | videosFolder: 'tests/e2e/videos', 9 | supportFile: 'tests/e2e/support/index.js' 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /src/components/Carousel/src/CarouselSlide.vue: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /src/components/SimpleList/src/SimpleList.vue: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/components/Tabs/src/TabPanes.vue: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1' 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue' 18 | ], 19 | testMatch: [ 20 | '/(tests/unit/**/*.spec.(ts|tsx|js)|**/__tests__/*.(ts|tsx|js))' 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | banshee 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/e2e/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /.github/FEATURE_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Feature Request 2 | 3 | Adapted from [Vue's feature request template](https://new-issue.vuejs.org/?repo=vuejs/vue). 4 | 5 | Have a cool idea to make Banshee better? Awesome! Thank you so much for thinking of ways to improve the library. Please fill out the template below in an issue to get started! 6 | 7 | ## Template 8 | 9 | **Title**: [FEATURE] {{ YOUR_TITLE_HERE }} 10 | 11 | **What problem does this feature solve?**: 12 | Explain your use case, context, and rationale behind this feature request. More importantly, what is the **end user experience** you are trying to build that led to the need for this feature? 13 | 14 | **What does the proposed API look like?**: 15 | Provide code samples of how this API would work and what it would look like to use. -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | export { BansheeCarousel, BansheeCarouselSlide } from './Carousel' 2 | export { default as BansheeErrorBoundary } from './ErrorBoundary' 3 | export { BansheeExpandable, BansheeExpandableItem, BansheeExpandableTitle, BansheeExpandableBody } from './Expandable' 4 | export { default as BansheeFetch } from './Fetch' 5 | export { BansheeListbox, BansheeListboxItem } from './Listbox' 6 | export { default as BansheeMediaQuery } from './MediaQuery' 7 | export { default as BansheeSimpleList } from './SimpleList' 8 | export { default as BansheeSmartList } from './SmartList' 9 | export { default as BansheeStorage } from './Storage' 10 | export { BansheeTabs, BansheeTabList, BansheeTab, BansheeTabPanes, BansheeTabPane } from './Tabs' 11 | export { default as BansheeToggle } from './Toggle' 12 | -------------------------------------------------------------------------------- /src/components/Expandable/src/ExpandableItem.vue: -------------------------------------------------------------------------------- 1 | 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Banshee Issue Template 2 | 3 | Adapted from [Vue's issue template](https://new-issue.vuejs.org/?repo=vuejs/vue). 4 | 5 | If you find an issue with Banshee please fill copy this format for your bug to get resolved as quickly as possible. Otherwise we may not respond to an issue or ask you to fill this out. 6 | 7 | Thank you for wanting to help improve Banshee. We appreciate it! 8 | 9 | ## Template 10 | 11 | **Title**: [ISSUE] {{ YOUR_TITLE_HERE }} 12 | 13 | **Version**: 14 | 15 | **Link to reproduction** (provide Codesandbox, Codepen, etc.): 16 | 17 | **Steps to reproduce**: 18 | How do we reproduce this bug? The more detailed the better and the quicker we can resolve your issue! 19 | 20 | **What is expected?**: 21 | 22 | **What is actually happening?**: 23 | 24 | **Additional comments?** (optional): 25 | -------------------------------------------------------------------------------- /src/components/Tabs/index.js: -------------------------------------------------------------------------------- 1 | import Tabs from './src/Tabs' 2 | import TabList from './src/TabList' 3 | import Tab from './src/Tab' 4 | import TabPanes from './src/TabPanes' 5 | import TabPane from './src/TabPane' 6 | 7 | Tabs.install = function (Vue) { 8 | Vue.component(Tabs.name, Tabs) 9 | } 10 | 11 | TabList.install = function (Vue) { 12 | Vue.component(TabList.name, TabList) 13 | } 14 | 15 | Tab.install = function (Vue) { 16 | Vue.component(Tab.name, Tab) 17 | } 18 | 19 | TabPanes.install = function (Vue) { 20 | Vue.component(TabPanes.name, TabPanes) 21 | } 22 | 23 | TabPane.install = function (Vue) { 24 | Vue.component(TabPane.name, TabPane) 25 | } 26 | 27 | export const BansheeTabs = Tabs 28 | export const BansheeTabList = TabList 29 | export const BansheeTab = Tab 30 | export const BansheeTabPanes = TabPanes 31 | export const BansheeTabPane = TabPane 32 | -------------------------------------------------------------------------------- /src/components/Expandable/src/ExpandableBody.vue: -------------------------------------------------------------------------------- 1 | 37 | -------------------------------------------------------------------------------- /src/components/Expandable/index.js: -------------------------------------------------------------------------------- 1 | import Expandable from './src/Expandable' 2 | import ExpandableItem from './src/ExpandableItem' 3 | import ExpandableTitle from './src/ExpandableTitle' 4 | import ExpandableBody from './src/ExpandableBody' 5 | 6 | Expandable.install = function (Vue) { 7 | Vue.component(Expandable.name, Expandable) 8 | } 9 | 10 | ExpandableItem.install = function (Vue) { 11 | Vue.component(ExpandableItem.name, ExpandableItem) 12 | } 13 | 14 | ExpandableTitle.install = function (Vue) { 15 | Vue.component(ExpandableTitle.name, ExpandableTitle) 16 | } 17 | 18 | ExpandableBody.install = function (Vue) { 19 | Vue.component(ExpandableBody.name, ExpandableBody) 20 | } 21 | 22 | export const BansheeExpandable = Expandable 23 | export const BansheeExpandableItem = ExpandableItem 24 | export const BansheeExpandableTitle = ExpandableTitle 25 | export const BansheeExpandableBody = ExpandableBody 26 | -------------------------------------------------------------------------------- /tests/e2e/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This is will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

Banshee

6 | 7 |

8 | A mostly renderless Vue UI component and utility library. 9 |

10 | 11 | ## Introduction 12 | 13 | Banshee is a component library for Vue which seeks to only provide the JavaScript functionality and leaves the HTML markup and styling to you. It ships with no CSS and minimal to no HTML in all components. 14 | 15 | Banshee allows you to focus on building custom applications the way you want them to look without having to conform to another library's design specs. Gain complete control on how you build Vue applications. 16 | 17 | **NOTE: Banshee is under active development and should not be used in a production environment. Expect API changes before Beta release.** 18 | 19 | ## Installation 20 | 21 | ```bash 22 | npm install --save banshee-ui 23 | ``` 24 | 25 | ## Documentation 26 | 27 | You can find the official documentation for Banshee [here](https://banshee-ui.github.io/docs/). 28 | 29 | -------------------------------------------------------------------------------- /src/components/ErrorBoundary/src/ErrorBoundary.vue: -------------------------------------------------------------------------------- 1 | 44 | -------------------------------------------------------------------------------- /src/components/Tabs/src/TabList.vue: -------------------------------------------------------------------------------- 1 | 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Dillon Chanis 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 | -------------------------------------------------------------------------------- /src/components/Listbox/src/ListboxItem.vue: -------------------------------------------------------------------------------- 1 | 54 | -------------------------------------------------------------------------------- /src/components/Expandable/src/ExpandableTitle.vue: -------------------------------------------------------------------------------- 1 | 58 | -------------------------------------------------------------------------------- /src/components/Tabs/src/Tabs.vue: -------------------------------------------------------------------------------- 1 | 58 | -------------------------------------------------------------------------------- /src/components/Tabs/src/Tab.vue: -------------------------------------------------------------------------------- 1 | 65 | -------------------------------------------------------------------------------- /src/components/MediaQuery/src/MediaQuery.vue: -------------------------------------------------------------------------------- 1 | 70 | -------------------------------------------------------------------------------- /src/components/Toggle/src/Toggle.vue: -------------------------------------------------------------------------------- 1 | 82 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "banshee-ui", 3 | "description": "A mostly renderless Vue UI component and utility library.", 4 | "version": "0.0.2", 5 | "license": "MIT", 6 | "author": { 7 | "name": "Dillon Chanis", 8 | "email": "dillonchanis92@gmail.com" 9 | }, 10 | "repository": "banshee-ui/banshee", 11 | "main": "dist/BansheeUI.umd.js", 12 | "module": "dist/BansheeUI.common.js", 13 | "unpkg": "dist/BansheeUI.umd.min.js", 14 | "scripts": { 15 | "serve": "vue-cli-service serve playground/main.js", 16 | "build": "vue-cli-service build", 17 | "test": "vue-cli-service test:unit", 18 | "e2e": "vue-cli-service e2e", 19 | "lint": "vue-cli-service lint", 20 | "e2e:open": "vue-cli-service e2e:open", 21 | "package": "vue-cli-service build --target lib --name BansheeUI src/index.js" 22 | }, 23 | "dependencies": { 24 | "vue": "^2.5.16" 25 | }, 26 | "devDependencies": { 27 | "@cypress/webpack-preprocessor": "^3.0.0", 28 | "@vue/cli-plugin-babel": "^3.0.4", 29 | "@vue/cli-plugin-e2e-cypress": "^3.0.4", 30 | "@vue/cli-plugin-eslint": "^3.0.4", 31 | "@vue/cli-plugin-unit-jest": "^3.0.4", 32 | "@vue/cli-service": "^3.0.4", 33 | "@vue/eslint-config-standard": "^3.0.5", 34 | "@vue/test-utils": "^1.0.0-beta.20", 35 | "babel-core": "7.0.0-bridge.0", 36 | "babel-jest": "^23.0.1", 37 | "vue-template-compiler": "^2.5.17", 38 | "lint-staged": "^6.0.0" 39 | }, 40 | "browserslist": [ 41 | "> 1%", 42 | "last 2 versions", 43 | "not ie <= 8" 44 | ], 45 | "gitHooks": { 46 | "pre-commit": "lint-staged" 47 | }, 48 | "lint-staged": { 49 | "*.js": [ 50 | "vue-cli-service lint", 51 | "git add" 52 | ], 53 | "*.vue": [ 54 | "vue-cli-service lint", 55 | "git add" 56 | ] 57 | }, 58 | "keywords": [ 59 | "vue", 60 | "vuejs", 61 | "banshee", 62 | "banshee-ui", 63 | "component", 64 | "components", 65 | "vue-components", 66 | "renderless", 67 | "javascript" 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /tests/unit/SmartList.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import BansheeSmartList from '@/components/SmartList/src/SmartList.vue' 3 | 4 | describe('SmartList.vue', () => { 5 | it('renders props.items when passed', () => { 6 | const items = ['One', 'Two', 'Three'] 7 | 8 | const wrapper = shallowMount(BansheeSmartList, { 9 | propsData: { items }, 10 | scopedSlots: { 11 | default: ` 12 | 17 | ` 18 | } 19 | }) 20 | 21 | // Number of
  • should match the array length 22 | expect(wrapper.findAll('li').length).toBe(items.length) 23 | }) 24 | 25 | it('renders with default sorting', () => { 26 | const items = ['c', 'd', 'a', 'b'] 27 | const sortedItems = items.sort() 28 | 29 | const wrapper = shallowMount(BansheeSmartList, { 30 | propsData: { 31 | items, 32 | 'default-sort': 'asc' 33 | }, 34 | scopedSlots: { 35 | default: ` 36 |
      37 |
    • 38 | {{ item }} 39 |
    • 40 |
    41 | ` 42 | } 43 | }) 44 | 45 | // First element should be 'a' 46 | expect(wrapper.findAll('li').at(0).text()).toBe(sortedItems[0]) 47 | }) 48 | 49 | it('renders only the items matching the search query', () => { 50 | const items = ['Alleria', 'Sylvanas', 'Vereesa'] 51 | const query = 'Syl' 52 | 53 | const wrapper = shallowMount(BansheeSmartList, { 54 | propsData: { items, query }, 55 | scopedSlots: { 56 | default: ` 57 |
      58 |
    • 59 | {{ item }} 60 |
    • 61 |
    62 | ` 63 | } 64 | }) 65 | 66 | expect(wrapper.find('li').text()).toBe('Sylvanas') 67 | }) 68 | }) 69 | -------------------------------------------------------------------------------- /src/components/Expandable/src/Expandable.vue: -------------------------------------------------------------------------------- 1 | 91 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Banshee Contributing Guide 2 | 3 | Thank you for being interested in contributing to Banshee! Before contributing please read through this document to make this process as painless as possible for both parties. 4 | 5 | ## Reporting Issues and Feature Requests 6 | 7 | If you find an issue or have an idea to improve Banshee, please open an issue [here](https://github.com/banshee-ui/banshee/issues). Please find and fill the templates for your respective request before submitting. 8 | 9 | ## Contributing to an Issue/Feature Request: 10 | 11 | If you find an issue/feature that you want to tackle please say so in a comment. If you find that someone has already commented please assume they are actively working on it. If some time has passed, you can ask them to make sure. We do not want two separate parties working on the same thing (but you can collaborate!). 12 | 13 | ## PR Guidelines 14 | 15 | - Do not submit PRs against the `master` branch. 16 | - Create a branch based on issue type 17 | - ie: `feature/{{ branch_name }}`, `bugfix/{{ branch_name }}` 18 | - Multiple commits are fine as they will be squashed 19 | - Do not work in the `dist/` folder and do not commit it 20 | - Do not commit work done in the `playground/` directory 21 | 22 | ## Development Setup 23 | 24 | Clone the repository and run: 25 | 26 | ```bash 27 | $ npm install # or yarn 28 | ``` 29 | 30 | To get running the development server running use: 31 | 32 | ```bash 33 | $ npm run serve 34 | ``` 35 | 36 | Make sure all work is done within the `src/` directory. 37 | 38 | To physically test components as you develop you can use the `playground/` directory. All modules of Banshee are automatically imported from the `src/` folder for you. You should not have to touch `main.js`. 39 | 40 | ## Project Structure 41 | 42 | - **playground**: imports all Banshee modules and mounts a Vue instance to play around with components while developing. 43 | - `playground/main.js`: imports Vue and Banshee and mounts App.vue to a Vue instance 44 | - `playground/App.vue`: Root Vue component to do your testing within 45 | 46 | - **public**: holds `index.html` file, shouldn't needed to be touched ever 47 | 48 | - **src**: contains all the source code to each Banshee component and their utilities 49 | - `src/components/`: the component source code for each Banshee component 50 | - `utils/`: utility functions for use within Banshee component files, you can add more if you see fit for whatever issue/feature you're working on 51 | - `index.js`: exports all Banshee component files, shouldn't need to be touched unless you are creating more components 52 | 53 | ## Credits 54 | 55 | Your name here! -------------------------------------------------------------------------------- /src/components/SmartList/src/SmartList.vue: -------------------------------------------------------------------------------- 1 | 101 | -------------------------------------------------------------------------------- /src/components/ErrorBoundary/README.md: -------------------------------------------------------------------------------- 1 | # Error Boundary 2 | 3 | A reusable error boundary component for catching JavaScript errors and displaying fallback UIs. 4 | 5 | The ErrorBoundary component is based on [React's example component](https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html) featuring a new component hook in React 16 called `componentDidCatch`. 6 | 7 | ## Basic Usage 8 | 9 | To use this component simply wrap any other component which may throw an Error. 10 | 11 | ```html 12 | 13 | 14 | 15 | ``` 16 | 17 | Errors thrown in child components will automatically bubble up to the `BansheeErrorBoundary` component. 18 | 19 | ## Error Boundary 20 | 21 | ### Attributes & Props 22 | 23 | | Name | Required | Type | Default | Description | 24 | | --- | --- | --- | --- | --- | 25 | | on-error | `false` | Function | `null` | callback function to execute in case an error is captured | 26 | | stop-propagation | `false` | Boolean | `false` | boolean to stop propagation of the error up the component tree | 27 | 28 | ### Events 29 | 30 | | Event | Parameters | Description | 31 | | --- | --- | --- | 32 | | onErrorCaptured | (error) | object returning | 33 | 34 | ### Scoped Slots 35 | 36 | | Property | Description | 37 | | --- | --- | 38 | | err | the error that triggered the boundary | 39 | | info | string containing information about the error | 40 | 41 | Furthermore, we can directly access the contents of the `BansheeErrorBoundary` component's `errorCaptured` hook either throw a callback or Vue's emit. 42 | 43 | ### Callbacks via on-error 44 | 45 | The `BansheeErrorBoundary` can receive a callback function through the `on-error` prop. 46 | 47 | ```html 48 |