kopia lustrzana https://github.com/shoelace-style/shoelace
Add hoist prop; fixes #179
rodzic
7d5aac4bc8
commit
b8f52e48ec
|
@ -2,6 +2,7 @@
|
|||
|
||||
## 2.0.0-beta.16
|
||||
|
||||
- Add `hoist` prop to `sl-color-picker`, `sl-dropdown`, and `sl-select` to work around panel clipping
|
||||
- Add `sl-format-bytes` utility component
|
||||
- Add `clearable` and `required` props to `sl-select`
|
||||
- Add `slClear` event to `sl-input`
|
||||
|
|
|
@ -87,4 +87,38 @@ The offset of the panel along the trigger can be customized using the `skidding`
|
|||
</sl-dropdown>
|
||||
```
|
||||
|
||||
### Hoisting
|
||||
|
||||
Dropdown panels will be clipped if they're inside a container that has `overflow: auto|hidden`. The `hoist` attribute forces the panel to use a fixed positioning strategy, allowing it to break out of the container. In this case, the panel will be positioned relative to its containing block, which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
```html preview
|
||||
<div class="dropdown-hoist">
|
||||
<sl-dropdown>
|
||||
<sl-button slot="trigger" caret>No Hoist</sl-button>
|
||||
<sl-menu>
|
||||
<sl-menu-item>Item 1</sl-menu-item>
|
||||
<sl-menu-item>Item 2</sl-menu-item>
|
||||
<sl-menu-item>Item 3</sl-menu-item>
|
||||
</sl-menu>
|
||||
</sl-dropdown>
|
||||
|
||||
<sl-dropdown hoist>
|
||||
<sl-button slot="trigger" caret>Hoist</sl-button>
|
||||
<sl-menu>
|
||||
<sl-menu-item>Item 1</sl-menu-item>
|
||||
<sl-menu-item>Item 2</sl-menu-item>
|
||||
<sl-menu-item>Item 3</sl-menu-item>
|
||||
</sl-menu>
|
||||
</sl-dropdown>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.dropdown-hoist {
|
||||
border: solid 2px var(--sl-color-gray-80);
|
||||
padding: var(--sl-spacing-medium);
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
[component-metadata:sl-dropdown]
|
||||
|
|
|
@ -243,6 +243,10 @@ export namespace Components {
|
|||
* The format to use for the display value. If opacity is enabled, these will translate to HEXA, RGBA, and HSLA respectively. The color picker will always accept user input in any format (including CSS color names) and convert it to the desired format.
|
||||
*/
|
||||
"format": 'hex' | 'rgb' | 'hsl';
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with `overflow: auto|scroll`.
|
||||
*/
|
||||
"hoist": boolean;
|
||||
/**
|
||||
* Set to true to render the color picker inline rather than inside a dropdown.
|
||||
*/
|
||||
|
@ -359,6 +363,10 @@ export namespace Components {
|
|||
* Hides the dropdown panel
|
||||
*/
|
||||
"hide": () => Promise<void>;
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with `overflow: auto|scroll`.
|
||||
*/
|
||||
"hoist": boolean;
|
||||
/**
|
||||
* Indicates whether or not the dropdown is open. You can use this in lieu of the show/hide methods.
|
||||
*/
|
||||
|
@ -742,6 +750,10 @@ export namespace Components {
|
|||
* Set to true to disable the select control.
|
||||
*/
|
||||
"disabled": boolean;
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with `overflow: auto|scroll`.
|
||||
*/
|
||||
"hoist": boolean;
|
||||
/**
|
||||
* Set to true to indicate that the user input is invalid.
|
||||
*/
|
||||
|
@ -1533,6 +1545,10 @@ declare namespace LocalJSX {
|
|||
* The format to use for the display value. If opacity is enabled, these will translate to HEXA, RGBA, and HSLA respectively. The color picker will always accept user input in any format (including CSS color names) and convert it to the desired format.
|
||||
*/
|
||||
"format"?: 'hex' | 'rgb' | 'hsl';
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with `overflow: auto|scroll`.
|
||||
*/
|
||||
"hoist"?: boolean;
|
||||
/**
|
||||
* Set to true to render the color picker inline rather than inside a dropdown.
|
||||
*/
|
||||
|
@ -1697,6 +1713,10 @@ declare namespace LocalJSX {
|
|||
* The distance in pixels from which to offset the panel away from its trigger.
|
||||
*/
|
||||
"distance"?: number;
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with `overflow: auto|scroll`.
|
||||
*/
|
||||
"hoist"?: boolean;
|
||||
/**
|
||||
* Emitted after the dropdown closes and all transitions are complete.
|
||||
*/
|
||||
|
@ -2108,6 +2128,10 @@ declare namespace LocalJSX {
|
|||
* Set to true to disable the select control.
|
||||
*/
|
||||
"disabled"?: boolean;
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with `overflow: auto|scroll`.
|
||||
*/
|
||||
"hoist"?: boolean;
|
||||
/**
|
||||
* Set to true to indicate that the user input is invalid.
|
||||
*/
|
||||
|
|
|
@ -64,6 +64,12 @@ export class ColorPicker {
|
|||
/** Set to true to disable the color picker. */
|
||||
@Prop() disabled = false;
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|scroll`.
|
||||
*/
|
||||
@Prop() hoist = false;
|
||||
|
||||
/** Whether to show the opacity slider. */
|
||||
@Prop() opacity = false;
|
||||
|
||||
|
@ -736,6 +742,7 @@ export class ColorPicker {
|
|||
class="color-dropdown"
|
||||
aria-disabled={this.disabled}
|
||||
containingElement={this.host}
|
||||
hoist={this.hoist}
|
||||
onSlShow={this.handleDropdownShow}
|
||||
onSlAfterShow={this.handleDropdownAfterShow}
|
||||
onSlHide={this.handleDropdownHide}
|
||||
|
|
|
@ -63,6 +63,12 @@ export class Dropdown {
|
|||
/** The distance in pixels from which to offset the panel along its trigger. */
|
||||
@Prop() skidding = 0;
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|scroll`.
|
||||
*/
|
||||
@Prop() hoist = false;
|
||||
|
||||
/** Emitted when the dropdown opens. Calling `event.preventDefault()` will prevent it from being opened. */
|
||||
@Event() slShow: EventEmitter;
|
||||
|
||||
|
@ -80,11 +86,17 @@ export class Dropdown {
|
|||
this.open ? this.show() : this.hide();
|
||||
}
|
||||
|
||||
@Watch('placement')
|
||||
@Watch('distance')
|
||||
@Watch('hoist')
|
||||
@Watch('placement')
|
||||
@Watch('skidding')
|
||||
handlePopoverOptionsChange() {
|
||||
this.popover.setOptions({ placement: this.placement });
|
||||
this.popover.setOptions({
|
||||
strategy: this.hoist ? 'fixed' : 'absolute',
|
||||
placement: this.placement,
|
||||
distance: this.distance,
|
||||
skidding: this.skidding
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
|
@ -102,9 +114,10 @@ export class Dropdown {
|
|||
|
||||
componentDidLoad() {
|
||||
this.popover = new Popover(this.trigger, this.panel, {
|
||||
strategy: this.hoist ? 'fixed' : 'absolute',
|
||||
placement: this.placement,
|
||||
skidding: this.skidding,
|
||||
distance: this.distance,
|
||||
skidding: this.skidding,
|
||||
onAfterHide: () => this.slAfterHide.emit(),
|
||||
onAfterShow: () => this.slAfterShow.emit(),
|
||||
onTransitionEnd: () => {
|
||||
|
|
|
@ -65,6 +65,12 @@ export class Select {
|
|||
/** The select's size. */
|
||||
@Prop() size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|scroll`.
|
||||
*/
|
||||
@Prop() hoist = false;
|
||||
|
||||
/** The value of the control. This will be a string or an array depending on `multiple`. */
|
||||
@Prop({ mutable: true }) value: string | Array<string> = '';
|
||||
|
||||
|
@ -333,6 +339,7 @@ export class Select {
|
|||
<sl-dropdown
|
||||
part="base"
|
||||
ref={el => (this.dropdown = el)}
|
||||
hoist={this.hoist}
|
||||
closeOnSelect={!this.multiple}
|
||||
containingElement={this.host}
|
||||
class={{
|
||||
|
|
|
@ -33,6 +33,7 @@ export default class Popover {
|
|||
skidding: 0,
|
||||
distance: 0,
|
||||
placement: 'bottom-start',
|
||||
strategy: 'absolute',
|
||||
visibleClass: 'popover-visible',
|
||||
onAfterShow: () => {},
|
||||
onAfterHide: () => {},
|
||||
|
@ -85,6 +86,7 @@ export default class Popover {
|
|||
|
||||
this.popper = createPopper(this.anchor, this.popover, {
|
||||
placement: this.options.placement,
|
||||
strategy: this.options.strategy,
|
||||
modifiers: [
|
||||
{
|
||||
name: 'flip',
|
||||
|
@ -123,7 +125,8 @@ export default class Popover {
|
|||
// Update popper options
|
||||
if (this.popper) {
|
||||
this.popper.setOptions({
|
||||
placement: this.options.placement
|
||||
placement: this.options.placement,
|
||||
strategy: this.options.strategy
|
||||
});
|
||||
|
||||
requestAnimationFrame(() => this.popper.update());
|
||||
|
@ -150,6 +153,7 @@ export interface PopoverOptions {
|
|||
| 'left-start'
|
||||
| 'left-end';
|
||||
skidding?: number;
|
||||
strategy?: 'absolute' | 'fixed';
|
||||
visibleClass?: string;
|
||||
onAfterShow?: () => any;
|
||||
onAfterHide?: () => any;
|
||||
|
|
Ładowanie…
Reference in New Issue