Web Share
Demonstration
Code
<div class="c-web-share "> <div class="c-web-share__wrap"> <!--{ Desktop Viewport Copy-to-clipboard Button }--> <!--{ @data-js Initializes the copy-to-clipboard utility }--> <!--{ @data-copy Identifies the target of the content to copy }--> <!--{ @aria-pressed Will signify a pressed state to screen readers }--> <button aria-pressed="false" class="btn btn-small btn-primary mie-1 hidden tablet:inline-flex" data-copy="web-share-url" data-js="copy"> <svg class="icon icon-ui"> <use data-js-copy="icon" href="#lucide-copy"></use> </svg> <span> <!--{ @class "sr-only" visually hides more descriptive text for screen readers }--> <span class="sr-only">Press to </span>Copy link <!--{ @class "sr-only" visually hides more descriptive text for screen readers }--> <span class="sr-only"> and share</span> </span> </button> <!--{ @data-js "web-share" initalizes the Web Share Component. Falls back to using the Toggle Utility to display the sharing menu }--> <!--{ @data-web-share Data attribute for holding data sent to the navigator.share() method. Note, in the Markup quotes are escaped as """ however, they must be regular quotes; "". Inspect the source of the Demostration to see the real example }--> <!--{ @aria-controls Targets the Web Share fallback }--> <!--{ @aria-expanded Indicates if the Web Share fallback is open or not }--> <button aria-controls="aria-c-web-share-fallback-cfd269cc20b8c" aria-expanded="false" class="btn btn-small btn-primary" data-js="web-share" data-web-share="{"title":"Web Share","text":"What users should say about this.","url":"https://nycopportunity.github.io/standard/web-share"}"> <svg class="c-web-share__icon icon-ui"> <use href="#lucide-share-2"></use> </svg> <span>Share <!--{ @class "sr-only" visually hides more descriptive text for screen readers }--> <span class="sr-only"> this page</span> </span> </button> </div> <!--{ Web Share Fallback }--> <!--{ @id Toggle target of the web share button. Must match the "aria-controls" attribute of the toggling button }--> <!--{ @role Indicates an area of significance }--> <!--{ @class Add "hidden" to hide the fallback. Add a z-index utility, such as "z-30" to position the fallback over other elements }--> <!--{ @aria-hidden Hides content from assistive technology }--> <div aria-hidden="true" class="c-web-share__fallback hidden z-30" id="aria-c-web-share-fallback-cfd269cc20b8c" role="region"> <div class="c-web-share__fallback-body"> <div class="flex mb-2 items-center flex-row-reverse"> <!--{ @data-js data-js="web-share" designates this element as a toggling element for the dropdown }--> <!--{ @aria-controls Targets the element that will be shown and hidden by the toggle }--> <!--{ @aria-expanded Indicates if the dropdown is open or not }--> <!--{ @data-dialog data-dialog="close" designates this element as the primary close toggle for the dropdown. It will be focused on when the dropdown is opened. Only one close toggle associated with this aria-controls value can exist on the page }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <button aria-controls="aria-c-web-share-fallback-cfd269cc20b8c" aria-expanded="false" class="link-icon m-0" data-js="web-share" tabindex="-1"> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <svg aria-hidden="true" class="icon-ui" tabindex="-1"> <use href="#lucide-x"></use> </svg> <span>Close</span> </button> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <label class="c-web-share__label flex-1" for="web-share-url" tabindex="-1">Link to share</label> </div> <div class="c-web-share__input input"> <!--{ Copy-to-clipboard Content }--> <!--{ @data-copy-target Identifies the input as the target of the copy button }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <input data-copy-target="web-share-url" id="web-share-url" name="web-share-url" tabindex="-1" type="text" value="https://nycopportunity.github.io/standard/web-share" /> </div> <div class="c-web-share__items"> <!--{ Copy-to-clipboard Button }--> <!--{ @data-js Initializes the copy-to-clipboard utility }--> <!--{ @data-copy Identifies the target of the content to copy }--> <!--{ @aria-pressed Will signify a pressed state to screen readers }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <button aria-pressed="false" class="c-web-share__item c-web-share__copy btn btn-small btn-primary mx-0" data-copy="web-share-url" data-js="copy" tabindex="-1"> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <svg class="icon icon-ui" tabindex="-1"> <use data-js-copy="icon" href="#lucide-copy"></use> </svg> <span> <!--{ @class "sr-only" visually hides more descriptive text for screen readers }--> <span class="sr-only">Press to </span>Copy link </span> </button> <!--{ Facebook Sharer }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <a class="c-web-share__item btn btn-small btn-primary mx-0" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fnycopportunity.github.io%2Fstandard%2Fweb-share" tabindex="-1" target="_blank"> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <svg class="icon-ui" tabindex="-1"> <use href="#lucide-facebook"></use> </svg> <span> <!--{ @class "sr-only" visually hides more descriptive text for screen readers }--> <span class="sr-only">Share to </span>Facebook </span> </a> <!--{ Twitter Tweet }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <a class="c-web-share__item btn btn-small btn-primary mx-0" href="https://twitter.com/intent/tweet?text=What%20users%20should%20say%20about%20this.%20https%3A%2F%2Fnycopportunity.github.io%2Fstandard%2Fweb-share" tabindex="-1" target="_blank"> <svg class="icon-ui" tabindex="-1"> <use href="#lucide-twitter"></use> </svg> <span> <!--{ @class "sr-only" visually hides more descriptive text for screen readers }--> <span class="sr-only">Share to </span>Twitter </span> </a> </div> </div> </div> </div>
The Web Share is a small button that invokes the Web Share API a browser utility that allows users to copy the URL to their clipboard or share on the social network platform of their choice. For browsers that do not support the Web Share API (refer to the Browser compatibility table), a fallback element is displayed to allow users to copy the link, share on Facebook, or share on Twitter.
Because some desktop browsers do not support copying to the clipboard in the Web Share dialog, the copy-to-clipboard button is shown next to the share button in desktop viewports.
Demonstration
Code
<!--{ Web Share Fallback }--> <!--{ @id Toggle target of the web share button. Must match the "aria-controls" attribute of the toggling button }--> <!--{ @role Indicates an area of significance }--> <!--{ @class Add "hidden" to hide the fallback. Add a z-index utility, such as "z-30" to position the fallback over other elements }--> <!--{ @aria-hidden Hides content from assistive technology }--> <div aria-hidden="true" class="c-web-share__fallback static" id="aria-c-web-share-fallback-52d19b3b4d135" role="region"> <div class="c-web-share__fallback-body"> <div class="flex mb-2 items-center flex-row-reverse"> <!--{ @data-js data-js="web-share" designates this element as a toggling element for the dropdown }--> <!--{ @aria-controls Targets the element that will be shown and hidden by the toggle }--> <!--{ @aria-expanded Indicates if the dropdown is open or not }--> <!--{ @data-dialog data-dialog="close" designates this element as the primary close toggle for the dropdown. It will be focused on when the dropdown is opened. Only one close toggle associated with this aria-controls value can exist on the page }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <button aria-controls="aria-c-web-share-fallback-52d19b3b4d135" aria-expanded="false" class="link-icon m-0" data-js="web-share"> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <svg aria-hidden="true" class="icon-ui"> <use href="#lucide-x"></use> </svg> <span>Close</span> </button> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <label class="c-web-share__label flex-1" for="web-share-url">Link to share</label> </div> <div class="c-web-share__input input"> <!--{ Copy-to-clipboard Content }--> <!--{ @data-copy-target Identifies the input as the target of the copy button }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <input data-copy-target="web-share-url" id="web-share-url" name="web-share-url" type="text" value="https://nycopportunity.github.io/standard/web-share#web-share-fallback" /> </div> <div class="c-web-share__items"> <!--{ Copy-to-clipboard Button }--> <!--{ @data-js Initializes the copy-to-clipboard utility }--> <!--{ @data-copy Identifies the target of the content to copy }--> <!--{ @aria-pressed Will signify a pressed state to screen readers }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <button aria-pressed="false" class="c-web-share__item c-web-share__copy btn btn-small btn-primary mx-0" data-copy="web-share-url" data-js="copy"> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <svg class="icon icon-ui"> <use data-js-copy="icon" href="#lucide-copy"></use> </svg> <span> <!--{ @class "sr-only" visually hides more descriptive text for screen readers }--> <span class="sr-only">Press to </span>Copy link </span> </button> <!--{ Facebook Sharer }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <a class="c-web-share__item btn btn-small btn-primary mx-0" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fnycopportunity.github.io%2Fstandard%2Fweb-share%23web-share-fallback" target="_blank"> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <svg class="icon-ui"> <use href="#lucide-facebook"></use> </svg> <span> <!--{ @class "sr-only" visually hides more descriptive text for screen readers }--> <span class="sr-only">Share to </span>Facebook </span> </a> <!--{ Twitter Tweet }--> <!--{ @tabindex Set the tabindex to '-1' on focusable elements if this area is hidden when the page is rendered }--> <a class="c-web-share__item btn btn-small btn-primary mx-0" href="https://twitter.com/intent/tweet?text=What%20users%20should%20say%20about%20this.%20https%3A%2F%2Fnycopportunity.github.io%2Fstandard%2Fweb-share%23web-share-fallback" target="_blank"> <svg class="icon-ui"> <use href="#lucide-twitter"></use> </svg> <span> <!--{ @class "sr-only" visually hides more descriptive text for screen readers }--> <span class="sr-only">Share to </span>Twitter </span> </a> </div> </div> </div>
The web share fallback is a dialog that displays the URL to be shared with the copy-to-clipboard button and button links to share on Facebook or Twitter. It will only be visible to users using a browser that does not support the Web Share API. The example below uses the static
class to show the fallback. To hide the fallback, use the hidden
class in the code example above.
The fallback uses the Patterns Scripts
Toggle Utility to show and hide the dialog. Potentially focusable elements must have their tabindex
set to -1
to hide them from screen readers before the dialog opens.
The fallback is positioned absolutely by default without an initial z-index. It may need its z-index set using a CSS utility to ensure it displays over other elements. For example, z-30
.
Global Script
The Web Share requires JavaScript for calling the navigator.share()
API in supported browsers and showing/hiding the fallback for unsupported browsers. It also uses the Patterns Scripts
Copy Utility for the copy-to-clipboard button and the Toggle Utility to show and hide the fallback component. To use the Web Share through the global script use the following code:
<script src="@nycopportunity/standard/dist/js/default.js"></script> <script> var Standard = new Default(); Standard.webShare(); Standard.copy(); </script>
This will instantiate the Web Share and fallback element.
Module Import
The Web Share source exists in the Patterns Scripts utility library, which is a dependency of this library. This method allows the specification of a callback method for a successful share and the fallback method. The Toggle
and Copy
modules are optional but required for the fallback in the demo.
import WebShare from '@nycopportunity/pttrn-scripts/src/web-share/web-share'; import Toggle from '@nycopportunity/pttrn-scripts/src/utilities/toggle/toggle'; import Copy from '@nycopportunity/pttrn-scripts/src/utilities/copy/copy'; new WebShare({ callback: () => { // Designate an optional callback function for a successful share here }, fallback: () => { new Toggle({ selector: WebShare.selector }); } }); new Copy();
Configuration
The WebShare()
accepts an object with the following attributes:
Attribute | Description |
---|---|
selector
|
An alternate selector to the default [data-js*="web-share"]
|
callback
|
A callback function executed on a successful share. |
fallback
|
A fallback function executed when the browser does not support navigator.share() . |