or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-creation.mdconfiguration.mdindex.mdreact-native-features.mdstyling-theming.mdutilities.md

utilities.mddocs/

0

# Utility Functions

1

2

Helper functions for style processing, event handling, platform detection, and component utilities.

3

4

## Capabilities

5

6

### Event Handling

7

8

Utilities for composing and managing event handlers across platforms.

9

10

```typescript { .api }

11

/**

12

* Compose multiple event handlers into a single function

13

* @param original - Original event handler

14

* @param next - Next event handler to compose

15

* @returns Composed event handler that calls both functions

16

*/

17

function composeEventHandlers<T extends Function>(

18

original?: T,

19

next?: T

20

): T;

21

```

22

23

**Usage Examples:**

24

25

```typescript

26

import { composeEventHandlers, styled, View } from "@tamagui/core";

27

28

function ComposedEvents() {

29

const handlePress1 = () => console.log('First handler');

30

const handlePress2 = () => console.log('Second handler');

31

32

const composedHandler = composeEventHandlers(handlePress1, handlePress2);

33

34

return (

35

<View onPress={composedHandler}>

36

<Text>Press me - both handlers will fire</Text>

37

</View>

38

);

39

}

40

41

// Using in styled components

42

const InteractiveView = styled(View, {

43

backgroundColor: '$background',

44

padding: '$4',

45

46

variants: {

47

interactive: {

48

true: {

49

cursor: 'pointer',

50

},

51

},

52

},

53

});

54

55

function InteractiveComponent({ onPress, onCustomEvent }) {

56

const handlePress = composeEventHandlers(

57

onPress,

58

(event) => {

59

// Custom press handling

60

console.log('Custom press handling');

61

onCustomEvent?.(event);

62

}

63

);

64

65

return (

66

<InteractiveView onPress={handlePress} interactive>

67

<Text>Interactive element</Text>

68

</InteractiveView>

69

);

70

}

71

```

72

73

### Style Processing

74

75

Advanced style processing and splitting utilities for optimized rendering.

76

77

```typescript { .api }

78

/**

79

* Split component props into style and non-style properties

80

* @param props - Component props to split

81

* @param staticConfig - Component static configuration

82

* @param theme - Current theme context

83

* @param state - Component state (hover, press, focus)

84

* @param options - Processing options

85

* @returns Split styles and properties

86

*/

87

function getSplitStyles<T>(

88

props: T,

89

staticConfig: StaticConfig,

90

theme: Theme,

91

state: ComponentState,

92

options?: GetStylesOptions

93

): SplitStyles;

94

95

/**

96

* Expand shorthand CSS properties to their full forms

97

* @param styles - Style object with potential shorthands

98

* @returns Style object with expanded properties

99

*/

100

function expandStyles(styles: StyleObject): StyleObject;

101

102

/**

103

* Get expanded shorthand properties mapping

104

* @param styles - Style object to process

105

* @returns Mapping of shorthand to expanded properties

106

*/

107

function getExpandedShorthands(styles: StyleObject): Record<string, string[]>;

108

109

/**

110

* Generate atomic CSS classes and rules

111

* @param styles - Style object to convert

112

* @returns Object with CSS class names and rule definitions

113

*/

114

function getCSSStylesAtomic(styles: StyleObject): {

115

classNames: string;

116

rules: string[];

117

};

118

119

interface SplitStyles {

120

/** Non-media style properties */

121

style: StyleObject;

122

/** Generated CSS class names */

123

classNames: string;

124

/** Pseudo-state styles (hover, press, focus) */

125

pseudos: Record<string, StyleObject>;

126

/** Spacing-related styles */

127

space: StyleObject;

128

/** Whether media queries are present */

129

hasMedia: boolean;

130

}

131

132

interface GetStylesOptions {

133

/** Disable shorthand expansion */

134

disableExpandShorthands?: boolean;

135

/** How to resolve CSS variables */

136

resolveVariablesAs?: 'value' | 'variable' | 'auto';

137

}

138

139

interface ComponentState {

140

hover: boolean;

141

press: boolean;

142

focus: boolean;

143

}

144

```

