@hexclave/ui 1.0.2 → 1.0.5

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 (86) hide show
  1. package/dist/components/copy-button.d.ts +1 -1
  2. package/dist/components/simple-tooltip.js +2 -2
  3. package/dist/components/simple-tooltip.js.map +1 -1
  4. package/dist/components/ui/badge.d.ts +2 -2
  5. package/dist/components/ui/button.d.ts +2 -2
  6. package/dist/components/ui/form.d.ts +1 -1
  7. package/dist/components/ui/form.d.ts.map +1 -1
  8. package/dist/components/ui/resizable.d.ts +1 -1
  9. package/dist/components/ui/resizable.d.ts.map +1 -1
  10. package/dist/components/ui/typography.d.ts +1 -1
  11. package/dist/esm/components/copy-button.d.ts +1 -1
  12. package/dist/esm/components/simple-tooltip.js +3 -3
  13. package/dist/esm/components/simple-tooltip.js.map +1 -1
  14. package/dist/esm/components/ui/badge.d.ts +2 -2
  15. package/dist/esm/components/ui/button.d.ts +2 -2
  16. package/dist/esm/components/ui/form.d.ts +1 -1
  17. package/dist/esm/components/ui/form.d.ts.map +1 -1
  18. package/dist/esm/components/ui/resizable.d.ts +1 -1
  19. package/dist/esm/components/ui/resizable.d.ts.map +1 -1
  20. package/dist/esm/components/ui/typography.d.ts +1 -1
  21. package/package.json +3 -2
  22. package/src/components/action-dialog.tsx +135 -0
  23. package/src/components/brand-icons.tsx +276 -0
  24. package/src/components/browser-frame/LICENSE +3 -0
  25. package/src/components/browser-frame/index.tsx +51 -0
  26. package/src/components/copy-button.tsx +36 -0
  27. package/src/components/copy-field.tsx +52 -0
  28. package/src/components/data-table/cells.tsx +133 -0
  29. package/src/components/data-table/column-header.tsx +52 -0
  30. package/src/components/data-table/data-table.tsx +318 -0
  31. package/src/components/data-table/faceted-filter.tsx +138 -0
  32. package/src/components/data-table/index.tsx +9 -0
  33. package/src/components/data-table/pagination.tsx +76 -0
  34. package/src/components/data-table/toolbar-items.tsx +13 -0
  35. package/src/components/data-table/toolbar.tsx +100 -0
  36. package/src/components/data-table/utils.tsx +7 -0
  37. package/src/components/data-table/view-options.tsx +64 -0
  38. package/src/components/simple-tooltip.tsx +48 -0
  39. package/src/components/ui/accordion.tsx +58 -0
  40. package/src/components/ui/alert.tsx +60 -0
  41. package/src/components/ui/aspect-ratio.tsx +7 -0
  42. package/src/components/ui/avatar.tsx +51 -0
  43. package/src/components/ui/badge.tsx +36 -0
  44. package/src/components/ui/breadcrumb.tsx +116 -0
  45. package/src/components/ui/button.tsx +95 -0
  46. package/src/components/ui/calendar.tsx +77 -0
  47. package/src/components/ui/card.tsx +88 -0
  48. package/src/components/ui/checkbox.tsx +31 -0
  49. package/src/components/ui/collapsible.tsx +11 -0
  50. package/src/components/ui/command.tsx +159 -0
  51. package/src/components/ui/context-menu.tsx +205 -0
  52. package/src/components/ui/dialog.tsx +135 -0
  53. package/src/components/ui/dropdown-menu.tsx +245 -0
  54. package/src/components/ui/form.tsx +173 -0
  55. package/src/components/ui/hover-card.tsx +30 -0
  56. package/src/components/ui/inline-code.tsx +40 -0
  57. package/src/components/ui/input-otp.tsx +73 -0
  58. package/src/components/ui/input.tsx +68 -0
  59. package/src/components/ui/label.tsx +40 -0
  60. package/src/components/ui/menubar.tsx +241 -0
  61. package/src/components/ui/navigation-menu.tsx +131 -0
  62. package/src/components/ui/password-input.tsx +50 -0
  63. package/src/components/ui/popover.tsx +34 -0
  64. package/src/components/ui/progress.tsx +29 -0
  65. package/src/components/ui/radio-group.tsx +45 -0
  66. package/src/components/ui/resizable.tsx +45 -0
  67. package/src/components/ui/scroll-area.tsx +49 -0
  68. package/src/components/ui/select.tsx +162 -0
  69. package/src/components/ui/separator.tsx +32 -0
  70. package/src/components/ui/sheet.tsx +139 -0
  71. package/src/components/ui/skeleton.tsx +23 -0
  72. package/src/components/ui/slider.tsx +29 -0
  73. package/src/components/ui/spinner.tsx +18 -0
  74. package/src/components/ui/switch.tsx +75 -0
  75. package/src/components/ui/table.tsx +117 -0
  76. package/src/components/ui/tabs.tsx +56 -0
  77. package/src/components/ui/textarea.tsx +24 -0
  78. package/src/components/ui/toast.tsx +135 -0
  79. package/src/components/ui/toaster.tsx +35 -0
  80. package/src/components/ui/toggle-group.tsx +62 -0
  81. package/src/components/ui/toggle.tsx +46 -0
  82. package/src/components/ui/tooltip.tsx +40 -0
  83. package/src/components/ui/typography.tsx +47 -0
  84. package/src/components/ui/use-toast.tsx +195 -0
  85. package/src/index.ts +54 -0
  86. package/src/lib/utils.tsx +6 -0
