@keenmate/pure-admin-core 2.9.0-rc01 → 2.9.0-rc04
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 +61 -14
- package/dist/css/main.css +748 -2
- package/package.json +3 -1
- package/snippets/buttons.html +51 -0
- package/snippets/cards.html +34 -4
- package/snippets/comparison.html +26 -22
- package/snippets/manifest.json +180 -115
- package/snippets/range-group.html +125 -0
- package/snippets/splitter.html +216 -0
- package/snippets/statistics.html +31 -0
- package/src/js/btn-split-auto-absorb.js +327 -0
- package/src/js/command-palette.js +472 -0
- package/src/js/file-selector.js +1275 -0
- package/src/js/internal/logging.js +121 -0
- package/src/js/logic-tree-renderer.js +303 -0
- package/src/js/modal-dialogs.js +460 -0
- package/src/js/overflow.js +371 -0
- package/src/js/pa-stat-fit.js +184 -0
- package/src/js/range-group.js +663 -0
- package/src/js/search-autocomplete-v2.js +907 -0
- package/src/js/search-autocomplete.js +434 -0
- package/src/js/settings-panel.js +245 -0
- package/src/js/split-button.js +141 -0
- package/src/js/splitter.js +1323 -0
- package/src/js/toast-service.js +302 -0
- package/src/js/tooltips-popovers.js +275 -0
- package/src/js/virtual-scroll.js +143 -0
- package/src/js/virtual-textbox.js +803 -0
- package/src/scss/_core.scss +10 -0
- package/src/scss/core-components/_buttons.scss +59 -0
- package/src/scss/core-components/_cards.scss +206 -0
- package/src/scss/core-components/_overflow.scss +50 -0
- package/src/scss/core-components/_range-group.scss +474 -0
- package/src/scss/core-components/_splitter.scss +206 -0
- package/src/scss/core-components/_statistics.scss +163 -0
- package/src/scss/variables/_components.scss +56 -2
|
@@ -118,6 +118,7 @@
|
|
|
118
118
|
padding: $spacing-lg;
|
|
119
119
|
min-height: $stat-square-min-size;
|
|
120
120
|
min-width: $stat-square-min-size;
|
|
121
|
+
max-height: $stat-square-max-height; // keep full-width tiles from growing into page-dominating banners
|
|
121
122
|
position: relative;
|
|
122
123
|
border-radius: var(--pa-border-radius);
|
|
123
124
|
box-shadow: $shadow-md;
|
|
@@ -183,6 +184,17 @@
|
|
|
183
184
|
&.pa-stat--warning {
|
|
184
185
|
background-color: var(--pa-warning-bg);
|
|
185
186
|
color: var(--pa-btn-warning-text);
|
|
187
|
+
|
|
188
|
+
// Warning is the one square variant with DARK text (on a light amber
|
|
189
|
+
// surface). The number's default black text-shadow + drop-shadow stack is
|
|
190
|
+
// tuned for the white-text variants; against a dark glyph it has no
|
|
191
|
+
// contrast and smears into an "ink-blot" halo. Dial it to a whisper and
|
|
192
|
+
// drop the costly drop-shadow layer. Covers classic AND fit mode, since
|
|
193
|
+
// both render the number through .pa-stat__number.
|
|
194
|
+
.pa-stat__number {
|
|
195
|
+
text-shadow: 0 1px 1px rgba(0, 0, 0, $opacity-light);
|
|
196
|
+
filter: none;
|
|
197
|
+
}
|
|
186
198
|
}
|
|
187
199
|
|
|
188
200
|
&.pa-stat--danger {
|
|
@@ -194,6 +206,157 @@
|
|
|
194
206
|
background-color: var(--pa-text-color-2);
|
|
195
207
|
color: var(--pa-btn-primary-text);
|
|
196
208
|
}
|
|
209
|
+
|
|
210
|
+
// ----------------------------------------------------------------
|
|
211
|
+
// FIT + PROGRESSIVE DISCLOSURE mode (opt-in: [data-pa-stat-fit])
|
|
212
|
+
// The number is sized to fill the tile by pa-stat-fit.js, which also
|
|
213
|
+
// wraps __number + __symbol into a __slot > __group at runtime. Lower-
|
|
214
|
+
// priority rows (label → change → context) reveal as the tile earns
|
|
215
|
+
// both width and height.
|
|
216
|
+
//
|
|
217
|
+
// REQUIRES A HEIGHT SOURCE on the tile (grid cell with a set height,
|
|
218
|
+
// explicit height, or aspect-ratio): container-type: size makes the
|
|
219
|
+
// box size independently of its content, so without a height it falls
|
|
220
|
+
// back to the $stat-square-min-size floor.
|
|
221
|
+
// ----------------------------------------------------------------
|
|
222
|
+
&[data-pa-stat-fit] {
|
|
223
|
+
container-type: size;
|
|
224
|
+
container-name: #{$stat-square-fit-container-name};
|
|
225
|
+
flex-direction: column;
|
|
226
|
+
flex-wrap: nowrap;
|
|
227
|
+
align-content: stretch;
|
|
228
|
+
align-items: stretch;
|
|
229
|
+
max-height: none; // fit height is container-driven; undo the base cap.
|
|
230
|
+
// min-height (the base $stat-square-min-size) stays as
|
|
231
|
+
// the default height when none is set + collapse floor.
|
|
232
|
+
|
|
233
|
+
// __slot grows to take the room not used by the metadata rows; the
|
|
234
|
+
// number is fit into it. ResizeObserver watches this element.
|
|
235
|
+
.pa-stat__slot {
|
|
236
|
+
flex: 1 1 auto;
|
|
237
|
+
min-height: 0;
|
|
238
|
+
display: flex;
|
|
239
|
+
align-items: center;
|
|
240
|
+
justify-content: flex-start;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// font-size is set inline (px) on __group by the JS; children scale via em.
|
|
244
|
+
.pa-stat__group {
|
|
245
|
+
display: inline-flex;
|
|
246
|
+
align-items: baseline;
|
|
247
|
+
column-gap: $stat-square-symbol-gap;
|
|
248
|
+
line-height: 1;
|
|
249
|
+
white-space: nowrap;
|
|
250
|
+
font-weight: $font-weight-bold;
|
|
251
|
+
|
|
252
|
+
.pa-stat__number { font-size: 1em; }
|
|
253
|
+
.pa-stat__symbol {
|
|
254
|
+
font-size: #{$stat-square-fit-symbol-ratio}em;
|
|
255
|
+
opacity: $stat-symbol-opacity;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// pa-stat-fit.js wraps the metadata rows into this column so the whole
|
|
260
|
+
// group can move beside the number in the horizontal (banner) layout.
|
|
261
|
+
// The number is the HERO; the metadata is subordinate — pa-stat-fit.js sets
|
|
262
|
+
// this column's font-size to a small fraction of the fitted number size
|
|
263
|
+
// (META_RATIO), so the rows below stay "supersmall" relative to the number at
|
|
264
|
+
// every tile size. The rows are em-relative so that one font-size cascades to
|
|
265
|
+
// all three. The value here is only the no-JS fallback.
|
|
266
|
+
.pa-stat__meta {
|
|
267
|
+
display: flex;
|
|
268
|
+
flex-direction: column;
|
|
269
|
+
min-width: 0; // let children ellipsis instead of overflowing
|
|
270
|
+
flex: 0 0 auto; // vertical layout: natural height below the slot
|
|
271
|
+
font-size: $stat-square-fit-meta-size; // JS overrides inline (px); this is the fallback
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// metadata rows sit below the slot, each on its own line — all em-relative to
|
|
275
|
+
// __meta's (JS-driven) font-size so they scale with the hero number.
|
|
276
|
+
.pa-stat__label {
|
|
277
|
+
flex: 0 0 auto; // undo the base square's flex-basis:100%
|
|
278
|
+
margin-top: 0.35em;
|
|
279
|
+
font-size: 1em; // the meta base — the largest metadata line
|
|
280
|
+
}
|
|
281
|
+
.pa-stat__change {
|
|
282
|
+
flex: 0 0 auto;
|
|
283
|
+
margin-top: 0.35em;
|
|
284
|
+
font-size: 0.9em;
|
|
285
|
+
font-weight: $font-weight-semibold;
|
|
286
|
+
line-height: 1.2;
|
|
287
|
+
color: inherit; // default to the tile's text colour…
|
|
288
|
+
white-space: nowrap;
|
|
289
|
+
overflow: hidden;
|
|
290
|
+
text-overflow: ellipsis;
|
|
291
|
+
|
|
292
|
+
// …opt-in sentiment tints (same scale as the hero variant's __change)
|
|
293
|
+
&--positive { color: var(--pa-positive); }
|
|
294
|
+
&--neutral { color: var(--pa-neutral); }
|
|
295
|
+
&--negative { color: var(--pa-negative); }
|
|
296
|
+
}
|
|
297
|
+
.pa-stat__context {
|
|
298
|
+
flex: 0 0 auto;
|
|
299
|
+
margin-top: 0.35em;
|
|
300
|
+
font-size: 0.8em;
|
|
301
|
+
opacity: 0.7;
|
|
302
|
+
white-space: nowrap;
|
|
303
|
+
overflow: hidden;
|
|
304
|
+
text-overflow: ellipsis;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ---- priority ladder: P0 number always; reveal P1–P4 with space ----
|
|
308
|
+
.pa-stat__symbol,
|
|
309
|
+
.pa-stat__label,
|
|
310
|
+
.pa-stat__change,
|
|
311
|
+
.pa-stat__context { display: none; }
|
|
312
|
+
|
|
313
|
+
@container #{$stat-square-fit-container-name} (min-width: #{$stat-square-fit-symbol-min-w}) and (min-height: #{$stat-square-fit-symbol-min-h}) {
|
|
314
|
+
.pa-stat__symbol { display: inline; }
|
|
315
|
+
}
|
|
316
|
+
@container #{$stat-square-fit-container-name} (min-width: #{$stat-square-fit-label-min-w}) and (min-height: #{$stat-square-fit-label-min-h}) {
|
|
317
|
+
.pa-stat__label { display: block; }
|
|
318
|
+
}
|
|
319
|
+
@container #{$stat-square-fit-container-name} (min-width: #{$stat-square-fit-change-min-w}) and (min-height: #{$stat-square-fit-change-min-h}) {
|
|
320
|
+
.pa-stat__change { display: block; }
|
|
321
|
+
}
|
|
322
|
+
@container #{$stat-square-fit-container-name} (min-width: #{$stat-square-fit-context-min-w}) and (min-height: #{$stat-square-fit-context-min-h}) {
|
|
323
|
+
.pa-stat__context { display: block; }
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// ---- HORIZONTAL "banner" layout for wide tiles ----
|
|
327
|
+
// Toggled by pa-stat-fit.js (.pa-stat--fit-wide) when the tile is at least
|
|
328
|
+
// $stat-square-fit-horizontal-min-w wide. This CANNOT be a `@container`
|
|
329
|
+
// query: the tile is its own size container, and a container query only
|
|
330
|
+
// restyles a container's DESCENDANTS — never the container element itself,
|
|
331
|
+
// so the tile's own `flex-direction` would never flip. A JS class on the
|
|
332
|
+
// tile sidesteps that.
|
|
333
|
+
//
|
|
334
|
+
// Number on the LEFT (__slot is first in DOM → first flex item), filling
|
|
335
|
+
// the height so it stays big; the metadata column sits to its RIGHT,
|
|
336
|
+
// vertically centred. All meta rows are revealed here regardless of height
|
|
337
|
+
// — stacked beside the number they don't need vertical room — so a short
|
|
338
|
+
// wide banner still shows trend + context.
|
|
339
|
+
&.pa-stat--fit-wide {
|
|
340
|
+
flex-direction: row;
|
|
341
|
+
align-items: stretch;
|
|
342
|
+
column-gap: $spacing-lg;
|
|
343
|
+
|
|
344
|
+
.pa-stat__slot {
|
|
345
|
+
flex: 0 0 #{$stat-square-fit-number-width};
|
|
346
|
+
min-width: 0; // never let the number push past its column
|
|
347
|
+
justify-content: center; // centre the number within its column
|
|
348
|
+
}
|
|
349
|
+
.pa-stat__meta {
|
|
350
|
+
flex: 1 1 auto;
|
|
351
|
+
min-width: 0; // allow the rows to ellipsis
|
|
352
|
+
justify-content: center; // centre the rows vertically beside the number
|
|
353
|
+
}
|
|
354
|
+
.pa-stat__symbol { display: inline; }
|
|
355
|
+
.pa-stat__label,
|
|
356
|
+
.pa-stat__change,
|
|
357
|
+
.pa-stat__context { display: block; }
|
|
358
|
+
}
|
|
359
|
+
}
|
|
197
360
|
}
|
|
198
361
|
}
|
|
199
362
|
|
|
@@ -187,6 +187,11 @@ $card-tab-inline-padding-v: 0.3rem !default; // 3px - compact for header
|
|
|
187
187
|
$card-tab-inline-padding-h: 0.8rem !default; // 8px
|
|
188
188
|
$card-tab-hover-opacity: 0.1 !default;
|
|
189
189
|
|
|
190
|
+
// Responsive actions — header width below which the spread button list
|
|
191
|
+
// hides and the collapsed (split-button) form takes over. Default 28rem
|
|
192
|
+
// = 280px, which fits a 3-button action set comfortably.
|
|
193
|
+
$card-actions-collapse-at: 28rem !default;
|
|
194
|
+
|
|
190
195
|
// ============================================================================
|
|
191
196
|
// TABLE SYSTEM
|
|
192
197
|
// ============================================================================
|
|
@@ -350,11 +355,43 @@ $stat-square-symbol-gap: 0.15em !default; // tight gap between number and symb
|
|
|
350
355
|
// (~250–400px). Numbers are sized aggressively so the KPI reads as the dominant element.
|
|
351
356
|
$stat-square-number-min: 3.2rem !default; // 32px floor
|
|
352
357
|
$stat-square-number-scale: 25cqi !default; // 25% of tile width
|
|
353
|
-
$stat-square-number-max:
|
|
358
|
+
$stat-square-number-max: 7.2rem !default; // 72px ceiling (was 9.6 — full-width tiles hit the ceiling and read as oversized banners; 72px keeps a wide tile readable without dominating the page)
|
|
354
359
|
// Symbol is intentionally smaller than the number (visual hierarchy: number primary, unit secondary).
|
|
355
360
|
$stat-square-symbol-min: 1.6rem !default; // 16px floor (~50% of number-min)
|
|
356
361
|
$stat-square-symbol-scale: 12cqi !default; // 12% of tile width (~48% of number)
|
|
357
|
-
$stat-square-symbol-max:
|
|
362
|
+
$stat-square-symbol-max: 3.6rem !default; // 36px ceiling (~50% of number-max, was 4.8)
|
|
363
|
+
|
|
364
|
+
// Guard so a very wide tile (e.g. one square per full-width row instead of in a
|
|
365
|
+
// 1/3 KPI column) can't grow into a page-dominating block. Caps how tall the
|
|
366
|
+
// flex layout gets before the label is pushed to the bottom edge.
|
|
367
|
+
$stat-square-max-height: 16rem !default; // 160px
|
|
368
|
+
|
|
369
|
+
// Stat square FIT mode (opt-in via [data-pa-stat-fit]) — progressive disclosure.
|
|
370
|
+
// The number is sized to fill the box by pa-stat-fit.js (ResizeObserver); the
|
|
371
|
+
// lower-priority rows reveal as the tile earns BOTH enough width and height.
|
|
372
|
+
// NB: @container does NOT auto-interpolate Sass vars (unlike @media) — these
|
|
373
|
+
// must be emitted with #{} in the rules. Gated on width AND height so a
|
|
374
|
+
// wide-but-short banner doesn't reveal the tall-only tiers.
|
|
375
|
+
$stat-square-fit-container-name: pa-stat !default;
|
|
376
|
+
$stat-square-fit-meta-size: $font-size-xs !default; // no-JS fallback for the metadata
|
|
377
|
+
// column; pa-stat-fit.js overrides it
|
|
378
|
+
// inline with META_RATIO × number size
|
|
379
|
+
$stat-square-fit-symbol-ratio: 0.5 !default; // symbol = 0.5em of the number
|
|
380
|
+
$stat-square-fit-symbol-min-w: 8rem !default; // P1 symbol reveals at…
|
|
381
|
+
$stat-square-fit-symbol-min-h: 4.5rem !default;
|
|
382
|
+
$stat-square-fit-label-min-w: 13rem !default; // P2 label
|
|
383
|
+
$stat-square-fit-label-min-h: 6.5rem !default;
|
|
384
|
+
$stat-square-fit-change-min-w: 18rem !default; // P3 trend
|
|
385
|
+
$stat-square-fit-change-min-h: 9.5rem !default;
|
|
386
|
+
$stat-square-fit-context-min-w: 24rem !default; // P4 context
|
|
387
|
+
$stat-square-fit-context-min-h: 13rem !default;
|
|
388
|
+
|
|
389
|
+
// Horizontal "banner" arrangement: on wide tiles the number moves to the left
|
|
390
|
+
// (filling the height) and the metadata stacks in a column to its right, so the
|
|
391
|
+
// number stays dominant and the width isn't wasted. Auto-switches once the tile
|
|
392
|
+
// is at least this wide (plain width query — broadest engine support).
|
|
393
|
+
$stat-square-fit-horizontal-min-w: 32rem !default; // ≥ this wide → horizontal banner
|
|
394
|
+
$stat-square-fit-number-width: 44% !default; // number column share in horizontal
|
|
358
395
|
|
|
359
396
|
// Stat shadow values
|
|
360
397
|
$stat-text-shadow-1-y: 4px !default;
|
|
@@ -772,3 +809,20 @@ $bar-list-bar-bg: rgba(0, 0, 0, 0.06) !default;
|
|
|
772
809
|
$bar-list-label-font-size: $font-size-sm !default;
|
|
773
810
|
$bar-list-value-font-size: $font-size-sm !default;
|
|
774
811
|
$bar-list-value-font-weight: $font-weight-semibold !default;
|
|
812
|
+
|
|
813
|
+
// ============================================================================
|
|
814
|
+
// SPLITTER SYSTEM
|
|
815
|
+
// ============================================================================
|
|
816
|
+
$splitter-gutter-size: 0.6rem !default; // 6px gutter thickness
|
|
817
|
+
$splitter-gutter-bg: rgba(128, 128, 128, 0.08) !default;
|
|
818
|
+
$splitter-gutter-hover-bg: rgba(128, 128, 128, 0.18) !default;
|
|
819
|
+
$splitter-gutter-active-bg: rgba($accent-color, 0.35) !default; // mid-drag
|
|
820
|
+
$splitter-gutter-grip-length: 2.4rem !default; // 24px grip indicator
|
|
821
|
+
$splitter-gutter-grip-thickness: 2px !default;
|
|
822
|
+
$splitter-gutter-grip-color: rgba(128, 128, 128, 0.45) !default;
|
|
823
|
+
$splitter-gutter-grip-hover-color: $accent-color !default;
|
|
824
|
+
$splitter-focus-ring-color: rgba($accent-color, 0.4) !default;
|
|
825
|
+
$splitter-focus-ring-width: 2px !default;
|
|
826
|
+
$splitter-transition: background-color 0.15s ease !default;
|
|
827
|
+
$splitter-pane-min-size: 0 !default; // absolute floor regardless of constraints
|
|
828
|
+
$splitter-rail-size: 4rem !default; // 40px — start pane width when minimized to rail
|