@internetarchive/histogram-date-range 0.1.11 → 0.1.12-alpha.2

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 CHANGED
@@ -41,6 +41,15 @@ npm i @internetarchive/histogram-date-range
41
41
  ></histogram-date-range>
42
42
  ```
43
43
 
44
+ A slot named `inputs-right-side` is available for inserting elements to the right
45
+ of the min/max date input fields, e.g.:
46
+
47
+ ```html
48
+ <histogram-date-range>
49
+ <button slot="inputs-right-side">Apply</button>
50
+ </histogram-date-range>
51
+ ```
52
+
44
53
  ## Linting with ESLint, Prettier, and Types
45
54
 
46
55
  To scan the project for linting errors, run
@@ -30,6 +30,7 @@ const selectedRangeColor = css `var(--histogramDateRangeSelectedRangeColor, #DBE
30
30
  const barIncludedFill = css `var(--histogramDateRangeBarIncludedFill, #2C2C2C)`;
31
31
  const activityIndicatorColor = css `var(--histogramDateRangeActivityIndicator, #2C2C2C)`;
32
32
  const barExcludedFill = css `var(--histogramDateRangeBarExcludedFill, #CCCCCC)`;
33
+ const inputRowMargin = css `var(--histogramDateRangeInputRowMargin, 0)`;
33
34
  const inputBorder = css `var(--histogramDateRangeInputBorder, 0.5px solid #2C2C2C)`;
34
35
  const inputWidth = css `var(--histogramDateRangeInputWidth, 35px)`;
35
36
  const inputFontSize = css `var(--histogramDateRangeInputFontSize, 1.2rem)`;
@@ -257,9 +258,9 @@ let HistogramDateRange = class HistogramDateRange extends LitElement {
257
258
  const formattedNumItems = Number(dataset.numItems).toLocaleString();
258
259
  this._tooltipOffset =
259
260
  x + (this._binWidth - this.sliderWidth - this.tooltipWidth) / 2;
260
- this._tooltipContent = html `
261
- ${formattedNumItems} ${itemsText}<br />
262
- ${dataset.binStart} - ${dataset.binEnd}
261
+ this._tooltipContent = html `
262
+ ${formattedNumItems} ${itemsText}<br />
263
+ ${dataset.binStart} - ${dataset.binEnd}
263
264
  `;
264
265
  this._tooltipVisible = true;
265
266
  }
@@ -449,25 +450,25 @@ let HistogramDateRange = class HistogramDateRange extends LitElement {
449
450
  // border-radius); used as part of a SVG quadratic curve. see
450
451
  // https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#curve_commands
451
452
  const cs = SLIDER_CORNER_SIZE;
452
- const sliderShape = `
453
- M${this.minSliderX},0
454
- h-${this.sliderWidth - cs}
455
- q-${cs},0 -${cs},${cs}
456
- v${this.height - cs * 2}
457
- q0,${cs} ${cs},${cs}
458
- h${this.sliderWidth - cs}
453
+ const sliderShape = `
454
+ M${this.minSliderX},0
455
+ h-${this.sliderWidth - cs}
456
+ q-${cs},0 -${cs},${cs}
457
+ v${this.height - cs * 2}
458
+ q0,${cs} ${cs},${cs}
459
+ h${this.sliderWidth - cs}
459
460
  `;
460
461
  return this.generateSliderSVG(this.minSliderX, 'slider-min', sliderShape);
461
462
  }
462
463
  get maxSliderTemplate() {
463
464
  const cs = SLIDER_CORNER_SIZE;
464
- const sliderShape = `
465
- M${this.maxSliderX},0
466
- h${this.sliderWidth - cs}
467
- q${cs},0 ${cs},${cs}
468
- v${this.height - cs * 2}
469
- q0,${cs} -${cs},${cs}
470
- h-${this.sliderWidth - cs}
465
+ const sliderShape = `
466
+ M${this.maxSliderX},0
467
+ h${this.sliderWidth - cs}
468
+ q${cs},0 ${cs},${cs}
469
+ v${this.height - cs * 2}
470
+ q0,${cs} -${cs},${cs}
471
+ h-${this.sliderWidth - cs}
471
472
  `;
472
473
  return this.generateSliderSVG(this.maxSliderX, 'slider-max', sliderShape);
473
474
  }
@@ -475,40 +476,40 @@ let HistogramDateRange = class HistogramDateRange extends LitElement {
475
476
  // whether the curved part of the slider is facing towards the left (1), ie
476
477
  // minimum, or facing towards the right (-1), ie maximum
477
478
  const k = id === 'slider-min' ? 1 : -1;
478
- return svg `
479
- <svg
480
- id="${id}"
481
- class="
482
- ${this.disabled ? '' : 'draggable'}
483
- ${this._isDragging ? 'dragging' : ''}"
484
- @pointerdown="${this.drag}"
485
- >
486
- <path d="${sliderShape} z" fill="${sliderColor}" />
487
- <rect
488
- x="${sliderPositionX - this.sliderWidth * k + this.sliderWidth * 0.4 * k}"
489
- y="${this.height / 3}"
490
- width="1"
491
- height="${this.height / 3}"
492
- fill="white"
493
- />
494
- <rect
495
- x="${sliderPositionX - this.sliderWidth * k + this.sliderWidth * 0.6 * k}"
496
- y="${this.height / 3}"
497
- width="1"
498
- height="${this.height / 3}"
499
- fill="white"
500
- />
501
- </svg>
479
+ return svg `
480
+ <svg
481
+ id="${id}"
482
+ class="
483
+ ${this.disabled ? '' : 'draggable'}
484
+ ${this._isDragging ? 'dragging' : ''}"
485
+ @pointerdown="${this.drag}"
486
+ >
487
+ <path d="${sliderShape} z" fill="${sliderColor}" />
488
+ <rect
489
+ x="${sliderPositionX - this.sliderWidth * k + this.sliderWidth * 0.4 * k}"
490
+ y="${this.height / 3}"
491
+ width="1"
492
+ height="${this.height / 3}"
493
+ fill="white"
494
+ />
495
+ <rect
496
+ x="${sliderPositionX - this.sliderWidth * k + this.sliderWidth * 0.6 * k}"
497
+ y="${this.height / 3}"
498
+ width="1"
499
+ height="${this.height / 3}"
500
+ fill="white"
501
+ />
502
+ </svg>
502
503
  `;
503
504
  }
504
505
  get selectedRangeTemplate() {
505
- return svg `
506
- <rect
507
- x="${this.minSliderX}"
508
- y="0"
509
- width="${this.maxSliderX - this.minSliderX}"
510
- height="${this.height}"
511
- fill="${selectedRangeColor}"
506
+ return svg `
507
+ <rect
508
+ x="${this.minSliderX}"
509
+ y="0"
510
+ width="${this.maxSliderX - this.minSliderX}"
511
+ height="${this.height}"
512
+ fill="${selectedRangeColor}"
512
513
  />`;
513
514
  }
514
515
  get histogramTemplate() {
@@ -520,23 +521,23 @@ let HistogramDateRange = class HistogramDateRange extends LitElement {
520
521
  // between adjacent bars (eg when viewing the tooltips or when trying to
521
522
  // extend the range by clicking on a bar)
522
523
  return this._histData.map(data => {
523
- const bar = svg `
524
- <rect
525
- class="bar"
526
- style='stroke-dasharray: 0 ${barWidth} ${data.height} ${barWidth} 0 ${data.height};'
527
- x="${x}"
528
- y="${this.height - data.height}"
529
- width="${barWidth}"
530
- height="${data.height}"
531
- @pointerenter="${this.showTooltip}"
532
- @pointerleave="${this.hideTooltip}"
533
- @click="${this.handleBarClick}"
524
+ const bar = svg `
525
+ <rect
526
+ class="bar"
527
+ style='stroke-dasharray: 0 ${barWidth} ${data.height} ${barWidth} 0 ${data.height};'
528
+ x="${x}"
529
+ y="${this.height - data.height}"
530
+ width="${barWidth}"
531
+ height="${data.height}"
532
+ @pointerenter="${this.showTooltip}"
533
+ @pointerleave="${this.hideTooltip}"
534
+ @click="${this.handleBarClick}"
534
535
  fill="${x + barWidth >= this.minSliderX && x <= this.maxSliderX
535
536
  ? barIncludedFill
536
- : barExcludedFill}"
537
- data-num-items="${data.value}"
538
- data-bin-start="${data.binStart}"
539
- data-bin-end="${data.binEnd}"
537
+ : barExcludedFill}"
538
+ data-num-items="${data.value}"
539
+ data-bin-start="${data.binStart}"
540
+ data-bin-end="${data.binEnd}"
540
541
  />`;
541
542
  x += xScale;
542
543
  return bar;
@@ -561,31 +562,31 @@ let HistogramDateRange = class HistogramDateRange extends LitElement {
561
562
  * https://lit.dev/docs/templates/directives/#live
562
563
  */
563
564
  get minInputTemplate() {
564
- return html `
565
- <input
566
- id="date-min"
567
- placeholder="${this.dateFormat}"
568
- type="text"
569
- @focus="${this.cancelPendingUpdateEvent}"
570
- @blur="${this.handleMinDateInput}"
571
- @keyup="${this.handleKeyUp}"
572
- .value="${live(this.minSelectedDate)}"
573
- ?disabled="${this.disabled}"
574
- />
565
+ return html `
566
+ <input
567
+ id="date-min"
568
+ placeholder="${this.dateFormat}"
569
+ type="text"
570
+ @focus="${this.cancelPendingUpdateEvent}"
571
+ @blur="${this.handleMinDateInput}"
572
+ @keyup="${this.handleKeyUp}"
573
+ .value="${live(this.minSelectedDate)}"
574
+ ?disabled="${this.disabled}"
575
+ />
575
576
  `;
576
577
  }
577
578
  get maxInputTemplate() {
578
- return html `
579
- <input
580
- id="date-max"
581
- placeholder="${this.dateFormat}"
582
- type="text"
583
- @focus="${this.cancelPendingUpdateEvent}"
584
- @blur="${this.handleMaxDateInput}"
585
- @keyup="${this.handleKeyUp}"
586
- .value="${live(this.maxSelectedDate)}"
587
- ?disabled="${this.disabled}"
588
- />
579
+ return html `
580
+ <input
581
+ id="date-max"
582
+ placeholder="${this.dateFormat}"
583
+ type="text"
584
+ @focus="${this.cancelPendingUpdateEvent}"
585
+ @blur="${this.handleMaxDateInput}"
586
+ @keyup="${this.handleKeyUp}"
587
+ .value="${live(this.maxSelectedDate)}"
588
+ ?disabled="${this.disabled}"
589
+ />
589
590
  `;
590
591
  }
591
592
  get minLabelTemplate() {
@@ -595,181 +596,184 @@ let HistogramDateRange = class HistogramDateRange extends LitElement {
595
596
  return html `<label for="date-max" class="sr-only">Maximum date:</label>`;
596
597
  }
597
598
  get tooltipTemplate() {
598
- return html `
599
- <style>
600
- #tooltip {
601
- width: ${this.tooltipWidth}px;
602
- height: ${this.tooltipHeight}px;
603
- top: ${-9 - this.tooltipHeight}px;
604
- left: ${this._tooltipOffset}px;
605
- display: ${this._tooltipVisible ? 'block' : 'none'};
606
- }
607
- #tooltip:after {
608
- left: ${this.tooltipWidth / 2}px;
609
- }
610
- </style>
611
- <div id="tooltip">${this._tooltipContent}</div>
599
+ return html `
600
+ <style>
601
+ #tooltip {
602
+ width: ${this.tooltipWidth}px;
603
+ height: ${this.tooltipHeight}px;
604
+ top: ${-9 - this.tooltipHeight}px;
605
+ left: ${this._tooltipOffset}px;
606
+ display: ${this._tooltipVisible ? 'block' : 'none'};
607
+ }
608
+ #tooltip:after {
609
+ left: ${this.tooltipWidth / 2}px;
610
+ }
611
+ </style>
612
+ <div id="tooltip">${this._tooltipContent}</div>
612
613
  `;
613
614
  }
614
615
  get noDataTemplate() {
615
- return html `
616
- <div class="missing-data-message">${this.missingDataMessage}</div>
616
+ return html `
617
+ <div class="missing-data-message">${this.missingDataMessage}</div>
617
618
  `;
618
619
  }
619
620
  get activityIndicatorTemplate() {
620
621
  if (!this.loading) {
621
622
  return nothing;
622
623
  }
623
- return html `
624
- <ia-activity-indicator mode="processing"> </ia-activity-indicator>
624
+ return html `
625
+ <ia-activity-indicator mode="processing"> </ia-activity-indicator>
625
626
  `;
626
627
  }
627
628
  render() {
628
629
  if (!this.hasBinData) {
629
630
  return this.noDataTemplate;
630
631
  }
631
- return html `
632
- <div
633
- id="container"
634
- class="
635
- noselect
636
- ${this._isDragging ? 'dragging' : ''}
637
- "
638
- style="width: ${this.width}px"
639
- >
640
- ${this.activityIndicatorTemplate} ${this.tooltipTemplate}
641
- <div
642
- class="inner-container
643
- ${this.disabled ? 'disabled' : ''}"
644
- >
645
- <svg
646
- width="${this.width}"
647
- height="${this.height}"
648
- @pointerleave="${this.drop}"
649
- >
650
- ${this.selectedRangeTemplate}
651
- <svg id="histogram">${this.histogramTemplate}</svg>
652
- ${this.minSliderTemplate} ${this.maxSliderTemplate}
653
- </svg>
654
- <div id="inputs">
655
- ${this.minLabelTemplate} ${this.minInputTemplate}
656
- <div class="dash">-</div>
657
- ${this.maxLabelTemplate} ${this.maxInputTemplate}
658
- </div>
659
- </div>
660
- </div>
632
+ return html `
633
+ <div
634
+ id="container"
635
+ class="
636
+ noselect
637
+ ${this._isDragging ? 'dragging' : ''}
638
+ "
639
+ style="width: ${this.width}px"
640
+ >
641
+ ${this.activityIndicatorTemplate} ${this.tooltipTemplate}
642
+ <div
643
+ class="inner-container
644
+ ${this.disabled ? 'disabled' : ''}"
645
+ >
646
+ <svg
647
+ width="${this.width}"
648
+ height="${this.height}"
649
+ @pointerleave="${this.drop}"
650
+ >
651
+ ${this.selectedRangeTemplate}
652
+ <svg id="histogram">${this.histogramTemplate}</svg>
653
+ ${this.minSliderTemplate} ${this.maxSliderTemplate}
654
+ </svg>
655
+ <div id="inputs">
656
+ ${this.minLabelTemplate} ${this.minInputTemplate}
657
+ <div class="dash">-</div>
658
+ ${this.maxLabelTemplate} ${this.maxInputTemplate}
659
+ <slot name="inputs-right-side"></slot>
660
+ </div>
661
+ </div>
662
+ </div>
661
663
  `;
662
664
  }
663
665
  };
664
- HistogramDateRange.styles = css `
665
- .missing-data-message {
666
- text-align: center;
667
- }
668
- #container {
669
- margin: 0;
670
- touch-action: none;
671
- position: relative;
672
- }
673
- .disabled {
674
- opacity: 0.3;
675
- }
676
- ia-activity-indicator {
677
- position: absolute;
678
- left: calc(50% - 10px);
679
- top: 10px;
680
- width: 20px;
681
- height: 20px;
682
- --activityIndicatorLoadingDotColor: rgba(0, 0, 0, 0);
683
- --activityIndicatorLoadingRingColor: ${activityIndicatorColor};
684
- }
685
-
686
- /* prevent selection from interfering with tooltip, especially on mobile */
687
- /* https://stackoverflow.com/a/4407335/1163042 */
688
- .noselect {
689
- -webkit-touch-callout: none; /* iOS Safari */
690
- -webkit-user-select: none; /* Safari */
691
- -moz-user-select: none; /* Old versions of Firefox */
692
- -ms-user-select: none; /* Internet Explorer/Edge */
693
- user-select: none; /* current Chrome, Edge, Opera and Firefox */
694
- }
695
- .bar {
696
- /* create a transparent border around the hist bars to prevent "gaps" and
697
- flickering when moving around between bars. this also helps with handling
698
- clicks on the bars, preventing users from being able to click in between
699
- bars */
700
- stroke: rgba(0, 0, 0, 0);
701
- /* ensure transparent stroke wide enough to cover gap between bars */
702
- stroke-width: 2px;
703
- }
704
- .bar:hover {
705
- /* highlight currently hovered bar */
706
- fill-opacity: 0.7;
707
- }
708
- .disabled .bar:hover {
709
- /* ensure no visual hover interaction when disabled */
710
- fill-opacity: 1;
711
- }
712
- /****** histogram ********/
713
- #tooltip {
714
- position: absolute;
715
- background: ${tooltipBackgroundColor};
716
- color: ${tooltipTextColor};
717
- text-align: center;
718
- border-radius: 3px;
719
- padding: 2px;
720
- font-size: ${tooltipFontSize};
721
- font-family: ${tooltipFontFamily};
722
- touch-action: none;
723
- pointer-events: none;
724
- }
725
- #tooltip:after {
726
- content: '';
727
- position: absolute;
728
- margin-left: -5px;
729
- top: 100%;
730
- /* arrow */
731
- border: 5px solid ${tooltipTextColor};
732
- border-color: ${tooltipBackgroundColor} transparent transparent
733
- transparent;
734
- }
735
- /****** slider ********/
736
- .draggable:hover {
737
- cursor: grab;
738
- }
739
- .dragging {
740
- cursor: grabbing !important;
741
- }
742
- /****** inputs ********/
743
- #inputs {
744
- display: flex;
745
- justify-content: center;
746
- }
747
- #inputs .dash {
748
- position: relative;
749
- bottom: -1px;
750
- }
751
- input {
752
- width: ${inputWidth};
753
- margin: 0 3px;
754
- border: ${inputBorder};
755
- border-radius: 2px !important;
756
- text-align: center;
757
- font-size: ${inputFontSize};
758
- font-family: ${inputFontFamily};
759
- }
760
- .sr-only {
761
- position: absolute !important;
762
- width: 1px !important;
763
- height: 1px !important;
764
- margin: 0 !important;
765
- padding: 0 !important;
766
- border: 0 !important;
767
- overflow: hidden !important;
768
- white-space: nowrap !important;
769
- clip: rect(1px, 1px, 1px, 1px) !important;
770
- -webkit-clip-path: inset(50%) !important;
771
- clip-path: inset(50%) !important;
772
- }
666
+ HistogramDateRange.styles = css `
667
+ .missing-data-message {
668
+ text-align: center;
669
+ }
670
+ #container {
671
+ margin: 0;
672
+ touch-action: none;
673
+ position: relative;
674
+ }
675
+ .disabled {
676
+ opacity: 0.3;
677
+ }
678
+ ia-activity-indicator {
679
+ position: absolute;
680
+ left: calc(50% - 10px);
681
+ top: 10px;
682
+ width: 20px;
683
+ height: 20px;
684
+ --activityIndicatorLoadingDotColor: rgba(0, 0, 0, 0);
685
+ --activityIndicatorLoadingRingColor: ${activityIndicatorColor};
686
+ }
687
+
688
+ /* prevent selection from interfering with tooltip, especially on mobile */
689
+ /* https://stackoverflow.com/a/4407335/1163042 */
690
+ .noselect {
691
+ -webkit-touch-callout: none; /* iOS Safari */
692
+ -webkit-user-select: none; /* Safari */
693
+ -moz-user-select: none; /* Old versions of Firefox */
694
+ -ms-user-select: none; /* Internet Explorer/Edge */
695
+ user-select: none; /* current Chrome, Edge, Opera and Firefox */
696
+ }
697
+ .bar {
698
+ /* create a transparent border around the hist bars to prevent "gaps" and
699
+ flickering when moving around between bars. this also helps with handling
700
+ clicks on the bars, preventing users from being able to click in between
701
+ bars */
702
+ stroke: rgba(0, 0, 0, 0);
703
+ /* ensure transparent stroke wide enough to cover gap between bars */
704
+ stroke-width: 2px;
705
+ }
706
+ .bar:hover {
707
+ /* highlight currently hovered bar */
708
+ fill-opacity: 0.7;
709
+ }
710
+ .disabled .bar:hover {
711
+ /* ensure no visual hover interaction when disabled */
712
+ fill-opacity: 1;
713
+ }
714
+ /****** histogram ********/
715
+ #tooltip {
716
+ position: absolute;
717
+ background: ${tooltipBackgroundColor};
718
+ color: ${tooltipTextColor};
719
+ text-align: center;
720
+ border-radius: 3px;
721
+ padding: 2px;
722
+ font-size: ${tooltipFontSize};
723
+ font-family: ${tooltipFontFamily};
724
+ touch-action: none;
725
+ pointer-events: none;
726
+ }
727
+ #tooltip:after {
728
+ content: '';
729
+ position: absolute;
730
+ margin-left: -5px;
731
+ top: 100%;
732
+ /* arrow */
733
+ border: 5px solid ${tooltipTextColor};
734
+ border-color: ${tooltipBackgroundColor} transparent transparent
735
+ transparent;
736
+ }
737
+ /****** slider ********/
738
+ .draggable:hover {
739
+ cursor: grab;
740
+ }
741
+ .dragging {
742
+ cursor: grabbing !important;
743
+ }
744
+ /****** inputs ********/
745
+ #inputs {
746
+ display: flex;
747
+ justify-content: center;
748
+ margin: ${inputRowMargin};
749
+ }
750
+ #inputs .dash {
751
+ position: relative;
752
+ bottom: -1px;
753
+ align-self: center; /* Otherwise the dash sticks to the top while the inputs grow */
754
+ }
755
+ input {
756
+ width: ${inputWidth};
757
+ margin: 0 3px;
758
+ border: ${inputBorder};
759
+ border-radius: 2px !important;
760
+ text-align: center;
761
+ font-size: ${inputFontSize};
762
+ font-family: ${inputFontFamily};
763
+ }
764
+ .sr-only {
765
+ position: absolute !important;
766
+ width: 1px !important;
767
+ height: 1px !important;
768
+ margin: 0 !important;
769
+ padding: 0 !important;
770
+ border: 0 !important;
771
+ overflow: hidden !important;
772
+ white-space: nowrap !important;
773
+ clip: rect(1px, 1px, 1px, 1px) !important;
774
+ -webkit-clip-path: inset(50%) !important;
775
+ clip-path: inset(50%) !important;
776
+ }
773
777
  `;
774
778
  __decorate([
775
779
  property({ type: Number })