diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 2caad20bf6..6809f1ffa5 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -80,7 +80,7 @@ "dayjs": "^1.10.8", "easymde": "^2.16.1", "svelte-dnd-action": "^0.9.8", - "svelte-portal": "^1.0.0" + "svelte-portal": "^2.2.1" }, "resolutions": { "loader-utils": "1.4.1" diff --git a/packages/bbui/src/Actions/click_outside.js b/packages/bbui/src/Actions/click_outside.ts similarity index 63% rename from packages/bbui/src/Actions/click_outside.js rename to packages/bbui/src/Actions/click_outside.ts index 526659cb7a..248a03039e 100644 --- a/packages/bbui/src/Actions/click_outside.js +++ b/packages/bbui/src/Actions/click_outside.ts @@ -1,3 +1,17 @@ +type ClickOutsideCallback = (event: MouseEvent) => void | undefined + +interface ClickOutsideOpts { + callback?: ClickOutsideCallback + anchor?: HTMLElement +} + +interface Handler { + id: number + element: HTMLElement + anchor: HTMLElement + callback?: ClickOutsideCallback +} + // These class names will never trigger a callback if clicked, no matter what const ignoredClasses = [ ".download-js-link", @@ -14,18 +28,20 @@ const conditionallyIgnoredClasses = [ ".drawer-wrapper", ".spectrum-Popover", ] -let clickHandlers = [] -let candidateTarget +let clickHandlers: Handler[] = [] +let candidateTarget: HTMLElement | undefined // Processes a "click outside" event and invokes callbacks if our source element // is valid -const handleClick = event => { +const handleClick = (e: MouseEvent) => { + const target = e.target as HTMLElement + // Ignore click if this is an ignored class - if (event.target.closest('[data-ignore-click-outside="true"]')) { + if (target.closest('[data-ignore-click-outside="true"]')) { return } for (let className of ignoredClasses) { - if (event.target.closest(className)) { + if (target.closest(className)) { return } } @@ -33,41 +49,41 @@ const handleClick = event => { // Process handlers clickHandlers.forEach(handler => { // Check that the click isn't inside the target - if (handler.element.contains(event.target)) { + if (handler.element.contains(target)) { return } // Ignore clicks for certain classes unless we're nested inside them for (let className of conditionallyIgnoredClasses) { const sourceInside = handler.anchor.closest(className) != null - const clickInside = event.target.closest(className) != null + const clickInside = target.closest(className) != null if (clickInside && !sourceInside) { return } } - handler.callback?.(event) + handler.callback?.(e) }) } // On mouse up we only trigger a "click outside" callback if we targetted the // same element that we did on mouse down. This fixes all sorts of issues where // we get annoying callbacks firing when we drag to select text. -const handleMouseUp = e => { +const handleMouseUp = (e: MouseEvent) => { if (candidateTarget === e.target) { handleClick(e) } - candidateTarget = null + candidateTarget = undefined } // On mouse down we store which element was targetted for comparison later -const handleMouseDown = e => { +const handleMouseDown = (e: MouseEvent) => { // Only handle the primary mouse button here. // We handle context menu (right click) events in another handler. if (e.button !== 0) { return } - candidateTarget = e.target + candidateTarget = e.target as HTMLElement // Clear any previous listeners in case of multiple down events, and register // a single mouse up listener @@ -82,7 +98,12 @@ document.addEventListener("contextmenu", handleClick) /** * Adds or updates a click handler */ -const updateHandler = (id, element, anchor, callback) => { +const updateHandler = ( + id: number, + element: HTMLElement, + anchor: HTMLElement, + callback: ClickOutsideCallback | undefined +) => { let existingHandler = clickHandlers.find(x => x.id === id) if (!existingHandler) { clickHandlers.push({ id, element, anchor, callback }) @@ -94,27 +115,52 @@ const updateHandler = (id, element, anchor, callback) => { /** * Removes a click handler */ -const removeHandler = id => { +const removeHandler = (id: number) => { clickHandlers = clickHandlers.filter(x => x.id !== id) } /** - * Svelte action to apply a click outside handler for a certain element + * Svelte action to apply a click outside handler for a certain element. * opts.anchor is an optional param specifying the real root source of the * component being observed. This is required for things like popovers, where * the element using the clickoutside action is the popover, but the popover is * rendered at the root of the DOM somewhere, whereas the popover anchor is the * element we actually want to consider when determining the source component. */ -export default (element, opts) => { +export default ( + element: HTMLElement, + opts?: ClickOutsideOpts | ClickOutsideCallback +) => { const id = Math.random() - const update = newOpts => { - const callback = - newOpts?.callback || (typeof newOpts === "function" ? newOpts : null) - const anchor = newOpts?.anchor || element + + const isCallback = ( + opts?: ClickOutsideOpts | ClickOutsideCallback + ): opts is ClickOutsideCallback => { + return typeof opts === "function" + } + + const isOpts = ( + opts?: ClickOutsideOpts | ClickOutsideCallback + ): opts is ClickOutsideOpts => { + return opts != null && typeof opts === "object" + } + + const update = (newOpts?: ClickOutsideOpts | ClickOutsideCallback) => { + let callback: ClickOutsideCallback | undefined + let anchor = element + if (isCallback(newOpts)) { + callback = newOpts + } else if (isOpts(newOpts)) { + callback = newOpts.callback + if (newOpts.anchor) { + anchor = newOpts.anchor + } + } updateHandler(id, element, anchor, callback) } + update(opts) + return { update, destroy: () => removeHandler(id), diff --git a/packages/bbui/src/Actions/position_dropdown.js b/packages/bbui/src/Actions/position_dropdown.js index e95c7dd1b6..258ce9879d 100644 --- a/packages/bbui/src/Actions/position_dropdown.js +++ b/packages/bbui/src/Actions/position_dropdown.js @@ -1,10 +1,4 @@ -/** - * Valid alignment options are - * - left - * - right - * - left-outside - * - right-outside - **/ +import { PopoverAlignment } from "../constants" // Strategies are defined as [Popover]To[Anchor]. // They can apply for both horizontal and vertical alignment. @@ -149,20 +143,29 @@ export default function positionDropdown(element, opts) { } // Determine X strategy - if (align === "right") { + if (align === PopoverAlignment.Right) { applyXStrategy(Strategies.EndToEnd) - } else if (align === "right-outside" || align === "right-context-menu") { + } else if ( + align === PopoverAlignment.RightOutside || + align === PopoverAlignment.RightContextMenu + ) { applyXStrategy(Strategies.StartToEnd) - } else if (align === "left-outside" || align === "left-context-menu") { + } else if ( + align === PopoverAlignment.LeftOutside || + align === PopoverAlignment.LeftContextMenu + ) { applyXStrategy(Strategies.EndToStart) - } else if (align === "center") { + } else if (align === PopoverAlignment.Center) { applyXStrategy(Strategies.MidPoint) } else { applyXStrategy(Strategies.StartToStart) } // Determine Y strategy - if (align === "right-outside" || align === "left-outside") { + if ( + align === PopoverAlignment.RightOutside || + align === PopoverAlignment.LeftOutside + ) { applyYStrategy(Strategies.MidPoint) } else if ( align === "right-context-menu" || diff --git a/packages/bbui/src/Icon/Icon.svelte b/packages/bbui/src/Icon/Icon.svelte index 7438fab5fd..2f12935f53 100644 --- a/packages/bbui/src/Icon/Icon.svelte +++ b/packages/bbui/src/Icon/Icon.svelte @@ -1,13 +1,10 @@ - - + + + + + +
+ {#if label != null} +
+
+ {#if expandable} + (expanded = !expanded)} + /> + {/if} +
+
(expanded = !expanded)} + on:click={() => dispatch("click-label", clickContext)} + > + {label} +
+
(valueExpanded = !valueExpanded)} + on:click={() => dispatch("click-value", clickContext)} + > + {displayValue} +
+ {#if showCopyIcon} +
+ dispatch("click-copy", clickContext)} + /> +
+ {/if} +
+ {/if} + {#if expandable && (expanded || label == null)} +
+ {#each keys as key} + + {/each} +
+ {/if} +
+ + diff --git a/packages/builder/src/components/common/UpdateAppTopNav.svelte b/packages/builder/src/components/common/UpdateAppTopNav.svelte index f4a76c4576..967bf1dfdf 100644 --- a/packages/builder/src/components/common/UpdateAppTopNav.svelte +++ b/packages/builder/src/components/common/UpdateAppTopNav.svelte @@ -25,7 +25,7 @@
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_layout.svelte index 16fe7d9c2f..f5dec6371f 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_layout.svelte @@ -30,7 +30,7 @@ if (id === `${$screenStore.selectedScreenId}-screen`) return true if (id === `${$screenStore.selectedScreenId}-navigation`) return true - return !!findComponent($selectedScreen.props, id) + return !!findComponent($selectedScreen?.props, id) } // Keep URL and state in sync for selected component ID diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte index d57e9431be..b04cd8b956 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte @@ -3,7 +3,6 @@ import AppPreview from "./AppPreview.svelte" import { screenStore, appStore } from "@/stores/builder" import UndoRedoControl from "@/components/common/UndoRedoControl.svelte" - import BindingsPanel from "./BindingsPanel.svelte"
@@ -11,13 +10,12 @@
+
+
{#if $appStore.clientFeatures.devicePreview} {/if}
-
- -
{#key $appStore.version} diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/BindingsPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/BindingsPanel.svelte index 73cac27331..9bfabe0584 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/BindingsPanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/BindingsPanel.svelte @@ -1,14 +1,99 @@ - -Bindings +
+ +
+ Showing all available bindings. + + Learn more. + +
+ +
+
- - - Some awesome bindings content. - - + diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentKeyHandler.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentKeyHandler.svelte similarity index 100% rename from packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentKeyHandler.svelte rename to packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentKeyHandler.svelte diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/index.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/index.svelte index eb5a57ec9c..7636d923de 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/index.svelte @@ -1,6 +1,5 @@ - -
-
- Components -
- -
-
- +
    openScreenContextMenu(e, false)} @@ -159,7 +135,6 @@
-