UNPKG

@square/maker

Version:

📚 Maker Design System by Square

1 lines • 7.1 kB
{"version":3,"sources":["webpack://../components/Modal/src/Modal.vue","webpack://../components/Modal/src/ModalContent.vue","webpack://../components/Modal/src/ModalLayer.vue"],"names":[],"mappings":"AAwCA,mBACA,WAAA,CACA,eAAA,CACA,kBACA,CAEA,oCACA,mBACA,WAAA,CACA,gBAAA,CACA,6BACA,CACA,CC5CA,mBACA,YACA,CCgLA,mBACA,iBAAA,CACA,SACA,CAEA,mBAMA,YAAA,CACA,kBAAA,CACA,sBACA,CAEA,sCAVA,cAAA,CACA,KAAA,CACA,OAAA,CACA,QAAA,CACA,MAaA,CAPA,mBAMA,+BACA,CAEA,mBACA,4BACA,CAEA,mBACA,eACA,CAEA,mBACA,iBAAA,CACA,UAAA,CACA,WAAA,CACA,eACA,CAEA,oCACA,mBACA,oBAAA,CACA,UAAA,CACA,WAAA,CACA,iBAAA,CACA,sCACA,CACA","file":"styles.css","sourcesContent":["<template>\n\t<div :class=\"$s.Modal\">\n\t\t<!-- @slot Modal content -->\n\t\t<slot />\n\t</div>\n</template>\n\n<script>\nimport modalApi from './modal-api';\n\nexport default {\n\tname: 'Modal',\n\n\tinject: {\n\t\tmodalApi,\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * Before close hook, can block closing\n\t\t */\n\t\tbeforeClose: {\n\t\t\ttype: Function,\n\t\t\trequired: false,\n\t\t\tdefault: undefined,\n\t\t},\n\t},\n\n\twatch: {\n\t\tbeforeClose: {\n\t\t\timmediate: true,\n\t\t\thandler(hook) {\n\t\t\t\tthis.modalApi.state.options.beforeCloseHook = hook;\n\t\t\t},\n\t\t},\n\t},\n};\n</script>\n\n<style module=\"$s\">\n.Modal {\n\theight: 100%;\n\toverflow: scroll;\n\tbackground: #f5f6f7;\n}\n\n@media screen and (min-width: 840px) {\n\t.Modal {\n\t\twidth: 600px;\n\t\tmin-height: 180px;\n\t\tmax-height: calc(100vh - 64px);\n\t}\n}\n</style>\n","<template>\n\t<div :class=\"$s.ModalContent\">\n\t\t<!-- @slot Modal Content content (gets correct padding) -->\n\t\t<slot />\n\t</div>\n</template>\n\n<style module=\"$s\">\n.ModalContent {\n\tpadding: 24px;\n}\n</style>\n","<template>\n\t<div :class=\"$s.Layer\">\n\t\t<m-transition-fade-in>\n\t\t\t<div\n\t\t\t\tv-if=\"currentLayer.state.vnode\"\n\t\t\t\t:class=\"[\n\t\t\t\t\t$s.Translucent,\n\t\t\t\t\t{ [$s.Transparent]: currentLayer.state.isStacked },\n\t\t\t\t]\"\n\t\t\t/>\n\t\t</m-transition-fade-in>\n\t\t<m-transition-responsive :transitions=\"transitions\">\n\t\t\t<div\n\t\t\t\tv-if=\"currentLayer.state.vnode\"\n\t\t\t\tref=\"baseModalLayer\"\n\t\t\t\t:class=\"$s.ModalLayer\"\n\t\t\t\t@click.capture=\"closeOnClickOutside\"\n\t\t\t>\n\t\t\t\t<pseudo-window\n\t\t\t\t\tbody\n\t\t\t\t\t:class=\"$s.disableScroll\"\n\t\t\t\t/>\n\t\t\t\t<div\n\t\t\t\t\tref=\"modal\"\n\t\t\t\t\t:class=\"$s.Container\"\n\t\t\t\t>\n\t\t\t\t\t<v :nodes=\"currentLayer.state.vnode\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</m-transition-responsive>\n\t\t<modal-layer v-if=\"currentLayer.state.vnode\" />\n\t</div>\n</template>\n\n<script>\nimport Vue from 'vue';\nimport V from 'vue-v';\nimport PseudoWindow from 'vue-pseudo-window';\nimport { MTransitionFadeIn } from '@square/maker/components/TransitionFadeIn';\nimport { MTransitionResponsive } from '@square/maker/utils/TransitionResponsive';\nimport {\n\tfadeOutFn,\n\tspringUpFn,\n\tspringDownFn,\n\tspringDelay,\n\tfloatUpFn,\n\tfloatDownFn,\n\tdelayedFloatUpFn,\n\tdelayedFadeInFn,\n\tmobileMinWidth,\n\ttabletMinWidth,\n} from '@square/maker/utils/transitions';\nimport modalApi from './modal-api';\n\nconst apiMixin = {\n\tinject: {\n\t\tcurrentLayer: {\n\t\t\tdefault: undefined,\n\t\t\tfrom: modalApi,\n\t\t},\n\t},\n\n\tprovide() {\n\t\tconst vm = this;\n\t\tconst api = {\n\t\t\tstate: Vue.observable({\n\t\t\t\tvnode: undefined,\n\t\t\t\toptions: {},\n\t\t\t\tisStacked: !!vm.currentLayer,\n\t\t\t}),\n\n\t\t\topen(renderFn, options = {}) {\n\t\t\t\tconst vnode = renderFn(vm.$createElement);\n\t\t\t\tthis.state.vnode = vnode;\n\t\t\t\tthis.state.options = options;\n\t\t\t\t// returned method only closes this specific modal\n\t\t\t\treturn () => {\n\t\t\t\t\tif (this.state.vnode === vnode) {\n\t\t\t\t\t\tthis.state.vnode = undefined;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tasync close() {\n\t\t\t\tconst isModalActive = !this.state.vnode; // Verify there's no modal on top\n\n\t\t\t\tif (isModalActive && vm.currentLayer) {\n\t\t\t\t\tif (typeof this.state.options.beforeCloseHook === 'function') {\n\t\t\t\t\t\tif (!(await this.state.options.beforeCloseHook())) {\n\t\t\t\t\t\t\treturn; // cancel\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tvm.currentLayer.state.vnode = undefined; // close modal\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\n\t\tif (!this.modalApi) {\n\t\t\tthis.modalApi = api;\n\t\t}\n\n\t\treturn {\n\t\t\t[modalApi]: api,\n\t\t};\n\t},\n};\n\nexport default {\n\tname: 'ModalLayer',\n\n\tcomponents: {\n\t\tV,\n\t\tPseudoWindow,\n\t\tMTransitionFadeIn,\n\t\tMTransitionResponsive,\n\t},\n\n\tmixins: [\n\t\tapiMixin,\n\t],\n\n\tinheritAttrs: false,\n\n\tapiMixin,\n\n\tdata() {\n\t\tlet tabletEnterFn = floatUpFn;\n\t\tlet tabletLeaveFn = floatDownFn;\n\t\tif (this.currentLayer.state.isStacked) {\n\t\t\ttabletEnterFn = delayedFloatUpFn;\n\t\t\ttabletLeaveFn = floatDownFn;\n\t\t}\n\t\treturn {\n\t\t\ttransitions: [{\n\t\t\t\tminWidth: mobileMinWidth,\n\t\t\t\tenter: springUpFn,\n\t\t\t\tleave: springDownFn,\n\t\t\t}, {\n\t\t\t\tminWidth: tabletMinWidth,\n\t\t\t\tenter: tabletEnterFn,\n\t\t\t\tleave: tabletLeaveFn,\n\t\t\t}],\n\t\t};\n\t},\n\n\tmounted() {\n\t\tconst vm = this;\n\t\tthis.unwatchStackedModal = this.$watch(() => vm.modalApi.state.vnode, () => {\n\t\t\tconst isTablet = window.innerWidth >= tabletMinWidth;\n\t\t\tconst isMobile = !isTablet;\n\t\t\tconst isOpeningStackedModal = !!vm.modalApi.state.vnode;\n\t\t\tconst isClosingStackedModal = !isOpeningStackedModal;\n\t\t\tconst element = this.$refs.baseModalLayer;\n\n\t\t\tif (isTablet && isOpeningStackedModal) {\n\t\t\t\tfadeOutFn({ element });\n\t\t\t} else if (isTablet && isClosingStackedModal) {\n\t\t\t\tdelayedFadeInFn({ element });\n\t\t\t} else if (isMobile && isOpeningStackedModal) {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\telement.style.opacity = '0%';\n\t\t\t\t}, springDelay);\n\t\t\t} else if (isMobile && isClosingStackedModal) {\n\t\t\t\telement.style.removeProperty('opacity');\n\t\t\t}\n\t\t});\n\t},\n\n\tdestroyed() {\n\t\tthis.unwatchStackedModal();\n\t},\n\n\tmethods: {\n\t\tcloseOnClickOutside(event) {\n\t\t\tconst { closeOnClickOutside } = this.currentLayer.state.options;\n\t\t\tconst { modal } = this.$refs;\n\t\t\tif (modal && closeOnClickOutside && !modal.contains(event.target)) {\n\t\t\t\tthis.modalApi.close();\n\t\t\t}\n\t\t},\n\t},\n};\n</script>\n\n<style module=\"$s\">\n.Layer {\n\tposition: relative;\n\tz-index: 1;\n}\n\n.ModalLayer {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.Translucent {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tbackground-color: rgba(0, 0, 0, 0.3);\n}\n\n.Transparent {\n\tbackground-color: transparent;\n}\n\n.disableScroll {\n\toverflow: hidden;\n}\n\n.Container {\n\tposition: relative;\n\twidth: 100%;\n\theight: 100%;\n\toverflow: hidden;\n}\n\n@media screen and (min-width: 840px) {\n\t.Container {\n\t\tdisplay: inline-block;\n\t\twidth: auto;\n\t\theight: auto;\n\t\tborder-radius: 8px;\n\t\tbox-shadow: 0 0 24px 8px rgba(0, 0, 0, 0.3);\n\t}\n}\n</style>\n"]}