@digital-ai/dot-illustrations 2.0.42 → 2.0.45
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/.github/workflows/publish.yml +1 -1
- package/README.md +176 -58
- package/demo/github-upload.js +20 -5
- package/demo/oauth-proxy/README.md +23 -0
- package/demo/oauth-proxy/worker.js +62 -0
- package/demo/oauth-proxy/wrangler.toml +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,102 +1,220 @@
|
|
|
1
|
-
# dot-illustrations
|
|
1
|
+
# dot-illustrations
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Central asset library for Digital.ai UX — illustrations and integration logos for use in products and documentation.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- illustrations
|
|
7
|
-
- integrations
|
|
5
|
+
📖 **[Browse the demo →](https://digital-ai.github.io/dot-illustrations/demo/)**
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-

|
|
7
|
+
---
|
|
11
8
|
|
|
9
|
+
## Contents
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
- [Asset types](#asset-types)
|
|
12
|
+
- [Browse the demo](#browse-the-demo)
|
|
13
|
+
- [Using illustrations](#using-illustrations)
|
|
14
|
+
- [Using integration logos](#using-integration-logos)
|
|
15
|
+
- [Adding a new illustration or integration logo](#adding-a-new-illustration-or-integration-logo)
|
|
16
|
+
- [Option A — Upload via demo UI (recommended)](#option-a--upload-via-demo-ui-recommended)
|
|
17
|
+
- [Option B — Manual contribution](#option-b--manual-contribution)
|
|
18
|
+
- [Troubleshooting](#troubleshooting)
|
|
14
19
|
|
|
20
|
+
---
|
|
15
21
|
|
|
16
|
-
##
|
|
22
|
+
## Asset types
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
| Type | Folder | Themes | React component |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| **Illustrations** | `illustrations/light/` + `illustrations/dark/` | Light + Dark | `DotIllustration` |
|
|
27
|
+
| **Integration logos** | `integrations/` | Single (no dark variant) | — (HTML only) |
|
|
19
28
|
|
|
20
|
-
|
|
29
|
+
---
|
|
21
30
|
|
|
22
|
-
|
|
31
|
+
## Browse the demo
|
|
32
|
+
|
|
33
|
+
**https://digital-ai.github.io/dot-illustrations/demo/**
|
|
34
|
+
|
|
35
|
+
The demo lets you:
|
|
36
|
+
- Browse **72 illustrations** (Global and Dashboards) and **113 integration logos**
|
|
37
|
+
- Switch between **Illustrations** and **Integrations** using the section switcher next to the search bar
|
|
38
|
+
- **Search** with fuzzy autocomplete across both sections
|
|
39
|
+
- Filter illustrations by **A–Z** (integrations only — 113 logos benefit from alphabet navigation)
|
|
40
|
+
- **Click any card** to open a detail modal with the copy-ready code snippet
|
|
41
|
+
- **Star items** to save them in your Favourites (persisted in your browser)
|
|
42
|
+
- **Upload a new illustration or integration logo** directly from the browser
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Using illustrations
|
|
47
|
+
|
|
48
|
+
### React — `DotIllustration` via `dot-components`
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { DotIllustration } from '@digital-ai/dot-components';
|
|
23
52
|
|
|
24
|
-
|
|
53
|
+
// Light (default)
|
|
54
|
+
<DotIllustration illustrationId="empty" />
|
|
55
|
+
|
|
56
|
+
// Dark
|
|
57
|
+
<DotIllustration illustrationId="done" theme="dark" />
|
|
58
|
+
|
|
59
|
+
// With tooltip
|
|
60
|
+
<DotIllustration illustrationId="features" tooltip="See all features" />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
[Full `DotIllustration` documentation →](https://digital-ai.github.io/dot-components/?path=/story/components-illustration--default)
|
|
64
|
+
|
|
65
|
+
### Standard HTML
|
|
25
66
|
|
|
26
67
|
```html
|
|
27
68
|
<link rel="stylesheet" href="./index.css" />
|
|
28
69
|
|
|
29
|
-
|
|
70
|
+
<!-- Light theme -->
|
|
71
|
+
<span class="dot-illustration">
|
|
72
|
+
<img class="done light" />
|
|
73
|
+
</span>
|
|
30
74
|
|
|
75
|
+
<!-- Dark theme -->
|
|
31
76
|
<span class="dot-illustration">
|
|
32
|
-
<img class="
|
|
77
|
+
<img class="done dark" />
|
|
33
78
|
</span>
|
|
34
79
|
```
|
|
35
80
|
|
|
36
|
-
|
|
81
|
+
Always set an explicit `width` and `height` — the library has no built-in sizing defaults.
|
|
37
82
|
|
|
38
|
-
|
|
83
|
+
---
|
|
39
84
|
|
|
40
|
-
##
|
|
85
|
+
## Using integration logos
|
|
41
86
|
|
|
42
|
-
|
|
87
|
+
There is no React component for integrations — use the HTML approach directly.
|
|
43
88
|
|
|
44
|
-
|
|
89
|
+
```html
|
|
90
|
+
<link rel="stylesheet" href="./index.css" />
|
|
45
91
|
|
|
46
|
-
|
|
92
|
+
<span class="dot-integration">
|
|
93
|
+
<img class="jenkins" />
|
|
94
|
+
</span>
|
|
95
|
+
```
|
|
47
96
|
|
|
48
|
-
|
|
97
|
+
> Integration logos are **single-theme only** — they have no dark variant.
|
|
49
98
|
|
|
50
|
-
|
|
51
|
-
<link rel="stylesheet" href="./integrations/index.css" />
|
|
99
|
+
---
|
|
52
100
|
|
|
53
|
-
|
|
101
|
+
## Adding a new illustration or integration logo
|
|
54
102
|
|
|
55
|
-
|
|
56
|
-
<img class="${integration-ID}"/>
|
|
57
|
-
</span>
|
|
58
|
-
```
|
|
103
|
+
### Option A — Upload via demo UI (recommended)
|
|
59
104
|
|
|
60
|
-
|
|
105
|
+
The demo includes a built-in upload flow that handles everything automatically.
|
|
61
106
|
|
|
62
|
-
|
|
107
|
+
#### Prerequisites
|
|
63
108
|
|
|
64
|
-
|
|
65
|
-
```css
|
|
66
|
-
/* ------------------ GLOBAL ILLUSTRATIONS -------------------- */
|
|
67
|
-
/*Path: --------- './illustrations/light/global/*.svg ----- light */
|
|
68
|
-
/*Path: --------- './illustrations/dark/global/*.svg ------ dark */
|
|
109
|
+
**On the hosted demo** (`digital-ai.github.io/dot-illustrations/demo/`): nothing to run yourself — click **Connect GitHub** and follow the device-code prompt. This works because a maintainer has deployed the `demo/oauth-proxy/` Worker + registered a GitHub OAuth App (one-time setup, see [`demo/oauth-proxy/`](demo/oauth-proxy/)). GitHub's device-flow endpoints don't support CORS, so the browser can't call them directly — the Worker forwards those two calls server-to-server. It holds no secrets; Device Flow for public OAuth Apps only needs the Client ID.
|
|
69
110
|
|
|
70
|
-
|
|
71
|
-
content: url('./illustrations/light/global/done.svg');
|
|
72
|
-
}
|
|
111
|
+
If that isn't configured yet, **Connect GitHub** falls back to a manual Personal Access Token paste-in (scope: `public_repo`).
|
|
73
112
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
113
|
+
**Running locally instead:** run the local proxy once so the demo can authenticate as you without entering a token:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# From the repo root (requires gh CLI authenticated: gh auth login)
|
|
117
|
+
node demo/local-proxy.js
|
|
77
118
|
```
|
|
78
119
|
|
|
79
|
-
|
|
120
|
+
#### Steps
|
|
80
121
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
122
|
+
1. Open **https://digital-ai.github.io/dot-illustrations/demo/** (or your local server)
|
|
123
|
+
2. Click **Upload New** in the header
|
|
124
|
+
3. Choose what you are uploading:
|
|
125
|
+
|
|
126
|
+
**Illustration**
|
|
127
|
+
- Enter the **Illustration ID** (lowercase, hyphens only — e.g. `my-new-state`)
|
|
128
|
+
- Select the **Category**: Global or Dashboards
|
|
129
|
+
- Upload the **Light SVG** (☀️) and **Dark SVG** (🌙) — both are required
|
|
130
|
+
- Click **Connect GitHub** (device-code prompt on the hosted demo, local `gh auth` session with the local proxy running, or PAT paste-in fallback) then **Create Pull Request**
|
|
131
|
+
|
|
132
|
+
**Integration logo**
|
|
133
|
+
- Enter the **Integration ID** (lowercase, hyphens — e.g. `my-tool`)
|
|
134
|
+
- Upload the single **SVG** file (no dark variant needed)
|
|
135
|
+
- Click **Connect GitHub** (device-code prompt on the hosted demo, local `gh auth` session with the local proxy running, or PAT paste-in fallback) then **Create Pull Request**
|
|
136
|
+
|
|
137
|
+
The PR is created automatically with:
|
|
138
|
+
- SVG file(s) committed to the correct folder
|
|
139
|
+
- CSS rule added to `index.css`
|
|
140
|
+
- ID added to `demo/script.js` in alphabetical order
|
|
141
|
+
|
|
142
|
+
> The local proxy uses your existing `gh auth` credentials — no token input required. The hosted demo's Connect GitHub button uses the device-flow proxy instead (see Prerequisites above); if it's not yet configured, it falls back to PAT paste-in.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### Option B — Manual contribution
|
|
147
|
+
|
|
148
|
+
Use this if the upload UI is not available.
|
|
149
|
+
|
|
150
|
+
#### Adding an illustration
|
|
151
|
+
|
|
152
|
+
1. Add your SVG files to the correct folders:
|
|
153
|
+
```
|
|
154
|
+
illustrations/light/global/my-new-state.svg
|
|
155
|
+
illustrations/dark/global/my-new-state.svg
|
|
156
|
+
```
|
|
157
|
+
Use `dashboards/` instead of `global/` for dashboard-specific illustrations.
|
|
158
|
+
|
|
159
|
+
2. Add CSS rules to `index.css`:
|
|
160
|
+
```css
|
|
161
|
+
.dot-illustration img.my-new-state.light {
|
|
162
|
+
content: url('./illustrations/light/global/my-new-state.svg');
|
|
163
|
+
}
|
|
164
|
+
.dot-illustration img.my-new-state.dark {
|
|
165
|
+
content: url('./illustrations/dark/global/my-new-state.svg');
|
|
166
|
+
}
|
|
167
|
+
```
|
|
89
168
|
|
|
90
|
-
|
|
169
|
+
3. Add the ID to `demo/script.js` inside the correct list (`globalList` or `dashboardsList`), **alphabetically ordered**:
|
|
170
|
+
```js
|
|
171
|
+
const globalList = [
|
|
172
|
+
"add-new",
|
|
173
|
+
"my-new-state", // ← inserted alphabetically
|
|
174
|
+
"no-chat",
|
|
175
|
+
];
|
|
176
|
+
```
|
|
91
177
|
|
|
92
|
-
|
|
178
|
+
#### Adding an integration logo
|
|
179
|
+
|
|
180
|
+
1. Add your SVG to `integrations/my-tool.svg`
|
|
181
|
+
|
|
182
|
+
2. Add a CSS rule to `index.css`:
|
|
183
|
+
```css
|
|
184
|
+
.dot-integration img.my-tool {
|
|
185
|
+
content: url('./integrations/my-tool.svg');
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
3. Add the ID to `demo/script.js` inside `integrationsList`, **alphabetically ordered**:
|
|
190
|
+
```js
|
|
191
|
+
const integrationsList = [
|
|
192
|
+
"microsoft-teams",
|
|
193
|
+
"my-tool", // ← inserted alphabetically
|
|
194
|
+
"mysql",
|
|
195
|
+
];
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
4. Open a pull request and post in [#dot-components](https://app.slack.com/client/T02GN6UQX/C01GVS9T7GV) on Slack for review.
|
|
199
|
+
|
|
200
|
+
---
|
|
93
201
|
|
|
94
202
|
## Troubleshooting
|
|
95
203
|
|
|
96
|
-
|
|
204
|
+
**Latest `dot-illustrations` not picked up by `dot-components`**
|
|
205
|
+
|
|
206
|
+
Add a `resolutions` entry to your `package.json`:
|
|
97
207
|
|
|
98
208
|
```json
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
```
|
|
209
|
+
"resolutions": {
|
|
210
|
+
"@digital-ai/dot-illustrations": "latest"
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Integration image not showing**
|
|
215
|
+
|
|
216
|
+
Make sure the CSS is imported: `<link rel="stylesheet" href="./index.css" />`. The library uses `content: url()` on `<img>` elements — the `<img>` tag must have **no `src` attribute** and the class must match the integration ID exactly.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
More information: [dot design system — Illustrations](https://zeroheight.com/4a9ac476a/p/86a804-illustrations)
|
package/demo/github-upload.js
CHANGED
|
@@ -6,11 +6,18 @@
|
|
|
6
6
|
* 1. Register a GitHub OAuth App at https://github.com/settings/developers
|
|
7
7
|
* - Homepage: https://digital-ai.github.io/dot-illustrations/demo/
|
|
8
8
|
* - Check "Enable Device Flow" — no callback URL needed
|
|
9
|
-
* 2.
|
|
9
|
+
* 2. Replace CLIENT_ID below with your app's Client ID
|
|
10
|
+
* 3. The Client ID is public-safe — only the Client Secret must stay private,
|
|
11
|
+
* and Device Flow never requires the secret in the browser.
|
|
12
|
+
* 4. Deploy demo/oauth-proxy/ (Cloudflare Worker) — GitHub's device-flow
|
|
13
|
+
* endpoints don't support CORS, so the browser can't call them directly;
|
|
14
|
+
* the Worker forwards those two calls server-to-server. Holds no secrets.
|
|
15
|
+
* 5. Replace OAUTH_PROXY_URL below with the deployed Worker's *.workers.dev URL.
|
|
10
16
|
*/
|
|
11
17
|
|
|
12
18
|
const GITHUB_UPLOAD_CONFIG = {
|
|
13
|
-
CLIENT_ID: '
|
|
19
|
+
CLIENT_ID: 'Ov23liJSaMsvgE5Q51cI',
|
|
20
|
+
OAUTH_PROXY_URL: 'https://dot-illustrations-oauth-proxy.dot-icons.workers.dev',
|
|
14
21
|
REPO_OWNER: 'digital-ai',
|
|
15
22
|
REPO_NAME: 'dot-illustrations',
|
|
16
23
|
BASE_BRANCH: 'main',
|
|
@@ -132,12 +139,20 @@ async function ghCreatePR(head, title, body) {
|
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
// ─── Device Flow ─────────────────────────────────────────────────────────────
|
|
142
|
+
// Both calls go through demo/oauth-proxy/ (Cloudflare Worker) — GitHub's
|
|
143
|
+
// device-flow endpoints don't support CORS, so the browser can't call
|
|
144
|
+
// github.com directly.
|
|
135
145
|
|
|
136
146
|
async function ghStartDeviceFlow() {
|
|
137
|
-
if (
|
|
147
|
+
if (
|
|
148
|
+
!GITHUB_UPLOAD_CONFIG.CLIENT_ID ||
|
|
149
|
+
GITHUB_UPLOAD_CONFIG.CLIENT_ID === 'YOUR_GITHUB_OAUTH_CLIENT_ID' ||
|
|
150
|
+
!GITHUB_UPLOAD_CONFIG.OAUTH_PROXY_URL ||
|
|
151
|
+
GITHUB_UPLOAD_CONFIG.OAUTH_PROXY_URL === 'YOUR_OAUTH_PROXY_WORKERS_DEV_URL'
|
|
152
|
+
) {
|
|
138
153
|
throw new Error('NO_CLIENT_ID');
|
|
139
154
|
}
|
|
140
|
-
const resp = await fetch(
|
|
155
|
+
const resp = await fetch(`${GITHUB_UPLOAD_CONFIG.OAUTH_PROXY_URL}/device/code`, {
|
|
141
156
|
method: 'POST',
|
|
142
157
|
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
|
|
143
158
|
body: JSON.stringify({ client_id: GITHUB_UPLOAD_CONFIG.CLIENT_ID, scope: GITHUB_UPLOAD_CONFIG.SCOPES }),
|
|
@@ -150,7 +165,7 @@ function ghPollForToken(deviceCode, intervalSec) {
|
|
|
150
165
|
return new Promise((resolve, reject) => {
|
|
151
166
|
const timer = setInterval(async () => {
|
|
152
167
|
try {
|
|
153
|
-
const resp = await fetch(
|
|
168
|
+
const resp = await fetch(`${GITHUB_UPLOAD_CONFIG.OAUTH_PROXY_URL}/access_token`, {
|
|
154
169
|
method: 'POST',
|
|
155
170
|
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
|
|
156
171
|
body: JSON.stringify({
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# OAuth device-flow proxy
|
|
2
|
+
|
|
3
|
+
Stateless Cloudflare Worker that forwards `POST /device/code` and `POST /access_token`
|
|
4
|
+
to GitHub's device-flow endpoints. Exists only because those endpoints don't support
|
|
5
|
+
CORS, so a static page can't call them directly from the browser. Holds no secrets —
|
|
6
|
+
device flow for public GitHub OAuth Apps only needs the Client ID, which the browser
|
|
7
|
+
already sends.
|
|
8
|
+
|
|
9
|
+
## Deploy (one-time, per maintainer/environment)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cd demo/oauth-proxy
|
|
13
|
+
npx wrangler login
|
|
14
|
+
npx wrangler deploy
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This prints a `*.workers.dev` URL. Then:
|
|
18
|
+
|
|
19
|
+
1. Put that URL into `OAUTH_PROXY_URL` in [`demo/github-upload.js`](../github-upload.js)
|
|
20
|
+
2. Put your GitHub OAuth App's Client ID into `CLIENT_ID` in the same file (see the
|
|
21
|
+
file's header comment for how to register the OAuth App)
|
|
22
|
+
3. If the demo isn't served from `https://digital-ai.github.io`, update
|
|
23
|
+
`ALLOWED_ORIGIN` in [`wrangler.toml`](./wrangler.toml) to match
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth device-flow proxy — Cloudflare Worker
|
|
3
|
+
*
|
|
4
|
+
* GitHub's device-flow endpoints (github.com/login/device/code and
|
|
5
|
+
* github.com/login/oauth/access_token) don't support CORS, so a static
|
|
6
|
+
* page can't call them directly from browser JS. This Worker forwards
|
|
7
|
+
* those two calls server-to-server, so the browser only ever talks to
|
|
8
|
+
* this Worker (which does send CORS headers).
|
|
9
|
+
*
|
|
10
|
+
* Holds no secrets: GitHub's device flow for public OAuth Apps only
|
|
11
|
+
* needs client_id (sent by the browser), never a client secret.
|
|
12
|
+
*
|
|
13
|
+
* Deploy: from this directory, `npx wrangler login && npx wrangler deploy`.
|
|
14
|
+
* Then set ALLOWED_ORIGIN below (or via `wrangler.toml` [vars]) and put the
|
|
15
|
+
* resulting *.workers.dev URL into demo/github-upload.js's OAUTH_PROXY_URL.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const GITHUB_ENDPOINTS = {
|
|
19
|
+
'/device/code': 'https://github.com/login/device/code',
|
|
20
|
+
'/access_token': 'https://github.com/login/oauth/access_token',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default {
|
|
24
|
+
async fetch(request, env) {
|
|
25
|
+
const allowedOrigin = env.ALLOWED_ORIGIN || 'https://digital-ai.github.io';
|
|
26
|
+
const corsHeaders = {
|
|
27
|
+
'Access-Control-Allow-Origin': allowedOrigin,
|
|
28
|
+
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
29
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
if (request.method === 'OPTIONS') {
|
|
33
|
+
return new Response(null, { headers: corsHeaders });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const url = new URL(request.url);
|
|
37
|
+
const target = GITHUB_ENDPOINTS[url.pathname];
|
|
38
|
+
|
|
39
|
+
if (!target || request.method !== 'POST') {
|
|
40
|
+
return new Response(JSON.stringify({ error: 'Not found' }), {
|
|
41
|
+
status: 404,
|
|
42
|
+
headers: { 'Content-Type': 'application/json', ...corsHeaders },
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const body = await request.text();
|
|
47
|
+
const upstream = await fetch(target, {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
headers: {
|
|
50
|
+
'Accept': 'application/json',
|
|
51
|
+
'Content-Type': 'application/json',
|
|
52
|
+
},
|
|
53
|
+
body,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const data = await upstream.text();
|
|
57
|
+
return new Response(data, {
|
|
58
|
+
status: upstream.status,
|
|
59
|
+
headers: { 'Content-Type': 'application/json', ...corsHeaders },
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
};
|
package/package.json
CHANGED