mirror of
https://github.com/responsively-org/responsively-app
synced 2024-11-10 06:44:13 +00:00
commit
f1d8a0361e
3 changed files with 368 additions and 22 deletions
|
@ -1,15 +1,16 @@
|
|||
import { Menu, Transition } from '@headlessui/react';
|
||||
import { Icon } from '@iconify/react';
|
||||
import cx from 'classnames';
|
||||
import { Fragment, useEffect, useRef, useState } from 'react';
|
||||
import { Fragment } from 'react';
|
||||
|
||||
interface Separator {
|
||||
type: 'separator';
|
||||
}
|
||||
|
||||
interface Option {
|
||||
type?: 'option';
|
||||
label: JSX.Element | string;
|
||||
onClick: () => void;
|
||||
onClick: (() => void) | null;
|
||||
}
|
||||
|
||||
type OptionOrSeparator = Option | Separator;
|
||||
|
@ -17,14 +18,15 @@ type OptionOrSeparator = Option | Separator;
|
|||
interface Props {
|
||||
label: JSX.Element | string;
|
||||
options: OptionOrSeparator[];
|
||||
className?: string | null;
|
||||
}
|
||||
|
||||
export function DropDown({ label, options }: Props) {
|
||||
export function DropDown({ label, options, className }: Props) {
|
||||
return (
|
||||
<div className="text-right">
|
||||
<Menu as="div" className="relative inline-block text-left">
|
||||
<Menu as="div" className={`relative inline-block text-left ${className}`}>
|
||||
<div>
|
||||
<Menu.Button className="inline-flex w-full justify-center gap-1 rounded-md bg-opacity-20 px-4 py-2 text-sm font-medium hover:bg-slate-300 hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 dark:hover:bg-slate-700">
|
||||
<Menu.Button className="inline-flex w-full justify-center gap-1 rounded-md bg-opacity-20 p-2 text-sm font-medium hover:bg-slate-300 hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 dark:hover:bg-slate-700">
|
||||
{label}
|
||||
<Icon icon="mdi:chevron-down" />
|
||||
</Menu.Button>
|
||||
|
@ -53,18 +55,29 @@ export function DropDown({ label, options }: Props) {
|
|||
return (
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<Menu.Item key={idx.toString()}>
|
||||
{({ active }) => (
|
||||
<button
|
||||
className={cx(
|
||||
'group flex w-full items-center rounded-md px-2 py-2 text-sm',
|
||||
{ 'bg-slate-200 dark:bg-slate-800': active }
|
||||
)}
|
||||
type="button"
|
||||
onClick={option.onClick}
|
||||
>
|
||||
{option.label}
|
||||
</button>
|
||||
)}
|
||||
{({ active }) =>
|
||||
option.onClick !== null ? (
|
||||
<button
|
||||
className={cx(
|
||||
'group flex w-full items-center rounded-md px-2 py-2',
|
||||
{ 'bg-slate-200 dark:bg-slate-800': active }
|
||||
)}
|
||||
type="button"
|
||||
onClick={option.onClick}
|
||||
>
|
||||
{option.label}
|
||||
</button>
|
||||
) : (
|
||||
<div
|
||||
className={cx(
|
||||
'group mt-2 flex w-full items-center rounded-md px-2',
|
||||
{ 'bg-slate-200 dark:bg-slate-800': active }
|
||||
)}
|
||||
>
|
||||
{option.label}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</Menu.Item>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -8,6 +8,14 @@ import WebPage from 'main/screenshot/webpage';
|
|||
|
||||
import screenshotSfx from 'renderer/assets/sfx/screenshot.mp3';
|
||||
import { updateWebViewHeightAndScale } from 'common/webViewUtils';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { DropDown } from '../../DropDown';
|
||||
|
||||
export interface InjectedCss {
|
||||
key: string;
|
||||
css: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
webview: Electron.WebviewTag | null;
|
||||
|
@ -28,6 +36,9 @@ const Toolbar = ({
|
|||
onIndividualLayoutHandler,
|
||||
isIndividualLayout,
|
||||
}: Props) => {
|
||||
const dispatch = useDispatch();
|
||||
// const cssSelector: InjectedCss | undefined = useSelector(selectCss);
|
||||
const [injectCss, setInjectCss] = useState<InjectedCss>();
|
||||
const [eventMirroringOff, setEventMirroringOff] = useState<boolean>(false);
|
||||
const [playScreenshotDone] = useSound(screenshotSfx, { volume: 0.5 });
|
||||
const [screenshotLoading, setScreenshotLoading] = useState<boolean>(false);
|
||||
|
@ -35,6 +46,17 @@ const Toolbar = ({
|
|||
useState<boolean>(false);
|
||||
const [rotated, setRotated] = useState<boolean>(false);
|
||||
|
||||
const redgreen = [
|
||||
'Deuteranopia',
|
||||
'Deuteranomaly',
|
||||
'Protanopia',
|
||||
'Protanomaly',
|
||||
];
|
||||
const blueyellow = ['Tritanopia', 'Tritanomaly'];
|
||||
const full = ['Achromatomaly', 'Achromatopsia'];
|
||||
const visualimpairments = ['Cataract', 'Farsightedness', 'Glaucome'];
|
||||
const sunlight = ['Solarize'];
|
||||
|
||||
const refreshView = () => {
|
||||
if (webview) {
|
||||
webview.reload();
|
||||
|
@ -42,7 +64,7 @@ const Toolbar = ({
|
|||
};
|
||||
|
||||
const toggleEventMirroring = async () => {
|
||||
if (webview == null) {
|
||||
if (webview === null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
@ -64,7 +86,7 @@ const Toolbar = ({
|
|||
};
|
||||
|
||||
const quickScreenshot = async () => {
|
||||
if (webview == null) {
|
||||
if (webview === null) {
|
||||
return;
|
||||
}
|
||||
setScreenshotLoading(true);
|
||||
|
@ -84,14 +106,128 @@ const Toolbar = ({
|
|||
setScreenshotLoading(false);
|
||||
};
|
||||
|
||||
const applyCss = async (
|
||||
debugType: string,
|
||||
css: string,
|
||||
js: string | null = null
|
||||
) => {
|
||||
if (webview === null) {
|
||||
return;
|
||||
}
|
||||
if (css === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (injectCss !== undefined) {
|
||||
if (js !== null) {
|
||||
webview.reload();
|
||||
}
|
||||
if (injectCss.css === css) {
|
||||
await webview.removeInsertedCSS(injectCss.key);
|
||||
setInjectCss(undefined);
|
||||
return;
|
||||
}
|
||||
await webview.removeInsertedCSS(injectCss.key);
|
||||
setInjectCss(undefined);
|
||||
}
|
||||
|
||||
try {
|
||||
const key = await webview.insertCSS(css);
|
||||
setInjectCss({ key, css, name: debugType });
|
||||
if (js !== null) {
|
||||
await webview.executeJavaScript(js);
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Error inserting css', error);
|
||||
// dispatch(setCss(undefined));
|
||||
setInjectCss(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
const applyColorDeficiency = async (colorDeficiency: string) => {
|
||||
const xsltPath =
|
||||
'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgdmVyc2lvbj0iMS4xIj4KICA8ZGVmcz4KICAgIDxmaWx0ZXIgaWQ9InByb3Rhbm9waWEiPgogICAgICA8ZmVDb2xvck1hdHJpeAogICAgICAgIGluPSJTb3VyY2VHcmFwaGljIgogICAgICAgIHR5cGU9Im1hdHJpeCIKICAgICAgICB2YWx1ZXM9IjAuNTY3LCAwLjQzMywgMCwgICAgIDAsIDAKICAgICAgICAgICAgICAgIDAuNTU4LCAwLjQ0MiwgMCwgICAgIDAsIDAKICAgICAgICAgICAgICAgIDAsICAgICAwLjI0MiwgMC43NTgsIDAsIDAKICAgICAgICAgICAgICAgIDAsICAgICAwLCAgICAgMCwgICAgIDEsIDAiLz4KICAgIDwvZmlsdGVyPgogICAgPGZpbHRlciBpZD0icHJvdGFub21hbHkiPgogICAgICA8ZmVDb2xvck1hdHJpeAogICAgICAgIGluPSJTb3VyY2VHcmFwaGljIgogICAgICAgIHR5cGU9Im1hdHJpeCIKICAgICAgICB2YWx1ZXM9IjAuODE3LCAwLjE4MywgMCwgICAgIDAsIDAKICAgICAgICAgICAgICAgIDAuMzMzLCAwLjY2NywgMCwgICAgIDAsIDAKICAgICAgICAgICAgICAgIDAsICAgICAwLjEyNSwgMC44NzUsIDAsIDAKICAgICAgICAgICAgICAgIDAsICAgICAwLCAgICAgMCwgICAgIDEsIDAiLz4KICAgIDwvZmlsdGVyPgogICAgPGZpbHRlciBpZD0iZGV1dGVyYW5vcGlhIj4KICAgICAgPGZlQ29sb3JNYXRyaXgKICAgICAgICBpbj0iU291cmNlR3JhcGhpYyIKICAgICAgICB0eXBlPSJtYXRyaXgiCiAgICAgICAgdmFsdWVzPSIwLjYyNSwgMC4zNzUsIDAsICAgMCwgMAogICAgICAgICAgICAgICAgMC43LCAgIDAuMywgICAwLCAgIDAsIDAKICAgICAgICAgICAgICAgIDAsICAgICAwLjMsICAgMC43LCAwLCAwCiAgICAgICAgICAgICAgICAwLCAgICAgMCwgICAgIDAsICAgMSwgMCIvPgogICAgPC9maWx0ZXI+CiAgICA8ZmlsdGVyIGlkPSJkZXV0ZXJhbm9tYWx5Ij4KICAgICAgPGZlQ29sb3JNYXRyaXgKICAgICAgICBpbj0iU291cmNlR3JhcGhpYyIKICAgICAgICB0eXBlPSJtYXRyaXgiCiAgICAgICAgdmFsdWVzPSIwLjgsICAgMC4yLCAgIDAsICAgICAwLCAwCiAgICAgICAgICAgICAgICAwLjI1OCwgMC43NDIsIDAsICAgICAwLCAwCiAgICAgICAgICAgICAgICAwLCAgICAgMC4xNDIsIDAuODU4LCAwLCAwCiAgICAgICAgICAgICAgICAwLCAgICAgMCwgICAgIDAsICAgICAxLCAwIi8+CiAgICA8L2ZpbHRlcj4KICAgIDxmaWx0ZXIgaWQ9InRyaXRhbm9waWEiPgogICAgICA8ZmVDb2xvck1hdHJpeAogICAgICAgIGluPSJTb3VyY2VHcmFwaGljIgogICAgICAgIHR5cGU9Im1hdHJpeCIKICAgICAgICB2YWx1ZXM9IjAuOTUsIDAuMDUsICAwLCAgICAgMCwgMAogICAgICAgICAgICAgICAgMCwgICAgMC40MzMsIDAuNTY3LCAwLCAwCiAgICAgICAgICAgICAgICAwLCAgICAwLjQ3NSwgMC41MjUsIDAsIDAKICAgICAgICAgICAgICAgIDAsICAgIDAsICAgICAwLCAgICAgMSwgMCIvPgogICAgPC9maWx0ZXI+CiAgICA8ZmlsdGVyIGlkPSJ0cml0YW5vbWFseSI+CiAgICAgIDxmZUNvbG9yTWF0cml4CiAgICAgICAgaW49IlNvdXJjZUdyYXBoaWMiCiAgICAgICAgdHlwZT0ibWF0cml4IgogICAgICAgIHZhbHVlcz0iMC45NjcsIDAuMDMzLCAwLCAgICAgMCwgMAogICAgICAgICAgICAgICAgMCwgICAgIDAuNzMzLCAwLjI2NywgMCwgMAogICAgICAgICAgICAgICAgMCwgICAgIDAuMTgzLCAwLjgxNywgMCwgMAogICAgICAgICAgICAgICAgMCwgICAgIDAsICAgICAwLCAgICAgMSwgMCIvPgogICAgPC9maWx0ZXI+CiAgICA8ZmlsdGVyIGlkPSJhY2hyb21hdG9wc2lhIj4KICAgICAgPGZlQ29sb3JNYXRyaXgKICAgICAgICBpbj0iU291cmNlR3JhcGhpYyIKICAgICAgICB0eXBlPSJtYXRyaXgiCiAgICAgICAgdmFsdWVzPSIwLjI5OSwgMC41ODcsIDAuMTE0LCAwLCAwCiAgICAgICAgICAgICAgICAwLjI5OSwgMC41ODcsIDAuMTE0LCAwLCAwCiAgICAgICAgICAgICAgICAwLjI5OSwgMC41ODcsIDAuMTE0LCAwLCAwCiAgICAgICAgICAgICAgICAwLCAgICAgMCwgICAgIDAsICAgICAxLCAwIi8+CiAgICA8L2ZpbHRlcj4KICAgIDxmaWx0ZXIgaWQ9ImFjaHJvbWF0b21hbHkiPgogICAgICA8ZmVDb2xvck1hdHJpeAogICAgICAgIGluPSJTb3VyY2VHcmFwaGljIgogICAgICAgIHR5cGU9Im1hdHJpeCIKICAgICAgICB2YWx1ZXM9IjAuNjE4LCAwLjMyMCwgMC4wNjIsIDAsIDAKICAgICAgICAgICAgICAgIDAuMTYzLCAwLjc3NSwgMC4wNjIsIDAsIDAKICAgICAgICAgICAgICAgIDAuMTYzLCAwLjMyMCwgMC41MTYsIDAsIDAKICAgICAgICAgICAgICAgIDAsICAgICAwLCAgICAgMCwgICAgIDEsIDAiLz4KICAgIDwvZmlsdGVyPgogIDwvZGVmcz4KPC9zdmc+Cg==';
|
||||
const css = `
|
||||
body {
|
||||
-webkit-filter: url('${xsltPath}#${colorDeficiency}');
|
||||
filter: url('${xsltPath}#${colorDeficiency}');
|
||||
}
|
||||
`;
|
||||
return applyCss(colorDeficiency, css);
|
||||
};
|
||||
|
||||
const applySunlight = async (condition: string) => {
|
||||
const css = 'body {backdrop-filter: brightness(0.5) !important;}';
|
||||
return applyCss(condition, css);
|
||||
};
|
||||
|
||||
const applyVisualImpairment = async (visualImpairment: string) => {
|
||||
const blur =
|
||||
'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8ZGVmcz4KICAgICAgICA8ZmlsdGVyIGlkPSJnYXVzc2lhbl9ibHVyIj4KICAgICAgICAgICAgPGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VHcmFwaGljIiBzdGREZXZpYXRpb249IjEwIiAvPgogICAgICAgIDwvZmlsdGVyPgogICAgPC9kZWZzPgo8L3N2Zz4=';
|
||||
|
||||
const impairments: { [key: string]: string } = {
|
||||
cataract: `body {
|
||||
-webkit-filter: url('${blur}#gaussian_blur');
|
||||
filter: url('${blur}#gaussian_blur');
|
||||
}`,
|
||||
glaucome: `#bigoverlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#spotlight {
|
||||
border-radius: 50%;
|
||||
width: 300vmax;
|
||||
height: 300vmax;
|
||||
box-shadow: 0 0 5vmax 110vmax inset black;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
left: -75vmax;
|
||||
top: -75vmax;
|
||||
}`,
|
||||
farsightedness: `body { filter: blur(2px); }`,
|
||||
};
|
||||
const css = impairments[visualImpairment.toLowerCase()];
|
||||
let js = null;
|
||||
if (visualImpairment.toLowerCase() === 'glaucome') {
|
||||
js = String(`var div = document.createElement('div');
|
||||
div.innerHTML ='<div class="bigoverlay" id="bigoverlay"><div class="spotlight" id="spotlight"></div></div>';
|
||||
var body = document.body;
|
||||
body.appendChild(div);
|
||||
function handleMouseMove(){
|
||||
var eventDoc, doc, body;
|
||||
eventDoc = (event.target && event.target.ownerDocument) || document;
|
||||
doc = eventDoc.documentElement;
|
||||
body = eventDoc.body;
|
||||
event.pageX = event.clientX +
|
||||
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
|
||||
(doc && doc.clientLeft || body && body.clientLeft || 0);
|
||||
event.pageY = event.clientY +
|
||||
(doc && doc.scrollTop || body && body.scrollTop || 0) -
|
||||
(doc && doc.clientTop || body && body.clientTop || 0 );
|
||||
const spotlight = document.getElementById("spotlight");
|
||||
const boundingRect = spotlight.getBoundingClientRect();
|
||||
spotlight.style.left = (event.pageX - boundingRect.width / 2) + "px"
|
||||
spotlight.style.top = (event.pageY - boundingRect.height / 2) + "px"
|
||||
};document.onmousemove = handleMouseMove;0`);
|
||||
}
|
||||
return applyCss(visualImpairment, css, js);
|
||||
};
|
||||
|
||||
const fullScreenshot = async () => {
|
||||
if (webview == null) {
|
||||
if (webview === null) {
|
||||
return;
|
||||
}
|
||||
setFullScreenshotLoading(true);
|
||||
try {
|
||||
const webviewTag = window.document.getElementById(device.name);
|
||||
if (webviewTag == null) {
|
||||
if (webviewTag === null) {
|
||||
return;
|
||||
}
|
||||
setScreenshotInProgress(true);
|
||||
|
@ -168,7 +304,7 @@ const Toolbar = ({
|
|||
<Button onClick={openDevTools} title="Open Devtools">
|
||||
<Icon icon="ic:round-code" />
|
||||
</Button>
|
||||
<Button onClick={rotate} isActive={rotated} title="Rotate This Device">
|
||||
<Button onClick={rotate} title="Rotate This Device">
|
||||
<Icon
|
||||
icon={
|
||||
rotated
|
||||
|
@ -177,6 +313,202 @@ const Toolbar = ({
|
|||
}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
<DropDown
|
||||
className="text-xs"
|
||||
label={<Icon icon="codicon:debug-line-by-line" fontSize={18} />}
|
||||
options={[
|
||||
{
|
||||
label: (
|
||||
<div className="flex w-full flex-shrink-0 items-center justify-between gap-12 whitespace-nowrap">
|
||||
<span className="font-bold">A11y Tools</span>
|
||||
</div>
|
||||
),
|
||||
onClick: null,
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<div className="flex w-full flex-shrink-0 items-center justify-between gap-12 whitespace-nowrap">
|
||||
<span>Visual deficiency</span>
|
||||
</div>
|
||||
),
|
||||
onClick: null,
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<div className="flex w-full flex-shrink-0 items-center justify-start gap-12 whitespace-nowrap">
|
||||
<span className="ml-1 font-semibold">
|
||||
Red-green deficiency
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
onClick: null,
|
||||
},
|
||||
...redgreen.map((x: string) => {
|
||||
return {
|
||||
label: (
|
||||
<div className="justify-normal flex w-full flex-shrink-0 items-center gap-1 whitespace-nowrap">
|
||||
{injectCss?.name === x.toLowerCase() ? (
|
||||
<Icon icon="ic:round-check" />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<span
|
||||
className={`ml-2 ${
|
||||
injectCss?.name === x.toLowerCase()
|
||||
? 'font-semibold text-black'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
{x}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
onClick: () => {
|
||||
applyColorDeficiency(x.toLowerCase());
|
||||
},
|
||||
};
|
||||
}),
|
||||
{
|
||||
label: (
|
||||
<div className="flex w-full flex-shrink-0 items-center justify-between gap-12 whitespace-nowrap">
|
||||
<span className="ml-1 font-semibold">
|
||||
Blue-yellow deficiency
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
onClick: null,
|
||||
},
|
||||
...blueyellow.map((x: string) => {
|
||||
return {
|
||||
label: (
|
||||
<div className="justify-normal flex w-full flex-shrink-0 items-center gap-1 whitespace-nowrap">
|
||||
{injectCss?.name === x.toLowerCase() ? (
|
||||
<Icon icon="ic:round-check" />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<span
|
||||
className={`ml-2 ${
|
||||
injectCss?.name === x.toLowerCase()
|
||||
? 'font-semibold text-black'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
{x}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
onClick: () => {
|
||||
applyColorDeficiency(x.toLowerCase());
|
||||
},
|
||||
};
|
||||
}),
|
||||
{
|
||||
label: (
|
||||
<div className="flex w-full flex-shrink-0 items-center justify-between gap-1 whitespace-nowrap">
|
||||
<span className="ml-1 font-semibold">
|
||||
Full color deficiency
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
onClick: null,
|
||||
},
|
||||
...full.map((x: string) => {
|
||||
return {
|
||||
label: (
|
||||
<div className="justify-normal flex w-full flex-shrink-0 items-center gap-1 whitespace-nowrap">
|
||||
{injectCss?.name === x.toLowerCase() ? (
|
||||
<Icon icon="ic:round-check" />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<span
|
||||
className={`ml-2 ${
|
||||
injectCss?.name === x.toLowerCase()
|
||||
? 'font-semibold text-black'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
{x}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
onClick: () => {
|
||||
applyColorDeficiency(x.toLowerCase());
|
||||
},
|
||||
};
|
||||
}),
|
||||
{
|
||||
label: (
|
||||
<div className="flex w-full flex-shrink-0 items-center justify-between gap-1 whitespace-nowrap">
|
||||
<span className="ml-1 font-semibold">Visual impairment</span>
|
||||
</div>
|
||||
),
|
||||
onClick: null,
|
||||
},
|
||||
...visualimpairments.map((x: string) => {
|
||||
return {
|
||||
label: (
|
||||
<div className="justify-normal flex w-full flex-shrink-0 items-center gap-1 whitespace-nowrap">
|
||||
{injectCss?.name === x.toLowerCase() ? (
|
||||
<Icon icon="ic:round-check" />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<span
|
||||
className={`ml-2 ${
|
||||
injectCss?.name === x.toLowerCase()
|
||||
? 'font-semibold text-black'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
{x}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
onClick: () => {
|
||||
applyVisualImpairment(x.toLowerCase());
|
||||
},
|
||||
};
|
||||
}),
|
||||
{
|
||||
label: (
|
||||
<div className="flex w-full flex-shrink-0 items-center justify-between gap-1 whitespace-nowrap">
|
||||
<span className="ml-1 font-semibold">
|
||||
Temporary impairment
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
onClick: null,
|
||||
},
|
||||
...sunlight.map((x: string) => {
|
||||
return {
|
||||
label: (
|
||||
<div className="justify-normal flex w-full flex-shrink-0 items-center gap-1 whitespace-nowrap">
|
||||
{injectCss?.name === x.toLowerCase() ? (
|
||||
<Icon icon="ic:round-check" />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<span
|
||||
className={`ml-2 ${
|
||||
injectCss?.name === x.toLowerCase()
|
||||
? 'font-semibold text-black'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
{x}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
onClick: () => {
|
||||
applySunlight(x.toLowerCase());
|
||||
},
|
||||
};
|
||||
}),
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
onClick={() => onIndividualLayoutHandler(device)}
|
||||
|
|
|
@ -148,6 +148,7 @@ export const selectZoomFactor = (state: RootState) => {
|
|||
}
|
||||
return state.renderer.zoomFactor;
|
||||
};
|
||||
|
||||
export const selectAddress = (state: RootState) => state.renderer.address;
|
||||
export const selectPageTitle = (state: RootState) => state.renderer.pageTitle;
|
||||
export const selectRotate = (state: RootState) => state.renderer.rotate;
|
||||
|
|
Loading…
Reference in a new issue