summaryrefslogtreecommitdiff
path: root/src/components/ShareArrowButton.svelte
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /src/components/ShareArrowButton.svelte
init commit
Diffstat (limited to 'src/components/ShareArrowButton.svelte')
-rw-r--r--src/components/ShareArrowButton.svelte90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/components/ShareArrowButton.svelte b/src/components/ShareArrowButton.svelte
new file mode 100644
index 0000000..7b822fc
--- /dev/null
+++ b/src/components/ShareArrowButton.svelte
@@ -0,0 +1,90 @@
+<script lang="ts" context="module">
+ export function isShareSupported() {
+ return (
+ typeof navigator !== 'undefined' &&
+ typeof navigator.share === 'function'
+ );
+ }
+</script>
+
+<script lang="ts">
+ import SFSymbol from '~/components/SFSymbol.svelte';
+ import { getI18n } from '~/stores/i18n';
+
+ export let url: string;
+ export let withLabel: boolean = false;
+
+ const i18n = getI18n();
+
+ $: isShareSheetOpen = false;
+
+ async function handleShareClick() {
+ isShareSheetOpen = !isShareSheetOpen;
+
+ try {
+ await navigator.share({ url });
+ isShareSheetOpen = false;
+ } catch {
+ isShareSheetOpen = false;
+ }
+ }
+</script>
+
+<button
+ on:click={handleShareClick}
+ aria-label={$i18n.t('ASE.Web.AppStore.Share.Button.AccessibilityValue')}
+ class:active={isShareSheetOpen}
+ class:with-label={withLabel}
+>
+ <SFSymbol name="square.and.arrow.up" ariaHidden={true} />
+
+ {#if withLabel}
+ {$i18n.t('ASE.Web.AppStore.Share.Button.Value')}
+ {/if}
+</button>
+
+<style lang="scss">
+ button {
+ position: relative;
+ z-index: 2;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ width: var(--share-arrow-size, 32px);
+ height: var(--share-arrow-size, 32px);
+ border-radius: var(--share-arrow-size, 32px);
+ background: var(--systemQuaternary-onDark);
+ transition: background-color 210ms ease-out;
+ mix-blend-mode: plus-lighter;
+ }
+
+ button.with-label {
+ display: flex;
+ align-items: center;
+ width: auto;
+ padding: 0 16px;
+ gap: 8px;
+ font: var(--body-emphasized);
+
+ :global(svg) {
+ height: 16px;
+ width: auto;
+ top: -2px;
+ position: relative;
+ }
+ }
+
+ button.active,
+ button:hover {
+ // stylelint-disable color-function-notation
+ background-color: rgb(from var(--systemTertiary-onDark) r g b/.13);
+ // stylelint-enable color-function-notation
+ }
+
+ button :global(svg) {
+ width: 37%;
+ fill: var(--systemPrimary-onDark);
+ overflow: visible;
+ }
+</style>