├── logo.jpg ├── src ├── markdown │ ├── roadmap │ │ ├── README.md │ │ └── meta.json │ └── getting-started │ │ ├── meta.json │ │ └── README.md ├── directives │ ├── tooltip │ │ ├── meta.json │ │ ├── index.js │ │ ├── README.md │ │ └── tooltip.js │ ├── index.js │ └── toggle │ │ ├── index.js │ │ └── toggle.js ├── components │ ├── badge │ │ ├── index.js │ │ ├── Badge.vue │ │ └── README.md │ ├── link │ │ ├── index.js │ │ ├── README.md │ │ ├── create-link-props.js │ │ └── Link.vue │ ├── alert │ │ ├── index.js │ │ ├── README.md │ │ └── Alert.vue │ ├── embed │ │ ├── index.js │ │ ├── README.md │ │ └── Embed.vue │ ├── slider │ │ ├── index.js │ │ ├── README.md │ │ └── Slider.vue │ ├── popover │ │ ├── index.js │ │ ├── README.md │ │ └── Popover.vue │ ├── tooltip │ │ ├── index.js │ │ ├── README.md │ │ └── Tooltip.vue │ ├── collapse │ │ ├── index.js │ │ └── README.md │ ├── datepicker │ │ └── index.js │ ├── image │ │ ├── index.js │ │ ├── README.md │ │ └── Image.vue │ ├── form-input │ │ ├── index.js │ │ └── README.md │ ├── form-radio │ │ ├── index.js │ │ ├── README.md │ │ └── FormRadio.vue │ ├── tabs │ │ ├── index.js │ │ ├── _TabButton.vue │ │ ├── Tab.vue │ │ └── README.md │ ├── form-select │ │ └── index.js │ ├── button-group │ │ ├── index.js │ │ ├── ButtonGroup.vue │ │ └── README.md │ ├── nav │ │ ├── index.js │ │ ├── NavText.vue │ │ ├── NavItem.vue │ │ ├── Nav.vue │ │ └── README.md │ ├── form-checkbox │ │ ├── index.js │ │ └── README.md │ ├── form-textarea │ │ ├── index.js │ │ └── README.md │ ├── button-toolbar │ │ ├── index.js │ │ ├── README.md │ │ └── ButtonToolbar.vue │ ├── form │ │ ├── FormRow.vue │ │ ├── index.js │ │ ├── FormValidFeedback.vue │ │ ├── FormInvalidFeedback.vue │ │ ├── FormFeedback.vue │ │ ├── Form.vue │ │ ├── FormText.vue │ │ └── README.md │ ├── modal │ │ ├── ModalBody.vue │ │ ├── ModalTitle.vue │ │ ├── ModalFooter.vue │ │ ├── index.js │ │ ├── ModalHeader.vue │ │ ├── README.md │ │ └── Modal.vue │ ├── progress │ │ ├── index.js │ │ ├── Progress.vue │ │ ├── README.md │ │ └── ProgressBar.vue │ ├── list-group │ │ ├── index.js │ │ ├── ListGroup.vue │ │ ├── README.md │ │ └── ListGroupItem.vue │ ├── input-group │ │ ├── InputGroupText.vue │ │ ├── index.js │ │ ├── InputGroupAddon.vue │ │ └── InputGroup.vue │ ├── container │ │ ├── index.js │ │ ├── Container.vue │ │ ├── Row.vue │ │ ├── README.md │ │ └── Col.vue │ ├── button │ │ ├── index.js │ │ ├── ButtonClose.vue │ │ └── Button.vue │ ├── dropdown │ │ ├── DropdownDivider.vue │ │ ├── index.js │ │ ├── DropdownItem.vue │ │ └── DropdownHeader.vue │ ├── navbar │ │ ├── index.js │ │ ├── NavbarNav.vue │ │ ├── NavbarBrand.vue │ │ ├── NavbarToggle.vue │ │ ├── Navbar.vue │ │ └── README.md │ ├── breadcrumb │ │ ├── index.js │ │ ├── BreadcrumbItem.vue │ │ ├── README.md │ │ ├── BreadcrumbLink.vue │ │ └── Breadcrumb.vue │ ├── card │ │ ├── index.js │ │ ├── CardGroup.vue │ │ ├── Card.vue │ │ ├── CardFooter.vue │ │ ├── CardHeader.vue │ │ ├── CardImg.vue │ │ ├── CardBody.vue │ │ └── README.md │ └── index.js ├── scripts │ └── utils.js ├── index.js ├── mixins │ ├── root-listener.mixin.js │ └── checkbox-radio.mixin.js └── utils │ ├── events.js │ ├── target.js │ ├── tooltip.class.js │ ├── observer.js │ ├── popover.class.js │ └── constants.js ├── .editorconfig ├── .gitignore ├── ISSUE_TEMPLATE.md ├── LICENSE ├── sandbox └── Sandbox.vue ├── CHANGELOG.md ├── package.json └── CONTRIBUTING.md /logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-vue/HEAD/logo.jpg -------------------------------------------------------------------------------- /src/markdown/roadmap/README.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | > **Note:** This page is currently under development. 4 | -------------------------------------------------------------------------------- /src/markdown/roadmap/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Getting Started", 3 | "slug": "getting-started" 4 | } 5 | -------------------------------------------------------------------------------- /src/directives/tooltip/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "directive", 3 | "name": "Tooltip", 4 | "slug": "tooltip" 5 | } -------------------------------------------------------------------------------- /src/markdown/getting-started/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Getting Started", 3 | "slug": "getting-started" 4 | } 5 | -------------------------------------------------------------------------------- /src/directives/index.js: -------------------------------------------------------------------------------- 1 | import dToggle from './toggle' 2 | import dTooltip from './tooltip' 3 | 4 | export { 5 | dToggle, 6 | dTooltip 7 | } 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 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 | -------------------------------------------------------------------------------- /src/directives/toggle/index.js: -------------------------------------------------------------------------------- 1 | import dToggle from './toggle' 2 | import { registerDirectives, vueUse } from '../../utils' 3 | 4 | const directives = { 5 | dToggle 6 | } 7 | 8 | const VuePlugin = { 9 | install (Vue) { 10 | registerDirectives(Vue, directives) 11 | } 12 | } 13 | 14 | vueUse(VuePlugin) 15 | 16 | export default VuePlugin 17 | -------------------------------------------------------------------------------- /src/directives/tooltip/index.js: -------------------------------------------------------------------------------- 1 | import dTooltip from './tooltip' 2 | import { registerDirectives, vueUse } from '../../utils' 3 | 4 | const directives = { 5 | dTooltip 6 | } 7 | 8 | const VuePlugin = { 9 | install (Vue) { 10 | registerDirectives(Vue, directives) 11 | } 12 | } 13 | 14 | vueUse(VuePlugin) 15 | 16 | export default VuePlugin 17 | -------------------------------------------------------------------------------- /src/components/badge/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dBadge from './Badge.vue' 4 | 5 | const components = { 6 | dBadge 7 | } 8 | 9 | const VuePlugin = { 10 | install (Vue) { 11 | registerComponents(Vue, components) 12 | } 13 | } 14 | 15 | vueUse(VuePlugin) 16 | 17 | export default VuePlugin 18 | -------------------------------------------------------------------------------- /src/components/link/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dLink from './Link.vue'; 4 | 5 | const components = { 6 | dLink 7 | } 8 | 9 | const VuePlugin = { 10 | install (Vue) { 11 | registerComponents(Vue, components) 12 | } 13 | } 14 | 15 | vueUse(VuePlugin) 16 | 17 | export default VuePlugin 18 | -------------------------------------------------------------------------------- /src/components/alert/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dAlert from './Alert.vue'; 4 | 5 | const components = { 6 | dAlert 7 | } 8 | 9 | const VuePlugin = { 10 | install (Vue) { 11 | registerComponents(Vue, components) 12 | } 13 | } 14 | 15 | vueUse(VuePlugin) 16 | 17 | export default VuePlugin 18 | -------------------------------------------------------------------------------- /src/components/embed/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils'; 2 | 3 | import dEmbed from './Embed.vue'; 4 | 5 | const components = { 6 | dEmbed, 7 | } 8 | 9 | const VuePlugin = { 10 | install (Vue) { 11 | registerComponents(Vue, components) 12 | } 13 | } 14 | 15 | vueUse(VuePlugin) 16 | 17 | export default VuePlugin 18 | -------------------------------------------------------------------------------- /src/components/slider/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dSlider from './Slider.vue' 4 | 5 | const components = { 6 | dSlider 7 | } 8 | 9 | const VuePlugin = { 10 | install (Vue) { 11 | registerComponents(Vue, components) 12 | } 13 | } 14 | 15 | vueUse(VuePlugin) 16 | 17 | export default VuePlugin 18 | -------------------------------------------------------------------------------- /src/components/popover/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils'; 2 | 3 | import dPopover from './Popover.vue'; 4 | 5 | const components = { 6 | dPopover 7 | } 8 | 9 | const VuePlugin = { 10 | install (Vue) { 11 | registerComponents(Vue, components) 12 | } 13 | } 14 | 15 | vueUse(VuePlugin) 16 | 17 | export default VuePlugin 18 | -------------------------------------------------------------------------------- /src/components/tooltip/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dTooltip from './Tooltip.vue'; 4 | 5 | const components = { 6 | dTooltip 7 | } 8 | 9 | const VuePlugin = { 10 | install (Vue) { 11 | registerComponents(Vue, components) 12 | } 13 | } 14 | 15 | vueUse(VuePlugin) 16 | 17 | export default VuePlugin 18 | -------------------------------------------------------------------------------- /src/components/collapse/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dCollapse from './Collapse.vue'; 4 | 5 | const components = { 6 | dCollapse 7 | } 8 | 9 | const VuePlugin = { 10 | install (Vue) { 11 | registerComponents(Vue, components) 12 | } 13 | } 14 | 15 | vueUse(VuePlugin) 16 | 17 | export default VuePlugin 18 | -------------------------------------------------------------------------------- /src/components/datepicker/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dDatepicker from './Datepicker.vue' 4 | 5 | const components = { 6 | dDatepicker 7 | } 8 | 9 | const VuePlugin = { 10 | install (Vue) { 11 | registerComponents(Vue, components) 12 | } 13 | } 14 | 15 | vueUse(VuePlugin) 16 | 17 | export default VuePlugin 18 | -------------------------------------------------------------------------------- /src/components/image/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils' 2 | 3 | import dImg from './Image.vue' 4 | 5 | const components = { 6 | dImg, 7 | dImage: dImg 8 | } 9 | 10 | const VuePlugin = { 11 | install (Vue) { 12 | registerComponents(Vue, components) 13 | } 14 | } 15 | 16 | vueUse(VuePlugin) 17 | 18 | export default VuePlugin 19 | -------------------------------------------------------------------------------- /src/components/form-input/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dFormInput from './FormInput.vue' 4 | 5 | const components = { 6 | dFormInput, 7 | dInput: dFormInput 8 | } 9 | 10 | const VuePlugin = { 11 | install (Vue) { 12 | registerComponents(Vue, components) 13 | } 14 | } 15 | 16 | vueUse(VuePlugin) 17 | 18 | export default VuePlugin 19 | -------------------------------------------------------------------------------- /src/components/form-radio/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dFormRadio from './FormRadio.vue' 4 | 5 | const components = { 6 | dFormRadio, 7 | dRadio: dFormRadio 8 | } 9 | 10 | const VuePlugin = { 11 | install (Vue) { 12 | registerComponents(Vue, components) 13 | } 14 | } 15 | 16 | vueUse(VuePlugin) 17 | 18 | export default VuePlugin 19 | -------------------------------------------------------------------------------- /src/components/tabs/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils'; 2 | 3 | import dTabs from './Tabs.vue'; 4 | import dTab from './Tab.vue'; 5 | 6 | const components = { 7 | dTabs, 8 | dTab 9 | } 10 | 11 | const VuePlugin = { 12 | install (Vue) { 13 | registerComponents(Vue, components) 14 | } 15 | } 16 | 17 | vueUse(VuePlugin) 18 | 19 | export default VuePlugin 20 | -------------------------------------------------------------------------------- /src/components/form-select/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dFormSelect from './FormSelect.vue' 4 | 5 | const components = { 6 | dFormSelect, 7 | dSelect: dFormSelect 8 | } 9 | 10 | const VuePlugin = { 11 | install (Vue) { 12 | registerComponents(Vue, components) 13 | } 14 | } 15 | 16 | vueUse(VuePlugin) 17 | 18 | export default VuePlugin 19 | -------------------------------------------------------------------------------- /src/components/button-group/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils'; 2 | 3 | import dButtonGroup from './ButtonGroup.vue'; 4 | 5 | const components = { 6 | dButtonGroup, 7 | sBtnGroup: dButtonGroup 8 | } 9 | 10 | const VuePlugin = { 11 | install (Vue) { 12 | registerComponents(Vue, components) 13 | } 14 | } 15 | 16 | vueUse(VuePlugin) 17 | 18 | export default VuePlugin 19 | -------------------------------------------------------------------------------- /src/components/nav/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dNav from './Nav.vue'; 4 | import dNavItem from './NavItem.vue'; 5 | 6 | const components = { 7 | dNav, 8 | dNavItem 9 | } 10 | 11 | const VuePlugin = { 12 | install (Vue) { 13 | registerComponents(Vue, components) 14 | } 15 | } 16 | 17 | vueUse(VuePlugin) 18 | 19 | export default VuePlugin 20 | -------------------------------------------------------------------------------- /src/components/form-checkbox/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dFormCheckbox from './FormCheckbox.vue' 4 | 5 | const components = { 6 | dFormCheckbox, 7 | dCheckbox: dFormCheckbox 8 | } 9 | 10 | const VuePlugin = { 11 | install (Vue) { 12 | registerComponents(Vue, components) 13 | } 14 | } 15 | 16 | vueUse(VuePlugin) 17 | 18 | export default VuePlugin 19 | -------------------------------------------------------------------------------- /src/components/form-textarea/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dFormTextarea from './FormTextarea.vue' 4 | 5 | const components = { 6 | dFormTextarea, 7 | dTextarea: dFormTextarea 8 | } 9 | 10 | const VuePlugin = { 11 | install (Vue) { 12 | registerComponents(Vue, components) 13 | } 14 | } 15 | 16 | vueUse(VuePlugin) 17 | 18 | export default VuePlugin 19 | -------------------------------------------------------------------------------- /src/components/button-toolbar/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils'; 2 | 3 | import dButtonToolbar from './ButtonToolbar.vue'; 4 | 5 | const components = { 6 | dButtonToolbar, 7 | dBtnToolbar: dButtonToolbar 8 | } 9 | 10 | const VuePlugin = { 11 | install (Vue) { 12 | registerComponents(Vue, components) 13 | } 14 | } 15 | 16 | vueUse(VuePlugin) 17 | 18 | export default VuePlugin 19 | -------------------------------------------------------------------------------- /src/components/form/FormRow.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | 22 | -------------------------------------------------------------------------------- /src/components/nav/NavText.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | 22 | -------------------------------------------------------------------------------- /src/components/modal/ModalBody.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | -------------------------------------------------------------------------------- /src/components/modal/ModalTitle.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | 22 | -------------------------------------------------------------------------------- /src/components/progress/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dProgress from './Progress.vue'; 4 | import dProgressBar from './ProgressBar.vue' 5 | 6 | const components = { 7 | dProgress, 8 | dProgressBar 9 | } 10 | 11 | const VuePlugin = { 12 | install (Vue) { 13 | registerComponents(Vue, components) 14 | } 15 | } 16 | 17 | vueUse(VuePlugin) 18 | 19 | export default VuePlugin 20 | -------------------------------------------------------------------------------- /src/components/modal/ModalFooter.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | 22 | -------------------------------------------------------------------------------- /src/components/list-group/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dListGroup from './ListGroup.vue'; 4 | import dListGroupItem from './ListGroupItem.vue' 5 | 6 | const components = { 7 | dListGroup, 8 | dListGroupItem 9 | } 10 | 11 | const VuePlugin = { 12 | install (Vue) { 13 | registerComponents(Vue, components) 14 | } 15 | } 16 | 17 | vueUse(VuePlugin) 18 | 19 | export default VuePlugin 20 | -------------------------------------------------------------------------------- /src/components/input-group/InputGroupText.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | -------------------------------------------------------------------------------- /src/components/container/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dContainer from './Container.vue'; 4 | import dRow from './Row.vue'; 5 | import dCol from './Col.vue'; 6 | 7 | const components = { 8 | dContainer, 9 | dRow, 10 | dCol, 11 | } 12 | 13 | const VuePlugin = { 14 | install (Vue) { 15 | registerComponents(Vue, components) 16 | } 17 | } 18 | 19 | vueUse(VuePlugin) 20 | 21 | export default VuePlugin 22 | -------------------------------------------------------------------------------- /src/components/button/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dButton from './Button.vue'; 4 | import dButtonClose from './ButtonClose.vue'; 5 | 6 | const components = { 7 | dButton, 8 | dBtn: dButton, 9 | dButtonClose, 10 | dBtnClose: dButtonClose 11 | } 12 | 13 | const VuePlugin = { 14 | install (Vue) { 15 | registerComponents(Vue, components) 16 | } 17 | } 18 | 19 | vueUse(VuePlugin) 20 | 21 | export default VuePlugin 22 | -------------------------------------------------------------------------------- /src/components/dropdown/DropdownDivider.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 23 | -------------------------------------------------------------------------------- /src/components/input-group/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dInputGroup from './InputGroup.vue' 4 | import dInputGroupText from './InputGroupText.vue' 5 | import dInputGroupAddon from './InputGroupAddon.vue' 6 | 7 | const components = { 8 | dInputGroup, 9 | dInputGroupText, 10 | dInputGroupAddon 11 | } 12 | 13 | const VuePlugin = { 14 | install (Vue) { 15 | registerComponents(Vue, components) 16 | } 17 | } 18 | 19 | vueUse(VuePlugin) 20 | 21 | export default VuePlugin 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Dependency directories 17 | node_modules/ 18 | 19 | # Optional npm cache directory 20 | .npm 21 | 22 | # Optional eslint cache 23 | .eslintcache 24 | 25 | # Optional REPL history 26 | .node_repl_history 27 | 28 | # Output of 'npm pack' 29 | *.tgz 30 | 31 | # Yarn Integrity file 32 | .yarn-integrity 33 | 34 | # dotenv environment variables file 35 | .env -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Expected Behavior 2 | 3 | 4 | ## Current Behavior 5 | 6 | 7 | ## Steps to Reproduce 8 | 1. 9 | 2. 10 | 3. 11 | 12 | ## Context (Environment) 13 | 14 | 15 | ## Possible Solution 16 | 17 | 18 | ## Possible Implementation 19 | -------------------------------------------------------------------------------- /src/components/navbar/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils'; 2 | 3 | import dNavbar from './Navbar.vue' 4 | import dNavbarBrand from './NavbarBrand.vue' 5 | import dNavbarNav from './NavbarNav.vue' 6 | import dNavbarToggle from './NavbarToggle.vue' 7 | 8 | const components = { 9 | dNavbar, 10 | dNavbarBrand, 11 | dNavbarNav, 12 | dNavbarToggle 13 | } 14 | 15 | const VuePlugin = { 16 | install (Vue) { 17 | registerComponents(Vue, components) 18 | } 19 | } 20 | 21 | vueUse(VuePlugin) 22 | 23 | export default VuePlugin 24 | -------------------------------------------------------------------------------- /src/components/breadcrumb/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils' 2 | 3 | import dLink from '../link/Link.vue' 4 | import dBreadcrumb from './Breadcrumb.vue' 5 | import dBreadcrumbItem from './BreadcrumbItem.vue' 6 | import dBreadcrumbLink from './BreadcrumbLink.vue' 7 | 8 | const components = { 9 | dLink, 10 | dBreadcrumb, 11 | dBreadcrumbItem, 12 | dBreadcrumbLink 13 | } 14 | 15 | const VuePlugin = { 16 | install (Vue) { 17 | registerComponents(Vue, components) 18 | } 19 | } 20 | 21 | vueUse(VuePlugin) 22 | 23 | export default VuePlugin 24 | -------------------------------------------------------------------------------- /src/components/nav/NavItem.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 24 | -------------------------------------------------------------------------------- /src/components/dropdown/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils'; 2 | 3 | import dDropdown from './Dropdown.vue' 4 | import dDropdownItem from './DropdownItem.vue' 5 | import dDropdownHeader from './DropdownHeader.vue' 6 | import dDropdownDivider from './DropdownDivider.vue' 7 | 8 | const components = { 9 | dDropdown, 10 | dDropdownItem, 11 | dDropdownHeader, 12 | dDropdownDivider 13 | } 14 | 15 | const VuePlugin = { 16 | install (Vue) { 17 | registerComponents(Vue, components) 18 | } 19 | } 20 | 21 | vueUse(VuePlugin) 22 | 23 | export default VuePlugin 24 | -------------------------------------------------------------------------------- /src/components/dropdown/DropdownItem.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | 21 | 26 | -------------------------------------------------------------------------------- /src/components/modal/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from './../../utils'; 2 | 3 | import dModal from './Modal.vue'; 4 | import dModalHeader from './ModalHeader.vue'; 5 | import dModalTitle from './ModalTitle.vue'; 6 | import dModalBody from './ModalBody.vue'; 7 | import dModalFooter from './ModalFooter.vue'; 8 | 9 | const components = { 10 | dModal, 11 | dModalHeader, 12 | dModalTitle, 13 | dModalBody, 14 | dModalFooter 15 | } 16 | 17 | const VuePlugin = { 18 | install (Vue) { 19 | registerComponents(Vue, components) 20 | } 21 | } 22 | 23 | vueUse(VuePlugin) 24 | 25 | export default VuePlugin 26 | -------------------------------------------------------------------------------- /src/scripts/utils.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk'); 2 | const log = console.log; 3 | 4 | exports.logError = (err, ...args) => { 5 | log(`${chalk.white.bgRed(' ERROR ')} ${err}\n`, args ? args : ''); 6 | } 7 | 8 | exports.logWarn = (warn, ...args) => { 9 | log(`${chalk.black.bgKeyword('orange')(' WARNING ')} ${warn}\n`, args.length ? args : ''); 10 | } 11 | 12 | exports.logInfo = (info, ...args) => { 13 | log(`${chalk.white.bgBlue(' INFO ')} ${info}\n`, args.length ? args : ''); 14 | } 15 | 16 | exports.logSuccess = (success, ...args) => { 17 | log(`${chalk.black.bgGreen(' SUCCESS ')} ${success}\n`, args.length ? args : ''); 18 | } -------------------------------------------------------------------------------- /src/components/dropdown/DropdownHeader.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 30 | -------------------------------------------------------------------------------- /src/components/button-toolbar/README.md: -------------------------------------------------------------------------------- 1 | # Button Toolbars 2 | 3 | Button toolbars allow you to group a series of button or input groups on a single line. 4 | 5 | :::demo 6 | ```html 7 | 8 | 9 | Create 10 | Edit 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ``` 20 | ::: 21 | 22 | ## Alias 23 | 24 | The `` component is also aliased as ``. 25 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import * as components from './components' 2 | import * as directives from './directives' 3 | import { vueUse } from './utils' 4 | 5 | const VuePlugin = { 6 | install: function (Vue) { 7 | if (Vue._shards_vue_installed) { 8 | return 9 | } 10 | 11 | Vue._shards_vue_installed = true; 12 | 13 | // Register component plugins 14 | for (let component in components) { 15 | Vue.use(components[component]) 16 | } 17 | 18 | // Register directive plugins 19 | for (let directive in directives) { 20 | Vue.use(directives[directive]) 21 | } 22 | } 23 | } 24 | 25 | vueUse(VuePlugin) 26 | 27 | export default VuePlugin -------------------------------------------------------------------------------- /src/components/card/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils'; 2 | 3 | import dCard from './Card.vue' 4 | import dCardBody from './CardBody.vue' 5 | import dCardFooter from './CardFooter.vue' 6 | import dCardGroup from './CardGroup.vue' 7 | import dCardHeader from './CardHeader.vue' 8 | import dCardImg from './CardImg.vue' 9 | 10 | const components = { 11 | dCard, 12 | dCardBody, 13 | dCardFooter, 14 | dCardGroup, 15 | dCardHeader, 16 | dCardImg 17 | } 18 | 19 | const VuePlugin = { 20 | install (Vue) { 21 | registerComponents(Vue, components) 22 | } 23 | } 24 | 25 | vueUse(VuePlugin) 26 | 27 | export default VuePlugin 28 | -------------------------------------------------------------------------------- /src/components/embed/README.md: -------------------------------------------------------------------------------- 1 | # Embeds 2 | 3 | Embeds allow you to create responsive video or slideshow embeds based on the width of the parent. 4 | 5 | ## Basic Example 6 | 7 | The following embed types are supported: `iframe` (by default), `video`, `object` and `embed`. 8 | 9 | :::demo 10 | ```html 11 | 12 | 16 | 17 | 18 | ``` 19 | ::: 20 | 21 | ## Aspect Ratios 22 | 23 | You can also set the embed aspect ratio via the `aspect` prop. The following aspect ratios are available: `21by9`, `16by9`, `4by3`, `1by1`. 24 | -------------------------------------------------------------------------------- /src/components/button-toolbar/ButtonToolbar.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 30 | -------------------------------------------------------------------------------- /src/components/list-group/ListGroup.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 31 | -------------------------------------------------------------------------------- /src/components/container/Container.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 31 | 32 | -------------------------------------------------------------------------------- /src/components/list-group/README.md: -------------------------------------------------------------------------------- 1 | # List Groups 2 | 3 | List groups allow you to display series of content. 4 | 5 | ## Basic Example 6 | 7 | You can create list groups using the `` component with the `` sub-component. 8 | 9 | :::demo 10 | ```html 11 | 12 | 13 | Cras justo odio 14 | Dapibus ac facilisis in 15 | Morbi leo risus 16 | Porta ac consectetur ac 17 | Vestibulum at eros 18 | 19 | 20 | 21 | 22 | ``` 23 | ::: 24 | -------------------------------------------------------------------------------- /src/components/image/README.md: -------------------------------------------------------------------------------- 1 | # Images 2 | 3 | The `` component provides an easy way of adding responsive behavior to your images. Other than this, the component also provides easy-to-use handles for thumbnail styling, alignment and rounded images. 4 | 5 | ## Alias 6 | 7 | The `` component is also available as ``. 8 | 9 | ## Basic Example 10 | 11 | :::demo 12 | ```html 13 | 14 | 15 | 16 | 17 | ``` 18 | ::: 19 | 20 | 21 | ## Thumbnails 22 | 23 | Using the `thumbnail` prop you can turn your images into thumbnails. 24 | 25 | :::demo 26 | ```html 27 | 28 | 29 | 30 | 31 | ``` 32 | ::: 33 | -------------------------------------------------------------------------------- /src/components/link/README.md: -------------------------------------------------------------------------------- 1 | # Links 2 | 3 | The `` component is a wrapper over regular `` links or ``s and it is used behind the scenes across multiple components. 4 | 5 | > **Note:** Most components that use the `` component are properly documented so you can see where you can take advantage of the props provided by this component. 6 | 7 | 8 | ## Basic Example 9 | 10 | Creating a regular link using the `` component is fairly simple. 11 | 12 | :::demo 13 | ```html 14 | 15 | My Link 16 | 17 | 18 | ``` 19 | ::: 20 | 21 | ## Router Links 22 | 23 | Using the `to` prop will turn the link into a `` component. 24 | 25 | ## Disabled State 26 | 27 | Using the `disabled` prop you can set your link as disabled. 28 | -------------------------------------------------------------------------------- /src/components/form/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponents, vueUse } from '../../utils' 2 | 3 | import dForm from './Form.vue' 4 | import dFormRow from './FormRow.vue' 5 | import dFormText from './FormText.vue' 6 | import dFormFeedback from './FormFeedback.vue' 7 | import dFormValidFeedback from './FormValidFeedback.vue' 8 | import dFormInvalidFeedback from './FormInvalidFeedback.vue' 9 | 10 | const components = { 11 | dForm, 12 | dFormRow, 13 | dFormText, 14 | dFormFeedback, 15 | dFormValidFeedback, 16 | dValidFeedback: dFormValidFeedback, 17 | dFormInvalidFeedback, 18 | dInvalidFeedback: dFormInvalidFeedback 19 | } 20 | 21 | const VuePlugin = { 22 | install (Vue) { 23 | registerComponents(Vue, components) 24 | } 25 | } 26 | 27 | vueUse(VuePlugin) 28 | 29 | export default VuePlugin 30 | -------------------------------------------------------------------------------- /src/components/form/FormValidFeedback.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 40 | -------------------------------------------------------------------------------- /src/components/form/FormInvalidFeedback.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 40 | -------------------------------------------------------------------------------- /src/components/modal/ModalHeader.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 39 | 40 | -------------------------------------------------------------------------------- /src/mixins/root-listener.mixin.js: -------------------------------------------------------------------------------- 1 | import { isArray } from '../utils'; 2 | 3 | const _DR_RL_ = '_DR_RL_'; 4 | 5 | export default { 6 | methods: { 7 | listenOnRoot(event, callback) { 8 | if (!this[_DR_RL_] || !isArray(this[_DR_RL_])) { 9 | this[_DR_RL_] = [] 10 | } 11 | 12 | this[_DR_RL_].push({ event, callback }) 13 | this.$root.$on(event, callback) 14 | 15 | return this 16 | }, 17 | emitOnRoot(event, ...args) { 18 | this.$root.$emit(event, ...args) 19 | return this 20 | } 21 | }, 22 | beforeDestroy() { 23 | if (!this[_DR_RL_] && !isArray(this[_DR_RL_])) { 24 | return 25 | } 26 | 27 | while (this[_DR_RL_].length > 0) { 28 | const { event, callback } = this[_DR_RL_].shift() 29 | this.$root.$off(event, callback) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/components/navbar/NavbarNav.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 39 | -------------------------------------------------------------------------------- /src/components/form/FormFeedback.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 40 | -------------------------------------------------------------------------------- /src/components/form/Form.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 41 | -------------------------------------------------------------------------------- /src/components/form/FormText.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 42 | -------------------------------------------------------------------------------- /src/directives/tooltip/README.md: -------------------------------------------------------------------------------- 1 | # Tooltip 2 | 3 | The `v-d-tooltip` directive can be applied to any component in order to create powerful and dynamic tooltips. 4 | 5 | ## Basic Example 6 | 7 | :::demo 8 | ```html 9 | 10 | Hover Me 11 | 12 | 13 | ``` 14 | ::: 15 | 16 | ## Placement 17 | 18 | Changing the tooltip's placement can be achieved using the, `auto`, `top`, `bottom`, `left`, `right`, `topleft`, `topright`, `bottomleft`, `bottomright`, `lefttop`, `leftbottom`, `righttop` or `rightbottom` modifiers. 19 | 20 | :::demo 21 | ```html 22 | 23 | Hover Me 24 | 25 | 26 | ``` 27 | ::: 28 | 29 | ## Triggers 30 | 31 | You can change the default trigger (hover) using either the `click`, `hover` or `focus` modifier. 32 | 33 | :::demo 34 | ```html 35 | 36 | Click Me 37 | 38 | 39 | ``` 40 | ::: 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/components/breadcrumb/BreadcrumbItem.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 43 | -------------------------------------------------------------------------------- /src/components/card/CardGroup.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 DesignRevision 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/navbar/NavbarBrand.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 42 | -------------------------------------------------------------------------------- /src/components/embed/Embed.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 47 | 48 | -------------------------------------------------------------------------------- /src/components/button/ButtonClose.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 48 | -------------------------------------------------------------------------------- /src/components/breadcrumb/README.md: -------------------------------------------------------------------------------- 1 | # Breadcrumbs 2 | 3 | Breadcrumbs are a great component for indicating the current page's location within a navigation. 4 | 5 | ## Basic Example 6 | 7 | The `` component comes with an `:items` prop that accepts an array of objects representing each breadcrumb menu item. 8 | 9 | :::demo 10 | ```html 11 | 14 | 15 | 33 | 34 | 35 | ``` 36 | ::: 37 | 38 | ## Manual Breadcrumbs 39 | 40 | You can also compose your own breadscumb structures using the `` component. 41 | 42 | :::demo 43 | ```html 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | ``` 53 | ::: 54 | -------------------------------------------------------------------------------- /sandbox/Sandbox.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 46 | -------------------------------------------------------------------------------- /src/components/link/create-link-props.js: -------------------------------------------------------------------------------- 1 | export default function createLinkProps() { 2 | return { 3 | href: { 4 | type: String, 5 | default: null 6 | }, 7 | to: { 8 | type: [String, Object], 9 | default: null 10 | }, 11 | disabled: { 12 | type: Boolean, 13 | default: false 14 | }, 15 | target: { 16 | type: String, 17 | default: '_self' 18 | }, 19 | rel: { 20 | type: String, 21 | default: null 22 | }, 23 | exact: { 24 | type: Boolean, 25 | default: false 26 | }, 27 | exactActiveClass: { 28 | type: String 29 | }, 30 | active: { 31 | type: Boolean, 32 | default: false 33 | }, 34 | activeClass: { 35 | type: String 36 | }, 37 | tag: { 38 | type: String, 39 | default: 'a' 40 | }, 41 | routerTag: { 42 | type: String, 43 | default: 'a' 44 | }, 45 | event: { 46 | type: [String, Array], 47 | default: 'click' 48 | }, 49 | append: { 50 | type: Boolean, 51 | default: false 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/components/breadcrumb/BreadcrumbLink.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 57 | -------------------------------------------------------------------------------- /src/components/card/Card.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 58 | -------------------------------------------------------------------------------- /src/components/input-group/InputGroupAddon.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 59 | -------------------------------------------------------------------------------- /src/components/nav/Nav.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 63 | -------------------------------------------------------------------------------- /src/components/card/CardFooter.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 62 | -------------------------------------------------------------------------------- /src/components/card/CardHeader.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 62 | -------------------------------------------------------------------------------- /src/components/breadcrumb/Breadcrumb.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 56 | -------------------------------------------------------------------------------- /src/utils/events.js: -------------------------------------------------------------------------------- 1 | // Creates the cancelable event props. 2 | function _makeCancelableEventProps() { 3 | return { enumerable: true, configurable: false, writable: false } 4 | } 5 | 6 | /** 7 | * Custom cancelable event. 8 | */ 9 | export class CancelableEvent { 10 | constructor (type, eventInit = {}) { 11 | Object.assign(this, CancelableEvent.defaults(), eventInit, { type }) 12 | 13 | Object.defineProperties(this, { 14 | type: _makeCancelableEventProps(), 15 | cancelable: _makeCancelableEventProps(), 16 | nativeEvent: _makeCancelableEventProps(), 17 | target: _makeCancelableEventProps(), 18 | relatedTarget: _makeCancelableEventProps(), 19 | vueTarget: _makeCancelableEventProps() 20 | }) 21 | 22 | let defaultPrevented = false 23 | 24 | this.preventDefault = function preventDefault() { 25 | if (this.cancelable) { 26 | defaultPrevented = true 27 | } 28 | } 29 | 30 | Object.defineProperty(this, 'defaultPrevented', { 31 | enumerable: true, 32 | get() { 33 | return defaultPrevented 34 | } 35 | }) 36 | } 37 | 38 | static defaults() { 39 | return { 40 | type: '', 41 | cancelable: true, 42 | nativeEvent: null, 43 | target: null, 44 | relatedTarget: null, 45 | vueTarget: null 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/components/navbar/NavbarToggle.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 56 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ### 1.0.7 - (2019-01-20) 6 | 7 | * fix(d-textarea): fix(d-textarea): dynamic height based on max-rows #12 8 | 9 | ### 1.0.6 - (2018-11-20) 10 | 11 | * compat: fix IE11 conflict 12 | * fix(d-form-checkbox): remove unnecessary `:checked` binding. 13 | * fix(d-form-radio): remove unnecessary `:checked` binding. 14 | 15 | ### 1.0.5 - (2018-10-30) 16 | 17 | * fix(d-link): exact/active classes not properly applied #10 18 | * fix(d-dropdown): hide dropdown when link is clicked 19 | 20 | ### 1.0.4 - (2018-10-15) 21 | 22 | * feature(d-datepicker): impr. highlighted dates, add small datepicker prop/modifier 23 | * feature(d-progress): add size prop + docs 24 | * fix(d-input): allow file inputs (temp) 25 | * fix(d-datepicker): fix datepickers inside input groups 26 | * fix(d-datepicker): fix highlighted colors 27 | * fix(d-card): bind listeners to the card component 28 | * fix: propagate link-specific props for d-dropdown-item 29 | * fix: incorrect use of `.includes()` in `` 30 | * fix: computed `d-col` offset and order classes 31 | * chore: update readme 32 | 33 | ### 1.0.3 - (2018-09-18) 34 | 35 | * chore: update BS 4.1.3, Shards 2.1.0 36 | * chore: update dist 37 | 38 | ### 1.0.2 - (2018-09-18) 39 | 40 | * fix(alert): close button alert issues 41 | * fix(d-link): invalid `to` prop binding 42 | 43 | ### 1.0.1 - (2018-09-12) 44 | 45 | * Fixed linting errors. 46 | 47 | ### 1.0.0 - (2018-09-11) 48 | 49 | * Initial release. 50 | -------------------------------------------------------------------------------- /src/components/card/CardImg.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 65 | -------------------------------------------------------------------------------- /src/utils/target.js: -------------------------------------------------------------------------------- 1 | const allListenTypes = { 2 | hover: true, 3 | click: true, 4 | focus: true 5 | } 6 | 7 | const BEL_KEY = '__DR_BOUND_EVENT_LISTENERS__' 8 | 9 | const bindTargets = (vnode, binding, listenTypes, callback) => { 10 | const targets = Object.keys(binding.modifiers || {}).filter(t => !allListenTypes[t]) 11 | 12 | if (binding.value) { 13 | targets.push(binding.value) 14 | } 15 | 16 | const listener = () => { 17 | callback({ targets, vnode }) 18 | } 19 | 20 | Object.keys(allListenTypes).forEach(type => { 21 | if (listenTypes[type] || binding.modifiers[type]) { 22 | vnode.elm.addEventListener(type, listener) 23 | const boundListeners = vnode.elm[BEL_KEY] || {} 24 | boundListeners[type] = boundListeners[type] || [] 25 | boundListeners[type].push(listener) 26 | vnode.elm[BEL_KEY] = boundListeners 27 | } 28 | }) 29 | 30 | return targets 31 | } 32 | 33 | const unbindTargets = (vnode, binding, listenTypes) => { 34 | Object.keys(allListenTypes).forEach(type => { 35 | if (listenTypes[type] || binding.modifiers[type]) { 36 | const boundListeners = vnode.elm[BEL_KEY] && vnode.elm[BEL_KEY][type] 37 | if (boundListeners) { 38 | boundListeners.forEach(listener => vnode.elm.removeEventListener(type, listener)) 39 | delete vnode.elm[BEL_KEY][type] 40 | } 41 | } 42 | }) 43 | } 44 | 45 | export { 46 | bindTargets, 47 | unbindTargets 48 | } 49 | 50 | export default bindTargets 51 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import Alert from './alert' 2 | import Badge from './badge' 3 | import Breadcrumb from './breadcrumb' 4 | import Button from './button' 5 | import ButtonGroup from './button-group' 6 | import ButtonToolbar from './button-toolbar' 7 | import Card from './card' 8 | import Collapse from './collapse' 9 | import Layout from './container' 10 | import Datepicker from './datepicker' 11 | import Dropdown from './dropdown' 12 | import Embed from './embed' 13 | import Form from './form' 14 | import FormCheckbox from './form-checkbox' 15 | import FormInput from './form-input' 16 | import FormRadio from './form-radio' 17 | import FormSelect from './form-select' 18 | import FormTextarea from './form-textarea' 19 | import Image from './image' 20 | import InputGroup from './input-group' 21 | import Link from './link' 22 | import ListGroup from './list-group' 23 | import Modal from './modal' 24 | import Nav from './nav' 25 | import Navbar from './navbar' 26 | import Popover from './popover' 27 | import Progress from './progress' 28 | import Slider from './slider' 29 | import Tabs from './tabs' 30 | import Tooltip from './tooltip' 31 | 32 | export { 33 | Alert, 34 | Badge, 35 | Breadcrumb, 36 | Button, 37 | ButtonGroup, 38 | ButtonToolbar, 39 | Card, 40 | Collapse, 41 | Layout, 42 | Datepicker, 43 | Dropdown, 44 | Embed, 45 | Form, 46 | FormCheckbox, 47 | FormInput, 48 | FormRadio, 49 | FormSelect, 50 | FormTextarea, 51 | Image, 52 | InputGroup, 53 | Link, 54 | ListGroup, 55 | Modal, 56 | Nav, 57 | Navbar, 58 | Popover, 59 | Progress, 60 | Slider, 61 | Tabs, 62 | Tooltip, 63 | } 64 | -------------------------------------------------------------------------------- /src/components/navbar/Navbar.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 64 | -------------------------------------------------------------------------------- /src/components/badge/Badge.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 63 | -------------------------------------------------------------------------------- /src/components/navbar/README.md: -------------------------------------------------------------------------------- 1 | # Navbars 2 | 3 | Using the `` component you can create powerful and responsive navigation headers. 4 | 5 | ## Basic Example 6 | 7 | :::demo 8 | ```html 9 | 10 | 11 | 12 | 13 |
Shards Vue
14 |
15 | 16 | 17 | 18 | Link 19 | Disabled 20 | 21 | Action 22 | Another action 23 | Something else here 24 | 25 | Separated link 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 | 42 | ``` 43 | ::: 44 | 45 | ## Themes and Text Colors 46 | 47 | The `` component supports all available color themes as well as text color types such as `dark` or `light`. 48 | 49 | ## Placement 50 | 51 | You an control the placement of the navbar component using the `fixed` and `sticky` props. 52 | -------------------------------------------------------------------------------- /src/components/form-radio/README.md: -------------------------------------------------------------------------------- 1 | # Form Radio 2 | 3 | The `` component is a wrapper over Bootstrap's [custom radio component](https://getbootstrap.com/docs/4.1/components/forms/#checkboxes-and-radios-1). 4 | 5 | ## Alias 6 | 7 | The `` component is also available as ``. 8 | 9 | ## Basic Demo 10 | 11 | :::demo 12 | ```html 13 | 22 | 23 | 32 | 33 | 34 | ``` 35 | ::: 36 | 37 | ## Inline Display 38 | 39 | Radios can also be displayed inline using the `inline` prop. 40 | 41 | :::demo 42 | ```html 43 | 44 |
45 | 46 | Basketball 47 | Football 48 | Tennis 49 |
50 | 51 | 52 | ``` 53 | ::: 54 | 55 | ## Missing Features 56 | 57 | The following radio features are currently not supported, but available on the [roadmap](/roadmap). 58 | 59 | * Possibility of creating plain radios. 60 | * Radio groups. 61 | * Button style radios. 62 | -------------------------------------------------------------------------------- /src/directives/toggle/toggle.js: -------------------------------------------------------------------------------- 1 | import target from '../../utils/target' 2 | import { COLLAPSE_EVENTS } from '../../utils/constants' 3 | import { setAttr, addClass, removeClass } from '../../utils' 4 | 5 | const inBrowser = typeof window !== 'undefined' 6 | const DR_TOGGLE = '__DRTOGGLE' 7 | 8 | export default { 9 | bind(element, binding, vnode) { 10 | const targets = target(vnode, binding, { click: true }, ({ targets, vnode }) => { 11 | targets.forEach(target => vnode.context.$root.$emit(COLLAPSE_EVENTS.TOGGLE, target)); 12 | }); 13 | 14 | if (inBrowser && vnode.context && targets.length > 0) { 15 | setAttr(element, 'aria-controls', targets.join(' ')) 16 | setAttr(element, 'aria-expanded', 'false') 17 | 18 | if (element.tagName !== 'BUTTON') { 19 | setAttr(element, 'role', 'button') 20 | } 21 | 22 | element[DR_TOGGLE] = function toggleDirectiveHandler(id, state) { 23 | if (targets.indexOf(id) !== -1) { 24 | setAttr(element, 'aria-expanded', state ? 'true' : 'false'); 25 | 26 | if (state) { 27 | removeClass(element, 'collapsed'); 28 | return; 29 | } 30 | 31 | addClass(element, 'collapsed'); 32 | } 33 | } 34 | vnode.context.$root.$on(COLLAPSE_EVENTS.STATE, element[DR_TOGGLE]) 35 | } 36 | }, 37 | unbind(element, binding, vnode) { 38 | if (!element[DR_TOGGLE]) { 39 | return 40 | } 41 | 42 | vnode.context.$root.$off(COLLAPSE_EVENTS.STATE, element[DR_TOGGLE]) 43 | element[DR_TOGGLE] = null 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/components/button-group/ButtonGroup.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 59 | 60 | 66 | 67 | -------------------------------------------------------------------------------- /src/components/container/Row.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 64 | 65 | -------------------------------------------------------------------------------- /src/components/button-group/README.md: -------------------------------------------------------------------------------- 1 | # Button Groups 2 | 3 | Button groups allow you to group buttons together on a single line. 4 | 5 | ## Basic Example 6 | 7 | You can create button groups using the `` component. 8 | 9 | :::demo Default button group 10 | ```html 11 | 12 | Left 13 | Middle 14 | Right 15 | 16 | 17 | 18 | ``` 19 | ::: 20 | 21 | 22 | ## Button Group Size 23 | 24 | The button group's size can be controlled via the `size` prop. The button group can be normal (default with no value), `small` or `large`. 25 | 26 | :::demo 27 | ```html 28 | 29 |
30 | 31 | 32 | Large 33 | Large 34 | 35 | 36 | 37 | 38 | Normal 39 | Normal 40 | 41 | 42 | 43 | 44 | Small 45 | Small 46 | 47 |
48 | 49 | 50 | ``` 51 | ::: 52 | 53 | 54 | ## Vertical Button Group 55 | 56 | You can stack button groups vertically using the `vertical` prop. 57 | 58 | :::demo 59 | ```html 60 | 61 | Button 1 62 | Button 2 63 | 64 | 65 | 66 | ``` 67 | ::: 68 | 69 | 70 | ## Alias 71 | 72 | The `` component is also aliased as ``. 73 | -------------------------------------------------------------------------------- /src/utils/tooltip.class.js: -------------------------------------------------------------------------------- 1 | 2 | import TPManager from './tpmanager.class' 3 | import { TP_STATE_CLASSES, TOOLTIP_SELECTORS } from './constants' 4 | import { removeClasses, selectElement } from './index' 5 | 6 | const TooltipDefaults = { 7 | template: '', 8 | } 9 | 10 | const Defaults = { ...TPManager.Defaults, ...TooltipDefaults } 11 | 12 | export default class Tooltip extends TPManager { 13 | 14 | static get Name() { 15 | return 'tooltip' 16 | } 17 | 18 | static get Defaults() { 19 | return Defaults 20 | } 21 | 22 | static get ClassPrefix() { 23 | return 'bs-tooltip' 24 | } 25 | 26 | /*-------------------------------------------------------------------------- 27 | /* OVERRIDES 28 | /*--------------------------------------------------------------------------*/ 29 | 30 | /** 31 | * Checks whether the Tooltip has any content. 32 | */ 33 | hasContent(TPElement) { 34 | const Tooltip = TPElement || this._TPElement 35 | 36 | if (!Tooltip) { 37 | return false 38 | } 39 | 40 | const tooltipInnerEl = selectElement(TOOLTIP_SELECTORS.TOOLTIP_INNER, Tooltip) 41 | 42 | return Boolean((tooltipInnerEl || {}).innerHTML) 43 | } 44 | 45 | /** 46 | * Sets the Tooltip content. 47 | */ 48 | setContent(TPElement) { 49 | const Tooltip = TPElement || this._TPElement 50 | 51 | if (!Tooltip) { 52 | return false 53 | } 54 | 55 | const tooltipInnerEl = selectElement(TOOLTIP_SELECTORS.TOOLTIP_INNER, Tooltip) 56 | this.setElementContent(tooltipInnerEl, this.getTitle()) 57 | 58 | removeClasses(Tooltip, [TP_STATE_CLASSES.FADE, TP_STATE_CLASSES.SHOW]) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/components/tooltip/README.md: -------------------------------------------------------------------------------- 1 | # Tooltips 2 | 3 | Tooltips are powerful components powered behind the scenes by Popper.js that can be attached to any element. 4 | 5 | > Note: The `container` prop is not always necessary and it is required in the following examples just for demo purposes. 6 | 7 | 8 | ## Directive 9 | 10 | You can also create tooltips using the [tooltip directive](/docs/directives/tooltip). 11 | 12 | 13 | ## Basic Example 14 | 15 | :::demo 16 | ```html 17 | 18 |
19 | 20 | 22 | 😃 Wooo! I am a tooltip! 23 | 24 |
25 | 26 | 27 | ``` 28 | ::: 29 | 30 | 31 | ## Placement 32 | 33 | The tooltip's position can be changed via the `placement` prop. The following placement options are available: `top`, `topleft`, `topright`, `right`, `righttop`, `rightbottom`, `bottom`, `bottomleft`, `bottomright`, `left`, `lefttop`, and `leftbottom`. 34 | 35 | :::demo 36 | ```html 37 | 38 |
39 | 40 | 43 | 👈 Wooo! I am on the left! 44 | 45 |
46 | 47 | 48 | ``` 49 | ::: 50 | 51 | 52 | ## Triggers 53 | 54 | Using the `triggers` prop you can control on which events the tooltip should be displayed. 55 | 56 | :::demo 57 | ```html 58 | 59 |
60 | Click Me 61 | 64 | 🖱 You just clicked me! 65 | 66 |
67 | 68 | 69 | ``` 70 | ::: 71 | -------------------------------------------------------------------------------- /src/utils/observer.js: -------------------------------------------------------------------------------- 1 | import { isElement } from './' 2 | 3 | /** 4 | * Observes DOM changes. 5 | * @see http://stackoverflow.com/questions/3219758 6 | */ 7 | export default (el, callback, opts = null) => { 8 | 9 | if (opts === null) { 10 | opts = { 11 | subtree: true, 12 | childList: true, 13 | characterData: true, 14 | attributes: true, 15 | attributeFilter: ['class', 'style'] 16 | } 17 | } 18 | 19 | const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver 20 | const eventListenerSupported = window.addEventListener 21 | 22 | el = el ? (el.$el || el) : null 23 | if (!isElement(el)) { 24 | return null 25 | } 26 | 27 | let obs = null 28 | 29 | if (MutationObserver) { 30 | obs = new MutationObserver(mutations => { 31 | let changed = false 32 | for (let i = 0; i < mutations.length && !changed; i++) { 33 | const mutation = mutations[i] 34 | const type = mutation.type 35 | const target = mutation.target 36 | if (type === 'characterData' && target.nodeType === Node.TEXT_NODE) { 37 | changed = true 38 | } else if (type === 'attributes') { 39 | changed = true 40 | } else if (type === 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)) { 41 | changed = true 42 | } 43 | } 44 | if (changed) { 45 | callback() 46 | } 47 | }) 48 | 49 | obs.observe(el, { ...{ childList: true, subtree: true }, ...opts }) 50 | } else if (eventListenerSupported) { 51 | el.addEventListener('DOMNodeInserted', callback, false) 52 | el.addEventListener('DOMNodeRemoved', callback, false) 53 | } 54 | 55 | return obs 56 | } 57 | -------------------------------------------------------------------------------- /src/components/nav/README.md: -------------------------------------------------------------------------------- 1 | # Navs 2 | 3 | The `` component allows you to build all types of navigation components. 4 | 5 | ## Basic Demo 6 | 7 | Creating navs can be easily achieved using the `` component together with the `` component. 8 | 9 | :::demo 10 | ```html 11 | 12 | 13 | Active 14 | Link 15 | Another Link 16 | Disabled 17 | 18 | 19 | 20 | ``` 21 | ::: 22 | 23 | ## Tabs Style 24 | 25 | Using the `tabs` prop, you can style the navs to look like tabs. 26 | 27 | :::demo 28 | ```html 29 | 30 | 31 | Active 32 | Link 33 | Another Link 34 | Disabled 35 | 36 | 37 | 38 | ``` 39 | ::: 40 | 41 | ## Pill Style 42 | 43 | Using the `pills` prop you can style the navs to look like pills. 44 | 45 | :::demo 46 | ```html 47 | 48 | 49 | Active 50 | Link 51 | Another Link 52 | Disabled 53 | 54 | 55 | 56 | ``` 57 | ::: 58 | 59 | ## Fill 60 | 61 | Using the `fill` prop, you can force the nav content to extend the full available width. 62 | 63 | :::demo 64 | ```html 65 | 66 | 67 | Active 68 | Link 69 | Another Link 70 | Disabled 71 | 72 | 73 | 74 | ``` 75 | ::: 76 | 77 | ## Justified 78 | 79 | Using the `justified` prop, you can define equal-width nav elements. 80 | 81 | :::demo 82 | ```html 83 | 84 | 85 | Active 86 | Link 87 | Another Link 88 | Disabled 89 | 90 | 91 | 92 | ``` 93 | ::: 94 | 95 | -------------------------------------------------------------------------------- /src/components/form-textarea/README.md: -------------------------------------------------------------------------------- 1 | # Form Textarea 2 | 3 | The `` component allows you to create multi-line text inputs that adjusts its height (text rows) automatically to fit the content. You can also limit the number of rows displayed using the `max-rows` prop. If you'd like to force the textarea element to a fixed height, you can use both `rows` and `max-rows` props simultaneously. 4 | 5 | ## Alias 6 | 7 | The `` component is also available as ``. 8 | 9 | ## Basic Example 10 | 11 | :::demo 12 | ```html 13 | 23 | 24 | 33 | 34 | 35 | ``` 36 | ::: 37 | 38 | ## Validation 39 | 40 | Using the `state` prop on the `` component you can control the textarea's validation state. 41 | 42 | The following textarea states are available: 43 | 44 | * `invalid` when the textarea is invalid. 45 | * `valid` when the use textarea is valid. 46 | * `null` when the textarea should display no validation state (neutral). 47 | 48 | :::demo 49 | ```html 50 | 61 | 62 | 71 | 72 | 73 | ``` 74 | ::: 75 | -------------------------------------------------------------------------------- /src/components/modal/README.md: -------------------------------------------------------------------------------- 1 | # Modals 2 | 3 | Creating flexible modal dialogs can be achieved using the `` component. They feature a series of helpful subcomponents, sizes and various other options that you can use to customize the display and behavior of your modals. 4 | 5 | ## Basic Example 6 | 7 | :::demo 8 | ```html 9 | 19 | 20 | 37 | 38 | 39 | ``` 40 | ::: 41 | 42 | ## Modal Size 43 | 44 | Using the `size` prop on the `` component, you can control the size of your modal. 45 | 46 | :::demo 47 | ```html 48 | 60 | 61 | 71 | 72 | 73 | ``` 74 | ::: 75 | -------------------------------------------------------------------------------- /src/components/popover/README.md: -------------------------------------------------------------------------------- 1 | # Popovers 2 | 3 | Popovers are powerful elements similar to tooltips and powered by Popper.js that can be applies to any interactive element. 4 | 5 | > Note: The `container` prop is not always necessary and it is required in the following examples just for demo purposes. 6 | 7 | ## Basic Example 8 | 9 | Popovers can be created using the `` component. 10 | 11 | :::demo 12 | ```html 13 | 14 |
15 | Click Me 16 | 17 | 20 | Content Here 21 | 22 |
23 | 24 | 25 | ``` 26 | ::: 27 | 28 | ## Triggers 29 | 30 | The `` component, by default is triggered by the `click` event. However, this can be easily adjusted using the `triggers` component which accepts one or multiple triggers. 31 | 32 | :::demo 33 | ```html 34 | 35 |
36 | Hover Me 37 | 40 | 43 | Content Here 44 | 45 |
46 | 47 | 48 | ``` 49 | ::: 50 | 51 | 52 | ## Placement 53 | 54 | Using the `placement` prop you can adjust where your popover will be displayed. So far, the following positions are available: `top`, `topleft`, `topright`, `right`, `righttop`, `rightbottom`, `bottom`, `bottomleft`, `bottomright`, `left`, `lefttop`, and `leftbottom`. 55 | 56 | :::demo 57 | ```html 58 | 59 |
60 | Click Me 61 | 64 | 67 | Content Here 68 | 69 |
70 | 71 | 72 | ``` 73 | ::: 74 | -------------------------------------------------------------------------------- /src/components/progress/Progress.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 87 | 88 | 94 | -------------------------------------------------------------------------------- /src/components/progress/README.md: -------------------------------------------------------------------------------- 1 | # Progres Bars 2 | 3 | You can use the `` component to display simple or complex progress bars. 4 | 5 | ## Basic Example 6 | 7 | :::demo 8 | ```html 9 | 10 | 11 | 12 | 13 | ``` 14 | ::: 15 | 16 | ## Labels 17 | 18 | You can add labels to your progress bars either by using the `show-progress` or `show-value` props. 19 | 20 | :::demo 21 | ```html 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | ``` 33 | ::: 34 | 35 | ## Size 36 | 37 | The size of the progress bar can be controlled via the `size` prop. Progress bars can be either `sm` for small or `lg` for large. Using a small progress bar would hide the label due to the lack of space. 38 | 39 | :::demo 40 | ```html 41 | 42 |
43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | ``` 52 | ::: 53 | 54 | ## Precision 55 | 56 | Using the `precision` prop you can specify the precision number of digits. 57 | 58 | :::demo 59 | ```html 60 | 61 | 62 | 63 | 64 | ``` 65 | ::: 66 | 67 | ## Multiple Progress Bars 68 | 69 | Inside the `` component you can also stack multiple `` components. 70 | 71 | :::demo 72 | ```html 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | ``` 82 | 83 | ## Height 84 | 85 | Using the `height` prop you can control the progress bar's height. 86 | 87 | :::demo 88 | ```html 89 | 90 |
91 | 92 | 93 |
94 | 95 | ``` 96 | -------------------------------------------------------------------------------- /src/markdown/getting-started/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | Shards Vue is really easy to get started with. Make sure to follow the guide below to get a better understanding about some of the decisions behind Shards Vue and how to use it to kick-start your next project. 4 | 5 | > **Note:** This page is currently a work in progress. 6 | 7 | ## Installation 8 | 9 | If you are using a module bundler such as [Webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/), you can install **Shards Vue** via [Yarn](https://yarnpkg.com/en/) or [NPM](https://www.npmjs.com/) and import Shards Vue directly into your project. 10 | 11 | ```bash 12 | // Install via Yarn 13 | yarn add shards-vue 14 | 15 | // Install via NPM 16 | npm i shards-vue 17 | ``` 18 | 19 | ## Module Bundlers 20 | 21 | You can register the entire UI kit as a Vue plugin in your app's entry point: 22 | 23 | ```javascript 24 | import Vue from 'vue' 25 | import ShardsVue from 'shards-vue' 26 | 27 | // Import base styles (Bootstrap and Shards) 28 | import 'bootstrap/dist/css/bootstrap.css' 29 | import 'shards-ui/dist/css/shards.css' 30 | 31 | Vue.use(ShardsVue); 32 | ``` 33 | 34 | ## Registering Components as Vue Plugins 35 | 36 | If you'd like to register only certain components as Vue plugins, make sure to import just the component you'd like to use. 37 | 38 | ```javascript 39 | import Vue from 'vue' 40 | 41 | // Import base styles (Bootstrap and Shards) 42 | import 'bootstrap/dist/css/bootstrap.css' 43 | import 'shards-ui/dist/css/shards.css' 44 | 45 | import { Button } from 'shards-vue/src/components' 46 | Vue.use(Button) 47 | 48 | ``` 49 | 50 | ## Importing Single File Components 51 | 52 | Importing single file components is also possible. 53 | 54 | ```vue 55 | 58 | 59 | 73 | ``` 74 | 75 | ## Naming Decisions 76 | 77 | You will notice that all components are prefixed with ``. The reason behind this decision is to provide a consistent naming experience across all existing and future products from DesignRevision. 78 | -------------------------------------------------------------------------------- /src/components/card/CardBody.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 93 | -------------------------------------------------------------------------------- /src/mixins/checkbox-radio.mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | data() { 3 | return { 4 | localChecked: this.checked, 5 | hasFocus: false 6 | } 7 | }, 8 | model: { 9 | prop: 'checked', 10 | event: 'input' 11 | }, 12 | props: { 13 | value: {}, 14 | checked: {}, 15 | buttonTheme: { 16 | type: String, 17 | default: null 18 | } 19 | }, 20 | computed: { 21 | computedLocalChecked: { 22 | get() { 23 | this.isChild ? this.$parent.localChecked : this.localChecked 24 | }, 25 | set (val) { 26 | if (this.isChild) { 27 | this.$parent.localChecked = val 28 | return 29 | } 30 | 31 | this.localChecked = val 32 | } 33 | }, 34 | isChild() { 35 | return Boolean(this.$parent && this.$parent.is_RadioCheckGroup) 36 | }, 37 | isDisabled() { 38 | return Boolean(this.isChild ? (this.$parent.disabled || this.disabled) : this.disabled) 39 | }, 40 | isPlain() { 41 | return Boolean(this.isChild ? this.$parent.plain : this.plain) 42 | }, 43 | getSize() { 44 | return this.isChild ? this.$parent.size : this.size 45 | }, 46 | getState() { 47 | if (this.isChild && typeof this.$parent.getState === 'boolean') { 48 | return this.$parent.getState 49 | } 50 | 51 | return this.computedState 52 | }, 53 | getStateClass() { 54 | return typeof this.getState === 'boolean' ? (this.getState ? 'is-valid' : 'is-invalid') : '' 55 | }, 56 | isStacked() { 57 | return Boolean(this.isChild && this.$parent.stacked) 58 | }, 59 | getButtonTheme() { 60 | return this.buttonTheme || (this.isChild ? this.$parent.buttonTheme : null) || 'secondary' 61 | }, 62 | buttonClasses() { 63 | return [ 64 | 'btn', 65 | `btn-${this.getButtonTheme}`, 66 | this.getSize ? `btn-${this.getSize}` : '', 67 | this.isDisabled ? 'disabled' : '', 68 | this.hasFocus ? 'focus' : '', 69 | this.isStacked ? 'mb-0' : '' 70 | ] 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/components/list-group/ListGroupItem.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 90 | 91 | -------------------------------------------------------------------------------- /src/components/alert/README.md: -------------------------------------------------------------------------------- 1 | # Alerts 2 | 3 | Alerts allow you to display contextual feedback for various user actions. 4 | 5 | ## Basic Alerts 6 | 7 | Alerts come in various contextual theme colors 8 | 9 | :::demo 10 | ```html Alerts contextual theme colors example 11 | 12 |
13 | Alert - Primary Theme (default) - Example Link 14 | Alert - Secondary Theme - Example Link 15 | Alert - Success Theme - Example Link 16 | Alert - Danger Theme - Example Link 17 | Alert - Warning Theme - Example Link 18 | Alert - Info Theme - Example Link 19 | Alert - Light Theme - Example Link 20 | Alert - Dark Theme - Example Link 21 |
22 | 23 | 24 | ``` 25 | ::: 26 | 27 | ## Dismissible Alerts 28 | 29 | Dismissible alerts provide the option to hide the alert with a close X button. 30 | 31 | :::demo Dismissible alert example 32 | ```html 33 | 34 |
35 | You can easily dismiss me using the close button → 36 |
37 | 38 | 39 | ``` 40 | ::: 41 | 42 | ## Self Dismissing Alerts 43 | 44 | You can also control how much time an alert is visible by providing a `Number` in seconds for the `show` prop. 45 | 46 | :::demo Auto dismissible alert example. 47 | ```html 48 | 49 | 63 | 64 | 82 | 83 | 84 | ``` 85 | ::: 86 | 87 | -------------------------------------------------------------------------------- /src/components/slider/README.md: -------------------------------------------------------------------------------- 1 | # Slider 2 | 3 | The slider component is powered behind the scenes by the [NoUiSlider](https://refreshless.com/nouislider/) library. 4 | 5 | ## Basic Slider 6 | 7 | You can create basic sliders using the `` component and a `v-model`. 8 | 9 | :::demo 10 | ```html 11 | 12 | 16 | 17 | 26 | 27 | 28 | ``` 29 | ::: 30 | 31 | ## Using Start Values 32 | 33 | Using the `start` prop you can also specify a start value for the knob. 34 | 35 | :::demo 36 | ```html 37 | 38 | 39 | 40 | 41 | ``` 42 | ::: 43 | 44 | ## Custom Range 45 | 46 | If the default `1-100` range is not enough, you can override it using the `range` prop. 47 | 48 | :::demo 49 | ```html 50 | 51 | 55 | 56 | 65 | 66 | ``` 67 | ::: 68 | 69 | ## Multiple Values 70 | 71 | If you'd like to control multiple values, you can use an `Array` for the `value` prop. 72 | 73 | :::demo 74 | ```html 75 | 76 | 80 | 81 | 90 | 91 | ``` 92 | ::: 93 | 94 | ## Using Pips 95 | 96 | Pips can also be enabled via the `options` prop. 97 | 98 | :::demo 99 | ```html 100 | 101 | 108 | 109 | 118 | 119 | ``` 120 | ::: 121 | -------------------------------------------------------------------------------- /src/components/card/README.md: -------------------------------------------------------------------------------- 1 | # Cards 2 | 3 | Cards provide a flexible content container that you can use to display a variety of content using contextual background colors, headers and footers. 4 | 5 | By default, cards fill in the full width of their parent element, however this can be customized via styling. 6 | 7 | ## Basic Example 8 | 9 | :::demo 10 | ```html 11 | 12 | 13 | Card header 14 | 15 | 16 |

