vue-svg-map
Version:
A set of Vue 3 components to display an interactive SVG map
144 lines (143 loc) • 4.12 kB
JavaScript
import { defineComponent as w, createElementBlock as h, openBlock as f, renderSlot as g, Fragment as E, renderList as S, mergeProps as L, mergeModels as M, useModel as $, createBlock as k, withKeys as d, withModifiers as l, createSlots as _, withCtx as y, normalizeProps as A, guardReactiveProps as C, useTemplateRef as K, onMounted as x } from "vue";
const P = ["viewBox", "aria-label"], R = ["id", "d", "aria-label"], B = /* @__PURE__ */ w({
__name: "SvgMap",
props: {
map: {},
locationAttributes: { type: [Object, Function], default: () => ({}) }
},
setup(v) {
return (e, m) => (f(), h("svg", {
xmlns: "http://www.w3.org/2000/svg",
viewBox: e.map.viewBox,
"aria-label": e.map.label,
class: "svg-map"
}, [
g(e.$slots, "before"),
(f(!0), h(E, null, S(e.map.locations, (n, u) => (f(), h("path", L({
key: n.id,
id: n.id,
d: n.path,
"aria-label": n.name,
class: "svg-map__location"
}, { ref_for: !0 }, {
...e.$attrs,
...typeof e.locationAttributes == "function" ? e.locationAttributes(n, u) : e.locationAttributes
}), null, 16, R))), 128)),
g(e.$slots, "after")
], 8, P));
}
}), I = /* @__PURE__ */ w({
__name: "SvgMapCheckbox",
props: /* @__PURE__ */ M({
map: {}
}, {
modelValue: { default: () => [] },
modelModifiers: {}
}),
emits: ["update:modelValue"],
setup(v) {
const e = $(v, "modelValue");
function m(a) {
return e.value.some((r) => r === a.id);
}
function n(a) {
return {
role: "checkbox",
tabindex: "0",
"aria-checked": m(a)
};
}
function u(a) {
const r = a.target;
if (r) {
const p = r.id, s = e.value.indexOf(p);
s > -1 ? e.value = [...e.value.slice(0, s), ...e.value.slice(s + 1)] : e.value = [...e.value, p];
}
}
return (a, r) => (f(), k(B, L(a.$attrs, {
map: a.map,
role: "group",
locationAttributes: n,
onClick: l(u, ["stop"]),
onKeydown: d(l(u, ["prevent", "stop"]), ["space"])
}), _({ _: 2 }, [
S(a.$slots, (p, s) => ({
name: s,
fn: y((b) => [
g(a.$slots, s, A(C(b)))
])
}))
]), 1040, ["map", "onKeydown"]));
}
}), O = /* @__PURE__ */ w({
__name: "SvgMapRadio",
props: /* @__PURE__ */ M({
map: {}
}, {
modelValue: { default: () => null },
modelModifiers: {}
}),
emits: ["update:modelValue"],
setup(v) {
const e = $(v, "modelValue"), m = K("svg");
let n;
x(() => {
m.value && (n = m.value.$el.querySelectorAll("path"));
});
function u(t) {
return e.value === t.id;
}
function a(t, o) {
return e.value ? u(t) ? "0" : "-1" : o === 0 ? "0" : "-1";
}
function r(t) {
t.id !== e.value && (e.value = t.id, t.focus());
}
function p(t) {
const o = t.target;
if (o) {
const i = o.nextElementSibling, c = i?.nodeName === "path" ? i : n[0];
r(c);
}
}
function s(t) {
const o = t.target;
if (o) {
const i = o.previousElementSibling, c = i?.nodeName === "path" ? i : n[n.length - 1];
r(c);
}
}
function b(t, o) {
return {
role: "radio",
tabindex: a(t, o),
"aria-checked": u(t)
};
}
return (t, o) => (f(), k(B, L({ ref: "svg" }, t.$attrs, {
map: t.map,
role: "radiogroup",
locationAttributes: b,
onClick: o[0] || (o[0] = l((i) => r(i.target), ["stop"])),
onKeydown: [
o[1] || (o[1] = d(l((i) => r(i.target), ["prevent", "stop"]), ["space"])),
d(l(p, ["prevent", "stop"]), ["down"]),
d(l(p, ["prevent", "stop"]), ["right"]),
d(l(s, ["prevent", "stop"]), ["up"]),
d(l(s, ["prevent", "stop"]), ["left"])
]
}), _({ _: 2 }, [
S(t.$slots, (i, c) => ({
name: c,
fn: y((V) => [
g(t.$slots, c, A(C(V)))
])
}))
]), 1040, ["map", "onKeydown"]));
}
});
export {
B as SvgMap,
I as SvgMapCheckbox,
O as SvgMapRadio
};