From 276be6a9a050058a1e18e47c117b03c7b7bba6ff Mon Sep 17 00:00:00 2001 From: Joffrey Bion Date: Sat, 4 Apr 2020 19:10:30 +0200 Subject: Add blueprintjs Overlay component --- sw-ui-kt/src/main/kotlin/blueprintjs.kt | 130 +++++++++++++++++++++++++ sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt | 26 +++++ 2 files changed, 156 insertions(+) (limited to 'sw-ui-kt/src/main') diff --git a/sw-ui-kt/src/main/kotlin/blueprintjs.kt b/sw-ui-kt/src/main/kotlin/blueprintjs.kt index eaf36618..13de8744 100644 --- a/sw-ui-kt/src/main/kotlin/blueprintjs.kt +++ b/sw-ui-kt/src/main/kotlin/blueprintjs.kt @@ -393,3 +393,133 @@ external class Classes { val HTML_TABLE: String = definedExternally } } + +external interface IOverlayableProps : IOverlayLifecycleProps { + /** + * Whether the overlay should acquire application focus when it first opens. + * @default true + */ + var autoFocus: Boolean? + /** + * Whether pressing the `esc` key should invoke `onClose`. + * @default true + */ + var canEscapeKeyClose: Boolean? + /** + * Whether the overlay should prevent focus from leaving itself. That is, if the user attempts + * to focus an element outside the overlay and this prop is enabled, then the overlay will + * immediately bring focus back to itself. If you are nesting overlay components, either disable + * this prop on the "outermost" overlays or mark the nested ones `usePortal={false}`. + * @default true + */ + var enforceFocus: Boolean? + /** + * If `true` and `usePortal={true}`, the `Portal` containing the children is created and attached + * to the DOM when the overlay is opened for the first time; otherwise this happens when the + * component mounts. Lazy mounting provides noticeable performance improvements if you have lots + * of overlays at once, such as on each row of a table. + * @default true + */ + var lazy: Boolean? + /** + * Indicates how long (in milliseconds) the overlay's enter/leave transition takes. + * This is used by React `CSSTransition` to know when a transition completes and must match + * the duration of the animation in CSS. Only set this prop if you override Blueprint's default + * transitions with new transitions of a different length. + * @default 300 + */ + var transitionDuration: Int? + /** + * Whether the overlay should be wrapped in a `Portal`, which renders its contents in a new + * element attached to `portalContainer` prop. + * + * This prop essentially determines which element is covered by the backdrop: if `false`, + * then only its parent is covered; otherwise, the entire page is covered (because the parent + * of the `Portal` is the `` itself). + * + * Set this prop to `false` on nested overlays (such as `Dialog` or `Popover`) to ensure that they + * are rendered above their parents. + * @default true + */ + var usePortal: Boolean? + /** + * Space-delimited string of class names applied to the `Portal` element if + * `usePortal={true}`. + */ + var portalClassName: String? + /** + * The container element into which the overlay renders its contents, when `usePortal` is `true`. + * This prop is ignored if `usePortal` is `false`. + * @default document.body + */ + var portalContainer: HTMLElement? + /** + * A callback that is invoked when user interaction causes the overlay to close, such as + * clicking on the overlay or pressing the `esc` key (if enabled). + * + * Receives the event from the user's interaction, if there was an event (generally either a + * mouse or key event). Note that, since this component is controlled by the `isOpen` prop, it + * will not actually close itself until that prop becomes `false`. + */ + var onClose: ((Event) -> Unit)? +} +external interface IOverlayLifecycleProps { + /** + * Lifecycle method invoked just before the CSS _close_ transition begins on + * a child. Receives the DOM element of the child being closed. + */ + var onClosing: ((node: HTMLElement) -> Unit)? + /** + * Lifecycle method invoked just after the CSS _close_ transition ends but + * before the child has been removed from the DOM. Receives the DOM element + * of the child being closed. + */ + var onClosed: ((node: HTMLElement) -> Unit)? + /** + * Lifecycle method invoked just after mounting the child in the DOM but + * just before the CSS _open_ transition begins. Receives the DOM element of + * the child being opened. + */ + var onOpening: ((node: HTMLElement) -> Unit)? + /** + * Lifecycle method invoked just after the CSS _open_ transition ends. + * Receives the DOM element of the child being opened. + */ + var onOpened: ((node: HTMLElement) -> Unit)? +} +external interface IBackdropProps { + /** CSS class names to apply to backdrop element. */ + var backdropClassName: String? + /** HTML props for the backdrop element. */ + var backdropProps: RProps? //React.HTMLProps? + /** + * Whether clicking outside the overlay element (either on backdrop when present or on document) + * should invoke `onClose`. + * @default true + */ + var canOutsideClickClose: Boolean? + /** + * Whether a container-spanning backdrop element should be rendered behind the contents. + * @default true + */ + var hasBackdrop: Boolean? +} +external interface IOverlayProps : IOverlayableProps, IBackdropProps, IProps { + /** + * Toggles the visibility of the overlay and its children. + * This prop is required because the component is controlled. + */ + var isOpen: Boolean + /** + * Name of the transition for internal `CSSTransition`. + * Providing your own name here will require defining new CSS transition properties. + * @default Classes.OVERLAY + */ + var transitionName: String? +} +external interface IOverlayState : RState { + var hasEverOpened: Boolean? +} +external class Overlay : PureComponent { + override fun render(): ReactElement +} \ No newline at end of file diff --git a/sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt b/sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt index 928653c5..da6b6914 100644 --- a/sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt +++ b/sw-ui-kt/src/main/kotlin/blueprintjsHelpers.kt @@ -30,6 +30,7 @@ fun RBuilder.bpIcon( fun RBuilder.bpButton( minimal: Boolean = false, + small: Boolean = false, large: Boolean = false, disabled: Boolean = false, title: String? = null, @@ -42,6 +43,7 @@ fun RBuilder.bpButton( attrs { this.title = title this.minimal = minimal + this.small = small this.large = large this.disabled = disabled this.icon = icon @@ -109,3 +111,27 @@ fun RBuilder.bpNonIdealState( } block() } + +fun RBuilder.bpOverlay( + isOpen: Boolean, + autoFocus: Boolean = true, + enforceFocus: Boolean = true, + usePortal: Boolean = true, + hasBackdrop: Boolean = true, + canEscapeKeyClose: Boolean = true, + canOutsideClickClose: Boolean = true, + onClose: () -> Unit = {}, + block: RHandler = {} +): ReactElement = child(Overlay::class) { + attrs { + this.isOpen = isOpen + this.autoFocus = autoFocus + this.enforceFocus = enforceFocus + this.usePortal = usePortal + this.hasBackdrop = hasBackdrop + this.canEscapeKeyClose = canEscapeKeyClose + this.canOutsideClickClose = canOutsideClickClose + this.onClose = { onClose() } + } + block() +} -- cgit