or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation-and-transitions.mdevent-management.mdfocus-and-accessibility.mdid-and-refs.mdindex.mdlinks-and-navigation.mdmiscellaneous-utilities.mdplatform-detection.mdprops-and-events.mdscrolling-and-layout.mdshadow-dom-support.mdstate-and-effects.mdvirtual-events-and-input.md

platform-detection.mddocs/

0

# Platform Detection

1

2

Browser and device identification utilities for conditional behavior and platform-specific features. All functions use caching for performance and return boolean values.

3

4

## Capabilities

5

6

### Apple Platform Detection

7

8

Utilities for detecting Apple devices and macOS platforms.

9

10

```typescript { .api }

11

/**

12

* Detects macOS platform

13

* @returns true if running on macOS

14

*/

15

function isMac(): boolean;

16

17

/**

18

* Detects iPhone devices

19

* @returns true if running on iPhone

20

*/

21

function isIPhone(): boolean;

22

23

/**

24

* Detects iPad devices (handles iPadOS 13+ detection)

25

* @returns true if running on iPad, including iPadOS 13+ devices

26

*/

27

function isIPad(): boolean;

28

29

/**

30

* Detects iOS devices (iPhone or iPad)

31

* @returns true if running on any iOS device

32

*/

33

function isIOS(): boolean;

34

35

/**

36

* Detects any Apple device (Mac or iOS)

37

* @returns true if running on any Apple device

38

*/

39

function isAppleDevice(): boolean;

40

```

41

42

**Usage Examples:**

43

44

```typescript

45

import { isMac, isIOS, isIPad } from "@react-aria/utils";

46

47

function PlatformSpecificComponent() {

48

const shortcutKey = isMac() ? "⌘" : "Ctrl";

49

const hasHover = !isIOS(); // iOS devices don't have true hover

50

51

return (

52

<div>

53

<p>Press {shortcutKey}+K to open search</p>

54

{hasHover && <button className="hover-effects">Hover me</button>}

55

{isIPad() && <p>iPad-specific feature available!</p>}

56

</div>

57

);

58

}

59

60

// Keyboard shortcut handling

61

function useKeyboardShortcuts() {

62

useEffect(() => {

63

const handleKeyDown = (e) => {

64

const cmdOrCtrl = isMac() ? e.metaKey : e.ctrlKey;

65

66

if (cmdOrCtrl && e.key === 'k') {

67

e.preventDefault();

68

openSearch();

69

}

70

};

71

72

window.addEventListener('keydown', handleKeyDown);

73

return () => window.removeEventListener('keydown', handleKeyDown);

74

}, []);

75

}

76

```

77

78

### Browser Detection

79

80

Utilities for detecting specific browsers and browser engines.

81

82

```typescript { .api }

83

/**

84

* Detects WebKit browsers (Safari, excluding Chrome)

85

* @returns true if running on WebKit-based browser (not Chrome)

86

*/

87

function isWebKit(): boolean;

88

89

/**

90

* Detects Chrome browser

91

* @returns true if running on Chrome browser

92

*/

93

function isChrome(): boolean;

94

95

/**

96

* Detects Firefox browser

97

* @returns true if running on Firefox browser

98

*/

99

function isFirefox(): boolean;

100

```

101

102

**Usage Examples:**

103

104

```typescript

105

import { isWebKit, isChrome, isFirefox } from "@react-aria/utils";

106

107

function BrowserSpecificBehavior() {

108

useEffect(() => {

109

// WebKit has different scrolling behavior

110

if (isWebKit()) {

111

document.body.style.webkitOverflowScrolling = 'touch';

112

}

113

114

// Chrome-specific optimizations

115

if (isChrome()) {

116

// Enable hardware acceleration for Chrome

117

document.body.style.transform = 'translateZ(0)';

118

}

119

120

// Firefox-specific handling

121

if (isFirefox()) {

122

// Firefox handles some CSS properties differently

123

document.documentElement.style.scrollBehavior = 'smooth';

124

}

125

}, []);

126

127

return <div>Browser-optimized content</div>;

128

}

129

130

// CSS-in-JS with browser detection

131

function getButtonStyles() {

132

return {

133

padding: '8px 16px',

134

borderRadius: isWebKit() ? '8px' : '4px', // Different radius for Safari

135

boxShadow: isChrome()

136

? '0 2px 4px rgba(0,0,0,0.1)'

137

: '0 1px 3px rgba(0,0,0,0.1)'

138

};

139

}

140

```

