@keenmate/pure-admin-core 2.3.6 → 2.5.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/README.md +23 -29
- package/dist/css/main.css +68 -148
- package/package.json +1 -5
- package/snippets/AUDIT.md +94 -0
- package/snippets/alerts.html +264 -89
- package/snippets/badges.html +193 -61
- package/snippets/buttons.html +178 -0
- package/snippets/callouts.html +210 -129
- package/snippets/cards.html +383 -200
- package/snippets/checkbox-lists.html +199 -65
- package/snippets/code.html +55 -11
- package/snippets/command-palette.html +401 -111
- package/snippets/comparison.html +144 -93
- package/snippets/customization.html +311 -104
- package/snippets/data-display.html +584 -0
- package/snippets/detail-panel.html +470 -138
- package/snippets/filter-card.html +246 -0
- package/snippets/forms.html +408 -308
- package/snippets/grid.html +253 -141
- package/snippets/layout.html +379 -480
- package/snippets/lists.html +144 -47
- package/snippets/loaders.html +64 -39
- package/snippets/manifest.json +330 -280
- package/snippets/modal-dialogs.html +137 -64
- package/snippets/modals.html +221 -151
- package/snippets/notifications.html +285 -0
- package/snippets/popconfirm.html +213 -19
- package/snippets/profile.html +290 -330
- package/snippets/statistics.html +247 -0
- package/snippets/tables.html +359 -150
- package/snippets/tabs.html +129 -45
- package/snippets/timeline.html +123 -56
- package/snippets/toasts.html +179 -31
- package/snippets/tooltips.html +199 -81
- package/snippets/typography.html +183 -58
- package/snippets/utilities.html +511 -415
- package/snippets/virtual-scroll.html +201 -75
- package/snippets/web-daterangepicker.html +369 -189
- package/snippets/web-multiselect.html +360 -124
- package/src/scss/core-components/_alerts.scss +51 -12
- package/src/scss/core-components/_pagers.scss +1 -1
- package/src/scss/core-components/_popconfirm.scss +35 -13
- package/src/scss/core-components/_profile.scss +18 -8
- package/src/scss/core-components/_statistics.scss +12 -12
- package/src/scss/core-components/_tables.scss +2 -134
- package/src/scss/variables/_components.scss +17 -2
- package/scripts/download-themes.js +0 -351
package/snippets/toasts.html
CHANGED
|
@@ -3,17 +3,27 @@
|
|
|
3
3
|
Pure Admin Visual Framework
|
|
4
4
|
================================ -->
|
|
5
5
|
|
|
6
|
-
<!--
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
<!--
|
|
7
|
+
Toast containers live at body level so toasts float above the layout.
|
|
8
|
+
Include one container per position you plan to use (usually all six,
|
|
9
|
+
once, in the app shell).
|
|
10
|
+
|
|
11
|
+
IMPORTANT: positions use CSS logical property names (start/end), NOT
|
|
12
|
+
left/right, so the UI mirrors correctly in RTL. --top-end is the
|
|
13
|
+
most common "toast in the upper-right" slot in LTR.
|
|
14
|
+
-->
|
|
15
|
+
<div id="toast-container-top-end" class="pa-toast-container pa-toast-container--top-end"></div>
|
|
16
|
+
<div id="toast-container-top-center" class="pa-toast-container pa-toast-container--top-center"></div>
|
|
17
|
+
<div id="toast-container-top-start" class="pa-toast-container pa-toast-container--top-start"></div>
|
|
18
|
+
<div id="toast-container-bottom-end" class="pa-toast-container pa-toast-container--bottom-end"></div>
|
|
12
19
|
<div id="toast-container-bottom-center" class="pa-toast-container pa-toast-container--bottom-center"></div>
|
|
13
|
-
<div id="toast-container-bottom-
|
|
20
|
+
<div id="toast-container-bottom-start" class="pa-toast-container pa-toast-container--bottom-start"></div>
|
|
14
21
|
|
|
15
22
|
|
|
16
|
-
<!--
|
|
23
|
+
<!-- ================================
|
|
24
|
+
TOAST STRUCTURE — BORDERED VARIANTS
|
|
25
|
+
Card-background with a coloured border and tinted icon chip.
|
|
26
|
+
================================ -->
|
|
17
27
|
|
|
18
28
|
<!-- Primary Toast -->
|
|
19
29
|
<div class="pa-toast pa-toast--primary pa-toast--show">
|
|
@@ -66,9 +76,60 @@
|
|
|
66
76
|
</div>
|
|
67
77
|
|
|
68
78
|
|
|
69
|
-
<!--
|
|
79
|
+
<!-- ================================
|
|
80
|
+
FILLED VARIANTS
|
|
81
|
+
Full-colour background; icon chip is a white-at-20%-alpha pill;
|
|
82
|
+
__actions separator goes to a 25% white line.
|
|
83
|
+
================================ -->
|
|
84
|
+
|
|
85
|
+
<!-- Filled Primary -->
|
|
86
|
+
<div class="pa-toast pa-toast--filled-primary pa-toast--show">
|
|
87
|
+
<div class="pa-toast__icon">ℹ️</div>
|
|
88
|
+
<div class="pa-toast__content">
|
|
89
|
+
<div class="pa-toast__title">Heads up</div>
|
|
90
|
+
<div class="pa-toast__message">This is a filled primary toast.</div>
|
|
91
|
+
</div>
|
|
92
|
+
<button class="pa-toast__close" aria-label="Close">✕</button>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<!-- Filled Success -->
|
|
96
|
+
<div class="pa-toast pa-toast--filled-success pa-toast--show">
|
|
97
|
+
<div class="pa-toast__icon">✓</div>
|
|
98
|
+
<div class="pa-toast__content">
|
|
99
|
+
<div class="pa-toast__title">Saved</div>
|
|
100
|
+
<div class="pa-toast__message">Changes stored successfully.</div>
|
|
101
|
+
</div>
|
|
102
|
+
<button class="pa-toast__close" aria-label="Close">✕</button>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<!-- Pattern: pa-toast--filled-{primary|success|danger|warning|info} and pa-toast--filled-color-{1..9} -->
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
<!-- ================================
|
|
109
|
+
TOAST WITH ACTION BUTTONS
|
|
110
|
+
__actions sits under a separator — good fit for "Undo" on an
|
|
111
|
+
optimistic delete, "Retry" on a failed request, etc.
|
|
112
|
+
================================ -->
|
|
113
|
+
|
|
114
|
+
<div class="pa-toast pa-toast--info pa-toast--show">
|
|
115
|
+
<div class="pa-toast__icon">🗑️</div>
|
|
116
|
+
<div class="pa-toast__content">
|
|
117
|
+
<div class="pa-toast__title">Entry removed</div>
|
|
118
|
+
<div class="pa-toast__message">The record was deleted from the list.</div>
|
|
119
|
+
<div class="pa-toast__actions">
|
|
120
|
+
<button class="pa-btn pa-btn--xs pa-btn--secondary">Undo</button>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
<button class="pa-toast__close" aria-label="Close">✕</button>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
<!-- ================================
|
|
128
|
+
TOAST WITH AUTO-DISMISS PROGRESS BAR
|
|
129
|
+
__progress is absolutely positioned along the bottom; JS animates
|
|
130
|
+
its width from 100% → 0% over the toast's lifetime.
|
|
131
|
+
================================ -->
|
|
70
132
|
|
|
71
|
-
<!-- Toast with Auto-dismiss Progress -->
|
|
72
133
|
<div class="pa-toast pa-toast--primary pa-toast--show">
|
|
73
134
|
<div class="pa-toast__icon">ℹ</div>
|
|
74
135
|
<div class="pa-toast__content">
|
|
@@ -80,11 +141,37 @@
|
|
|
80
141
|
</div>
|
|
81
142
|
|
|
82
143
|
|
|
83
|
-
<!--
|
|
144
|
+
<!-- ================================
|
|
145
|
+
THEME COLOR SLOT VARIANTS
|
|
146
|
+
================================ -->
|
|
147
|
+
|
|
148
|
+
<!-- Bordered theme-color-1 toast -->
|
|
149
|
+
<div class="pa-toast pa-toast--color-1 pa-toast--show">
|
|
150
|
+
<div class="pa-toast__icon">●</div>
|
|
151
|
+
<div class="pa-toast__content">
|
|
152
|
+
<div class="pa-toast__title">Color 1</div>
|
|
153
|
+
<div class="pa-toast__message">Border and icon pulled from <code>--pa-color-1</code>.</div>
|
|
154
|
+
</div>
|
|
155
|
+
<button class="pa-toast__close" aria-label="Close">✕</button>
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
<!-- Pattern: pa-toast--color-{1..9} (bordered) and pa-toast--filled-color-{1..9} (filled) -->
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
<!-- ================================
|
|
162
|
+
JAVASCRIPT API
|
|
163
|
+
The real implementation lives in demo/js/toast-service.js
|
|
164
|
+
(exposed as window.PureAdmin.toast). Below is a minimal
|
|
165
|
+
reference for embedding toasts without that service.
|
|
166
|
+
================================ -->
|
|
167
|
+
|
|
84
168
|
<script>
|
|
85
169
|
// Create a toast notification
|
|
86
170
|
function createToast(position, variant, title, message, duration = 5000, showProgress = false, persistent = false) {
|
|
171
|
+
// position is one of: top-end, top-start, top-center, bottom-end, bottom-start, bottom-center
|
|
87
172
|
const container = document.getElementById(`toast-container-${position}`);
|
|
173
|
+
if (!container) return;
|
|
174
|
+
|
|
88
175
|
const toastId = `toast-${Date.now()}-${Math.random()}`;
|
|
89
176
|
|
|
90
177
|
const toast = document.createElement('div');
|
|
@@ -111,44 +198,105 @@ function createToast(position, variant, title, message, duration = 5000, showPro
|
|
|
111
198
|
|
|
112
199
|
container.appendChild(toast);
|
|
113
200
|
|
|
114
|
-
//
|
|
115
|
-
setTimeout(() =>
|
|
116
|
-
toast.classList.add('pa-toast--show');
|
|
117
|
-
}, 10);
|
|
201
|
+
// Flip to show state on the next frame so the transition runs
|
|
202
|
+
setTimeout(() => toast.classList.add('pa-toast--show'), 10);
|
|
118
203
|
|
|
119
|
-
// Progress bar animation
|
|
204
|
+
// Progress bar animation — width transitions from 100% → 0% over the toast lifetime
|
|
120
205
|
if (showProgress && !persistent) {
|
|
121
206
|
const progress = toast.querySelector('.pa-toast__progress');
|
|
122
207
|
if (progress) {
|
|
123
208
|
progress.style.transition = `width ${duration}ms linear`;
|
|
124
|
-
setTimeout(() => {
|
|
125
|
-
progress.style.width = '0%';
|
|
126
|
-
}, 50);
|
|
209
|
+
setTimeout(() => { progress.style.width = '0%'; }, 50);
|
|
127
210
|
}
|
|
128
211
|
}
|
|
129
212
|
|
|
130
|
-
// Auto-dismiss (only if not persistent)
|
|
131
213
|
if (!persistent) {
|
|
132
|
-
setTimeout(() =>
|
|
133
|
-
dismissToast(toastId);
|
|
134
|
-
}, duration);
|
|
214
|
+
setTimeout(() => dismissToast(toastId), duration);
|
|
135
215
|
}
|
|
136
216
|
}
|
|
137
217
|
|
|
138
|
-
// Dismiss a toast
|
|
139
218
|
function dismissToast(toastId) {
|
|
140
219
|
const toast = document.getElementById(toastId);
|
|
141
220
|
if (!toast) return;
|
|
142
|
-
|
|
143
221
|
toast.classList.remove('pa-toast--show');
|
|
144
222
|
toast.classList.add('pa-toast--hide');
|
|
145
|
-
|
|
146
|
-
setTimeout(() => {
|
|
147
|
-
toast.remove();
|
|
148
|
-
}, 300);
|
|
223
|
+
setTimeout(() => toast.remove(), 300);
|
|
149
224
|
}
|
|
150
225
|
|
|
151
226
|
// Usage examples:
|
|
152
|
-
// createToast('top-
|
|
153
|
-
// createToast('top-
|
|
227
|
+
// createToast('top-end', 'success', 'Saved', 'Operation completed.');
|
|
228
|
+
// createToast('top-end', 'warning', 'Heads up', 'Please review.', 0, false, true); // persistent
|
|
154
229
|
</script>
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
<!-- ================================
|
|
233
|
+
COMPONENT REFERENCE
|
|
234
|
+
================================ -->
|
|
235
|
+
|
|
236
|
+
<!--
|
|
237
|
+
CONTAINERS:
|
|
238
|
+
- .pa-toast-container — fixed, pointer-events: none so toasts through
|
|
239
|
+
- .pa-toast-container--top-end — upper inline-end (right in LTR, left in RTL)
|
|
240
|
+
- .pa-toast-container--top-start — upper inline-start (left in LTR, right in RTL)
|
|
241
|
+
- .pa-toast-container--top-center — upper centre (translateX)
|
|
242
|
+
- .pa-toast-container--bottom-end — lower inline-end
|
|
243
|
+
- .pa-toast-container--bottom-start — lower inline-start
|
|
244
|
+
- .pa-toast-container--bottom-center — lower centre
|
|
245
|
+
|
|
246
|
+
(No --*-right / --*-left classes exist. Logical props mirror in RTL.)
|
|
247
|
+
|
|
248
|
+
TOAST ITEM:
|
|
249
|
+
- .pa-toast — base toast (card-bg + border + shadow); starts hidden
|
|
250
|
+
- .pa-toast--show — animation end state: opacity 1, transform: 0 (apply via JS)
|
|
251
|
+
- .pa-toast--hide — animation exit state: opacity 0, transform: off-axis
|
|
252
|
+
|
|
253
|
+
BORDERED VARIANTS (coloured border + tinted icon chip):
|
|
254
|
+
- .pa-toast--primary / --success / --danger / --warning / --info
|
|
255
|
+
- .pa-toast--color-{1..9} — theme colour slots
|
|
256
|
+
|
|
257
|
+
FILLED VARIANTS (full-colour background):
|
|
258
|
+
- .pa-toast--filled-primary / -success / -danger / -warning / -info
|
|
259
|
+
- .pa-toast--filled-color-{1..9}
|
|
260
|
+
|
|
261
|
+
SUB-ELEMENTS:
|
|
262
|
+
- .pa-toast__icon — leading chip (48×48 default, flex-centered)
|
|
263
|
+
- .pa-toast__content — flex: 1 column; hosts __title + __message (+ __actions)
|
|
264
|
+
- .pa-toast__title — bold, text-color-1
|
|
265
|
+
- .pa-toast__message — text-color-2, line-height-base
|
|
266
|
+
- .pa-toast__actions — optional button row under a 1px separator (Undo/Retry/etc.)
|
|
267
|
+
- .pa-toast__close — 32×32 trailing close button (inherits color)
|
|
268
|
+
- .pa-toast__progress — absolute bar along the bottom edge; JS animates width → 0
|
|
269
|
+
|
|
270
|
+
RESPONSIVE:
|
|
271
|
+
- Below $mobile-breakpoint the container goes full-width (inset-inline: $spacing-md)
|
|
272
|
+
and centre positions drop their translateX — so toasts are readable on phones.
|
|
273
|
+
|
|
274
|
+
PATTERNS:
|
|
275
|
+
|
|
276
|
+
Bordered toast:
|
|
277
|
+
<div class="pa-toast pa-toast--success pa-toast--show">
|
|
278
|
+
<div class="pa-toast__icon">✓</div>
|
|
279
|
+
<div class="pa-toast__content">
|
|
280
|
+
<div class="pa-toast__title">Saved</div>
|
|
281
|
+
<div class="pa-toast__message">Entry stored.</div>
|
|
282
|
+
</div>
|
|
283
|
+
<button class="pa-toast__close" aria-label="Close">✕</button>
|
|
284
|
+
</div>
|
|
285
|
+
|
|
286
|
+
Toast with Undo action:
|
|
287
|
+
<div class="pa-toast pa-toast--info pa-toast--show">
|
|
288
|
+
<div class="pa-toast__content">
|
|
289
|
+
<div class="pa-toast__title">Entry removed</div>
|
|
290
|
+
<div class="pa-toast__actions">
|
|
291
|
+
<button class="pa-btn pa-btn--xs pa-btn--secondary">Undo</button>
|
|
292
|
+
</div>
|
|
293
|
+
</div>
|
|
294
|
+
<button class="pa-toast__close" aria-label="Close">✕</button>
|
|
295
|
+
</div>
|
|
296
|
+
|
|
297
|
+
Toast with progress bar:
|
|
298
|
+
<div class="pa-toast pa-toast--primary pa-toast--show">
|
|
299
|
+
…
|
|
300
|
+
<div class="pa-toast__progress w-100" style="transition: width 5000ms linear;"></div>
|
|
301
|
+
</div>
|
|
302
|
+
-->
|
package/snippets/tooltips.html
CHANGED
|
@@ -89,18 +89,25 @@
|
|
|
89
89
|
<span class="pa-tooltip pa-tooltip--color-9" data-tooltip="Color 9">Color 9</span>
|
|
90
90
|
|
|
91
91
|
|
|
92
|
-
<!-- CURSOR MODIFIERS -->
|
|
92
|
+
<!-- CURSOR / UNDERLINE MODIFIERS -->
|
|
93
93
|
|
|
94
|
-
<!-- Default tooltip (inherits parent cursor
|
|
94
|
+
<!-- Default tooltip (inherits parent cursor — good for clickable elements like buttons, tabs) -->
|
|
95
95
|
<button class="pa-btn pa-btn--primary pa-tooltip" data-tooltip="Click to view">
|
|
96
96
|
Clickable Item
|
|
97
97
|
</button>
|
|
98
98
|
|
|
99
|
-
<!-- Help cursor tooltip (question
|
|
99
|
+
<!-- Help cursor tooltip (question-mark cursor — good for informational hints) -->
|
|
100
100
|
<span class="pa-tooltip pa-tooltip--help" data-tooltip="This provides helpful information">
|
|
101
101
|
What's this?
|
|
102
102
|
</span>
|
|
103
103
|
|
|
104
|
+
<!-- Keyword tooltip (dotted underline + help cursor — good for inline term explanations) -->
|
|
105
|
+
<p>
|
|
106
|
+
The system uses
|
|
107
|
+
<span class="pa-tooltip pa-tooltip--keyword" data-tooltip="JSON Web Tokens: a signed claim used for stateless auth">JWT</span>
|
|
108
|
+
for session authentication.
|
|
109
|
+
</p>
|
|
110
|
+
|
|
104
111
|
|
|
105
112
|
<!-- COLORED TOOLTIPS WITH POSITIONS -->
|
|
106
113
|
|
|
@@ -172,6 +179,42 @@
|
|
|
172
179
|
</span>
|
|
173
180
|
|
|
174
181
|
|
|
182
|
+
<!-- ================================
|
|
183
|
+
JS-PORTAL TOOLTIP (.pa-tooltip-floating)
|
|
184
|
+
A separate class for tooltips rendered into the body by JS (the
|
|
185
|
+
tooltips-popovers.js script does this automatically). Use when the
|
|
186
|
+
trigger sits inside an overflow: hidden container — a CSS tooltip
|
|
187
|
+
would be clipped; the portal-rendered one escapes the parent.
|
|
188
|
+
|
|
189
|
+
Consumers don't author this markup directly — it's emitted by
|
|
190
|
+
the tooltip JS at runtime. But for framework wrappers (Svelte/Vue/
|
|
191
|
+
React) that render their own portal tooltip, match this shape:
|
|
192
|
+
================================ -->
|
|
193
|
+
|
|
194
|
+
<div class="pa-tooltip-floating" role="tooltip">
|
|
195
|
+
Tooltip text here
|
|
196
|
+
</div>
|
|
197
|
+
|
|
198
|
+
<!-- Floating tooltip with colour / multiline variants -->
|
|
199
|
+
<div class="pa-tooltip-floating pa-tooltip--primary" role="tooltip">Primary</div>
|
|
200
|
+
<div class="pa-tooltip-floating pa-tooltip--success" role="tooltip">Success</div>
|
|
201
|
+
<div class="pa-tooltip-floating pa-tooltip--warning" role="tooltip">Warning</div>
|
|
202
|
+
<div class="pa-tooltip-floating pa-tooltip--danger" role="tooltip">Danger</div>
|
|
203
|
+
<div class="pa-tooltip-floating pa-tooltip--color-3" role="tooltip">Theme color 3</div>
|
|
204
|
+
|
|
205
|
+
<div class="pa-tooltip-floating pa-tooltip--multiline" role="tooltip">
|
|
206
|
+
Long multi-line content that wraps inside the tooltip box.
|
|
207
|
+
</div>
|
|
208
|
+
|
|
209
|
+
<!--
|
|
210
|
+
If you attach the portal tooltip to an element that ALSO has a
|
|
211
|
+
pa-tooltip CSS class, add pa-tooltip--floating to the element to
|
|
212
|
+
suppress the CSS pseudo tooltip — otherwise you get two tooltips
|
|
213
|
+
stacked over the trigger.
|
|
214
|
+
-->
|
|
215
|
+
<span class="pa-tooltip pa-tooltip--floating" data-tooltip="handled by JS">Trigger</span>
|
|
216
|
+
|
|
217
|
+
|
|
175
218
|
<!-- POPOVERS - Basic -->
|
|
176
219
|
|
|
177
220
|
<!-- Popovers are click-triggered rich content overlays
|
|
@@ -394,86 +437,161 @@ document.addEventListener('content-loaded', function() {
|
|
|
394
437
|
</script>
|
|
395
438
|
|
|
396
439
|
|
|
397
|
-
<!--
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
- pa-tooltip (base class, top position by default)
|
|
401
|
-
|
|
402
|
-
POSITIONS (RTL-aware):
|
|
403
|
-
- pa-tooltip--end (inline-end: right in LTR, left in RTL)
|
|
404
|
-
- pa-tooltip--bottom
|
|
405
|
-
- pa-tooltip--start (inline-start: left in LTR, right in RTL)
|
|
406
|
-
|
|
407
|
-
VARIANTS:
|
|
408
|
-
- pa-tooltip--primary (primary colored background)
|
|
409
|
-
- pa-tooltip--success (success colored background)
|
|
410
|
-
- pa-tooltip--warning (warning colored background)
|
|
411
|
-
- pa-tooltip--danger (danger colored background)
|
|
412
|
-
- pa-tooltip--color-1 through pa-tooltip--color-9 (theme-defined colors)
|
|
413
|
-
|
|
414
|
-
MULTILINE:
|
|
415
|
-
- pa-tooltip--multiline (allows text wrapping)
|
|
416
|
-
|
|
417
|
-
POPOVERS:
|
|
418
|
-
- pa-popover (base container)
|
|
419
|
-
|
|
420
|
-
POSITIONING (use data-placement attribute, RTL-aware):
|
|
421
|
-
- data-placement="top" (default)
|
|
422
|
-
- data-placement="end" (inline-end: right in LTR, left in RTL)
|
|
423
|
-
- data-placement="bottom"
|
|
424
|
-
- data-placement="start" (inline-start: left in LTR, right in RTL)
|
|
425
|
-
|
|
426
|
-
SIZES:
|
|
427
|
-
- pa-popover--sm (small)
|
|
428
|
-
- pa-popover--lg (large)
|
|
429
|
-
|
|
430
|
-
ALIGNMENT:
|
|
431
|
-
- pa-popover--center (centered body text)
|
|
432
|
-
- pa-popover--end (end-aligned body text)
|
|
433
|
-
|
|
434
|
-
COMPONENTS:
|
|
435
|
-
- pa-popover__trigger (button/trigger element)
|
|
436
|
-
- pa-popover__content (popover container)
|
|
437
|
-
- pa-popover__header (header section)
|
|
438
|
-
- pa-popover__body (content section)
|
|
439
|
-
- pa-popover__close (close button)
|
|
440
|
-
|
|
441
|
-
FLOATING UI FEATURES:
|
|
442
|
-
- Automatic collision detection
|
|
443
|
-
- Auto-flipping when near viewport edges
|
|
444
|
-
- Smart shift to stay visible
|
|
445
|
-
- No manual positioning needed
|
|
446
|
-
- autoUpdate for automatic repositioning on scroll/resize
|
|
447
|
-
-->
|
|
440
|
+
<!-- ================================
|
|
441
|
+
COMPONENT REFERENCE
|
|
442
|
+
================================ -->
|
|
448
443
|
|
|
449
|
-
<!-- IMPLEMENTATION NOTES -->
|
|
450
444
|
<!--
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
-
|
|
458
|
-
-
|
|
459
|
-
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
-
|
|
465
|
-
-
|
|
445
|
+
CSS TOOLTIP (.pa-tooltip):
|
|
446
|
+
Pure CSS pseudo-element tooltip — no JS needed for the basic effect.
|
|
447
|
+
Text comes from the `data-tooltip` attribute on the trigger.
|
|
448
|
+
|
|
449
|
+
Position (logical, RTL-aware):
|
|
450
|
+
- .pa-tooltip default (top)
|
|
451
|
+
- .pa-tooltip--bottom below the trigger
|
|
452
|
+
- .pa-tooltip--end inline-end (right in LTR, left in RTL)
|
|
453
|
+
- .pa-tooltip--start inline-start (left in LTR, right in RTL)
|
|
454
|
+
|
|
455
|
+
Colour variants (colour the bubble + arrow):
|
|
456
|
+
- .pa-tooltip--primary / --success / --warning / --danger
|
|
457
|
+
(--warning uses dark text automatically because yellow-on-white is
|
|
458
|
+
low-contrast; the others keep --pa-tooltip-text.)
|
|
459
|
+
- .pa-tooltip--color-{1..9} theme colour slots
|
|
460
|
+
|
|
461
|
+
Modifiers:
|
|
462
|
+
- .pa-tooltip--multiline allow text wrapping (fixed width); default
|
|
463
|
+
is single-line with ellipsis overflow.
|
|
464
|
+
- .pa-tooltip--help cursor: help (? cursor) — informational hints
|
|
465
|
+
- .pa-tooltip--keyword dotted underline + help cursor — for
|
|
466
|
+
term-explanation inline in prose.
|
|
467
|
+
- .pa-tooltip--floating suppress the CSS pseudo tooltip — used when
|
|
468
|
+
a JS portal tooltip (.pa-tooltip-floating)
|
|
469
|
+
is showing over the same trigger, to prevent
|
|
470
|
+
double tooltips.
|
|
471
|
+
|
|
472
|
+
Auto-flip (applied at runtime by tooltips-popovers.js when the
|
|
473
|
+
tooltip would overflow the viewport — not typically authored):
|
|
474
|
+
- .pa-tooltip--auto-flip-top shifted to show above after being
|
|
475
|
+
authored below
|
|
476
|
+
- .pa-tooltip--auto-flip-bottom inverse
|
|
477
|
+
- .pa-tooltip--auto-flip-start inverse of --end
|
|
478
|
+
- .pa-tooltip--auto-flip-end inverse of --start
|
|
479
|
+
(These are CSS classes the JS toggles dynamically. Safe to author
|
|
480
|
+
your tooltip with whatever side you prefer and let the JS handle
|
|
481
|
+
collisions.)
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
JS PORTAL TOOLTIP (.pa-tooltip-floating):
|
|
485
|
+
Separate class for a tooltip element appended to the body by JS. Used
|
|
486
|
+
when the trigger lives inside an `overflow: hidden` ancestor that
|
|
487
|
+
would clip the pseudo-element tooltip. Emitted automatically by
|
|
488
|
+
tooltips-popovers.js; framework wrappers should match this structure:
|
|
489
|
+
|
|
490
|
+
<div class="pa-tooltip-floating" role="tooltip">Tooltip text</div>
|
|
491
|
+
|
|
492
|
+
Variants (compose with the base class):
|
|
493
|
+
- .pa-tooltip--multiline
|
|
494
|
+
- .pa-tooltip--primary / --success / --warning / --danger
|
|
495
|
+
- .pa-tooltip--color-{1..9}
|
|
496
|
+
|
|
497
|
+
(When using .pa-tooltip-floating against a trigger that also has
|
|
498
|
+
pa-tooltip, add .pa-tooltip--floating to the trigger to hide the
|
|
499
|
+
CSS pseudo — otherwise both tooltips render.)
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
POPOVER (.pa-popover):
|
|
503
|
+
Click-triggered rich-content container. JS-positioned via Floating UI;
|
|
504
|
+
shown/hidden by toggling `data-show` on `__content`.
|
|
505
|
+
|
|
506
|
+
Structure:
|
|
507
|
+
.pa-popover[data-placement="top|bottom|start|end"]
|
|
508
|
+
button.pa-popover__trigger circular trigger button
|
|
509
|
+
.pa-popover__content[data-show] hidden without data-show
|
|
510
|
+
.pa-popover__header
|
|
511
|
+
<h4>Title</h4> header expects <h4> (styled)
|
|
512
|
+
button.pa-popover__close × close button
|
|
513
|
+
.pa-popover__body
|
|
514
|
+
<p>, <ul>/<ol>, <a>, <code> all auto-styled (see below)
|
|
515
|
+
|
|
516
|
+
Positioning:
|
|
517
|
+
- data-placement="top" (default)
|
|
518
|
+
- data-placement="bottom"
|
|
519
|
+
- data-placement="end" inline-end (RTL-aware)
|
|
520
|
+
- data-placement="start" inline-start (RTL-aware)
|
|
521
|
+
(Popovers use an attribute, not a class modifier, because positioning
|
|
522
|
+
is entirely JS-driven — there's no CSS fallback.)
|
|
523
|
+
|
|
524
|
+
Sizes:
|
|
525
|
+
- .pa-popover--sm
|
|
526
|
+
- (default)
|
|
527
|
+
- .pa-popover--lg
|
|
528
|
+
|
|
529
|
+
Body alignment:
|
|
530
|
+
- (default) text-align: start
|
|
531
|
+
- .pa-popover--center text-align: center on body
|
|
532
|
+
- .pa-popover--end text-align: end on body (RTL-aware)
|
|
533
|
+
|
|
534
|
+
Auto-styled inside .pa-popover__body:
|
|
535
|
+
- <p> spaced paragraphs; last-child bottom margin collapsed
|
|
536
|
+
- <a> accent colour, underlined, darker on hover
|
|
537
|
+
- <ul>, <ol> spacing-sm vertical margin, padding-inline-start
|
|
538
|
+
- <code> monospace, tinted background, small padding
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
FLOATING UI CONTRACT:
|
|
542
|
+
Both .pa-tooltip-floating rendering and .pa-popover positioning are
|
|
543
|
+
driven by @floating-ui/core + @floating-ui/dom. Features the demo
|
|
544
|
+
bundle wires up via tooltips-popovers.js:
|
|
545
|
+
- computePosition() with offset + flip + shift middleware
|
|
546
|
+
- autoUpdate() so tooltips / popovers reposition on scroll + resize
|
|
466
547
|
- Single shared tooltip element (performance)
|
|
467
|
-
- Positioned using computePosition() with flip, shift, offset middleware
|
|
468
|
-
|
|
469
|
-
POPOVER BEHAVIOR:
|
|
470
|
-
- Show on trigger click
|
|
471
|
-
- Hide on close button click or outside click
|
|
472
|
-
- Use data-placement attribute for positioning (not CSS classes)
|
|
473
|
-
- Positioned using computePosition() with flip, shift, offset middleware
|
|
474
|
-
- autoUpdate ensures automatic repositioning on scroll/resize
|
|
475
|
-
- Uses data-show attribute for visibility control
|
|
476
|
-
- Absolute positioning relative to trigger
|
|
477
548
|
- Only one popover open at a time
|
|
478
|
-
-
|
|
549
|
+
- Outside-click and Escape close popovers; close-button does the same
|
|
550
|
+
|
|
551
|
+
JAVASCRIPT API:
|
|
552
|
+
tooltips-popovers.js exposes:
|
|
553
|
+
window.PureAdminTooltips.init() (re-scan DOM)
|
|
554
|
+
window.PureAdminTooltips.initTooltips()
|
|
555
|
+
window.PureAdminTooltips.initPopovers()
|
|
556
|
+
window.PureAdminTooltips.showTooltip(el)
|
|
557
|
+
window.PureAdminTooltips.hideTooltip()
|
|
558
|
+
|
|
559
|
+
Call init() after dynamically-inserted content to register new
|
|
560
|
+
triggers. Demo example:
|
|
561
|
+
document.addEventListener('content-loaded', () => {
|
|
562
|
+
window.PureAdminTooltips.init();
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
STRUCTURE PATTERNS:
|
|
567
|
+
|
|
568
|
+
Simple tooltip:
|
|
569
|
+
<span class="pa-tooltip" data-tooltip="Hello">Hover me</span>
|
|
570
|
+
|
|
571
|
+
Tooltip on an icon button (bottom, coloured):
|
|
572
|
+
<button class="pa-btn pa-btn--xs pa-btn--icon-only pa-btn--danger pa-tooltip pa-tooltip--bottom" data-tooltip="Delete user">
|
|
573
|
+
🗑️
|
|
574
|
+
</button>
|
|
575
|
+
|
|
576
|
+
Keyword tooltip inline in prose (dotted underline):
|
|
577
|
+
<p>
|
|
578
|
+
Ask for a
|
|
579
|
+
<span class="pa-tooltip pa-tooltip--keyword" data-tooltip="Web Worker">WW</span>
|
|
580
|
+
when you need background threads.
|
|
581
|
+
</p>
|
|
582
|
+
|
|
583
|
+
Rich popover:
|
|
584
|
+
<div class="pa-popover" data-placement="bottom">
|
|
585
|
+
<button class="pa-popover__trigger">?</button>
|
|
586
|
+
<div class="pa-popover__content">
|
|
587
|
+
<div class="pa-popover__header">
|
|
588
|
+
<h4>Help</h4>
|
|
589
|
+
<button class="pa-popover__close">×</button>
|
|
590
|
+
</div>
|
|
591
|
+
<div class="pa-popover__body">
|
|
592
|
+
<p>Rich popover with a <a href="#">link</a> and a list:</p>
|
|
593
|
+
<ul><li>Item A</li><li>Item B</li></ul>
|
|
594
|
+
</div>
|
|
595
|
+
</div>
|
|
596
|
+
</div>
|
|
479
597
|
-->
|