Commerce & auth
Sign Up
Multi-step capable user registration with strength telemetry
detent-sign-up
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 3
- Wave
- phase-3-data
- Group
- Commerce & auth
8.6 KB gzip for the class module
Variants
Sample data; nothing is fetched or sent. Type a password to see the four-tier strength meter, submit an empty form
to see the five inline role="alert" messages, and use either eye button to reveal a password. The
loading card disables submission and shows the spinner; the last card is shown with its two default-true flags
resolved (both stay on until the property opts out). All three events are composed and bubble.
Recorded states
focus-visiblerecorded state; no setterloadingrecorded state; no setter
Usage
Import
import '/components/sign-up/define.js';
// or register it yourself
import { DetentSignUp } from '/components/sign-up/sign-up.js';
Attributes
descriptionerroris-loadingrequire-confirm-passwordshow-social-sign-upsign-in-texttitle
Properties
onSignInClickonSocialSignUponSubmitformData
Slots
logoterms-text
Events
detent-submit— {}detent-sign-in-click— {}detent-social-sign-up— {}
Example
Runnable example: site/examples/sign-up.ts. The snippet below is generated from the catalogued attributes.
<detent-sign-up
description="Join Detent to access components and templates"
error
is-loading
require-confirm-password
show-social-sign-up
sign-in-text
title="Create an account"
></detent-sign-up>
Property-only values
const element = document.querySelector('detent-sign-up');
if (element !== null) {
// onSubmit: (data: SignUpFormData) => void
element.onSubmit = () => {};
// onSignInClick: () => void
element.onSignInClick = () => {};
}
Source
The pinned upstream source for this row:
src/components/ui/SignUp.tsxsha256 e24b677da41e…
Native files
The native module and its artifacts:
src/components/sign-up/sign-up.tssrc/components/sign-up/styles.csssrc/components/sign-up/define.tsdocs/components/sign-up.mdsite/examples/sign-up.tstests/browser/sign-up.spec.tsevidence/components/sign-up.md
API
Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.
Attributes
| Attribute | Property | Type | Default | Notes |
|---|---|---|---|---|
description | description | string | 'Join Detent to access components and templates' | Kebab-case attribute; camelCase property. |
error | error | string | null | null | Kebab-case attribute; camelCase property. |
is-loading | isLoading | boolean | false | Presence semantics: present means true, absent means false. |
require-confirm-password | requireConfirmPassword | boolean | true | Presence semantics: present means true, absent means false. |
show-social-sign-up | showSocialSignUp | boolean | true | Presence semantics: present means true, absent means false. |
sign-in-text | — | — | — | Recorded in the catalog as an attribute. |
title | title | string | 'Create an account' | Kebab-case attribute; camelCase property. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
onSignInClick | () => void | undefined | Property-only: assign from script; not accepted as an attribute. |
onSocialSignUp | — | — | Recorded in the catalog without a top-level type; pinned from source when the row is ported. |
onSubmit | (data: SignUpFormData) => void | undefined | Property-only: assign from script; not accepted as an attribute. |
formData | — | — | Recorded in the catalog without a top-level type; pinned from source when the row is ported. |
Events
| Event | Upstream prop | Payload type | Notes |
|---|---|---|---|
detent-submit | onSubmit | (data: SignUpFormData) => void | Composed, bubbles; fires only for a user action. |
detent-sign-in-click | onSignInClick | () => void | Composed, bubbles; fires only for a user action. |
detent-social-sign-up | onSocialSignUp | (provider: 'github' | 'google') => void | Composed, bubbles; fires only for a user action. |
Slots
| Slot | Notes |
|---|---|
logo | Consumer content; rendered through a slot, never re-created. |
terms-text | Consumer content; rendered through a slot, never re-created. |
CSS customisation
- React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
- React callback props become typed composed CustomEvents; programmatic state assignment emits none.
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- The sign-in affordance is always rendered (upstream renders it only when onSignInClick exists); the element always exposes detent-sign-in-click.
- show-social-sign-up and require-confirm-password default to true, are reflected while connected, and the property is the opt-out (presence semantics, PC-3.2).
- The error banner toggles hidden instead of unmounting, so the role="alert" region stays in the tree for reliable announcements.
- Framer Motion springs become CSS transitions; the submit spinner is a static glyph under prefers-reduced-motion: reduce.
- The field boundary uses #6b6b6b so it reaches the WCAG 1.4.11 3:1 non-text ratio; dividers keep the upstream hairline.
- The pinned card was one fixed dark panel because the source has no dark: variants; this port follows the theme tokens in both colour schemes, and --detent-sign-up-* custom properties still override every value.
- The terms links are associated with the required checkbox through aria-labelledby instead of being nested inside the label, so both links stay independently focusable (PC-12.6).
- A failed submit moves focus to the first invalid control (PC-12.6).
- The password-strength meter is role="status" with aria-live="polite" (PC-12.5).
- detail.data always carries confirmPassword, as the string "" when the confirmation field is hidden, matching the pinned source's unconditional argument.
- className is replaced by the documented CSS parts and custom properties; logos and the cloud glyph are local inline SVG, not lucide-react.
- ReactNode props become slots (logo, terms-text) with local fallbacks.
- Client-side validation only: the element never authenticates, stores or transmits credentials and makes no network request.
- Default demo copy and labels use Detent branding instead of EasyUI (pre-release rebrand).
What it does
A registration card: a slotted logo, title and description, an optional server-error banner, GitHub and Google SSO, a validated four-field form with two password visibility toggles, the live four-tier strength meter, the terms checkbox and the secondary sign-in action.
Upstream behaviour
- Integrated live 4-tier password strength indicator bar
- Password confirmation matching validation
- Interactive eye icons for show/hide password visibility
- Terms of service and privacy agreement checkbox validation
- Customizable social onboarding SSO buttons (GitHub & Google)
- Submitting state with monochrome button spinner
- Responsive layout with atmospheric glow and dark slate tokens
Differences from upstream
- React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
- React callback props become typed composed CustomEvents; programmatic state assignment emits none.
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- The sign-in affordance is always rendered (upstream renders it only when onSignInClick exists); the element always exposes detent-sign-in-click.
- show-social-sign-up and require-confirm-password default to true, are reflected while connected, and the property is the opt-out (presence semantics, PC-3.2).
- The error banner toggles hidden instead of unmounting, so the role="alert" region stays in the tree for reliable announcements.
- Framer Motion springs become CSS transitions; the submit spinner is a static glyph under prefers-reduced-motion: reduce.
- The field boundary uses #6b6b6b so it reaches the WCAG 1.4.11 3:1 non-text ratio; dividers keep the upstream hairline.
- The pinned card was one fixed dark panel because the source has no dark: variants; this port follows the theme tokens in both colour schemes, and --detent-sign-up-* custom properties still override every value.
- The terms links are associated with the required checkbox through aria-labelledby instead of being nested inside the label, so both links stay independently focusable (PC-12.6).
- A failed submit moves focus to the first invalid control (PC-12.6).
- The password-strength meter is role="status" with aria-live="polite" (PC-12.5).
- detail.data always carries confirmPassword, as the string "" when the confirmation field is hidden, matching the pinned source's unconditional argument.
- className is replaced by the documented CSS parts and custom properties; logos and the cloud glyph are local inline SVG, not lucide-react.
- ReactNode props become slots (logo, terms-text) with local fallbacks.
- Client-side validation only: the element never authenticates, stores or transmits credentials and makes no network request.
- Default demo copy and labels use Detent branding instead of EasyUI (pre-release rebrand).