@digital-ai/dot-illustrations 2.0.22 → 2.0.23

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 CHANGED
@@ -118,3 +118,64 @@ body.dark-mode .dot-illustration img.dark {
118
118
  padding-right: 0.75rem;
119
119
  font-size: 0.85rem;
120
120
  }
121
+
122
+ /* Modal styles */
123
+ #illustration-modal {
124
+ display: none;
125
+ align-items: center;
126
+ justify-content: center;
127
+ background: rgba(0,0,0,0.5);
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;
168
+ }
169
+ #illustration-modal #modal-close:hover {
170
+ color: #333;
171
+ }
172
+ @media (max-width: 600px) {
173
+ #illustration-modal .modal-content {
174
+ padding: 1rem;
175
+ max-width: 98vw;
176
+ }
177
+ #illustration-modal .modal-image img {
178
+ width: 140px;
179
+ height: 140px;
180
+ }
181
+ }
@@ -0,0 +1,67 @@
1
+ {
2
+ "add-new": "This is the add-new illustration.",
3
+ "ai": "This is the ai illustration.",
4
+ "add-new-grid": "This is the add-new-grid illustration.",
5
+ "add-team": "This is the add-team illustration.",
6
+ "add-user": "This is the add-user illustration.",
7
+ "assets": "This is the assets illustration.",
8
+ "analysis-circle": "This is the analysis-circle illustration.",
9
+ "community": "This is the community illustration.",
10
+ "chart": "This is the chart illustration.",
11
+ "custom-dashboards": "This is the custom-dashboards illustration.",
12
+ "dependency-down": "This is the dependency-down illustration.",
13
+ "dependency-up": "This is the dependency-up illustration.",
14
+ "disconnected": "This is the disconnected illustration.",
15
+ "done": "This is the done illustration.",
16
+ "dora-metrics-circle": "This is the dora-metrics-circle illustration.",
17
+ "download": "This is the download illustration.",
18
+ "empty": "This is the empty illustration.",
19
+ "error-fourhundredfour": "This is the error-fourhundredfour illustration.",
20
+ "error-fivehundred": "This is the error-fivehundred illustration.",
21
+ "error-fivehundredthree": "This is the error-fivehundredthree illustration.",
22
+ "error-fourhundredthree": "This is the error-fourhundredthree illustration.",
23
+ "favorite": "This is the favorite illustration.",
24
+ "features": "This is the features illustration.",
25
+ "folder-versioning": "This is the folder-versioning illustration.",
26
+ "forbiden-access": "This is the forbiden-access illustration.",
27
+ "filter-empty": "This is the filter-empty illustration.",
28
+ "launch": "This is the launch illustration.",
29
+ "no-files": "This is the no-files illustration.",
30
+ "no-filters": "This is the no-filters illustration.",
31
+ "nothing-defined": "This is the nothing-defined illustration.",
32
+ "password-token": "This is the password-token illustration.",
33
+ "protection-in-progress": "This is the protection-in-progress illustration.",
34
+ "reports": "This is the reports illustration.",
35
+ "scan-document": "This is the scan-document illustration.",
36
+ "survey": "This is the survey illustration.",
37
+ "user": "This is the user illustration.",
38
+ "ui-ux-improvements": "This is the ui-ux-improvements illustration.",
39
+ "upload": "This is the upload illustration.",
40
+ "work-item": "This is the work-item illustration.",
41
+ "workflows-main": "This is the workflows-main illustration.",
42
+ "research": "This is the research illustration.",
43
+ "commitrepo": "This is the commitrepo illustration.",
44
+ "analysis": "This is the analysis illustration.",
45
+ "automation": "This is the automation illustration.",
46
+ "burn-down": "This is the burn-down illustration.",
47
+ "burn-up": "This is the burn-up illustration.",
48
+ "change-credit-score": "This is the change-credit-score illustration.",
49
+ "change-data-quality": "This is the change-data-quality illustration.",
50
+ "change-executive": "This is the change-executive illustration.",
51
+ "change-impact-detection": "This is the change-impact-detection illustration.",
52
+ "change-impact-hotspots": "This is the change-impact-hotspots illustration.",
53
+ "change-failure-factors": "This is the change-failure-factors illustration.",
54
+ "change-failure-prediction": "This is the change-failure-prediction illustration.",
55
+ "CRP-failure-prediction-monitoring": "This is the CRP-failure-prediction-monitoring illustration.",
56
+ "custom": "This is the custom illustration.",
57
+ "defect": "This is the defect illustration.",
58
+ "dependency": "This is the dependency illustration.",
59
+ "dora": "This is the dora illustration.",
60
+ "executive": "This is the executive illustration.",
61
+ "change-impact": "This is the change-impact illustration.",
62
+ "item": "This is the item illustration.",
63
+ "late-task": "This is the late-task illustration.",
64
+ "onboarding": "This is the onboarding illustration.",
65
+ "data-extraction": "This is the data-extraction illustration.",
66
+ "workflow": "This is the workflow illustration."
67
+ }
package/demo/index.html CHANGED
@@ -59,5 +59,29 @@
59
59
  <!-- Illustrations will be injected here -->
