Best JavaScript code snippet using testcafe
main.js
Source:main.js  
1// remove shortcut if it is a touch device2var isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; 3//  'ontouchstart' in window works on most browsers 4// navigator.msMaxTouchPoints > 0 works for microsoft IE backwards compatibility56var FamilyTree = familyTree(isTouchDevice);78if (isTouchDevice){9	$('.cmd-text:not(.caret-right),#selection-area-item').addClass('hide');10	$('#details-node,#details-group').removeClass('hide');11}1213var viewport = document.getElementById('viewport');1415// resize event16function onResize(){17	var w = document.body.clientWidth,18		h = document.body.clientHeight,19		top = viewport.offsetTop,20		left = viewport.offsetLeft;21	h -= top;22	w -= left;2324	$('.fixed-menu').css('max-height', h + 'px');2526	FamilyTree.resize(w, h);27};2829function undo(){30	FamilyTree.undo();31};3233function redo(){34	FamilyTree.redo();35};3637function selectAll(){38	FamilyTree.selectAll();39	FamilyTree.centerAll();40};4142function deleteElements(){43	var objects = FamilyTree.getObjectsToDelete();44	FamilyTree.deleteObjects(45		objects.nodes, 46		objects.relLinks, 47		objects.childLinks,48		objects.groups,49		function(){ FamilyTree.draw(); }, 50		function(){ FamilyTree.draw(); }, 51		function(){ FamilyTree.draw(); }52	);53};545556if (!isTouchDevice){57	d3.select(document.body)58		.on('keydown', function (ev) {		59			var Keys = {60					DELETE: 46,61					A: 65,62					E: 69,63					S: 83,64					Z: 90,65					Y: 8966				};6768			if (['input', 'textarea'].indexOf(d3.event.target.tagName.toLowerCase()) != -1)69				return;7071			var w = this.clientWidth,72				h = this.clientHeight;7374			// Area Selection75			if ((d3.event.shiftKey) && (!FamilyTree.getBrushLayer())) {76				FamilyTree.startBrush();77			}78			// Center selection 79			else if (d3.event.keyCode == Keys.S) {80				FamilyTree.centerSelection();81			}82			83			// Center all tree84			else if (d3.event.keyCode == Keys.E) {85				FamilyTree.centerAll();86			}8788			// delete nodes and/or links89			else if (d3.event.keyCode == Keys.DELETE) {90				FamilyTree.hideContextMenus();91				deleteElements();92			}93				94			else if (d3.event.ctrlKey){95				// Select all tree96				if (d3.event.keyCode == Keys.A) {97					d3.event.preventDefault();98					FamilyTree.hideContextMenus();99					selectAll();100				} 101102				// UNDO103				else if (d3.event.keyCode == Keys.Z) 104					undo();105			106				// REDO107				else if (d3.event.keyCode == Keys.Y)108					redo();109110				else111					util.selectionMode.enableMulti(isTouchDevice);112			}113		})114		.on('keyup', function() {115			if (d3.event.target.tagName.toLowerCase() == 'input')116				return;117118			if (!d3.event.shiftKey && FamilyTree.isMovingBrush())119				FamilyTree.endBrush();120121			if (!d3.event.ctrlKey && util.selectionMode.isMulti())122				util.selectionMode.disableMulti();123		});124}125126document.body.onresize = onResize;127	128FamilyTree.init(viewport, document.body.clientWidth, document.body.clientHeight);129onResize();130131var eventStart = isTouchDevice ? 'touchstart' : 'mousedown';132133var mainCollapsableNavbar = $('#main-navbar-collapse'),134	treeNameItem = $('#loaded-tree-name'),135	alertPopup = $('#alert-popup'),136	openFilePopup = $('#open-file-popup'),137	saveAsPopup = $('#save-as-popup'),138	fileField = openFilePopup.find('#field-file-name #input-file'),139	undoMenuItem = $('#undo-item'),140	redoMenuItem = $('#redo-item'),141	deleteMenuItem = $('#delete-item'),142	fileNameItem = $('#loaded-file-name'),143	centerSelItem = $('#center-selection-item'),144	extendItem = $('#extend-item');145146saveAsPopup.on("hide.bs.modal", function () {147    $('#json-format-opt').click();148    $('#input-name').val('');149});150151// create new tree152$('#new-item').on(eventStart, function(){153	if (!undoMenuItem.hasClass('disabled')){154		alertPopup.modal();155		alertPopup.isLoadingNewTree = true;156	} else {157		treeNameItem.html(dictionary.get('Default')).removeClass('modified');158		FamilyTree.load();159	}160	if (isTouchDevice && mainCollapsableNavbar.is(':visible')){161		mainCollapsableNavbar.collapse('toggle');162	}163});164165// open existing tree166var fileContent = null;167168openFilePopup.on("hide.bs.modal", function () {169    fileContent = null;170	fileField.val('');171	openFilePopup.find("#upload-file-info").val('');172});173174openFilePopup.find('#upload-file-btn').on(eventStart, function(){175	if (fileContent)176		FamilyTree.load(JSON.parse(fileContent));177	openFilePopup.modal('hide');	178});179180fileField.on('change', function(){181	var fileName = $(this).val();182	var nameArray = fileName.split('\\');183	var name = nameArray[nameArray.length - 1];184	openFilePopup.find("#upload-file-info").val(name);185186	var reader = new FileReader();187	reader.onload = function(){188        treeNameItem.html(name.replace('.json', '')).removeClass('modified');189        fileContent = this.result;190    };191    reader.readAsText(this.files.item(0)); 192})193194alertPopup.find('#yes').on(eventStart, function(){ 195	alertPopup.modal('hide');196	saveAsPopup.modal();197});198199alertPopup.find('#no').on(eventStart, function(){ 200	alertPopup.modal('hide');201	if (alertPopup.isLoadingNewTree){202		alertPopup.isLoadingNewTree = false;203		FamilyTree.load();204		treeNameItem.html(dictionary.get('Default'));205	} else if (alertPopup.isOpeningTree){206		alertPopup.isOpeningTree = false;207		openFilePopup.modal();208	} 209});210211function showOpenFilePopup (){212	if (!undoMenuItem.hasClass('disabled')){213		alertPopup.modal();		214		alertPopup.isOpeningTree = true;215	} else 216		openFilePopup.modal();217};218219$('#open-item').on(eventStart, function(){	220	if (isTouchDevice && mainCollapsableNavbar.is(':visible')){221		mainCollapsableNavbar.collapse('toggle');222		mainCollapsableNavbar.one('hidden.bs.collapse', function(){223			showOpenFilePopup();224		});225	} else 226		showOpenFilePopup();227});228229saveAsPopup.find('.btn-group[data-toggle-name]').each(function () {230    var group = $(this);231    var form = group.parents('form').eq(0);232    var name = group.attr('data-toggle-name');233    var hidden = $('input[name="' + name + '"]', form);234    $('button', group).each(function () {235        var button = $(this);236        button.live('click', function () {237            hidden.val($(this).val());238        });239        if (button.val() == hidden.val()) {240            button.addClass('active');241        }242    });243});244245$('#save-as-item').on(eventStart, function(){	246	if (isTouchDevice && mainCollapsableNavbar.is(':visible')){247		mainCollapsableNavbar.collapse('toggle');248		mainCollapsableNavbar.one('hidden.bs.collapse', function(){249			saveAsPopup.modal();250		});251	} else 252		saveAsPopup.modal();253});254255$('#save-item').on(eventStart, function(){256	FamilyTree.saveAs('json', treeNameItem.html());257});258259saveAsPopup.find("#input-format").on('change', function() {260	var sField =  saveAsPopup.find('#field-scale');261	sField.val(100);262	if ($(this).val() == 'png')263		sField.removeClass('hide');264	else265		sField.addClass('hide');266});267268saveAsPopup.find('#save').on(eventStart, function(){269	var form = saveAsPopup.find('.form-horizontal');270		nodeId = form.find('#input-id').val();271	if (!form.valid())272		return;273	var records = form.serializeArray(),274		values = {};275	records.forEach(function(rec){276		values[rec.name] = rec.value;277	});278279	FamilyTree.saveAs(values.format, values.fileName, values.scale);280281	saveAsPopup.modal('hide');282	$('json-format-opt').trigger(eventStart);283	$('#input-name').val('');284	$('#field-scale').val(100);285286	if (alertPopup.isLoadingNewTree){287		alertPopup.isLoadingNewTree = false;288		FamilyTree.load();289		treeNameItem.html(dictionary.get('Default'));290	} else if (alertPopup.isOpeningTree){291		alertPopup.isOpeningTree = false;292		openFilePopup.modal();293	} 294});295296297// edit298$('#edit-menu').on(eventStart, function (){299	var selection = FamilyTree.getSelectionCount(),300		count = selection.length;301	if (count)302		deleteMenuItem.removeClass('disabled');303	else 304		deleteMenuItem.addClass('disabled');305});306307undoMenuItem.on(eventStart, function(){308	if (isTouchDevice && mainCollapsableNavbar.is(':visible')){309		mainCollapsableNavbar.collapse('toggle');310		mainCollapsableNavbar.one('hidden.bs.collapse', function(){311			undo();312		});313	} else 314		undo();315});316317redoMenuItem.on(eventStart, function(){318	if (isTouchDevice && mainCollapsableNavbar.is(':visible')){319		mainCollapsableNavbar.collapse('toggle');320		mainCollapsableNavbar.one('hidden.bs.collapse', function(){321			redo();322		});323	} else 324		redo();325});326327deleteMenuItem.on(eventStart, function(){328	if (isTouchDevice && mainCollapsableNavbar.is(':visible')){329		mainCollapsableNavbar.collapse('toggle');330		mainCollapsableNavbar.one('hidden.bs.collapse', function(){331			deleteElements();332		});333	} else 334		deleteElements();335});336337$('#select-all-item').on(eventStart, function(){338	if (isTouchDevice && mainCollapsableNavbar.is(':visible')){339		mainCollapsableNavbar.collapse('toggle');340		mainCollapsableNavbar.one('hidden.bs.collapse', function(){341			selectAll();342		});343	} else 344		selectAll();345});346347$('#selection-area-item').on(eventStart, function(){348	if (!isTouchDevice && !FamilyTree.getBrushLayer()) 349		FamilyTree.startBrush();350});351352//view353$('#view-menu').on(eventStart, function(){354	var count = FamilyTree.getSelectionCount();355	if (count)356		centerSelItem.removeClass('disabled');357	else358		centerSelItem.addClass('disabled');359});360361centerSelItem.on(eventStart, function(){362	if (isTouchDevice && mainCollapsableNavbar.is(':visible')){363		mainCollapsableNavbar.collapse('toggle');364		mainCollapsableNavbar.one('hidden.bs.collapse', function(){365			FamilyTree.centerSelection();366		});367	} else 368		FamilyTree.centerSelection();369});370371extendItem.on(eventStart, function(){372	if (isTouchDevice && mainCollapsableNavbar.is(':visible')){373		mainCollapsableNavbar.collapse('toggle');374		mainCollapsableNavbar.one('hidden.bs.collapse', function(){375			FamilyTree.centerAll();376		});377	} else 378		FamilyTree.centerAll();379});380381// hide all visible context menus when clicking or touching a navigation bar 382$('.navbar').on(eventStart, function(e) {383	FamilyTree.hideContextMenus();384});385386// search387var searchInput = $('#search-field input'),388	searchIcon = $('#search-icon');389searchInput.on('keydown', function(){	390	if (event.keyCode == 13){391		searchIcon.trigger(eventStart);392	}393});394395searchIcon.on(eventStart, function(){396	var searchValue = searchInput.val();397	if (!searchValue || !searchValue.length)398		return;399	var results = FamilyTree.search(searchValue);400	$('#search-result-list').show('toggle');401});402403$('#close-search-result-list').on(eventStart, function(){404	$('#search-result-list').hide('toggle');405})406407// language408var langMenu = $('#language-menu');409	410langMenu.parent().find('li').each(function(){411	$(this).find('a').on(eventStart, function(){412		langMenu.parent().find('li.active').removeClass('active');413		var $a = $(this);414		$a.parent().addClass('active');415 		var lang = $a.html();	416 		langMenu.html(lang + '<b class = "caret">');417 		dictionary.setLanguage(lang.toLowerCase());418 	});419});	420421$('#viewport').on(eventStart, function(){422	$('nav.dropdown.open').trigger(eventStart);423});424425// multi selection navbar426$('#exit-from-selection-mode a').on(eventStart, function(){427	util.selectionMode.disableMulti(isTouchDevice);428	FamilyTree.deselectAll();429	if (isTouchDevice && mainCollapsableNavbar.is(':visible'))430		mainCollapsableNavbar.collapse('toggle');431});432433$('#delete-selected-objects a').on(isTouchDevice ? 'touchend' : 'click', function(){434	deleteElements();435	util.selectionMode.disableMulti(isTouchDevice);436	/*if (isTouchDevice && mainCollapsableNavbar.is(':visible'))437		mainCollapsableNavbar.collapse('toggle');*/438});439440$('#center-selected-objects a').on(isTouchDevice ? 'touchend' : 'click', function(){441	FamilyTree.centerSelection();442	util.selectionMode.disableMulti(isTouchDevice);	443	FamilyTree.deselectAll();444	/*if (isTouchDevice && mainCollapsableNavbar.is(':visible'))445		mainCollapsableNavbar.collapse('toggle');*/446});447448$('#select-all-objects').on(isTouchDevice ? 'touchend' : 'click', function(){449	FamilyTree.selectAll();450});451452$('#deselect-all-objects').on(isTouchDevice ? 'touchend' : 'click', function(){453	FamilyTree.deselectAll();454});455456$(document).on('action', function(ev, action, undoCounter, redoCounter){457	if (undoCounter){458		undoMenuItem.removeClass('disabled');459		treeNameItem.addClass('modified');460	}461	else {462		undoMenuItem.addClass('disabled');463		treeNameItem.removeClass('modified');464	}465	if (redoCounter)466		redoMenuItem.removeClass('disabled');467	else 468		redoMenuItem.addClass('disabled');
...MapControls.jsx
Source:MapControls.jsx  
1import React, { useEffect, useState, useRef } from 'react';2import { AiFillWarning, AiOutlineWarning } from 'react-icons/ai';3import { ImSpinner10 } from 'react-icons/im';4import { IoHandRight, IoHandRightOutline, IoLayers, IoSkullOutline, IoSkull, IoCubeOutline, IoCube, IoStatsChartOutline, IoStatsChart } from 'react-icons/io5';5import { FaBiohazard } from 'react-icons/fa';6import { GiResize, GiDeathSkull, GiBiohazard } from 'react-icons/gi';7import {8  RiCursorLine, RiCursorFill, RiZoomInLine, RiZoomInFill, RiZoomOutLine, RiZoomOutFill, RiMessage2Fill, RiMessage2Line, RiAlarmWarningLine, RiAlarmWarningFill ,9  RiSyringeFill,10  RiSyringeLine,11  RiPercentLine, RiPercentFill,12  RiExchangeLine, RiExchangeFill13} from 'react-icons/ri';14import { BsCursor, BsCursorFill, BsBarChart, BsBarChartFill } from 'react-icons/bs';15import { FiHelpCircle } from 'react-icons/fi';16import { TiChartLineOutline, TiChartLine, TiChartBar, TiChartBarOutline } from 'react-icons/ti';17import ReactTooltip from 'react-tooltip';18import './MapControls.css';19const MapControlDropdownButton = ({ onClick, icon, tooltipId, tooltipContent, isTouchDevice, children, dataTour, tooltipPlace, setHighlightedState }) => {20  const [isMouseOver, setIsMouseOver] = useState(false);21  const ref = useRef(null);22  useEffect(() => {23    if (isMouseOver) {24      setHighlightedState(null);25    }26  }, [isMouseOver])27  return (28    <div className="map-control-btn map-control-dropdown-btn" data-tip data-for={tooltipId} data-tour={tooltipId || dataTour} onClick={() => setIsMouseOver(!isMouseOver)} onMouseEnter={() => setIsMouseOver(true)} onMouseOver={() => setIsMouseOver(true)} onMouseLeave={() => setIsMouseOver(false)} ref={ref}>29      {icon}30      {!isTouchDevice && tooltipId && tooltipContent && <ReactTooltip31        id={tooltipId}32        aria-haspopup='true'33        effect="solid"34        delayShow={1500}35        className="tooltip"36        clickable={true}37        place={tooltipPlace}38      >39        <div style={{ maxWidth: `${.3 * innerWidth}px`, fontSize: '13px' }}>40          {tooltipContent}41        </div>42      </ReactTooltip>}43      <div className={`map-control-dropdown ${isMouseOver ? 'show' : 'hide'}`} data-tour="map-layers-dropdown">44        <div className="map-control-drop-down-container overlay">45          {(Array.isArray(children) ? children : [children]).map(child => <div>{child}</div>)}46        </div>47      </div>48    </div>49  )50}51const MapControlLayerButton = ({ className, style, tool, activateTool, activeTool, activeIcon, inactiveIcon, tooltipId, tooltipContent, isTouchDevice, tooltipPlace, layerName }) => {52  const toolId = tool || tooltipId;53  const onClick = (e) => {54    e.stopPropagation();55    activateTool(toolId);56  }57  return (58    <React.Fragment>59      <div className={`map-control-btn map-control-layer-btn ${className ? className : ''}`} style={style} onClick={onClick} data-tip data-for={tooltipId} data-tour={tooltipId}>60        <div className="layer-icon">{activeTool === toolId ? activeIcon : inactiveIcon}</div>61        <div className="layer-name">{layerName}</div>62      </div>63      {!isTouchDevice && tooltipId && tooltipContent && <ReactTooltip64        id={tooltipId}65        aria-haspopup='true'66        effect="solid"67        delayShow={1500}68        className="tooltip"69        clickable={true}70        place={tooltipPlace}71      >72        <div style={{ maxWidth: `${.3 * innerWidth}px`, fontSize: '13px' }}>73          {tooltipContent}74        </div>75      </ReactTooltip>}76    </React.Fragment>77  )78}79const MapControlToggleButton = ({ className, style, tool, activateTool, activeTool, activeIcon, inactiveIcon, tooltipId, tooltipContent, isTouchDevice, tooltipPlace }) => {80  const toolId = tool || tooltipId;81  return (82    <React.Fragment>83      <div className={`map-control-btn ${className ? className : ''}`} style={style} onClick={(e) => activateTool(toolId)} data-tip data-for={tooltipId} data-tour={tooltipId}>84        {activeTool === toolId ? activeIcon : inactiveIcon}85      </div>86      {!isTouchDevice && tooltipId && tooltipContent && <ReactTooltip87        id={tooltipId}88        aria-haspopup='true'89        effect="solid"90        delayShow={1500}91        className="tooltip"92        clickable={true}93        place={tooltipPlace}94      >95        <div style={{ maxWidth: `${.3 * innerWidth}px`, fontSize: '13px' }}>96          {tooltipContent}97        </div>98      </ReactTooltip>}99    </React.Fragment>100  )101}102const MapControlButton = ({ onClick, icon, tooltipId, tooltipContent, isTouchDevice, tooltipPlace }) => {103  return (104    <div className="map-control-btn" onClick={onClick} data-tip data-for={tooltipId} data-tour={tooltipId}>105      {icon}106      {!isTouchDevice && tooltipId && tooltipContent && <ReactTooltip107        id={tooltipId}108        aria-haspopup='true'109        effect="solid"110        delayShow={1500}111        className="tooltip"112        clickable={true}113        place={tooltipPlace}114      >115        <div style={{ maxWidth: `${.3 * innerWidth}px`, fontSize: '13px' }}>116          {tooltipContent}117        </div>118      </ReactTooltip>}119    </div>120  )121}122export default function MapControls({ style, fitToViewer, locationLock, toggleLocationLock, activeTool, activateTool, showStats, toggleStats, setIsTourOpen, locating, isTouchDevice, toggleTooltips, showTooltips, mapLayer, setMapLayer, setHighlightedState }) {123  return (124    <div className="map-controls overlay" data-tour="map-controls">125      <MapControlToggleButton126        tool="location-lock"127        isTouchDevice={isTouchDevice}128        activateTool={toggleLocationLock}129        activeTool={locationLock ? 'location-lock' : 'none'}130        activeIcon={locating ? <ImSpinner10 /> : <BsCursorFill />}131        inactiveIcon={locating ? <ImSpinner10 /> : <BsCursor />}132        className={locating ? 'spin' : ''}133        style={{ transform: locating ? undefined : 'scale(-1, 1) rotate(-24deg) translate(-2px, 1px)' }}134        tooltipId="location-lock"135        tooltipContent={<p>Tap here to find your location. When this tool is active, your location will be highlighted on the map and the county's statistics will be shown.</p>}136      />137      <MapControlToggleButton138        tool="none"139        isTouchDevice={isTouchDevice}140        activateTool={activateTool}141        activeTool={activeTool}142        activeIcon={<RiCursorFill />}143        inactiveIcon={<RiCursorLine />}144        tooltipId="none"145        tooltipContent={<p>Tap here to activate the cursor tool. When this tool is active, tapping on counties will activate them and show their statistics.</p>}146      />147      <MapControlToggleButton148        tool="pan"149        isTouchDevice={isTouchDevice}150        activateTool={activateTool}151        activeTool={activeTool}152        activeIcon={<IoHandRight />}153        inactiveIcon={<IoHandRightOutline />}154        tooltipId="pan"155        tooltipContent={<p>Tap here to activate the pan tool. When this tool is active, a tap and drag will pan the map left/right/up/down.</p>}156      />157      <MapControlToggleButton158        tool="zoom-in"159        isTouchDevice={isTouchDevice}160        activateTool={activateTool}161        activeTool={activeTool}162        activeIcon={<RiZoomInFill />}163        inactiveIcon={<RiZoomInLine />}164        tooltipId="zoom-in"165        tooltipContent={<p>Tap here to activate the zoom in tool. When this tool is active, a single tap will zoom the map out in to that position. A tap and drag action allows you to zoom into a particular selected area.</p>}166      />167      <MapControlToggleButton168        tool="zoom-out"169        isTouchDevice={isTouchDevice}170        activateTool={activateTool}171        activeTool={activeTool}172        activeIcon={<RiZoomOutFill />}173        inactiveIcon={<RiZoomOutLine />}174        tooltipId="zoom-out"175        tooltipContent={<p>Tap here to activate the zoom out tool. When this tool is active, a single tap will zoom the map out from that position.</p>}176      />177      <MapControlButton178        isTouchDevice={isTouchDevice}179        onClick={fitToViewer}180        icon={<GiResize />}181        tooltipId="fit-to-viewer"182        tooltipContent={<p>Tap here to fit the map to the window.</p>}183      />184      <MapControlButton185        isTouchDevice={isTouchDevice}186        onClick={toggleStats}187        icon={showStats ? <TiChartLine /> : <TiChartLineOutline />}188        tooltipId="toggle-stats"189        tooltipContent={<p>{`Tap here to ${showStats ? 'hide' : 'show'} the stats overlay.`}</p>}190      />191      <MapControlButton192        isTouchDevice={isTouchDevice}193        onClick={toggleTooltips}194        icon={showTooltips ? <RiMessage2Fill /> : <RiMessage2Line />}195        tooltipId="toggle-tooltips"196        tooltipContent={<p>{`Tap here to ${showTooltips ? 'hide' : 'show'} tooltips for each state.`}</p>}197      />198      <MapControlDropdownButton199        isTouchDevice={isTouchDevice}200        setHighlightedState={setHighlightedState}201        icon={<IoLayers />}202        dataTour="map-layers"203      >204        <MapControlLayerButton205          isTouchDevice={isTouchDevice}206          activateTool={setMapLayer}207          activeTool={mapLayer}208          activeIcon={<RiAlarmWarningFill />}209          inactiveIcon={<RiAlarmWarningLine />}210          layerName={`Overall Risk Level`}211          tooltipId="risk"212        />213        <MapControlLayerButton214          isTouchDevice={isTouchDevice}215          activateTool={setMapLayer}216          activeTool={mapLayer}217          activeIcon={<BsBarChartFill />}218          inactiveIcon={<BsBarChart />}219          layerName={`ICU Capacity`}220          tooltipId="icuCap"221        />222        <MapControlLayerButton223          isTouchDevice={isTouchDevice}224          activateTool={setMapLayer}225          activeTool={mapLayer}226          activeIcon={<TiChartBar />}227          inactiveIcon={<TiChartBarOutline />}228          layerName={`Hospital Capacity`}229          tooltipId="hospitalCap"230        />231        <MapControlLayerButton232          isTouchDevice={isTouchDevice}233          activateTool={setMapLayer}234          activeTool={mapLayer}235          activeIcon={<IoStatsChart />}236          inactiveIcon={<IoStatsChartOutline />}237          layerName={`Case Fatality Rate`}238          tooltipId="cfr"239        />240        <MapControlLayerButton241          isTouchDevice={isTouchDevice}242          activateTool={setMapLayer}243          activeTool={mapLayer}244          activeIcon={<IoSkull />}245          inactiveIcon={<IoSkullOutline />}246          layerName={`Total Deaths`}247          tooltipId="deaths"248        />249        <MapControlLayerButton250          isTouchDevice={isTouchDevice}251          activateTool={setMapLayer}252          activeTool={mapLayer}253          activeIcon={<RiSyringeFill />}254          inactiveIcon={<RiSyringeLine />}255          layerName={`Vaccinated`}256          tooltipId="vaccinated"257        />258        <MapControlLayerButton259          isTouchDevice={isTouchDevice}260          activateTool={setMapLayer}261          activeTool={mapLayer}262          activeIcon={<AiFillWarning />}263          inactiveIcon={<AiOutlineWarning />}264          layerName={`Cases`}265          tooltipId="cases"266        />267        <MapControlLayerButton268          isTouchDevice={isTouchDevice}269          activateTool={setMapLayer}270          activeTool={mapLayer}271          activeIcon={<IoCube />}272          inactiveIcon={<IoCubeOutline />}273          layerName={`Case Density`}274          tooltipId="caseDensity"275        />276        <MapControlLayerButton277          isTouchDevice={isTouchDevice}278          activateTool={setMapLayer}279          activeTool={mapLayer}280          activeIcon={<FaBiohazard />}281          inactiveIcon={<GiBiohazard />}282          layerName={`Infection Rate`}283          tooltipId="infectionRate"284        />285        <MapControlLayerButton286          isTouchDevice={isTouchDevice}287          activateTool={setMapLayer}288          activeTool={mapLayer}289          activeIcon={<RiPercentFill />}290          inactiveIcon={<RiPercentLine />}291          layerName={`Test Positivity`}292          tooltipId="testPositivityRatio"293        />294        <MapControlLayerButton295          isTouchDevice={isTouchDevice}296          activateTool={setMapLayer}297          activeTool={mapLayer}298          activeIcon={<RiExchangeFill />}299          inactiveIcon={<RiExchangeLine />}300          layerName={`CDC Transmission Level`}301          tooltipId="cdc"302        />303      </MapControlDropdownButton>304      <MapControlButton305        isTouchDevice={isTouchDevice}306        onClick={() => setIsTourOpen(true)}307        icon={<FiHelpCircle />}308        tooltipId="interactive-help"309        tooltipContent={<p>Tap here to view the interactive tour and information about this application.</p>}310      />311    </div>312  );...Projects.js
Source:Projects.js  
...46          Promise.all(IMAGES.map(image => loadImage(image)))47            .then(() => setImgsLoaded(true))48            .catch(err => console.log("Failed to load images", err))49    }, [])50    function isTouchDevice() {51        return (('ontouchstart' in window) ||52           (navigator.maxTouchPoints > 0) ||53           (navigator.msMaxTouchPoints > 0));54      }55    const handleClicked=(e)=>{56        if(hover[e.currentTarget.id]===false){57            const hoverClone={...hover}58            delete hoverClone[e.currentTarget.id]59            let updatedState={};60            updatedState[e.currentTarget.id]=true;61            setHover(hover={...hoverClone,...updatedState})62        }63        else if(hover[e.currentTarget.id]===true){64            const hoverClone={...hover}65            delete hoverClone[e.currentTarget.id]66            let updatedState={};67            updatedState[e.currentTarget.id]=false;68            setHover(hover={...hoverClone,...updatedState})69        }70    }71    const handleMouseIn=(e)=>{72        const hoverClone={...hover}73        delete hoverClone[e.currentTarget.id]74        let updatedState={};75        updatedState[e.currentTarget.id]=true;76        setHover(hover={...hoverClone,...updatedState})77    }78    const handleMouseOut =(e)=>{79        const hoverClone={...hover}80        delete hoverClone[e.currentTarget.id]81        let updatedState={};82        updatedState[e.currentTarget.id]=false;83        setHover(hover={...hoverClone,...updatedState})84    }85    86    const ProjectsGrid=()=>{87       88        return(89            <div className="projects__grid--container">90                <div className="projects__grid--unit-title">SL Cocilux</div>91                {hover.slcocilux?92                    <div className="projects__grid--unit-container" id="slcocilux" 93                    onClick={isTouchDevice()? (e)=>handleClicked(e): undefined} 94                    onMouseEnter={isTouchDevice()? undefined:(e)=>handleMouseIn(e)} 95                    onMouseLeave={isTouchDevice()? undefined:(e)=>handleMouseOut(e)}96                    >97                        <div className="projects__grid--unit slcocilux hover white" style={{backgroundImage:`url(${IMAGES[0].url})`}}></div>98                        <div className="projects__grid--unit-description white">SL Cocilux is a kitchen design company based in Madrid, their web displays their catalog. It is build on ReactJS.99                        <br></br>100                        <a href="https://slcocilux.com/" className="projects__grid--unit-link white">WEBSITE</a>101                        <a href="https://github.com/GunnerAg/CociLux" className="projects__grid--unit-link white">GITHUB REPO</a>102                        </div>103                        104                    </div>105                    :106                    <div className="projects__grid--unit slcocilux" id="slcocilux" 107                    onClick={isTouchDevice()? (e)=>handleClicked(e): undefined} 108                    onMouseEnter={isTouchDevice()? undefined:(e)=>handleMouseIn(e)} 109                    onMouseLeave={isTouchDevice()? undefined:(e)=>handleMouseOut(e)}110                    style={{backgroundImage:`url(${IMAGES[0].url})`}}111                    ></div>112                }113                114                <div className="projects__grid--unit-title">NFT ERC-721</div>115                {hover.nftERC? 116                    <div className="projects__grid--unit-container"  id="nftERC"  117                    onClick={isTouchDevice()? (e)=>handleClicked(e): undefined} 118                    onMouseEnter={isTouchDevice()? undefined:(e)=>handleMouseIn(e)} 119                    onMouseLeave={isTouchDevice()? undefined:(e)=>handleMouseOut(e)}120                    >121                    <div className="projects__grid--unit nftERC hover white" style={{backgroundImage:`url(${IMAGES[1].url})`}}></div>122                        <div className="projects__grid--unit-description white">This is a simple example of a NFT ethereum token minting app, it works with metamask and ganache on localhost.123                        It was done using ReactJS, Solidity and Web3.124                        <br></br>125                        <a href="https://nft-erc-721.netlify.app/" className="projects__grid--unit-link white">WEBSITE</a>126                        <a href="https://github.com/GunnerAg/ERC721" className="projects__grid--unit-link white">GITHUB REPO</a>127                        </div>128                        129                    </div>130                    :131                    <div className="projects__grid--unit nftERC" id="nftERC"  132                    onClick={isTouchDevice()? (e)=>handleClicked(e): undefined} 133                    onMouseEnter={isTouchDevice()? undefined:(e)=>handleMouseIn(e)} 134                    onMouseLeave={isTouchDevice()? undefined:(e)=>handleMouseOut(e)}135                    style={{backgroundImage:`url(${IMAGES[1].url})`}}136                    ></div>137                }138                <div className="projects__grid--unit-title">The Vault</div>139                {hover.theVault? 140                    <div className="projects__grid--unit-container" id="theVault"  141                    onClick={isTouchDevice()? (e)=>handleClicked(e): undefined} 142                    onMouseEnter={isTouchDevice()? undefined:(e)=>handleMouseIn(e)} 143                    onMouseLeave={isTouchDevice()? undefined:(e)=>handleMouseOut(e)}144                    >145                        <div className="projects__grid--unit theVault hover white" style={{backgroundImage:`url(${IMAGES[2].url})`}}></div>146                        <div className="projects__grid--unit-description white">The Vault is a social network to share knowladge, find people by affinity, create and see events, as well as  share/store related docs! It is build on ReactJS, NodeJS and MongoDB.147                        <br></br>148                        <a href="https://the-vault-project.herokuapp.com/" className="projects__grid--unit-link white">WEBSITE</a>149                        <a href="https://github.com/GunnerAg/The-Vault-Project-" className="projects__grid--unit-link white">GITHUB REPO</a>150                        </div>151                        152                    </div>:153                    <div className="projects__grid--unit theVault" id="theVault" 154                    onClick={isTouchDevice()? (e)=>handleClicked(e): undefined} 155                    onMouseEnter={isTouchDevice()? undefined:(e)=>handleMouseIn(e)} 156                    onMouseLeave={isTouchDevice()? undefined:(e)=>handleMouseOut(e)}157                    style={{backgroundImage:`url(${IMAGES[2].url})`}}158                    ></div>159                }160                161                <div className="projects__grid--unit-title">Jobber</div>162                {hover.jobber? 163                    <div className="projects__grid--unit-container" id="jobber" 164                    onClick={isTouchDevice()? (e)=>handleClicked(e): undefined} 165                    onMouseEnter={isTouchDevice()? undefined:(e)=>handleMouseIn(e)} 166                    onMouseLeave={isTouchDevice()? undefined:(e)=>handleMouseOut(e)}167                        168                    >169                    <div className="projects__grid--unit jobber hover white" style={window.innerWidth>=600?{backgroundImage:`url(${IMAGES[3].url})`}:{backgroundImage:`url(${IMAGES[4].url})`}}></div>170                        <div className="projects__grid--unit-description white">Jobber is a minimalist job search engine for companies and employees done with Handlebars, NodeJS and MongoDB. 171                        <br></br>172                        <a href="https://j0bber.herokuapp.com/" className="projects__grid--unit-link white">WEBSITE</a>173                        <a href="https://github.com/GunnerAg/Jobber-JobSearchEngine." className="projects__grid--unit-link white">GITHUB REPO</a>174                        </div>175                    176                    </div>:177                    <div className="projects__grid--unit jobber" id="jobber" 178                    onClick={isTouchDevice()? (e)=>handleClicked(e): undefined} 179                    onMouseEnter={isTouchDevice()? undefined:(e)=>handleMouseIn(e)} 180                    onMouseLeave={isTouchDevice()? undefined:(e)=>handleMouseOut(e)}181                    style={window.innerWidth>=600?{backgroundImage:`url(${IMAGES[3].url})`}:{backgroundImage:`url(${IMAGES[4].url})`}}182                    ></div>183                }184                185            </div>186        )187    };188    return (189        <>190        {imgsLoaded ?191        <>192            <Suspense fallback={<div className="home--loading">LOADING<Spinner animation="border" variant="light"  role="status" style={{fontSize:'16px'}}/></div>}>193                <NavBar2/>194            </Suspense>...donate.jsx
Source:donate.jsx  
1import React from "react";2import PropTypes from "prop-types";3import { Grid, Row, Col } from "react-bootstrap";4import Donors from "./donors";5const DonateContent = ( { year, data, isTouchDevice } ) => (6  <Grid fluid={isTouchDevice}>7    <Row>8      <Col xs={12}>9        <h3>10          <a name="donate" href="#donate">11            <span>{I18n.t( "views.stats.year.donate_title" )}</span>12          </a>13        </h3>14        <p15          dangerouslySetInnerHTML={{16            __html: I18n.t( "views.stats.year.donate_desc_html", {17              team_url: "https://www.inaturalist.org/pages/about",18              seek_url: "https://www.inaturalist.org/pages/seek_app",19              year20            } )21          }}22        />23        <div className="support-row flex-row">24          <div className="support">25            <a26              href={`/monthly-supporters?utm_campaign=${year}-year-in-review&utm_medium=web&utm_content=button&utm_term=monthly`}27              className="btn btn-default btn-primary btn-bordered btn-donate"28            >29              <i className="fa fa-calendar" />30              { I18n.t( "give_monthly_caps" ) }31            </a>32            <a33              href={`/donate?utm_campaign=${year}-year-in-review&utm_medium=web&utm_content=button&utm_term=now`}34              className="btn btn-default btn-primary btn-bordered btn-donate"35            >36              <i className="fa fa-heart" />37              { I18n.t( "give_now_caps" ) }38            </a>39          </div>40          { data.budget && data.budget.donors && <Donors year={year} data={data.budget.donors} /> }41        </div>42      </Col>43    </Row>44  </Grid>45);46DonateContent.propTypes = {47  year: PropTypes.number,48  data: PropTypes.object,49  isTouchDevice: PropTypes.bool50};51const StoreContent = ( { isTouchDevice } ) => (52  <Grid fluid={isTouchDevice} className="store">53    <Row>54      <Col xs={12}>55        <a56          href="https://store.inaturalist.org"57          className="img-link"58        >59          <img60            alt={I18n.t( "store" )}61            src="https://static.inaturalist.org/misc/yir-inat-shirts-2020.png"62            className="img-responsive"63          />64        </a>65        <div className="prompt">66          <p>{I18n.t( "views.stats.year.store_prompt" )}</p>67          <a68            href="https://store.inaturalist.org"69            className="btn btn-default btn-donate btn-bordered"70          >71            <i className="fa fa-shopping-cart" />72            { I18n.t( "store" ) }73          </a>74        </div>75      </Col>76    </Row>77  </Grid>78);79StoreContent.propTypes = {80  isTouchDevice: PropTypes.bool81};82const DonateContent2021 = ( { forDonor, isTouchDevice, year } ) => {83  let utmTerm = "become-a-donor-today";84  let btnText = I18n.t( "become_a_donor_today_caps" );85  if ( forDonor ) {86    utmTerm = "donate-again-today";87    btnText = I18n.t( "donate_again_today_caps" );88  }89  return (90    <div className="DonateContent2021">91      <Grid fluid={isTouchDevice}>92        <Row>93          <Col xs={12}>94            <h3>95              <a name="donate" href="#donate">96                <span>{I18n.t( "yir_donate_inaturalist_needs_your_support" )}</span>97              </a>98            </h3>99            <div className="flex-row">100              <div className="donate-image" />101              <div>102                <ul>103                  <li><p>{ I18n.t( "yir_millions_of_people_used_inaturalist" ) }</p></li>104                  <li><p>{ I18n.t( "yir_generating_and_sharing" ) }</p></li>105                  <li><p>{ I18n.t( "yir_your_gift_sustains" ) }</p></li>106                </ul>107              </div>108            </div>109          </Col>110        </Row>111      </Grid>112      <a113        className="bar"114        href={`/donate?utm_campaign=${year}-year-in-review&utm_medium=web&utm_content=banner-global-bottom&utm_term=${utmTerm}`}115      >116        <span117          className="btn btn-default btn-inat btn-donate"118        >119          { btnText }120        </span>121      </a>122      <Grid fluid={isTouchDevice}>123        <Row>124          <Col xs={12}>125            <h3>126              <a name="thanks" href="#thanks">127                <span>{I18n.t( "views.stats.year.donate_title" )}</span>128              </a>129            </h3>130            <p>{ I18n.t( "yir_thank_your_for_being_generous" ) }</p>131          </Col>132        </Row>133      </Grid>134    </div>135  );136}137DonateContent2021.propTypes = {138  forDonor: PropTypes.bool,139  isTouchDevice: PropTypes.bool,140  year: PropTypes.number141};142const StoreContent2021 = ( { isTouchDevice } ) => (143  <Grid fluid={isTouchDevice} className="StoreContent2021">144    <Row>145      <Col xs={12}>146        <h3>147          <a name="store" href="#store">148            <span>{I18n.t( "check_out_the_inat_store" )}</span>149          </a>150        </h3>151        <a152          href="https://store.inaturalist.org"153          className="img-link"154        >155          <img156            alt={I18n.t( "store" )}157            src="https://static.inaturalist.org/misc/2021-yir/2021-yir-store.png"158            className="img-responsive"159          />160        </a>161      </Col>162    </Row>163  </Grid>164);165StoreContent2021.propTypes = {166  isTouchDevice: PropTypes.bool167};168const Donate = ( { forDonor, year, data } ) => {169  let storeContent;170  let donateContent;171  // https://gist.github.com/59naga/ed6714519284d36792ba172  const isTouchDevice = navigator.userAgent.match(173    /(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i174  ) !== null;175  if ( year >= 2021 ) {176    storeContent = <StoreContent2021 isTouchDevice={isTouchDevice} />;177    donateContent = <DonateContent2021 forDonor={forDonor} year={year} isTouchDevice={isTouchDevice} />;178  } else {179    storeContent = <StoreContent isTouchDevice={isTouchDevice} />;180    donateContent = <DonateContent year={year} data={data} isTouchDevice={isTouchDevice} />;181  }182  return (183    <div className="Donate">184      { storeContent }185      { donateContent }186    </div>187  );188};189Donate.propTypes = {190  forDonor: PropTypes.bool,191  year: PropTypes.number,192  data: PropTypes.object193};...test.browser.js
Source:test.browser.js  
...36	isTouchDevice = proxyquire( './../lib/browser.js', {37		'@stdlib/utils/global': getGlobal,38		'./../../is-browser': true39	});40	t.equal( isTouchDevice(), true, 'returns true' );41	t.end();42	function getGlobal() {43		return win;44	}45});46tape( 'the function returns `false` if the current environment is a touch device (no `ontouchstart` handler)', function test( t ) {47	var isTouchDevice;48	var win;49	win = {};50	isTouchDevice = proxyquire( './../lib/browser.js', {51		'@stdlib/utils/global': getGlobal,52		'./../../is-browser': true53	});54	t.equal( isTouchDevice(), false, 'returns false' );55	t.end();56	function getGlobal() {57		return win;58	}59});60tape( 'the function returns `true` if the current environment is a touch device (`DocumentTouch`)', function test( t ) {61	var isTouchDevice;62	var win;63	win = {64		'DocumentTouch': noop65	};66	win.document = new win.DocumentTouch();67	isTouchDevice = proxyquire( './../lib/browser.js', {68		'@stdlib/utils/global': getGlobal,69		'./../../is-browser': true70	});71	t.equal( isTouchDevice(), true, 'returns true' );72	t.end();73	function getGlobal() {74		return win;75	}76});77tape( 'the function returns `false` if the current environment is not a touch device (`DocumentTouch`)', function test( t ) {78	var isTouchDevice;79	var win;80	win = {81		'DocumentTouch': noop82	};83	win.document = {};84	isTouchDevice = proxyquire( './../lib/browser.js', {85		'@stdlib/utils/global': getGlobal,86		'./../../is-browser': true87	});88	t.equal( isTouchDevice(), false, 'returns false' );89	t.end();90	function getGlobal() {91		return win;92	}93});94tape( 'the function returns `true` if the current environment is a touch device (touch points detection)', function test( t ) {95	var isTouchDevice;96	var win;97	win = {98		'navigator': {99			'maxTouchPoints': 3,100			'msMaxTouchPoints': 3101		}102	};103	isTouchDevice = proxyquire( './../lib/browser.js', {104		'@stdlib/utils/global': getGlobal,105		'./../../is-browser': true106	});107	t.equal( isTouchDevice(), true, 'returns true' );108	t.end();109	function getGlobal() {110		return win;111	}112});113tape( 'the function returns `false` if the current environment is not a touch device (touch points detection)', function test( t ) {114	var isTouchDevice;115	var win;116	win = {117		'navigator': {118			'maxTouchPoints': 0,119			'msMaxTouchPoints': 0120		}121	};122	isTouchDevice = proxyquire( './../lib/browser.js', {123		'@stdlib/utils/global': getGlobal,124		'./../../is-browser': true125	});126	t.equal( isTouchDevice(), false, 'returns false' );127	t.end();128	function getGlobal() {129		return win;130	}131});132tape( 'the function returns `false` if the current environment is not a browser', function test( t ) {133	var isTouchDevice = proxyquire( './../lib/browser.js', {134		'./../../is-browser': false135	});136	t.equal( isTouchDevice(), false, 'returns false' );137	t.end();...button.js
Source:button.js  
1function Button() {};2Button.hasDeterminedIfTouchDevice = false;3Button.isTouchDevice = false;4Button.down = function(self, event) {5  event.stopPropagation();6  self.savedClassName = self.className;7  self.className += ' pressed';8  self.isTouchDown = true;9};10Button.move = function(self, event) {11  event.stopPropagation();12  if (self.isTouchDown) {13    self.className = self.savedClassName;14    self.isTouchDown = false;15  }16};17Button.up = function(self, event) {18  if (self.isTouchDown) {19    event.stopPropagation();20    self.className = self.savedClassName;21    self.isTouchDown = false;22    self.clickFunction(self);23  }24};25Button.setupDeviceType = function(isTouchDevice) {26  if (!Button.hasDeterminedIfTouchDevice) {27    Button.hasDeterminedIfTouchDevice = true;28    Button.isTouchDevice = isTouchDevice;29  }30};31Button.touchstart = function(event) {32  Button.setupDeviceType(true);33  if (Button.isTouchDevice) {34    Button.down(this, event);35  }36};37Button.touchmove = function(event) {38  Button.setupDeviceType(true);39  if (Button.isTouchDevice) {40    Button.move(this, event);41  }42};43Button.touchend = function(event) {44  Button.setupDeviceType(true);45  if (Button.isTouchDevice) {46    Button.up(this, event);47  }48};49Button.mousedown = function(event) {50  Button.setupDeviceType(false);51  if (!Button.isTouchDevice) {52    Button.down(this, event);53  }54};55Button.mousemove = function(event) {56  Button.setupDeviceType(false);57  if (!Button.isTouchDevice) {58    Button.move(this, event);59  }60};61Button.mouseup = function(event) {62  Button.setupDeviceType(false);63  if (!Button.isTouchDevice) {64    Button.up(this, event);65  }66};67Button.enable = function(button, callback) {68  if (!Button.hasDeterminedIfTouchDevice || Button.isTouchDevice) {69    button.addEventListener('touchstart', Button.touchstart);70    button.addEventListener('touchmove', Button.touchmove);71    button.addEventListener('touchend', Button.touchend);72  }73  if (!Button.hasDeterminedIfTouchDevice || !Button.isTouchDevice) {74    button.addEventListener('mousedown', Button.mousedown);75    button.addEventListener('mousemove', Button.mousemove);76    button.addEventListener('mouseup', Button.mouseup);77  }78  button.clickFunction = function(element) {79    callback(element);80  };81};82Button.disable = function(button) {83  button.removeEventListener('touchstart', Button.touchstart);84  button.removeEventListener('touchmove', Button.touchmove);85  button.removeEventListener('touchend', Button.touchend);86  button.removeEventListener('mousedown', Button.mousedown);87  button.removeEventListener('mousemove', Button.mousemove);88  button.removeEventListener('mouseup', Button.mouseup);...Flippy.js
Source:Flippy.js  
1import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';2import './styles.css';3const Flippy = React.forwardRef(({4  isFlipped: _isFlipped,5  className,6  flipDirection,7  style,8  children,9  flipOnHover,10  flipOnClick,11  onClick,12  onTouchStart,13  onMouseEnter,14  onMouseLeave,15  ...rest16}, ref) => {17  const simpleFlag = useRef({ isTouchDevice: false });18  const [isTouchDevice, setTouchDevice] = useState(false);19  const [isFlipped, setFlipped] = useState(false);20  const toggle = () => setFlipped(!isFlipped);21  useImperativeHandle(ref, () => ({ toggle }));22  const handleTouchStart = event => {23    if (!isTouchDevice) {24      simpleFlag.current.isTouchDevice = true;25      setTouchDevice(true);26    }27    onTouchStart(event);28  }29  30  const handleMouseEnter = event => {31    if (flipOnHover && !simpleFlag.current.isTouchDevice) { setFlipped(true); }32    onMouseEnter(event);33  };34  const handleMouseLeave = event => {35    if (flipOnHover && !simpleFlag.current.isTouchDevice) { setFlipped(false); }36    onMouseLeave(event);37  };38  const handleClick = event => {39    switch(true) {40      case flipOnHover && !simpleFlag.current.isTouchDevice:41      case !flipOnClick && !flipOnHover:42        break;43      default:44        setFlipped(!isFlipped);45        break;46    }47    onClick(event);48  };49  useEffect(() => {50    if (typeof _isFlipped === 'boolean' && _isFlipped !== isFlipped) {51      setFlipped(_isFlipped);52    }53  }, [_isFlipped]);54  return (55    <div56      {...rest}57      className={`flippy-container ${className || ''}`}58      style={{59        ...style60      }}61      onTouchStart={handleTouchStart}62      onMouseEnter={handleMouseEnter}63      onMouseLeave={handleMouseLeave}64      onClick={handleClick}65    >66      <div className={`flippy-cardContainer-wrapper ${flipDirection}`}>67        <div68          className={`flippy-cardContainer ${isFlipped ? 'isActive' : ''} ${isTouchDevice ? 'istouchdevice' : ''}`}69        >70          {children}71        </div>72      </div>73    </div>74  );75});76export default Flippy;77Flippy.defaultProps = {78  flipDirection: 'horizontal',79  flipOnHover: false,80  flipOnClick: true,81  isFlipped: false,82  onMouseEnter: () => {},83  onMouseLeave: () => {},84  onTouchStart: () => {},85  onClick: () => {}...isTouchDevice_spec.js
Source:isTouchDevice_spec.js  
...6  describe('with neither `window` nor `navigator`', () => {7    it('returns false', () => {8      expect(typeof window).to.equal('undefined');9      expect(typeof navigator).to.equal('undefined');10      expect(isTouchDevice()).to.equal(false);11    });12  });13  wrap()14  .withGlobal('window', () => ({}))15  .describe('with `window`', () => {16    it('returns false without `window.ontouchstart`', () => {17      expect(isTouchDevice()).to.equal(false);18    });19    wrap()20    .withOverride(() => window, 'ontouchstart', () => true)21    .it('returns true with `window.ontouchstart', () => {22      expect(isTouchDevice()).to.equal(true);23    });24  });25  wrap()26  .withGlobal('navigator', () => ({}))27  .describe('with `navigator`', () => {28    wrap()29    .withOverride(() => navigator, 'maxTouchPoints', () => {})30    .it('returns false with a falsy maxTouchPoints', () => {31      expect(isTouchDevice()).to.equal(false);32    });33    wrap()34    .withOverride(() => navigator, 'maxTouchPoints', () => 42)35    .it('returns false with a truthy maxTouchPoints', () => {36      expect(isTouchDevice()).to.equal(true);37    });38  });...Using AI Code Generation
1import { Selector } from 'testcafe';2test('My first test', async t => {3        .typeText('#developer-name', 'John Smith')4        .click('#windows')5        .click('#submit-button');6});7import { Selector } from 'testcafe';8test('My first test', async t => {9        .typeText('#developer-name', 'John Smith')10        .click('#windows')11        .click('#submit-button');12});13import { Selector } from 'testcafe';14test('My first test', async t => {15        .typeText('#developer-name', 'John Smith')16        .click('#windows')17        .click('#submit-button');18});19import { Selector } from 'testcafe';20test('My first test', async t => {21        .typeText('#developer-name', 'John Smith')22        .click('#windows')23        .click('#submit-button');24});25import { Selector } from 'testcafe';26test('My first test', async t => {27        .typeText('#developer-name', 'John Smith')28        .click('#windows')29        .click('#submit-button');30});31import { Selector } from 'testcafe';Using AI Code Generation
1import { Selector } from 'testcafe';2test('My first test', async t => {3        .typeText('#developer-name', 'John Smith')4        .click('#submit-button');5});6import { isTouchDevice } from 'testcafe-browser-tools';7test('My first test', async t => {8    if (await isTouchDevice()) {9            .click('#tried-test-cafe')10            .click('#submit-button');11    }12    else {13            .click('#macos')14            .click('#submit-button');15    }16});17import { Selector } from 'testcafe';18test('My first test', async t => {19        .typeText('#developer-name', 'John Smith')20        .click('#submit-button');21});22import { Selector } from 'testcafe';23test('My first test', async t => {24        .typeText('#developer-name', 'John Smith')25        .click('#submit-button');26});27import { Selector } from 'testcafe';28test('My first test', async t => {29        .typeText('#developer-name', 'John Smith')30        .click('#submit-button');31});32import { Selector } from 'testcafe';33test('My first test', async t => {34        .typeText('#developer-name', 'John Smith')35        .click('#submit-button');36});37import { Selector } from 'testcafe';38test('My first testUsing AI Code Generation
1import { Selector } from 'testcafe';2test('My first test', async t => {3        .typeText('#developer-name', 'John Smith')4        .click('#submit-button');5    await t.expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');6});7import { Selector } from 'testcafe';8test('My first test', async t => {9        .typeText('#developer-name', 'John Smith')10        .click('#submit-button');11    await t.expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');12});13import { Selector } from 'testcafe';14test('My first test', async t => {15        .typeText('#developer-name', 'John Smith')16        .click('#submit-button');17    await t.expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');18});19import { Selector } from 'testcafe';20test('My first test', async t => {21        .typeText('#developer-name', 'John Smith')22        .click('#submit-button');23    await t.expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');24});25import { Selector } from 'testcafe';Using AI Code Generation
1import { isTouchDevice } from 'testcafe-browser-tools';2test('My Test', async t => {3    if (await isTouchDevice()) {4            .click('#tried-test-cafe')5            .click('#macos');6    } else {7            .click('#windows')8            .click('#tried-test-cafe');9    }10});11import { isTouchDevice } from 'testcafe-browser-tools';12test('My Test', async t => {13    if (await isTouchDevice()) {14            .click('#tried-test-cafe')15            .click('#macos');16    } else {17            .click('#windows')18            .click('#tried-test-cafe');19    }20});21import { isTouchDevice } from 'testcafe-browser-tools';22test('My Test', async t => {23    if (await isTouchDevice()) {24            .click('#tried-test-cafe')25            .click('#macos');26    } else {27            .click('#windows')28            .click('#tried-test-cafe');29    }30});31import { isTouchDevice } from 'testcafe-browser-tools';32test('My Test', async t => {33    if (await isTouchDevice()) {34            .click('#tried-test-cafe')35            .click('#macos');36    } else {37            .click('#windows')38            .click('#tried-test-cafe');39    }40});41import { isTouchDevice } from 'testcafe-browser-tools';Using AI Code Generation
1import { Selector } from 'testcafe';2test('My first test', async t => {3});4import { Selector } from 'testcafe';5test('My first test', async t => {6});7import { Selector } from 'testcafe';8import { isTouchDevice } from 'testcafe-browser-provider-electron';9test('My first test', async t => {10});11import { Selector } from 'testcafe';12import { isTouchDevice } from 'testcafe-browser-provider-electron';13test('My first test', async t => {14});15import { Selector } from 'testcafe';16import { isTouchDevice } from 'testcafe-browser-provider-electron';17test('My first test', async t => {18});19import { Selector } from 'testcafe';20import { isTouchDevice } from 'testcafe-browser-provider-electron';21test('My first test', async t => {22});23import { Selector } from 'testcafe';24import { isTouchDevice } from 'testcafe-browser-provider-electron';25test('My first test', async t => {26});27import { Selector } from 'testcafe';28import { isTouchDevice } from 'testcafe-browser-provider-electron';29test('My first test', async t => {30});31import { Selector } from 'testcafe';32import { isUsing AI Code Generation
1import { Selector } from 'testcafe';2test('My test', async t => {3        .click('#tried-test-cafe')4        .wait(1000)5        .expect(Selector('#tried-test-cafe').checked).ok()6        .expect(Selector('#tried-test-cafe').exists).ok()7        .expect(Selector('#tried-test-cafe').visible).ok()8        .expect(Selector('#tried-test-cafe').focused).ok()9        .expect(Selector('#tried-test-cafe').count).eql(1)10        .expect(Selector('#tried-test-cafe').value).eql('on')11        .expect(Selector('#tried-test-cafe').with({ boundTestRun: t }).value).eql('on')12        .expect(Selector('#tried-test-cafe').with({ visibilityCheck: true, timeout: 1000 }).value).eql('on')13        .expect(Selector('#tried-test-cafe').with({ visibilityCheck: true }).value).eql('on');14});15import { Selector } from 'testcafe';16test('My test', async t => {17        .click('#tried-test-cafe')18        .wait(1000)19        .expect(Selector('#tried-test-cafe').checked).ok()20        .expect(Selector('#tried-test-cafe').exists).ok()21        .expect(Selector('#tried-test-cafe').visible).ok()22        .expect(Selector('#tried-test-cafe').focused).ok()23        .expect(Selector('#tried-test-cafe').count).eql(1)24        .expect(Selector('#tried-test-cafe').value).eql('on')25        .expect(Selector('#tried-test-cafe').with({ boundTestRun: t }).value).eql('on')26        .expect(Selector('#tried-test-cafe').with({ visibilityCheck: true, timeout: 1000 }).value).eql('on')27        .expect(SelectorUsing AI Code Generation
1import { Selector } from 'testcafe';2test('My first test', async t => {3    if (await t.eval(() => window.isTouchDevice)) {4    } else {5    }6});7import { Selector } from 'testcafe';8test('My first test', async t => {9    if (await t.eval(() => window.isTouchDevice)) {10    } else {11    }12});13    .resizeWindow(375, 667)14    .emulate({15    });16    .resizeWindow(1024, 768)17    .emulate({18    });19    .resizeWindow(375, 667)Using AI Code Generation
1import { isTouchDevice } from 'testcafe-browser-tools';2test('Touch device', async t => {3    if (await isTouchDevice()) {4        console.log('Touch device');5    }6    else {7        console.log('Not a touch device');8    }9});10{11    "scripts": {12    },13    "dependencies": {Using AI Code Generation
1await t.expect(isTouchDevice).notOk();2await t.expect(isTouchDevice).ok();3await t.expect(isTouchDevice).eql(true);4await t.expect(isTouchDevice).eql(false);5await t.expect(isTouchDevice).notEql(false);6await t.expect(isTouchDevice).notEql(true);7await t.expect(isTouchDevice).contains(true);8await t.expect(isTouchDevice).contains(false);9await t.expect(isTouchDevice).notContains(false);10await t.expect(isTouchDevice).notContains(true);11await t.expect(isTouchDevice).gt(true);12await t.expect(isTouchDevice).gt(false);13await t.expect(isTouchDevice).gte(true);14await t.expect(isTouchDevice).gte(false);15await t.expect(isTouchDevice).lt(true);16await t.expect(isTouchDevice).lt(false);17await t.expect(isTouchDevice).lte(true);18await t.expect(isTouchDevice).lte(false);19await t.expect(isTouchDevice).within(true, true);20await t.expect(isTouchDevice).within(false, false);21await t.expect(isTouchDevice).notWithin(false, false);Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
