progressive-share-button 1.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 John Morton
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # Progressive Share Button
2
+
3
+ The _Progressive Share Button_ web component is a simple way to add a share button to your web page. The button will only be displayed if the browser supports the [Web Share API](https://w3c.github.io/web-share/).
4
+
5
+ The web component is a wrapper around the [Web Share API](https://w3c.github.io/web-share/) that attempts to display a share icon appropriate to the user's device with icons that will be recognizable to iOS/Mac, Android and Windows. If the device type can't be determined, the component will display a Windows share icon.
6
+
7
+ ## Limitations
8
+
9
+ The [Web Share API](https://w3c.github.io/web-share/), while still in draft, has wide support on mobile. Desktop support is decent on Windows. Mac support works in Safari, but lags on third-party browsers. Check [caniuse/web-share](https://caniuse.com/web-share) for the most up-to-date information on its progress.
10
+
11
+ The component will only display the share button if the browser supports the Web Share API. If the browser does not support the Web Share API, the component will not display anything.
12
+
13
+ _Progressive Share Button_ does not support the sharing of files.
14
+
15
+ ## Basic Usage
16
+
17
+ The most basic usage of the component is to pass the URL to be shared. The component will render a share icon that will open the native share dialog when clicked.
18
+
19
+ ```html
20
+ Basic Example: <progressive-share-button url="https://example.com" />
21
+ ```
22
+
23
+ This will render one of the following, depending on the device and browser. This example shows the Windows sharing icon, the Android sharing icon, and the iOS sharing icon.
24
+
25
+ ![Basic Example](./img/button-examples.png)
26
+
27
+ ## Installation as a module
28
+
29
+ Run the following command to install it.
30
+
31
+ ```bash
32
+ npm install progressive-share-button
33
+ ```
34
+
35
+ main.js, if installed with npm
36
+ ```javascript
37
+ import { ProgressiveShareButton } from 'progressive-share-button';
38
+ customElements.define('progressive-share-button', ProgressiveShareButton);
39
+ ```
40
+
41
+ ### CDN
42
+
43
+ https://unpkg.com/ info to come
44
+
45
+ ```html
46
+ <script src="https://unpkg.com/TBD/progressive-share-button"></script>
47
+ ```
48
+
49
+ ## Customizing the Component
50
+
51
+ The component accepts the following attributes:
52
+
53
+ | Attributes | Type | Default | Description |
54
+ | --- | --- | --- | --- |
55
+ | title | string | null | The title of the page to be shared. |
56
+ | text | string | null | The text string to be shared. |
57
+ | url | string | null | The URL to be shared. |
58
+ | smart-share | boolean | false | Accepts 0, false, 1, or true. If true, the component concatenate the title, text, and url into a single string. See the [_Why use smart-share_](#why-use-smart-share) section below for more information. |
59
+ | icon-size | string or int | 24 | The size of the SVG share icon. The icon is rendered in a square. If an integer is passed, the component assumes the value is given in pixels, 24 becomes "24px", but you may also pass a string with a valid CSS size, like "1rem". |
60
+ | debug | boolean | false | Accepts 0, false, 1, or true. If true is passed, the share icon will be displayed even if the Web Share API is not supported in the browser. The share behavior will *not* open the share dialog but, but instead will pass the data to be shared to the console for debugging. |
61
+ ## Styling
62
+
63
+ The component uses the [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) to encapsulate the styles. This means that the styles are not inherited by the parent page. To style the component, you must use the [::part()](https://developer.mozilla.org/en-US/docs/Web/CSS/::part) pseudo-element. There are two parts that can be styled: `shareButton` and `shareIcon`.
64
+
65
+ ### shareButton
66
+
67
+ The `shareButton` part is the button that is displayed when the Web Share API is supported. The button is a [button](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) element. The button has the following default styles:
68
+
69
+ ```css
70
+ button {
71
+ background: none;
72
+ border: none;
73
+ padding: 1px 2px 1px 2px;
74
+ margin: 0;
75
+ cursor: pointer;
76
+ }
77
+ ```
78
+
79
+ ### shareIcon
80
+
81
+ The `shareIcon` part is the icon that is displayed when the Web Share API is supported. The icon is an [svg](https://developer.mozilla.org/en-US/docs/Web/SVG) element. The icon has the following default styles:
82
+
83
+ ```css
84
+ svg {
85
+ width: 24px;
86
+ height: 24px;
87
+ fill: currentColor;
88
+ vertical-align: bottom;
89
+ }
90
+ ```
91
+
92
+ ## Usage Examples
93
+
94
+ ### Basic Usage
95
+
96
+ As shown earlier, the most basic usage of the component is to pass the URL to be shared.
97
+ ```
98
+ <progressive-share-button url="https://example.com" />
99
+ ```
100
+
101
+ ### Usage with Text
102
+
103
+ You can replace the share icon with text by inserting text into the component's slot. The following example replaces the share icon with the text "Share this link". The text is styled with the `text-share-example-1` class using using the [::part()](https://developer.mozilla.org/en-US/docs/Web/CSS/::part) pseudo-element named `shareButton`.
104
+
105
+ ```
106
+ <progressive-share-button url="https://example.com" class="text-share-example-1">Share this link</progressive-share-button>
107
+
108
+ <style>
109
+ progressive-share-button.text-share-example-1::part(shareButton) {
110
+ font-size: 1rem;
111
+ text-decoration: underline;
112
+ color: blue;
113
+ }
114
+ </style>
115
+ ```
116
+
117
+ ### Advanced Usage with Options
118
+
119
+ In the following example,
120
+
121
+ ```
122
+ <progressive-share-button
123
+ title="Progressive Share Button Web Component"
124
+ text="Check out this cool web component that creates a share button that will only be displayed if the browser supports the Web Share API."
125
+ url="https://example.com"
126
+ smart-share=1
127
+ icon-size="20"
128
+ debug=0
129
+ class="text-share-example-2"
130
+ />
131
+
132
+ <style>
133
+ progressive-share-button.text-share-example-2::part(shareIcon) {
134
+ font-size: 1rem;
135
+ text-decoration: underline;
136
+ color: blue;
137
+ }
138
+ ```
139
+
140
+ ## Why use smart-share
141
+
142
+ The Web Share API requires that the data to be shared be passed as an object with the following optional properties:
143
+
144
+ * title
145
+ * text
146
+ * url
147
+
148
+ The _Progressive Share Button_ web component by default simply passes your data to the Web Share API, like this:
149
+
150
+ ```
151
+ {
152
+ title: 'Example Page',
153
+ text: 'This is an example page.',
154
+ url: 'https://example.com'
155
+ }
156
+ ```
157
+
158
+ The problem is that when multiple properties are passed as separate properties what actually gets shared doesn't always include all the pieces of data you pass into the API. Some devices and applications receiving the data object will only share a single property, most often the URL in my tests.
159
+
160
+ If have `smart-share` set to true, the component will concatenate all of the data into a single string and pass it to the Web Share API as text. The `title` and `text` will have a period added at the end of the string if it is not present. This will allow the data to be shared on any device or application that supports sharing text. The data will be shared as a single string, like this:
161
+
162
+ ```
163
+ {
164
+ text: 'Example Page. This is an example page. https://example.com'
165
+ }
166
+ ```
167
+
168
+ The following link lets you test the Web Share API on your devices to make a more informed decision as to what option works best for your use case.
169
+
170
+ https://w3c.github.io/web-share/demos/share-files.html
171
+
172
+ ## Demo
173
+
174
+ Demo to come.
175
+
176
+ ~~[https://johnfmorton.github.io/progressive-share-button/](https://johnfmorton.github.io/progressive-share-button/)~~
177
+
178
+ ## License
179
+
180
+ MIT
181
+
182
+ ## Author
183
+
184
+ [John F. Morton](https://johnfmorton.com)
@@ -0,0 +1,82 @@
1
+ class g extends HTMLElement {
2
+ constructor() {
3
+ super(), this.attachShadow({ mode: "open" }), this.iconSize = () => {
4
+ const e = this.getAttribute("icon-size");
5
+ return i(e) ? e + "px" : e || 24 + "px";
6
+ };
7
+ function i(e) {
8
+ return /^-?\d+$/.test(e);
9
+ }
10
+ (navigator.share || c(this.getAttribute("debug"))) && (this.shadowRoot.innerHTML = `
11
+ <style>
12
+ :host {
13
+ display: inline-block;
14
+ cursor: pointer;
15
+ }
16
+ svg {
17
+ width: ${this.iconSize()};
18
+ height: ${this.iconSize()};
19
+ fill: currentColor;
20
+ vertical-align: bottom;
21
+ }
22
+ button {
23
+ background: none;
24
+ border: none;
25
+ padding: 1px 2px 1px 2px;
26
+ margin: 0;
27
+ cursor: pointer;
28
+ }
29
+ :host(:hover) {
30
+ }
31
+ </style>
32
+ <button part="shareButton">
33
+ <slot>
34
+ ${d()}
35
+ </slot>
36
+ </button>
37
+ `, this.addEventListener("click", this.share));
38
+ }
39
+ share() {
40
+ const i = c(this.getAttribute("debug")), e = c(this.getAttribute("smart-share")), n = this.getAttribute("url");
41
+ let s = this.getAttribute("text"), r = this.getAttribute("title"), o = {};
42
+ n && (o.url = n), s && (o.text = s), r && (o.title = r), e && (r && r.slice(-1) !== "." && (r = r + "."), s && s.slice(-1) !== "." && (s = s + "."), o = {
43
+ text: `${r ? r + " " : ""}${s ? s + " " : ""}${n || ""}`
44
+ }), navigator.share ? i == 1 ? console.debug("data to be shared", o) : navigator.share(o).then(() => {
45
+ console.log("Thanks for sharing!");
46
+ }).catch(console.error) : console.debug("data to be shared", o);
47
+ }
48
+ }
49
+ const h = () => '<svg xmlns="http://www.w3.org/2000/svg" part="shareIcon" viewBox="0 0 84.53 108.43" class="icon"><title>Share icon</title><desc>Square with upward arrow</desc><path d="m76.21,33.15h-23.38v5.28h23.38c1.72,0,3.04,1.32,3.04,2.91v58.77c0,1.58-1.32,2.91-3.04,2.91H8.32c-1.72,0-3.04-1.32-3.04-2.9v-58.64c0-1.58,1.32-2.91,3.04-2.91h20.74v-5.28H8.32c-4.62,0-8.32,3.7-8.32,8.19v58.77c0,4.49,3.7,8.19,8.32,8.19h67.88c4.62,0,8.32-3.7,8.32-8.19v-58.77c0-4.62-3.7-8.32-8.32-8.32h0Z"/><path d="m39.62,8.58v69.21h5.28V8.58l13.6,10.04,3.17-4.23L42.26,0l-19.41,14.4,3.17,4.23,13.6-10.04Z"/></svg>', l = () => '<svg id="b" xmlns="http://www.w3.org/2000/svg" part="shareIcon" viewBox="0 0 18.19 21.46" class="icon"><title>Share icon</title><desc>Circle with smaller circles radiating out</desc><g id="c"><path d="m15.1,15.29c-.89,0-1.7.38-2.28.98l-6.98-3.84c.24-.43.38-.94.38-1.49s-.14-1.03-.38-1.49l7.22-4.03c.55.48,1.25.77,2.04.77,1.7,0,3.1-1.39,3.1-3.1s-1.39-3.1-3.1-3.1-3.1,1.39-3.1,3.1c0,.67.22,1.27.58,1.78l-7.18,4.01c-.58-.62-1.39-1.03-2.3-1.03-1.7,0-3.1,1.39-3.1,3.1s1.39,3.1,3.1,3.1c.91,0,1.73-.41,2.3-1.03l6.98,3.84c-.26.46-.41.96-.41,1.51,0,1.7,1.39,3.1,3.1,3.1s3.1-1.39,3.1-3.1-1.37-3.07-3.07-3.07h0Zm0-14.54c1.32,0,2.38,1.08,2.38,2.38s-1.08,2.38-2.38,2.38-2.38-1.08-2.38-2.38,1.06-2.38,2.38-2.38ZM3.1,13.32c-1.32,0-2.38-1.08-2.38-2.38s1.08-2.38,2.38-2.38,2.38,1.08,2.38,2.38-1.06,2.38-2.38,2.38Zm12,7.44c-1.32,0-2.38-1.08-2.38-2.38s1.08-2.38,2.38-2.38,2.38,1.08,2.38,2.38-1.08,2.38-2.38,2.38Z"/></g></svg>', a = () => '<svg id="b" xmlns="http://www.w3.org/2000/svg" part="shareIcon" viewBox="0 0 112.98 100.64" class="icon" ><title>Share icon</title><desc>Square with arrow coming out to the right</desc><g id="c"><path d="m80.68,16.3l22.7,22.65-22.7,22.64v-11.44h-6.78c-18.27,0-33.35,6.91-43.25,13.14,2.34-12.07,7.94-21.2,16.75-27.16,10.12-6.84,22.02-7.83,26.67-7.94l6.6-.15v-11.73M73.93,0v21.43c-12.15.29-51.56,5.17-51.27,56.46,0,0,21.02-20.94,51.27-20.98v20.98l39.05-38.98L73.93,0ZM0,28.24v72.39h86.95v-20.98l-6.6,6.61v7.26H8.12V28.24H0Z"/></g></svg>', u = () => {
50
+ const t = navigator.userAgent;
51
+ return /iPhone|iPad|iPod/.test(t) ? "iOS" : /Android/.test(t) ? "Android" : /_whichIcon/.test(t) ? "Windows" : /Mac/.test(t) ? "Mac" : "Unknown";
52
+ }, d = (t) => {
53
+ switch (u()) {
54
+ case "iOS":
55
+ case "Mac":
56
+ return h();
57
+ case "Android":
58
+ return l();
59
+ case "Windows":
60
+ return a();
61
+ default:
62
+ return a();
63
+ }
64
+ };
65
+ function c(t) {
66
+ var i;
67
+ switch ((i = t == null ? void 0 : t.toLowerCase()) == null ? void 0 : i.trim()) {
68
+ case "true":
69
+ case "1":
70
+ return !0;
71
+ case "false":
72
+ case "0":
73
+ case null:
74
+ case void 0:
75
+ return !1;
76
+ default:
77
+ return JSON.parse(t);
78
+ }
79
+ }
80
+ export {
81
+ g as default
82
+ };
@@ -0,0 +1,28 @@
1
+ (function(o,c){typeof exports=="object"&&typeof module<"u"?module.exports=c():typeof define=="function"&&define.amd?define(c):(o=typeof globalThis<"u"?globalThis:o||self,o["progressive-share-button"]=c())})(this,function(){"use strict";class o extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this.iconSize=()=>{const e=this.getAttribute("icon-size");return i(e)?e+"px":e||24+"px"};function i(e){return/^-?\d+$/.test(e)}(navigator.share||h(this.getAttribute("debug")))&&(this.shadowRoot.innerHTML=`
2
+ <style>
3
+ :host {
4
+ display: inline-block;
5
+ cursor: pointer;
6
+ }
7
+ svg {
8
+ width: ${this.iconSize()};
9
+ height: ${this.iconSize()};
10
+ fill: currentColor;
11
+ vertical-align: bottom;
12
+ }
13
+ button {
14
+ background: none;
15
+ border: none;
16
+ padding: 1px 2px 1px 2px;
17
+ margin: 0;
18
+ cursor: pointer;
19
+ }
20
+ :host(:hover) {
21
+ }
22
+ </style>
23
+ <button part="shareButton">
24
+ <slot>
25
+ ${g()}
26
+ </slot>
27
+ </button>
28
+ `,this.addEventListener("click",this.share))}share(){const i=h(this.getAttribute("debug")),e=h(this.getAttribute("smart-share")),a=this.getAttribute("url");let s=this.getAttribute("text"),r=this.getAttribute("title"),n={};a&&(n.url=a),s&&(n.text=s),r&&(n.title=r),e&&(r&&r.slice(-1)!=="."&&(r=r+"."),s&&s.slice(-1)!=="."&&(s=s+"."),n={text:`${r?r+" ":""}${s?s+" ":""}${a||""}`}),navigator.share?i==1?console.debug("data to be shared",n):navigator.share(n).then(()=>{console.log("Thanks for sharing!")}).catch(console.error):console.debug("data to be shared",n)}}const c=()=>'<svg xmlns="http://www.w3.org/2000/svg" part="shareIcon" viewBox="0 0 84.53 108.43" class="icon"><title>Share icon</title><desc>Square with upward arrow</desc><path d="m76.21,33.15h-23.38v5.28h23.38c1.72,0,3.04,1.32,3.04,2.91v58.77c0,1.58-1.32,2.91-3.04,2.91H8.32c-1.72,0-3.04-1.32-3.04-2.9v-58.64c0-1.58,1.32-2.91,3.04-2.91h20.74v-5.28H8.32c-4.62,0-8.32,3.7-8.32,8.19v58.77c0,4.49,3.7,8.19,8.32,8.19h67.88c4.62,0,8.32-3.7,8.32-8.19v-58.77c0-4.62-3.7-8.32-8.32-8.32h0Z"/><path d="m39.62,8.58v69.21h5.28V8.58l13.6,10.04,3.17-4.23L42.26,0l-19.41,14.4,3.17,4.23,13.6-10.04Z"/></svg>',u=()=>'<svg id="b" xmlns="http://www.w3.org/2000/svg" part="shareIcon" viewBox="0 0 18.19 21.46" class="icon"><title>Share icon</title><desc>Circle with smaller circles radiating out</desc><g id="c"><path d="m15.1,15.29c-.89,0-1.7.38-2.28.98l-6.98-3.84c.24-.43.38-.94.38-1.49s-.14-1.03-.38-1.49l7.22-4.03c.55.48,1.25.77,2.04.77,1.7,0,3.1-1.39,3.1-3.1s-1.39-3.1-3.1-3.1-3.1,1.39-3.1,3.1c0,.67.22,1.27.58,1.78l-7.18,4.01c-.58-.62-1.39-1.03-2.3-1.03-1.7,0-3.1,1.39-3.1,3.1s1.39,3.1,3.1,3.1c.91,0,1.73-.41,2.3-1.03l6.98,3.84c-.26.46-.41.96-.41,1.51,0,1.7,1.39,3.1,3.1,3.1s3.1-1.39,3.1-3.1-1.37-3.07-3.07-3.07h0Zm0-14.54c1.32,0,2.38,1.08,2.38,2.38s-1.08,2.38-2.38,2.38-2.38-1.08-2.38-2.38,1.06-2.38,2.38-2.38ZM3.1,13.32c-1.32,0-2.38-1.08-2.38-2.38s1.08-2.38,2.38-2.38,2.38,1.08,2.38,2.38-1.06,2.38-2.38,2.38Zm12,7.44c-1.32,0-2.38-1.08-2.38-2.38s1.08-2.38,2.38-2.38,2.38,1.08,2.38,2.38-1.08,2.38-2.38,2.38Z"/></g></svg>',l=()=>'<svg id="b" xmlns="http://www.w3.org/2000/svg" part="shareIcon" viewBox="0 0 112.98 100.64" class="icon" ><title>Share icon</title><desc>Square with arrow coming out to the right</desc><g id="c"><path d="m80.68,16.3l22.7,22.65-22.7,22.64v-11.44h-6.78c-18.27,0-33.35,6.91-43.25,13.14,2.34-12.07,7.94-21.2,16.75-27.16,10.12-6.84,22.02-7.83,26.67-7.94l6.6-.15v-11.73M73.93,0v21.43c-12.15.29-51.56,5.17-51.27,56.46,0,0,21.02-20.94,51.27-20.98v20.98l39.05-38.98L73.93,0ZM0,28.24v72.39h86.95v-20.98l-6.6,6.61v7.26H8.12V28.24H0Z"/></g></svg>',d=()=>{const t=navigator.userAgent;return/iPhone|iPad|iPod/.test(t)?"iOS":/Android/.test(t)?"Android":/_whichIcon/.test(t)?"Windows":/Mac/.test(t)?"Mac":"Unknown"},g=t=>{switch(d()){case"iOS":case"Mac":return c();case"Android":return u();case"Windows":return l();default:return l()}};function h(t){var i;switch((i=t==null?void 0:t.toLowerCase())==null?void 0:i.trim()){case"true":case"1":return!0;case"false":case"0":case null:case void 0:return!1;default:return JSON.parse(t)}}return o});
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "progressive-share-button",
3
+ "version": "1.0.0-alpha.1",
4
+ "description": "A web componet that creates a OS-native share button.",
5
+ "files":["dist"],
6
+ "main":"./dist/progressive-share-button.umd.js",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/johnfmorton/progressive-share-button"
10
+ },
11
+ "module":"./dist/progressive-share-button.es.js",
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/progressive-share-button.es.js",
15
+ "require": "./dist/progressive-share-button.umd.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "dev": "vite --host 0.0.0.0 --port 8888",
20
+ "build": "vite build",
21
+ "preview": "vite preview",
22
+ "test": "echo \"Error: no test specified\" && exit 1"
23
+ },
24
+ "keywords": [
25
+ "share",
26
+ "button",
27
+ "progressive",
28
+ "web-components",
29
+ "web-share-api"
30
+ ],
31
+ "author": "John F. Morton <john@johnfmorton.com> (https://supergeekery.com)",
32
+ "license": "MIT",
33
+ "devDependencies": {
34
+ "vite": "^4.1.3"
35
+ }
36
+ }