@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
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<!-- ================================
|
|
2
|
+
WEB DATE RANGE PICKER
|
|
3
|
+
A framework-agnostic web component from @keenmate/web-daterangepicker
|
|
4
|
+
(separate package; not part of pure-admin-core's CSS).
|
|
5
|
+
|
|
6
|
+
Pure Admin's role: themes export ~45 --base-* CSS variables (see
|
|
7
|
+
_base-css-variables.scss + _web-components-theme.scss bridge).
|
|
8
|
+
The component reads them via fallback chains:
|
|
9
|
+
|
|
10
|
+
1. Page override : web-daterangepicker { --drp-accent-color: … }
|
|
11
|
+
2. Theme base value: var(--base-accent-color)
|
|
12
|
+
3. Hardcoded default: built into the component
|
|
13
|
+
|
|
14
|
+
So in a Pure Admin app you usually do NOT override --drp-* — the
|
|
15
|
+
theme already cascades. Override --drp-* only for one-off
|
|
16
|
+
instance-specific tweaks.
|
|
17
|
+
|
|
5
18
|
Package: npm install @keenmate/web-daterangepicker
|
|
6
|
-
|
|
19
|
+
Repo: https://github.com/keenmate/web-daterangepicker
|
|
20
|
+
Auto-registers as <web-daterangepicker> on import.
|
|
21
|
+
================================ -->
|
|
7
22
|
|
|
8
23
|
<!-- ========================================
|
|
9
24
|
BASIC USAGE
|
|
@@ -24,7 +39,11 @@
|
|
|
24
39
|
date-format-mask="YYYY-MM-DD">
|
|
25
40
|
</web-daterangepicker>
|
|
26
41
|
|
|
27
|
-
<!-- Multiple Dates/Ranges Selection
|
|
42
|
+
<!-- Multiple Dates/Ranges Selection
|
|
43
|
+
Note: TypeScript narrows the public selectionMode property to
|
|
44
|
+
'single' | 'range', but the underlying engine accepts 'multiple'
|
|
45
|
+
too — used in the demo (date-picker.mustache) for cherry-picking
|
|
46
|
+
several dates / ranges. -->
|
|
28
47
|
<web-daterangepicker
|
|
29
48
|
selection-mode="multiple"
|
|
30
49
|
placeholder="Select multiple dates"
|
|
@@ -181,7 +200,12 @@ pastOnly.setAttribute('max-date', yesterday.toISOString().split('T')[0]);
|
|
|
181
200
|
<script>
|
|
182
201
|
const customBadges = document.getElementById('custom-badges');
|
|
183
202
|
|
|
184
|
-
//
|
|
203
|
+
// Callback returns DateInfo or null. DateInfo shape:
|
|
204
|
+
// { isDisabled?, badgeText?, badgeClass?, badgeTooltip?,
|
|
205
|
+
// dayClass?, dayTooltip? }
|
|
206
|
+
// badgeText goes in the badge row above the day number; badgeClass /
|
|
207
|
+
// dayClass let you compose with predefined .holiday / .event classes
|
|
208
|
+
// or your own.
|
|
185
209
|
customBadges.getDateMetadataCallback = (date) => {
|
|
186
210
|
const day = date.getDate();
|
|
187
211
|
const month = date.getMonth();
|
|
@@ -189,32 +213,41 @@ customBadges.getDateMetadataCallback = (date) => {
|
|
|
189
213
|
// New Year's Day
|
|
190
214
|
if (month === 0 && day === 1) {
|
|
191
215
|
return {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
216
|
+
badgeText: '🎉',
|
|
217
|
+
badgeClass: 'holiday',
|
|
218
|
+
badgeTooltip: "New Year's Day",
|
|
219
|
+
dayTooltip: 'Public holiday'
|
|
195
220
|
};
|
|
196
221
|
}
|
|
197
222
|
|
|
198
223
|
// Valentine's Day
|
|
199
224
|
if (month === 1 && day === 14) {
|
|
200
225
|
return {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
226
|
+
badgeText: '❤️',
|
|
227
|
+
badgeClass: 'holiday',
|
|
228
|
+
badgeTooltip: "Valentine's Day"
|
|
204
229
|
};
|
|
205
230
|
}
|
|
206
231
|
|
|
207
232
|
// Team meetings on Mondays
|
|
208
233
|
if (date.getDay() === 1) {
|
|
209
234
|
return {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
235
|
+
badgeText: '📅',
|
|
236
|
+
badgeClass: 'event',
|
|
237
|
+
badgeTooltip: 'Team Meeting at 10 AM'
|
|
213
238
|
};
|
|
214
239
|
}
|
|
215
240
|
|
|
216
241
|
return null;
|
|
217
242
|
};
|
|
243
|
+
|
|
244
|
+
// Alternative: pre-built specialDates array (no callback overhead).
|
|
245
|
+
// Property names default to date / badgeText / badgeClass / badgeTooltip
|
|
246
|
+
// / dayClass / dayTooltip / isDisabled — override via *Member options.
|
|
247
|
+
customBadges.specialDates = [
|
|
248
|
+
{ date: '2025-12-25', badgeText: '🎄', badgeTooltip: 'Christmas', badgeClass: 'holiday' },
|
|
249
|
+
{ date: '2025-12-31', badgeText: '🎆', badgeTooltip: "New Year's Eve" }
|
|
250
|
+
];
|
|
218
251
|
</script>
|
|
219
252
|
|
|
220
253
|
<!-- ========================================
|
|
@@ -250,32 +283,70 @@ disabledDates.getDateMetadataCallback = (date) => {
|
|
|
250
283
|
</script>
|
|
251
284
|
|
|
252
285
|
<!-- ========================================
|
|
253
|
-
RANGE HANDLING MODES
|
|
286
|
+
RANGE HANDLING MODES (disabled-dates-handling)
|
|
287
|
+
Five modes for what happens when a selected range overlaps
|
|
288
|
+
disabled dates. Set via attribute OR property.
|
|
254
289
|
======================================== -->
|
|
255
290
|
|
|
256
|
-
<!--
|
|
291
|
+
<!-- allow (default): range spans disabled dates;
|
|
292
|
+
event detail includes enabledDates + disabledDates arrays -->
|
|
257
293
|
<web-daterangepicker
|
|
258
294
|
selection-mode="range"
|
|
259
295
|
visible-months-count="2"
|
|
260
296
|
disabled-weekdays="0,6"
|
|
261
|
-
|
|
297
|
+
disabled-dates-handling="allow"
|
|
298
|
+
placeholder="Range includes weekends (counted separately)"
|
|
262
299
|
date-format-mask="YYYY-MM-DD">
|
|
263
300
|
</web-daterangepicker>
|
|
264
301
|
|
|
265
|
-
<!--
|
|
302
|
+
<!-- block: range end snaps to last enabled date before any gap -->
|
|
266
303
|
<web-daterangepicker
|
|
267
|
-
id="block-mode"
|
|
268
304
|
selection-mode="range"
|
|
269
305
|
visible-months-count="2"
|
|
270
306
|
disabled-weekdays="0,6"
|
|
307
|
+
disabled-dates-handling="block"
|
|
271
308
|
placeholder="Range stops at weekends"
|
|
272
309
|
date-format-mask="YYYY-MM-DD">
|
|
273
310
|
</web-daterangepicker>
|
|
274
311
|
|
|
275
|
-
<!--
|
|
312
|
+
<!-- prevent: range can't be selected at all if it would cross disabled -->
|
|
313
|
+
<web-daterangepicker
|
|
314
|
+
selection-mode="range"
|
|
315
|
+
visible-months-count="2"
|
|
316
|
+
disabled-weekdays="0,6"
|
|
317
|
+
disabled-dates-handling="prevent"
|
|
318
|
+
placeholder="Selection rejected if it crosses disabled dates"
|
|
319
|
+
date-format-mask="YYYY-MM-DD">
|
|
320
|
+
</web-daterangepicker>
|
|
321
|
+
|
|
322
|
+
<!-- split: returns multiple ranges separated by disabled gaps;
|
|
323
|
+
event detail.dateRanges is DateRange[] -->
|
|
324
|
+
<web-daterangepicker
|
|
325
|
+
selection-mode="range"
|
|
326
|
+
visible-months-count="2"
|
|
327
|
+
disabled-weekdays="0,6"
|
|
328
|
+
disabled-dates-handling="split"
|
|
329
|
+
placeholder="Split into weekday-only sub-ranges"
|
|
330
|
+
date-format-mask="YYYY-MM-DD">
|
|
331
|
+
</web-daterangepicker>
|
|
332
|
+
|
|
333
|
+
<!-- individual: returns a flat array of enabled dates only;
|
|
334
|
+
event detail.dates is Date[] -->
|
|
335
|
+
<web-daterangepicker
|
|
336
|
+
selection-mode="range"
|
|
337
|
+
visible-months-count="2"
|
|
338
|
+
disabled-weekdays="0,6"
|
|
339
|
+
disabled-dates-handling="individual"
|
|
340
|
+
placeholder="Each enabled day picked individually"
|
|
341
|
+
date-format-mask="YYYY-MM-DD">
|
|
342
|
+
</web-daterangepicker>
|
|
343
|
+
|
|
344
|
+
<!-- Equivalent JS: -->
|
|
276
345
|
<script>
|
|
277
|
-
const
|
|
278
|
-
//
|
|
346
|
+
// const picker = document.querySelector('web-daterangepicker');
|
|
347
|
+
// picker.setAttribute('disabled-dates-handling', 'block');
|
|
348
|
+
// or via the underlying picker engine:
|
|
349
|
+
// picker.picker.options.disabledDatesHandling = 'block';
|
|
279
350
|
</script>
|
|
280
351
|
|
|
281
352
|
<!-- ========================================
|
|
@@ -416,30 +487,33 @@ programmatic.addEventListener('change', (e) => {
|
|
|
416
487
|
</web-daterangepicker>
|
|
417
488
|
|
|
418
489
|
<!-- ========================================
|
|
419
|
-
AUTO-CLOSE BEHAVIOR
|
|
490
|
+
AUTO-CLOSE BEHAVIOR (auto-close)
|
|
491
|
+
Three values: 'never' | 'selection' | 'apply'
|
|
420
492
|
======================================== -->
|
|
421
493
|
|
|
422
|
-
<!--
|
|
494
|
+
<!-- selection: close as soon as selection completes
|
|
495
|
+
(single date picked, or range end picked) -->
|
|
423
496
|
<web-daterangepicker
|
|
424
497
|
selection-mode="single"
|
|
425
|
-
auto-close="
|
|
498
|
+
auto-close="selection"
|
|
426
499
|
placeholder="Closes after selection"
|
|
427
500
|
date-format-mask="YYYY-MM-DD">
|
|
428
501
|
</web-daterangepicker>
|
|
429
502
|
|
|
430
|
-
<!--
|
|
503
|
+
<!-- apply: stay open until the user clicks Apply -->
|
|
431
504
|
<web-daterangepicker
|
|
432
505
|
selection-mode="range"
|
|
433
|
-
|
|
434
|
-
|
|
506
|
+
show-apply-button="true"
|
|
507
|
+
auto-close="apply"
|
|
508
|
+
placeholder="Closes only when Apply clicked"
|
|
435
509
|
date-format-mask="YYYY-MM-DD">
|
|
436
510
|
</web-daterangepicker>
|
|
437
511
|
|
|
438
|
-
<!--
|
|
512
|
+
<!-- never: never auto-close; manage open/close yourself with show()/hide() -->
|
|
439
513
|
<web-daterangepicker
|
|
440
514
|
selection-mode="range"
|
|
441
|
-
|
|
442
|
-
placeholder="
|
|
515
|
+
auto-close="never"
|
|
516
|
+
placeholder="Stays open"
|
|
443
517
|
date-format-mask="YYYY-MM-DD">
|
|
444
518
|
</web-daterangepicker>
|
|
445
519
|
|
|
@@ -448,187 +522,293 @@ programmatic.addEventListener('change', (e) => {
|
|
|
448
522
|
======================================== -->
|
|
449
523
|
|
|
450
524
|
<!--
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
-
|
|
456
|
-
-
|
|
457
|
-
|
|
458
|
-
-
|
|
459
|
-
|
|
525
|
+
Source of truth: web-component.ts observedAttributes list. The full
|
|
526
|
+
set of attributes the web component accepts:
|
|
527
|
+
|
|
528
|
+
Core:
|
|
529
|
+
- selection-mode "single" (default) | "range" | "multiple"
|
|
530
|
+
- date-format-mask Format pattern. YYYY/YY, MM/M, DD/D with
|
|
531
|
+
separators -, /, . Default: YYYY-MM-DD
|
|
532
|
+
- display-format-mask Localized format shown to user (e.g.
|
|
533
|
+
"dd/mm/aaaa" in Spanish); validation still
|
|
534
|
+
uses date-format-mask
|
|
535
|
+
- visible-months-count Number of months on screen (default:
|
|
536
|
+
1 single, 2 range)
|
|
537
|
+
- calendar-open-trigger "focus" (default) | "typing" | "manual"
|
|
538
|
+
- placeholder Input placeholder text
|
|
539
|
+
- value Current formatted value
|
|
540
|
+
- disabled Boolean attribute
|
|
541
|
+
- week-start-day "auto" (locale-based) | 0..6
|
|
542
|
+
- locale "auto" (default) | "en" | "de" | "fr" | "es" | …
|
|
543
|
+
- show-debug-info Boolean — enables loglevel debug output
|
|
544
|
+
- enable-transitions Boolean — opt-in CSS transitions
|
|
545
|
+
|
|
546
|
+
Layout (multi-month):
|
|
547
|
+
- positioning-mode "floating" (default) | "inline"
|
|
548
|
+
- calendar-placement Floating UI placement: bottom / top /
|
|
549
|
+
left / right / bottom-start / bottom-end / …
|
|
550
|
+
- month-layout "horizontal" (default) | "grid"
|
|
551
|
+
- grid-rows number (e.g. 2 for a 2×3 grid)
|
|
552
|
+
- grid-columns number (e.g. 3 for a 2×3 grid)
|
|
460
553
|
|
|
461
554
|
Date Restrictions:
|
|
462
|
-
- min-date
|
|
463
|
-
- max-date
|
|
464
|
-
- disabled-weekdays
|
|
555
|
+
- min-date YYYY-MM-DD
|
|
556
|
+
- max-date YYYY-MM-DD
|
|
557
|
+
- disabled-weekdays "0,6" etc. (0=Sun, 6=Sat)
|
|
558
|
+
- disabled-dates-handling "allow" (default) | "block" | "prevent"
|
|
559
|
+
| "split" | "individual"
|
|
560
|
+
- highlight-disabled-in-range Boolean (default true)
|
|
561
|
+
|
|
562
|
+
Action Buttons (set "true" to show):
|
|
563
|
+
- show-today-button
|
|
564
|
+
- show-clear-button
|
|
565
|
+
- show-apply-button Defaults to true for range / multiple modes
|
|
566
|
+
|
|
567
|
+
Close Behavior:
|
|
568
|
+
- auto-close "never" | "selection" | "apply"
|
|
569
|
+
- close-on-scroll Boolean
|
|
570
|
+
|
|
571
|
+
Sizing (5-step scale, all default "md"):
|
|
572
|
+
- input-size xs | sm | md | lg | xl (input field)
|
|
573
|
+
- spacing xs | sm | md | lg | xl (calendar gaps)
|
|
574
|
+
- font-size xs | sm | md | lg | xl (calendar text)
|
|
575
|
+
- cell-size xs | sm | md | lg | xl (day cell size)
|
|
576
|
+
-->
|
|
465
577
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
578
|
+
<!-- ========================================
|
|
579
|
+
WRAPPER CLASSES (page-level, on a parent <div>)
|
|
580
|
+
Lets you scale font and spacing independently of the input-size /
|
|
581
|
+
spacing / font-size attributes — handy when the picker lives
|
|
582
|
+
inside a section with its own density.
|
|
583
|
+
======================================== -->
|
|
584
|
+
|
|
585
|
+
<!-- Compact spacing with large readable text -->
|
|
586
|
+
<div class="drp-font-lg drp-spacing-xs">
|
|
587
|
+
<web-daterangepicker selection-mode="single"></web-daterangepicker>
|
|
588
|
+
</div>
|
|
589
|
+
|
|
590
|
+
<!-- Responsive: scales font + spacing down at 1200px and 768px breakpoints -->
|
|
591
|
+
<div class="drp-font-md drp-spacing-md drp-responsive">
|
|
592
|
+
<web-daterangepicker selection-mode="range"></web-daterangepicker>
|
|
593
|
+
</div>
|
|
470
594
|
|
|
471
|
-
|
|
472
|
-
|
|
595
|
+
<!--
|
|
596
|
+
Wrapper class scales (multipliers — defaults are 1.0×):
|
|
597
|
+
.drp-font-xs .drp-font-sm .drp-font-md .drp-font-lg .drp-font-xl
|
|
598
|
+
.drp-spacing-xs .drp-spacing-sm .drp-spacing-md .drp-spacing-lg .drp-spacing-xl
|
|
599
|
+
.drp-responsive — flips to a smaller scale below 1200px and again below 768px
|
|
473
600
|
-->
|
|
474
601
|
|
|
602
|
+
|
|
475
603
|
<!-- ========================================
|
|
476
|
-
CSS
|
|
604
|
+
CSS CUSTOM PROPERTIES (--drp-*)
|
|
605
|
+
The component defines these on :host inside its shadow DOM, so
|
|
606
|
+
override them by targeting the element (NOT :root — :root inside
|
|
607
|
+
shadow DOM doesn't reach the component).
|
|
477
608
|
======================================== -->
|
|
478
609
|
|
|
479
610
|
<style>
|
|
480
|
-
/* Override
|
|
481
|
-
|
|
482
|
-
/*
|
|
483
|
-
--drp-
|
|
484
|
-
--drp-primary
|
|
485
|
-
--drp-text-
|
|
486
|
-
--drp-
|
|
487
|
-
--drp-border-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
--drp-
|
|
493
|
-
--drp-
|
|
494
|
-
--drp-
|
|
495
|
-
--drp-calendar-padding: 1rem;
|
|
496
|
-
|
|
497
|
-
/* Days */
|
|
498
|
-
--drp-day-size: 2.25rem;
|
|
499
|
-
--drp-day-font-size: 0.875rem;
|
|
500
|
-
--drp-day-border-radius: 2px;
|
|
501
|
-
--drp-day-hover-bg: rgba(0, 123, 255, 0.1);
|
|
502
|
-
--drp-day-selected-bg: #007bff;
|
|
503
|
-
--drp-day-selected-text: #ffffff;
|
|
504
|
-
--drp-day-range-bg: rgba(0, 123, 255, 0.05);
|
|
505
|
-
--drp-day-today-border: #007bff;
|
|
506
|
-
--drp-day-disabled-opacity: 0.65;
|
|
507
|
-
|
|
508
|
-
/* Weekday Header */
|
|
509
|
-
--drp-weekday-font-size: 0.75rem;
|
|
510
|
-
--drp-weekday-font-weight: 600;
|
|
511
|
-
--drp-weekday-text: #6c757d;
|
|
512
|
-
|
|
513
|
-
/* Badges */
|
|
514
|
-
--drp-badge-primary: #007bff;
|
|
515
|
-
--drp-badge-success: #28a745;
|
|
516
|
-
--drp-badge-warning: #ffc107;
|
|
517
|
-
--drp-badge-danger: #dc3545;
|
|
518
|
-
--drp-badge-info: #17a2b8;
|
|
519
|
-
|
|
520
|
-
/* Input */
|
|
521
|
-
--drp-input-bg: #ffffff;
|
|
522
|
-
--drp-input-border: #ced4da;
|
|
523
|
-
--drp-input-padding-v: 0.5rem;
|
|
524
|
-
--drp-input-padding-h: 0.75rem;
|
|
525
|
-
--drp-input-font-size: 0.875rem;
|
|
526
|
-
--drp-input-border-radius: 4px;
|
|
527
|
-
--drp-input-focus-border: #007bff;
|
|
528
|
-
|
|
529
|
-
/* Action Buttons */
|
|
530
|
-
--drp-action-btn-primary-bg: #007bff;
|
|
531
|
-
--drp-action-btn-primary-text: #ffffff;
|
|
532
|
-
|
|
533
|
-
/* Spacing */
|
|
534
|
-
--drp-spacing-sm: 0.5rem;
|
|
535
|
-
--drp-spacing-md: 0.75rem;
|
|
536
|
-
--drp-spacing-base: 1rem;
|
|
537
|
-
|
|
538
|
-
/* Animations */
|
|
539
|
-
--drp-transition-normal: 0.15s;
|
|
540
|
-
--drp-easing-smooth: ease;
|
|
611
|
+
/* Override on the element so the variables cascade into the shadow root */
|
|
612
|
+
web-daterangepicker {
|
|
613
|
+
--drp-accent-color: var(--pa-accent); /* hook into Pure Admin theme */
|
|
614
|
+
--drp-card-bg: var(--pa-card-bg);
|
|
615
|
+
--drp-text-primary: var(--pa-text-color-1);
|
|
616
|
+
--drp-text-secondary: var(--pa-text-color-2);
|
|
617
|
+
--drp-border-color: var(--pa-border-color);
|
|
618
|
+
--drp-border-radius: var(--pa-border-radius);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/* Scoped instance override (e.g. a "compact" variant on a search bar) */
|
|
622
|
+
web-daterangepicker.compact {
|
|
623
|
+
--drp-card-bg: #1e293b;
|
|
624
|
+
--drp-text-primary: #f1f5f9;
|
|
625
|
+
--drp-accent-color: #10b981;
|
|
541
626
|
}
|
|
542
627
|
</style>
|
|
543
628
|
|
|
629
|
+
<!--
|
|
630
|
+
Common --drp-* tokens (full list in API.md):
|
|
631
|
+
|
|
632
|
+
Colors --drp-card-bg, --drp-border-color, --drp-primary-bg,
|
|
633
|
+
--drp-primary-bg-hover, --drp-accent-color,
|
|
634
|
+
--drp-accent-color-hover, --drp-text-primary,
|
|
635
|
+
--drp-text-secondary, --drp-accent-text-color,
|
|
636
|
+
--drp-button-text-color
|
|
637
|
+
Spacing --drp-spacing-xs / -sm / -md / -lg / -xl
|
|
638
|
+
Typography --drp-font-size-{2xs..2xl}, --drp-font-weight-{medium,semibold}
|
|
639
|
+
Borders --drp-border-width-base, --drp-border-radius, --drp-shadow-xl
|
|
640
|
+
Transitions --drp-transition-fast, --drp-easing-snappy
|
|
641
|
+
Input sizes --drp-input-size-{xs|sm|md|lg|xl}-{font|padding-v|padding-h|height|icon-size}
|
|
642
|
+
Grid --drp-grid-rows, --drp-grid-columns (set automatically)
|
|
643
|
+
|
|
644
|
+
PURE ADMIN INTEGRATION:
|
|
645
|
+
packages/core/src/scss/core-components/_web-components-theme.scss
|
|
646
|
+
bridges Pure Admin's --base-* variables (set by themes) into the
|
|
647
|
+
daterangepicker's fallback chain. So in a Pure Admin app you usually
|
|
648
|
+
do NOT hand-set --drp-* — the theme already cascades. Override
|
|
649
|
+
--drp-* only for one-off tweaks like the .compact example above.
|
|
650
|
+
-->
|
|
651
|
+
|
|
544
652
|
<!-- ========================================
|
|
545
653
|
TYPESCRIPT TYPES
|
|
546
654
|
======================================== -->
|
|
547
655
|
|
|
548
656
|
<!--
|
|
549
|
-
TypeScript usage:
|
|
550
|
-
|
|
551
657
|
import '@keenmate/web-daterangepicker';
|
|
552
|
-
import type {
|
|
553
|
-
|
|
554
|
-
const picker = document.querySelector<DateRangePickerElement>('web-daterangepicker');
|
|
555
|
-
|
|
556
|
-
if (picker) {
|
|
557
|
-
// Type-safe API
|
|
558
|
-
picker.addEventListener('date-select', (e: CustomEvent<{
|
|
559
|
-
date?: string;
|
|
560
|
-
dateRange?: { start: string; end: string };
|
|
561
|
-
}>) => {
|
|
562
|
-
console.log(e.detail);
|
|
563
|
-
});
|
|
564
|
-
|
|
565
|
-
// Validation callback
|
|
566
|
-
picker.beforeDateSelectCallback = async (selection) => {
|
|
567
|
-
return true; // or false to reject
|
|
568
|
-
};
|
|
569
|
-
|
|
570
|
-
// Custom rendering
|
|
571
|
-
picker.getDateMetadataCallback = (date: Date) => {
|
|
572
|
-
return {
|
|
573
|
-
badge: 'primary',
|
|
574
|
-
tooltip: 'Event',
|
|
575
|
-
isDisabled: false
|
|
576
|
-
};
|
|
577
|
-
};
|
|
578
|
-
}
|
|
579
|
-
-->
|
|
658
|
+
import type { DatePickerOptions, DateRange, DecoratedDate, DateInfo }
|
|
659
|
+
from '@keenmate/web-daterangepicker';
|
|
580
660
|
|
|
581
|
-
|
|
582
|
-
KEY FEATURES
|
|
583
|
-
======================================== -->
|
|
661
|
+
const picker = document.querySelector('web-daterangepicker');
|
|
584
662
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
✅ Custom Rendering: Badges, tooltips, and custom content for dates
|
|
591
|
-
✅ Validation: Async beforeDateSelectCallback for validation
|
|
592
|
-
✅ Action Buttons: Today, Clear, Apply buttons with customization
|
|
593
|
-
✅ Range Handling: 5 modes (allow, block, split, individual, prevent) for disabled dates
|
|
594
|
-
✅ Input Masking: Auto-format dates as user types
|
|
595
|
-
✅ Localization: Support for multiple languages and date formats
|
|
596
|
-
✅ Inline Mode: Display calendar directly on page instead of dropdown
|
|
597
|
-
✅ Framework Agnostic: Works with any framework or vanilla JS
|
|
598
|
-
✅ TypeScript: Full type definitions included
|
|
599
|
-
✅ Accessible: Keyboard-friendly with proper focus management
|
|
600
|
-
✅ Customizable: 40+ CSS variables for theming
|
|
601
|
-
✅ Dependencies: Only @floating-ui/dom for smart positioning
|
|
602
|
-
-->
|
|
663
|
+
picker.addEventListener('date-select', (e) => {
|
|
664
|
+
// detail is a discriminated union by mode + disabled-dates-handling.
|
|
665
|
+
// See COMPONENT REFERENCE → EVENTS below for the full shape.
|
|
666
|
+
console.log(e.detail);
|
|
667
|
+
});
|
|
603
668
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
669
|
+
picker.beforeDateSelectCallback = async (selection) => {
|
|
670
|
+
return true; // false to reject
|
|
671
|
+
};
|
|
607
672
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
- Home/End: First/last day of month
|
|
615
|
-
- Ctrl+Home/End: First/last day of year
|
|
616
|
-
- Tab: Switch between month columns (multi-month view)
|
|
617
|
-
- T: Jump to today
|
|
618
|
-
|
|
619
|
-
Actions:
|
|
620
|
-
- Enter: Select focused day
|
|
621
|
-
- Esc: Close calendar
|
|
622
|
-
- Space: Toggle selection (in multiple mode)
|
|
673
|
+
picker.getDateMetadataCallback = (date) => ({
|
|
674
|
+
badgeText: 'E',
|
|
675
|
+
badgeClass: 'event',
|
|
676
|
+
badgeTooltip: 'Event',
|
|
677
|
+
isDisabled: false
|
|
678
|
+
});
|
|
623
679
|
-->
|
|
624
680
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
681
|
+
|
|
682
|
+
<!-- ================================
|
|
683
|
+
COMPONENT REFERENCE
|
|
684
|
+
================================ -->
|
|
628
685
|
|
|
629
686
|
<!--
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
687
|
+
SELECTION MODES:
|
|
688
|
+
single One date.
|
|
689
|
+
range Two dates with a fill in between.
|
|
690
|
+
multiple Cherry-pick individual dates / mini-ranges (TS narrows
|
|
691
|
+
public type to 'single' | 'range', but the engine
|
|
692
|
+
handles 'multiple' too — used in date-picker demo).
|
|
693
|
+
|
|
694
|
+
DATE METADATA — TWO PATHS:
|
|
695
|
+
1. specialDates property (preferred for static data)
|
|
696
|
+
picker.specialDates = [
|
|
697
|
+
{ date: '2025-12-25', badgeText: '🎄', badgeTooltip: 'Christmas' },
|
|
698
|
+
…
|
|
699
|
+
];
|
|
700
|
+
Property names default to date / badgeText / badgeClass /
|
|
701
|
+
badgeTooltip / dayClass / dayTooltip / isDisabled — re-map via
|
|
702
|
+
dateMember / badgeTextMember / etc. when consuming an existing
|
|
703
|
+
dataset shape.
|
|
704
|
+
|
|
705
|
+
2. getDateMetadataCallback (computed per render)
|
|
706
|
+
picker.getDateMetadataCallback = (date) => DateInfo | null;
|
|
707
|
+
DateInfo = { isDisabled?, badgeText?, badgeClass?, badgeTooltip?,
|
|
708
|
+
dayClass?, dayTooltip? }
|
|
709
|
+
Predefined classes you can hand to badgeClass / dayClass:
|
|
710
|
+
.holiday (red tint) and .event (green tint). Plus any custom class.
|
|
711
|
+
|
|
712
|
+
VALIDATION HOOK:
|
|
713
|
+
picker.beforeDateSelectCallback = async (selection) => boolean
|
|
714
|
+
Async-supported. Return false to reject; the calendar reverts.
|
|
715
|
+
|
|
716
|
+
EVENTS (both bubble, both composed — use either):
|
|
717
|
+
date-select Always fires on selection change.
|
|
718
|
+
change Alias of date-select.
|
|
719
|
+
|
|
720
|
+
event.detail shape varies by mode:
|
|
721
|
+
formattedValue always present
|
|
722
|
+
date single mode
|
|
723
|
+
dateRange { start, end } range mode (allow / block)
|
|
724
|
+
dateRanges DateRange[] range mode + split
|
|
725
|
+
dates Date[] range mode + split / individual
|
|
726
|
+
enabledDates / disabledDates range mode + allow
|
|
727
|
+
getEnabledDateCount() / getTotalDays() range + allow helpers
|
|
728
|
+
|
|
729
|
+
PUBLIC METHODS (on <web-daterangepicker> element):
|
|
730
|
+
show() / hide() / toggle() floating mode visibility
|
|
731
|
+
clearSelection() wipe all selections + input
|
|
732
|
+
getInputValue() current formatted string
|
|
733
|
+
setInputValue(v) set value + sync calendar
|
|
734
|
+
picker the underlying PureDatePicker
|
|
735
|
+
instance (deeper API: formatDate,
|
|
736
|
+
isDateDisabledInternal,
|
|
737
|
+
getEnabledDatesInRange, etc.)
|
|
738
|
+
|
|
739
|
+
SIZING:
|
|
740
|
+
Two coordinated paths:
|
|
741
|
+
a) Attributes (single instance):
|
|
742
|
+
input-size, spacing, font-size, cell-size — each xs..xl, default md.
|
|
743
|
+
b) Wrapper classes (parent <div>):
|
|
744
|
+
.drp-font-{xs..xl}, .drp-spacing-{xs..xl}, .drp-responsive
|
|
745
|
+
|
|
746
|
+
KEYBOARD:
|
|
747
|
+
Arrow keys navigate by day; up/down moves by week
|
|
748
|
+
Ctrl/Cmd + ←/→ or PgUp/PgDn prev / next month (keep day position)
|
|
749
|
+
Home / End first / last day of month (press again
|
|
750
|
+
for adjacent month)
|
|
751
|
+
Ctrl/Cmd + Home / End Jan 1 / Dec 31 of current year
|
|
752
|
+
Tab / Shift+Tab switch month column in multi-month view
|
|
753
|
+
Enter select focused day
|
|
754
|
+
Space toggle (multiple mode)
|
|
755
|
+
T / t jump to today
|
|
756
|
+
Esc close (floating mode)
|
|
757
|
+
|
|
758
|
+
CSS VARIABLE NAMESPACES:
|
|
759
|
+
--drp-* Component runtime tokens. Set on the element (not
|
|
760
|
+
:root — :root inside shadow DOM doesn't reach the
|
|
761
|
+
component).
|
|
762
|
+
--base-* Pure Admin theme bridge. Themes export ~45 of these
|
|
763
|
+
via output-base-css-variables; the component falls
|
|
764
|
+
back from --drp-* → var(--base-*, hardcoded). So
|
|
765
|
+
themes "just work"; only override --drp-* for one-off
|
|
766
|
+
instances.
|
|
767
|
+
|
|
768
|
+
LOAD ORDER:
|
|
769
|
+
Import the component once (auto-registers the custom element):
|
|
770
|
+
import '@keenmate/web-daterangepicker';
|
|
771
|
+
import '@keenmate/web-daterangepicker/style.css';
|
|
772
|
+
Pure Admin's CSS provides the --base-* values; the component picks
|
|
773
|
+
them up automatically.
|
|
774
|
+
|
|
775
|
+
STRUCTURE PATTERNS:
|
|
776
|
+
|
|
777
|
+
Basic single-date input:
|
|
778
|
+
<web-daterangepicker selection-mode="single"
|
|
779
|
+
date-format-mask="DD.MM.YYYY"
|
|
780
|
+
placeholder="Select date">
|
|
781
|
+
</web-daterangepicker>
|
|
782
|
+
|
|
783
|
+
Range with weekend block + apply button + auto-close on apply:
|
|
784
|
+
<web-daterangepicker selection-mode="range"
|
|
785
|
+
visible-months-count="2"
|
|
786
|
+
disabled-weekdays="0,6"
|
|
787
|
+
disabled-dates-handling="block"
|
|
788
|
+
show-apply-button="true"
|
|
789
|
+
auto-close="apply">
|
|
790
|
+
</web-daterangepicker>
|
|
791
|
+
|
|
792
|
+
6-month inline grid for big picture views:
|
|
793
|
+
<web-daterangepicker selection-mode="single"
|
|
794
|
+
positioning-mode="inline"
|
|
795
|
+
visible-months-count="6"
|
|
796
|
+
month-layout="grid"
|
|
797
|
+
grid-rows="2" grid-columns="3">
|
|
798
|
+
</web-daterangepicker>
|
|
799
|
+
|
|
800
|
+
Localized display (validates ISO, displays Spanish):
|
|
801
|
+
<web-daterangepicker selection-mode="single"
|
|
802
|
+
locale="es"
|
|
803
|
+
date-format-mask="YYYY-MM-DD"
|
|
804
|
+
display-format-mask="dd/mm/aaaa">
|
|
805
|
+
</web-daterangepicker>
|
|
806
|
+
|
|
807
|
+
RESOURCES:
|
|
808
|
+
npm @keenmate/web-daterangepicker
|
|
809
|
+
Repository https://github.com/keenmate/web-daterangepicker
|
|
810
|
+
API docs ../../web-daterangepicker/API.md
|
|
811
|
+
AI guides ../../web-daterangepicker/ai/
|
|
812
|
+
Pure Admin src/scss/core-components/_web-components-theme.scss
|
|
813
|
+
bridges --base-* into the component's fallback chain.
|
|
634
814
|
-->
|