@gluwa/connect-kit 0.1.0-next.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.
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@gluwa/connect-kit",
3
+ "version": "0.1.0-next.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "default": "./dist/index.js"
9
+ },
10
+ "./index.css": "./dist/index.css"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "sideEffects": true,
16
+ "author": "",
17
+ "license": "ISC",
18
+ "dependencies": {
19
+ "qrcode.react": "^3.2.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/react": "^18.3.18",
23
+ "@wagmi/core": "^2.16.7",
24
+ "esbuild-sass-plugin": "^3.7.0",
25
+ "react": "^18.3.1",
26
+ "react-dom": "^18.3.1",
27
+ "tsup": "^8.4.0",
28
+ "typescript": "5.5.4",
29
+ "typescript-eslint": "^8.18.2",
30
+ "viem": "^2.31.7",
31
+ "wagmi": "^2.15.6",
32
+ "@gluwa/credit-connect-sdk": "0.2.0-next.1"
33
+ },
34
+ "peerDependencies": {
35
+ "react": "^18.0.0 || ^19.0.0",
36
+ "wagmi": ">=2.0.0",
37
+ "@gluwa/credit-connect-sdk": "0.2.0-next.1"
38
+ },
39
+ "peerDependenciesMeta": {
40
+ "@gluwa/credit-connect-sdk": {
41
+ "optional": true
42
+ }
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/gluwa/credit-connect.git",
47
+ "directory": "packages/connect-kit"
48
+ },
49
+ "scripts": {
50
+ "build": "tsup",
51
+ "typecheck": "tsc --noEmit --project tsconfig.json",
52
+ "lint": "eslint . --quiet",
53
+ "lint:fix": "eslint . --quiet --fix"
54
+ },
55
+ "main": "./dist/index.js",
56
+ "types": "./dist/index.d.ts"
57
+ }
@@ -0,0 +1,627 @@
1
+ .ck-root {
2
+ position: fixed;
3
+ inset: 0;
4
+ z-index: 9999;
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ }
9
+
10
+ .ck-overlay {
11
+ position: absolute;
12
+ inset: 0;
13
+ background: rgba(0, 0, 0, 0.6);
14
+ }
15
+
16
+ .ck-modal {
17
+ position: relative;
18
+ display: flex;
19
+ width: 1120px;
20
+ height: 620px;
21
+ border-radius: 16px;
22
+ overflow: hidden;
23
+ background: #1a1a1a;
24
+ color: #fff;
25
+ }
26
+
27
+ // ── Pane (shared) ────────────────────────────────────────
28
+
29
+ .ck-pane {
30
+ display: flex;
31
+ flex-direction: column;
32
+ padding: 24px;
33
+ width: 560px;
34
+ flex-shrink: 0;
35
+ box-sizing: border-box;
36
+
37
+ &--selector {
38
+ border-right: 1px solid rgba(255, 255, 255, 0.08);
39
+ }
40
+
41
+ &--detail {
42
+ padding-inline: 20px; // 560 - 20*2 = 520px 콘텐츠 영역
43
+ overflow: hidden;
44
+ min-height: 0;
45
+ }
46
+ }
47
+
48
+ .ck-pane__header {
49
+ display: flex;
50
+ align-items: center;
51
+ gap: 8px;
52
+ margin-bottom: 20px;
53
+ }
54
+
55
+ .ck-pane__title {
56
+ flex: 1;
57
+ font-size: 16px;
58
+ font-weight: 600;
59
+ margin: 0;
60
+ }
61
+
62
+ .ck-pane__body {
63
+ flex: 1;
64
+ display: flex;
65
+ flex-direction: column;
66
+ min-height: 0;
67
+ overflow: hidden;
68
+ }
69
+
70
+ .ck-pane__footer {
71
+ margin-top: auto;
72
+ padding-top: 16px;
73
+ text-align: center;
74
+ }
75
+
76
+ // ── Buttons ──────────────────────────────────────────────
77
+
78
+ .ck-btn-close,
79
+ .ck-btn-back {
80
+ position: relative;
81
+ width: 28px;
82
+ height: 28px;
83
+ background: none;
84
+ border: none;
85
+ cursor: pointer;
86
+ padding: 0;
87
+ border-radius: 50%;
88
+ flex-shrink: 0;
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+
93
+ &:hover {
94
+ background: rgba(255, 255, 255, 0.08);
95
+ }
96
+ }
97
+
98
+ .ck-btn-close {
99
+ &::before,
100
+ &::after {
101
+ content: '';
102
+ position: absolute;
103
+ width: 14px;
104
+ height: 2px;
105
+ background: rgba(255, 255, 255, 0.7);
106
+ border-radius: 1px;
107
+ }
108
+ &::before { transform: rotate(45deg); }
109
+ &::after { transform: rotate(-45deg); }
110
+ }
111
+
112
+ .ck-btn-back {
113
+ &::before {
114
+ content: '';
115
+ position: absolute;
116
+ width: 8px;
117
+ height: 8px;
118
+ border-left: 2px solid rgba(255, 255, 255, 0.7);
119
+ border-bottom: 2px solid rgba(255, 255, 255, 0.7);
120
+ transform: rotate(45deg) translate(1px, -1px);
121
+ border-radius: 1px;
122
+ }
123
+ }
124
+
125
+ .ck-btn-primary {
126
+ display: inline-flex;
127
+ align-items: center;
128
+ justify-content: center;
129
+ padding: 8px 16px;
130
+ border-radius: 8px;
131
+ font-size: 14px;
132
+ font-weight: 600;
133
+ text-decoration: none;
134
+ cursor: pointer;
135
+ white-space: nowrap;
136
+ color: #fff;
137
+ background: rgba(255, 255, 255, 0.15);
138
+ border: none;
139
+
140
+ &:hover {
141
+ background: rgba(255, 255, 255, 0.22);
142
+ }
143
+ }
144
+
145
+ // ── Connector list ────────────────────────────────────────
146
+
147
+ .ck-connector-list {
148
+ display: flex;
149
+ flex-direction: column;
150
+ gap: 8px;
151
+ }
152
+
153
+ .ck-connector-item {
154
+ display: flex;
155
+ align-items: center;
156
+ gap: 12px;
157
+ width: 100%;
158
+ padding: 12px 16px;
159
+ border: none;
160
+ border-radius: 12px;
161
+ cursor: pointer;
162
+ text-align: left;
163
+ color: #fff;
164
+ background: rgba(255, 255, 255, 0.05);
165
+ transition: background 0.15s;
166
+
167
+ &:hover:not(:disabled) {
168
+ background: rgba(255, 255, 255, 0.08);
169
+ }
170
+
171
+ &.is-active {
172
+ background: #3b82f6;
173
+ }
174
+
175
+ &:disabled {
176
+ opacity: 0.5;
177
+ cursor: not-allowed;
178
+ }
179
+ }
180
+
181
+ .ck-connector-item__icon {
182
+ width: 32px;
183
+ height: 32px;
184
+ border-radius: 8px;
185
+ flex-shrink: 0;
186
+ background: rgba(255, 255, 255, 0.1);
187
+ display: block;
188
+ object-fit: cover;
189
+
190
+ // img 태그일 때는 배경 불필요
191
+ &[src] {
192
+ background: none;
193
+ }
194
+ }
195
+
196
+ .ck-connector-item__label {
197
+ flex: 1;
198
+ font-size: 14px;
199
+ font-weight: 500;
200
+ }
201
+
202
+ .ck-connector-item__badge {
203
+ font-size: 11px;
204
+ font-weight: 600;
205
+ padding: 2px 6px;
206
+ border-radius: 4px;
207
+ background: rgba(255, 255, 255, 0.15);
208
+ color: rgba(255, 255, 255, 0.8);
209
+ }
210
+
211
+ .ck-divider {
212
+ display: flex;
213
+ align-items: center;
214
+ gap: 8px;
215
+ color: rgba(255, 255, 255, 0.3);
216
+ font-size: 12px;
217
+ margin: 4px 0;
218
+
219
+ &::before,
220
+ &::after {
221
+ content: '';
222
+ flex: 1;
223
+ height: 1px;
224
+ background: rgba(255, 255, 255, 0.1);
225
+ }
226
+ }
227
+
228
+ .ck-link-no-wallet {
229
+ font-size: 13px;
230
+ text-decoration: none;
231
+ color: rgba(255, 255, 255, 0.5);
232
+ }
233
+
234
+ // ── Views ────────────────────────────────────────────────
235
+
236
+ .ck-view {
237
+ display: flex;
238
+ flex-direction: column;
239
+ align-items: center;
240
+ flex: 1;
241
+
242
+ &--idle {
243
+ justify-content: center;
244
+ text-align: center;
245
+ gap: 12px;
246
+ }
247
+
248
+ &--qr {
249
+ gap: 16px;
250
+ }
251
+
252
+ &--extension {
253
+ justify-content: center;
254
+ align-items: center;
255
+ gap: 12px;
256
+ text-align: center;
257
+ }
258
+
259
+ &--wallet-list {
260
+ align-items: stretch;
261
+ gap: 12px;
262
+ height: 100%;
263
+ overflow: hidden;
264
+ width: 100%;
265
+ box-sizing: border-box;
266
+ }
267
+ }
268
+
269
+ .ck-view__illustration {
270
+ width: 180px;
271
+ height: auto;
272
+ display: block;
273
+ }
274
+
275
+ .ck-view__wallet-icon {
276
+ width: 64px;
277
+ height: 64px;
278
+ border-radius: 16px;
279
+ background: rgba(255, 255, 255, 0.1);
280
+
281
+ &--metamask {
282
+ // TODO: MetaMask icon
283
+ }
284
+ }
285
+
286
+ .ck-view__title {
287
+ font-size: 18px;
288
+ font-weight: 600;
289
+ margin: 0;
290
+ }
291
+
292
+ .ck-view__description,
293
+ .ck-view__caption {
294
+ font-size: 13px;
295
+ opacity: 0.6;
296
+ margin: 0;
297
+ text-align: center;
298
+ }
299
+
300
+ // ── QR ───────────────────────────────────────────────────
301
+
302
+ .ck-qr-frame {
303
+ width: 216px;
304
+ height: 216px;
305
+ border-radius: 16px;
306
+ display: flex;
307
+ align-items: center;
308
+ justify-content: center;
309
+ background: #fff;
310
+ overflow: hidden;
311
+ flex-shrink: 0;
312
+
313
+ &--loading {
314
+ background: rgba(255, 255, 255, 0.05);
315
+ }
316
+ }
317
+
318
+ .ck-qr-spinner,
319
+ .ck-spinner {
320
+ width: 32px;
321
+ height: 32px;
322
+ border: 3px solid rgba(255, 255, 255, 0.15);
323
+ border-top-color: rgba(255, 255, 255, 0.6);
324
+ border-radius: 50%;
325
+ animation: ck-spin 0.8s linear infinite;
326
+ }
327
+
328
+ @keyframes ck-spin {
329
+ to { transform: rotate(360deg); }
330
+ }
331
+
332
+ .ck-copy-link {
333
+ background: none;
334
+ border: none;
335
+ cursor: pointer;
336
+ font-size: 13px;
337
+ color: #fff;
338
+ opacity: 0.5;
339
+ display: flex;
340
+ align-items: center;
341
+ gap: 4px;
342
+ }
343
+
344
+ // ── Download card ────────────────────────────────────────
345
+
346
+ .ck-download-card {
347
+ display: flex;
348
+ align-items: center;
349
+ justify-content: space-between;
350
+ width: 100%;
351
+ padding: 14px 16px;
352
+ border-radius: 12px;
353
+ background: rgba(255, 255, 255, 0.05);
354
+ margin-top: auto;
355
+ gap: 12px;
356
+ }
357
+
358
+ .ck-download-card__text {
359
+ display: flex;
360
+ flex-direction: column;
361
+ gap: 2px;
362
+ }
363
+
364
+ .ck-download-card__title {
365
+ font-size: 14px;
366
+ font-weight: 500;
367
+ margin: 0;
368
+ }
369
+
370
+ .ck-download-card__sub {
371
+ font-size: 12px;
372
+ opacity: 0.5;
373
+ margin: 0;
374
+ }
375
+
376
+ // ── WalletConnect list ────────────────────────────────────
377
+
378
+ .ck-all-wallets-btn {
379
+ display: flex;
380
+ align-items: center;
381
+ gap: 12px;
382
+ width: 100%;
383
+ padding: 14px 16px;
384
+ border: none;
385
+ border-radius: 12px;
386
+ background: rgba(255, 255, 255, 0.05);
387
+ color: #fff;
388
+ cursor: pointer;
389
+ margin-top: auto;
390
+ }
391
+
392
+ .ck-all-wallets-btn__icon {
393
+ width: 32px;
394
+ height: 32px;
395
+ border-radius: 8px;
396
+ background: rgba(255, 255, 255, 0.1);
397
+ }
398
+
399
+ .ck-all-wallets-btn__label {
400
+ flex: 1;
401
+ font-size: 14px;
402
+ font-weight: 500;
403
+ text-align: left;
404
+ }
405
+
406
+ .ck-all-wallets-btn__count {
407
+ font-size: 12px;
408
+ opacity: 0.5;
409
+ }
410
+
411
+ .ck-wallet-search {
412
+ display: flex;
413
+ align-items: center;
414
+ gap: 8px;
415
+ }
416
+
417
+ .ck-wallet-search__input {
418
+ flex: 1;
419
+ padding: 10px 14px;
420
+ border-radius: 10px;
421
+ border: 1px solid rgba(255, 255, 255, 0.1);
422
+ background: rgba(255, 255, 255, 0.05);
423
+ font-size: 14px;
424
+ outline: none;
425
+ color: #fff;
426
+
427
+ &::placeholder {
428
+ color: rgba(255, 255, 255, 0.35);
429
+ }
430
+ }
431
+
432
+ .ck-wc-filter {
433
+ display: flex;
434
+ align-items: center;
435
+ gap: 6px;
436
+ flex-shrink: 0;
437
+ border: none;
438
+ background: none;
439
+ cursor: pointer;
440
+ padding: 0;
441
+ }
442
+
443
+ .ck-wc-filter__icon {
444
+ width: 20px;
445
+ height: 20px;
446
+ border-radius: 4px;
447
+ display: block;
448
+ opacity: 0.5;
449
+
450
+ .ck-wc-filter.is-active & {
451
+ opacity: 1;
452
+ }
453
+ }
454
+
455
+ // toggle track
456
+ .ck-wc-filter__track {
457
+ position: relative;
458
+ width: 36px;
459
+ height: 20px;
460
+ border-radius: 10px;
461
+ background: rgba(255, 255, 255, 0.15);
462
+ transition: background 0.2s;
463
+
464
+ .ck-wc-filter.is-active & {
465
+ background: #3b82f6;
466
+ }
467
+ }
468
+
469
+ // toggle thumb
470
+ .ck-wc-filter__thumb {
471
+ position: absolute;
472
+ top: 2px;
473
+ left: 2px;
474
+ width: 16px;
475
+ height: 16px;
476
+ border-radius: 50%;
477
+ background: #fff;
478
+ transition: transform 0.2s;
479
+
480
+ .ck-wc-filter.is-active & {
481
+ transform: translateX(16px);
482
+ }
483
+ }
484
+
485
+ // 스크롤 wrapper — 520px 고정, 세로 스크롤만 담당
486
+ .ck-wallet-grid-scroll {
487
+ flex: 1;
488
+ min-height: 0;
489
+ width: 520px;
490
+ overflow-x: hidden;
491
+ overflow-y: auto;
492
+ }
493
+
494
+ .ck-wallet-grid {
495
+ display: grid;
496
+ grid-template-columns: repeat(4, minmax(0, 1fr));
497
+ grid-auto-rows: max-content;
498
+ gap: 8px;
499
+ list-style: none;
500
+ margin: 0;
501
+ padding: 0;
502
+ width: 100%; // scroll wrapper 폭 그대로 채움
503
+ box-sizing: border-box;
504
+ }
505
+
506
+ .ck-wallet-grid__item {
507
+ display: flex;
508
+ flex-direction: column;
509
+ align-items: center;
510
+ gap: 6px;
511
+ padding: 10px 4px;
512
+ width: 100%;
513
+ background: none;
514
+ border: none;
515
+ border-radius: 10px;
516
+ cursor: pointer;
517
+ color: #fff;
518
+ box-sizing: border-box;
519
+
520
+ &:hover {
521
+ background: rgba(255, 255, 255, 0.05);
522
+ }
523
+ }
524
+
525
+ .ck-wallet-grid__icon {
526
+ width: 48px;
527
+ height: 48px;
528
+ border-radius: 12px;
529
+ flex-shrink: 0;
530
+ }
531
+
532
+ .ck-wallet-grid__icon-placeholder {
533
+ width: 48px;
534
+ height: 48px;
535
+ border-radius: 12px;
536
+ flex-shrink: 0;
537
+ background: rgba(255, 255, 255, 0.1);
538
+ }
539
+
540
+ .ck-wallet-grid__name {
541
+ display: flex;
542
+ align-items: center;
543
+ justify-content: center;
544
+ gap: 3px;
545
+ width: 100%;
546
+ min-width: 0;
547
+ }
548
+
549
+ .ck-wallet-grid__name-text {
550
+ flex: 1;
551
+ min-width: 0;
552
+ font-size: 11px;
553
+ overflow: hidden;
554
+ text-overflow: ellipsis;
555
+ white-space: nowrap;
556
+ }
557
+
558
+ .ck-wallet-grid__wc-badge {
559
+ width: 10px;
560
+ height: 10px;
561
+ border-radius: 2px;
562
+ flex-shrink: 0;
563
+ opacity: 0.7;
564
+ }
565
+
566
+ .ck-wallet-list-loading,
567
+ .ck-wallet-list-empty {
568
+ display: flex;
569
+ align-items: center;
570
+ justify-content: center;
571
+ padding: 32px;
572
+ opacity: 0.4;
573
+ }
574
+
575
+ // ── Mobile ────────────────────────────────────────────────
576
+
577
+ .ck-mobile-only {
578
+ display: none;
579
+ }
580
+
581
+ @media (max-width: 1120px) {
582
+ // 오버레이 아래쪽 정렬
583
+ .ck-root {
584
+ align-items: flex-end;
585
+ }
586
+
587
+ // 바텀시트 — 슬라이드업 애니메이션
588
+ .ck-modal {
589
+ flex-direction: column;
590
+ width: 100%;
591
+ height: auto;
592
+ max-height: 90dvh;
593
+ border-radius: 20px 20px 0 0;
594
+ animation: ck-slide-up 0.28s cubic-bezier(0.32, 0.72, 0, 1);
595
+ overflow-y: auto;
596
+ }
597
+
598
+ @keyframes ck-slide-up {
599
+ from { transform: translateY(100%); }
600
+ to { transform: translateY(0); }
601
+ }
602
+
603
+ // selector만 보일 때: detail 숨김
604
+ .ck-modal:not(.ck-modal--has-detail) .ck-pane--detail {
605
+ display: none;
606
+ }
607
+
608
+ // detail 보일 때: selector 숨김
609
+ .ck-modal.ck-modal--has-detail .ck-pane--selector {
610
+ display: none;
611
+ }
612
+
613
+ .ck-pane--selector,
614
+ .ck-pane--detail {
615
+ width: 100%;
616
+ border-right: none;
617
+ }
618
+
619
+ // detail pane 최소 높이 — QR 코드 등 표시 공간 확보
620
+ .ck-pane--detail {
621
+ min-height: 420px;
622
+ }
623
+
624
+ .ck-mobile-only {
625
+ display: block;
626
+ }
627
+ }