Lorem ipsum dolor sit amet.

17 | Read more → 18 |
19 | Card footer 20 |
21 | 22 | 23 | ``` 24 | ::: 25 | 26 | ## Card Content Types 27 | 28 | Cards support a large variety of content including images, links, text, list groups and more. Make sure to check out the examples below. 29 | 30 | ### Card Body 31 | 32 | The core building block of a card is the ``. You can use it whenever you'd like to add a padded section within a card. 33 | 34 | :::demo 35 | ```html 36 | 37 | 38 | 39 | Nunc quis nisl ac justo elementum sagittis in quis justo. 40 | 41 | 42 | 43 | 44 | ``` 45 | ::: 46 | 47 | #### Card Body Title and Subtitle 48 | 49 | You can display a card's Title and Subtitle using the `title` and `subtitle` props on the `` component. 50 | 51 | :::demo 52 | ```html 53 | 54 | 55 | 56 | Nunc quis nisl ac justo elementum sagittis in quis justo. 57 | 58 | 59 | 60 | 61 | ``` 62 | ::: 63 | 64 | ### Card Image 65 | 66 | Using the `` component you can place a responsive image on top of the card that will adjust its width when the width of the card changes. 67 | 68 | :::demo 69 | ```html 70 | 71 |
72 | 73 | 74 | 75 | 76 | 77 | 78 |
this is the body contents
79 |
80 |
81 |
82 | 83 | 84 | 85 |
this is the body contents
86 |
87 | 88 |
89 |
90 |
91 |
92 |
93 | 94 | 95 | ``` 96 | ::: 97 | -------------------------------------------------------------------------------- /src/components/form/README.md: -------------------------------------------------------------------------------- 1 | # Forms 2 | 3 | The `` component is a form wrapper that supports inline form styles and provides validation states. 4 | 5 | ## Inline Forms 6 | 7 | You can create inline forms using the `inline` prop. 8 | 9 | :::demo 10 | ```html 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Register 19 | 20 | 21 | 22 | ``` 23 | ::: 24 | 25 | ## Form Validation 26 | 27 | The form component also provides validation states out of the box. 28 | 29 | :::demo 30 | ```html 31 | 60 | 61 | 81 | 82 | 83 | ``` 84 | ::: 85 | -------------------------------------------------------------------------------- /src/components/modal/Modal.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 84 | 85 | 122 | -------------------------------------------------------------------------------- /src/components/slider/Slider.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 104 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shards-vue", 3 | "version": "1.0.7", 4 | "license": "MIT", 5 | "description": "A free, beautiful and modern Vue.js UI kit based on the Shards UI kit.", 6 | "main": "dist/shards-vue.common.js", 7 | "web": "dist/shards-vue.umd.js", 8 | "module": "dist/shards-vue.esm.js", 9 | "jsnext:main": "dist/shards-vue.esm.js", 10 | "homepage": "https://designrevision.com/downloads/shards-vue", 11 | "contributors": [ 12 | { 13 | "name": "Catalin Vasile", 14 | "url": "https://github.com/hisk" 15 | } 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "git+git@github.com:DesignRevision/shards-vue.git" 20 | }, 21 | "scripts": { 22 | "build": "npm run clean && rollup --c build/rollup.config.js && npm run optimize && npm run bundlesize", 23 | "optimize": "node ./build/optimize.js", 24 | "watch": "vue serve sandbox/Sandbox.vue", 25 | "clean": "rimraf dist/*", 26 | "bundlesize": "bundlesize" 27 | }, 28 | "keywords": [ 29 | "Shards", 30 | "Shards UI Kit", 31 | "Bootstrap", 32 | "Bootstrap 4", 33 | "Bootstrap Vue", 34 | "Web", 35 | "Components", 36 | "Directives", 37 | "UI Kit", 38 | "Free", 39 | "Vue", 40 | "VueJS", 41 | "Vue2", 42 | "WebComponents", 43 | "jquery", 44 | "Popper.js", 45 | "vue-strap", 46 | "vue-datepicker", 47 | "CSS", 48 | "Flexbox", 49 | "Alert", 50 | "Breadcrumb", 51 | "Button", 52 | "Checkbox", 53 | "Radio", 54 | "Card", 55 | "Carousel", 56 | "Slider", 57 | "Collapse", 58 | "Dropdown", 59 | "Select", 60 | "Option", 61 | "Input", 62 | "Jumbotron", 63 | "List", 64 | "Nav", 65 | "Modal", 66 | "Navbar", 67 | "Pagination", 68 | "Popover", 69 | "Progress", 70 | "Tab", 71 | "Tag", 72 | "Tooltip" 73 | ], 74 | "bundlesize": [ 75 | { 76 | "path": "./dist/shards-vue.common.min.js" 77 | }, 78 | { 79 | "path": "./dist/shards-vue.esm.min.js" 80 | }, 81 | { 82 | "path": "./dist/shards-vue.umd.min.js" 83 | } 84 | ], 85 | "dependencies": { 86 | "bootstrap": "^4.1.3", 87 | "shards-ui": "^2.1.0", 88 | "lodash.xor": "^4.5.0", 89 | "nouislider": "^11.1.0", 90 | "popper.js": "^1.14.4", 91 | "vue-clickaway": "^2.2.2", 92 | "vuejs-datepicker": "^1.5.3" 93 | }, 94 | "devDependencies": { 95 | "bundlesize": "^0.17.0", 96 | "chalk": "^2.4.1", 97 | "glob": "^7.1.3", 98 | "node-sass": "^4.9.3", 99 | "rimraf": "^2.6.2", 100 | "rollup": "^0.63.4", 101 | "rollup-plugin-buble": "^0.19.2", 102 | "rollup-plugin-commonjs": "^9.1.6", 103 | "rollup-plugin-node-resolve": "^3.3.0", 104 | "rollup-plugin-uglify": "^4.0.0", 105 | "rollup-plugin-vue": "^4.3.1", 106 | "sass-loader": "^7.1.0", 107 | "uglify-es": "^3.3.9", 108 | "uglify-js": "^3.4.8", 109 | "vue-template-compiler": "^2.5.21" 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/components/button/Button.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 108 | -------------------------------------------------------------------------------- /src/utils/popover.class.js: -------------------------------------------------------------------------------- 1 | import TPManager from './tpmanager.class' 2 | import { selectElement, removeClasses } from './index' 3 | import { POPOVER_SELECTORS, TP_STATE_CLASSES } from './constants' 4 | 5 | const PopoverDefaults = { 6 | trigger: 'click', 7 | content: '', 8 | template: '' 9 | } 10 | 11 | const Defaults = { ...TPManager.Defaults, ...PopoverDefaults } 12 | 13 | export default class Popover extends TPManager { 14 | 15 | static get Name () { 16 | return 'popover' 17 | } 18 | 19 | static get Defaults () { 20 | return Defaults 21 | } 22 | 23 | static get ClassPrefix () { 24 | return 'bs-popover' 25 | } 26 | 27 | /*-------------------------------------------------------------------------- 28 | /* OVERRIDES 29 | /*--------------------------------------------------------------------------*/ 30 | 31 | /** 32 | * Checks if the Popover has content. 33 | * @returns True if the Popover has content (title or body), false otherwise. 34 | */ 35 | hasContent(TPElement) { 36 | const Popover = TPElement || this._TPElement 37 | 38 | if (!Popover) { 39 | return false 40 | } 41 | 42 | const popoverHeaderEl = selectElement(POPOVER_SELECTORS.HEADER, Popover) 43 | const popoverBodyEl = selectElement(POPOVER_SELECTORS.BODY, Popover) 44 | const hasHeader = Boolean((popoverHeaderEl || {}).innerHTML) 45 | const hasBody = Boolean((popoverBodyEl || {}).innerHTML) 46 | 47 | return hasHeader || hasBody 48 | } 49 | 50 | /** 51 | * Sets the content for the Popover element. 52 | */ 53 | setContent(TPElement) { 54 | const Popover = TPElement || this._TPElement 55 | 56 | const popoverHeaderEl = selectElement(POPOVER_SELECTORS.HEADER, Popover) 57 | const popoverBodyEl = selectElement(POPOVER_SELECTORS.BODY, Popover) 58 | 59 | this.setElementContent( popoverHeaderEl, this.getTitle()) 60 | this.setElementContent( popoverBodyEl, this.getContent()) 61 | 62 | removeClasses(Popover, [TP_STATE_CLASSES.FADE, TP_STATE_CLASSES.SHOW]) 63 | } 64 | 65 | /*-------------------------------------------------------------------------- 66 | /* CLASS SPECIFIC 67 | /*--------------------------------------------------------------------------*/ 68 | 69 | /** 70 | * Returns the Popover content. 71 | */ 72 | getContent() { 73 | let content = this._config.content || '' 74 | 75 | switch (content) { 76 | case 'string': 77 | content = content.trim() 78 | break 79 | case 'function': 80 | content = content(this._targetElement) 81 | break 82 | case 'object': 83 | if (content.nodeType && !content.innerHTML.trim()) { 84 | content = '' 85 | } 86 | break 87 | } 88 | 89 | return content 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/components/tooltip/Tooltip.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 116 | -------------------------------------------------------------------------------- /src/components/container/README.md: -------------------------------------------------------------------------------- 1 | # Layout & Grid System 2 | 3 | Shards Vue provides support for all native Bootstrap 4 layout elements including **containers**, **rows**, **columns** and **form rows** so you can use its full power while building your project's responsive layout powered by flexbox. 4 | 5 | :::demo 6 | ```html 7 | 8 | 9 | 1 / 12 10 | 2 / 12 11 | 3 / 12 12 | 4 / 12 13 | 5 / 12 14 | 6 / 12 15 | 7 / 12 16 | 8 / 12 17 | 9 / 12 18 | 10 / 12 19 | 11 / 12 20 | 12 / 12 21 | 22 | 23 | 24 | 1 / 6 25 | 2 / 6 26 | 3 / 6 27 | 4 / 6 28 | 5 / 6 29 | 6 / 6 30 | 31 | 32 | 33 | 1 / 3 34 | 2 / 3 35 | 3 / 3 36 | 37 | 38 | 39 | 1 / 2 40 | 2 / 2 41 | 42 | 43 | 44 | 1 / 1 45 | 46 | 47 | 48 | 49 | ``` 50 | ::: 51 | 52 | ## Containers 53 | 54 | Containers are the most **fundamental and required layout element** for your application or website's layout. You can use the `` component for a fixed container, or `` for a fluid container. 55 | 56 | ## Rows 57 | 58 | The `` component must be placed inside a `` component and it is used to define a row of columns. You can also use the `` component for building form layouts that help you create a layout with more compact margins. 59 | 60 | ## Columns 61 | 62 | The `` component is used to represent a column and must be placed inside a `` component. You can also use the `` component without a breakpoint-specific prop (`sm`, `md`, `lg`, `xl`) for easy column sizing that have an equal width (as seen in the examples above). 63 | 64 | ## Mixing Breakpoints 65 | 66 | You can use a combination of different props for each tier as needed. 67 | 68 | :::demo 69 | ```html 70 | 71 | 72 | cols="12" md="6" lg="8" 73 | cols="12" md="6" lg="8" 74 | 75 | 76 | 77 | cols="12" md="4" lg="3" 78 | cols="12" md="4" lg="6" 79 | cols="12" md="4" lg="3" 80 | 81 | 82 | 83 | cols="12" md="6" lg="4" 84 | cols="12" md="6" lg="8" 85 | 86 | 87 | 88 | 89 | ``` 90 | ::: 91 | 92 | -------------------------------------------------------------------------------- /src/components/form-input/README.md: -------------------------------------------------------------------------------- 1 | # Form Input 2 | 3 | The form input allows you to create various text style inputs such as `text`, `password`, `email`, `number`, `url`, `search` and more. 4 | 5 | ## Alias 6 | 7 | The `` component is also available as ``. 8 | 9 | ## Basic Input 10 | 11 | The `` component is a `text` input by default. However, you can set its type prop to one of the supported types as well: `text`, `password`, `email`, `number`, `url`, `tel`, `search`, `date`, `datetime`, `datetime-local`, `month`, `week`, `time`. 12 | 13 | :::demo 14 | ```html 15 | 16 | 23 | 24 | 31 | 32 | 33 | ``` 34 | ::: 35 | 36 | ## Supported Types 37 | 38 | The following input types are currently supported. 39 | 40 | :::demo 41 | ```html 42 | 43 | 51 | 52 | 61 | 62 | 63 | ``` 64 | ::: 65 | 66 | > Note: The `range` and `color` input types are currently not supported. 67 | 68 | ## Sizing 69 | 70 | Using the `size` prop, you can change the input size as small (`sm`) or large (`lg`). 71 | 72 | :::demo 73 | ```html 74 | 75 |
76 | 77 | 78 | 79 |
80 | 81 | 82 | ``` 83 | ::: 84 | 85 | ## Validation States 86 | 87 | Using the `state` prop on the `` component you can control the input's validation state. 88 | 89 | The following input states are available: 90 | 91 | * `invalid` when the input is invalid. 92 | * `valid` when the use input is valid. 93 | * `null` when the input should display no validation state (neutral). 94 | 95 | :::demo 96 | ```html 97 | 98 |
99 | 100 | 101 | 102 |
103 | 104 | 105 | ``` 106 | ::: 107 | 108 | ## Readonly & Plaintext 109 | 110 | You can also display the input as readonly or plain text using the `readonly` and `plaintext` props. 111 | -------------------------------------------------------------------------------- /src/components/image/Image.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 122 | 123 | -------------------------------------------------------------------------------- /src/components/popover/Popover.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 126 | 127 | -------------------------------------------------------------------------------- /src/components/tabs/_TabButton.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 117 | 118 | 131 | -------------------------------------------------------------------------------- /src/components/collapse/README.md: -------------------------------------------------------------------------------- 1 | # Collapse 2 | 3 | The `` component, together with the [`v-d-toggle`](/docs/directives/toggle) directive allow you to easily toggle the visibility of your content. 4 | 5 | ## Basic Example 6 | 7 | :::demo 8 | ```html 9 |
10 | Toggle Collapse 11 | 12 |
13 |
😍 Now you see me!
14 | In sagittis nibh non arcu viverra, nec imperdiet quam suscipit. Sed porta eleifend scelerisque. Vestibulum dapibus quis arcu a facilisis. 15 |
16 |
17 |
18 | 19 | 20 | ``` 21 | ::: 22 | 23 | ## Initial Visibility 24 | 25 | Using the `visible` prop, you can make the `` component show initially. 26 | 27 | :::demo 28 | ```html 29 |
30 | Toggle Collapse 31 | 32 |
33 |
😁 I'm already visible!
34 | In sagittis nibh non arcu viverra, nec imperdiet quam suscipit. Sed porta eleifend scelerisque. Vestibulum dapibus quis arcu a facilisis. 35 |
36 |
37 |
38 | 39 | 40 | ``` 41 | ::: 42 | 43 | ## Accordions 44 | 45 | The `accordion` prop you allows you to create dynamic and flexible accordions. 46 | 47 | :::demo 48 | ```html 49 |
50 | 51 | 52 | Accordion 1 53 | 54 | 55 | 56 |

