@sublimee/auth-ui 0.1.1 → 0.1.12

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/AI_INDEX.md ADDED
@@ -0,0 +1,64 @@
1
+ # @sublimee/auth-ui AI Index
2
+
3
+ Token-efficient entry point for AI agents reading the installed npm package.
4
+
5
+ ## Use This Package For
6
+
7
+ - ready-to-use OAuth buttons,
8
+ - built-in button motion and loading,
9
+ - token-driven button customization without rebuilding base styling.
10
+
11
+ ## First Move
12
+
13
+ ```tsx
14
+ import "@sublimee/tokens/tokens.css";
15
+ import { OAuthButton } from "@sublimee/auth-ui";
16
+
17
+ <OAuthButton provider="google" />
18
+ ```
19
+
20
+ ## Current Public Surface
21
+
22
+ - `OAuthButton`
23
+ - `GoogleIcon`
24
+ - `DiscordIcon`
25
+ - `useButtonAnimation`
26
+
27
+ Current providers:
28
+ - `google`
29
+ - `discord`
30
+
31
+ ## Important Defaults
32
+
33
+ - built on `@base-ui/react/button`
34
+ - default variant: `secondary`
35
+ - default animation: `press`
36
+ - loading is built in
37
+ - default loading animation: `spinner`
38
+ - runtime button styles are included automatically
39
+
40
+ ## Key Props
41
+
42
+ - `provider`
43
+ - `variant`
44
+ - `animation`
45
+ - `loading`
46
+ - `loadingAnimation`
47
+ - `disabled`
48
+ - `className`
49
+ - `children`
50
+
51
+ ## Read Next
52
+
53
+ 1. [README.md](./README.md)
54
+ 2. [src/types.ts](./src/types.ts)
55
+ 3. [src/oauth-button.tsx](./src/oauth-button.tsx)
56
+ 4. [src/base-button.tsx](./src/base-button.tsx)
57
+ 5. [src/runtime-styles.ts](./src/runtime-styles.ts)
58
+
59
+ ## Non-Goals
60
+
61
+ Do not assume:
62
+ - this package is headless,
63
+ - the consumer must import extra component CSS for the normal path,
64
+ - the consumer should rebuild spacing, border, or focus behavior from scratch.
package/README.md CHANGED
@@ -1,169 +1,129 @@
1
1
  # @sublimee/auth-ui
2
2
 
3
- Headless authentication UI components for Sublime, built on base-ui primitives.
3
+ AI-first package doc for Sublime auth components.
4
4
 
5
- ## Design Philosophy
5
+ If you are an AI agent reading the installed npm package directly, start with [AI_INDEX.md](./AI_INDEX.md).
6
6
 
7
- **"Headless but sensible"**
7
+ ## Use This Package When
8
8
 