141

142

### Mobile Platform Detection

143

144

Utilities for detecting mobile platforms and devices.

145

146

```typescript { .api }

147

/**

148

* Detects Android devices

149

* @returns true if running on Android device

150

*/

151

function isAndroid(): boolean;

152

```

153

154

**Usage Examples:**

155

156

```typescript

157

import { isAndroid, isIOS } from "@react-aria/utils";

158

159

function MobileOptimizedComponent() {

160

const isMobile = isIOS() || isAndroid();

161

const touchOptimized = isMobile;

162

163

return (

164

<button

165

style={{

166

minHeight: touchOptimized ? '44px' : '32px', // Larger touch targets

167

fontSize: isAndroid() ? '16px' : '14px' // Prevent zoom on Android

168

}}

169

>

170

{isMobile ? 'Tap me' : 'Click me'}

171

</button>

172

);

173

}

174

175

// Platform-specific input handling

176

function useInputBehavior() {

177

const [inputMode, setInputMode] = useState('none');

178

179

useEffect(() => {

180

if (isIOS()) {

181

setInputMode('decimal'); // Better numeric input on iOS

182

} else if (isAndroid()) {

183

setInputMode('numeric'); // Android prefers numeric mode

184

} else {

185

setInputMode('none'); // Desktop doesn't need input mode

186

}

187

}, []);

188

189

return inputMode;

190

}

191

```

192

193

### Combined Platform Logic

194

195

Real-world examples combining multiple platform checks:

196

197

```typescript

198

import { isMac, isIOS, isAndroid, isWebKit, isChrome } from "@react-aria/utils";

199

200

function PlatformAwareComponent() {

201

// Determine if device supports true hover

202

const hasHover = !isIOS() && !isAndroid();

203

204

// Determine optimal scroll behavior

205

const scrollBehavior = useMemo(() => {

206

if (isIOS()) return 'momentum'; // iOS has native momentum scrolling

207

if (isAndroid()) return 'smooth'; // Android prefers smooth scrolling

208

return 'auto'; // Desktop default

209

}, []);

210

211

// Platform-specific event handling

212

const handleClick = useCallback((e) => {

213

// Prevent double-tap zoom on mobile

214

if (isIOS() || isAndroid()) {

215

e.preventDefault();

216

}

217

218

// Handle platform-specific actions

219

if (isMac()) {

220

// Mac-specific behavior

221

}

222

}, []);

223

224

return (

225

<div

226

onClick={handleClick}

227

style={{

228

cursor: hasHover ? 'pointer' : 'default',

229

WebkitOverflowScrolling: isIOS() ? 'touch' : undefined,

230

scrollBehavior: scrollBehavior

231

}}

232

>

233

Content optimized for {

234

isIOS() ? 'iOS' :

235

isAndroid() ? 'Android' :

236

isMac() ? 'macOS' :

237

'Desktop'

238

}

239

</div>

240

);

241

}

242

243

// Feature detection based on platform

244

function useFeatureSupport() {

245

return useMemo(() => ({

246

supportsHover: !isIOS() && !isAndroid(),

247

supportsTouch: isIOS() || isAndroid(),

248

prefersMomentumScrolling: isIOS(),

249

needsLargerTouchTargets: isIOS() || isAndroid(),

250

supportsBackdropFilter: isWebKit() || isChrome(),

251

usesCmdKey: isMac(),

252

supportsPassiveEvents: !isAndroid() // Some Android versions have issues

253

}), []);

254

}

255

```

256

257

## Performance Notes

258

259

All platform detection functions use caching internally, so multiple calls to the same function within a render cycle are optimized. The detection is performed once and cached for subsequent calls:

260

261

```typescript

262

// These calls are optimized - detection only happens once

263

const isMacPlatform = isMac();

264

const isIOSPlatform = isIOS();

265

const isMacAgain = isMac(); // Returns cached result

266

```