Share Button
Accessible, unstyled Web Share button primitive.
| Package | @vizejs/ui/share-button |
| Maturity | stable |
| Own the source | vize lib pull share-button |
| Requires | — |
| Aliases | share button, web share button, share action, share control |
| Covers | Web Share API, React Aria Button, WAI-ARIA Button |
Usage
import { ShareButton } from "@vizejs/ui/share-button";
Or copy the source into your project with vize lib pull share-button (see Source Distribution).
API
ShareButton
Source: src/families/actions/share-button/share-button.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as |
PrimitiveAs |
"button" |
Native element, custom element, or component to render. |
native |
boolean |
true when |
Whether the rendered target already implements native button semantics. |
type |
ShareButtonType |
"button" |
Native button submission behavior. |
disabled |
boolean |
false |
Remove the control from activation and sequential keyboard focus. |
title |
string |
undefined |
Optional share title. |
text |
string |
undefined |
Optional share body text. |
url |
string |
undefined |
Optional URL to share. |
files |
File[] |
undefined |
Optional files to share when the platform supports file sharing. |
idleLabel |
string |
"Share" |
Idle fallback text rendered when no default slot is supplied. |
sharingLabel |
string |
"Sharing" |
Busy fallback text rendered while the configured action is pending. |
sharedLabel |
string |
"Shared" |
Success fallback text rendered when no default slot is supplied. |
errorLabel |
string |
"Share failed" |
Failure fallback text rendered when no default slot is supplied. |
ariaLabel |
string |
undefined |
Accessible name when no visible label or aria-labelledby supplies one. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label the button. |
ariaDescribedby |
string |
undefined |
Space-separated ids that describe the button. |
action |
ShareButtonAction |
navigator.share |
Test, platform, or product hook for sharing. |
Events
| Event | Payload | Description |
|---|---|---|
share |
[payload: ShareButtonPayload, nativeEvent: MouseEvent] |
Fired after the submitted share action completes. |
error |
[error: unknown, payload: ShareButtonPayload, nativeEvent: MouseEvent] |
Fired after the submitted share action throws or rejects. |
Slots
| Slot | Slot props | Description |
|---|---|---|
default |
ShareButtonSlotState |
Renders button contents with the current share state. |
Exposed
| Member | Type | Description |
|---|---|---|
payload |
ShareButtonPayload |
Payload captured for the next activation. |
disabled |
boolean |
Whether the control suppresses user activation. |
sharing |
boolean |
Whether an async share action is already in flight. |
unavailable |
boolean |
Whether activation is currently unavailable. |
state |
ShareButtonState |
Stable share lifecycle token for styling and tests. |
label |
string |
Resolved fallback text for the current state. |
element |
ShareButtonElement | null |
Rendered root element or component instance. |
focus |
(options?: FocusOptions) => void |
Move focus to the rendered control. |
Behavior
Normative state and input outcome table for share-button.vue.
| ID | Scenario | Behavior | Assertion |
|---|---|---|---|
| S1 | native render | renders a native button with type="button", part="root", label part, idle state, and no styling |
renders deterministic native button semantics and default label |
| S2 | non-native activation | non-native hosts expose button semantics and emulate native Enter/Space timing | non-native hosts preserve keyboard button activation |
| S3 | default share | activation calls navigator.share with the normalized submitted payload when available |
uses navigator.share by default |
| S4 | unavailable platform | missing Web Share support emits a stable unavailable error payload without throwing from activation | emits a stable error when navigator.share is unavailable |
| S5 | injected action | activation runs the captured action with title, text, url, files, and the triggering mouse event | runs the configured action and exposes shared state |
| S6 | rejected action | catches action failures, emits error with the submitted payload, and exposes data-state="error" |
captures action failures without throwing out of activation |
| S7 | disabled | native and non-native disabled states suppress activation without emitting share lifecycle events | disabled share buttons suppress actions and keep availability hooks |
| S8 | duplicate activation | sharing state sets busy hooks and suppresses duplicate actions | suppresses duplicate actions while sharing is in flight |
| S9 | submitted payload | an in-flight operation completes against the action and payload captured at activation time | uses the submitted action and payload when props change |
| S10 | labels and slots | label props and default slot receive the same strict idle | sharing | shared | error state |
supports custom labels and slot rendering |
| S11 | public instance | exposes live state, sharing, unavailable, payload, element, label, and focus() |
exposes live state and focus |
| S12 | SSR and hydration | setup never touches browser globals or Web Share APIs; markup is stable and hydrates without warnings | share-button-ssr.test.ts and runtime conformance fixtures |
Contract
ShareButton is a headless action primitive for Web Share payloads. The default
action calls navigator.share(payload) only after the user activates the
control, and the action may be injected for tests, SSR, or product-specific
behavior. Component setup, server rendering, and hydration do not touch
navigator, window, document, timers, or Web Share APIs.
The lifecycle state is closed to idle, sharing, shared, and error.
The submitted action and normalized payload are captured before the async
operation starts, so prop changes while sharing do not affect completion emits.
Duplicate activation is suppressed while sharing, but the rendered control
remains focusable unless it is explicitly disabled.
The rendered DOM exposes part="root" on the host and part="label" on the
fallback label span. Stable selectors are data-vize-ui="share-button" and
data-vize-ui="share-button-label". Styling hooks are data attributes and
ARIA state only: data-state, data-sharing, data-disabled, aria-busy,
and aria-disabled. No CSS classes, runtime styles, CSS custom properties, or
share payload data attributes are emitted; all visual styling remains
consumer-owned.