@authdog/react-elements 0.0.40 → 0.0.42

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.
Files changed (66) hide show
  1. package/.eslintrc.js +1 -1
  2. package/.storybook/main.ts +21 -0
  3. package/.storybook/preview.ts +17 -0
  4. package/.storybook/vitest.setup.ts +7 -0
  5. package/.turbo/turbo-build.log +43 -43
  6. package/CHANGELOG.md +12 -0
  7. package/dist/components/ui/alert.js.map +1 -1
  8. package/dist/components/ui/alert.mjs.map +1 -1
  9. package/dist/components/ui/avatar.js.map +1 -1
  10. package/dist/components/ui/avatar.mjs.map +1 -1
  11. package/dist/components/ui/badge.js.map +1 -1
  12. package/dist/components/ui/badge.mjs.map +1 -1
  13. package/dist/components/ui/card.js.map +1 -1
  14. package/dist/components/ui/card.mjs.map +1 -1
  15. package/dist/components/ui/dropdown-menu.js +1 -1
  16. package/dist/components/ui/dropdown-menu.js.map +1 -1
  17. package/dist/components/ui/dropdown-menu.mjs +1 -1
  18. package/dist/components/ui/dropdown-menu.mjs.map +1 -1
  19. package/dist/components/ui/input.js.map +1 -1
  20. package/dist/components/ui/input.mjs.map +1 -1
  21. package/dist/components/ui/label.js.map +1 -1
  22. package/dist/components/ui/label.mjs.map +1 -1
  23. package/dist/components/ui/separator.js.map +1 -1
  24. package/dist/components/ui/separator.mjs.map +1 -1
  25. package/dist/components/ui/sheet.js.map +1 -1
  26. package/dist/components/ui/sheet.mjs.map +1 -1
  27. package/dist/index.d.mts +3 -1
  28. package/dist/index.d.ts +3 -1
  29. package/dist/index.js +1 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +1 -1
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/styles.css +217 -7
  34. package/package.json +21 -10
  35. package/src/components/core/user-dropdown.tsx +22 -4
  36. package/src/components/icons.tsx +6 -12
  37. package/src/components/ui/alert.tsx +1 -1
  38. package/src/components/ui/avatar.tsx +1 -1
  39. package/src/components/ui/badge.tsx +1 -1
  40. package/src/components/ui/card.tsx +1 -1
  41. package/src/components/ui/dropdown-menu.tsx +198 -197
  42. package/src/components/ui/input.tsx +1 -1
  43. package/src/components/ui/label.tsx +1 -1
  44. package/src/components/ui/separator.tsx +1 -1
  45. package/src/components/ui/sheet.tsx +1 -1
  46. package/src/stories/core/Navbar.stories.tsx +45 -0
  47. package/src/stories/core/PlaceholderAlert.stories.tsx +23 -0
  48. package/src/stories/core/UserDropdown.stories.tsx +56 -0
  49. package/src/stories/core/UserProfile.stories.tsx +47 -0
  50. package/src/stories/flow/LoginForm.stories.tsx +20 -0
  51. package/src/stories/flow/TotpValidator.stories.tsx +23 -0
  52. package/src/stories/showcase/Landing.stories.tsx +376 -0
  53. package/src/stories/ui/Button.stories.tsx +45 -0
  54. package/vitest.config.ts +39 -0
  55. package/vitest.shims.d.ts +1 -0
  56. package/wrangler.prod.toml +4 -0
  57. package/ladle.config.mjs +0 -21
  58. package/src/main.tsx +0 -9
  59. package/src/preview.tsx +0 -7
  60. package/src/stories/Button._stories.tsx +0 -28
  61. package/src/stories/LoginForm.stories.tsx +0 -29
  62. package/src/stories/Navbar._stories.tsx +0 -66
  63. package/src/stories/PlaceholderAlert._stories.tsx +0 -13
  64. package/src/stories/TotpValidator.stories.tsx +0 -16
  65. package/src/stories/UserDropdown.stories.tsx +0 -34
  66. package/src/stories/UserProfile.stories.tsx +0 -46