@@ -0,0 +1,276 @@
1
+ import { HexclaveAssertionError, throwErr } from "@hexclave/shared/dist/utils/errors";
2
+
3
+ export function Google({ iconSize }: { iconSize: number }) {
4
+ return (
5
+ <svg xmlns="http://www.w3.org/2000/svg" width={iconSize} height={iconSize} viewBox="0 0 24 24">
6
+ <path fill="#4285F4"
7
+ d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
8
+ <path fill="#34A853"
9
+ d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
10
+ <path fill="#FBBC05"
11
+ d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
12
+ <path fill="#EA4335"
13
+ d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
14
+ <path fill="none" d="M1 1h22v22H1z"/>
15
+ </svg>
16
+ );
17
+ }
18
+
19
+ export function Facebook({ iconSize }: { iconSize: number }) {
20
+ return (
21
+ <svg xmlns="http://www.w3.org/2000/svg" width={iconSize} height={iconSize} viewBox="0 0 512 512">
22
+ <path fill='#FFFFFF'
23
+ d="M512 256C512 114.6 397.4 0 256 0S0 114.6 0 256C0 376 82.7 476.8 194.2 504.5V334.2H141.4V256h52.8V222.3c0-87.1 39.4-127.5 125-127.5c16.2 0 44.2 3.2 55.7 6.4V172c-6-.6-16.5-1-29.6-1c-42 0-58.2 15.9-58.2 57.2V256h83.6l-14.4 78.2H287V510.1C413.8 494.8 512 386.9 512 256h0z"/>
24
+ </svg>
25
+ );
26
+ }
27
+
28
+ export function GitHub({ iconSize }: { iconSize: number }) {
29
+ return (
30
+ <svg xmlns="http://www.w3.org/2000/svg" width={iconSize} height={iconSize} viewBox="0 0 496 512">
31
+ <path fill='#FFFFFF'
32
+ d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/>
33
+ </svg>
34
+ );
35
+ }
36
+
37
+ export function Microsoft({ iconSize }: { iconSize: number }) {
38
+ return (
39
+ <svg xmlns="http://www.w3.org/2000/svg" width={iconSize} height={iconSize} viewBox="0 0 21 21">
40
+ <title>{"MS-SymbolLockup"}</title>
41
+ <path fill="#f25022" d="M1 1h9v9H1z"/>
42
+ <path fill="#00a4ef" d="M1 11h9v9H1z"/>
43
+ <path fill="#7fba00" d="M11 1h9v9h-9z"/>
44
+ <path fill="#ffb900" d="M11 11h9v9h-9z"/>
45
+ </svg>
46
+ );
47
+ }
48
+
49
+ export function Spotify({ iconSize }: { iconSize: number }) {
50
+ return (
51
+ <svg xmlns="http://www.w3.org/2000/svg" width={iconSize} height={iconSize} viewBox="0 0 496 512">
52
+ <path fill='#ffffff'
53
+ d="M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"/>
54
+ </svg>
55
+ );
56
+ }
57
+
58
+ export function Discord({ iconSize }: { iconSize: number }) {
59
+ return (
60
+ <svg xmlns="http://www.w3.org/2000/svg" width={iconSize} height={iconSize} viewBox="0 0 127.14 96.36">
61
+ <path fill="#fff"
62
+ d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/>
63
+ </svg>
64
+ );
65
+ }
66
+
67
+ export function Gitlab({ iconSize }: { iconSize: number }) {
68
+ return (
69
+ <svg
70
+ xmlns="http://www.w3.org/2000/svg"
71
+ width={iconSize}
72
+ height={iconSize}
73
+ viewBox="0 -10 256 256"
74
+ version="1.1"
75
+ preserveAspectRatio="xMidYMid"
76
+ >
77
+ <g>
78
+ <path
79
+ d="M128.07485,236.074667 L128.07485,236.074667 L175.17885,91.1043048 L80.9708495,91.1043048 L128.07485,236.074667 L128.07485,236.074667 Z"
80
+ fill="#E24329"></path>
81
+ <path
82
+ d="M128.07485,236.074423 L80.9708495,91.104061 L14.9557638,91.104061 L128.07485,236.074423 L128.07485,236.074423 Z"
83
+ fill="#FC6D26"></path>
84
+ <path
85
+ d="M14.9558857,91.1044267 L14.9558857,91.1044267 L0.641828571,135.159589 C-0.663771429,139.17757 0.766171429,143.57955 4.18438095,146.06275 L128.074971,236.074789 L14.9558857,91.1044267 L14.9558857,91.1044267 Z"
86
+ fill="#FCA326"></path>
87
+ <path
88
+ d="M14.9558857,91.1045486 L80.9709714,91.1045486 L52.6000762,3.79026286 C51.1408762,-0.703146667 44.7847619,-0.701927619 43.3255619,3.79026286 L14.9558857,91.1045486 L14.9558857,91.1045486 Z"
89
+ fill="#E24329"></path>
90
+ <path
91
+ d="M128.07485,236.074423 L175.17885,91.104061 L241.193935,91.104061 L128.07485,236.074423 L128.07485,236.074423 Z"
92
+ fill="#FC6D26"></path>
93
+ <path
94
+ d="M241.193935,91.1044267 L241.193935,91.1044267 L255.507992,135.159589 C256.813592,139.17757 255.38365,143.57955 251.96544,146.06275 L128.07485,236.074789 L241.193935,91.1044267 L241.193935,91.1044267 Z"
95
+ fill="#FCA326"></path>
96
+ <path
97
+ d="M241.193935,91.1045486 L175.17885,91.1045486 L203.549745,3.79026286 C205.008945,-0.703146667 211.365059,-0.701927619 212.824259,3.79026286 L241.193935,91.1045486 L241.193935,91.1045486 Z"
98
+ fill="#E24329"></path>
99
+ </g>
100
+ </svg>
101
+ );
102
+ }
103
+
104
+ export function Bitbucket({ iconSize }: { iconSize: number }) {
105
+ return (
106
+ <svg
107
+ preserveAspectRatio="xMidYMid"
108
+ xmlns="http://www.w3.org/2000/svg"
109
+ viewBox="-0.9662264221278978 -0.5824607696358868 257.93281329857973 230.8324730411935"
110
+ width={iconSize}
111
+ height={iconSize}
112
+ >
113
+ <linearGradient
114
+ id="a"
115
+ x1="108.633%"
116
+ x2="46.927%"
117
+ y1="13.818%"
118
+ y2="78.776%"
119
+ >
120
+ <stop offset=".18" stopColor="#0052cc"/>
121
+ <stop offset="1" stopColor="#2684ff"/>
122
+ </linearGradient>
123
+ <g fill="none">
124
+ <path d="M101.272 152.561h53.449l12.901-75.32H87.06z"/>
125
+ <path
126
+ d="M8.308 0A8.202 8.202 0 0 0 .106 9.516l34.819 211.373a11.155 11.155 0 0 0 10.909 9.31h167.04a8.202 8.202 0 0 0 8.201-6.89l34.82-213.752a8.202 8.202 0 0 0-8.203-9.514zm146.616 152.768h-53.315l-14.436-75.42h80.67z"
127
+ fill="#2684ff"/>
128
+ <path
129
+ d="M244.61 77.242h-76.916l-12.909 75.36h-53.272l-62.902 74.663a11.105 11.105 0 0 0 7.171 2.704H212.73a8.196 8.196 0 0 0 8.196-6.884z"
130
+ fill="url(#a)"/>
131
+ </g>
132
+ </svg>
133
+ );
134
+ }
135
+
136
+ export function LinkedIn({ iconSize }: { iconSize: number }) {
137
+ return (
138
+ <svg
139
+ xmlns="http://www.w3.org/2000/svg"
140
+ fill="#fff"
141
+ height={iconSize}
142
+ width={iconSize}
143
+ viewBox="0 0 310 310"
144
+ >
145
+ <g id="XMLID_801_">
146
+ <path id="XMLID_802_"
147
+ d="M72.16,99.73H9.927c-2.762,0-5,2.239-5,5v199.928c0,2.762,2.238,5,5,5H72.16c2.762,0,5-2.238,5-5V104.73 C77.16,101.969,74.922,99.73,72.16,99.73z"/>
148
+ <path id="XMLID_803_"
149
+ d="M41.066,0.341C18.422,0.341,0,18.743,0,41.362C0,63.991,18.422,82.4,41.066,82.4 c22.626,0,41.033-18.41,41.033-41.038C82.1,18.743,63.692,0.341,41.066,0.341z"/>
150
+ <path id="XMLID_804_"
151
+ d="M230.454,94.761c-24.995,0-43.472,10.745-54.679,22.954V104.73c0-2.761-2.238-5-5-5h-59.599 c-2.762,0-5,2.239-5,5v199.928c0,2.762,2.238,5,5,5h62.097c2.762,0,5-2.238,5-5v-98.918c0-33.333,9.054-46.319,32.29-46.319 c25.306,0,27.317,20.818,27.317,48.034v97.204c0,2.762,2.238,5,5,5H305c2.762,0,5-2.238,5-5V194.995 C310,145.43,300.549,94.761,230.454,94.761z"/>
152
+ </g>
153
+ </svg>
154
+ );
155
+ }
156
+
157
+ export function Apple({ iconSize }: { iconSize: number }) {
158
+ return (
159
+ <svg fill="#fff" height={iconSize} width={iconSize} version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
160
+ viewBox="0 0 22.773 22.773">
161
+ <path
162
+ d="M15.769,0c0.053,0,0.106,0,0.162,0c0.13,1.606-0.483,2.806-1.228,3.675c-0.731,0.863-1.732,1.7-3.351,1.573c-0.108-1.583,0.506-2.694,1.25-3.561C13.292,0.879,14.557,0.16,15.769,0z"/>
163
+ <path
164
+ d="M20.67,16.716c0,0.016,0,0.03,0,0.045c-0.455,1.378-1.104,2.559-1.896,3.655c-0.723,0.995-1.609,2.334-3.191,2.334c-1.367,0-2.275-0.879-3.676-0.903c-1.482-0.024-2.297,0.735-3.652,0.926c-0.155,0-0.31,0-0.462,0c-0.995-0.144-1.798-0.932-2.383-1.642c-1.725-2.098-3.058-4.808-3.306-8.276c0-0.34,0-0.679,0-1.019c0.105-2.482,1.311-4.5,2.914-5.478c0.846-0.52,2.009-0.963,3.304-0.765c0.555,0.086,1.122,0.276,1.619,0.464c0.471,0.181,1.06,0.502,1.618,0.485c0.378-0.011,0.754-0.208,1.135-0.347c1.116-0.403,2.21-0.865,3.652-0.648c1.733,0.262,2.963,1.032,3.723,2.22c-1.466,0.933-2.625,2.339-2.427,4.74C17.818,14.688,19.086,15.964,20.67,16.716z"/>
165
+ </svg>
166
+ );
167
+ }
168
+
169
+ export function X({ iconSize }: { iconSize: number }) {
170
+ return (
171
+ <svg aria-label="X" viewBox="0 0 1200 1227" width={iconSize} height={iconSize}
172
+ xmlns="http://www.w3.org/2000/svg">
173
+ <path fill="#FFFFFF"
174
+ d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z"/>
175
+ </svg>
176
+ );
177
+ }
178
+
179
+ export function Twitch({ iconSize }: { iconSize: number }) {
180
+ return (
181
+ <svg aria-label="Twitch" viewBox="0 0 2400 2800" width={iconSize} height={iconSize}
182
+ xmlns="http://www.w3.org/2000/svg">
183
+ <g>
184
+ <polygon fill={"#FFFFFF"}
185
+ points="2200,1300 1800,1700 1400,1700 1050,2050 1050,1700 600,1700 600,200 2200,200"/>
186
+ <g>
187
+ <g id="Layer_1-2">
188
+ <path fill={"#9146FF"} d="M500,0L0,500v1800h600v500l500-500h400l900-900V0H500z M2200,1300l-400,400h-400l-350,350v-350H600V200h1600 V1300z"/>
189
+ <rect x="1700" y="550" fill={"#9146FF"} width="200" height="600"/>
190
+ <rect x="1150" y="550" fill={"#9146FF"} width="200" height="600"/>
191
+ </g>
192
+ </g>
193
+ </g>
194
+ </svg>
195
+ );
196
+ }
197
+
198
+ export function Mapping({
199
+ provider,
200
+ iconSize,
201
+ }: {
202
+ provider: string,
203
+ iconSize: number,
204
+ }) {
205
+ switch (provider) {
206
+ case "google": {
207
+ return <Google iconSize={iconSize}/>;
208
+ }
209
+ case "github": {
210
+ return <GitHub iconSize={iconSize}/>;
211
+ }
212
+ case "facebook": {
213
+ return <Facebook iconSize={iconSize}/>;
214
+ }
215
+ case "microsoft": {
216
+ return <Microsoft iconSize={iconSize}/>;
217
+ }
218
+ case "spotify": {
219
+ return <Spotify iconSize={iconSize}/>;
220
+ }
221
+ case "discord": {
222
+ return <Discord iconSize={iconSize}/>;
223
+ }
224
+ case "gitlab": {
225
+ return <Gitlab iconSize={iconSize}/>;
226
+ }
227
+ case "bitbucket": {
228
+ return <Bitbucket iconSize={iconSize}/>;
229
+ }
230
+ case "linkedin": {
231
+ return <LinkedIn iconSize={iconSize}/>;
232
+ }
233
+ case "apple": {
234
+ return <Apple iconSize={iconSize}/>;
235
+ }
236
+ case "x": {
237
+ return <X iconSize={iconSize}/>;
238
+ }
239
+ case "twitch": {
240
+ return <Twitch iconSize={iconSize}/>;
241
+ }
242
+ default: {
243
+ throw new HexclaveAssertionError(`Icon not found for provider: ${provider}`);
244
+ }
245
+ }
246
+ }
247
+
248
+ export function toTitle(id: string) {
249
+ return {
250
+ github: "GitHub",
251
+ google: "Google",
252
+ facebook: "Facebook",
253
+ microsoft: "Microsoft",
254
+ spotify: "Spotify",
255
+ discord: "Discord",
256
+ gitlab: "GitLab",
257
+ apple: "Apple",
258
+ bitbucket: "Bitbucket",
259
+ linkedin: "LinkedIn",
260
+ x: "X",
261
+ twitch: "Twitch"
262
+ }[id] || throwErr(`Unknown provider: ${id}`);
263
+ }
264
+
265
+ export const BRAND_COLORS: Record<string, string> = {
266
+ github: '#24292e',
267
+ google: '#ffffff',
268
+ facebook: '#0866FF',
269
+ microsoft: '#2F2F2F',
270
+ spotify: '#1DD65F',
271
+ discord: '#5661F5',
272
+ linkedin: '#0A66C2',
273
+ x: '#000000',
274
+ apple: '#000000',
275
+ twitch: '#ffffff'
276
+ };
@@ -0,0 +1,3 @@
1
+ This folder contains code modified from react-browser-frame by liamjohnston. The original code is under the MIT license and can be found at https://github.com/liamjohnston/react-browser-frame
2
+
3
+ MIT © liamjohnston
@@ -0,0 +1,51 @@
1
+ import React from "react";
2
+
3
+ export type Props = {
4
+ url?: string,
5
+ padding?: string,
6
+ transparentBackground?: boolean,
7
+ children: React.ReactNode,
8
+ className?: string,
9
+ };
10
+
11
+ export const BrowserFrame = ({ url, padding, transparentBackground, children, className }: Props) => (
12
+ <div className={`rounded-xl overflow-hidden shadow-2xl ${className}`}>
13
+ <div className="bg-gray-200 dark:bg-gray-800 h-10 flex items-center py-2 px-4 box-border">
14
+ <div className="w-3 h-3 bg-red-500 rounded-full mr-1.5 flex-shrink-0" />
15
+ <div className="w-3 h-3 bg-yellow-500 rounded-full mr-1.5 flex-shrink-0" />
16
+ <div className="w-3 h-3 bg-green-500 rounded-full mr-2 flex-shrink-0" />
17
+ {url && (
18
+ <div
19
+ className="text-left bg-white dark:bg-gray-700 h-6 rounded-full leading-6 text-sm text-gray-700 dark:text-gray-300 flex-grow ml-2 mr-4 px-4 whitespace-nowrap overflow-hidden overflow-ellipsis"
20
+ aria-hidden
21
+ >
22
+ {url}
23
+ </div>
24
+ )}
25
+ <div className="w-4 h-4 ml-auto flex flex-col justify-evenly items-stretch flex-shrink-0">
26
+ <span className="h-0.5 bg-gray-400 dark:bg-gray-500" />
27
+ <span className="h-0.5 bg-gray-400 dark:bg-gray-500" />
28
+ <span className="h-0.5 bg-gray-400 dark:bg-gray-500" />
29
+ </div>
30
+ </div>
31
+ <div
32
+ className={`flex grow flex-col p-4 rounded-b-md ${padding ? padding : ""} ${
33
+ transparentBackground
34
+ ? ""
35
+ : "bg-white dark:bg-black"
36
+ }`}
37
+ style={transparentBackground ? {
38
+ backgroundImage: `
39
+ linear-gradient(45deg, #f0f0f0 25%, transparent 25%),
40
+ linear-gradient(-45deg, #f0f0f0 25%, transparent 25%),
41
+ linear-gradient(45deg, transparent 75%, #f0f0f0 75%),
42
+ linear-gradient(-45deg, transparent 75%, #f0f0f0 75%)
43
+ `,
44
+ backgroundSize: '20px 20px',
45
+ backgroundPosition: '0 0, 0 10px, 10px -10px, -10px 0px'
46
+ } : {}}
47
+ >
48
+ {children}
49
+ </div>
50
+ </div>
51
+ );
@@ -0,0 +1,36 @@
1
+ "use client";
2
+
3
+ import { forwardRefIfNeeded } from "@hexclave/shared/dist/utils/react";
4
+ import { Copy } from "lucide-react";
5
+ import React from "react";
6
+ import { Button, cn, type ButtonProps, useToast } from "..";
7
+
8
+ const CopyButton = forwardRefIfNeeded<
9
+ HTMLButtonElement,
10
+ ButtonProps & { content: string }
11
+ >((props, ref) => {
12
+ const { toast } = useToast();
13
+
14
+ return (
15
+ <Button
16
+ variant="secondary"
17
+ {...props}
18
+ className={cn("h-6 w-6 p-1", props.className)}
19
+ ref={ref}
20
+ onClick={async (...args) => {
21
+ await props.onClick?.(...args);
22
+ try {
23
+ await navigator.clipboard.writeText(props.content);
24
+ toast({ description: 'Copied to clipboard!', variant: 'success' });
25
+ } catch (e) {
26
+ toast({ description: 'Failed to copy to clipboard', variant: 'destructive' });
27
+ }
28
+ }}
29
+ >
30
+ <Copy />
31
+ </Button>
32
+ );
33
+ });
34
+ CopyButton.displayName = "CopyButton";
35
+
36
+ export { CopyButton };
@@ -0,0 +1,52 @@
1
+ import { Input, Label, SimpleTooltip, Textarea } from "..";
2
+ import { CopyButton } from "./copy-button";
3
+
4
+ export function CopyField(props: {
5
+ value: string,
6
+ label?: React.ReactNode,
7
+ helper?: React.ReactNode,
8
+ monospace?: boolean,
9
+ fixedSize?: boolean,
10
+ } & ({
11
+ type: "textarea",
12
+ height?: number,
13
+ } | {
14
+ type: "input",
15
+ })) {
16
+ return (
17
+ <div>
18
+ {props.label && (
19
+ <Label className="flex items-center gap-2 mb-2">
20
+ {props.label}
21
+ {props.helper && <SimpleTooltip type="info" tooltip={props.helper} />}
22
+ </Label>
23
+ )}
24
+ {props.type === "textarea" ? (
25
+ <div className="relative pr-2">
26
+ <Textarea
27
+ readOnly
28
+ value={props.value}
29
+ style={{
30
+ height: props.height,
31
+ fontFamily: props.monospace ? "ui-monospace, monospace" : "inherit",
32
+ whiteSpace: props.monospace ? "pre" : "normal",
33
+ resize: props.fixedSize ? "none" : "vertical"
34
+ }}
35
+ />
36
+ <CopyButton content={props.value} className="absolute right-4 top-2" />
37
+ </div>
38
+ ) : (
39
+ <div className="flex items-center gap-2">
40
+ <Input
41
+ readOnly
42
+ value={props.value}
43
+ style={{
44
+ fontFamily: props.monospace ? "ui-monospace, monospace" : "inherit",
45
+ }}
46
+ />
47
+ <CopyButton content={props.value} />
48
+ </div>
49
+ )}
50
+ </div>
51
+ );
52
+ }
@@ -0,0 +1,133 @@
1
+
2
+ 'use client';
3
+ import { DotsHorizontalIcon } from "@radix-ui/react-icons";
4
+ import React, { useEffect, useRef, useState } from "react";
5
+ import { Avatar, AvatarFallback, AvatarImage, Badge, Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, SimpleTooltip, cn } from "../..";
6
+
7
+ export function TextCell(props: { children: React.ReactNode, size?: number, icon?: React.ReactNode }) {
8
+ const textRef = useRef<HTMLDivElement>(null);
9
+ const [isOverflowing, setIsOverflowing] = useState(false);
10
+ const overflowStyle = "text-ellipsis text-nowrap overflow-x-hidden";
11
+
12
+ useEffect(() => {
13
+ const checkOverflow = () => {
14
+ if (textRef.current) {
15
+ const isOverflowing = textRef.current.scrollWidth > textRef.current.clientWidth;
16
+ setIsOverflowing(isOverflowing);
17
+ }
18
+ };
19
+
20
+ checkOverflow();
21
+ window.addEventListener('resize', checkOverflow);
22
+ return () => {
23
+ window.removeEventListener('resize', checkOverflow);
24
+ };
25
+ }, []);
26
+
27
+ return (
28
+ <div className="relative" style={{ minWidth: props.size }}>
29
+ <div className="flex items-center gap-2 absolute inset-0">
30
+ <div className={overflowStyle} ref={textRef}>
31
+ {isOverflowing ? (
32
+ <SimpleTooltip tooltip={props.children}>
33
+ <div className={overflowStyle}>
34
+ {props.children}
35
+ </div>
36
+ </SimpleTooltip>
37
+ ) : props.children}
38
+ </div>
39
+ {props.icon && <div>{props.icon}</div>}
40
+ </div>
41
+ </div>
42
+ );
43
+ }
44
+
45
+ export function AvatarCell(props: { src?: string, fallback?: string }) {
46
+ return (
47
+ <Avatar className="h-6 w-6">
48
+ <AvatarImage src={props.src} />
49
+ <AvatarFallback>{props.fallback}</AvatarFallback>
50
+ </Avatar>
51
+ );
52
+ }
53
+
54
+ export function DateCell(props: { date: Date, ignoreAfterYears?: number }) {
55
+ const ignore = !!props.ignoreAfterYears && new Date(new Date().setFullYear(new Date().getFullYear() + props.ignoreAfterYears)) < props.date;
56
+ const timeString = props.date.toLocaleTimeString([], { year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit' });
57
+ return (
58
+ <TextCell size={140}>
59
+ {ignore ? 'Never' : timeString}
60
+ </TextCell>
61
+ );
62
+ }
63
+
64
+ type ActionItem = '-' | {
65
+ item: React.ReactNode,
66
+ onClick: (e: React.MouseEvent) => void | Promise<void>,
67
+ danger?: boolean,
68
+ disabled?: boolean,
69
+ disabledTooltip?: string,
70
+ }
71
+
72
+ export function ActionCell(props: {
73
+ items?: ActionItem[],
74
+ invisible?: boolean,
75
+ }) {
76
+ return (
77
+ <DropdownMenu>
78
+ <DropdownMenuTrigger asChild>
79
+ <Button
80
+ variant="ghost"
81
+ className={cn(
82
+ "flex h-8 w-8 p-0 data-[state=open]:bg-muted",
83
+ props.invisible && "invisible",
84
+ )}
85
+ >
86
+ <DotsHorizontalIcon className="h-4 w-4" />
87
+ <span className="sr-only">Open menu</span>
88
+ </Button>
89
+ </DropdownMenuTrigger>
90
+ <DropdownMenuContent align="end" className="min-w-[150px] max-w-[300px] stack-scope">
91
+ {props.items?.map((item, index) => {
92
+ if (item === '-') {
93
+ return <DropdownMenuSeparator key={index} />;
94
+ }
95
+
96
+ const menuItemProps = {
97
+ onClick: item.onClick,
98
+ className: cn(item.danger ? "text-destructive" : ""),
99
+ disabled: item.disabled
100
+ };
101
+
102
+ const menuItem = (
103
+ <DropdownMenuItem {...menuItemProps} key={index}>
104
+ {item.item}
105
+ </DropdownMenuItem>
106
+ );
107
+
108
+ if (item.disabled && item.disabledTooltip) {
109
+ return (
110
+ <SimpleTooltip tooltip={item.disabledTooltip} key={index}>
111
+ {React.cloneElement(menuItem, {
112
+ className: cn(menuItemProps.className, "opacity-50 cursor-not-allowed")
113
+ })}
114
+ </SimpleTooltip>
115
+ );
116
+ }
117
+
118
+ return menuItem;
119
+ })}
120
+ </DropdownMenuContent>
121
+ </DropdownMenu>
122
+ );
123
+ }
124
+
125
+ export function BadgeCell(props: { badges: string[], size?: number }) {
126
+ return (
127
+ <div className="flex items-center gap-1 flex-wrap">
128
+ {props.badges.map((badge, index) => (
129
+ <Badge key={index} variant="secondary">{badge}</Badge>
130
+ ))}
131
+ </div>
132
+ );
133
+ }
@@ -0,0 +1,52 @@
1
+ import { Button } from "../ui/button";
2
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
3
+ import { Column } from "@tanstack/react-table";
4
+ import { ArrowDown, ArrowUp, LucideIcon } from "lucide-react";
5
+ import { cn } from "../../lib/utils";
6
+
7
+ type DataTableColumnHeaderProps<TData, TValue> = {
8
+ column: Column<TData, TValue>,
9
+ columnTitle: React.ReactNode,
10
+ } & React.HTMLAttributes<HTMLDivElement>
11
+
12
+ function Item(props: { icon: LucideIcon, onClick: () => void, children: React.ReactNode }) {
13
+ return (
14
+ <DropdownMenuItem onClick={props.onClick}>
15
+ <div className="flex items-center">
16
+ <props.icon className="mr-2 h-3.5 w-3.5 text-muted-foreground/70" />
17
+ {props.children}
18
+ </div>
19
+ </DropdownMenuItem>
20
+ );
21
+ }
22
+
23
+ export function DataTableColumnHeader<TData, TValue>({
24
+ column,
25
+ columnTitle,
26
+ className,
27
+ }: DataTableColumnHeaderProps<TData, TValue>) {
28
+ return (
29
+ <div className={cn("flex items-center space-x-2", className)}>
30
+ <DropdownMenu>
31
+ <DropdownMenuTrigger asChild>
32
+ <Button
33
+ variant="ghost"
34
+ size="sm"
35
+ className={cn("-ml-3 h-8 data-[state=open]:bg-accent", !column.getCanSort() && "pointer-events-none")}
36
+ >
37
+ <span>{columnTitle}</span>
38
+ {column.getIsSorted() === "desc" ? (
39
+ <ArrowDown className="ml-2 h-4 w-4" />
40
+ ) : column.getIsSorted() === "asc" ? (
41
+ <ArrowUp className="ml-2 h-4 w-4" />
42
+ ) : null}
43
+ </Button>
44
+ </DropdownMenuTrigger>
45
+ <DropdownMenuContent align="start" className="stack-scope">
46
+ <Item icon={ArrowUp} onClick={() => column.toggleSorting(false)}>Asc</Item>
47
+ <Item icon={ArrowDown} onClick={() => column.toggleSorting(true)}>Desc</Item>
48
+ </DropdownMenuContent>
49
+ </DropdownMenu>
50
+ </div>
51
+ );
52
+ }