@sk1llahh/react-bvi
Version:
React BVI — библиотека для добавления режима слабовидящих на любой сайт. Панель настроек доступности: контрастность, шрифты, цвета, TTS, изображения и др.
2 lines (1 loc) • 14.6 kB
JavaScript
(function(o,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("react/jsx-runtime"),require("react"),require("react-i18next"),require("classnames")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","react-i18next","classnames"],a):(o=typeof globalThis<"u"?globalThis:o||self,a(o.ReactBVI={},o.jsxRuntime,o.React,o.reactI18next,o.cl))})(this,function(o,a,v,A,c){"use strict";const g={speak(i,e="ru-RU"){if(typeof window>"u")return;if(!("speechSynthesis"in window)){console.warn("BVI: SpeechSynthesis is not supported in this browser");return}if(!i)return;window.speechSynthesis.cancel();const t=new SpeechSynthesisUtterance(i);t.lang=e;const r=this.getVoiceForLang(e);r&&(t.voice=r),t.rate=1,t.pitch=1,window.speechSynthesis.speak(t)},getVoiceForLang(i){var r,l;if(typeof window>"u"||!i)return null;const e=((l=(r=window.speechSynthesis).getVoices)==null?void 0:l.call(r))||[];if(!e.length)return null;const t=String(i).toLowerCase();return e.find(n=>{var d;return((d=n.lang)==null?void 0:d.toLowerCase())===t})||e.find(n=>{var d;return(d=n.lang)==null?void 0:d.toLowerCase().startsWith(t.split("-")[0])})},stop(){typeof window>"u"||"speechSynthesis"in window&&window.speechSynthesis.cancel()}},z=()=>{const{state:i}=p();v.useEffect(()=>{if(!i.active||!i.tts)return;function e(t){const r=t.target;if(!r||r.closest&&r.closest(".bvi-panel"))return;const l=r.innerText||r.textContent;l&&g.speak(l,i.ttsLang)}return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[i.active,i.tts,i.ttsLang])};function T(){const[i,e]=v.useState(()=>({width:typeof window<"u"?window.innerWidth:0,height:typeof window<"u"?window.innerHeight:0}));return v.useEffect(()=>{if(typeof window>"u")return;function t(){e({width:window.innerWidth,height:window.innerHeight})}return t(),window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[]),i}const F=()=>{const{t:i}=A.useTranslation(),e=T(),{state:t,toggleActive:r,setTheme:l,setSize:n,setImagesMode:d,setLineHeight:U,setLetterSpacing:J,setFontFamily:D,setFlashIframe:L,resetToDefaults:Y,setTtsEnabled:B,speakPage:Z,stopSpeak:j,togglePanelHidden:w}=p();z();const[K,I]=v.useState(!1),[Q,X]=v.useState(!1);return t.active?a.jsxs("div",{className:c("bvi-panel",{"bvi-fixed-top":t.fixedPanel},{"bvi-panel-hidden":t.panelHidden}),children:[a.jsx("div",{className:"bvi-container-fluid",children:a.jsx("div",{className:"bvi-row bvi-no-gutters",children:a.jsx("div",{className:"bvi-col-12",children:a.jsxs("div",{className:"bvi-panel-toggler",children:[a.jsx("a",{href:"#",id:"bvi-toggler",className:"bvi-link",onClick:s=>{s.preventDefault(),X(b=>!b)},children:"Меню"}),a.jsx("a",{href:"#",id:"bvi-toggler-close",className:"bvi-link",onClick:s=>{s.preventDefault(),r()},children:i("bvi.button")}),a.jsx("a",{href:"#",id:"bvi-toggler-menu-hide",className:"bvi-link",onClick:s=>{s.preventDefault(),w()},children:a.jsx("i",{className:"bvi-images bvi-images-minus-square-o"})})]})})})}),a.jsxs("div",{className:c("bvi-panel-container",e.width>992?"bvi-container":"bvi-container-fluid"),style:e.width>992?{}:{display:Q?"block":"none"},children:[a.jsxs("div",{className:"bvi-row bvi-no-gutters",children:[a.jsxs("div",{className:"bvi-col-6 bvi-col-sm-6 bvi-col-md-3 bvi-col-lg-3 bvi-col-xl-3 bvi-text-center",children:[a.jsxs("div",{className:"bvi-title",children:[i("bvi.font-size")," ",a.jsx("span",{id:"bvi-font-size",children:t.size})," px"]}),a.jsx("a",{href:"#",id:"bvi-font-size-less",className:"bvi-link",onClick:s=>{s.preventDefault(),n(Math.max(14,Number(t.size)-2))},children:"A -"}),a.jsx("a",{href:"#",id:"bvi-font-size-more",className:"bvi-link",onClick:s=>{s.preventDefault(),n(Math.min(40,Number(t.size)+2))},children:"A +"})]}),a.jsxs("div",{className:"bvi-col-6 bvi-col-sm-6 bvi-col-md-3 bvi-col-lg-3 bvi-col-xl-3 bvi-text-center",children:[a.jsx("div",{className:"bvi-title",children:i("bvi.color")}),["white","black","blue","brown","green"].map(s=>a.jsx("a",{href:"#",id:`bvi-theme-${s}`,className:c("bvi-link",`bvi-link-${s}`,{active:t.theme===s}),onClick:b=>{b.preventDefault(),l(s)},children:"Ц"},s))]}),a.jsxs("div",{className:"bvi-col-6 bvi-col-sm-6 bvi-col-md-3 bvi-col-lg-3 bvi-col-xl-2 bvi-text-center",children:[a.jsx("div",{className:"bvi-title",children:i("bvi.image")}),a.jsx("a",{href:"#",id:"bvi-images-true",className:c("bvi-link",{active:t.images==="true"}),onClick:s=>{s.preventDefault(),d("true")},children:a.jsx("i",{className:"bvi-images bvi-images-on"})}),a.jsx("a",{href:"#",id:"bvi-images-false",className:c("bvi-link",{active:t.images==="false"}),onClick:s=>{s.preventDefault(),d("false")},children:a.jsx("i",{className:"bvi-images bvi-images-off"})}),a.jsx("a",{href:"#",id:"bvi-images-grayscale",className:c("bvi-link",{active:t.images==="grayscale"}),onClick:s=>{s.preventDefault(),d("grayscale")},children:a.jsx("i",{className:"bvi-images bvi-images-adjust"})})]}),a.jsxs("div",{className:"bvi-col-6 bvi-col-sm-6 bvi-col-md-3 bvi-col-lg-3 bvi-col-xl-4 bvi-text-center",children:[a.jsx("div",{className:"bvi-title",children:i("bvi.add")}),a.jsx("a",{href:"#",id:"bvi-tts-true",className:c("bvi-link",{active:t.tts}),onClick:s=>{s.preventDefault(),B(!0)},children:a.jsx("i",{className:"bvi-images bvi-images-volume-on"})}),a.jsx("a",{href:"#",id:"bvi-tts-false",className:c("bvi-link",{active:!t.tts}),onClick:s=>{s.preventDefault(),B(!1)},children:a.jsx("i",{className:"bvi-images bvi-images-volume-off"})}),a.jsx("a",{href:"#",id:"bvi-setting",className:"bvi-link",onClick:s=>{s.preventDefault(),I(b=>!b)},children:i("bvi.setting")}),a.jsx("a",{href:"#",id:"bvi-panel-close",className:"bvi-link",onClick:s=>{s.preventDefault(),r()},children:a.jsx("i",{className:"bvi-images bvi-images-eye-slash"})}),a.jsx("a",{href:"#",id:"bvi-panel-hide",className:"bvi-link",onClick:s=>{s.preventDefault(),w()},children:a.jsx("i",{className:"bvi-images bvi-images-minus-square-o"})})]})]}),a.jsx("div",{className:"bvi-setting-menu",style:{display:K?"block":"none"},children:a.jsxs("div",{className:"bvi-row bvi-no-gutters",children:[a.jsxs("div",{className:"bvi-col-sm-12 bvi-col-md-6 bvi-col-lg-4 bvi-col-xl-4 bvi-text-center",children:[a.jsx("div",{className:"bvi-title",children:i("bvi.line-height")}),[["normal",i("bvi.l-h-default")],["average",i("bvi.l-h-middle")],["big",i("bvi.l-h-big")]].map(([s,b])=>a.jsx("a",{href:"#",id:`bvi-line-height-${s}`,className:c("bvi-link",{active:t.lineHeight===s}),onClick:N=>{N.preventDefault(),U(s)},children:b},s))]}),a.jsxs("div",{className:"bvi-col-sm-12 bvi-col-md-6 bvi-col-lg-5 bvi-col-xl-5 bvi-text-center",children:[a.jsx("div",{className:"bvi-title",children:i("bvi.letter-spacing")}),[["normal",i("bvi.l-s-1")],["average",i("bvi.l-s-15")],["big",i("bvi.l-s-2")]].map(([s,b])=>a.jsx("a",{href:"#",id:`bvi-letter-spacing-${s}`,className:c("bvi-link",{active:t.letterSpacing===s}),onClick:N=>{N.preventDefault(),J(s)},children:b},s))]}),a.jsxs("div",{className:"bvi-col-sm-12 bvi-col-md-6 bvi-col-lg-3 bvi-col-xl-3 bvi-text-center",children:[a.jsx("div",{className:"bvi-title",children:i("bvi.font-family")}),a.jsx("a",{href:"#",id:"bvi-font-family-arial",className:c("bvi-link",{active:t.fontFamily==="arial"}),onClick:s=>{s.preventDefault(),D("arial")},children:i("bvi.ff-arial")}),a.jsx("a",{href:"#",id:"bvi-font-family-times",className:c("bvi-link",{active:t.fontFamily==="times"}),onClick:s=>{s.preventDefault(),D("times")},children:i("bvi.ff-times")})]}),a.jsxs("div",{className:"bvi-col-sm-12 bvi-col-md-6 bvi-col-lg-6 bvi-col-xl-6 bvi-text-center",children:[a.jsx("div",{className:"bvi-title",children:i("bvi.elements")}),a.jsx("a",{href:"#",id:"bvi-flash-iframe-true",className:c("bvi-link",{active:t.flashIframe=="true"}),onClick:s=>{s.preventDefault(),L(!0)},children:i("bvi.on")}),a.jsx("a",{href:"#",id:"bvi-flash-iframe-false",className:c("bvi-link",{active:t.flashIframe=="false"}),onClick:s=>{s.preventDefault(),L(!1)},children:i("bvi.off")})]}),a.jsxs("div",{className:"bvi-col-sm-12 bvi-col-md-12 bvi-col-lg-6 bvi-col-xl-6 bvi-text-right",children:[a.jsx("div",{className:"bvi-title",children:" "}),a.jsx("a",{href:"#",id:"bvi-settings-default",className:"bvi-link",onClick:s=>{s.preventDefault(),Y()},children:i("bvi.default_settings")}),a.jsx("a",{href:"#",id:"bvi-setting-close",className:"bvi-link",onClick:s=>{s.preventDefault(),I(!1)},children:i("bvi.close_panel")})]})]})})]}),a.jsx("a",{href:"#",id:"bvi-panel-show",className:"bvi-link bvi-link-top",style:{display:t.panelHidden?"block":"none"},onClick:s=>{s.preventDefault(),w()},children:a.jsx("i",{className:"bvi-images bvi-images-eye"})})]}):null},H=".bvi-body",S=()=>document.querySelector(H)||document.body,h=i=>Array.from(i.querySelectorAll("img")),u=i=>Array.from(i.querySelectorAll("svg")),m=i=>Array.from(i.querySelectorAll('object[type="image/svg+xml"], embed[type="image/svg+xml"]')),y=i=>Array.from(i.querySelectorAll("*")),q=i=>{if(!i||i==="none")return null;const e=i.match(/^url\(["']?(.*)["']?\)$/);return e?e[1]:null},k=(i,e="Изображение")=>{const t=i.getAttribute("alt")||i.getAttribute("aria-label")||i.getAttribute("title")||e,r=i.getAttribute("class")||"bvi-class-none",l=i.id||"",n=document.createElement("div");n.className=`${r} bvi-img`,l&&(n.id=l),n.textContent=t;const d=i.naturalWidth||i.width||i.clientWidth||i.getBoundingClientRect().width||null;d&&(n.style.width=`${d}px`),n.style.height="100%",i.insertAdjacentElement("afterend",n)},P=i=>{h(i).forEach(e=>{e.style.display="";const t=e.getAttribute("data-bvi-img-original");t&&(e.src=t)}),u(i).forEach(e=>{const t=e.getAttribute("data-bvi-original-display");e.style.display=t!==null?t:"",e.removeAttribute("data-bvi-original-display")}),m(i).forEach(e=>{const t=e.getAttribute("data-bvi-original-display");e.style.display=t!==null?t:"",e.removeAttribute("data-bvi-original-display")}),y(i).forEach(e=>{const t=e.getAttribute("data-bvi-background-image-original");t&&(e.style.backgroundImage=`url("${t}")`)})},O=i=>{h(i).forEach(e=>{e.getAttribute("data-bvi-img-original")||e.setAttribute("data-bvi-img-original",e.src),e.getAttribute("data-bvi-original-display")||e.setAttribute("data-bvi-original-display",e.style.display||""),e.style.display="none",k(e,"Изображение")}),u(i).forEach(e=>{e.getAttribute("data-bvi-original-display")||e.setAttribute("data-bvi-original-display",e.style.display||""),e.style.display="none",k(e,"SVG изображение")}),m(i).forEach(e=>{e.getAttribute("data-bvi-original-display")||e.setAttribute("data-bvi-original-display",e.style.display||""),e.style.display="none",k(e,"SVG изображение")})},V=i=>{h(i).forEach(e=>{e.style.display="",e.classList.add("bvi-img"),e.getAttribute("data-bvi-img-original")||e.setAttribute("data-bvi-img-original",e.src)}),u(i).forEach(e=>{e.style.display="",e.classList.add("bvi-img")}),m(i).forEach(e=>{e.style.display="",e.classList.add("bvi-img")}),y(i).forEach(e=>{const r=window.getComputedStyle(e).backgroundImage,l=q(r);l&&(e.classList.contains("bvi-background-image")||e.classList.add("bvi-background-image"),e.getAttribute("data-bvi-background-image-original")||e.setAttribute("data-bvi-background-image-original",l))})},$=i=>{const e=S();e.querySelectorAll("div.bvi-img").forEach(t=>t.remove()),i==="true"||i===!0?P(e):i==="false"||i===!1?O(e):i==="grayscale"&&V(e),e.setAttribute("data-bvi-images",i)},x=i=>{$(i)},M=()=>{const i=S();h(i).forEach(e=>{e.style.display=e.getAttribute("data-bvi-original-display")||"",e.removeAttribute("data-bvi-original-display");const t=e.getAttribute("data-bvi-img-original");t&&(e.src=t),e.classList.remove("bvi-img"),e.removeAttribute("data-bvi-img-original")}),u(i).forEach(e=>{const t=e.getAttribute("data-bvi-original-display");e.style.display=t!==null?t:"",e.removeAttribute("data-bvi-original-display"),e.classList.remove("bvi-img")}),m(i).forEach(e=>{const t=e.getAttribute("data-bvi-original-display");e.style.display=t!==null?t:"",e.removeAttribute("data-bvi-original-display"),e.classList.remove("bvi-img")}),i.querySelectorAll("div.bvi-img").forEach(e=>e.remove()),y(i).forEach(e=>{const t=e.getAttribute("data-bvi-background-image-original");t&&(e.style.backgroundImage=`url("${t}")`,e.classList.remove("bvi-background-image"),e.removeAttribute("data-bvi-background-image-original"))}),i.removeAttribute("data-bvi-images")},C=v.createContext(null),E="bvi-react-state",f={active:!1,theme:"white",size:"16",images:"true",lineHeight:"normal",letterSpacing:"normal",fontFamily:"default",flashIframe:"true",fixedPanel:!1,panelHidden:!1,tts:!0,ttsLang:"ru-RU"},W=()=>{if(typeof window>"u")return f;try{const i=localStorage.getItem(E);if(!i)return f;const e=JSON.parse(i);return{...f,...e}}catch{return f}},_=({children:i})=>{const[e,t]=v.useState(W);v.useEffect(()=>{if(!(typeof window>"u"))try{localStorage.setItem(E,JSON.stringify(e))}catch{console.log("BVI: failed")}},[e]);const r={state:e,toggleActive:()=>t(l=>(l.active?x(l.images):M(),{...l,active:!l.active,images:l.active?l.images:"true"})),setTheme:l=>t(n=>({...n,theme:l})),setSize:l=>t(n=>({...n,size:String(l)})),setImagesMode:l=>{x(l),t(n=>({...n,images:l}))},setLineHeight:l=>t(n=>({...n,lineHeight:l})),setLetterSpacing:l=>t(n=>({...n,letterSpacing:l})),setFontFamily:l=>t(n=>({...n,fontFamily:l})),setFlashIframe:l=>t(n=>({...n,flashIframe:l?"true":"false"})),setTtsLanguage:l=>t(n=>({...n,ttsLang:l})),togglePanelHidden:()=>t(l=>({...l,panelHidden:!l.panelHidden})),setTtsEnabled:l=>{l||g.stop(),t(n=>({...n,tts:l}))},resetToDefaults:()=>t(l=>({...f,images:"true",active:l.active})),speakPage:()=>{if(!e.tts||typeof document>"u")return;const l=document.body.innerText||document.body.textContent||"";g.speak(l.slice(0,8e3),e.ttsLang)},stopSpeak:()=>{g.stop()}};return a.jsx(C.Provider,{value:r,children:e.active?a.jsxs(a.Fragment,{children:[a.jsx(F,{}),a.jsx("div",{className:"bvi-body","data-bvi-active":e.active,"data-bvi-theme":e.theme,"data-bvi-size":e.size,"data-bvi-images":e.images,"data-bvi-line-height":e.lineHeight,"data-bvi-letter-spacing":e.letterSpacing,"data-bvi-font-family":e.fontFamily,"data-bvi-flash-iframe":e.flashIframe,"data-bvi-language":e.ttsLang,children:i})]}):i})};function p(){const i=v.useContext(C);if(!i)throw new Error("useBvi must be used within BviProvider");return i}const G=({children:i})=>{const{t:e}=A.useTranslation(),{state:t,toggleActive:r}=p();return a.jsx("button",{type:"button",className:c("bvi-open"),onClick:r,children:t.active?e("bvi.button"):i||e("bvi.title")})};o.BviButton=G,o.BviProvider=_,o.useBvi=p,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})});