a tool for shared writing and social publishing

remove @react-aria/utils

+2 -2
components/Blocks/TextBlock/index.tsx
··· 1 - import { useRef, useEffect, useState } from "react"; 1 + import { useRef, useEffect, useState, useLayoutEffect } from "react"; 2 2 import { elementId } from "src/utils/elementId"; 3 3 import { baseKeymap } from "prosemirror-commands"; 4 4 import { keymap } from "prosemirror-keymap"; ··· 22 22 import { addBlueskyPostBlock, addLinkBlock } from "src/utils/addLinkBlock"; 23 23 import { BlockCommandBar } from "components/Blocks/BlockCommandBar"; 24 24 import { useEditorStates } from "src/state/useEditorState"; 25 - import { isIOS, useLayoutEffect } from "@react-aria/utils"; 26 25 import { useEntitySetContext } from "components/EntitySetProvider"; 27 26 import { useHandlePaste } from "./useHandlePaste"; 28 27 import { highlightSelectionPlugin } from "./plugins"; ··· 35 34 import { AddTiny } from "components/Icons/AddTiny"; 36 35 import { BlockDocPageSmall } from "components/Icons/BlockDocPageSmall"; 37 36 import { BlockImageSmall } from "components/Icons/BlockImageSmall"; 37 + import { isIOS } from "src/utils/isDevice"; 38 38 39 39 const HeadingStyle = { 40 40 1: "text-xl font-bold",
+1 -1
components/HelpPopover.tsx
··· 1 1 "use client"; 2 - import { isMac } from "@react-aria/utils"; 3 2 import { ShortcutKey } from "./Layout"; 4 3 import { Media } from "./Media"; 5 4 import { Popover } from "./Popover"; ··· 8 7 import { useState } from "react"; 9 8 import { ActionButton } from "components/ActionBar/ActionButton"; 10 9 import { HelpSmall } from "./Icons/HelpSmall"; 10 + import { isMac } from "src/utils/isDevice"; 11 11 12 12 export const HelpPopover = (props: { noShortcuts?: boolean }) => { 13 13 let entity_set = useEntitySetContext();
+1 -1
components/Input.tsx
··· 1 1 "use client"; 2 - import { isIOS } from "@react-aria/utils"; 3 2 import { useCallback, useEffect, useRef, type JSX } from "react"; 4 3 import { onMouseDown } from "src/utils/iosInputMouseDown"; 4 + import { isIOS } from "src/utils/isDevice"; 5 5 6 6 export function Input( 7 7 props: React.DetailedHTMLProps<
+1 -1
components/Toolbar/HighlightToolbar.tsx
··· 22 22 import { rangeHasMark } from "src/utils/prosemirror/rangeHasMark"; 23 23 24 24 import { Separator, ShortcutKey } from "components/Layout"; 25 - import { isMac } from "@react-aria/utils"; 26 25 import { ToolbarButton } from "."; 27 26 import { NestedCardThemeProvider } from "components/ThemeManager/ThemeProvider"; 28 27 import { Props } from "components/Icons/Props"; ··· 30 29 import { ArrowRightTiny } from "components/Icons/ArrowRightTiny"; 31 30 import { PaintSmall } from "components/Icons/PaintSmall"; 32 31 import { Color } from "react-aria-components"; 32 + import { isMac } from "src/utils/isDevice"; 33 33 34 34 export const HighlightButton = (props: { 35 35 lastUsedHighlight: string;
+1 -1
components/Toolbar/TextToolbar.tsx
··· 1 - import { isMac } from "@react-aria/utils"; 2 1 import { Separator, ShortcutKey } from "components/Layout"; 3 2 import { metaKey } from "src/utils/metaKey"; 4 3 import { LinkButton } from "./InlineLinkToolbar"; ··· 11 10 import { TextAlignmentButton } from "./TextAlignmentToolbar"; 12 11 import { LockBlockButton } from "./LockBlockButton"; 13 12 import { Props } from "components/Icons/Props"; 13 + import { isMac } from "src/utils/isDevice"; 14 14 15 15 export const TextToolbar = (props: { 16 16 lastUsedHighlight: string;
+37 -1
components/ViewportSizeLayout.tsx
··· 1 1 "use client"; 2 - import { isIOS, useViewportSize } from "@react-aria/utils"; 3 2 import { useEffect, useState } from "react"; 3 + import { isIOS } from "src/utils/isDevice"; 4 4 5 5 export function ViewportSizeLayout(props: { children: React.ReactNode }) { 6 6 let viewheight = useViewportSize().height; ··· 53 53 height: visualViewport?.height || window?.innerHeight, 54 54 }; 55 55 } 56 + 57 + export function useViewportSize(): { 58 + width: number; 59 + height: number; 60 + } { 61 + let [size, setSize] = useState(() => getViewportSize()); 62 + 63 + useEffect(() => { 64 + // Use visualViewport api to track available height even on iOS virtual keyboard opening 65 + let onResize = () => { 66 + setSize((size) => { 67 + let newSize = getViewportSize(); 68 + if (newSize.width === size.width && newSize.height === size.height) { 69 + return size; 70 + } 71 + return newSize; 72 + }); 73 + }; 74 + 75 + if (!visualViewport) { 76 + window.addEventListener("resize", onResize); 77 + } else { 78 + visualViewport.addEventListener("resize", onResize); 79 + } 80 + 81 + return () => { 82 + if (!visualViewport) { 83 + window.removeEventListener("resize", onResize); 84 + } else { 85 + visualViewport.removeEventListener("resize", onResize); 86 + } 87 + }; 88 + }, []); 89 + 90 + return size; 91 + }
+159 -27
package-lock.json
··· 18 18 "@atproto/xrpc": "^0.6.9", 19 19 "@mdx-js/loader": "^3.1.0", 20 20 "@mdx-js/react": "^3.1.0", 21 + "@next/bundle-analyzer": "^15.3.2", 21 22 "@next/mdx": "15.3.2", 22 23 "@radix-ui/react-dropdown-menu": "^2.1.14", 23 24 "@radix-ui/react-popover": "^1.1.13", 24 25 "@radix-ui/react-slider": "^1.3.4", 25 26 "@radix-ui/react-tooltip": "^1.2.6", 26 - "@react-aria/utils": "^3.24.1", 27 27 "@react-spring/web": "^10.0.0-beta.0", 28 28 "@rocicorp/undo": "^0.2.1", 29 29 "@supabase/ssr": "^0.3.0", ··· 31 31 "@tiptap/core": "^2.11.5", 32 32 "@types/mdx": "^2.0.13", 33 33 "@vercel/analytics": "^1.3.1", 34 - "@vercel/kv": "^1.0.1", 35 34 "@vercel/sdk": "^1.3.1", 36 35 "babel-plugin-react-compiler": "^19.1.0-rc.1", 37 36 "base64-js": "^1.5.1", ··· 790 789 "version": "1.2.0", 791 790 "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.2.0.tgz", 792 791 "integrity": "sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==" 792 + }, 793 + "node_modules/@discoveryjs/json-ext": { 794 + "version": "0.5.7", 795 + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", 796 + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", 797 + "license": "MIT", 798 + "engines": { 799 + "node": ">=10.0.0" 800 + } 793 801 }, 794 802 "node_modules/@emnapi/runtime": { 795 803 "version": "1.4.3", ··· 2518 2526 "react": ">=16" 2519 2527 } 2520 2528 }, 2529 + "node_modules/@next/bundle-analyzer": { 2530 + "version": "15.3.2", 2531 + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-15.3.2.tgz", 2532 + "integrity": "sha512-zY5O1PNKNxWEjaFX8gKzm77z2oL0cnj+m5aiqNBgay9LPLCDO13Cf+FJONeNq/nJjeXptwHFT9EMmTecF9U4Iw==", 2533 + "license": "MIT", 2534 + "dependencies": { 2535 + "webpack-bundle-analyzer": "4.10.1" 2536 + } 2537 + }, 2521 2538 "node_modules/@next/env": { 2522 2539 "version": "15.3.2", 2523 2540 "resolved": "https://registry.npmjs.org/@next/env/-/env-15.3.2.tgz", ··· 2802 2819 "engines": { 2803 2820 "node": ">=14" 2804 2821 } 2822 + }, 2823 + "node_modules/@polka/url": { 2824 + "version": "1.0.0-next.29", 2825 + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", 2826 + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", 2827 + "license": "MIT" 2805 2828 }, 2806 2829 "node_modules/@radix-ui/number": { 2807 2830 "version": "1.1.1", ··· 5958 5981 "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", 5959 5982 "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" 5960 5983 }, 5961 - "node_modules/@upstash/redis": { 5962 - "version": "1.25.1", 5963 - "resolved": "https://registry.npmjs.org/@upstash/redis/-/redis-1.25.1.tgz", 5964 - "integrity": "sha512-ACj0GhJ4qrQyBshwFgPod6XufVEfKX2wcaihsEvSdLYnY+m+pa13kGt1RXm/yTHKf4TQi/Dy2A8z/y6WUEOmlg==", 5965 - "dependencies": { 5966 - "crypto-js": "^4.2.0" 5967 - } 5968 - }, 5969 5984 "node_modules/@vercel/analytics": { 5970 5985 "version": "1.3.1", 5971 5986 "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.3.1.tgz", ··· 5984 5999 "react": { 5985 6000 "optional": true 5986 6001 } 5987 - } 5988 - }, 5989 - "node_modules/@vercel/kv": { 5990 - "version": "1.0.1", 5991 - "resolved": "https://registry.npmjs.org/@vercel/kv/-/kv-1.0.1.tgz", 5992 - "integrity": "sha512-uTKddsqVYS2GRAM/QMNNXCTuw9N742mLoGRXoNDcyECaxEXvIHG0dEY+ZnYISV4Vz534VwJO+64fd9XeSggSKw==", 5993 - "dependencies": { 5994 - "@upstash/redis": "1.25.1" 5995 - }, 5996 - "engines": { 5997 - "node": ">=14.6" 5998 6002 } 5999 6003 }, 6000 6004 "node_modules/@vercel/sdk": { ··· 6053 6057 "version": "8.3.2", 6054 6058 "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", 6055 6059 "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", 6056 - "dev": true, 6057 6060 "engines": { 6058 6061 "node": ">=0.4.0" 6059 6062 } ··· 7135 7138 "node": ">= 8" 7136 7139 } 7137 7140 }, 7138 - "node_modules/crypto-js": { 7139 - "version": "4.2.0", 7140 - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", 7141 - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" 7142 - }, 7143 7141 "node_modules/cssesc": { 7144 7142 "version": "3.0.0", 7145 7143 "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", ··· 7587 7585 "engines": { 7588 7586 "node": ">= 0.4" 7589 7587 } 7588 + }, 7589 + "node_modules/duplexer": { 7590 + "version": "0.1.2", 7591 + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", 7592 + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", 7593 + "license": "MIT" 7590 7594 }, 7591 7595 "node_modules/eastasianwidth": { 7592 7596 "version": "0.2.0", ··· 9255 9259 "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 9256 9260 "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" 9257 9261 }, 9262 + "node_modules/gzip-size": { 9263 + "version": "6.0.0", 9264 + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", 9265 + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", 9266 + "license": "MIT", 9267 + "dependencies": { 9268 + "duplexer": "^0.1.2" 9269 + }, 9270 + "engines": { 9271 + "node": ">=10" 9272 + }, 9273 + "funding": { 9274 + "url": "https://github.com/sponsors/sindresorhus" 9275 + } 9276 + }, 9258 9277 "node_modules/hanji": { 9259 9278 "version": "0.0.5", 9260 9279 "resolved": "https://registry.npmjs.org/hanji/-/hanji-0.0.5.tgz", ··· 9670 9689 "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", 9671 9690 "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", 9672 9691 "dev": true 9692 + }, 9693 + "node_modules/html-escaper": { 9694 + "version": "2.0.2", 9695 + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", 9696 + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", 9697 + "license": "MIT" 9673 9698 }, 9674 9699 "node_modules/html-void-elements": { 9675 9700 "version": "3.0.0", ··· 10159 10184 }, 10160 10185 "funding": { 10161 10186 "url": "https://github.com/sponsors/sindresorhus" 10187 + } 10188 + }, 10189 + "node_modules/is-plain-object": { 10190 + "version": "5.0.0", 10191 + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", 10192 + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", 10193 + "license": "MIT", 10194 + "engines": { 10195 + "node": ">=0.10.0" 10162 10196 } 10163 10197 }, 10164 10198 "node_modules/is-promise": { ··· 12003 12037 "url": "https://github.com/sponsors/isaacs" 12004 12038 } 12005 12039 }, 12040 + "node_modules/mrmime": { 12041 + "version": "2.0.1", 12042 + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", 12043 + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", 12044 + "license": "MIT", 12045 + "engines": { 12046 + "node": ">=10" 12047 + } 12048 + }, 12006 12049 "node_modules/ms": { 12007 12050 "version": "2.1.2", 12008 12051 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", ··· 12402 12445 "dev": true, 12403 12446 "dependencies": { 12404 12447 "wrappy": "1" 12448 + } 12449 + }, 12450 + "node_modules/opener": { 12451 + "version": "1.5.2", 12452 + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", 12453 + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", 12454 + "license": "(WTFPL OR MIT)", 12455 + "bin": { 12456 + "opener": "bin/opener-bin.js" 12405 12457 } 12406 12458 }, 12407 12459 "node_modules/optionator": { ··· 14464 14516 "is-arrayish": "^0.3.1" 14465 14517 } 14466 14518 }, 14519 + "node_modules/sirv": { 14520 + "version": "2.0.4", 14521 + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", 14522 + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", 14523 + "license": "MIT", 14524 + "dependencies": { 14525 + "@polka/url": "^1.0.0-next.24", 14526 + "mrmime": "^2.0.0", 14527 + "totalist": "^3.0.0" 14528 + }, 14529 + "engines": { 14530 + "node": ">= 10" 14531 + } 14532 + }, 14467 14533 "node_modules/sisteransi": { 14468 14534 "version": "1.0.5", 14469 14535 "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", ··· 15113 15179 "license": "MIT", 15114 15180 "engines": { 15115 15181 "node": ">=0.6" 15182 + } 15183 + }, 15184 + "node_modules/totalist": { 15185 + "version": "3.0.1", 15186 + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", 15187 + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", 15188 + "license": "MIT", 15189 + "engines": { 15190 + "node": ">=6" 15116 15191 } 15117 15192 }, 15118 15193 "node_modules/tr46": { ··· 16196 16271 "license": "BSD-2-Clause", 16197 16272 "engines": { 16198 16273 "node": ">=12" 16274 + } 16275 + }, 16276 + "node_modules/webpack-bundle-analyzer": { 16277 + "version": "4.10.1", 16278 + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", 16279 + "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", 16280 + "license": "MIT", 16281 + "dependencies": { 16282 + "@discoveryjs/json-ext": "0.5.7", 16283 + "acorn": "^8.0.4", 16284 + "acorn-walk": "^8.0.0", 16285 + "commander": "^7.2.0", 16286 + "debounce": "^1.2.1", 16287 + "escape-string-regexp": "^4.0.0", 16288 + "gzip-size": "^6.0.0", 16289 + "html-escaper": "^2.0.2", 16290 + "is-plain-object": "^5.0.0", 16291 + "opener": "^1.5.2", 16292 + "picocolors": "^1.0.0", 16293 + "sirv": "^2.0.3", 16294 + "ws": "^7.3.1" 16295 + }, 16296 + "bin": { 16297 + "webpack-bundle-analyzer": "lib/bin/analyzer.js" 16298 + }, 16299 + "engines": { 16300 + "node": ">= 10.13.0" 16301 + } 16302 + }, 16303 + "node_modules/webpack-bundle-analyzer/node_modules/commander": { 16304 + "version": "7.2.0", 16305 + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", 16306 + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", 16307 + "license": "MIT", 16308 + "engines": { 16309 + "node": ">= 10" 16310 + } 16311 + }, 16312 + "node_modules/webpack-bundle-analyzer/node_modules/ws": { 16313 + "version": "7.5.10", 16314 + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", 16315 + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", 16316 + "license": "MIT", 16317 + "engines": { 16318 + "node": ">=8.3.0" 16319 + }, 16320 + "peerDependencies": { 16321 + "bufferutil": "^4.0.1", 16322 + "utf-8-validate": "^5.0.2" 16323 + }, 16324 + "peerDependenciesMeta": { 16325 + "bufferutil": { 16326 + "optional": true 16327 + }, 16328 + "utf-8-validate": { 16329 + "optional": true 16330 + } 16199 16331 } 16200 16332 }, 16201 16333 "node_modules/whatwg-url": {
+2 -2
package.json
··· 5 5 "main": "index.js", 6 6 "scripts": { 7 7 "dev": "next dev", 8 + "generate-db-types": "supabase gen types --local > supabase/database.types.ts && drizzle-kit introspect && rm -rf ./drizzle/*.sql ./drizzle/meta", 8 9 "lexgen": "tsx ./lexicons/build.ts && lex gen-api ./lexicons/api ./lexicons/pub/leaflet/* ./lexicons/pub/leaflet/*/* ./lexicons/com/atproto/*/* --yes", 9 10 "wrangler-dev": "wrangler dev", 10 11 "start-appview-dev": "tsx --env-file='./.env.local' --watch appview/index.ts", ··· 23 24 "@atproto/xrpc": "^0.6.9", 24 25 "@mdx-js/loader": "^3.1.0", 25 26 "@mdx-js/react": "^3.1.0", 27 + "@next/bundle-analyzer": "^15.3.2", 26 28 "@next/mdx": "15.3.2", 27 29 "@radix-ui/react-dropdown-menu": "^2.1.14", 28 30 "@radix-ui/react-popover": "^1.1.13", 29 31 "@radix-ui/react-slider": "^1.3.4", 30 32 "@radix-ui/react-tooltip": "^1.2.6", 31 - "@react-aria/utils": "^3.24.1", 32 33 "@react-spring/web": "^10.0.0-beta.0", 33 34 "@rocicorp/undo": "^0.2.1", 34 35 "@supabase/ssr": "^0.3.0", ··· 36 37 "@tiptap/core": "^2.11.5", 37 38 "@types/mdx": "^2.0.13", 38 39 "@vercel/analytics": "^1.3.1", 39 - "@vercel/kv": "^1.0.1", 40 40 "@vercel/sdk": "^1.3.1", 41 41 "babel-plugin-react-compiler": "^19.1.0-rc.1", 42 42 "base64-js": "^1.5.1",
+1 -1
src/shortcuts.ts
··· 1 - import { isIOS, isMac } from "@react-aria/utils"; 2 1 import { useUIState } from "./useUIState"; 3 2 import { Replicache } from "replicache"; 4 3 import { ReplicacheMutators } from "./replicache"; 4 + import { isMac } from "./utils/isDevice"; 5 5 6 6 type Shortcut = { 7 7 metaKey?: boolean;
+1 -1
src/utils/iosInputMouseDown.ts
··· 1 - import { isIOS } from "@react-aria/utils"; 1 + import { isIOS } from "./isDevice"; 2 2 3 3 export function onMouseDown(e: React.MouseEvent<HTMLInputElement>) { 4 4 if (!isIOS()) return;
+87
src/utils/isDevice.ts
··· 1 + /* 2 + * Copyright 2020 Adobe. All rights reserved. 3 + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 + * you may not use this file except in compliance with the License. You may obtain a copy 5 + * of the License at http://www.apache.org/licenses/LICENSE-2.0 6 + * 7 + * Unless required by applicable law or agreed to in writing, software distributed under 8 + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 + * OF ANY KIND, either express or implied. See the License for the specific language 10 + * governing permissions and limitations under the License. 11 + */ 12 + 13 + function testUserAgent(re: RegExp) { 14 + if (typeof window === "undefined" || window.navigator == null) { 15 + return false; 16 + } 17 + return ( 18 + //@ts-ignore 19 + window.navigator["userAgentData"]?.brands.some( 20 + (brand: { brand: string; version: string }) => re.test(brand.brand), 21 + ) || re.test(window.navigator.userAgent) 22 + ); 23 + } 24 + 25 + function testPlatform(re: RegExp) { 26 + return typeof window !== "undefined" && window.navigator != null 27 + ? re.test( 28 + //@ts-ignore 29 + window.navigator["userAgentData"]?.platform || 30 + window.navigator.platform, 31 + ) 32 + : false; 33 + } 34 + 35 + function cached(fn: () => boolean) { 36 + if (process.env.NODE_ENV === "test") { 37 + return fn; 38 + } 39 + 40 + let res: boolean | null = null; 41 + return () => { 42 + if (res == null) { 43 + res = fn(); 44 + } 45 + return res; 46 + }; 47 + } 48 + 49 + export const isMac = cached(function () { 50 + return testPlatform(/^Mac/i); 51 + }); 52 + 53 + export const isIPhone = cached(function () { 54 + return testPlatform(/^iPhone/i); 55 + }); 56 + 57 + export const isIPad = cached(function () { 58 + return ( 59 + testPlatform(/^iPad/i) || 60 + // iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support. 61 + (isMac() && navigator.maxTouchPoints > 1) 62 + ); 63 + }); 64 + 65 + export const isIOS = cached(function () { 66 + return isIPhone() || isIPad(); 67 + }); 68 + 69 + export const isAppleDevice = cached(function () { 70 + return isMac() || isIOS(); 71 + }); 72 + 73 + export const isWebKit = cached(function () { 74 + return testUserAgent(/AppleWebKit/i) && !isChrome(); 75 + }); 76 + 77 + export const isChrome = cached(function () { 78 + return testUserAgent(/Chrome/i); 79 + }); 80 + 81 + export const isAndroid = cached(function () { 82 + return testUserAgent(/Android/i); 83 + }); 84 + 85 + export const isFirefox = cached(function () { 86 + return testUserAgent(/Firefox/i); 87 + });