@synqauth/react 0.0.0-stage → 0.2.0

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.
@@ -0,0 +1,268 @@
1
+ /*
2
+ * @synqauth/react's components, styled. Import it once:
3
+ *
4
+ * import '@synqauth/react/styles.css'
5
+ *
6
+ * A theme is a few variables, set on :root or any element above the
7
+ * components. Every rule is inside :where(), so the app's own CSS wins over
8
+ * any of them without fighting specificity. A component with `unstyled`
9
+ * carries none of these classes.
10
+ */
11
+
12
+ :where(.synq) {
13
+ --synq-font-family: inherit;
14
+ --synq-font-size: 0.9375rem;
15
+ --synq-color-text: #0f172a;
16
+ --synq-color-muted: #64748b;
17
+ --synq-color-background: #ffffff;
18
+ --synq-color-surface: #f8fafc;
19
+ --synq-color-border: #e2e8f0;
20
+ --synq-color-primary: #4f46e5;
21
+ --synq-color-primary-text: #ffffff;
22
+ --synq-color-danger: #dc2626;
23
+ --synq-radius: 0.5rem;
24
+ --synq-spacing: 0.75rem;
25
+ --synq-shadow: 0 8px 24px rgb(15 23 42 / 0.12);
26
+
27
+ font-family: var(--synq-font-family);
28
+ font-size: var(--synq-font-size);
29
+ color: var(--synq-color-text);
30
+ }
31
+
32
+ @media (prefers-color-scheme: dark) {
33
+ :where(.synq) {
34
+ --synq-color-text: #e2e8f0;
35
+ --synq-color-muted: #94a3b8;
36
+ --synq-color-background: #0f172a;
37
+ --synq-color-surface: #1e293b;
38
+ --synq-color-border: #334155;
39
+ --synq-color-primary: #818cf8;
40
+ --synq-color-primary-text: #0f172a;
41
+ --synq-color-danger: #f87171;
42
+ --synq-shadow: 0 8px 24px rgb(0 0 0 / 0.4);
43
+ }
44
+ }
45
+
46
+ :where(.synq-sign-in-button, .synq-button) {
47
+ display: inline-flex;
48
+ align-items: center;
49
+ gap: 0.375rem;
50
+ padding: 0.5rem 0.875rem;
51
+ border: 1px solid var(--synq-color-border);
52
+ border-radius: var(--synq-radius);
53
+ background: var(--synq-color-background);
54
+ color: var(--synq-color-text);
55
+ font: inherit;
56
+ font-weight: 500;
57
+ cursor: pointer;
58
+ }
59
+
60
+ :where(.synq-sign-in-button, .synq-button-primary) {
61
+ border-color: var(--synq-color-primary);
62
+ background: var(--synq-color-primary);
63
+ color: var(--synq-color-primary-text);
64
+ }
65
+
66
+ :where(.synq-sign-in-button, .synq-button):disabled {
67
+ opacity: 0.55;
68
+ cursor: not-allowed;
69
+ }
70
+
71
+ :where(
72
+ .synq-sign-in-button,
73
+ .synq-button,
74
+ .synq-user-button-trigger,
75
+ .synq-menu-item,
76
+ .synq-input,
77
+ .synq-link
78
+ ):focus-visible {
79
+ outline: 2px solid var(--synq-color-primary);
80
+ outline-offset: 2px;
81
+ }
82
+
83
+ :where(.synq-user-button) {
84
+ position: relative;
85
+ display: inline-block;
86
+ }
87
+
88
+ :where(.synq-user-button-trigger) {
89
+ display: inline-flex;
90
+ align-items: center;
91
+ gap: 0.5rem;
92
+ padding: 0.25rem 0.625rem 0.25rem 0.25rem;
93
+ border: 1px solid var(--synq-color-border);
94
+ border-radius: 999px;
95
+ background: var(--synq-color-background);
96
+ color: inherit;
97
+ font: inherit;
98
+ cursor: pointer;
99
+ }
100
+
101
+ :where(.synq-avatar) {
102
+ display: inline-grid;
103
+ place-items: center;
104
+ width: 2rem;
105
+ height: 2rem;
106
+ border-radius: 999px;
107
+ background: var(--synq-color-primary);
108
+ color: var(--synq-color-primary-text);
109
+ font-size: 0.8125rem;
110
+ font-weight: 600;
111
+ object-fit: cover;
112
+ }
113
+
114
+ :where(.synq-menu) {
115
+ position: absolute;
116
+ right: 0;
117
+ z-index: 50;
118
+ display: grid;
119
+ min-width: 12rem;
120
+ margin-top: 0.375rem;
121
+ padding: 0.25rem;
122
+ border: 1px solid var(--synq-color-border);
123
+ border-radius: var(--synq-radius);
124
+ background: var(--synq-color-background);
125
+ box-shadow: var(--synq-shadow);
126
+ }
127
+
128
+ :where(.synq-menu-item) {
129
+ display: block;
130
+ padding: 0.5rem 0.75rem;
131
+ border: 0;
132
+ border-radius: calc(var(--synq-radius) - 0.125rem);
133
+ background: none;
134
+ color: inherit;
135
+ font: inherit;
136
+ text-align: left;
137
+ text-decoration: none;
138
+ cursor: pointer;
139
+ }
140
+
141
+ :where(.synq-menu-item):hover {
142
+ background: var(--synq-color-surface);
143
+ }
144
+
145
+ :where(.synq-account-manager) {
146
+ display: grid;
147
+ gap: calc(var(--synq-spacing) * 2);
148
+ }
149
+
150
+ :where(.synq-section, .synq-wallet-manager) {
151
+ display: grid;
152
+ gap: var(--synq-spacing);
153
+ padding: calc(var(--synq-spacing) * 1.5);
154
+ border: 1px solid var(--synq-color-border);
155
+ border-radius: var(--synq-radius);
156
+ background: var(--synq-color-background);
157
+ }
158
+
159
+ :where(.synq-heading) {
160
+ margin: 0;
161
+ font-size: 1rem;
162
+ font-weight: 600;
163
+ }
164
+
165
+ :where(.synq-form) {
166
+ display: grid;
167
+ gap: var(--synq-spacing);
168
+ }
169
+
170
+ :where(.synq-form-inline) {
171
+ display: flex;
172
+ flex-wrap: wrap;
173
+ align-items: end;
174
+ gap: 0.5rem;
175
+ }
176
+
177
+ :where(.synq-field) {
178
+ display: grid;
179
+ gap: 0.25rem;
180
+ }
181
+
182
+ :where(.synq-label) {
183
+ color: var(--synq-color-muted);
184
+ font-size: 0.8125rem;
185
+ }
186
+
187
+ :where(.synq-input) {
188
+ padding: 0.5rem 0.625rem;
189
+ border: 1px solid var(--synq-color-border);
190
+ border-radius: var(--synq-radius);
191
+ background: var(--synq-color-background);
192
+ color: inherit;
193
+ font: inherit;
194
+ }
195
+
196
+ :where(.synq-actions) {
197
+ display: flex;
198
+ align-items: center;
199
+ gap: var(--synq-spacing);
200
+ }
201
+
202
+ :where(.synq-list) {
203
+ display: grid;
204
+ margin: 0;
205
+ padding: 0;
206
+ list-style: none;
207
+ }
208
+
209
+ :where(.synq-row) {
210
+ display: flex;
211
+ flex-wrap: wrap;
212
+ align-items: center;
213
+ gap: 0.5rem;
214
+ padding: 0.625rem 0;
215
+ border-top: 1px solid var(--synq-color-border);
216
+ }
217
+
218
+ :where(.synq-row):first-child {
219
+ border-top: 0;
220
+ }
221
+
222
+ :where(.synq-row-title) {
223
+ flex: 1 1 auto;
224
+ font-weight: 500;
225
+ }
226
+
227
+ :where(.synq-badge) {
228
+ padding: 0.125rem 0.5rem;
229
+ border-radius: 999px;
230
+ background: var(--synq-color-surface);
231
+ color: var(--synq-color-primary);
232
+ font-size: 0.75rem;
233
+ font-weight: 600;
234
+ }
235
+
236
+ :where(.synq-muted) {
237
+ margin: 0;
238
+ color: var(--synq-color-muted);
239
+ }
240
+
241
+ :where(.synq-error) {
242
+ flex-basis: 100%;
243
+ margin: 0;
244
+ color: var(--synq-color-danger);
245
+ }
246
+
247
+ :where(.synq-sign-in-form) {
248
+ max-width: 24rem;
249
+ }
250
+
251
+ :where(.synq-sign-in-form .synq-button) {
252
+ justify-content: center;
253
+ }
254
+
255
+ :where(.synq-code-input) {
256
+ font-variant-numeric: tabular-nums;
257
+ letter-spacing: 0.25em;
258
+ }
259
+
260
+ :where(.synq-link) {
261
+ padding: 0;
262
+ border: 0;
263
+ background: none;
264
+ color: var(--synq-color-primary);
265
+ font: inherit;
266
+ font-weight: 500;
267
+ cursor: pointer;
268
+ }
package/package.json CHANGED
@@ -1,6 +1,56 @@
1
1
  {
2
2
  "name": "@synqauth/react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "React hooks and components for Synq.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/aerosol-build/synq.git",
9
+ "directory": "packages/react"
10
+ },
11
+ "type": "module",
12
+ "sideEffects": [
13
+ "*.css"
14
+ ],
15
+ "engines": {
16
+ "node": ">=22"
17
+ },
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ },
23
+ "./styles.css": "./dist/styles.css",
24
+ "./package.json": "./package.json"
25
+ },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "dependencies": {
33
+ "@synqauth/js": "0.2.0"
34
+ },
35
+ "peerDependencies": {
36
+ "react": ">=19.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@testing-library/dom": "10.4.2",
40
+ "@testing-library/react": "16.3.3",
41
+ "@testing-library/user-event": "14.6.7",
42
+ "@types/react": "19.3.0",
43
+ "@types/react-dom": "19.3.0",
44
+ "@vitest/coverage-v8": "5.0.2",
45
+ "jsdom": "30.1.1",
46
+ "react": "19.3.0",
47
+ "react-dom": "19.3.0",
48
+ "vitest": "5.0.2"
49
+ },
50
+ "scripts": {
51
+ "build": "tsdown",
52
+ "lint": "eslint .",
53
+ "typecheck": "tsc",
54
+ "test": "vitest run --coverage"
55
+ }
6
56
  }