60
60
  </div>
61
61
  </div>
62
+ <!-- Modal for illustration details -->
63
+ <div id="illustration-modal" class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 dark:bg-black/70 hidden">
64
+ <div class="bg-white dark:bg-gray-900 rounded-xl shadow-2xl max-w-lg w-full p-6 relative flex flex-col items-center">
65
+ <button id="modal-close" class="absolute top-3 right-3 text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 text-2xl font-bold focus:outline-none">&times;</button>
66
+ <h2 class="text-xl font-semibold mb-4 w-full text-center text-gray-900 dark:text-gray-100">Illustration preview</h2>
67
+ <div id="modal-image" class="mb-4"></div>
68
+ <div class="w-full flex flex-col gap-2 mb-2">
69
+ <label class="text-xs font-medium text-gray-500 dark:text-gray-400" for="modal-id-input">Image ID</label>
70
+ <div class="flex flex-row items-center gap-2">
71
+ <input id="modal-id-input" class="flex-1 px-2 py-1 border border-gray-300 dark:border-gray-700 rounded bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white text-base font-mono" readonly />
72
+ <button id="modal-copy-id" class="button flex items-center justify-center px-2 py-1 text-xs text-gray-400 border border-gray-300 dark:border-gray-700 rounded bg-white dark:bg-gray-800 font-normal hover:bg-blue-100 dark:hover:bg-blue-900 transition relative text-center">Copy ID</button>
73
+ </div>
74
+ </div>
75
+ <div id="modal-description" class="w-full text-center text-sm text-gray-700 dark:text-gray-300 mb-4"></div>
76
+ <div class="w-full flex flex-col gap-2 mb-2">
77
+ <label class="text-xs font-medium text-gray-500 dark:text-gray-400" for="modal-code">Code</label>
78
+ <div class="flex flex-row items-center gap-2">
79
+ <textarea id="modal-code" class="flex-1 px-2 py-1 border border-gray-300 dark:border-gray-700 rounded bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white text-xs font-mono resize-none" rows="2" readonly></textarea>
80
+ <button id="modal-copy-code" class="button flex items-center justify-center px-2 py-1 text-xs text-gray-400 border border-gray-300 dark:border-gray-700 rounded bg-white dark:bg-gray-800 font-normal hover:bg-blue-100 dark:hover:bg-blue-900 transition relative text-center">Copy Code</button>
81
+ </div>
82
+ </div>
83
+ <button id="modal-close-bottom" class="mt-4 px-4 py-2 rounded bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-gray-200 font-medium hover:bg-gray-300 dark:hover:bg-gray-600 transition">Close</button>
84
+ </div>
85
+ </div>
62
86
  </body>
63
87
  </html>
package/demo/script.js CHANGED
@@ -85,70 +85,28 @@ window.copyText = function(button) {
85
85
  });
86
86
  }
87
87
 
88
- // Theme toggle logic
89
- const button = document.getElementById('theme-toggle');
90
- const body = document.body;
91
-
92
- // Default to light mode on page load
93
- body.classList.add('light-mode');
94
-
95
- let isDarkMode = false;
96
-
97
- button.addEventListener('click', () => {
98
- isDarkMode = !isDarkMode;
99
- const imgs = document.querySelectorAll("img");
100
-
101
- if (isDarkMode) {
102
- imgs.forEach(img => {
103
- img.classList.remove("light");
104
- img.classList.add("dark");
105
- })
106
- body.classList.remove('light-mode');
107
- body.classList.add('dark-mode');
108
- button.textContent = 'Switch to light mode';
109
- } else {
110
- imgs.forEach(img => {
111
- img.classList.remove("dark");
112
- img.classList.add("light");
113
- })
114
- body.classList.remove('dark-mode');
115
- body.classList.add('light-mode');
116
- button.textContent = 'Switch to dark mode';
117
- }
118
- });
119
-
120
88
  // --- THEME SWITCHER & TABS ---
