From af9905acff4834863311e97f1d3a911001aa8e76 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Mon, 22 Aug 2022 17:11:21 -0400 Subject: [PATCH] fix flip fallbacks and add example --- docs/components/popup.md | 91 +++++++++++++++++++++++++++++++++++ docs/resources/changelog.md | 3 ++ src/components/popup/popup.ts | 11 ++--- 3 files changed, 99 insertions(+), 6 deletions(-) diff --git a/docs/components/popup.md b/docs/components/popup.md index 042fd1bc..73604392 100644 --- a/docs/components/popup.md +++ b/docs/components/popup.md @@ -1094,6 +1094,97 @@ const App = () => { }; ``` +### Flip Fallbacks + +While using the `flip` attribute, you can customize the placement of the popup when the preferred placement doesn't have room. For this, use `flip-fallback-placements` and `flip-fallback-strategy`. + +If the preferred placement doesn't have room, the first suitable placement found in `flip-fallback-placement` will be used. The value of this attribute must be a string including any number of placements separated by a space, e.g. `"right bottom"`. + +If no fallback placement works, the final placement will be determined by `flip-fallback-strategy`. This value can be either `initial` (default), where the placement reverts to the position in `placement`, or `best-fit`, where the placement is chosen based on available space. + +Scroll the container to see how the popup changes it's fallback placement to prevent clipping. + +```html preview + + + +``` + +```jsx react +import { useState } from 'react'; +import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-flip-fallbacks .overflow { + position: relative; + height: 300px; + border: solid 2px var(--sl-color-neutral-200); + overflow: auto; + } + + .popup-flip-fallbacks span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 250px 50px; + } + + .popup-flip-fallbacks .box { + width: 100px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } +`; + +const App = () => { + return ( + <> +
+
+ + +
+ +
+
+ + + + ); +}; +``` + ### Shift When a popup is longer than its anchor, it risks being clipped by an overflowing container. In this case, use the `shift` attribute to shift the popup along its axis and back into view. You can customize the shift behavior using `shiftBoundary` and `shift-padding`. diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md index 000cdd20..540d9ee1 100644 --- a/docs/resources/changelog.md +++ b/docs/resources/changelog.md @@ -12,9 +12,12 @@ _During the beta period, these restrictions may be relaxed in the event of a mis - Added the `sync` attribute to `` - Changed the `auto-size` attribute of the experimental `` component so it accepts `horizontal`, `vertical`, and `both` instead of a boolean value +- Changed the `flip-fallback-placement` attribute of the experimental `` component to `flip-fallback-placements` +- Changed the `flip-fallback-strategy` in the experimental `` component to accept `best-fit` and `initial` instead of `bestFit` and `initialPlacement` - Fixed a bug in `` that caused the panel to resize horizontally when the trigger is clipped by the viewport [#860](https://github.com/shoelace-style/shoelace/issues/860) - Fixed a bug in `` where dynamically changing slotted items wouldn't update the tree properly - Fixed a bug in `` that caused the panel to stack when clicking on the divider in mobile versions of Chrome [#862](https://github.com/shoelace-style/shoelace/issues/862) +- Fixed a bug in `` that prevented flip fallbacks from working as intended - Improved single selection in `` so nodes expand and collapse and receive selection when clicking on the label - Renamed `expanded-icon` and `collapsed-icon` slots to `expand-icon` and `collapse-icon` in the experimental `` and `` components - Improved RTL support for `` diff --git a/src/components/popup/popup.ts b/src/components/popup/popup.ts index 1ecc299c..4597d566 100644 --- a/src/components/popup/popup.ts +++ b/src/components/popup/popup.ts @@ -101,7 +101,7 @@ export default class SlPopup extends ShoelaceElement { /** * When set, placement of the popup will flip to the opposite site to keep it in view. You can use - * `flipFallbackPlacement` to further configure how the fallback placement is determined. + * `flipFallbackPlacements` to further configure how the fallback placement is determined. */ @property({ type: Boolean }) flip = false; @@ -111,7 +111,7 @@ export default class SlPopup extends ShoelaceElement { * fallback strategy will be used instead. * */ @property({ - attribute: 'flip-fallback-placement', + attribute: 'flip-fallback-placements', converter: { fromAttribute: (value: string) => { return value @@ -124,15 +124,14 @@ export default class SlPopup extends ShoelaceElement { } } }) - flipFallbackPlacement = ''; + flipFallbackPlacements = ''; /** * When neither the preferred placement nor the fallback placements fit, this value will be used to determine whether * the popup should be positioned as it was initially preferred or using the best available fit based on available * space. */ - @property({ attribute: 'flip-fallback-strategy' }) flipFallbackStrategy: 'bestFit' | 'initialPlacement' = - 'initialPlacement'; + @property({ attribute: 'flip-fallback-strategy' }) flipFallbackStrategy: 'best-fit' | 'initial' = 'initial'; /** * The flip boundary describes clipping element(s) that overflow will be checked relative to when flipping. By @@ -304,7 +303,7 @@ export default class SlPopup extends ShoelaceElement { flip({ boundary: this.flipBoundary, // @ts-expect-error - We're converting a string attribute to an array here - fallbackPlacement: this.flipFallbackPlacement, + fallbackPlacements: this.flipFallbackPlacements, fallbackStrategy: this.flipFallbackStrategy, padding: this.flipPadding })