@sublimee/auth-ui 0.1.0 → 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/dist/index.mjs CHANGED
@@ -1,12 +1,14 @@
1
1
  // src/oauth-button.tsx
2
- import { forwardRef, useMemo } from "react";
2
+ import { forwardRef as forwardRef2 } from "react";
3
+
4
+ // src/base-button.tsx
5
+ import { forwardRef } from "react";
3
6
  import { Button } from "@base-ui/react/button";
4
7
 
5
8
  // src/icons.tsx
6
9
  import { jsx, jsxs } from "react/jsx-runtime";
7
- function getSafeSize(size) {
8
- const safeSize = size ?? 24;
9
- return Math.max(1, safeSize);
10
+ function getSafeSize(size, defaultSize = 24) {
11
+ return Math.max(1, size ?? defaultSize);
10
12
  }
11
13
  function GoogleIcon({ size, className }) {
12
14
  const safeSize = getSafeSize(size);
@@ -18,8 +20,8 @@ function GoogleIcon({ size, className }) {
18
20
  viewBox: "0 0 24 24",
19
21
  fill: "none",
20
22
  xmlns: "http://www.w3.org/2000/svg",
21
- className,
22
23
  "aria-hidden": "true",
24
+ className,
23
25
  children: [
24
26
  /* @__PURE__ */ jsx(
25
27
  "path",
@@ -63,8 +65,8 @@ function DiscordIcon({ size, className }) {
63
65
  viewBox: "0 0 24 24",
64
66
  fill: "none",
65
67
  xmlns: "http://www.w3.org/2000/svg",
66
- className,
67
68
  "aria-hidden": "true",
69
+ className,
68
70
  children: /* @__PURE__ */ jsx(
69
71
  "path",
70
72
  {
@@ -76,51 +78,36 @@ function DiscordIcon({ size, className }) {
76
78
  );
77
79
  }
78
80
  function SpinnerIcon({ size, className }) {
79
- const safeSize = size ?? 20;
80
- const finalSize = Math.max(1, safeSize);
81
+ const safeSize = getSafeSize(size, 20);
81
82
  return /* @__PURE__ */ jsxs(
82
83
  "svg",
83
84
  {
84
- width: finalSize,
85
- height: finalSize,
85
+ width: safeSize,
86
+ height: safeSize,
86
87
  viewBox: "0 0 24 24",
87
88
  fill: "none",
88
89
  xmlns: "http://www.w3.org/2000/svg",
89
- className,
90
90
  "aria-hidden": "true",
91
+ className,
91
92
  children: [
92
93
  /* @__PURE__ */ jsx(
93
94
  "circle",
94
95
  {
95
96
  cx: "12",
96
97
  cy: "12",
97
- r: "10",
98
+ r: "9",
98
99
  stroke: "currentColor",
99
- strokeWidth: "4",
100
- strokeLinecap: "round",
101
- strokeDasharray: "60",
102
- strokeDashoffset: "20",
103
- opacity: "0.25"
100
+ strokeWidth: "3",
101
+ opacity: "0.22"
104
102
  }
105
103
  ),
106
104
  /* @__PURE__ */ jsx(
107
105
  "path",
108
106
  {
109
- d: "M12 2C6.477 2 2 6.477 2 12",
107
+ d: "M12 3a9 9 0 0 1 9 9",
110
108
  stroke: "currentColor",
111
- strokeWidth: "4",
112
- strokeLinecap: "round",
113
- children: /* @__PURE__ */ jsx(
114
- "animateTransform",
115
- {
116
- attributeName: "transform",
117
- type: "rotate",
118
- from: "0 12 12",
119
- to: "360 12 12",
120
- dur: "1s",
121
- repeatCount: "indefinite"
122
- }
123
- )
109
+ strokeWidth: "3",
110
+ strokeLinecap: "round"
124
111
  }
125
112
  )
126
113
  ]
@@ -128,79 +115,463 @@ function SpinnerIcon({ size, className }) {
128
115
  );
129
116
  }
130
117
 
131
- // src/oauth-button.tsx
132
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
133
- var PROVIDER_NAMES = {
134
- google: "Google",
135
- discord: "Discord"
118
+ // src/button-loading-indicator.tsx
119
+ import { jsx as jsx2 } from "react/jsx-runtime";
120
+ function SpinnerLoadingIndicator({ size }) {
121
+ return /* @__PURE__ */ jsx2(SpinnerIcon, { size, className: "sublime-button__spinner" });
122
+ }
123
+ var LOADING_INDICATORS = {
124
+ spinner: SpinnerLoadingIndicator
136
125
  };
137
- function getProviderIcon(provider) {
138
- switch (provider) {
139
- case "google":
140
- return GoogleIcon;
141
- case "discord":
142
- return DiscordIcon;
143
- default:
144
- return () => null;
145
- }
126
+ function ButtonLoadingIndicator({
127
+ animation = "spinner",
128
+ size = 18
129
+ }) {
130
+ const LoadingIndicator = LOADING_INDICATORS[animation];
131
+ return /* @__PURE__ */ jsx2(LoadingIndicator, { size });
146
132
  }
147
- var SENSIBLE_DEFAULTS = ["cursor-pointer"];
148
- function mergeButtonClasses(userClassName, isDisabled) {
149
- const userClasses = userClassName?.trim() ?? "";
150
- const neededDefaults = SENSIBLE_DEFAULTS.filter(
151
- (defaultClass) => !userClasses.includes(defaultClass)
133
+
134
+ // src/use-button-animation.ts
135
+ import { useCallback, useEffect, useRef, useState } from "react";
136
+ var PRESS_RELEASE_DURATION = 180;
137
+ function useButtonAnimation(animation = "press") {
138
+ const [phase, setPhase] = useState("idle");
139
+ const timeoutRef = useRef(null);
140
+ const clearExistingTimeout = useCallback(() => {
141
+ if (timeoutRef.current) {
142
+ clearTimeout(timeoutRef.current);
143
+ timeoutRef.current = null;
144
+ }
145
+ }, []);
146
+ useEffect(() => {
147
+ return () => {
148
+ clearExistingTimeout();
149
+ };
150
+ }, [clearExistingTimeout]);
151
+ const handlePressStart = useCallback(() => {
152
+ if (!animation) {
153
+ return;
154
+ }
155
+ clearExistingTimeout();
156
+ setPhase("pressed");
157
+ }, [animation, clearExistingTimeout]);
158
+ const handlePressEnd = useCallback(() => {
159
+ if (!animation || phase !== "pressed") {
160
+ return;
161
+ }
162
+ setPhase("releasing");
163
+ timeoutRef.current = setTimeout(() => {
164
+ setPhase("idle");
165
+ }, PRESS_RELEASE_DURATION);
166
+ }, [animation, phase]);
167
+ const handleBlur = useCallback(() => {
168
+ clearExistingTimeout();
169
+ setPhase("idle");
170
+ }, [clearExistingTimeout]);
171
+ const handleKeyDown = useCallback(
172
+ (event) => {
173
+ if (event.repeat) {
174
+ return;
175
+ }
176
+ if (event.key === " " || event.key === "Enter") {
177
+ handlePressStart();
178
+ }
179
+ },
180
+ [handlePressStart]
181
+ );
182
+ const handleKeyUp = useCallback(
183
+ (event) => {
184
+ if (event.key === " " || event.key === "Enter") {
185
+ handlePressEnd();
186
+ }
187
+ },
188
+ [handlePressEnd]
152
189
  );
153
- if (isDisabled && !userClasses.includes("cursor-not-allowed")) {
154
- neededDefaults.push("cursor-not-allowed");
190
+ const getAnimationClass = () => {
191
+ if (!animation) {
192
+ return "";
193
+ }
194
+ if (phase === "pressed") {
195
+ return "sublime-button-pressed";
196
+ }
197
+ if (phase === "releasing") {
198
+ return "animate-sublime-button-press-release";
199
+ }
200
+ return "";
201
+ };
202
+ return {
203
+ animationClassName: getAnimationClass(),
204
+ eventHandlers: {
205
+ onBlur: handleBlur,
206
+ onKeyDown: handleKeyDown,
207
+ onKeyUp: handleKeyUp,
208
+ onMouseDown: handlePressStart,
209
+ onMouseLeave: handlePressEnd,
210
+ onMouseUp: handlePressEnd,
211
+ onTouchEnd: handlePressEnd,
212
+ onTouchStart: handlePressStart
213
+ }
214
+ };
215
+ }
216
+
217
+ // src/runtime-styles.ts
218
+ import { useInsertionEffect } from "react";
219
+ var AUTH_UI_RUNTIME_STYLE_ID = "sublime-auth-ui-runtime-styles";
220
+ var AUTH_UI_RUNTIME_STYLES = `
221
+ .sublime-button {
222
+ --sublime-button-gap: var(--sublime-space-3, 0.75rem);
223
+ --sublime-button-padding-x: var(--sublime-space-button-x, 1rem);
224
+ --sublime-button-padding-y: var(--sublime-space-button-y, 0.75rem);
225
+ --sublime-button-height: var(--sublime-size-button-height-md, 2.75rem);
226
+ --sublime-button-radius: var(--sublime-radius-button, 0.875rem);
227
+ --sublime-button-font-family: var(--sublime-font-family-sans, ui-sans-serif, system-ui, sans-serif);
228
+ --sublime-button-font-size: var(--sublime-font-size-sm, 0.875rem);
229
+ --sublime-button-font-weight: var(--sublime-font-weight-medium, 500);
230
+ --sublime-button-line-height: var(--sublime-line-height-tight, 1.15);
231
+ --sublime-button-visual-size: 1.25rem;
232
+ --sublime-button-transition: var(--sublime-transition-button, background-color 160ms cubic-bezier(0.4, 0, 0.2, 1), border-color 160ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 160ms cubic-bezier(0.4, 0, 0.2, 1), color 160ms cubic-bezier(0.4, 0, 0.2, 1), transform 160ms cubic-bezier(0.4, 0, 0.2, 1));
233
+ --sublime-button-bg: var(--sublime-color-surface-1, #ffffff);
234
+ --sublime-button-bg-hover: var(--sublime-color-surface-1-hover, #f8fafc);
235
+ --sublime-button-bg-active: var(--sublime-color-surface-1-active, #eef2f7);
236
+ --sublime-button-color: var(--sublime-color-text-primary, #111827);
237
+ --sublime-button-color-hover: var(--sublime-color-text-primary, #111827);
238
+ --sublime-button-border: var(--sublime-color-border-primary, #d1d5db);
239
+ --sublime-button-border-hover: var(--sublime-color-border-primary-hover, #9ca3af);
240
+ --sublime-button-border-active: var(--sublime-color-border-primary-active, #6b7280);
241
+ --sublime-button-shadow: var(--sublime-shadow-button, 0 1px 2px rgb(15 23 42 / 0.08));
242
+ --sublime-button-shadow-hover: var(--sublime-shadow-button-hover, 0 8px 20px rgb(15 23 42 / 0.12));
243
+ --sublime-button-shadow-active: var(--sublime-shadow-button-active, inset 0 1px 2px rgb(15 23 42 / 0.14));
244
+ --sublime-button-focus-ring: var(--sublime-color-focus-ring, var(--sublime-color-interactive-accent, #2563eb));
245
+ --sublime-button-focus-ring-offset: var(--sublime-color-focus-ring-offset, var(--sublime-color-surface-0, #ffffff));
246
+ position: relative;
247
+ display: inline-flex;
248
+ min-height: var(--sublime-button-height);
249
+ align-items: center;
250
+ justify-content: center;
251
+ gap: var(--sublime-button-gap);
252
+ padding: var(--sublime-button-padding-y) var(--sublime-button-padding-x);
253
+ border: 1px solid var(--sublime-button-border);
254
+ border-radius: var(--sublime-button-radius);
255
+ background: var(--sublime-button-bg);
256
+ color: var(--sublime-button-color);
257
+ box-shadow: var(--sublime-button-shadow);
258
+ font-family: var(--sublime-button-font-family);
259
+ font-size: var(--sublime-button-font-size);
260
+ font-weight: var(--sublime-button-font-weight);
261
+ line-height: var(--sublime-button-line-height);
262
+ cursor: pointer;
263
+ user-select: none;
264
+ text-decoration: none;
265
+ white-space: nowrap;
266
+ vertical-align: middle;
267
+ isolation: isolate;
268
+ overflow: hidden;
269
+ appearance: none;
270
+ -webkit-tap-highlight-color: transparent;
271
+ transition: var(--sublime-button-transition);
272
+ }
273
+
274
+ .sublime-button:hover:not(:disabled) {
275
+ background: var(--sublime-button-bg-hover);
276
+ color: var(--sublime-button-color-hover);
277
+ border-color: var(--sublime-button-border-hover);
278
+ box-shadow: var(--sublime-button-shadow-hover);
279
+ }
280
+
281
+ .sublime-button:active:not(:disabled) {
282
+ background: var(--sublime-button-bg-active);
283
+ border-color: var(--sublime-button-border-active);
284
+ box-shadow: var(--sublime-button-shadow-active);
285
+ }
286
+
287
+ .sublime-button:focus {
288
+ outline: none;
289
+ }
290
+
291
+ .sublime-button:focus-visible {
292
+ box-shadow:
293
+ 0 0 0 2px var(--sublime-button-focus-ring-offset),
294
+ 0 0 0 4px var(--sublime-button-focus-ring),
295
+ var(--sublime-button-shadow-hover);
296
+ }
297
+
298
+ .sublime-button:disabled {
299
+ cursor: not-allowed;
300
+ opacity: 0.6;
301
+ box-shadow: none;
302
+ }
303
+
304
+ .sublime-button[data-loading='true'] {
305
+ cursor: progress;
306
+ }
307
+
308
+ .sublime-button[data-loading='true']:disabled {
309
+ opacity: 0.78;
310
+ }
311
+
312
+ .sublime-button[data-icon-only='true'] {
313
+ min-width: var(--sublime-button-height);
314
+ padding-inline: calc(var(--sublime-button-padding-y) + 0.125rem);
315
+ }
316
+
317
+ .sublime-button__content {
318
+ display: inline-flex;
319
+ width: 100%;
320
+ align-items: center;
321
+ justify-content: center;
322
+ gap: inherit;
323
+ }
324
+
325
+ .sublime-button__visual,
326
+ .sublime-button__label {
327
+ display: inline-flex;
328
+ align-items: center;
329
+ }
330
+
331
+ .sublime-button__visual {
332
+ flex-shrink: 0;
333
+ justify-content: center;
334
+ min-width: var(--sublime-button-visual-size);
335
+ }
336
+
337
+ .sublime-button__visual svg {
338
+ display: block;
339
+ }
340
+
341
+ .sublime-button__label {
342
+ min-width: 0;
343
+ }
344
+
345
+ .sublime-button--primary {
346
+ --sublime-button-bg: var(--sublime-color-interactive-primary, #111827);
347
+ --sublime-button-bg-hover: var(--sublime-color-interactive-primary-hover, #1f2937);
348
+ --sublime-button-bg-active: var(--sublime-color-interactive-primary-active, #0f172a);
349
+ --sublime-button-color: var(--sublime-color-interactive-primary-text, #f9fafb);
350
+ --sublime-button-color-hover: var(--sublime-color-interactive-primary-text, #f9fafb);
351
+ --sublime-button-border: var(--sublime-color-interactive-primary, #111827);
352
+ --sublime-button-border-hover: var(--sublime-color-interactive-primary-hover, #1f2937);
353
+ --sublime-button-border-active: var(--sublime-color-interactive-primary-active, #0f172a);
354
+ }
355
+
356
+ .sublime-button--secondary {
357
+ --sublime-button-bg: var(--sublime-color-surface-1, #ffffff);
358
+ --sublime-button-bg-hover: var(--sublime-color-surface-1-hover, #f8fafc);
359
+ --sublime-button-bg-active: var(--sublime-color-surface-1-active, #eef2f7);
360
+ --sublime-button-color: var(--sublime-color-text-primary, #111827);
361
+ --sublime-button-color-hover: var(--sublime-color-text-primary, #111827);
362
+ --sublime-button-border: var(--sublime-color-border-primary, #d1d5db);
363
+ --sublime-button-border-hover: var(--sublime-color-border-primary-hover, #9ca3af);
364
+ --sublime-button-border-active: var(--sublime-color-border-primary-active, #6b7280);
365
+ }
366
+
367
+ .sublime-auth-button[data-provider='discord'] .sublime-button__visual {
368
+ color: #5865f2;
369
+ }
370
+
371
+ .sublime-auth-button[data-loading='true'] .sublime-button__visual {
372
+ color: currentColor;
373
+ }
374
+
375
+ @keyframes sublime-button-press-release {
376
+ 0% {
377
+ transform: translateY(1px) scale(0.985);
378
+ box-shadow: var(--sublime-button-shadow-active);
379
+ }
380
+ 100% {
381
+ transform: translateY(0) scale(1);
382
+ box-shadow: var(--sublime-button-shadow);
383
+ }
384
+ }
385
+
386
+ @keyframes sublime-button-spinner {
387
+ from {
388
+ transform: rotate(0deg);
389
+ }
390
+ to {
391
+ transform: rotate(360deg);
392
+ }
393
+ }
394
+
395
+ .sublime-button-pressed {
396
+ transform: translateY(1px) scale(0.985);
397
+ box-shadow: var(--sublime-button-shadow-active);
398
+ }
399
+
400
+ .animate-sublime-button-press-release {
401
+ animation: sublime-button-press-release 180ms var(--sublime-ease-out, cubic-bezier(0, 0, 0.2, 1));
402
+ }
403
+
404
+ .sublime-button__spinner {
405
+ animation: sublime-button-spinner 720ms linear infinite;
406
+ transform-origin: center;
407
+ }
408
+
409
+ @media (prefers-reduced-motion: reduce) {
410
+ .sublime-button,
411
+ .animate-sublime-button-press-release {
412
+ animation-duration: 0.01ms !important;
413
+ animation-iteration-count: 1 !important;
414
+ transition-duration: 0.01ms !important;
415
+ }
416
+
417
+ .sublime-button__spinner {
418
+ animation-duration: 1.6s !important;
155
419
  }
156
- if (neededDefaults.length === 0) {
157
- return userClasses;
420
+ }
421
+ `;
422
+ function useAuthUiRuntimeStyles() {
423
+ useInsertionEffect(() => {
424
+ if (typeof document === "undefined") {
425
+ return;
426
+ }
427
+ if (document.getElementById(AUTH_UI_RUNTIME_STYLE_ID)) {
428
+ return;
429
+ }
430
+ const styleElement = document.createElement("style");
431
+ styleElement.id = AUTH_UI_RUNTIME_STYLE_ID;
432
+ styleElement.textContent = AUTH_UI_RUNTIME_STYLES;
433
+ document.head.prepend(styleElement);
434
+ }, []);
435
+ }
436
+
437
+ // src/base-button.tsx
438
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
439
+ function mergeClassNames(...classNames) {
440
+ return classNames.filter(Boolean).join(" ");
441
+ }
442
+ function composeEventHandlers(internalHandler, externalHandler) {
443
+ if (!internalHandler) {
444
+ return externalHandler;
445
+ }
446
+ if (!externalHandler) {
447
+ return internalHandler;
448
+ }
449
+ return (event) => {
450
+ internalHandler(event);
451
+ externalHandler(event);
452
+ };
453
+ }
454
+ var BaseButton = forwardRef(
455
+ function BaseButton2(props, forwardedRef) {
456
+ const {
457
+ animation = "press",
458
+ "aria-busy": ariaBusy,
459
+ children,
460
+ className,
461
+ disabled = false,
462
+ isIconOnly = false,
463
+ leadingVisual,
464
+ loading = false,
465
+ loadingAnimation = "spinner",
466
+ type = "button",
467
+ variant = "secondary",
468
+ onBlur,
469
+ onKeyDown,
470
+ onKeyUp,
471
+ onMouseDown,
472
+ onMouseLeave,
473
+ onMouseUp,
474
+ onTouchEnd,
475
+ onTouchStart,
476
+ ...otherProps
477
+ } = props;
478
+ useAuthUiRuntimeStyles();
479
+ const { animationClassName, eventHandlers } = useButtonAnimation(
480
+ disabled || loading ? null : animation
481
+ );
482
+ const mergedClassName = mergeClassNames(
483
+ "sublime-button",
484
+ `sublime-button--${variant}`,
485
+ animationClassName,
486
+ className
487
+ );
488
+ const visualContent = loading ? /* @__PURE__ */ jsx3(ButtonLoadingIndicator, { animation: loadingAnimation, size: 18 }) : leadingVisual ?? (isIconOnly ? children : void 0);
489
+ const labelContent = isIconOnly ? null : children;
490
+ return /* @__PURE__ */ jsx3(
491
+ Button,
492
+ {
493
+ ref: forwardedRef,
494
+ type,
495
+ disabled: disabled || loading,
496
+ className: mergedClassName,
497
+ "data-icon-only": isIconOnly ? "true" : void 0,
498
+ "data-loading": loading ? "true" : void 0,
499
+ "aria-busy": loading ? true : ariaBusy,
500
+ ...otherProps,
501
+ onBlur: composeEventHandlers(eventHandlers.onBlur, onBlur),
502
+ onKeyDown: composeEventHandlers(eventHandlers.onKeyDown, onKeyDown),
503
+ onKeyUp: composeEventHandlers(eventHandlers.onKeyUp, onKeyUp),
504
+ onMouseDown: composeEventHandlers(eventHandlers.onMouseDown, onMouseDown),
505
+ onMouseLeave: composeEventHandlers(eventHandlers.onMouseLeave, onMouseLeave),
506
+ onMouseUp: composeEventHandlers(eventHandlers.onMouseUp, onMouseUp),
507
+ onTouchEnd: composeEventHandlers(eventHandlers.onTouchEnd, onTouchEnd),
508
+ onTouchStart: composeEventHandlers(eventHandlers.onTouchStart, onTouchStart),
509
+ children: /* @__PURE__ */ jsxs2("span", { className: "sublime-button__content", children: [
510
+ visualContent ? /* @__PURE__ */ jsx3("span", { className: "sublime-button__visual", children: visualContent }) : null,
511
+ labelContent !== null && labelContent !== void 0 ? /* @__PURE__ */ jsx3("span", { className: "sublime-button__label", children: labelContent }) : null
512
+ ] })
513
+ }
514
+ );
158
515
  }
159
- return `${neededDefaults.join(" ")} ${userClasses}`.trim();
516
+ );
517
+
518
+ // src/oauth-button.tsx
519
+ import { jsx as jsx4 } from "react/jsx-runtime";
520
+ var PROVIDER_NAMES = {
521
+ google: "Google",
522
+ discord: "Discord"
523
+ };
524
+ var PROVIDER_ICONS = {
525
+ google: GoogleIcon,
526
+ discord: DiscordIcon
527
+ };
528
+ function mergeClassNames2(...classNames) {
529
+ return classNames.filter(Boolean).join(" ");
160
530
  }
161
- var OAuthButton = forwardRef(
531
+ var OAuthButton = forwardRef2(
162
532
  function OAuthButton2(props, forwardedRef) {
163
533
  const {
534
+ "aria-label": ariaLabel,
164
535
  provider,
165
536
  onClick,
166
537
  loading = false,
538
+ loadingAnimation = "spinner",
539
+ disabled = false,
540
+ variant = "secondary",
541
+ animation = "press",
167
542
  className,
168
543
  children,
169
- disabled = false,
170
544
  ...otherProps
171
545
  } = props;
172
- const isDisabled = disabled || loading;
173
- const Icon = getProviderIcon(provider);
546
+ const isIconOnly = children === null;
547
+ const Icon = PROVIDER_ICONS[provider];
174
548
  const defaultText = `Continuar con ${PROVIDER_NAMES[provider]}`;
175
- const mergedClassName = useMemo(
176
- () => mergeButtonClasses(className, isDisabled),
177
- [className, isDisabled]
178
- );
179
- return /* @__PURE__ */ jsx2(
180
- Button,
549
+ const buttonLabel = loading ? children ?? "Conectando..." : children ?? defaultText;
550
+ const resolvedAriaLabel = ariaLabel ?? (isIconOnly ? defaultText : void 0);
551
+ return /* @__PURE__ */ jsx4(
552
+ BaseButton,
181
553
  {
182
554
  ref: forwardedRef,
183
555
  onClick,
184
- disabled: isDisabled,
185
- "aria-busy": loading,
186
- className: mergedClassName,
556
+ disabled,
557
+ animation,
558
+ variant,
559
+ loading,
560
+ loadingAnimation,
561
+ isIconOnly,
562
+ leadingVisual: /* @__PURE__ */ jsx4(Icon, { size: 20 }),
563
+ className: mergeClassNames2("sublime-auth-button", className),
564
+ "data-provider": provider,
565
+ "aria-label": resolvedAriaLabel,
187
566
  ...otherProps,
188
- children: loading ? /* @__PURE__ */ jsxs2(Fragment, { children: [
189
- /* @__PURE__ */ jsx2(SpinnerIcon, {}),
190
- children !== null && /* @__PURE__ */ jsx2("span", { children: children ?? "Conectando..." })
191
- ] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
192
- /* @__PURE__ */ jsx2(Icon, {}),
193
- children !== null && /* @__PURE__ */ jsx2("span", { children: children ?? defaultText })
194
- ] })
567
+ children: buttonLabel
195
568
  }
196
569
  );
197
570
  }
198
571
  );
199
- var oauth_button_default = OAuthButton;
200
572
  export {
201
573
  DiscordIcon,
202
574
  GoogleIcon,
203
575
  OAuthButton,
204
- SpinnerIcon,
205
- oauth_button_default as default
576
+ useButtonAnimation
206
577
  };
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@sublimee/auth-ui",
3
- "version": "0.1.0",
4
- "description": "Headless authentication UI components for Sublime",
3
+ "version": "0.1.12",
4
+ "description": "Production-ready authentication UI components for Sublime",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
8
8
  "files": [
9
9
  "dist",
10
- "src"
10
+ "src",
11
+ "AI_INDEX.md"
11
12
  ],
12
13
  "exports": {
13
14
  ".": {
@@ -15,6 +16,7 @@
15
16
  "import": "./dist/index.mjs",
16
17
  "require": "./dist/index.js"
17
18
  },
19
+ "./animations.css": "./dist/animations.css",
18
20
  "./package.json": "./package.json"
19
21
  },
20
22
  "publishConfig": {
@@ -31,14 +33,15 @@
31
33
  "oauth",
32
34
  "ui",
33
35
  "components",
34
- "headless",
36
+ "semantic",
35
37
  "base-ui"
36
38
  ],
37
39
  "author": "Sublime Team",
38
40
  "license": "MIT",
39
41
  "peerDependencies": {
40
42
  "react": "^19.0.0",
41
- "react-dom": "^19.0.0"
43
+ "react-dom": "^19.0.0",
44
+ "@sublimee/tokens": "0.1.10"
42
45
  },
43
46
  "dependencies": {
44
47
  "@base-ui/react": "^1.0.0"
@@ -50,7 +53,7 @@
50
53
  "typescript": "^5"
51
54
  },
52
55
  "scripts": {
53
- "build": "tsup src/index.ts --format cjs,esm --dts --clean",
56
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean && cp src/animations.css dist/animations.css",
54
57
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
55
58
  "typecheck": "tsc --noEmit"
56
59
  }