Nullam augue tortor, viverra id gravida fermentum, posuere a libero. Curabitur at arcu tortor. Donec cursus blandit leo consequat convallis.

57 |
58 |
59 |
60 | 61 | 62 | 63 | Accordion 2 64 | 65 | 66 | 67 |

Etiam at congue tellus, vitae congue metus. Praesent eget arcu eget justo sodales venenatis. Nam nec est urna. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

68 |
69 |
70 |
71 | 72 | 73 | 74 | Accordion 3 75 | 76 | 77 | 78 |

Maecenas tempor dapibus eros, ut ultricies est dapibus eu. Pellentesque quis nisi suscipit, dignissim nunc nec, rhoncus dolor. Maecenas tempus egestas egestas.

79 |
80 |
81 |
82 |
83 | 84 | 85 | ``` 86 | ::: 87 | -------------------------------------------------------------------------------- /src/components/input-group/InputGroup.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 87 | 88 | 126 | -------------------------------------------------------------------------------- /src/components/tabs/Tab.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 118 | 119 | 133 | -------------------------------------------------------------------------------- /src/components/form-checkbox/README.md: -------------------------------------------------------------------------------- 1 | # Form Checkbox 2 | 3 | The `` component is a wrapper over Bootstrap's [custom checkbox component](https://getbootstrap.com/docs/4.1/components/forms/#checkboxes-and-radios-1). 4 | 5 | ## Alias 6 | 7 | The `` component is also available as ``. 8 | 9 | ## Basic Demo 10 | 11 | :::demo 12 | ```html 13 | 22 | 23 | 32 | 33 | 34 | ``` 35 | ::: 36 | 37 | ## Toggles 38 | 39 | Checkboxes can be turned into toggles by using the `toggle` prop. 40 | 41 | :::demo 42 | ```html 43 | 44 | 45 | 50 | 51 | 60 | 61 | 62 | ``` 63 | ::: 64 | 65 | 66 | ## Inline Display 67 | 68 | Checkboxes can also be displayed inline using the `inline` prop. 69 | 70 | :::demo 71 | ```html 72 |
73 | 74 | Basketball 75 | Football 76 | Tennis 77 |
78 | 79 | 80 | ``` 81 | ::: 82 | 83 | ## Values 84 | 85 | By default, the `` component's value will be `true` or `false` depending on its checked state. However, this can be easily adjusted using the `value` and `unchecked-value` props. 86 | 87 | ## Indeterminate State 88 | 89 | :::demo 90 | ```html 91 | 104 | 105 | 120 | 121 | 122 | ``` 123 | ::: 124 | 125 | ## Missing Features 126 | 127 | The following checkbox features are currently not supported, but available on the [roadmap](/roadmap). 128 | 129 | * Possibility of creating plain checkboxes. 130 | * Checkbox groups. 131 | * Button style checkboxes. 132 | -------------------------------------------------------------------------------- /src/components/badge/README.md: -------------------------------------------------------------------------------- 1 | # Badges 2 | 3 | Badges are the perfect component for labels and count values. 4 | 5 | ## Contextual Variations 6 | 7 | Using the `theme` prop you can easily change the appearance of your badge using the main theme colors: `primary, secondary, success, danger, warning, info, light` and `dark`. 8 | 9 | :::demo 10 | ```html 11 |
12 | Primary 13 | Secondary 14 | Success 15 | Danger 16 | Warning 17 | Info 18 | Light 19 | Dark 20 |
21 | 22 | 23 | ``` 24 | ::: 25 | 26 | ## Pill-Shaped Badges 27 | 28 | Using the `pill` prop appiles a larger border radius that make your badges to look rounded. 29 | 30 | :::demo 31 | ```html 32 |
33 | Primary 34 | Secondary 35 | Success 36 | Danger 37 | Warning 38 | Info 39 | Light 40 | Dark 41 |
42 | 43 | 44 | ``` 45 | ::: 46 | 47 | ## Outline Badges 48 | 49 | Using the `outline` prop removes the background color and applies a thin border that make your badges to look outlined. 50 | 51 | :::demo 52 | ```html 53 |
54 | Primary 55 | Secondary 56 | Success 57 | Danger 58 | Warning 59 | Info 60 | Light 61 | Dark 62 |
63 | 64 | 65 | ``` 66 | ::: 67 | 68 | ## Mixed Effects 69 | 70 | You can also mix both `pill` and `outline` props to get mixed results. 71 | 72 | :::demo 73 | ```html 74 |
75 | Primary 76 | Secondary 77 | Success 78 | Danger 79 | Warning 80 | Info 81 | Light 82 | Dark 83 |
84 | 85 | 86 | ``` 87 | ::: 88 | 89 | ## Link Badges 90 | 91 | Using the `href` or `to` prop you can turn your badges into regular or router links. 92 | 93 | :::demo 94 | ```html 95 |
96 | Primary 97 | Secondary 98 | Success 99 | Danger 100 | Warning 101 | Info 102 | Light 103 | Dark 104 |
105 | 106 | 107 | ``` 108 | ::: 109 | 110 | ## Inherited Props 111 | 112 | > **Note:** This component is also inheriting the [Link](/docs/components/link) component's props. 113 | -------------------------------------------------------------------------------- /src/components/tabs/README.md: -------------------------------------------------------------------------------- 1 | # Tabs 2 | 3 | Using the `` component you can easily create tabbable panes of content. 4 | 5 | :::demo 6 | ```html 7 | 8 | 9 | 10 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin efficitur eros tellus. Fusce mollis felis a lorem euismod sollicitudin. Maecenas et porttitor mauris.
11 |
12 | 13 |
Sed at lacus efficitur, imperdiet purus et, pretium arcu. Mauris vulputate, libero in dignissim auctor, nunc tortor interdum elit, ac dignissim ex enim vitae diam.
14 |
15 |
16 | 17 | 18 | ``` 19 | ::: 20 | 21 | 22 | ## Cards 23 | 24 | Wrapping the `` component inside a `` component you can also display the tabs as cards. 25 | 26 | :::demo 27 | ```html 28 | 29 | 30 | 31 | 32 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin efficitur eros tellus. Fusce mollis felis a lorem euismod sollicitudin. Maecenas et porttitor mauris. 33 | 34 | 35 | Sed at lacus efficitur, imperdiet purus et, pretium arcu. Mauris vulputate, libero in dignissim auctor, nunc tortor interdum elit, ac dignissim ex enim vitae diam. 36 | 37 | 38 | 39 | 40 | 41 | ``` 42 | ::: 43 | 44 | 45 | ## Pills 46 | 47 | Using the `pills` prop you can turn your tab controls into 'pill' buttons. 48 | 49 | :::demo 50 | ```html 51 | 52 | 53 | 54 | 55 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin efficitur eros tellus. Fusce mollis felis a lorem euismod sollicitudin. Maecenas et porttitor mauris. 56 | 57 | 58 | Sed at lacus efficitur, imperdiet purus et, pretium arcu. Mauris vulputate, libero in dignissim auctor, nunc tortor interdum elit, ac dignissim ex enim vitae diam. 59 | 60 | 61 | 62 | 63 | 64 | ``` 65 | ::: 66 | 67 | 68 | ## Vertical Tabs 69 | 70 | Placing the tab controls vertically can be easily achieved using the `vertical` prop. 71 | 72 | :::demo 73 | ```html 74 | 75 | 76 | 77 | 78 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin efficitur eros tellus. Fusce mollis felis a lorem euismod sollicitudin. Maecenas et porttitor mauris. 79 | 80 | 81 | Sed at lacus efficitur, imperdiet purus et, pretium arcu. Mauris vulputate, libero in dignissim auctor, nunc tortor interdum elit, ac dignissim ex enim vitae diam. 82 | 83 | 84 | 85 | 86 | 87 | ``` 88 | ::: 89 | 90 | 91 | ## Disabled Tab Controls 92 | 93 | You can set some of your tab controls as disabled, using the `disabled` prop 94 | 95 | :::demo 96 | ```html 97 | 98 | 99 | 100 | 101 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin efficitur eros tellus. Fusce mollis felis a lorem euismod sollicitudin. Maecenas et porttitor mauris. 102 | 103 | 104 | Sed at lacus efficitur, imperdiet purus et, pretium arcu. Mauris vulputate, libero in dignissim auctor, nunc tortor interdum elit, ac dignissim ex enim vitae diam. 105 | 106 | 107 | 108 | 109 | 110 | ``` 111 | ::: 112 | -------------------------------------------------------------------------------- /src/components/progress/ProgressBar.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 118 | 119 | 124 | -------------------------------------------------------------------------------- /src/utils/constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Various constants used across the project. 3 | */ 4 | 5 | // Theme Colors 6 | export const THEMECOLORS = [ 7 | 'primary', 8 | 'secondary', 9 | 'success', 10 | 'info', 11 | 'warning', 12 | 'danger', 13 | 'light', 14 | 'dark' 15 | ]; 16 | 17 | /** 18 | * EVENTS 19 | */ 20 | 21 | // Accordion 22 | export const COLLAPSE_EVENTS = { 23 | ACCORDION: 'collapse-accordion', 24 | TOGGLE: 'collapse-toggle', 25 | STATE: 'collapse-state' 26 | } 27 | 28 | // Modal events 29 | export const MODAL_EVENTS = { 30 | HIDDEN: 'modal-hidden' 31 | } 32 | 33 | // Alert Events 34 | export const ALERT_EVENTS = { 35 | DISMISS_COUNTDOWN: 'alert-dismiss-countdown', 36 | DISMISSED: 'alert-dismissed' 37 | } 38 | 39 | // Dropdown Events 40 | export const DROPDOWN_EVENTS = { 41 | SHOWN: 'dropdown-shown', 42 | SHOW: 'dropdown-show', 43 | HIDE: 'dropdown-hide', 44 | HIDDEN: 'dropdown-hidden' 45 | } 46 | 47 | // Link Events 48 | export const LINK_EVENTS = { 49 | CLICKED: 'link-clicked' 50 | } 51 | 52 | // All events 53 | export const EVENTS = { 54 | MODAL: MODAL_EVENTS, 55 | ALERT: ALERT_EVENTS, 56 | DROPDOWN: DROPDOWN_EVENTS, 57 | LINK: LINK_EVENTS 58 | } 59 | 60 | /** 61 | * TOOLTIP / POPOVER 62 | */ 63 | 64 | // Tooltip / Popover placements 65 | export const TP_PLACEMENTS = { 66 | TOP: 'top', 67 | TOPLEFT: 'topleft', 68 | TOPRIGHT: 'topright', 69 | RIGHT: 'right', 70 | RIGHTTOP: 'righttop', 71 | RIGHTBOTTOM: 'rightbottom', 72 | BOTTOM: 'bottom', 73 | BOTTOMLEFT: 'bottomleft', 74 | BOTTOMRIGHT: 'bottomright', 75 | LEFT: 'left', 76 | LEFTTOP: 'lefttop', 77 | LEFTBOTTOM: 'leftbottom', 78 | AUTO: 'auto' 79 | } 80 | 81 | // Normalized placements 82 | export const N_TP_PLACEMENTS = { 83 | AUTO: 'auto', 84 | TOP: 'top', 85 | RIGHT: 'right', 86 | BOTTOM: 'bottom', 87 | LEFT: 'left', 88 | TOPLEFT: 'top', 89 | TOPRIGHT: 'top', 90 | RIGHTTOP: 'right', 91 | RIGHTBOTTOM: 'right', 92 | BOTTOMLEFT: 'bottom', 93 | BOTTOMRIGHT: 'bottom', 94 | LEFTTOP: 'left', 95 | LEFTBOTTOM: 'left' 96 | } 97 | 98 | // Tooltip/Popover offset map 99 | export const TP_OFFSET_MAP = { 100 | AUTO: 0, 101 | TOPLEFT: -1, 102 | TOP: 0, 103 | TOPRIGHT: +1, 104 | RIGHTTOP: -1, 105 | RIGHT: 0, 106 | RIGHTBOTTOM: +1, 107 | BOTTOMLEFT: -1, 108 | BOTTOM: 0, 109 | BOTTOMRIGHT: +1, 110 | LEFTTOP: -1, 111 | LEFT: 0, 112 | LEFTBOTTOM: +1 113 | } 114 | 115 | // Popover state classes 116 | export const TP_STATE_CLASSES = { 117 | FADE: 'fade', 118 | SHOW: 'show' 119 | } 120 | 121 | // Popover selectors 122 | export const POPOVER_SELECTORS = { 123 | HEADER: '.popover-header', 124 | BODY: '.popover-body' 125 | } 126 | 127 | // Tooltip selectors 128 | export const TOOLTIP_SELECTORS = { 129 | TOOLTIP: '.tooltip', 130 | TOOLTIP_INNER: '.tooltip-inner', 131 | ARROW: '.arrow' 132 | } 133 | 134 | // Tooltip hover state classes 135 | export const TOOLTIP_HOVER_STATE_CLASSES = { 136 | SHOW: 'show', 137 | OUT: 'out' 138 | } 139 | 140 | /** 141 | * FORMS 142 | */ 143 | 144 | export const INPUT_TYPES = [ 145 | 'text', 146 | 'password', 147 | 'email', 148 | 'number', 149 | 'tel', 150 | 'url', 151 | 'search', 152 | 'range', 153 | 'color', 154 | 'date', 155 | 'time', 156 | 'datetime', 157 | 'datetime-local', 158 | 'month', 159 | 'week', 160 | 'file' 161 | ] 162 | 163 | /** 164 | * EMBEDS 165 | */ 166 | 167 | export const EMBED_TYPES = [ 168 | 'iframe', 169 | 'video', 170 | 'embed', 171 | 'object', 172 | 'img', 173 | 'd-img' 174 | ] 175 | 176 | export const EMBED_ASPECTS = [ 177 | '21by9', 178 | '16by9', 179 | '4by3', 180 | '1by1' 181 | ] 182 | 183 | // Keycodes 184 | export const KEYCODES = { 185 | UP: 38, 186 | DOWN: 40, 187 | LEFT: 37, 188 | RIGHT: 39, 189 | ENTER: 13, 190 | SPACE: 32 191 | } 192 | -------------------------------------------------------------------------------- /src/components/form-radio/FormRadio.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 156 | -------------------------------------------------------------------------------- /src/directives/tooltip/tooltip.js: -------------------------------------------------------------------------------- 1 | import Tooltip from '../../utils/tooltip.class' 2 | 3 | const inBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' 4 | const KEY = '_DR_TOOLTIP_' 5 | const validTriggers = { 6 | 'focus': true, 7 | 'hover': true, 8 | 'click': true, 9 | 'blur': true 10 | } 11 | 12 | /** 13 | * Bindings parser. 14 | */ 15 | function parseBindings(bindings) { 16 | let config = {} 17 | 18 | switch (typeof bindings.value) { 19 | case 'string': 20 | case 'function': 21 | config.title = bindings.value 22 | break 23 | case 'object': 24 | config = { ...bindings.value } 25 | } 26 | 27 | // Parse args (eg: v-d-tooltip:my-container) 28 | if (bindings.arg) { 29 | config.container = `#${bindings.arg}` // #my-container 30 | } 31 | 32 | // Parse modifiers. eg: v-d-tooltip.my-modifier 33 | Object.keys(bindings.modifiers).forEach(mod => { 34 | // Parse if the title allows HTML 35 | if (/^html$/.test(mod)) { 36 | config.html = true 37 | 38 | // Parse animation 39 | } else if (/^nofade$/.test(mod)) { 40 | config.animation = false 41 | 42 | // Parse placement 43 | } else if (/^(auto|top(left|right)?|bottom(left|right)?|left(top|bottom)?|right(top|bottom)?)$/.test(mod)) { 44 | config.placement = mod 45 | 46 | // Parse boundary 47 | } else if (/^(window|viewport)$/.test(mod)) { 48 | config.boundary = mod 49 | 50 | // Parse delay 51 | } else if (/^d\d+$/.test(mod)) { 52 | const delay = parseInt(mod.slice(1), 10) || 0 53 | if (delay) { 54 | config.delay = delay 55 | } 56 | 57 | // Parse offset 58 | } else if (/^o-?\d+$/.test(mod)) { 59 | const offset = parseInt(mod.slice(1), 10) || 0 60 | if (offset) { 61 | config.offset = offset 62 | } 63 | } 64 | }) 65 | 66 | // Parse selected triggers. 67 | const selectedTriggers = {} 68 | let triggers = typeof config.trigger === 'string' ? config.trigger.trim().split(/\s+/) : [] 69 | 70 | triggers.forEach(trigger => { 71 | if (validTriggers[trigger]) { 72 | selectedTriggers[trigger] = true 73 | } 74 | }) 75 | 76 | // Parse trigger modifiers. eg: v-d-tooltip.click 77 | Object.keys(validTriggers).forEach(trigger => { 78 | if (bindings.modifiers[trigger]) { 79 | selectedTriggers[trigger] = true 80 | } 81 | }) 82 | 83 | config.trigger = Object.keys(selectedTriggers).join(' ') 84 | 85 | // Convert `blur` to `focus` 86 | if (config.trigger === 'blur') { 87 | config.trigger = 'focus' 88 | } 89 | 90 | // If there's no trigger assigned, just delete the key. 91 | if (!config.trigger) { 92 | delete config.trigger 93 | } 94 | 95 | return config 96 | } 97 | 98 | function applyTooltip(el, bindings, vnode) { 99 | if (!inBrowser) { 100 | return 101 | } 102 | 103 | const parsedBindings = parseBindings(bindings) 104 | 105 | if (!el[KEY]) { 106 | el[KEY] = new Tooltip(el, parsedBindings, vnode.context.$root) 107 | return 108 | } 109 | 110 | el[KEY].updateConfig(parsedBindings) 111 | } 112 | 113 | export default { 114 | bind (el, bindings, vnode) { 115 | applyTooltip(el, bindings, vnode) 116 | }, 117 | 118 | inserted(el, bindings, vnode) { 119 | applyTooltip(el, bindings, vnode) 120 | }, 121 | 122 | update (el, bindings, vnode) { 123 | if (bindings.value !== bindings.oldValue) { 124 | applyTooltip(el, bindings, vnode) 125 | } 126 | }, 127 | 128 | componentUpdated (el, bindings, vnode) { 129 | if (bindings.value !== bindings.oldValue) { 130 | applyTooltip(el, bindings, vnode) 131 | } 132 | }, 133 | 134 | unbind (el) { 135 | if (!inBrowser) { 136 | return 137 | } 138 | 139 | if (el[KEY]) { 140 | el[KEY].destroy() 141 | el[KEY] = null 142 | delete el[KEY] 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/components/alert/Alert.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 150 | 151 | 157 | -------------------------------------------------------------------------------- /src/components/container/Col.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 125 | 126 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Update the README.md with details of changes to the interface, this includes new environment 13 | variables, exposed ports, useful file locations and container parameters. 14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 17 | do not have permission to do that, you may request the second reviewer to merge it for you. 18 | 19 | ## Code of Conduct 20 | 21 | ### Our Pledge 22 | 23 | In the interest of fostering an open and welcoming environment, we as 24 | contributors and maintainers pledge to making participation in our project and 25 | our community a harassment-free experience for everyone, regardless of age, body 26 | size, disability, ethnicity, gender identity and expression, level of experience, 27 | nationality, personal appearance, race, religion, or sexual identity and 28 | orientation. 29 | 30 | ### Our Standards 31 | 32 | Examples of behavior that contributes to creating a positive environment 33 | include: 34 | 35 | * Using welcoming and inclusive language 36 | * Being respectful of differing viewpoints and experiences 37 | * Gracefully accepting constructive criticism 38 | * Focusing on what is best for the community 39 | * Showing empathy towards other community members 40 | 41 | Examples of unacceptable behavior by participants include: 42 | 43 | * The use of sexualized language or imagery and unwelcome sexual attention or 44 | advances 45 | * Trolling, insulting/derogatory comments, and personal or political attacks 46 | * Public or private harassment 47 | * Publishing others' private information, such as a physical or electronic 48 | address, without explicit permission 49 | * Other conduct which could reasonably be considered inappropriate in a 50 | professional setting 51 | 52 | ### Our Responsibilities 53 | 54 | Project maintainers are responsible for clarifying the standards of acceptable 55 | behavior and are expected to take appropriate and fair corrective action in 56 | response to any instances of unacceptable behavior. 57 | 58 | Project maintainers have the right and responsibility to remove, edit, or 59 | reject comments, commits, code, wiki edits, issues, and other contributions 60 | that are not aligned to this Code of Conduct, or to ban temporarily or 61 | permanently any contributor for other behaviors that they deem inappropriate, 62 | threatening, offensive, or harmful. 63 | 64 | ### Scope 65 | 66 | This Code of Conduct applies both within project spaces and in public spaces 67 | when an individual is representing the project or its community. Examples of 68 | representing a project or community include using an official project e-mail 69 | address, posting via an official social media account, or acting as an appointed 70 | representative at an online or offline event. Representation of a project may be 71 | further defined and clarified by project maintainers. 72 | 73 | ### Enforcement 74 | 75 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 76 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All 77 | complaints will be reviewed and investigated and will result in a response that 78 | is deemed necessary and appropriate to the circumstances. The project team is 79 | obligated to maintain confidentiality with regard to the reporter of an incident. 80 | Further details of specific enforcement policies may be posted separately. 81 | 82 | Project maintainers who do not follow or enforce the Code of Conduct in good 83 | faith may face temporary or permanent repercussions as determined by other 84 | members of the project's leadership. 85 | 86 | ### Attribution 87 | 88 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 89 | available at [http://contributor-covenant.org/version/1/4][version] 90 | 91 | [homepage]: http://contributor-covenant.org 92 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /src/components/link/Link.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 158 | --------------------------------------------------------------------------------