diff --git a/packages/documentation/Overview.vue b/packages/documentation/Overview.vue index 813fe64..9a332e0 100644 --- a/packages/documentation/Overview.vue +++ b/packages/documentation/Overview.vue @@ -110,7 +110,8 @@ import {SpinnerSize} from "../office-ui-fabric-vue/components/Spinner/OfficeSpin Test Layer! - + @@ -139,6 +140,56 @@ import {SpinnerSize} from "../office-ui-fabric-vue/components/Spinner/OfficeSpin + + + + This is the demo page for office-ui-fabric-vue @@ -149,10 +200,8 @@ import {SpinnerSize} from "../office-ui-fabric-vue/components/Spinner/OfficeSpin import {Component, Prop, Vue} from "vue-property-decorator"; import OfficeButton from "../office-ui-fabric-vue/components/Button/OfficeButton.vue"; import OfficeCheckbox from "../office-ui-fabric-vue/components/Checkbox/OfficeCheckbox.vue"; - import OfficeChoiceGroup from "../office-ui-fabric-vue/components/ChoiceGroup/OfficeChoiceGroup.vue"; import OfficeIcon from "../office-ui-fabric-vue/components/Icon/OfficeIcon.vue"; - import {ImageFit} from "../office-ui-fabric-vue/components/Image/OfficeImage.types"; import OfficeImage from "../office-ui-fabric-vue/components/Image/OfficeImage.vue"; import OfficeLabel from "../office-ui-fabric-vue/components/Label/OfficeLabel.vue"; @@ -169,8 +218,10 @@ import {SpinnerSize} from "../office-ui-fabric-vue/components/Spinner/OfficeSpin import OfficeToggle from "../office-ui-fabric-vue/components/Toggle/OfficeToggle.vue"; import FocusTrapZoneExample from "./FocusTrapZoneExample.vue"; import {ItemTypes} from "./ItemTypes"; - import OverviewItem, {IItemOptions} from "./OverviewItem.vue"; + import OfficeChoiceGroupOption + from "../office-ui-fabric-vue/components/ChoiceGroup/ChoiceGroupOption/OfficeChoiceGroupOption.vue"; + import OfficeModal from "../office-ui-fabric-vue/components/Modal/OfficeModal.vue"; @Component({ components: { @@ -180,6 +231,7 @@ import {SpinnerSize} from "../office-ui-fabric-vue/components/Spinner/OfficeSpin OfficeSlider, OfficeLink, OfficeToggle, + OfficeChoiceGroupOption, OfficeChoiceGroup, OfficeIcon, OfficeImage, @@ -191,6 +243,7 @@ import {SpinnerSize} from "../office-ui-fabric-vue/components/Spinner/OfficeSpin OfficeOverlay, OfficeLayerHost, OfficeProgressIndicator, + OfficeModal }, }) export default class Overview extends Vue { @@ -228,9 +281,19 @@ import {SpinnerSize} from "../office-ui-fabric-vue/components/Spinner/OfficeSpin window.alert("clicked!"); } + private modalActive = false; + + private openModal() { + this.modalActive = true; + } + + private closeModal() { + this.modalActive = false; + } + private mounted() { this.interval = window.setInterval(() => { - if(this.progressValue > 1) + if (this.progressValue > 1) return this.progressValue = 0; this.progressValue += 0.01; @@ -259,6 +322,16 @@ import {SpinnerSize} from "../office-ui-fabric-vue/components/Spinner/OfficeSpin }; } + get modalOptions(): IItemOptions { + return { + isDarkOverlay: {type: ItemTypes.BooleanToggle}, + isBlocking: {type: ItemTypes.BooleanToggle, value: true}, + topOffsetFixed: {type: ItemTypes.BooleanToggle}, + forceFocusInsideTrap: {type: ItemTypes.BooleanToggle, value: true}, + ignoreExternalFocusing: {type: ItemTypes.BooleanToggle}, + }; + } + get choiceGroupOptions(): IItemOptions { return { disabled: {type: ItemTypes.BooleanToggle}, diff --git a/packages/office-ui-fabric-vue/components/Modal/OfficeModal.style.ts b/packages/office-ui-fabric-vue/components/Modal/OfficeModal.style.ts new file mode 100644 index 0000000..e131c34 --- /dev/null +++ b/packages/office-ui-fabric-vue/components/Modal/OfficeModal.style.ts @@ -0,0 +1,103 @@ +/* +Taken from https://github.com/OfficeDev/office-ui-fabric-react and slightly modified + +License: + Office UI Fabric React + Copyright (c) Microsoft Corporation + All rights reserved. + MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + Note: Usage of the fonts and icons referenced in Office UI Fabric is subject to the terms listed at http://aka.ms/fabric-assets-license +*/ + +import {AnimationVariables} from "@styling/styles"; +import {getGlobalClassNames} from "@styling/styles/getGlobalClassNames"; +import {IOfficeModalStyleProps, IOfficeModalStyles} from "./OfficeModal.types"; + +export const animationDuration = AnimationVariables.durationValue2; + +const globalClassNames = { + root: "ms-Modal", + main: "ms-Dialog-main", + scrollableContent: "ms-Modal-scrollableContent", + isOpen: "is-open" +}; + +export const getStyles = (props: IOfficeModalStyleProps): IOfficeModalStyles => { + const { + topOffsetFixed, + hasBeenOpened, + isOpen, + isVisible, + modalRectangleTop, + scrollableContentClassName, + containerClassName, + className, + theme + } = props; + + const {palette} = theme; + + const classNames = getGlobalClassNames(globalClassNames, theme); + + + return { + root: [ + classNames.root, + theme.fonts.medium, + { + backgroundColor: "transparent", + position: "fixed", + height: "100%", + width: "100%", + display: "flex", + alignItems: "center", + justifyContent: "center", + opacity: 0, + pointerEvents: "none", + transition: `opacity ${animationDuration}` + }, + topOffsetFixed && + hasBeenOpened && { + alignItems: "flex-start" + }, + isOpen && classNames.isOpen, + isVisible && { + opacity: 1, + pointerEvents: "auto" + }, + className + ], + /** + * + */ + main: [ + classNames.main, + { + boxShadow: "0 0 5px 0 rgba(0, 0, 0, 0.4)", + backgroundColor: palette.white, + boxSizing: "border-box", + position: "relative", + textAlign: "left", + outline: "3px solid transparent", + maxHeight: "100%", + overflowY: "auto" + }, + topOffsetFixed && + hasBeenOpened && { + top: modalRectangleTop + }, + containerClassName + ], + scrollableContent: [ + classNames.scrollableContent, + { + overflowY: "auto", + flexGrow: 1 + }, + scrollableContentClassName + ] + }; +}; diff --git a/packages/office-ui-fabric-vue/components/Modal/OfficeModal.types.ts b/packages/office-ui-fabric-vue/components/Modal/OfficeModal.types.ts new file mode 100644 index 0000000..8bd2bd7 --- /dev/null +++ b/packages/office-ui-fabric-vue/components/Modal/OfficeModal.types.ts @@ -0,0 +1,102 @@ +/* +Taken from https://github.com/OfficeDev/office-ui-fabric-react and slightly modified + +License: + Office UI Fabric React + Copyright (c) Microsoft Corporation + All rights reserved. + MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + Note: Usage of the fonts and icons referenced in Office UI Fabric is subject to the terms listed at http://aka.ms/fabric-assets-license +*/ + +import {IStyle, IStyleFunctionOrObject} from "@uifabric/merge-styles"; +import {ITheme} from "../../../styling"; +import {IOfficeLayerProps} from "@components/Layer/OfficeLayer.types"; + +export interface IOfficeModalProps { + /** + * Theme provided by High-Order Component. + */ + theme?: ITheme; + + /** + * Whether the dialog is displayed. + * @defaultvalue false + */ + isOpen?: boolean; + + /** + * Whether the overlay is dark themed. + * @defaultvalue true + */ + isDarkOverlay?: boolean; + /** + * Optional override for root class + */ + className?: string; + /** + * Optional override for container class + */ + containerClassName?: string; + + /** + * Optional override for scrollable content class + */ + scrollableContentClassName?: string; + + /** + * A callback function for when the Modal is dismissed light dismiss, before the animation completes. + */ + onDismiss?: () => any; + + /** + * Props to be passed through to Layer + */ + layerProps?: IOfficeLayerProps; + + /** + * Whether the dialog can be light dismissed by clicking outside the dialog (on the overlay). + * @defaultvalue false + */ + isBlocking?: boolean; + + /** + * Whether the modal should have top offset fixed once opened and expand from the bottom only + * when the content changes dynamically. + */ + topOffsetFixed?: boolean; +} + +export interface IOfficeModalStyleProps { + /** + * Accept theme prop. + */ + theme: ITheme; + topOffsetFixed?: boolean; + containerClassName?: string; + className?: string; + + /** + * Optional override for scrollable content class + */ + scrollableContentClassName?: string; + /** Modal open state. */ + isOpen?: boolean; + /** Modal visible state. */ + isVisible?: boolean; + /** Modal has been opened state. */ + hasBeenOpened?: boolean; + + /** Positioning of modal on first render */ + modalRectangleTop?: number; +} + + +export interface IOfficeModalStyles { + root: IStyle; + main: IStyle; + scrollableContent: IStyle; +} diff --git a/packages/office-ui-fabric-vue/components/Modal/OfficeModal.vue b/packages/office-ui-fabric-vue/components/Modal/OfficeModal.vue new file mode 100644 index 0000000..25612ba --- /dev/null +++ b/packages/office-ui-fabric-vue/components/Modal/OfficeModal.vue @@ -0,0 +1,96 @@ + + + diff --git a/packages/office-ui-fabric-vue/components/Overlay/OfficeOverlay.vue b/packages/office-ui-fabric-vue/components/Overlay/OfficeOverlay.vue index 3f8d910..3e4e398 100644 --- a/packages/office-ui-fabric-vue/components/Overlay/OfficeOverlay.vue +++ b/packages/office-ui-fabric-vue/components/Overlay/OfficeOverlay.vue @@ -24,6 +24,10 @@ overflow: "hidden !important" as "hidden" }); + public destroyed() { + this.enableBodyScroll(); + } + public get classNames() { return mergeStyleSets(getStyles({ isDark: this.isDarkThemed, @@ -58,5 +62,7 @@ doc.body.removeEventListener("touchmove", this.disableIosBodyScroll); } } + + } diff --git a/packages/office-ui-fabric-vue/components/Popup/OfficePopup.vue b/packages/office-ui-fabric-vue/components/Popup/OfficePopup.vue index 319da82..d711045 100644 --- a/packages/office-ui-fabric-vue/components/Popup/OfficePopup.vue +++ b/packages/office-ui-fabric-vue/components/Popup/OfficePopup.vue @@ -76,7 +76,7 @@ return; } let needsVerticalScrollBar = false; - if (root.firstElementChild) { + if (root && root.firstElementChild) { // ClientHeight returns the client height of an element rounded to an // integer. On some browsers at different zoom levels this rounding // can generate different results for the root container and child even