9
- Our components are built on top of [base-ui](https://base-ui.com/) primitives. This means:
9
+ - you need a ready-to-use OAuth button,
10
+ - you want built-in structure, motion, loading, and accessibility defaults,
11
+ - you want token-driven customization instead of rebuilding button styles from scratch.
10
12
 
11
- - **We inherit base-ui's sensible defaults** — cursor-pointer, focus states, keyboard navigation, accessibility
12
- - ✅ **We DON'T impose visual opinions** — you control 100% of styling via Tailwind `className`
13
- - ✅ **You get a solid, accessible foundation** that looks exactly how you want
13
+ ## First Move
14
14
 
15
- This approach solves recurring UI issues (like missing `cursor: pointer`) once and for all, while preserving complete flexibility over visual design.
16
-
17
- ## Installation
15
+ ```tsx
16
+ import "@sublimee/tokens/tokens.css";
17
+ import { OAuthButton } from "@sublimee/auth-ui";
18
18
 
19
- ```bash
20
- pnpm add @sublimee/auth-ui
19
+ <OAuthButton provider="google" />
21
20
  ```
22
21
 
23
- ## Dependencies
22
+ The package injects its runtime button styles automatically. No extra component stylesheet import is required for the normal path.
24
23
 
25
- - `@base-ui/react` Button primitives with sensible defaults
26
- - `react` ^19.0.0
27
- - `react-dom` ^19.0.0
24
+ ## Current Public Surface
28
25
 
29
- ## Components
26
+ ### Components
30
27
 
31
- ### OAuthButton
28
+ - `OAuthButton`
32
29
 
33
- A headless OAuth authentication button with Google and Discord provider icons.
30
+ ### Other exports
34
31
 
35
- ```tsx
36
- import { OAuthButton } from '@sublimee/auth-ui';
32
+ - `GoogleIcon`
33
+ - `DiscordIcon`
34
+ - `useButtonAnimation`
37
35
 
38
- // Basic usage — inherits cursor-pointer and focus states from base-ui
39
- <OAuthButton
40
- provider="google"
41
- onClick={signInWithGoogle}
42
- className="flex items-center gap-3 px-6 py-3 bg-white text-gray-900 rounded-lg font-medium"
43
- />
36
+ ### Current providers
44
37
 
45
- // Outline style
46
- <OAuthButton
47
- provider="discord"
48
- onClick={signInWithDiscord}
49
- className="flex items-center gap-3 px-6 py-3 border border-white/20 text-white rounded-lg hover:bg-white/5"
50
- />
38
+ - `google`
39
+ - `discord`
51
40
 
52
- // Icon only — pass {null} as children
53
- <OAuthButton
54
- provider="google"
55
- onClick={signInWithGoogle}
56
- className="p-3 rounded-full bg-white/10 hover:bg-white/20 transition-colors"
57
- >
58
- {null}
59
- </OAuthButton>
41
+ ## Important Defaults
60
42
 
61
- // Loading state
62
- <OAuthButton
63
- provider="google"
64
- loading
65
- className="opacity-50"
66
- />
43
+ - built on `@base-ui/react/button`
44
+ - default variant: `secondary`
45
+ - default interaction motion: `press`
46
+ - loading is built in
47
+ - default loading animation: `spinner`
48
+ - focus styling is semantic-token driven
67
49
 
68
- // Custom text
50
+ ## Primary API
51
+
52
+ ```tsx
69
53
  <OAuthButton
70
54
  provider="google"
71
- onClick={signInWithGoogle}
72
- className="px-6 py-3 bg-blue-600 text-white rounded-lg"
55
+ variant="secondary"
56
+ loading={false}
57
+ disabled={false}
73
58
  >
74
- Sign in with Google
59
+ Continuar con Google
75
60
  </OAuthButton>
76
61
  ```
77
62
 
78
- #### Props
79
-
80
- | Prop | Type | Default | Description |
81
- |------|------|---------|-------------|
82
- | `provider` | `'google' \| 'discord'` | required | OAuth provider to authenticate with |
83
- | `onClick` | `() => void` | - | Click handler |
84
- | `loading` | `boolean` | `false` | Shows spinner when true |
85
- | `disabled` | `boolean` | `false` | Disables the button |
86
- | `className` | `string` | - | Tailwind classes for styling |
87
- | `children` | `ReactNode` | provider name | Button text. Pass `{null}` for icon-only |
88
-
89
- #### Sensible defaults we provide
63
+ | Prop | Type | Default | Meaning |
64
+ |------|------|---------|---------|
65
+ | `provider` | `'google' \| 'discord'` | required | OAuth provider |
66
+ | `variant` | `'primary' \| 'secondary'` | `'secondary'` | emphasis level |
67
+ | `animation` | `'press'` | `'press'` | interaction motion |
68
+ | `loading` | `boolean` | `false` | shows loading UI and disables interaction |
69
+ | `loadingAnimation` | `'spinner'` | `'spinner'` | loading indicator |
70
+ | `disabled` | `boolean` | `false` | disables interaction |
71
+ | `className` | `string` | - | later override hook |
72
+ | `children` | `ReactNode` | provider label | custom content; pass `{null}` for icon-only |
90
73
 
91
- `OAuthButton` includes these UX fundamentals automatically:
74
+ ## Task Routing
92
75
 
93
- | Behavior | Automatic? |
94
- |----------|------------|
95
- | `cursor: pointer` on hover | ✅ |
96
- | `cursor: not-allowed` when disabled/loading | ✅ |
97
- | **Focus visible states** via base-ui | ✅ |
98
- | **Keyboard navigation** via base-ui | ✅ |
99
- | **ARIA attributes** via base-ui | ✅ |
100
- | **Disabled state handling** via base-ui | ✅ |
101
-
102
- You don't need to add `cursor-pointer` to your className — it's automatic. Your `className` is merged with our sensible defaults, with your styles taking precedence.
103
-
104
- ### Icons
105
-
106
- Individual icons are also exported if you need them separately:
76
+ ### Google auth button
107
77
 
108
78
  ```tsx
109
- import { GoogleIcon, DiscordIcon, SpinnerIcon } from '@sublimee/auth-ui';
110
-
111
- <GoogleIcon size={24} className="text-red-500" />
112
- <DiscordIcon size={20} />
113
- <SpinnerIcon size={16} className="animate-spin" />
79
+ <OAuthButton provider="google" />
114
80
  ```
115
81
 
116
- ## Styling Guidelines
117
-
118
- Since components are headless, you provide all styles via `className`. Here are recommended patterns:
119
-
120
- ### Common Patterns
82
+ ### Primary call to action
121
83
 
122
84
  ```tsx
123
- // Full-width button
124
- className="w-full flex items-center justify-center gap-3 px-6 py-3 bg-white text-gray-900 rounded-lg"
125
-
126
- // Minimal icon button
127
- className="p-2 rounded-full hover:bg-white/10 transition-colors"
128
-
129
- // Outline variant
130
- className="flex items-center gap-2 px-4 py-2 border border-current rounded-md hover:bg-white/5"
131
-
132
- // Loading state
133
- className="opacity-50 cursor-wait"
85
+ <OAuthButton provider="google" variant="primary" />
134
86
  ```
135
87
 
136
- ### State Handling
137
-
138
- The component accepts a `disabled` prop and renders in a loading state when `loading={true}`. These states automatically get `cursor: not-allowed` from base-ui, but you may want to add visual indicators:
88
+ ### Loading state
139
89
 
140
90
  ```tsx
141
- <OAuthButton
142
- provider="google"
143
- loading={isLoading}
144
- disabled={isLoading}
145
- className={`flex items-center gap-3 px-6 py-3 rounded-lg ${
146
- isLoading ? 'opacity-50' : 'hover:bg-gray-50'
147
- }`}
148
- />
91
+ <OAuthButton provider="google" loading />
149
92
  ```
150
93
 
151
- ## TypeScript
94
+ ## Customization Order
152
95
 
153
- Full TypeScript support is included:
96
+ Use this order:
97
+ 1. import tokens
98
+ 2. override semantic CSS custom properties
99
+ 3. use props like `variant`, `loading`, and `disabled`
100
+ 4. use `className` only for edge-case local adjustments
154
101
 
155
- ```tsx
156
- import type { OAuthButtonProps, OAuthProvider, OAuthIconsProps } from '@sublimee/auth-ui';
102
+ Example:
103
+
104
+ ```css
105
+ @import "@sublimee/tokens/tokens.css";
106
+
107
+ :root {
108
+ --sublime-color-interactive-primary: #ec4899;
109
+ --sublime-color-interactive-primary-hover: #db2777;
110
+ --sublime-color-focus-ring: #ec4899;
111
+ --sublime-radius-button: 9999px;
112
+ }
157
113
  ```
158
114
 
159
- ## Why base-ui?
115
+ ## Zero-Setup Contract
116
+
117
+ For this package, zero-setup means:
118
+ - the button should look like a button on first render,
119
+ - provider icon and layout should be built in,
120
+ - the consumer should not rebuild spacing, border, focus, or interaction states,
121
+ - customization should extend the component rather than complete it.
160
122
 
161
- We chose base-ui as our foundation because:
123
+ ## Notes
162
124
 
163
- 1. **Sensible defaults out of the box** No more forgetting `cursor: pointer`
164
- 2. **Accessibility built-in** Proper ARIA, focus management, keyboard support
165
- 3. **Headless by design** — Complete control over styling
166
- 4. **Production-tested** — Built by the MUI team, battle-tested at scale
125
+ - `@sublimee/auth-ui/animations.css` still exists as a legacy optional export, but the normal path should not require it.
126
+ - Public-facing default copy is currently Spanish.
167
127
 
168
128
  ## License
169
129
 
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @sublimee/auth-ui runtime animations
3
+ *
4
+ * Optional legacy export.
5
+ * Most consumers should not need to import this file because auth-ui now
6
+ * injects its runtime button styles automatically.
7
+ */
8
+
9
+ @keyframes sublime-button-press-release {
10
+ 0% {
11
+ transform: translateY(1px) scale(0.985);
12
+ box-shadow: var(--sublime-button-shadow-active);
13
+ }
14
+ 100% {
15
+ transform: translateY(0) scale(1);
16
+ box-shadow: var(--sublime-button-shadow);
17
+ }
18
+ }
19
+
20
+ @keyframes sublime-button-spinner {
21
+ from {
22
+ transform: rotate(0deg);
23
+ }
24
+ to {
25
+ transform: rotate(360deg);
26
+ }
27
+ }
28
+
29
+ .sublime-button-pressed {
30
+ transform: translateY(1px) scale(0.985);
31
+ box-shadow: var(--sublime-button-shadow-active);
32
+ }
33
+
34
+ .animate-sublime-button-press-release {
35
+ animation: sublime-button-press-release 180ms var(--sublime-ease-out, cubic-bezier(0, 0, 0.2, 1));
36
+ }
37
+
38
+ .sublime-button__spinner {
39
+ animation: sublime-button-spinner 720ms linear infinite;
40
+ transform-origin: center;
41
+ }
42
+
43
+ @media (prefers-reduced-motion: reduce) {
44
+ .animate-sublime-button-press-release {
45
+ animation-duration: 0.01ms !important;
46
+ animation-iteration-count: 1 !important;
47
+ }
48
+
49
+ .sublime-button__spinner {
50
+ animation-duration: 1.6s !important;
51
+ }
52
+ }
package/dist/index.d.mts CHANGED
@@ -1,88 +1,105 @@
1
1
  import * as react from 'react';
2
- import { ButtonHTMLAttributes, ReactNode } from 'react';
2
+ import { ButtonHTMLAttributes, MouseEventHandler, ReactNode } from 'react';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
5
  type OAuthProvider = 'google' | 'discord';
6
+ type ButtonVariant = 'primary' | 'secondary';
7
+ type ButtonAnimation = 'press';
8
+ type ButtonLoadingAnimation = 'spinner';
6
9
  interface OAuthButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {
7
10
  /**
8
- * The OAuth provider to authenticate with
11
+ * The OAuth provider to authenticate with.
9
12
  */
10
13
  provider: OAuthProvider;
11
14
  /**
12
- * Click handler - typically calls supabase.auth.signInWithOAuth
15
+ * Click handler - typically calls supabase.auth.signInWithOAuth.
13
16
  */
14
- onClick?: () => void;
17
+ onClick?: MouseEventHandler<HTMLButtonElement>;
15
18
  /**
16
- * Loading state - shows spinner when true
19
+ * Loading state - shows the configured loading animation and disables interaction.
17
20
  */
18
21
  loading?: boolean;
19
22
  /**
20
- * Custom className - use Tailwind for styling
21
- * @example "flex items-center gap-2 px-4 py-2 bg-white text-gray-900 rounded-lg"
23
+ * Loading animation shown while `loading` is true.
24
+ * @default 'spinner'
25
+ */
26
+ loadingAnimation?: ButtonLoadingAnimation;
27
+ /**
28
+ * Visual variant of the button.
29
+ * - primary: High emphasis, filled background
30
+ * - secondary: Medium emphasis, bordered (default)
31
+ * @default 'secondary'
32
+ */
33
+ variant?: ButtonVariant;
34
+ /**
35
+ * Interaction motion applied on press.
36
+ * @default 'press'
37
+ */
38
+ animation?: ButtonAnimation;
39
+ /**
40
+ * Custom className appended after the built-in runtime classes.
22
41
  */
23
42
  className?: string;
24
43
  /**
25
- * Button children - defaults to provider name
26
- * Pass `null` for icon-only mode
44
+ * Button children - defaults to provider name in Spanish.
45
+ * Pass `null` for icon-only mode.
27
46
  */
28
47
  children?: ReactNode;
29
48
  }
30
49
  interface OAuthIconsProps {
31
50
  /**
32
- * Icon size in pixels (min: 1)
51
+ * Icon size in pixels (min: 1).
33
52
  * @default 24
34
53
  */
35
54
  size?: number;
55
+ /**
56
+ * Optional className for icon-specific styling.
57
+ */
58
+ className?: string;
59
+ }
60
+ interface UseButtonAnimationResult {
61
+ /**
62
+ * CSS classes to apply for the current animation state.
63
+ */
64
+ animationClassName: string;
65
+ /**
66
+ * Event handlers to attach to the button.
67
+ */
68
+ eventHandlers: Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'onBlur' | 'onKeyDown' | 'onKeyUp' | 'onMouseDown' | 'onMouseLeave' | 'onMouseUp' | 'onTouchEnd' | 'onTouchStart'>;
36
69
  }
37
70
 
38
71
  /**
39
72
  * OAuthButton component
40
73
  *
41
- * A headless OAuth button built on top of base-ui's Button primitive.
42
- * Includes sensible defaults (cursor-pointer) while remaining fully
43
- * customizable via className.
44
- *
45
- * Design Philosophy:
46
- * - We add sensible UX defaults (cursor-pointer, proper disabled states)
47
- * - We don't impose visual opinions - you control all styling via className
48
- * - The result is a solid, accessible foundation that looks exactly how you want
74
+ * Built on top of the shared Sublime button foundation so it inherits
75
+ * runtime styling, semantic variants, curated press motion, and loading
76
+ * behavior by default.
49
77
  *
50
78
  * @example
51
79
  * ```tsx
52
- * // Basic usage - cursor-pointer is automatic
53
- * <OAuthButton
54
- * provider="google"
55
- * onClick={signInWithGoogle}
56
- * className="flex items-center gap-3 px-6 py-3 bg-white text-gray-900 rounded-lg font-medium"
57
- * />
58
- *
59
- * // Icon only - pass {null} as children
60
- * <OAuthButton
61
- * provider="google"
62
- * className="p-3 rounded-full hover:bg-white/10"
63
- * >
64
- * {null}
65
- * </OAuthButton>
66
- *
67
- * // Loading state - cursor-not-allowed is automatic
68
- * <OAuthButton provider="google" loading className="opacity-50" />
80
+ * <OAuthButton provider="google" />
81
+ * <OAuthButton provider="discord" variant="primary" loading />
69
82
  * ```
70
83
  */
71
84
  declare const OAuthButton: react.ForwardRefExoticComponent<OAuthButtonProps & react.RefAttributes<HTMLButtonElement>>;
72
85
 
86
+ /**
87
+ * Hook to provide the curated button press animation.
88
+ *
89
+ * Handles mouse, touch, and keyboard interaction so motion feedback stays
90
+ * consistent across the different ways users can activate a button.
91
+ */
92
+ declare function useButtonAnimation(animation?: ButtonAnimation | null): UseButtonAnimationResult;
93
+
73
94
  /**
74
95
  * Google Logo Icon
75
96
  * Official Google "G" logo for OAuth authentication
76
97
  */
77
- declare function GoogleIcon({ size }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
98
+ declare function GoogleIcon({ size, className }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
78
99
  /**
79
100
  * Discord Logo Icon
80
101
  * Official Discord logo for OAuth authentication
81
102
  */
82
- declare function DiscordIcon({ size }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
83
- /**
84
- * Spinner Icon for loading state
85
- */
86
- declare function SpinnerIcon({ size }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
103
+ declare function DiscordIcon({ size, className }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
87
104
 
88
- export { DiscordIcon, GoogleIcon, OAuthButton, type OAuthButtonProps, type OAuthIconsProps, type OAuthProvider, SpinnerIcon };
105
+ export { type ButtonAnimation, type ButtonLoadingAnimation, type ButtonVariant, DiscordIcon, GoogleIcon, OAuthButton, type OAuthButtonProps, type OAuthIconsProps, type OAuthProvider, type UseButtonAnimationResult, useButtonAnimation };
package/dist/index.d.ts CHANGED
@@ -1,88 +1,105 @@
1
1
  import * as react from 'react';
2
- import { ButtonHTMLAttributes, ReactNode } from 'react';
2
+ import { ButtonHTMLAttributes, MouseEventHandler, ReactNode } from 'react';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
5
  type OAuthProvider = 'google' | 'discord';
6
+ type ButtonVariant = 'primary' | 'secondary';
7
+ type ButtonAnimation = 'press';
8
+ type ButtonLoadingAnimation = 'spinner';
6
9
  interface OAuthButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {
7
10
  /**
8
- * The OAuth provider to authenticate with
11
+ * The OAuth provider to authenticate with.
9
12
  */
10
13
  provider: OAuthProvider;
11
14
  /**
12
- * Click handler - typically calls supabase.auth.signInWithOAuth
15
+ * Click handler - typically calls supabase.auth.signInWithOAuth.
13
16
  */
14
- onClick?: () => void;
17
+ onClick?: MouseEventHandler<HTMLButtonElement>;
15
18
  /**
16
- * Loading state - shows spinner when true
19
+ * Loading state - shows the configured loading animation and disables interaction.
17
20
  */
18
21
  loading?: boolean;
19
22
  /**
20
- * Custom className - use Tailwind for styling
21
- * @example "flex items-center gap-2 px-4 py-2 bg-white text-gray-900 rounded-lg"
23
+ * Loading animation shown while `loading` is true.
24
+ * @default 'spinner'
25
+ */
26
+ loadingAnimation?: ButtonLoadingAnimation;
27
+ /**
28
+ * Visual variant of the button.
29
+ * - primary: High emphasis, filled background
30
+ * - secondary: Medium emphasis, bordered (default)
31
+ * @default 'secondary'
32
+ */
33
+ variant?: ButtonVariant;
34
+ /**
35
+ * Interaction motion applied on press.
36
+ * @default 'press'
37
+ */
38
+ animation?: ButtonAnimation;
39
+ /**
40
+ * Custom className appended after the built-in runtime classes.
22
41
  */
23
42
  className?: string;
24
43
  /**
25
- * Button children - defaults to provider name
26
- * Pass `null` for icon-only mode
44
+ * Button children - defaults to provider name in Spanish.
45
+ * Pass `null` for icon-only mode.
27
46
  */
28
47
  children?: ReactNode;
29
48
  }
30
49
  interface OAuthIconsProps {
31
50
  /**
32
- * Icon size in pixels (min: 1)
51
+ * Icon size in pixels (min: 1).
33
52
  * @default 24
34
53
  */
35
54
  size?: number;
55
+ /**
56
+ * Optional className for icon-specific styling.
57
+ */
58
+ className?: string;
59
+ }
60
+ interface UseButtonAnimationResult {
61
+ /**
62
+ * CSS classes to apply for the current animation state.
63
+ */
64
+ animationClassName: string;
65
+ /**
66
+ * Event handlers to attach to the button.
67
+ */
68
+ eventHandlers: Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'onBlur' | 'onKeyDown' | 'onKeyUp' | 'onMouseDown' | 'onMouseLeave' | 'onMouseUp' | 'onTouchEnd' | 'onTouchStart'>;
36
69
  }
37
70
 
38
71
  /**
39
72
  * OAuthButton component
40
73
  *
41
- * A headless OAuth button built on top of base-ui's Button primitive.
42
- * Includes sensible defaults (cursor-pointer) while remaining fully
43
- * customizable via className.
44
- *
45
- * Design Philosophy:
46
- * - We add sensible UX defaults (cursor-pointer, proper disabled states)
47
- * - We don't impose visual opinions - you control all styling via className
48
- * - The result is a solid, accessible foundation that looks exactly how you want
74
+ * Built on top of the shared Sublime button foundation so it inherits
75
+ * runtime styling, semantic variants, curated press motion, and loading
76
+ * behavior by default.
49
77
  *
50
78
  * @example
51
79
  * ```tsx
52
- * // Basic usage - cursor-pointer is automatic
53
- * <OAuthButton
54
- * provider="google"
55
- * onClick={signInWithGoogle}
56
- * className="flex items-center gap-3 px-6 py-3 bg-white text-gray-900 rounded-lg font-medium"
57
- * />
58
- *
59
- * // Icon only - pass {null} as children
60
- * <OAuthButton
61
- * provider="google"
62
- * className="p-3 rounded-full hover:bg-white/10"
63
- * >
64
- * {null}
65
- * </OAuthButton>
66
- *
67
- * // Loading state - cursor-not-allowed is automatic
68
- * <OAuthButton provider="google" loading className="opacity-50" />
80
+ * <OAuthButton provider="google" />
81
+ * <OAuthButton provider="discord" variant="primary" loading />
69
82
  * ```
70
83
  */
71
84
  declare const OAuthButton: react.ForwardRefExoticComponent<OAuthButtonProps & react.RefAttributes<HTMLButtonElement>>;
72
85
 
86
+ /**
87
+ * Hook to provide the curated button press animation.
88
+ *
89
+ * Handles mouse, touch, and keyboard interaction so motion feedback stays
90
+ * consistent across the different ways users can activate a button.
91
+ */
92
+ declare function useButtonAnimation(animation?: ButtonAnimation | null): UseButtonAnimationResult;
93
+
73
94
  /**
74
95
  * Google Logo Icon
75
96
  * Official Google "G" logo for OAuth authentication
76
97
  */
77
- declare function GoogleIcon({ size }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
98
+ declare function GoogleIcon({ size, className }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
78
99
  /**
79
100
  * Discord Logo Icon
80
101
  * Official Discord logo for OAuth authentication
81
102
  */
82
- declare function DiscordIcon({ size }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
83
- /**
84
- * Spinner Icon for loading state
85
- */
86
- declare function SpinnerIcon({ size }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
103
+ declare function DiscordIcon({ size, className }: OAuthIconsProps): react_jsx_runtime.JSX.Element;
87
104
 
88
- export { DiscordIcon, GoogleIcon, OAuthButton, type OAuthButtonProps, type OAuthIconsProps, type OAuthProvider, SpinnerIcon };
105
+ export { type ButtonAnimation, type ButtonLoadingAnimation, type ButtonVariant, DiscordIcon, GoogleIcon, OAuthButton, type OAuthButtonProps, type OAuthIconsProps, type OAuthProvider, type UseButtonAnimationResult, useButtonAnimation };