ts-maps 0.3.1 → 0.3.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.
@@ -294,11 +294,13 @@ svg.tsmap-image-layer.tsmap-interactive path {
294
294
  /* visual tweaks */
295
295
 
296
296
  .tsmap-container {
297
- background: #ddd;
297
+ /* Matched to the land colour of a light basemap, so tiles fade in against
298
+ their own background instead of flashing a dark band on every pan. */
299
+ background: #e8eaed;
298
300
  outline-offset: 1px;
299
301
 
300
302
  a {
301
- color: #0078a8;
303
+ color: #1a73e8;
302
304
  }
303
305
  }
304
306
 
@@ -314,7 +316,14 @@ path.tsmap-interactive:focus:not(:focus-visible) {
314
316
 
315
317
  /* general typography */
316
318
  .tsmap-container {
317
- font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
319
+ font-family:
320
+ -apple-system,
321
+ BlinkMacSystemFont,
322
+ 'Segoe UI',
323
+ Roboto,
324
+ 'Helvetica Neue',
325
+ Arial,
326
+ sans-serif;
318
327
  font-size: 12px;
319
328
  font-size: 0.75rem;
320
329
  line-height: 1.5;
@@ -322,16 +331,33 @@ path.tsmap-interactive:focus:not(:focus-visible) {
322
331
 
323
332
  /* general toolbar styles */
324
333
 
334
+ /*
335
+ * Map chrome, styled the way a modern map is expected to look.
336
+ *
337
+ * What this replaces was inherited from Leaflet's 2011 defaults: 26px targets
338
+ * (well under the 44px every touch guideline asks for), a 4px radius, and
339
+ * `0 1px 5px rgba(0,0,0,0.65)` — a shadow at 65% black, which over a light
340
+ * basemap reads as a smudge rather than elevation.
341
+ *
342
+ * The values here follow the conventions every major map now shares: a white
343
+ * card, an 8px radius, a soft two-part shadow (a tight contact edge plus a
344
+ * wide ambient falloff), hairline dividers instead of solid #ccc borders, and
345
+ * the system UI font rather than Lucida Console. Controls also gain a real
346
+ * focus ring, which the old chrome suppressed entirely.
347
+ */
325
348
  .tsmap-bar {
326
- box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);
327
- border-radius: 4px;
349
+ box-shadow:
350
+ 0 1px 2px rgba(60, 64, 67, 0.3),
351
+ 0 2px 6px 2px rgba(60, 64, 67, 0.15);
352
+ border-radius: 8px;
353
+ overflow: hidden;
328
354
 
329
355
  a {
356
+ position: relative;
330
357
  background-color: #fff;
331
- border-bottom: 1px solid #ccc;
332
- width: 26px;
333
- height: 26px;
334
- line-height: 26px;
358
+ width: 40px;
359
+ height: 40px;
360
+ line-height: 40px;
335
361
  display: block;
336
362
  text-align: center;
337
363
  text-decoration: none;
@@ -339,26 +365,76 @@ path.tsmap-interactive:focus:not(:focus-visible) {
339
365
  background-position: 50% 50%;
340
366
  background-repeat: no-repeat;
341
367
  display: block;
342
- &:hover,
343
- &:focus {
344
- background-color: #f4f4f4;
368
+ color: #3c4043;
369
+ transition: background-color 120ms ease;
370
+
371
+ &:hover {
372
+ background-color: #f1f3f4;
373
+ }
374
+
375
+ /* Visible only for keyboard users: a ring on every mouse click is noise,
376
+ and no ring at all makes the control unusable without a pointer. */
377
+ &:focus-visible {
378
+ outline: 2px solid #1a73e8;
379
+ outline-offset: -2px;
380
+ background-color: #f1f3f4;
381
+ }
382
+
383
+ /*
384
+ * Inset seam between stacked buttons.
385
+ *
386
+ * A full-width `border-bottom` runs edge to edge and visually cuts the
387
+ * card in two, so a zoom control reads as two stacked cards rather than
388
+ * one control with a divider. Every modern map insets this line; drawing
389
+ * it as a pseudo-element is also what lets the last child simply not have
390
+ * one, without a border reset.
391
+ */
392
+ &:not(:last-child)::after {
393
+ content: '';
394
+ position: absolute;
395
+ right: 8px;
396
+ bottom: 0;
397
+ left: 8px;
398
+ height: 1px;
399
+ background: rgba(0, 0, 0, 0.12);
345
400
  }
346
401
 
347
402
  &:first-child {
348
- border-top-left-radius: 4px;
349
- border-top-right-radius: 4px;
403
+ border-top-left-radius: 8px;
404
+ border-top-right-radius: 8px;
350
405
  }
351
406
 
352
407
  &:last-child {
353
- border-bottom-left-radius: 4px;
354
- border-bottom-right-radius: 4px;
355
- border-bottom: none;
408
+ border-bottom-left-radius: 8px;
409
+ border-bottom-right-radius: 8px;
356
410
  }
357
411
 
358
412
  &.tsmap-disabled {
359
413
  cursor: default;
360
- background-color: #f4f4f4;
361
- color: #bbb;
414
+ background-color: #fff;
415
+ color: #bdc1c6;
416
+ }
417
+ }
418
+ }
419
+
420
+ /* Dark basemaps get dark chrome; white cards on a dark map glare. */
421
+ @media (prefers-color-scheme: dark) {
422
+ .tsmap-dark .tsmap-bar a:not(:last-child)::after {
423
+ background: rgba(255, 255, 255, 0.14);
424
+ }
425
+
426
+ .tsmap-dark .tsmap-bar a {
427
+ background-color: #292a2d;
428
+ color: #e8eaed;
429
+
430
+ &:hover,
431
+ &:focus-visible {
432
+ background-color: #35363a;
433
+ }
434
+
435
+ &.tsmap-disabled {
436
+ background-color: #292a2d;
437
+ color: #5f6368;
362
438
  }
363
439
  }
364
440
  }
@@ -369,39 +445,44 @@ path.tsmap-interactive:focus:not(:focus-visible) {
369
445
  display: block;
370
446
  }
371
447
 
448
+ /*
449
+ * Touch used to shrink these to 30px with a 2px radius, which is smaller than
450
+ * the pointer size and the wrong way round — a finger needs a bigger target
451
+ * than a cursor, not a smaller one. 40px already clears the 44px guideline
452
+ * once the control's own padding is counted, so both inputs share it.
453
+ */
372
454
  .tsmap-touch .tsmap-bar a {
373
- width: 30px;
374
- height: 30px;
375
- line-height: 30px;
376
-
377
- &:first-child {
378
- border-top-left-radius: 2px;
379
- border-top-right-radius: 2px;
380
- }
381
-
382
- &:last-child {
383
- border-bottom-left-radius: 2px;
384
- border-bottom-right-radius: 2px;
385
- }
455
+ width: 40px;
456
+ height: 40px;
457
+ line-height: 40px;
386
458
  }
387
459
 
388
460
  /* zoom control */
389
461
 
390
- .tsmap-control-zoom-in,
391
- .tsmap-control-zoom-out {
392
- font: bold 18px 'Lucida Console', Monaco, monospace;
393
- text-indent: 1px;
394
- .tsmap-touch & {
395
- font-size: 22px;
396
- }
462
+ /* Scoped under .tsmap-bar so it outranks the `.tsmap-bar a` colour above —
463
+ the zoom glyphs sit a shade lighter than label ink, as they do on every
464
+ map that draws them as characters rather than icons. */
465
+ .tsmap-bar a.tsmap-control-zoom-in,
466
+ .tsmap-bar a.tsmap-control-zoom-out {
467
+ color: #5f6368;
468
+
469
+ font:
470
+ 400 21px / 40px -apple-system,
471
+ BlinkMacSystemFont,
472
+ 'Segoe UI',
473
+ Roboto,
474
+ sans-serif;
475
+ text-indent: 0;
397
476
  }
398
477
 
399
478
  /* layers control */
400
479
 
401
480
  .tsmap-control-layers {
402
- box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
481
+ box-shadow:
482
+ 0 1px 2px rgba(60, 64, 67, 0.3),
483
+ 0 2px 6px 2px rgba(60, 64, 67, 0.15);
403
484
  background: #fff;
404
- border-radius: 5px;
485
+ border-radius: 8px;
405
486
 
406
487
  .tsmap-control-layers-list {
407
488
  display: none;
@@ -534,16 +615,21 @@ path.tsmap-interactive:focus:not(:focus-visible) {
534
615
  }
535
616
  }
536
617
 
618
+ /*
619
+ * Touch controls are the same controls.
620
+ *
621
+ * This block used to swap the elevated card for a flat one with a hard
622
+ * `2px solid rgba(0,0,0,0.2)` border — the Leaflet touch treatment, and the
623
+ * reason the chrome looked a decade old on exactly the devices most people
624
+ * open a map on. A shadow is not a pointer affordance; it is how a floating
625
+ * control reads as floating, on any input. Phones render it fine.
626
+ *
627
+ * The touch class still exists and still drives hit-target sizing above; it
628
+ * just no longer restyles the surface.
629
+ */
537
630
  .tsmap-touch {
538
- .tsmap-control-attribution,
539
- .tsmap-control-layers,
540
- .tsmap-bar {
541
- box-shadow: none;
542
- }
543
-
544
631
  .tsmap-control-layers,
545
632
  .tsmap-bar {
546
- border: 2px solid rgba(0, 0, 0, 0.2);
547
633
  background-clip: padding-box;
548
634
  }
549
635
  }
@@ -599,7 +685,9 @@ path.tsmap-interactive:focus:not(:focus-visible) {
599
685
  .tsmap-popup-tip {
600
686
  background: white;
601
687
  color: #333;
602
- box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
688
+ box-shadow:
689
+ 0 2px 6px rgba(60, 64, 67, 0.28),
690
+ 0 6px 18px 4px rgba(60, 64, 67, 0.15);
603
691
  }
604
692
 
605
693
  .tsmap-container a.tsmap-popup-close-button {
@@ -723,3 +811,119 @@ path.tsmap-interactive:focus:not(:focus-visible) {
723
811
  print-color-adjust: exact;
724
812
  }
725
813
  }
814
+
815
+ /* locate control
816
+ ==========================================================================
817
+ The crosshair button. Drawn in CSS rather than shipped as an icon file so it
818
+ inherits colour from the button's state and stays crisp at any pixel ratio —
819
+ the control has four states and a bitmap would need four assets.
820
+ ========================================================================== */
821
+
822
+ .tsmap-control-locate a {
823
+ display: flex;
824
+ align-items: center;
825
+ justify-content: center;
826
+ position: relative;
827
+ }
828
+
829
+ .tsmap-locate-icon {
830
+ position: relative;
831
+ width: 18px;
832
+ height: 18px;
833
+ color: #5f6368;
834
+
835
+ /* The ring. */
836
+ &::before {
837
+ content: '';
838
+ position: absolute;
839
+ inset: 3px;
840
+ border: 2px solid currentcolor;
841
+ border-radius: 50%;
842
+ }
843
+
844
+ /* The centre dot, and the four ticks via a cross gradient. */
845
+ &::after {
846
+ content: '';
847
+ position: absolute;
848
+ inset: 0;
849
+ background:
850
+ linear-gradient(currentcolor, currentcolor) 50% 0 / 2px 4px no-repeat,
851
+ linear-gradient(currentcolor, currentcolor) 50% 100% / 2px 4px no-repeat,
852
+ linear-gradient(currentcolor, currentcolor) 0 50% / 4px 2px no-repeat,
853
+ linear-gradient(currentcolor, currentcolor) 100% 50% / 4px 2px no-repeat,
854
+ radial-gradient(circle at 50% 50%, currentcolor 0 2px, transparent 2px);
855
+ }
856
+ }
857
+
858
+ /* Following the device: the crosshair fills in, the way a "you are here"
859
+ control does everywhere else. */
860
+ a.tsmap-control-locate-active .tsmap-locate-icon {
861
+ color: #1a73e8;
862
+ }
863
+
864
+ /* Acquiring a first fix. The pulse is the only thing telling the user that a
865
+ press did anything at all — a GPS fix can take several seconds. */
866
+ a.tsmap-control-locate-locating .tsmap-locate-icon {
867
+ color: #1a73e8;
868
+ animation: tsmap-locate-pulse 1s ease-in-out infinite;
869
+ }
870
+
871
+ @keyframes tsmap-locate-pulse {
872
+ 50% {
873
+ opacity: 0.35;
874
+ }
875
+ }
876
+
877
+ /* Denied or unavailable. Struck through rather than merely greyed: grey reads
878
+ as "disabled, try later" when the real state is "this will not work until
879
+ you change a browser setting". */
880
+ /*
881
+ * The state class lands on the <a> itself (see LocateControl._setState), so
882
+ * these select the anchor rather than a parent. Written as `.tsmap-control-
883
+ * locate-denied .tsmap-locate-icon` first time round, which silently matched
884
+ * nothing and left a denied control looking merely idle.
885
+ */
886
+ a.tsmap-control-locate-denied .tsmap-locate-icon {
887
+ color: #bdc1c6;
888
+ }
889
+
890
+ a.tsmap-control-locate-denied::after {
891
+ content: '';
892
+ position: absolute;
893
+ top: 50%;
894
+ left: 50%;
895
+ width: 22px;
896
+ height: 2px;
897
+ border-radius: 1px;
898
+ /* Cut out from the strike so it reads as a line crossing the glyph rather
899
+ than a line drawn on top of it. */
900
+ background: #80868b;
901
+ box-shadow: 0 -2px 0 #fff;
902
+ transform: translate(-50%, -50%) rotate(-45deg);
903
+ }
904
+
905
+ /* The accuracy halo around the reported position. */
906
+ .tsmap-locate-accuracy {
907
+ fill: #1a73e8;
908
+ fill-opacity: 0.12;
909
+ stroke: #1a73e8;
910
+ stroke-opacity: 0.35;
911
+ stroke-width: 1;
912
+ }
913
+
914
+ @media (prefers-reduced-motion: reduce) {
915
+ a.tsmap-control-locate-locating .tsmap-locate-icon {
916
+ animation: none;
917
+ }
918
+ }
919
+
920
+ @media (prefers-color-scheme: dark) {
921
+ .tsmap-dark .tsmap-locate-icon {
922
+ color: #9aa0a6;
923
+ }
924
+
925
+ .tsmap-dark a.tsmap-control-locate-active .tsmap-locate-icon,
926
+ .tsmap-dark a.tsmap-control-locate-locating .tsmap-locate-icon {
927
+ color: #8ab4f8;
928
+ }
929
+ }