145

146

**Usage Examples:**

147

148

```typescript

149

import { getSplitStyles, expandStyles } from "@tamagui/core";

150

151

// Style expansion example

152

const shorthandStyles = {

153

padding: 16,

154

margin: '8px 16px',

155

border: '1px solid red',

156

};

157

158

const expandedStyles = expandStyles(shorthandStyles);

159

// Result: {

160

// paddingTop: 16, paddingRight: 16, paddingBottom: 16, paddingLeft: 16,

161

// marginTop: '8px', marginRight: '16px', marginBottom: '8px', marginLeft: '16px',

162

// borderWidth: '1px', borderStyle: 'solid', borderColor: 'red'

163

// }

164

165

// Advanced component using style splitting

166

function CustomComponent(props) {

167

const theme = useTheme();

168

const [state, setState] = useState({ hover: false, press: false, focus: false });

169

170

const splitStyles = getSplitStyles(

171

props,

172

{ componentName: 'Custom' },

173

theme,

174

state

175

);

176

177

return (

178

<div

179

className={splitStyles.classNames}

180

style={splitStyles.style}

181

onMouseEnter={() => setState(s => ({ ...s, hover: true }))}

182

onMouseLeave={() => setState(s => ({ ...s, hover: false }))}

183

>

184

{props.children}

185

</div>

186

);

187

}

188

```

189

190

### Value Normalization

191

192

Functions for normalizing and processing style values across platforms.

193

194

```typescript { .api }

195

/**

196

* Normalize color values for cross-platform compatibility

197

* @param color - Color value in any supported format

198

* @returns Normalized color string

199

*/

200

function normalizeColor(color: any): string;

201

202

/**

203

* Normalize style values with property-specific processing

204

* @param value - Style value to normalize

205

* @param property - CSS property name for context

206

* @returns Normalized value appropriate for the property

207

*/

208

function normalizeValueWithProperty(value: any, property: string): any;

209

210

/**

211

* Normalize entire style object

212

* @param styles - Style object to normalize

213

* @returns Normalized style object

214

*/

215

function normalizeStyle(styles: StyleObject): StyleObject;

216

```

217

218

**Usage Examples:**

219

220

```typescript

221

import { normalizeColor, normalizeValueWithProperty } from "@tamagui/core";

222

223

// Color normalization

224

const color1 = normalizeColor('#ff0000'); // '#ff0000'

225

const color2 = normalizeColor('red'); // '#ff0000'

226

const color3 = normalizeColor('rgb(255,0,0)'); // '#ff0000'

227

228

// Value normalization by property

229

const width = normalizeValueWithProperty(100, 'width'); // '100px'

230

const fontSize = normalizeValueWithProperty(16, 'fontSize'); // 16

231

const margin = normalizeValueWithProperty('auto', 'margin'); // 'auto'

232

233

// Practical usage in components

234

function NormalizedButton({ color, size, ...props }) {

235

const normalizedColor = normalizeColor(color || '#007AFF');

236

const normalizedSize = normalizeValueWithProperty(size || 16, 'fontSize');

237

238

return (

239

<View

240

style={{

241

backgroundColor: normalizedColor,

242

fontSize: normalizedSize,

243

}}

244

{...props}

245

/>

246

);

247

}

248

```

249

250

### Component Property Utilities

251

252

Utilities for working with component properties and variants.

253

254

