Skip to main content

dioxus_clerk/components/
sign_up_button.rs

1use super::AuthButtonMode;
2use crate::options::SignUpOptions;
3use dioxus::prelude::*;
4
5/// Unstyled sign-up button that schedules the appropriate Clerk action.
6///
7/// This component renders a native `<button>` and treats `children` as button
8/// contents. For design-system buttons that own their own DOM element, call
9/// [`crate::use_clerk`] from the button's click handler instead.
10///
11/// Props cover the options Clerk's modal and redirect flows accept. Embedded
12/// UI options such as `routing`/`path` apply only to the mounted [`SignUp`]
13/// component, not to a button, so they are not exposed here.
14///
15/// [`SignUp`]: crate::SignUp
16///
17/// # Example
18///
19/// ```no_run
20/// use dioxus::prelude::*;
21/// use dioxus_clerk::*;
22///
23/// #[component]
24/// fn SignUpAction() -> Element {
25///     rsx! {
26///         SignUpButton { class: "btn btn-secondary", "Create account" }
27///     }
28/// }
29/// ```
30#[component]
31pub fn SignUpButton(
32    /// Whether to open a modal or redirect. Defaults to redirect for Clerk React parity.
33    #[props(default)]
34    mode: AuthButtonMode,
35    /// Full URL or path to the sign-in page used by Clerk's sign-up flow.
36    #[props(into)]
37    sign_in_url: Option<String>,
38    /// Full URL or path to the waitlist page used by Clerk's sign-up flow.
39    #[props(into)]
40    waitlist_url: Option<String>,
41    /// Always redirect here after sign-up.
42    #[props(into)]
43    force_redirect_url: Option<String>,
44    /// Fallback redirect URL after sign-up.
45    #[props(into)]
46    fallback_redirect_url: Option<String>,
47    /// Always redirect here after sign-in from sign-up.
48    #[props(into)]
49    sign_in_force_redirect_url: Option<String>,
50    /// Fallback redirect URL after sign-in from sign-up.
51    #[props(into)]
52    sign_in_fallback_redirect_url: Option<String>,
53    /// Raw Clerk initialValues object.
54    initial_values: Option<serde_json::Value>,
55    /// Raw Clerk appearance object.
56    appearance: Option<serde_json::Value>,
57    /// Advanced options forwarded to Clerk, as a
58    /// [`SignUpOptions`](crate::SignUpOptions) builder or a raw
59    /// `serde_json::Value`. Explicit props win when both set the same Clerk
60    /// option key.
61    #[props(default = SignUpOptions::from_value(serde_json::Value::Null), into)]
62    options: SignUpOptions,
63    /// Disable the generated `<button>`.
64    #[props(default)]
65    disabled: bool,
66    /// Attributes spread onto the generated `<button>` (`id`, `class`,
67    /// `title`, `aria-*`, `r#type`, ...). `r#type` defaults to `"button"` to
68    /// avoid accidental form submits.
69    #[props(extends = GlobalAttributes, extends = button)]
70    attributes: Vec<Attribute>,
71    /// Optional click handler, called before the Clerk action is scheduled
72    /// (matching Clerk React's ordering).
73    #[props(default, into)]
74    onclick: Callback<MouseEvent>,
75    /// Optional custom button contents. Defaults to `Sign up`.
76    #[props(default = rsx! { "Sign up" })]
77    children: Element,
78) -> Element {
79    let options = options
80        .maybe_sign_in_url(sign_in_url)
81        .maybe_waitlist_url(waitlist_url)
82        .maybe_force_redirect_url(force_redirect_url)
83        .maybe_fallback_redirect_url(fallback_redirect_url)
84        .maybe_sign_in_force_redirect_url(sign_in_force_redirect_url)
85        .maybe_sign_in_fallback_redirect_url(sign_in_fallback_redirect_url)
86        .maybe_initial_values(initial_values)
87        .maybe_appearance(appearance)
88        .into_value();
89
90    let clerk = crate::use_clerk();
91    super::button_host::button_host(
92        super::button_host::ButtonChrome {
93            attributes,
94            disabled,
95            onclick,
96            children,
97        },
98        move || match mode {
99            AuthButtonMode::Modal => clerk.open_sign_up_with_options(options.clone()),
100            AuthButtonMode::Redirect => clerk.redirect_to_sign_up_with_options(options.clone()),
101        },
102    )
103}