121
89
  document.addEventListener('DOMContentLoaded', () => {
122
- // Theme Switcher
123
- const themeToggle = document.getElementById('theme-toggle');
124
- const themeIcon = document.getElementById('theme-icon');
125
- const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
126
-
90
+ // --- THEME HANDLING ---
127
91
  function setTheme(dark) {
128
- const imgs = document.querySelectorAll('img');
92
+ const themeIcon = document.getElementById('theme-icon');
129
93
  if (dark) {
130
94
  root.classList.add('dark');
131
95
  localStorage.setItem('theme', 'dark');
132
- themeIcon.innerHTML = `<svg xmlns='http://www.w3.org/2000/svg' class='h-5 w-5' fill='none' viewBox='0 0 24 24' stroke='currentColor'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M21 12.79A9 9 0 1111.21 3a7 7 0 109.79 9.79z' /></svg>`;
133
- imgs.forEach(img => {
134
- img.classList.remove('light');
135
- img.classList.add('dark');
136
- });
96
+ if (themeIcon) themeIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0112 21.75c-5.385 0-9.75-4.365-9.75-9.75 0-4.005 2.356-7.45 5.748-9.002a.75.75 0 01.908.325.75.75 0 01-.098.976A7.501 7.501 0 0012 19.5a7.5 7.5 0 006.201-11.501.75.75 0 01-.098-.976.75.75 0 01.908-.325c3.392 1.552 5.748 4.997 5.748 9.002z" /></svg>`;
137
97
  } else {
138
98
  root.classList.remove('dark');
139
99
  localStorage.setItem('theme', 'light');
140
- themeIcon.innerHTML = `<svg xmlns='http://www.w3.org/2000/svg' class='h-5 w-5' fill='none' viewBox='0 0 24 24' stroke='currentColor'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M12 3v1m0 16v1m8.66-13.66l-.71.71M4.05 19.07l-.71.71M21 12h-1M4 12H3m16.66 6.66l-.71-.71M4.05 4.93l-.71-.71M16 12a4 4 0 11-8 0 4 4 0 018 0z' /></svg>`;
141
- imgs.forEach(img => {
142
- img.classList.remove('dark');
143
- img.classList.add('light');
144
- });
100
+ if (themeIcon) themeIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1.5M12 19.5V21M4.219 4.219l1.061 1.061M17.657 17.657l1.061 1.061M3 12h1.5M19.5 12H21M4.219 19.781l1.061-1.061M17.657 6.343l1.061-1.061M12 7.5A4.5 4.5 0 1012 16.5 4.5 4.5 0 0012 7.5z" /></svg>`;
145
101
  }
146
102
  }
147
103
 
148
- // Initial theme
149
- const savedTheme = localStorage.getItem('theme');
150
- setTheme(savedTheme === 'dark' || (!savedTheme && prefersDark));
151
-
104
+ // Theme Switcher
105
+ const themeToggle = document.getElementById('theme-toggle');
106
+ const themeIcon = document.getElementById('theme-icon');
107
+ // Force light theme on initial load
108
+ setTheme(false);
109
+ localStorage.setItem('theme', 'light');
152
110
  themeToggle.addEventListener('click', () => {
153
111
  setTheme(!root.classList.contains('dark'));
154
112
  });
@@ -226,6 +184,57 @@ document.addEventListener('DOMContentLoaded', () => {
226
184
  renderIllustrations();
227
185
  };
228
186
 
187
+ // --- MODAL LOGIC ---
188
+ let illustrationDescriptions = {};
189
+ let descriptionsLoaded = false;
190
+ let descriptionsLoadError = false;
191
+ fetch('descriptions.json')
192
+ .then(res => res.json())
193
+ .then(data => { illustrationDescriptions = data; descriptionsLoaded = true; })
194
+ .catch(() => { illustrationDescriptions = {}; descriptionsLoaded = true; descriptionsLoadError = true; });
195
+
196
+ const modal = document.getElementById('illustration-modal');
197
+ const modalImage = document.getElementById('modal-image');
198
+ const modalIdInput = document.getElementById('modal-id-input');
199
+ const modalDescription = document.getElementById('modal-description');
200
+ const modalCode = document.getElementById('modal-code');
201
+ const modalCopyId = document.getElementById('modal-copy-id');
202
+ const modalCopyCode = document.getElementById('modal-copy-code');
203
+ const modalClose = document.getElementById('modal-close');
204
+ const modalCloseBottom = document.getElementById('modal-close-bottom');
205
+
206
+ function openModal(illustration) {
207
+ if (modalDescription) modalDescription.innerHTML = '';
208
+ if (!descriptionsLoaded) return;
209
+ const themeClass = root.classList.contains('dark') ? 'dark' : 'light';
210
+ let categoryClass = "";
211
+ if (globalList.includes(illustration)) categoryClass = "global-illustration";
212
+ else if (dashboardsList.includes(illustration)) categoryClass = "dashboards-illustration";
213
+ modalImage.innerHTML = `<span class=\"dot-illustration\"><img src=\"svgs/${illustration}.svg\" class=\"${illustration} ${themeClass} ${categoryClass}\" style=\"width:286px;height:286px;object-fit:contain;\"/></span>`;
214
+ modalIdInput.value = illustration;
215
+ const codeString = `<span class=\"dot-illustration\"><img src=\"svgs/${illustration}.svg\" class=\"${illustration} ${themeClass} ${categoryClass}\"/></span>`;
216
+ modalCode.value = codeString;
217
+ modal.classList.add('active');
218
+ modal.classList.remove('hidden');
219
+ }
220
+ function closeModal() {
221
+ modal.classList.remove('active');
222
+ modal.classList.add('hidden');
223
+ }
224
+ modalClose.addEventListener('click', closeModal);
225
+ modalCloseBottom.addEventListener('click', closeModal);
226
+ modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });
227
+ document.addEventListener('keydown', (e) => { if (modal.classList.contains('active') && e.key === 'Escape') closeModal(); });
228
+ modalCopyId.addEventListener('click', () => {
229
+ navigator.clipboard.writeText(modalIdInput.value);
230
+ showToast('Copied ID: ' + modalIdInput.value);
231
+ });
232
+ modalCopyCode.addEventListener('click', () => {
233
+ navigator.clipboard.writeText(modalCode.value);
234
+ showToast('Copied code: ' + modalCode.value);
235
+ });
236
+
237
+ // --- ILLUSTRATION RENDERING ---
229
238
  function renderIllustrations() {
230
239
  const list = document.getElementById("illustration-list");
231
240
  list.innerHTML = "";
@@ -263,7 +272,7 @@ document.addEventListener('DOMContentLoaded', () => {
263
272
  </button>
264
273
  <div class="flex-1 flex flex-col justify-center items-center">
265
274
  <span class="dot-illustration">
266
- <img src="./svgs/${illustration}.svg" class="${illustration} ${themeClass} ${categoryClass}"/>
275
+ <img src="svgs/${illustration}.svg" class="${illustration} ${themeClass} ${categoryClass}"/>
267
276
  </span>
268
277
  <span class="iconID block text-center text-base font-medium text-gray-800 dark:text-gray-200 my-2">${illustration}</span>
269
278
  </div>
@@ -277,10 +286,19 @@ document.addEventListener('DOMContentLoaded', () => {
277
286
  <span class="tooltiptext left-1/2 -translate-x-1/2 bottom-10 shadow-md">Copy Code</span>
278
287
  </button>
279
288
  </div>
280
- <pre class="codeBlock"><code class="codeBlock"><span class="dot-illustration"><img src="./svgs/${illustration}.svg" class="${illustration} ${themeClass} ${categoryClass}"/></span></code></pre>
289
+ <pre class="codeBlock"><code class="codeBlock"><span class="dot-illustration"><img src="svgs/${illustration}.svg" class="${illustration} ${themeClass} ${categoryClass}"/></span></code></pre>
281
290
  `;
282
291
  list.appendChild(div);
283
292
  });
293
+ // Attach modal click handler to each card
294
+ document.querySelectorAll('.copy-container').forEach(card => {
295
+ card.addEventListener('click', function(e) {
296
+ if (e.target.closest('button')) return;
297
+ if (!descriptionsLoaded) return; // Wait for descriptions
298
+ const id = this.querySelector('.iconID')?.textContent;
299
+ if (id) openModal(id);
300
+ });
301
+ });
284
302
  }
285
303
 
286
304
  // Search input
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digital-ai/dot-illustrations",
3
- "version": "2.0.22",
3
+ "version": "2.0.23",
4
4
  "description": "A central place for the design team to keep illustrations and for dev teams to find them.",
5
5
  "main": "./index.css",
6
6
  "scripts": {