```typescript { .api }

255

/**

256

* Process component props through Tamagui's prop system

257

* @param props - Raw component props

258

* @param config - Component configuration

259

* @returns Processed props with resolved tokens and variants

260

*/

261

function useProps<T>(props: T, config?: ComponentConfig): T;

262

263

/**

264

* Merge multiple prop objects with proper precedence

265

* @param props - Array of prop objects to merge

266

* @returns Merged props object

267

*/

268

function mergeProps(...props: Record<string, any>[]): Record<string, any>;

269

270

/**

271

* Get extra configuration for component variants

272

* @param variants - Variant configuration

273

* @param props - Component props

274

* @returns Extra variant configuration

275

*/

276

function getVariantExtras(

277

variants: VariantsConfig,

278

props: Record<string, any>

279

): VariantExtras;

280

281

/**

282

* Map props to different names or transform values

283

* @param propMappings - Mapping configuration

284

* @returns Prop mapping function

285

*/

286

function propMapper(propMappings: PropMappings): (props: any) => any;

287

288

interface ComponentConfig {

289

variants?: VariantsConfig;

290

defaultVariants?: Record<string, any>;

291

accept?: Record<string, any>;

292

}

293

294

interface VariantExtras {

295

resolvedProps: Record<string, any>;

296

variantStyles: StyleObject;

297

defaultVariants: Record<string, any>;

298

}

299

300

interface PropMappings {

301

[propName: string]: string | ((value: any) => any);

302

}

303

```

304

305

### Component Detection & Validation

306

307

Utilities for detecting and validating Tamagui components.

308

309

```typescript { .api }

310

/**

311

* Check if a value is a Tamagui component

312

* @param component - Component to check

313

* @returns True if component is a Tamagui component

314

*/

315

function isTamaguiComponent(component: any): component is TamaguiComponent;

316

317

/**

318

* Check if a React element is a Tamagui element

319

* @param element - Element to check

320

* @returns True if element is created by a Tamagui component

321

*/

322

function isTamaguiElement(element: any): element is TamaguiElement;

323

324

/**

325

* Make a component compatible with Tamagui theming

326

* @param component - Component to make themeable

327

* @param config - Theming configuration

328

* @returns Themeable component

329

*/

330

function themeable<T extends React.ComponentType<any>>(

331

component: T,

332

config?: ThemeableConfig

333

): T;

334

335

interface ThemeableConfig {

336

accept?: Record<string, any>;

337

isText?: boolean;

338

}

339

```

340

341

### Platform Detection Constants

342

343

Cross-platform detection constants for conditional behavior.

344

345

```typescript { .api }

346

/** True when running on web platform */

347

declare const isWeb: boolean;

348

349

/** True when running on server (SSR) */

350

declare const isServer: boolean;

351

352

/** True when running on client */

353

declare const isClient: boolean;

354

355

/** True when running on Android platform */

356

declare const isAndroid: boolean;

357

358

/** True when running on iOS platform */

359

declare const isIos: boolean;

360

361

/** True when device supports touch */

362

declare const isTouchable: boolean;

363

364

/** True when web platform supports touch */

365

declare const isWebTouchable: boolean;

366

367

/**

368

* SSR-safe version of useLayoutEffect

369

* Uses useLayoutEffect on client, useEffect on server

370

*/

371

declare const useIsomorphicLayoutEffect: typeof React.useLayoutEffect;

372

```

373

374

**Usage Examples:**

375

376

```typescript

377

import {

378

isWeb,

379

isAndroid,

380

isIos,

381

isTouchable,

382

useIsomorphicLayoutEffect

383

} from "@tamagui/core";

384

385

function PlatformAwareComponent() {

386

useIsomorphicLayoutEffect(() => {

387

// Safe to use on both client and server

388

console.log('Layout effect');

389

}, []);

390

391

return (

392

<View style={{

393

// Platform-specific styles

394

...isWeb && { cursor: 'pointer' },

395

...isAndroid && { elevation: 4 },

396

...isIos && { shadowOpacity: 0.3 },

397

...isTouchable && { minHeight: 44 }, // Touch target size

398

}}>

399

<Text>

400

Platform: {

401

isWeb ? 'Web' :

402

isAndroid ? 'Android' :

403

isIos ? 'iOS' :

404

'Unknown'

405

}

406

</Text>

407

</View>

408

);

409

}

410

```

