@digital-ai/dot-illustrations 2.0.36 → 2.0.38
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/demo/demo.css +37 -183
- package/demo/github-upload.js +39 -4
- package/demo/index.html +251 -171
- package/demo/local-proxy.js +90 -0
- package/demo/script.js +170 -89
- package/package.json +1 -1
package/demo/demo.css
CHANGED
|
@@ -1,95 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
body {
|
|
6
|
-
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
|
|
7
|
-
margin: 0 auto;
|
|
8
|
-
height: 100%;
|
|
9
|
-
text-align: center;
|
|
10
|
-
}
|
|
1
|
+
/* dot-illustrations demo — custom styles
|
|
2
|
+
Tailwind handles layout; this file fills the gaps. */
|
|
11
3
|
|
|
12
|
-
|
|
13
|
-
align-items: center;
|
|
14
|
-
height: 160px;
|
|
15
|
-
width: 160px;
|
|
16
|
-
max-width: 160px;
|
|
17
|
-
max-height: 160px;
|
|
18
|
-
min-width: 92px;
|
|
19
|
-
min-height: 92px;
|
|
20
|
-
margin: auto;
|
|
21
|
-
}
|
|
4
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
22
5
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
flex-wrap: wrap;
|
|
27
|
-
font-family: 'Lato', sans-serif;
|
|
28
|
-
font-size: 14px;
|
|
29
|
-
margin-top: 8px;
|
|
30
|
-
text-align: center;
|
|
31
|
-
color: #667385;
|
|
32
|
-
z-index: 0;
|
|
33
|
-
}
|
|
6
|
+
/* ── Prevent legacy img rule from overriding card images ─────────────────── */
|
|
7
|
+
/* Only illustration img elements inside .dot-illustration get size treatment */
|
|
8
|
+
.dot-illustration img { display: block; }
|
|
34
9
|
|
|
35
|
-
|
|
10
|
+
/* ── Hidden clipboard source ────────────────────────────────────────────── */
|
|
11
|
+
.codeBlock { display: none !important; }
|
|
36
12
|
|
|
37
|
-
/* Tooltip for
|
|
38
|
-
.tooltiptext {
|
|
39
|
-
visibility: hidden;
|
|
40
|
-
background-color: black;
|
|
41
|
-
color: #fff;
|
|
42
|
-
text-align: center;
|
|
43
|
-
border-radius: 5px;
|
|
44
|
-
padding: 5px;
|
|
45
|
-
position: absolute;
|
|
46
|
-
z-index: 1;
|
|
47
|
-
bottom: 125%;
|
|
48
|
-
left: 50%;
|
|
49
|
-
transform: translateX(-50%);
|
|
50
|
-
opacity: 0;
|
|
51
|
-
transition: opacity 0.3s;
|
|
52
|
-
white-space: nowrap;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.button:hover .tooltiptext {
|
|
56
|
-
visibility: visible;
|
|
57
|
-
opacity: 1;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.codeBlock {
|
|
61
|
-
visibility: hidden;
|
|
62
|
-
white-space: pre-wrap;
|
|
63
|
-
background-color: #f4f4f4;
|
|
64
|
-
padding: 10px;
|
|
65
|
-
border: 1px solid #ddd;
|
|
66
|
-
border-radius: 5px;
|
|
67
|
-
max-width: 300px;
|
|
68
|
-
overflow: auto;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.codeInclude {
|
|
72
|
-
color: rgb(43, 50, 55);
|
|
73
|
-
white-space: pre-wrap;
|
|
74
|
-
background-color: #f4f4f4;
|
|
75
|
-
padding: 10px;
|
|
76
|
-
border: 1px solid #ddd;
|
|
77
|
-
border-radius: 5px;
|
|
78
|
-
max-width: 300px;
|
|
79
|
-
overflow: auto;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/* When dark mode is active */
|
|
83
|
-
body.dark-mode .dot-illustration img.light {
|
|
84
|
-
display: none;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
body.dark-mode .dot-illustration img.dark {
|
|
88
|
-
display: block;
|
|
89
|
-
background-color: #232E40;
|
|
90
|
-
border-radius: 8px;
|
|
91
|
-
}
|
|
13
|
+
/* ── Tooltip (legacy compat — kept for copyText/copyCode) ───────────────── */
|
|
14
|
+
.tooltiptext { display: none; }
|
|
92
15
|
|
|
16
|
+
/* ── Floating bar — hidden off-screen, slides in on scroll ─────────────── */
|
|
93
17
|
#floating-bar {
|
|
94
18
|
pointer-events: none;
|
|
95
19
|
opacity: 0;
|
|
@@ -99,110 +23,40 @@ body.dark-mode .dot-illustration img.dark {
|
|
|
99
23
|
pointer-events: auto;
|
|
100
24
|
opacity: 1;
|
|
101
25
|
transform: translateY(0);
|
|
102
|
-
transition: transform 0.
|
|
103
|
-
|
|
104
|
-
.floating-search {
|
|
105
|
-
min-width: 0;
|
|
106
|
-
width: 120px;
|
|
107
|
-
max-width: 200px;
|
|
108
|
-
}
|
|
109
|
-
@media (min-width: 640px) {
|
|
110
|
-
.floating-search {
|
|
111
|
-
width: 200px;
|
|
112
|
-
max-width: 320px;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
.floating-tab {
|
|
116
|
-
min-width: 60px;
|
|
117
|
-
padding-left: 0.75rem;
|
|
118
|
-
padding-right: 0.75rem;
|
|
119
|
-
font-size: 0.85rem;
|
|
26
|
+
transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1),
|
|
27
|
+
opacity 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
|
120
28
|
}
|
|
121
29
|
|
|
122
|
-
/*
|
|
123
|
-
#
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
#illustration-modal.active {
|
|
130
|
-
display: flex;
|
|
131
|
-
}
|
|
132
|
-
#illustration-modal .modal-content {
|
|
133
|
-
background: white;
|
|
134
|
-
border-radius: 1rem;
|
|
135
|
-
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
|
|
136
|
-
max-width: 90vw;
|
|
137
|
-
max-height: 90vh;
|
|
138
|
-
overflow-y: auto;
|
|
139
|
-
padding: 2rem;
|
|
140
|
-
position: relative;
|
|
141
|
-
}
|
|
142
|
-
#illustration-modal .modal-image img {
|
|
143
|
-
width: 220px;
|
|
144
|
-
height: 220px;
|
|
145
|
-
object-fit: contain;
|
|
146
|
-
border-radius: 0.75rem;
|
|
147
|
-
background: #f3f4f6;
|
|
148
|
-
margin-bottom: 1rem;
|
|
149
|
-
}
|
|
150
|
-
#illustration-modal .iconID {
|
|
151
|
-
font-size: 1.2rem;
|
|
152
|
-
font-weight: 600;
|
|
153
|
-
}
|
|
154
|
-
#illustration-modal .button-group {
|
|
155
|
-
margin-bottom: 1rem;
|
|
156
|
-
}
|
|
157
|
-
#illustration-modal #modal-close {
|
|
158
|
-
position: absolute;
|
|
159
|
-
top: 1rem;
|
|
160
|
-
right: 1rem;
|
|
161
|
-
background: none;
|
|
162
|
-
border: none;
|
|
163
|
-
font-size: 2rem;
|
|
164
|
-
color: #aaa;
|
|
165
|
-
cursor: pointer;
|
|
166
|
-
z-index: 10;
|
|
167
|
-
transition: color 0.2s;
|
|
30
|
+
/* ── Scrollable navs (no scrollbar) ─────────────────────────────────────── */
|
|
31
|
+
#illus-sub-tabs,
|
|
32
|
+
#floating-tabs,
|
|
33
|
+
#section-switcher {
|
|
34
|
+
overflow-x: auto;
|
|
35
|
+
scrollbar-width: none;
|
|
168
36
|
}
|
|
169
|
-
#
|
|
170
|
-
|
|
37
|
+
#illus-sub-tabs::-webkit-scrollbar,
|
|
38
|
+
#floating-tabs::-webkit-scrollbar,
|
|
39
|
+
#section-switcher::-webkit-scrollbar { display: none; }
|
|
40
|
+
|
|
41
|
+
/* ── GitHub user badge ──────────────────────────────────────────────────── */
|
|
42
|
+
#gh-user-badge { display: none; }
|
|
43
|
+
#gh-user-badge.connected { display: flex; }
|
|
44
|
+
|
|
45
|
+
/* ── Card grid items — slide-up action bar ──────────────────────────────── */
|
|
46
|
+
.copy-container { position: relative; }
|
|
47
|
+
.copy-container .action-bar {
|
|
48
|
+
transform: translateY(100%);
|
|
49
|
+
transition: transform 0.15s ease-out;
|
|
171
50
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
padding: 1rem;
|
|
175
|
-
max-width: 98vw;
|
|
176
|
-
}
|
|
177
|
-
#illustration-modal .modal-image img {
|
|
178
|
-
width: 140px;
|
|
179
|
-
height: 140px;
|
|
180
|
-
}
|
|
51
|
+
.copy-container:hover .action-bar {
|
|
52
|
+
transform: translateY(0);
|
|
181
53
|
}
|
|
182
54
|
|
|
183
55
|
/* ── Alphabet strip ─────────────────────────────────────────────────────── */
|
|
184
56
|
#alphabet-strip {
|
|
185
57
|
display: flex;
|
|
186
58
|
flex-wrap: wrap;
|
|
187
|
-
|
|
188
|
-
gap: 0.
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
/* ── Tab nav horizontal scroll ──────────────────────────────────────────── */
|
|
192
|
-
#main-tabs {
|
|
193
|
-
overflow-x: auto;
|
|
194
|
-
scrollbar-width: none;
|
|
195
|
-
}
|
|
196
|
-
#main-tabs::-webkit-scrollbar { display: none; }
|
|
197
|
-
#floating-tabs { scrollbar-width: none; }
|
|
198
|
-
#floating-tabs::-webkit-scrollbar { display: none; }
|
|
199
|
-
|
|
200
|
-
/* ── GitHub user badge flex ─────────────────────────────────────────────── */
|
|
201
|
-
#gh-user-badge[style*="flex"] { display: flex !important; }
|
|
202
|
-
|
|
203
|
-
/* ── Integration card image sizing ─────────────────────────────────────── */
|
|
204
|
-
.dot-integration img {
|
|
205
|
-
width: 100%;
|
|
206
|
-
height: 100%;
|
|
207
|
-
object-fit: contain;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: 0.125rem;
|
|
61
|
+
row-gap: 0.25rem;
|
|
208
62
|
}
|
package/demo/github-upload.js
CHANGED
|
@@ -15,20 +15,54 @@ const GITHUB_UPLOAD_CONFIG = {
|
|
|
15
15
|
REPO_NAME: 'dot-illustrations',
|
|
16
16
|
BASE_BRANCH: 'main',
|
|
17
17
|
SCOPES: 'public_repo',
|
|
18
|
+
LOCAL_PROXY: 'http://localhost:3001', // run: node demo/local-proxy.js
|
|
18
19
|
};
|
|
19
20
|
|
|
20
|
-
// ─── In-memory
|
|
21
|
+
// ─── In-memory only — never stored, cleared on page close ────────────────────
|
|
21
22
|
|
|
22
|
-
let _ghToken
|
|
23
|
-
let _ghUser
|
|
23
|
+
let _ghToken = null;
|
|
24
|
+
let _ghUser = null;
|
|
25
|
+
let _usingProxy = false;
|
|
24
26
|
|
|
25
27
|
function ghGetToken() { return _ghToken; }
|
|
26
28
|
function ghSetToken(t) { _ghToken = t; }
|
|
27
|
-
function ghClearToken() { _ghToken = null; _ghUser = null; }
|
|
29
|
+
function ghClearToken() { _ghToken = null; _ghUser = null; _usingProxy = false; }
|
|
30
|
+
|
|
31
|
+
// ─── Auto-connect via local proxy ────────────────────────────────────────────
|
|
32
|
+
// Called once on page load. If `node demo/local-proxy.js` is running, the user
|
|
33
|
+
// is authenticated automatically using their existing `gh auth` credentials —
|
|
34
|
+
// no token input required.
|
|
35
|
+
|
|
36
|
+
async function ghTryLocalProxy() {
|
|
37
|
+
try {
|
|
38
|
+
const resp = await fetch(`${GITHUB_UPLOAD_CONFIG.LOCAL_PROXY}/whoami`, {
|
|
39
|
+
signal: AbortSignal.timeout(900),
|
|
40
|
+
});
|
|
41
|
+
if (!resp.ok) return null;
|
|
42
|
+
const data = await resp.json();
|
|
43
|
+
if (data.login) {
|
|
44
|
+
_usingProxy = true;
|
|
45
|
+
_ghToken = '__proxy__'; // sentinel; actual auth lives in the proxy process
|
|
46
|
+
return data;
|
|
47
|
+
}
|
|
48
|
+
} catch { /* proxy not running */ }
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
28
51
|
|
|
29
52
|
// ─── GitHub API helpers ──────────────────────────────────────────────────────
|
|
30
53
|
|
|
31
54
|
async function ghApi(path, opts = {}) {
|
|
55
|
+
// Route through local proxy when available (no token exposed to browser)
|
|
56
|
+
if (_usingProxy) {
|
|
57
|
+
const resp = await fetch(`${GITHUB_UPLOAD_CONFIG.LOCAL_PROXY}${path}`, {
|
|
58
|
+
...opts,
|
|
59
|
+
headers: { 'Content-Type': 'application/json', ...(opts.headers || {}) },
|
|
60
|
+
});
|
|
61
|
+
const data = await resp.json();
|
|
62
|
+
if (!resp.ok) throw new Error(data.message || `GitHub API error ${resp.status}`);
|
|
63
|
+
return data;
|
|
64
|
+
}
|
|
65
|
+
|
|
32
66
|
const token = ghGetToken();
|
|
33
67
|
const resp = await fetch(`https://api.github.com${path}`, {
|
|
34
68
|
...opts,
|
|
@@ -279,6 +313,7 @@ window.GitHubUpload = {
|
|
|
279
313
|
setToken: ghSetToken,
|
|
280
314
|
clearToken: ghClearToken,
|
|
281
315
|
getUser: ghGetUser,
|
|
316
|
+
tryLocalProxy: ghTryLocalProxy,
|
|
282
317
|
startDeviceFlow: ghStartDeviceFlow,
|
|
283
318
|
pollForToken: ghPollForToken,
|
|
284
319
|
createIllustrationPR: ghCreateIllustrationPR,
|