From cf2915a5916c90a29a52e96d7777e6ec1a9301fe Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Tue, 9 Aug 2022 12:49:01 -0400 Subject: [PATCH] add react examples --- docs/components/popup.md | 612 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 612 insertions(+) diff --git a/docs/components/popup.md b/docs/components/popup.md index b076ecb8d..85ccddbd4 100644 --- a/docs/components/popup.md +++ b/docs/components/popup.md @@ -97,6 +97,124 @@ The popup's preferred placement, distance, and skidding (offset) can be configur ``` +```jsx react +import { useState } from 'react'; +import { SlPopup, SlSelect, SlMenuItem, SlInput, SlSwitch } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-overview sl-popup { + --arrow-color: var(--sl-color-primary-600); + } + + .popup-overview span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 50px; + } + + .popup-overview .box { + width: 100px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } + + .popup-overview-options { + display: flex; + flex-wrap: wrap; + align-items: end; + gap: 1rem; + } + + .popup-overview-options sl-select { + width: 160px; + } + + .popup-overview-options sl-input { + width: 100px; + } + + .popup-overview-options + .popup-overview-options { + margin-top: 1rem; + } +`; + +const App = () => { + const [placement, setPlacement] = useState('top'); + const [distance, setDistance] = useState(0); + const [skidding, setSkidding] = useState(0); + const [active, setActive] = useState(true); + const [arrow, setArrow] = useState(false); + + return ( + <> +
+ + +
+ + +
+ setPlacement(event.target.value)} + > + top + top-start + top-end + bottom + bottom-start + bottom-end + right + right-start + right-end + left + left-start + left-end + + setDistance(event.target.value)} + /> + setSkidding(event.target.value)} + /> +
+ +
+ setActive(event.target.checked)}> + Active + + setArrow(event.target.checked)}> + Arrow + +
+
+ + + + ); +}; +``` + ?> A popup's anchor should never be styled with `display: contents` since the coordinates will not be eligible for calculation. However, if the anchor is a `` element, popup will use the first assigned element as the anchor. This behavior allows other components to pass anchors through more easily via composition. ## Examples @@ -142,6 +260,50 @@ Popups are inactive and hidden until the `active` attribute is applied. Removing ``` +```jsx react +import { useState } from 'react'; +import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-active span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 50px; + } + + .popup-active .box { + width: 100px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } +`; + +const App = () => { + const [active, setActive] = useState(true); + + return ( + <> +
+ + +
+ + +
+ setActive(event.target.checked)}> + Active + +
+ + + + ); +}; +``` + ### Placement Use the `placement` attribute to tell the popup the preferred placement of the popup. Note that the actual position will vary to ensure the panel remains in the viewport if you're using positioning features such as `flip` and `shift`. @@ -199,6 +361,64 @@ Use the `placement` attribute to tell the popup the preferred placement of the p ``` +```jsx react +import { useState } from 'react'; +import { SlPopup, SlSelect, SlMenuItem } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-placement span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 50px; + } + + .popup-placement .box { + width: 100px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } + + .popup-placement sl-select { + max-width: 280px; + } +`; + +const App = () => { + const [placement, setPlacement] = useState('top'); + + return ( +
+
+ + +
+ + + setPlacement(event.target.value)}> + top + top-start + top-end + bottom + bottom-start + bottom-end + right + right-start + right-end + left + left-start + left-end + +
+ + +
+ ); +}; +``` + ### Distance Use the `distance` attribute to change the distance between the popup and its anchor. A positive value will move the popup further away and a negative value will move it closer. @@ -243,6 +463,58 @@ Use the `distance` attribute to change the distance between the popup and its an ``` +```jsx react +import { useState } from 'react'; +import { SlPopup, SlRange } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-distance span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 50px; + } + + .popup-distance .box { + width: 100px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } + + .popup-distance sl-range { + max-width: 260px; + } +`; + +const App = () => { + const [distance, setDistance] = useState(0); + + return ( + <> +
+ + +
+ + + setDistance(event.target.value)} + /> +
+ + + + ); +}; +``` + ### Skidding The `skidding` attribute is similar to `distance`, but instead allows you to offset the popup along the anchor's axis. Both positive and negative values are allowed. @@ -287,6 +559,58 @@ The `skidding` attribute is similar to `distance`, but instead allows you to off ``` +```jsx react +import { useState } from 'react'; +import { SlPopup, SlRange } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-skidding span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 50px; + } + + .popup-skidding .box { + width: 100px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } + + .popup-skidding sl-range { + max-width: 260px; + } +`; + +const App = () => { + const [skidding, setSkidding] = useState(0); + + return ( + <> +
+ + +
+
+ + setSkidding(event.target.value)} + /> +
+ + + + ); +}; +``` + ### Arrows Add an arrow to your popup with the `arrow` attribute. It's usually a good idea to set a `distance` to make room for the arrow. To adjust the arrow's color and size, use the `--arrow-color` and `--arrow-size` custom properties, respectively. You can also target the `arrow` part to add additional styles such as shadows and borders. @@ -332,6 +656,54 @@ Add an arrow to your popup with the `arrow` attribute. It's usually a good idea ``` +```jsx react +import { useState } from 'react'; +import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-arrow sl-popup { + --arrow-color: var(--sl-color-primary-600); + } + + .popup-arrow span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 50px; + } + + .popup-arrow .box { + width: 100px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } +`; + +const App = () => { + const [arrow, setArrow] = useState(true); + + return ( + <> +
+ + +
+ + +
+ setArrow(event.target.checked)}> + Arrow + +
+ + + + ); +}; +``` + ### Positioning Strategy By default, the popup is positioned using an absolute positioning strategy. However, if your anchor is fixed or exists within a container that has `overflow: auto|hidden`, the popup risks being clipped. To work around this, you can use a fixed positioning strategy by setting the `strategy` attribute to `fixed`. @@ -391,6 +763,62 @@ Toggle the switch and scroll the container to see the difference. ``` +```jsx react +import { useState } from 'react'; +import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-strategy .overflow { + position: relative; + height: 300px; + border: solid 2px var(--sl-color-neutral-200); + overflow: auto; + } + + .popup-strategy span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 150px 50px; + } + + .popup-strategy .box { + width: 100px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } + + .popup-strategy sl-switch { + margin-top: 1rem; + } +`; + +const App = () => { + const [fixed, setFixed] = useState(true); + + return ( + <> +
+
+ + +
+ +
+ + setFixed(event.target.value)}> + Fixed + +
+ + + + ); +}; +``` + ### Flip When the popup doesn't have enough room in its preferred placement, it can automatically flip to keep it in view. To enable this, use the `flip` attribute. By default, the popup will flip to the opposite placement, but you can configure preferred fallback placements using `flip-fallback-placement` and `flip-fallback-strategy`. Additional options are available to control the flip behavior's boundary and padding. @@ -405,6 +833,9 @@ Scroll the container to see how the popup flips to prevent clipping.
+ +
+ Flip
+ + +``` + +```jsx react +import { useState } from 'react'; +import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-flip .overflow { + position: relative; + height: 300px; + border: solid 2px var(--sl-color-neutral-200); + overflow: auto; + } + + .popup-flip span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 150px 50px; + } + + .popup-flip .box { + width: 100px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } +`; + +const App = () => { + const [flip, setFlip] = useState(true); + + return ( + <> +
+
+ + +
+ +
+ +
+ setFlip(event.target.checked)}> + Flip + +
+ + + + ); +}; ``` ### Shift @@ -482,6 +974,57 @@ Toggle the switch to see the difference. ``` +```jsx react +import { useState } from 'react'; +import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-shift .overflow { + position: relative; + border: solid 2px var(--sl-color-neutral-200); + overflow: auto; + } + + .popup-shift span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 60px 0 0 10px; + } + + .popup-shift .box { + width: 300px; + height: 50px; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } +`; + +const App = () => { + const [shift, setShift] = useState(true); + + return ( + <> +
+
+ + +
+ +
+ + setShift(event.target.checked)}> + Shift + +
+ + + + ); +}; +``` + ### Auto-size Use the `auto-size` attribute to tell the popup to resize when necessary to prevent it from overflowing. You can use `autoSizeBoundary` and `auto-size-padding` to customize the behavior of this option. @@ -498,6 +1041,9 @@ Scroll the container to see auto-size in action.
+ +
+ Auto-size
+ + +``` + +```jsx react +import { useState } from 'react'; +import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react'; + +const css = ` + .popup-auto-size .overflow { + position: relative; + height: 300px; + border: solid 2px var(--sl-color-neutral-200); + overflow: auto; + } + + .popup-auto-size span[slot='anchor'] { + display: inline-block; + width: 150px; + height: 150px; + border: dashed 2px var(--sl-color-neutral-600); + margin: 100px 50px 250px 50px; + } + + .popup-auto-size sl-popup::part(popup) { + width: 100px; + height: 200px; + } + + .popup-auto-size .box { + width: 100%; + height: 100%; + background: var(--sl-color-primary-600); + border-radius: var(--sl-border-radius-medium); + } +`; + +const App = () => { + const [autoSize, setAutoSize] = useState(true); + + return ( + <> +
+
+ + +
+ +
+ +
+ setAutoSize(event.target.checked)}> + Auto-size + +
+ + + + ); +}; ``` [component-metadata:sl-popup]