411

412

### Context Utilities

413

414

Utilities for working with React contexts in styled components.

415

416

```typescript { .api }

417

/**

418

* Create a styled context for component communication

419

* @param defaultValue - Default context value

420

* @returns Context provider and consumer

421

*/

422

function createStyledContext<T>(defaultValue: T): {

423

Provider: React.ComponentType<{ value: T; children: React.ReactNode }>;

424

useStyledContext: () => T;

425

};

426

427

/**

428

* Component-level context for sharing state

429

*/

430

declare const ComponentContext: React.Context<ComponentContextValue>;

431

432

/**

433

* Group context for coordinating related components

434

*/

435

declare const GroupContext: React.Context<GroupContextValue>;

436

437

interface ComponentContextValue {

438

disabled?: boolean;

439

size?: string;

440

variant?: string;

441

}

442

443

interface GroupContextValue {

444

name?: string;

445

disabled?: boolean;

446

orientation?: 'horizontal' | 'vertical';

447

}

448

```

449

450

### Debug Utilities

451

452

Development and debugging utilities.

453

454

```typescript { .api }

455

/**

456

* Setup development mode features

457

* @param options - Development configuration

458

*/

459

function setupDev(options?: DevOptions): void;

460

461

interface DevOptions {

462

/** Enable verbose logging */

463

debug?: boolean;

464

/** Enable style visualizer */

465

visualizer?: boolean;

466

/** Custom debug configuration */

467

debugConfig?: DebugConfig;

468

}

469

470

interface DebugConfig {

471

/** Log style calculations */

472

logStyles?: boolean;

473

/** Log theme changes */

474

logThemes?: boolean;

475

/** Log media query changes */

476

logMedia?: boolean;

477

}

478

```

479

480

## Advanced Utilities

481

482

### Performance Optimization

483

484

```typescript

485

// Custom hook combining multiple utilities

486

function useOptimizedComponent(props, config) {

487

const theme = useTheme();

488

const media = useMedia();

489

const processedProps = useProps(props, config);

490

491

const splitStyles = useMemo(() =>

492

getSplitStyles(processedProps, config, theme, { hover: false, press: false, focus: false }),

493

[processedProps, config, theme]

494

);

495

496

return {

497

...processedProps,

498

style: splitStyles.style,

499

className: splitStyles.classNames,

500

};

501

}

502

```

503

504

### Custom Style Processors

505

506

```typescript

507

// Creating custom style processing logic

508

function createCustomStyleProcessor(options: ProcessorOptions) {

509

return (styles: StyleObject) => {

510

const expanded = expandStyles(styles);

511

const normalized = normalizeStyle(expanded);

512

513

if (options.addPrefix) {

514

return Object.keys(normalized).reduce((acc, key) => {

515

acc[`${options.prefix}-${key}`] = normalized[key];

516

return acc;

517

}, {});

518

}

519

520

return normalized;

521

};

522

}

523

```

524

525

## Types

526

527

```typescript { .api }

528

interface StyleObject {

529

[key: string]: any;

530

}

531

532

interface StaticConfig {

533

componentName?: string;

534

variants?: VariantsConfig;

535

defaultVariants?: Record<string, any>;

536

accept?: Record<string, any>;

537

isText?: boolean;

538

isZStack?: boolean;

539

validStyles?: Record<string, boolean>;

540

}

541

542

interface VariantsConfig {

543

[variantName: string]: {

544

[variantValue: string]: StyleObject | (() => StyleObject);

545

};

546

}

547

548

interface Theme {

549

[key: string]: string | Variable;

550

}

551

552

interface Variable<T = any> {

553

key: string;

554

name: string;

555

val: T;

556

variable: string;

557

}

558

```