mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Added Modal to our Styleguide
This commit is contained in:
parent
c144e12229
commit
17a52fa8e5
22
store/modal.js
Normal file
22
store/modal.js
Normal file
@ -0,0 +1,22 @@
|
||||
export const state = () => {
|
||||
return {
|
||||
open: null,
|
||||
data: {}
|
||||
}
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
SET_OPEN(state, ctx) {
|
||||
state.open = ctx.name || null
|
||||
state.data = ctx.data || {}
|
||||
}
|
||||
}
|
||||
|
||||
export const getters = {
|
||||
open(state) {
|
||||
return state.open
|
||||
},
|
||||
data(state) {
|
||||
return state.data
|
||||
}
|
||||
}
|
||||
191
styleguide/src/system/components/layout/Modal/Modal.vue
Normal file
191
styleguide/src/system/components/layout/Modal/Modal.vue
Normal file
@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<portal to="modal">
|
||||
<div :key="key" class="ds-modal-wrapper">
|
||||
<transition name="ds-transition-fade" appear>
|
||||
<div
|
||||
v-if="isOpen"
|
||||
class="ds-modal-backdrop"
|
||||
ref="backdrop"
|
||||
@click="backdropHandler"
|
||||
>
|
||||
|
||||
</div>
|
||||
</transition>
|
||||
<transition name="ds-transition-modal-appear" appear>
|
||||
<div
|
||||
v-if="isOpen"
|
||||
class="ds-modal"
|
||||
tableindex="-1"
|
||||
role="dialog"
|
||||
ref="modal"
|
||||
style="display: block"
|
||||
>
|
||||
<div class="ds-modal-dialog">
|
||||
<div class="ds-modal-content">
|
||||
<div class="ds-modal-header">
|
||||
<ds-heading
|
||||
tag="h3"
|
||||
class="ds-modal-title"
|
||||
>
|
||||
{{ title }}
|
||||
</ds-heading>
|
||||
<ds-button
|
||||
v-if="allowAbort"
|
||||
class="ds-modal-close"
|
||||
ghost
|
||||
size="small"
|
||||
icon="close"
|
||||
aria-hidden="true"
|
||||
@click="cancel('close')"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ds-modal-body"
|
||||
ref="modalBody"
|
||||
>
|
||||
<!-- @slot Modal content -->
|
||||
<slot/>
|
||||
</div>
|
||||
<div class="ds-modal-footer">
|
||||
<!-- @slot Modal footer with action buttons -->
|
||||
<slot
|
||||
name="footer"
|
||||
:confirm="confirm"
|
||||
:cancel="cancel"
|
||||
:cancelLabel="cancelLabel"
|
||||
:confirmLabel="confirmLabel"
|
||||
>
|
||||
<ds-button ghost icon="close" @click.prevent="cancel('cancel')">{{ cancelLabel }}</ds-button>
|
||||
<ds-button primary icon="check" @click.prevent="confirm('confirm')">{{ confirmLabel }}</ds-button>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</portal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import portal from 'portal-vue'
|
||||
Vue.use(portal)
|
||||
|
||||
/* eslint-disable no-empty */
|
||||
|
||||
/**
|
||||
* Simple Modal Component
|
||||
* @version 1.0.0
|
||||
*/
|
||||
export default {
|
||||
name: 'DsModal',
|
||||
props: {
|
||||
/**
|
||||
* Modal title
|
||||
*/
|
||||
title: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* Open state
|
||||
*/
|
||||
isOpen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* Allow closing without choosing action by ESC key, close button or click on the backdrop
|
||||
*/
|
||||
allowAbort: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
/**
|
||||
* Cancel button label
|
||||
*/
|
||||
cancelLabel: {
|
||||
type: String,
|
||||
default: 'Cancel'
|
||||
},
|
||||
/**
|
||||
* Confirm button label
|
||||
*/
|
||||
confirmLabel: {
|
||||
type: String,
|
||||
default: 'Confirm'
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'isOpen',
|
||||
event: 'update:isOpen'
|
||||
},
|
||||
watch: {
|
||||
isOpen: {
|
||||
immediate: true,
|
||||
handler(show) {
|
||||
try {
|
||||
if (show) {
|
||||
this.$emit('opened')
|
||||
document
|
||||
.getElementsByTagName('body')[0]
|
||||
.classList
|
||||
.add('modal-open')
|
||||
} else {
|
||||
document
|
||||
.getElementsByTagName('body')[0]
|
||||
.classList
|
||||
.remove('modal-open')
|
||||
}
|
||||
} catch (err) {}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
confirm (type = 'confirm') {
|
||||
this.$emit('confirm')
|
||||
this.close(type)
|
||||
},
|
||||
cancel (type = 'cancel') {
|
||||
this.$emit('cancel')
|
||||
this.close(type)
|
||||
},
|
||||
close (type) {
|
||||
this.$emit('update:isOpen', false)
|
||||
this.$emit('close', type)
|
||||
},
|
||||
backdropHandler () {
|
||||
if (this.allowAbort) {
|
||||
this.cancel('backdrop')
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
// create random key string
|
||||
this.key = Math.random()
|
||||
.toString(36)
|
||||
.replace(/[^a-z]+/g, '')
|
||||
.substr(0, 5)
|
||||
},
|
||||
mounted() {
|
||||
const keydownListener = document.addEventListener('keydown', e => {
|
||||
if (this.isOpen && this.allowAbort && e.keyCode === 27) {
|
||||
this.cancel('backdrop')
|
||||
}
|
||||
})
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
document.removeEventListener('keydown', keydownListener)
|
||||
})
|
||||
|
||||
if (this.isOpen) {
|
||||
this.$emit('opened')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" src="./style.scss">
|
||||
</style>
|
||||
|
||||
<docs src="./demo.md"></docs>
|
||||
65
styleguide/src/system/components/layout/Modal/demo.md
Normal file
65
styleguide/src/system/components/layout/Modal/demo.md
Normal file
@ -0,0 +1,65 @@
|
||||
## Basic Modal
|
||||
|
||||
Basic modal usage
|
||||
|
||||
You will need to add the portal-target to the end of your html body to get the modal working properly
|
||||
```html
|
||||
<!-- put the following tag as last element to your html body / layout -->
|
||||
<!-- make sure you only include it once! -->
|
||||
<portal-target name="modal" style="position: absolute" />
|
||||
```
|
||||
|
||||
```
|
||||
<template>
|
||||
<div>
|
||||
<ds-modal
|
||||
v-model="isOpen"
|
||||
title="Modal Title"
|
||||
>
|
||||
<p>Hello World</p>
|
||||
</ds-modal>
|
||||
<ds-button primary icon="rocket" @click="isOpen = true">Open Modal</ds-button>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isOpen: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Customize button labels
|
||||
```
|
||||
<template>
|
||||
<div>
|
||||
<ds-modal
|
||||
v-if="isOpen"
|
||||
v-model="isOpen"
|
||||
title="Custom Button Labels"
|
||||
:allow-abort="false"
|
||||
confirm-label="All right"
|
||||
cancel-label="Please not"
|
||||
>
|
||||
<p>Culpa amet sunt aperiam ratione est sed. Molestiae minus doloremque libero. Beatae nam repellendus aliquid maxime.</p>
|
||||
<p>Sint quasi provident natus id earum debitis. Et facilis a iure ullam. Velit autem eveniet ea reprehenderit ducimus doloribus earum quo.</p>
|
||||
<p>Consequatur ratione repudiandae aliquid ea. Ut eum architecto assumenda. Autem eaque provident quia et.</p>
|
||||
<p>Eaque quia aut dolorum sunt ea consequuntur. Labore reprehenderit placeat pariatur molestiae sit laborum nostrum. Deserunt est commodi et suscipit tenetur ipsa voluptas cupiditate. Porro laborum quidem ut corrupti. Dolorum et est placeat qui.</p>
|
||||
<p>Adipisci beatae cumque esse harum. Error quis nulla illo nemo est. Enim est quis explicabo voluptatem. Omnis maxime qui similique consequatur voluptatibus. Est necessitatibus iure aliquid omnis eum. Ut voluptatibus vel error exercitationem temporibus qui expedita.</p>
|
||||
</ds-modal>
|
||||
<ds-button primary icon="rocket" @click="isOpen = true">Open Modal</ds-button>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isOpen: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
75
styleguide/src/system/components/layout/Modal/style.scss
Normal file
75
styleguide/src/system/components/layout/Modal/style.scss
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
.ds-modal-wrapper {
|
||||
padding: $space-base;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ds-modal {
|
||||
position: fixed;
|
||||
z-index: $z-index-modal;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 600px;
|
||||
width: calc(90vw - 40px);
|
||||
max-height: 90vh;
|
||||
background: white;
|
||||
border-radius: $border-radius-large;
|
||||
padding: 0 $space-base;
|
||||
box-shadow: $box-shadow-x-large;
|
||||
}
|
||||
.ds-modal-close {
|
||||
position: absolute;
|
||||
top: $space-small;
|
||||
right: $space-small;
|
||||
}
|
||||
.ds-modal-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
height: auto;
|
||||
min-height: 100px;
|
||||
max-height: 60vh;
|
||||
}
|
||||
.ds-modal-header {
|
||||
padding-top: $space-base;
|
||||
|
||||
.ds-modal-title {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.ds-modal-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: $z-index-modal - 1;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
.ds-modal-footer {
|
||||
display: flex;
|
||||
padding: $space-base 0;
|
||||
flex-shrink: 0;
|
||||
justify-content: flex-end;
|
||||
|
||||
& > button {
|
||||
margin-left: $space-x-small;
|
||||
}
|
||||
}
|
||||
|
||||
$easeOut: cubic-bezier(0.19, 1, 0.22, 1);
|
||||
|
||||
.ds-transition-modal-appear-enter-active {
|
||||
opacity: 1;
|
||||
transition: all 180ms $easeOut;
|
||||
transition-delay: 0;
|
||||
transform: translate3d(-50%, -50%, 0) scale(1);
|
||||
}
|
||||
.ds-transition-modal-appear-enter,
|
||||
.ds-transition-modal-appear-leave-active {
|
||||
opacity: 0;
|
||||
transition-delay: 0;
|
||||
transform: translate3d(-50%, -50%, 0) scale(0.9);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user