JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta charset="utf-8">
  <!-- include polyfills for custom event, Symbol and Custom Elements -->
  <script src="//unpkg.com/babel-polyfill@6.26.0/dist/polyfill.js"></script>
  <script src="//unpkg.com/custom-event-polyfill@0.3.0/custom-event-polyfill.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/document-register-element/1.8.0/document-register-element.js"></script>

  <script src="//unpkg.com/d3@5.5.0"></script>
  <script src="//unpkg.com/d3fc@14.0.1"></script>

  <script src="https://npmcdn.com/topojson@1.6.24/build/topojson.min.js"></script>

</head>

<body>

  

</body>

</html>

CSS

.subunit.SCT {
      fill: #ddc;
    }

    .subunit.WLS {
      fill: #cdd;
    }

    .subunit.NIR {
      fill: #cdc;
    }

    .subunit.ENG {
      fill: #dcd;
    }

    .subunit.IRL,
    .subunit-label.IRL {
      display: none;
    }

    .subunit-boundary {
      fill: none;
      stroke: #777;
      stroke-dasharray: 2, 2;
      stroke-linejoin: round;
    }

    .subunit-boundary.IRL {
      stroke: #aaa;
    }

    .subunit-label {
      fill: #777;
      fill-opacity: .5;
      font-size: 20px;
      font-weight: 300;
      text-anchor: middle;
    }

    .place,
    .place-label {
      fill: #444;
    }

    text {
      font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
      font-size: 14px;
      pointer-events: none;
    }

    .label rect {
      fill: transparent;
    }

JavaScript

var width = 600,
      height =600;

    var projection = d3.geoAlbers()
      .center([0, 55.4])
      .rotate([4.4, 0])
      .parallels([50, 60])
      .scale(1200 * 5)
      .translate([width / 2, height / 2]);

    var path = d3.geoPath()
      .projection(projection)
      .pointRadius(2);


    var zoom = d3.zoom()
      .scaleExtent([1, 10])

    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)

    var zoom = d3.zoom()
      .scaleExtent([1, 28])
      .on('zoom', function () {
      const t=d3.event.transform;
        svg.selectAll('path')
          .attr('transform', t);
        svg.selectAll(".label")
          .attr('transform',  d=>{
          const p=projection(d.geometry.coordinates)
					return `translate(${p[0]*t.k+t.x}, ${p[1]*t.k+t.y}) scale(${t.k})`
          })


      });

    svg.call(zoom);


    d3.json("https://benderlidze.github.io/d3-uk-map/uk.json").then(uk => {
      var subunits = topojson.feature(uk, uk.objects.subunits),
        places = topojson.feature(uk, uk.objects.places);

      svg.selectAll(".subunit")
        .data(subunits.features)
        .enter().append("path")
        .attr("class", function (d) { return "subunit " + d.id; })
        .attr("d", path);

      svg.append("path")
        .datum(places)
        .attr("d", path)
        .attr("class", "place");

      var labelPadding = 2;

      // the component used to render each label
      var textLabel = fc.layoutTextLabel()
        .padding(labelPadding)
        .value(function (d) { return d.properties.name; });

      // a strategy that combines simulated annealing with removal
      // of overlapping labels
      var strategy = fc.layoutRemoveOverlaps(fc.layoutGreedy());

      // create the layout that positions the labels
      var labels = fc.layoutLabel(strategy)
        .size(function (_, i, g) {
          // measure the label and add the required padding
          var textSize = d3.select(g[i])
          ...