package/dist/styles.css CHANGED
@@ -665,9 +665,24 @@ video {
665
665
  .mt-1 {
666
666
  margin-top: 0.25rem;
667
667
  }
668
+ .mt-10 {
669
+ margin-top: 2.5rem;
670
+ }
668
671
  .mt-2 {
669
672
  margin-top: 0.5rem;
670
673
  }
674
+ .mt-3 {
675
+ margin-top: 0.75rem;
676
+ }
677
+ .mt-4 {
678
+ margin-top: 1rem;
679
+ }
680
+ .mt-6 {
681
+ margin-top: 1.5rem;
682
+ }
683
+ .mt-8 {
684
+ margin-top: 2rem;
685
+ }
671
686
  .mt-auto {
672
687
  margin-top: auto;
673
688
  }
@@ -680,6 +695,9 @@ video {
680
695
  .inline-block {
681
696
  display: inline-block;
682
697
  }
698
+ .inline {
699
+ display: inline;
700
+ }
683
701
  .flex {
684
702
  display: flex;
685
703
  }
@@ -818,6 +836,12 @@ video {
818
836
  .min-w-\[8rem\] {
819
837
  min-width: 8rem;
820
838
  }
839
+ .max-w-3xl {
840
+ max-width: 48rem;
841
+ }
842
+ .max-w-6xl {
843
+ max-width: 72rem;
844
+ }
821
845
  .max-w-md {
822
846
  max-width: 28rem;
823
847
  }
@@ -868,12 +892,18 @@ video {
868
892
  .flex-col {
869
893
  flex-direction: column;
870
894
  }
895
+ .flex-wrap {
896
+ flex-wrap: wrap;
897
+ }
871
898
  .items-start {
872
899
  align-items: flex-start;
873
900
  }
874
901
  .items-center {
875
902
  align-items: center;
876
903
  }
904
+ .justify-start {
905
+ justify-content: flex-start;
906
+ }
877
907
  .justify-end {
878
908
  justify-content: flex-end;
879
909
  }
@@ -892,6 +922,12 @@ video {
892
922
  .gap-1\.5 {
893
923
  gap: 0.375rem;
894
924
  }
925
+ .gap-12 {
926
+ gap: 3rem;
927
+ }
928
+ .gap-16 {
929
+ gap: 4rem;
930
+ }
895
931
  .gap-2 {
896
932
  gap: 0.5rem;
897
933
  }
@@ -904,6 +940,9 @@ video {
904
940
  .gap-6 {
905
941
  gap: 1.5rem;
906
942
  }
943
+ .gap-8 {
944
+ gap: 2rem;
945
+ }
907
946
  .gap-y-0\.5 {
908
947
  row-gap: 0.125rem;
909
948
  }
@@ -942,6 +981,11 @@ video {
942
981
  margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
943
982
  margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
944
983
  }
984
+ .space-y-8 > :not([hidden]) ~ :not([hidden]) {
985
+ --tw-space-y-reverse: 0;
986
+ margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
987
+ margin-bottom: calc(2rem * var(--tw-space-y-reverse));
988
+ }
945
989
  .self-start {
946
990
  align-self: flex-start;
947
991
  }
@@ -968,6 +1012,18 @@ video {
968
1012
  .rounded {
969
1013
  border-radius: 0.25rem;
970
1014
  }
1015
+ .rounded-2xl {
1016
+ border-radius: 1rem;
1017
+ }
1018
+ .rounded-3xl {
1019
+ border-radius: 1.5rem;
1020
+ }
1021
+ .rounded-\[28px\] {
1022
+ border-radius: 28px;
1023
+ }
1024
+ .rounded-\[32px\] {
1025
+ border-radius: 32px;
1026
+ }
971
1027
  .rounded-full {
972
1028
  border-radius: 9999px;
973
1029
  }
@@ -986,6 +1042,9 @@ video {
986
1042
  .border {
987
1043
  border-width: 1px;
988
1044
  }
1045
+ .border-0 {
1046
+ border-width: 0px;
1047
+ }
989
1048
  .border-2 {
990
1049
  border-width: 2px;
991
1050
  }
@@ -1011,6 +1070,9 @@ video {
1011
1070
  .border-border {
1012
1071
  border-color: hsl(var(--border));
1013
1072
  }
1073
+ .border-emerald-400\/30 {
1074
+ border-color: rgb(52 211 153 / 0.3);
1075
+ }
1014
1076
  .border-green-200 {
1015
1077
  --tw-border-opacity: 1;
1016
1078
  border-color: rgb(187 247 208 / var(--tw-border-opacity, 1));
@@ -1025,6 +1087,15 @@ video {
1025
1087
  .border-transparent {
1026
1088
  border-color: transparent;
1027
1089
  }
1090
+ .border-white\/10 {
1091
+ border-color: rgb(255 255 255 / 0.1);
1092
+ }
1093
+ .border-white\/15 {
1094
+ border-color: rgb(255 255 255 / 0.15);
1095
+ }
1096
+ .border-white\/20 {
1097
+ border-color: rgb(255 255 255 / 0.2);
1098
+ }
1028
1099
  .bg-amber-100 {
1029
1100
  --tw-bg-opacity: 1;
1030
1101
  background-color: rgb(254 243 199 / var(--tw-bg-opacity, 1));
@@ -1048,6 +1119,12 @@ video {
1048
1119
  .bg-destructive {
1049
1120
  background-color: hsl(var(--destructive));
1050
1121
  }
1122
+ .bg-emerald-500\/10 {
1123
+ background-color: rgb(16 185 129 / 0.1);
1124
+ }
1125
+ .bg-emerald-500\/20 {
1126
+ background-color: rgb(16 185 129 / 0.2);
1127
+ }
1051
1128
  .bg-gray-100 {
1052
1129
  --tw-bg-opacity: 1;
1053
1130
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
@@ -1080,6 +1157,13 @@ video {
1080
1157
  .bg-secondary {
1081
1158
  background-color: hsl(var(--secondary));
1082
1159
  }
1160
+ .bg-slate-900\/70 {
1161
+ background-color: rgb(15 23 42 / 0.7);
1162
+ }
1163
+ .bg-slate-950 {
1164
+ --tw-bg-opacity: 1;
1165
+ background-color: rgb(2 6 23 / var(--tw-bg-opacity, 1));
1166
+ }
1083
1167
  .bg-transparent {
1084
1168
  background-color: transparent;
1085
1169
  }
@@ -1087,16 +1171,22 @@ video {
1087
1171
  --tw-bg-opacity: 1;
1088
1172
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
1089
1173
  }
1090
- .bg-gradient-to-r {
1091
- background-image: linear-gradient(to right, var(--tw-gradient-stops));
1174
+ .bg-white\/10 {
1175
+ background-color: rgb(255 255 255 / 0.1);
1092
1176
  }
1093
- .from-blue-500 {
1094
- --tw-gradient-from: #3b82f6 var(--tw-gradient-from-position);
1095
- --tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);
1177
+ .bg-white\/5 {
1178
+ background-color: rgb(255 255 255 / 0.05);
1179
+ }
1180
+ .bg-gradient-to-br {
1181
+ background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
1182
+ }
1183
+ .from-slate-900\/60 {
1184
+ --tw-gradient-from: rgb(15 23 42 / 0.6) var(--tw-gradient-from-position);
1185
+ --tw-gradient-to: rgb(15 23 42 / 0) var(--tw-gradient-to-position);
1096
1186
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
1097
1187
  }
1098
- .to-purple-500 {
1099
- --tw-gradient-to: #a855f7 var(--tw-gradient-to-position);
1188
+ .to-slate-900\/20 {
1189
+ --tw-gradient-to: rgb(15 23 42 / 0.2) var(--tw-gradient-to-position);
1100
1190
  }
1101
1191
  .fill-current {
1102
1192
  fill: currentColor;
@@ -1119,9 +1209,15 @@ video {
1119
1209
  .p-4 {
1120
1210
  padding: 1rem;
1121
1211
  }
1212
+ .p-5 {
1213
+ padding: 1.25rem;
1214
+ }
1122
1215
  .p-6 {
1123
1216
  padding: 1.5rem;
1124
1217
  }
1218
+ .p-8 {
1219
+ padding: 2rem;
1220
+ }
1125
1221
  .px-2 {
1126
1222
  padding-left: 0.5rem;
1127
1223
  padding-right: 0.5rem;
@@ -1162,6 +1258,10 @@ video {
1162
1258
  padding-top: 3rem;
1163
1259
  padding-bottom: 3rem;
1164
1260
  }
1261
+ .py-16 {
1262
+ padding-top: 4rem;
1263
+ padding-bottom: 4rem;
1264
+ }
1165
1265
  .py-2 {
1166
1266
  padding-top: 0.5rem;
1167
1267
  padding-bottom: 0.5rem;
@@ -1192,13 +1292,27 @@ video {
1192
1292
  .pt-6 {
1193
1293
  padding-top: 1.5rem;
1194
1294
  }
1295
+ .text-left {
1296
+ text-align: left;
1297
+ }
1195
1298
  .text-center {
1196
1299
  text-align: center;
1197
1300
  }
1301
+ .font-mono {
1302
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
1303
+ }
1198
1304
  .text-2xl {
1199
1305
  font-size: 1.5rem;
1200
1306
  line-height: 2rem;
1201
1307
  }
1308
+ .text-3xl {
1309
+ font-size: 1.875rem;
1310
+ line-height: 2.25rem;
1311
+ }
1312
+ .text-4xl {
1313
+ font-size: 2.25rem;
1314
+ line-height: 2.5rem;
1315
+ }
1202
1316
  .text-base {
1203
1317
  font-size: 1rem;
1204
1318
  line-height: 1.5rem;
@@ -1231,12 +1345,27 @@ video {
1231
1345
  .font-semibold {
1232
1346
  font-weight: 600;
1233
1347
  }
1348
+ .uppercase {
1349
+ text-transform: uppercase;
1350
+ }
1234
1351
  .leading-none {
1235
1352
  line-height: 1;
1236
1353
  }
1354
+ .leading-relaxed {
1355
+ line-height: 1.625;
1356
+ }
1357
+ .leading-tight {
1358
+ line-height: 1.25;
1359
+ }
1360
+ .tracking-\[0\.3em\] {
1361
+ letter-spacing: 0.3em;
1362
+ }
1237
1363
  .tracking-tight {
1238
1364
  letter-spacing: -0.025em;
1239
1365
  }
1366
+ .tracking-wide {
1367
+ letter-spacing: 0.025em;
1368
+ }
1240
1369
  .tracking-widest {
1241
1370
  letter-spacing: 0.1em;
1242
1371
  }
@@ -1257,6 +1386,14 @@ video {
1257
1386
  .text-destructive-foreground {
1258
1387
  color: hsl(var(--destructive-foreground));
1259
1388
  }
1389
+ .text-emerald-100 {
1390
+ --tw-text-opacity: 1;
1391
+ color: rgb(209 250 229 / var(--tw-text-opacity, 1));
1392
+ }
1393
+ .text-emerald-200 {
1394
+ --tw-text-opacity: 1;
1395
+ color: rgb(167 243 208 / var(--tw-text-opacity, 1));
1396
+ }
1260
1397
  .text-foreground {
1261
1398
  color: hsl(var(--foreground));
1262
1399
  }
@@ -1315,10 +1452,27 @@ video {
1315
1452
  .text-secondary-foreground {
1316
1453
  color: hsl(var(--secondary-foreground));
1317
1454
  }
1455
+ .text-slate-300 {
1456
+ --tw-text-opacity: 1;
1457
+ color: rgb(203 213 225 / var(--tw-text-opacity, 1));
1458
+ }
1459
+ .text-slate-900 {
1460
+ --tw-text-opacity: 1;
1461
+ color: rgb(15 23 42 / var(--tw-text-opacity, 1));
1462
+ }
1318
1463
  .text-white {
1319
1464
  --tw-text-opacity: 1;
1320
1465
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
1321
1466
  }
1467
+ .text-white\/60 {
1468
+ color: rgb(255 255 255 / 0.6);
1469
+ }
1470
+ .text-white\/70 {
1471
+ color: rgb(255 255 255 / 0.7);
1472
+ }
1473
+ .text-white\/80 {
1474
+ color: rgb(255 255 255 / 0.8);
1475
+ }
1322
1476
  .underline-offset-4 {
1323
1477
  text-underline-offset: 4px;
1324
1478
  }
@@ -1333,6 +1487,26 @@ video {
1333
1487
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
1334
1488
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1335
1489
  }
1490
+ .shadow-2xl {
1491
+ --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
1492
+ --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
1493
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1494
+ }
1495
+ .shadow-\[0_20px_80px_rgba\(15\2c 23\2c 42\2c 0\.4\)\] {
1496
+ --tw-shadow: 0 20px 80px rgba(15,23,42,0.4);
1497
+ --tw-shadow-colored: 0 20px 80px var(--tw-shadow-color);
1498
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1499
+ }
1500
+ .shadow-\[0_40px_120px_rgba\(15\2c 23\2c 42\2c 0\.35\)\] {
1501
+ --tw-shadow: 0 40px 120px rgba(15,23,42,0.35);
1502
+ --tw-shadow-colored: 0 40px 120px var(--tw-shadow-color);
1503
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1504
+ }
1505
+ .shadow-inner {
1506
+ --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
1507
+ --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
1508
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1509
+ }
1336
1510
  .shadow-lg {
1337
1511
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
1338
1512
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
@@ -1363,6 +1537,11 @@ video {
1363
1537
  .ring-offset-background {
1364
1538
  --tw-ring-offset-color: hsl(var(--background));
1365
1539
  }
1540
+ .backdrop-blur {
1541
+ --tw-backdrop-blur: blur(8px);
1542
+ -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
1543
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
1544
+ }
1366
1545
  .transition {
1367
1546
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
1368
1547
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
@@ -1467,6 +1646,9 @@ video {
1467
1646
  .hover\:bg-destructive\/90:hover {
1468
1647
  background-color: hsl(var(--destructive) / 0.9);
1469
1648
  }
1649
+ .hover\:bg-emerald-500\/30:hover {
1650
+ background-color: rgb(16 185 129 / 0.3);
1651
+ }
1470
1652
  .hover\:bg-gray-100:hover {
1471
1653
  --tw-bg-opacity: 1;
1472
1654
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
@@ -1487,6 +1669,9 @@ video {
1487
1669
  .hover\:bg-secondary\/80:hover {
1488
1670
  background-color: hsl(var(--secondary) / 0.8);
1489
1671
  }
1672
+ .hover\:bg-white\/90:hover {
1673
+ background-color: rgb(255 255 255 / 0.9);
1674
+ }
1490
1675
  .hover\:text-accent-foreground:hover {
1491
1676
  color: hsl(var(--accent-foreground));
1492
1677
  }
@@ -1790,10 +1975,19 @@ video {
1790
1975
  max-width: 24rem;
1791
1976
  }
1792
1977
 
1978
+ .sm\:grid-cols-3 {
1979
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1980
+ }
1981
+
1793
1982
  .sm\:px-6 {
1794
1983
  padding-left: 1.5rem;
1795
1984
  padding-right: 1.5rem;
1796
1985
  }
1986
+
1987
+ .sm\:text-5xl {
1988
+ font-size: 3rem;
1989
+ line-height: 1;
1990
+ }
1797
1991
  }
1798
1992
  @media (min-width: 768px) {
1799
1993
 
@@ -1809,6 +2003,14 @@ video {
1809
2003
  display: none;
1810
2004
  }
1811
2005
 
2006
+ .md\:grid-cols-2 {
2007
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2008
+ }
2009
+
2010
+ .md\:grid-cols-3 {
2011
+ grid-template-columns: repeat(3, minmax(0, 1fr));
2012
+ }
2013
+
1812
2014
  .md\:space-y-6 > :not([hidden]) ~ :not([hidden]) {
1813
2015
  --tw-space-y-reverse: 0;
1814
2016
  margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
@@ -1835,6 +2037,14 @@ video {
1835
2037
  }
1836
2038
  @media (min-width: 1024px) {
1837
2039
 
2040
+ .lg\:grid-cols-4 {
2041
+ grid-template-columns: repeat(4, minmax(0, 1fr));
2042
+ }
2043
+
2044
+ .lg\:grid-cols-\[1\.2fr_minmax\(0\2c 1fr\)\] {
2045
+ grid-template-columns: 1.2fr minmax(0,1fr);
2046
+ }
2047
+
1838
2048
  .lg\:px-8 {
1839
2049
  padding-left: 2rem;
1840
2050
  padding-right: 2rem;
package/package.json CHANGED
@@ -1,29 +1,39 @@
1
1
  {
2
2
  "name": "@authdog/react-elements",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.mts",
7
7
  "peerDependencies": {
8
- "react": "^19.1.0",
9
- "react-dom": "^19.1.0"
8
+ "react": "19.0.0",
9
+ "react-dom": "19.0.0"
10
10
  },
11
11
  "devDependencies": {
12
- "@ladle/react": "^2.0.0",
13
- "@types/node": "^20",
14
- "@types/react": "^19.1.0",
15
- "@types/react-dom": "^19.1.0",
12
+ "@storybook/addon-a11y": "^10.1.3",
13
+ "@storybook/addon-docs": "10.1.3",
14
+ "@storybook/addon-links": "^10.1.3",
15
+ "@storybook/react-vite": "^10.1.3",
16
+ "@types/node": "22.10.10",
17
+ "@types/react": "19.1.8",
18
+ "@types/react-dom": "19.0.0",
16
19
  "@vitejs/plugin-react": "^4.4.1",
17
20
  "autoprefixer": "^10",
18
21
  "css-loader": "^6.8.1",
22
+ "eslint-plugin-storybook": "^10.1.3",
23
+ "next": "15.1.6",
19
24
  "postcss": "^8",
20
25
  "postcss-cli": "^11.0.1",
21
26
  "postcss-import": "^16.1.0",
22
27
  "postcss-load-config": "^6",
28
+ "react": "19.0.0",
29
+ "react-dom": "19.0.0",
30
+ "react-tweet": "^3.2.1",
31
+ "storybook": "^10.1.3",
23
32
  "style-loader": "^3.3.3",
24
33
  "tailwindcss": "3.4.18",
25
34
  "ts-loader": "^9.5.1",
26
- "typescript": "^5.6.3",
35
+ "typescript": "5.7.3",
36
+ "vite": "^4.5.0",
27
37
  "webpack": "^5.89.0",
28
38
  "@authdog/eslint-config": "0.0.0",
29
39
  "@authdog/typescript-config": "0.0.0"
@@ -72,7 +82,8 @@
72
82
  "lint": "eslint .",
73
83
  "build:styles": "postcss src/global.css -o dist/styles.css",
74
84
  "build": "pnpm tsup && pnpm build:styles",
75
- "ladle": "ladle serve",
76
- "ladle:build": "ladle build"
85
+ "storybook": "storybook dev -p 7007",
86
+ "build-storybook": "storybook build",
87
+ "deploy-docs": "wrangler pages deploy"
77
88
  }
78
89
  }
@@ -12,8 +12,9 @@ import {
12
12
  AvatarFallback,
13
13
  AvatarImage,
14
14
  } from "../../components/ui/avatar";
15
- import { cn } from "@authdog/react-elements/lib/utils";
15
+ import { cn } from "../../lib/utils";
16
16
  import { LogOut, Settings, ExternalLink } from "lucide-react";
17
+ import type { ComponentType } from "react";
17
18
 
18
19
  export type UserDropdownLink = {
19
20
  label: string;
@@ -40,6 +41,8 @@ export interface UserDropdownProps {
40
41
  align?: "start" | "center" | "end";
41
42
  sideOffset?: number;
42
43
  modal?: boolean;
44
+ triggerAsChild?: boolean;
45
+ triggerWrapperClassName?: string;
43
46
  }
44
47
 
45
48
  const getInitials = (name?: string) => {
@@ -63,6 +66,8 @@ export const UserDropdown = ({
63
66
  align = "end",
64
67
  sideOffset = 8,
65
68
  modal = false,
69
+ triggerAsChild = false,
70
+ triggerWrapperClassName,
66
71
  }: UserDropdownProps) => {
67
72
  const primaryEmail = user?.emails?.[0]?.value || user?.email || "";
68
73
  const displayName = user?.displayName || user?.name || "";
@@ -80,10 +85,23 @@ export const UserDropdown = ({
80
85
  };
81
86
 
82
87
  const IconExternal = ExternalLink as any;
88
+ const SettingsIcon = Settings as ComponentType<any>;
89
+ const LogOutIcon = LogOut as ComponentType<any>;
83
90
 
84
91
  return (
85
92
  <DropdownMenu modal={modal}>
86
- <DropdownMenuTrigger asChild>{trigger}</DropdownMenuTrigger>
93
+ {triggerAsChild ? (
94
+ <DropdownMenuTrigger asChild>{trigger}</DropdownMenuTrigger>
95
+ ) : (
96
+ <DropdownMenuTrigger
97
+ className={cn(
98
+ "inline-flex items-center justify-center bg-transparent p-0 border-0 outline-none focus-visible:outline-none",
99
+ triggerWrapperClassName,
100
+ )}
101
+ >
102
+ {trigger}
103
+ </DropdownMenuTrigger>
104
+ )}
87
105
  <DropdownMenuContent
88
106
  align={align}
89
107
  side={side}
@@ -112,7 +130,7 @@ export const UserDropdown = ({
112
130
  className="cursor-pointer py-2"
113
131
  onClick={() => onManageAccount?.()}
114
132
  >
115
- <Settings className="mr-2 h-4 w-4" />
133
+ <SettingsIcon className="mr-2 h-4 w-4" />
116
134
  <span>Manage account</span>
117
135
  </DropdownMenuItem>
118
136
  {links.map((item, idx) => {
@@ -133,7 +151,7 @@ export const UserDropdown = ({
133
151
  className="cursor-pointer py-2 rounded-md font-semibold text-red-600 dark:text-red-300 hover:bg-red-50 hover:text-red-700 focus:bg-red-50 focus:text-red-700 dark:hover:bg-red-500/20 dark:focus:bg-red-500/25 dark:hover:text-red-100 dark:focus:text-red-100 border border-transparent dark:border-red-500/30 ring-0 focus-visible:ring-2 focus-visible:ring-red-400/40 dark:focus-visible:ring-red-400/40"
134
152
  onClick={() => onSignout?.()}
135
153
  >
136
- <LogOut className="mr-2 h-4 w-4 text-red-600 dark:text-red-300" />
154
+ <LogOutIcon className="mr-2 h-4 w-4 text-red-600 dark:text-red-300" />
137
155
  <span>Sign out</span>
138
156
  </DropdownMenuItem>
139
157
  </DropdownMenuContent>
@@ -6,26 +6,20 @@ const iconProps: LucideProps = {
6
6
  "aria-hidden": "true",
7
7
  };
8
8
 
9
- export const renderIcon = ((Icon: any) => {
9
+ export const IconWrapper = ({ Icon }: { Icon: any }) => {
10
10
  const [isMounted, setIsMounted] = useState(false);
11
11
 
12
12
  useEffect(() => {
13
13
  setIsMounted(true);
14
14
  }, []);
15
15
 
16
- if (!isMounted) {
17
- return <span className="mr-2 h-4 w-4" aria-hidden="true" />;
18
- }
19
-
20
- return <Icon {...iconProps} />;
21
- }) as React.FC<{
22
- Icon: any;
23
- }>;
24
-
25
- export const IconWrapper = ({ Icon }: { Icon: any }) => {
26
16
  return (
27
17
  <span className="inline-flex items-center justify-center">
28
- {renderIcon(Icon)}
18
+ {!isMounted ? (
19
+ <span className="mr-2 h-4 w-4" aria-hidden="true" />
20
+ ) : (
21
+ <Icon {...iconProps} />
22
+ )}
29
23
  </span>
30
24
  );
31
25
  };
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { cva, type VariantProps } from "class-variance-authority";
3
3
 
4
- import { cn } from "@authdog/react-elements/lib/utils";
4
+ import { cn } from "../../lib/utils";
5
5
 
6
6
  const alertVariants = cva(
7
7
  "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
@@ -3,7 +3,7 @@
3
3
  import * as React from "react";
4
4
  import * as AvatarPrimitive from "@radix-ui/react-avatar";
5
5
 
6
- import { cn } from "@authdog/react-elements/lib/utils";
6
+ import { cn } from "../../lib/utils";
7
7
 
8
8
  function Avatar({
9
9
  className,
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import { Slot } from "@radix-ui/react-slot";
3
3
  import { cva, type VariantProps } from "class-variance-authority";
4
4
 
5
- import { cn } from "@authdog/react-elements/lib/utils";
5
+ import { cn } from "../../lib/utils";
6
6
 
7
7
  const badgeVariants = cva(
8
8
  "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
 
3
- import { cn } from "@authdog/react-elements/lib/utils";
3
+ import { cn } from "../../lib/utils";
4
4
 
5
5
  function Card({ className, ...props }: React.ComponentProps<"div">) {
6
6
  return (