diff --git a/.github/workflows/brownfield.yml b/.github/workflows/brownfield.yml index ef798151ce816a..b773b508ad3106 100644 --- a/.github/workflows/brownfield.yml +++ b/.github/workflows/brownfield.yml @@ -81,149 +81,6 @@ jobs: - 'packages/expo-dev-menu/ios/**' - 'packages/expo-manifests/ios/EXManifests/**' - jest-ubuntu-cli: - runs-on: ubuntu-24.04 - needs: analyze-changes - if: needs.analyze-changes.outputs.cli_e2e == 'true' || needs.analyze-changes.outputs.all_tests == 'true' - strategy: - fail-fast: false - matrix: - shard: [1, 2, 3] - steps: - - name: ๐Ÿ—๏ธ Setup Node - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: ๐Ÿ—๏ธ Setup Bun - uses: oven-sh/setup-bun@v2 - with: - # Version `1.x` fails due to https://github.com/oven-sh/setup-bun/issues/37 - # TODO(cedric): swap `latest` back once the issue is resolved - bun-version: latest - - - name: ๐Ÿ‘€ Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 100 - - name: โฌ‡๏ธ Fetch commits from base branch - run: git fetch origin ${{ github.event.before || github.base_ref || 'main' }}:${{ github.event.before || github.base_ref || 'main' }} --depth 100 - if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' - - - name: ๐Ÿ”Ž Find Yarn Cache - id: yarn-cache - run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - shell: bash - - name: โ™ป๏ธ Restore Yarn Cache - uses: actions/cache@v4 - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - name: ๐Ÿงถ Install node modules in root dir - run: yarn install --prefer-offline --frozen-lockfile - env: - YARN_IGNORE_SCRIPTS: 'true' - - - name: ๐Ÿ‘ท Build Expo CLI - run: yarn workspace @expo/cli prepare - - - name: ๐Ÿ‘ท Build Create Expo CLI - run: yarn workspace create-expo build:prod - - - name: ๐Ÿ‘ท Build Expo Brownfield - run: yarn workspace expo-brownfield prepare - - - name: ๐Ÿ“ฆ Generate expo-brownfield tarball - run: npm pack --json - working-directory: packages/expo-brownfield - - - name: ๐Ÿ“ฆ Generate expo-template-default tarball - run: npm pack --json - working-directory: templates/expo-template-default - - - name: ๐Ÿงช E2E Test Brownfield CLI - working-directory: packages/expo-brownfield - run: yarn test:e2e-cli --testPathIgnorePatterns e2e/cli/__tests__/build-ios.test.ts --max-workers 1 --shard ${{ matrix.shard }}/${{ strategy.job-total }} - - - name: ๐Ÿงช E2E Test Brownfield Config Plugin - working-directory: packages/expo-brownfield - run: yarn test:e2e-plugin --max-workers 1 --shard ${{ matrix.shard }}/${{ strategy.job-total }} - - jest-macos-cli: - runs-on: macos-15 - needs: analyze-changes - if: needs.analyze-changes.outputs.cli_e2e == 'true' || needs.analyze-changes.outputs.all_tests == 'true' - steps: - - name: ๐Ÿ—๏ธ Setup Node - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: ๐Ÿ—๏ธ Setup Bun - uses: oven-sh/setup-bun@v2 - with: - # Version `1.x` fails due to https://github.com/oven-sh/setup-bun/issues/37 - # TODO(cedric): swap `latest` back once the issue is resolved - bun-version: latest - - - name: ๐Ÿ’Ž Setup Ruby and install gems - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true - ruby-version: 3.2.2 - - - name: ๐Ÿ’Ž Install cocoapods - run: sudo gem install cocoapods - - - name: ๐Ÿ‘€ Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 100 - - name: โฌ‡๏ธ Fetch commits from base branch - run: git fetch origin ${{ github.event.before || github.base_ref || 'main' }}:${{ github.event.before || github.base_ref || 'main' }} --depth 100 - if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' - - - name: ๐Ÿ”Ž Find Yarn Cache - id: yarn-cache - run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - shell: bash - - name: โ™ป๏ธ Restore Yarn Cache - uses: actions/cache@v4 - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - name: ๐Ÿงถ Install node modules in root dir - run: yarn install --prefer-offline --frozen-lockfile - env: - YARN_IGNORE_SCRIPTS: 'true' - - - name: ๐Ÿ‘ท Build Expo CLI - run: yarn workspace @expo/cli prepare - - - name: ๐Ÿ‘ท Build Create Expo CLI - run: yarn workspace create-expo build:prod - - - name: ๐Ÿ‘ท Build Expo Brownfield - run: yarn workspace expo-brownfield prepare - - - name: ๐Ÿ“ฆ Generate expo-brownfield tarball - run: npm pack --json - working-directory: packages/expo-brownfield - - - name: ๐Ÿ“ฆ Generate expo-template-default tarball - run: npm pack --json - working-directory: templates/expo-template-default - - - name: ๐Ÿงช E2E Test Brownfield CLI - working-directory: packages/expo-brownfield - run: yarn test:e2e-cli e2e/cli/__tests__/build-ios.test.ts - compilation-test-android: runs-on: ubuntu-24.04 needs: analyze-changes diff --git a/apps/brownfield-tester/android-integrated/app/src/main/java/dev/expo/brownfieldintegratedtester/BrownfieldTestActivity.kt b/apps/brownfield-tester/android-integrated/app/src/main/java/dev/expo/brownfieldintegratedtester/BrownfieldTestActivity.kt index f0e96d534ae7fd..377e683e2a7a96 100644 --- a/apps/brownfield-tester/android-integrated/app/src/main/java/dev/expo/brownfieldintegratedtester/BrownfieldTestActivity.kt +++ b/apps/brownfield-tester/android-integrated/app/src/main/java/dev/expo/brownfieldintegratedtester/BrownfieldTestActivity.kt @@ -14,7 +14,7 @@ import kotlin.concurrent.timerTask open class BrownfieldTestActivity : BrownfieldActivity(), DefaultHardwareBackBtnHandler { // Listeners private var messagingListenerId: String? = null - private var stateListener: Removable? = null + private var stateListeners: MutableList = mutableListOf() // Other test utils private var messageTimer: Timer? = null @@ -29,18 +29,7 @@ open class BrownfieldTestActivity : BrownfieldActivity(), DefaultHardwareBackBtn showToast(message) } - // Shared state - stateListener = - BrownfieldState.subscribe("counter") { state: Any? -> - val count = state as? Double - if (count == null) { - Log.i("BrownfieldTestActivity", "Failed to parse state update as a double") - return@subscribe - } - // Return (synchronize) duplicated value to JS - BrownfieldState.set("counter-duplicated", count * 2) - } - + setupStateListeners() startMessageTimer() } @@ -50,7 +39,7 @@ open class BrownfieldTestActivity : BrownfieldActivity(), DefaultHardwareBackBtn messagingListenerId?.let { BrownfieldMessaging.removeListener(it) } stopMessageTimer() // Clean up state tests - stateListener?.remove() + stateListeners.forEach { it?.remove() } } private fun startMessageTimer() { @@ -67,6 +56,42 @@ open class BrownfieldTestActivity : BrownfieldActivity(), DefaultHardwareBackBtn } } + private fun setupStateListeners() { + stateListeners += + mutableListOf( + BrownfieldState.subscribe("number") { number -> + val cast = number as? Double + if (cast != null) { + Log.i("BrownfieldState", cast.toString()) + } + }, + BrownfieldState.subscribe("string") { string -> + val cast = string as? String + if (cast != null) { + Log.i("BrownfieldState", cast) + } + }, + BrownfieldState.subscribe("boolean") { bool -> + val cast = bool as? Boolean + if (cast != null) { + Log.i("BrownfieldState", cast.toString()) + } + }, + BrownfieldState.subscribe("array") { array -> + val cast = array as? MutableList<*> + if (cast != null) { + Log.i("BrownfieldState", cast.toString()) + } + }, + BrownfieldState.subscribe("object") { obj -> + val cast = obj as? MutableMap<*, *> + if (cast != null) { + Log.i("BrownfieldState", cast.toString()) + } + }, + ) + } + private fun stopMessageTimer() { messageTimer?.cancel() messageTimer = null @@ -97,7 +122,7 @@ open class BrownfieldTestActivity : BrownfieldActivity(), DefaultHardwareBackBtn val timeString = java.time.LocalDateTime.now() .format(java.time.format.DateTimeFormatter.ofPattern("HH:mm:ss")) - BrownfieldState.set("time", mapOf("time" to timeString)) + BrownfieldState.set("time", timeString) } override fun invokeDefaultOnBackPressed() { diff --git a/apps/brownfield-tester/expo-app/src/app/apis/state.tsx b/apps/brownfield-tester/expo-app/src/app/apis/state.tsx index d488fdb23fb409..1cafcc7ef2fa39 100644 --- a/apps/brownfield-tester/expo-app/src/app/apis/state.tsx +++ b/apps/brownfield-tester/expo-app/src/app/apis/state.tsx @@ -1,136 +1,181 @@ -import Feather from '@expo/vector-icons/Feather'; import * as ExpoBrownfield from 'expo-brownfield'; -import { StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'; -import { SafeAreaView } from 'react-native-safe-area-context'; +import { useEffect, useRef } from 'react'; +import { Button, ScrollView, StyleSheet, Text, View } from 'react-native'; import { Header } from '@/components'; const State = () => { - const [counter, setCounter] = ExpoBrownfield.useSharedState('counter', 0); - const [counterDuplicated] = ExpoBrownfield.useSharedState('counter-duplicated', 0); - const [time] = ExpoBrownfield.useSharedState('time'); - return ( - +
- {/* JS to native synchronization */} - JS to native synchronization - - setCounter((prev) => (prev ?? 0) + 1)}> - - - {String(counter)} - setCounter((prev) => (prev ?? 0) - 1)}> - - - - - - - Counter duplicated (in native): {String(counterDuplicated)} - + {/* Data types */} + + {/* Operations */} + + {/* Native -> JS synchronization */} + + {/* JS -> Native synchronization */} + + + ); +}; + +const DataTypesDemo = () => { + const [number, setNumber] = ExpoBrownfield.useSharedState('number', 0); + const [string, setString] = ExpoBrownfield.useSharedState('string', 'ex'); + const [boolean, setBoolean] = ExpoBrownfield.useSharedState('boolean', false); + const [array, setArray] = ExpoBrownfield.useSharedState('array', []); + const [object, setObject] = ExpoBrownfield.useSharedState>('object', {}); - {/* Native to JS synchronization */} - Native to JS synchronization - - Time: {time?.time ?? 'N / A'} - + return ( + + Data types + + setNumber((p) => (p ?? 0) + 1)} + /> + setString((p) => (p ?? '') + 'ex')} + /> + setBoolean((p) => !p)} + /> + setArray((p) => [...(p ?? []), 'ex', 1, 2.34, false, { a: 'b' }])} + /> + setObject({ a: 'b', c: { d: 'e', f: ['g', { h: 'i' }] } })} + /> - + ); }; -const InputDemo = () => { - const [counter] = ExpoBrownfield.useSharedState('counter'); - return ; +const DataTypesDemoItem = ({ + stateKey, + label, + text, + onPress, +}: { + stateKey: string; + label: string; + text: string; + onPress: () => void; +}) => { + return ( + + + {label} + + { + console.log('Confirmed'); + setVisible(false); + }} + onDismissPressed={() => { + console.log('Dismissed'); + setVisible(false); + }} + /> + + ); +} +``` + +## API + +```tsx +import { AlertDialog } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/basicalertdialog.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/basicalertdialog.mdx new file mode 100644 index 00000000000000..10a980d49eff6e --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/basicalertdialog.mdx @@ -0,0 +1,55 @@ +--- +title: BasicAlertDialog +description: A Jetpack Compose BasicAlertDialog component for displaying dialogs with custom content. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI BasicAlertDialog matches the official Jetpack Compose [BasicAlertDialog API](https://developer.android.com/develop/ui/compose/components/dialog) and displays a minimal dialog that accepts custom children as its content, giving you full control over the dialog layout. + +## Installation + + + +## Usage + +### Basic dialog with custom content + +```tsx BasicAlertDialogExample.tsx +import { useState } from 'react'; +import { Host, BasicAlertDialog, Button, Text, Surface, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicAlertDialogExample() { + const [visible, setVisible] = useState(false); + + return ( + + + {visible && ( + setVisible(false)}> + + + Custom Dialog + This dialog contains fully custom content defined as children. + + + + + )} + + ); +} +``` + +## API + +```tsx +import { BasicAlertDialog } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/bottomsheet.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/bottomsheet.mdx index 6001ffbce042be..a1474fa3f74c06 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/bottomsheet.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/bottomsheet.mdx @@ -1,6 +1,6 @@ --- -title: BottomSheet -description: A Jetpack Compose BottomSheet component that presents content from the bottom of the screen. +title: ModalBottomSheet +description: A Jetpack Compose ModalBottomSheet component that presents content from the bottom of the screen. sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' packageName: '@expo/ui' platforms: ['android'] @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A bottom sheet component that slides up from the bottom of the screen to present content using native Android bottom sheet behavior. +Expo UI ModalBottomSheet matches the official Jetpack Compose [Bottom Sheet API](https://developer.android.com/develop/ui/compose/components/bottom-sheets) and displays content in a modal sheet that slides up from the bottom. ## Installation @@ -19,35 +17,64 @@ A bottom sheet component that slides up from the bottom of the screen to present ## Usage - - - - - - ```tsx - import { BottomSheet } from '@expo/ui/jetpack-compose'; - - - Hello from bottom sheet! - - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/bottom-sheets) for more information. +### Basic bottom sheet + +```tsx BasicBottomSheetExample.tsx +import { useState } from 'react'; +import { Host, ModalBottomSheet, Button, Column, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicBottomSheetExample() { + const [visible, setVisible] = useState(false); + + return ( + + + {visible && ( + setVisible(false)}> + + Hello from bottom sheet! + You can add more content here. + + + + )} + + ); +} +``` + +### Full-screen bottom sheet + +```tsx FullScreenBottomSheetExample.tsx +import { useState } from 'react'; +import { Host, ModalBottomSheet, Button, Column, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function FullScreenBottomSheetExample() { + const [visible, setVisible] = useState(false); + + return ( + + + {visible && ( + setVisible(false)}> + + This sheet expands to full screen. + Add as much content as you need. + + + + )} + + ); +} +``` ## API ```tsx -import { BottomSheet } from '@expo/ui/jetpack-compose'; +import { ModalBottomSheet } from '@expo/ui/jetpack-compose'; ``` diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/box.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/box.mdx new file mode 100644 index 00000000000000..c7c038f34a1c41 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/box.mdx @@ -0,0 +1,43 @@ +--- +title: Box +description: A Jetpack Compose Box component for stacking child elements. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Box matches the official Jetpack Compose [Box](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Box) API and stacks children on top of each other with configurable content alignment. + +## Installation + + + +## Usage + +`Box` stacks children on top of each other. Use `contentAlignment` to position them within the box. + +```tsx BoxExample.tsx +import { Host, Box, Text } from '@expo/ui/jetpack-compose'; +import { size, background } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BoxExample() { + return ( + + + Centered in Box + + + ); +} +``` + +## API + +```tsx +import { Box } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/button.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/button.mdx index 742dc7eb11f155..97c3c98fa127e7 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/button.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/button.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A button component for displaying native buttons. +Expo UI Button matches the official Jetpack Compose [Button API](https://developer.android.com/develop/ui/compose/components/button) and supports variants, icons, custom colors, and shapes. ## Installation @@ -19,41 +17,51 @@ A button component for displaying native buttons. ## Usage - - - - - - ```tsx - import { Button } from '@expo/ui/jetpack-compose'; +### Basic button - +```tsx BasicButtonExample.tsx +import { Host, Button } from '@expo/ui/jetpack-compose'; - {/* Button with both leading and trailing icons */} - - ``` +export default function BasicButtonExample() { + return ( + + + + ); +} +``` + +### Button variants - - +Use the `variant` prop to change the button's appearance. Available variants are: `default`, `bordered`, `borderless`, `outlined`, and `elevated`. -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/button) for more information. +```tsx ButtonVariantsExample.tsx +import { Host, Button, Column } from '@expo/ui/jetpack-compose'; + +export default function ButtonVariantsExample() { + return ( + + + + + + + + + + ); +} +``` ## API diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/card.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/card.mdx new file mode 100644 index 00000000000000..0f8a35587db5f5 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/card.mdx @@ -0,0 +1,70 @@ +--- +title: Card +description: A Jetpack Compose Card component for displaying content in a styled container. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Card matches the official Jetpack Compose [Card API](https://developer.android.com/develop/ui/compose/components/card) and displays content inside a styled surface container with optional elevation and outline. + +## Installation + + + +## Usage + +### Basic card + +```tsx BasicCardExample.tsx +import { Host, Card, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicCardExample() { + return ( + + + This is a basic card with default styling. + + + ); +} +``` + +### Card variants + +Use the `variant` prop to switch between `'default'`, `'elevated'`, and `'outlined'` styles. + +```tsx CardVariantsExample.tsx +import { Host, Card, Text, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function CardVariantsExample() { + return ( + + + + Default card + + + Elevated card + + + Outlined card + + + + ); +} +``` + +## API + +```tsx +import { Card } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/carousel.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/carousel.mdx new file mode 100644 index 00000000000000..96c7e23798882e --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/carousel.mdx @@ -0,0 +1,131 @@ +--- +title: Carousel +description: A Jetpack Compose Carousel component for displaying scrollable collections of items. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Carousel matches the official Jetpack Compose [Carousel API](https://developer.android.com/develop/ui/compose/layouts/pager) and displays a horizontally scrollable collection of items with configurable sizing and fling behavior. + +## Installation + + + +## Usage + +### Basic carousel + +```tsx BasicCarouselExample.tsx +import { Host, Carousel, Box, Text } from '@expo/ui/jetpack-compose'; +import { size, background } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicCarouselExample() { + const items = [ + { label: 'Item 1', color: '#6200EE' }, + { label: 'Item 2', color: '#03DAC5' }, + { label: 'Item 3', color: '#FF5722' }, + { label: 'Item 4', color: '#4CAF50' }, + { label: 'Item 5', color: '#2196F3' }, + ]; + + return ( + + + {items.map(item => ( + + + {item.label} + + + ))} + + + ); +} +``` + +### MultiBrowse variant + +The `multiBrowse` variant shows a large item alongside smaller peek items, letting users see what comes next. + +```tsx MultiBrowseCarouselExample.tsx +import { Host, Carousel, Box, Text } from '@expo/ui/jetpack-compose'; +import { size, background } from '@expo/ui/jetpack-compose/modifiers'; + +export default function MultiBrowseCarouselExample() { + const colors = ['#6200EE', '#03DAC5', '#FF5722', '#4CAF50', '#2196F3']; + + return ( + + + {colors.map((color, index) => ( + + + Card {index + 1} + + + ))} + + + ); +} +``` + +### Unconstrained variant + +The `unconstrained` variant gives each item a fixed width without snapping behavior, allowing free-form scrolling. + +```tsx UnconstrainedCarouselExample.tsx +import { Host, Carousel, Box, Text } from '@expo/ui/jetpack-compose'; +import { size, background } from '@expo/ui/jetpack-compose/modifiers'; + +export default function UnconstrainedCarouselExample() { + const items = ['Photo 1', 'Photo 2', 'Photo 3', 'Photo 4', 'Photo 5']; + + return ( + + + {items.map(item => ( + + + {item} + + + ))} + + + ); +} +``` + +## API + +```tsx +import { Carousel } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/chip.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/chip.mdx index 188197e98a2eec..b1bdee5383b272 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/chip.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/chip.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A chip component for displaying compact elements that represent inputs, attributes, or actions. +Expo UI Chip matches the official Jetpack Compose [Chip API](https://developer.android.com/develop/ui/compose/components/chip) and supports assist, filter, input, and suggestion chip variants. ## Installation @@ -19,56 +17,77 @@ A chip component for displaying compact elements that represent inputs, attribut ## Usage - - - - - - ```tsx - import { Chip } from '@expo/ui/jetpack-compose'; - - // Assist chip with icon - console.log('Opening flight booking...')} - /> - - // Filter chip with selection - handleFilterToggle('Images')} - /> - - // Input chip with dismiss - handleInputDismiss('Work')} - /> - - // Suggestion chip - console.log('Searching nearby...')} - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/chip) for more information. +### Assist chip + +```tsx AssistChipExample.tsx +import { Host, Chip } from '@expo/ui/jetpack-compose'; + +export default function AssistChipExample() { + return ( + + console.log('Opening flight booking...')} + /> + + ); +} +``` + +### Filter chip + +```tsx FilterChipExample.tsx +import { useState } from 'react'; +import { Host, Chip } from '@expo/ui/jetpack-compose'; + +export default function FilterChipExample() { + const [selected, setSelected] = useState(false); + + return ( + + setSelected(!selected)} + /> + + ); +} +``` + +### Input chip + +```tsx InputChipExample.tsx +import { Host, Chip } from '@expo/ui/jetpack-compose'; + +export default function InputChipExample() { + return ( + + console.log('Dismissed Work chip')} /> + + ); +} +``` + +### Suggestion chip + +```tsx SuggestionChipExample.tsx +import { Host, Chip } from '@expo/ui/jetpack-compose'; + +export default function SuggestionChipExample() { + return ( + + console.log('Searching nearby...')} + /> + + ); +} +``` ## API diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/circularprogress.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/circularprogress.mdx index dd1a9c53358e67..05468e2d700790 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/circularprogress.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/circularprogress.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A circular progress indicator component for displaying progress in a circular format. +Expo UI CircularProgress matches the official Jetpack Compose [Progress Indicator API](https://developer.android.com/develop/ui/compose/components/progress) and displays progress in a circular format. ## Installation @@ -19,30 +17,59 @@ A circular progress indicator component for displaying progress in a circular fo ## Usage - - - - - - ```tsx - import { CircularProgress } from '@expo/ui/jetpack-compose'; +### Indeterminate progress - - ``` +When no `progress` is provided, the progress indicator displays an indeterminate spinning animation. - - +```tsx IndeterminateCircularExample.tsx +import { Host, CircularProgress } from '@expo/ui/jetpack-compose'; -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/progress) for more information. +export default function IndeterminateCircularExample() { + return ( + + + + ); +} +``` + +### Determinate progress + +Provide a `progress` value between `0` and `1` to show determinate progress. + +```tsx DeterminateCircularExample.tsx +import { Host, CircularProgress } from '@expo/ui/jetpack-compose'; + +export default function DeterminateCircularExample() { + return ( + + + + ); +} +``` + +### Wavy progress + +`CircularWavyProgress` renders a circular progress indicator with a wavy animation style. + +```tsx CircularWavyExample.tsx +import { Host, CircularWavyProgress } from '@expo/ui/jetpack-compose'; + +export default function CircularWavyExample() { + return ( + + + + ); +} +``` ## API ```tsx -import { CircularProgress } from '@expo/ui/jetpack-compose'; +import { CircularProgress, CircularWavyProgress } from '@expo/ui/jetpack-compose'; ``` + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/column.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/column.mdx new file mode 100644 index 00000000000000..4298e18e359670 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/column.mdx @@ -0,0 +1,48 @@ +--- +title: Column +description: A Jetpack Compose Column component for placing children vertically. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Column matches the official Jetpack Compose [Column](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Column) API and places children vertically with configurable arrangement and alignment. + +## Installation + + + +## Usage + +`Column` places children vertically. Use `verticalArrangement` and `horizontalAlignment` to control spacing and alignment. + +```tsx ColumnExample.tsx +import { Host, Column, Text } from '@expo/ui/jetpack-compose'; +import { fillMaxWidth, paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function ColumnExample() { + return ( + + + First + Second + Third + + + ); +} +``` + +## API + +```tsx +import { Column } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/contextmenu.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/contextmenu.mdx index bf19d2738a1906..d26e4577bdb3b7 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/contextmenu.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/contextmenu.mdx @@ -8,12 +8,10 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -> **Note:** Also known as **DropdownMenu**. +Expo UI ContextMenu matches the official Jetpack Compose [Menu API](https://developer.android.com/develop/ui/compose/components/menu) and displays a context menu when a trigger element is long-pressed or clicked. -A context menu component that displays a menu when triggered, commonly used for actions and options. +> **Note:** Also known as **DropdownMenu**. ## Installation @@ -21,51 +19,31 @@ A context menu component that displays a menu when triggered, commonly used for ## Usage - - - - - - ```tsx - import { ContextMenu } from '@expo/ui/jetpack-compose'; - - - - - - setSelectedIndex(index)} - /> - - - - - - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/menu) for more information. +### Basic context menu + +```tsx BasicContextMenuExample.tsx +import { Host, ContextMenu, Button } from '@expo/ui/jetpack-compose'; + +export default function BasicContextMenuExample() { + return ( + + + + + + + + + + + + ); +} +``` ## API diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/datetimepicker.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/datetimepicker.mdx index 08bca9c41b623a..74b33e53ca7332 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/datetimepicker.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/datetimepicker.mdx @@ -8,72 +8,88 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A date and time picker component that allows users to select dates, times, or both using native Android dialogs. +Expo UI DateTimePicker matches the official Jetpack Compose [Date Picker](https://developer.android.com/develop/ui/compose/components/datepickers) and [Time Picker](https://developer.android.com/develop/ui/compose/components/time-pickers) APIs and supports date, time, and combined selection. ## Installation -## Date time picker - - - - - - - ```tsx - import { DateTimePicker } from '@expo/ui/jetpack-compose'; - - { - setSelectedDate(date); - }} - displayedComponents='date' - initialDate={selectedDate.toISOString()} - variant='picker' - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/datepickers) for more information. - -## Time picker - - - - - - - ```tsx - import { DateTimePicker } from '@expo/ui/jetpack-compose'; - - { - setSelectedDate(date); - }} - displayedComponents='hourAndMinute' - initialDate={selectedDate.toISOString()} - variant='picker' - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/time-pickers) for more information. +## Usage + +### Date picker + +```tsx DatePickerExample.tsx +import { useState } from 'react'; +import { Host, DateTimePicker } from '@expo/ui/jetpack-compose'; + +export default function DatePickerExample() { + const [selectedDate, setSelectedDate] = useState(new Date()); + + return ( + + { + setSelectedDate(date); + }} + displayedComponents="date" + initialDate={selectedDate.toISOString()} + variant="picker" + /> + + ); +} +``` + +### Time picker + +```tsx TimePickerExample.tsx +import { useState } from 'react'; +import { Host, DateTimePicker } from '@expo/ui/jetpack-compose'; + +export default function TimePickerExample() { + const [selectedDate, setSelectedDate] = useState(new Date()); + + return ( + + { + setSelectedDate(date); + }} + displayedComponents="hourAndMinute" + initialDate={selectedDate.toISOString()} + variant="picker" + /> + + ); +} +``` + +### Input variant + +Use `variant="input"` to display the picker as a text input field instead of the default picker UI. + +```tsx InputVariantExample.tsx +import { useState } from 'react'; +import { Host, DateTimePicker } from '@expo/ui/jetpack-compose'; + +export default function InputVariantExample() { + const [selectedDate, setSelectedDate] = useState(new Date()); + + return ( + + { + setSelectedDate(date); + }} + displayedComponents="date" + initialDate={selectedDate.toISOString()} + variant="input" + /> + + ); +} +``` ## API diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/divider.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/divider.mdx new file mode 100644 index 00000000000000..9fd32de4bb9a88 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/divider.mdx @@ -0,0 +1,67 @@ +--- +title: Divider +description: A Jetpack Compose Divider component for creating visual separators. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Divider matches the official Jetpack Compose [HorizontalDivider API](https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#HorizontalDivider) and creates a thin horizontal line to visually separate content. + +## Installation + + + +## Usage + +### Basic divider + +```tsx BasicDividerExample.tsx +import { Host, Divider, Column, Text } from '@expo/ui/jetpack-compose'; + +export default function BasicDividerExample() { + return ( + + + First section + + Second section + + + ); +} +``` + +### Divider with padding modifier + +Use the `modifiers` prop to add padding around the divider. + +```tsx DividerWithPaddingExample.tsx +import { Host, Divider, Column, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function DividerWithPaddingExample() { + return ( + + + Section A + + Section B + + Section C + + + ); +} +``` + +## API + +```tsx +import { Divider } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/dockedsearchbar.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/dockedsearchbar.mdx new file mode 100644 index 00000000000000..78de7aafad86fb --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/dockedsearchbar.mdx @@ -0,0 +1,69 @@ +--- +title: DockedSearchBar +description: A Jetpack Compose DockedSearchBar component for displaying an inline search input. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI DockedSearchBar matches the official Jetpack Compose [SearchBar API](https://developer.android.com/develop/ui/compose/components/search) and displays a search input that remains anchored in its parent layout rather than expanding to full screen. + +## Installation + + + +## Usage + +### Basic docked search bar + +```tsx BasicDockedSearchBarExample.tsx +import { useState } from 'react'; +import { Host, DockedSearchBar } from '@expo/ui/jetpack-compose'; + +export default function BasicDockedSearchBarExample() { + const [query, setQuery] = useState(''); + + return ( + + + + ); +} +``` + +### With placeholder and leading icon + +Use the `DockedSearchBar.Placeholder` and `DockedSearchBar.LeadingIcon` slot components to customize the search bar appearance. + +```tsx DockedSearchBarWithSlotsExample.tsx +import { useState } from 'react'; +import { Host, DockedSearchBar, Text } from '@expo/ui/jetpack-compose'; + +export default function DockedSearchBarWithSlotsExample() { + const [query, setQuery] = useState(''); + + return ( + + + + Search items... + + + ๐Ÿ” + + + + ); +} +``` + +## API + +```tsx +import { DockedSearchBar } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/filterchip.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/filterchip.mdx new file mode 100644 index 00000000000000..cbe6322bc55465 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/filterchip.mdx @@ -0,0 +1,87 @@ +--- +title: FilterChip +description: A Jetpack Compose FilterChip component for displaying toggleable filter options. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI FilterChip matches the official Jetpack Compose [FilterChip API](https://developer.android.com/develop/ui/compose/components/chip) and displays a compact, toggleable element used to filter content. + +## Installation + + + +## Usage + +### Basic filter chip + +```tsx BasicFilterChipExample.tsx +import { useState } from 'react'; +import { Host, FilterChip } from '@expo/ui/jetpack-compose'; + +export default function BasicFilterChipExample() { + const [selected, setSelected] = useState(false); + + return ( + + setSelected(!selected)} /> + + ); +} +``` + +### With leading icon + +Use the `FilterChip.LeadingIcon` slot component to display an icon before the label. + +```tsx FilterChipWithLeadingIconExample.tsx +import { useState } from 'react'; +import { Host, FilterChip, Text } from '@expo/ui/jetpack-compose'; + +export default function FilterChipWithLeadingIconExample() { + const [selected, setSelected] = useState(false); + + return ( + + setSelected(!selected)}> + + ๐Ÿ“ท + + + + ); +} +``` + +### Disabled chip + +Set the `enabled` prop to `false` to prevent user interaction. + +```tsx DisabledFilterChipExample.tsx +import { Host, FilterChip } from '@expo/ui/jetpack-compose'; + +export default function DisabledFilterChipExample() { + return ( + + console.log('This will not fire')} + /> + + ); +} +``` + +## API + +```tsx +import { FilterChip } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/flowrow.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/flowrow.mdx new file mode 100644 index 00000000000000..4f91972f6fca11 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/flowrow.mdx @@ -0,0 +1,50 @@ +--- +title: FlowRow +description: A Jetpack Compose FlowRow component for wrapping children horizontally. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI FlowRow matches the official Jetpack Compose [FlowRow](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#FlowRow) API and arranges children in a horizontal flow that wraps to the next line when it runs out of space. + +## Installation + + + +## Usage + +`FlowRow` arranges children in a horizontal flow that wraps to the next line when it runs out of space. + +```tsx FlowRowExample.tsx +import { Host, FlowRow, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function FlowRowExample() { + const tags = ['React Native', 'Expo', 'Android', 'Jetpack Compose', 'Material 3', 'Kotlin']; + + return ( + + + {tags.map(tag => ( + {tag} + ))} + + + ); +} +``` + +## API + +```tsx +import { FlowRow } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/horizontalfloatingtoolbar.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/horizontalfloatingtoolbar.mdx new file mode 100644 index 00000000000000..9aca4fd622bf06 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/horizontalfloatingtoolbar.mdx @@ -0,0 +1,55 @@ +--- +title: HorizontalFloatingToolbar +description: A Jetpack Compose HorizontalFloatingToolbar component for displaying a floating action bar. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI HorizontalFloatingToolbar matches the official Jetpack Compose [FloatingActionButton API](https://developer.android.com/develop/ui/compose/components/floating-action-button) and displays a horizontal toolbar that floats above content, containing action buttons. + +## Installation + + + +## Usage + +### Toolbar with FloatingActionButton + +Use `IconButton` as direct children for toolbar items, and `HorizontalFloatingToolbar.FloatingActionButton` for the primary action. + +```tsx ToolbarWithFABExample.tsx +import { Host, HorizontalFloatingToolbar, IconButton, Icon } from '@expo/ui/jetpack-compose'; + +export default function ToolbarWithFABExample() { + return ( + + + console.log('Edit pressed')}> + + + console.log('Share pressed')}> + + + console.log('Add pressed')}> + + + + + ); +} +``` + +## API + +```tsx +import { HorizontalFloatingToolbar } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/host.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/host.mdx new file mode 100644 index 00000000000000..293a92ab4e0525 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/host.mdx @@ -0,0 +1,58 @@ +--- +title: Host +description: A Jetpack Compose Host component for bridging React Native and Jetpack Compose. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +The `Host` component is the bridge between React Native and Jetpack Compose. Every Jetpack Compose component from `@expo/ui/jetpack-compose` must be wrapped in a `Host` to render correctly. + +## Installation + + + +## Usage + +### Match contents + +Use the `matchContents` prop to make the `Host` size itself to fit the content. You can pass a boolean or an object to control vertical and horizontal sizing independently. + +```tsx MatchContents.tsx +import { Host, Button } from '@expo/ui/jetpack-compose'; + +export default function MatchContents() { + return ( + + + + ); +} +``` + +### With style + +Apply standard React Native styles to the `Host` wrapper. + +```tsx HostWithStyle.tsx +import { Host, Button } from '@expo/ui/jetpack-compose'; + +export default function HostWithStyle() { + return ( + + + + ); +} +``` + +## API + +```tsx +import { Host } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/icon.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/icon.mdx new file mode 100644 index 00000000000000..c3a964e8599150 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/icon.mdx @@ -0,0 +1,78 @@ +--- +title: Icon +description: A Jetpack Compose Icon component for displaying icons. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +An icon component for rendering icons in Jetpack Compose. We recommend downloading icons as XML vector drawables from [Material Symbols](https://fonts.google.com/icons), which is the standard approach for Android development. + +## Installation + + + +## Usage + +### Basic icon + +Use `require()` to load an XML vector drawable downloaded from [Material Symbols](https://fonts.google.com/icons). + +```tsx BasicIcon.tsx +import { Host, Icon } from '@expo/ui/jetpack-compose'; + +export default function BasicIcon() { + return ( + + + + ); +} +``` + +### Icon with tint color + +Use the `tintColor` prop to apply a color overlay to the icon. + +```tsx TintedIcon.tsx +import { Host, Icon } from '@expo/ui/jetpack-compose'; + +export default function TintedIcon() { + return ( + + + + ); +} +``` + +### Icon with size + +Specify a custom size in dp using the `size` prop. + +```tsx SizedIcon.tsx +import { Host, Icon } from '@expo/ui/jetpack-compose'; + +export default function SizedIcon() { + return ( + + + + ); +} +``` + +## API + +```tsx +import { Icon } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/iconbutton.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/iconbutton.mdx new file mode 100644 index 00000000000000..50ee9aea57f5d7 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/iconbutton.mdx @@ -0,0 +1,84 @@ +--- +title: IconButton +description: A Jetpack Compose IconButton component for displaying tappable icon buttons. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +An icon button component that wraps an icon in a tappable container with different visual variants. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/button#icon) for more information. + +## Installation + + + +## Usage + +### Basic icon button + +```tsx BasicIconButton.tsx +import { Host, IconButton, Icon } from '@expo/ui/jetpack-compose'; + +export default function BasicIconButton() { + return ( + + console.log('Pressed')}> + + + + ); +} +``` + +### Variants + +Use the `variant` prop to change the visual style of the button. Available variants are `'default'`, `'bordered'`, and `'outlined'`. + +```tsx IconButtonVariants.tsx +import { Host, IconButton, Icon } from '@expo/ui/jetpack-compose'; + +export default function IconButtonVariants() { + return ( + + console.log('Default')}> + + + console.log('Bordered')}> + + + console.log('Outlined')}> + + + + ); +} +``` + +### Disabled + +Set the `disabled` prop to prevent interaction. + +```tsx DisabledIconButton.tsx +import { Host, IconButton, Icon } from '@expo/ui/jetpack-compose'; + +export default function DisabledIconButton() { + return ( + + console.log('Pressed')}> + + + + ); +} +``` + +## API + +```tsx +import { IconButton } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/index.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/index.mdx index fc8c8cd05cccee..c8c6dfdd4e949a 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/index.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/index.mdx @@ -18,3 +18,19 @@ The Jetpack Compose components in `@expo/ui/jetpack-compose` allow you to build ## Installation + +## Usage + +Using a component from `@expo/ui/jetpack-compose` requires wrapping it in a [`Host`](./host) component. The `Host` is a container for Jetpack Compose views. + +```tsx +import { Host, Button } from '@expo/ui/jetpack-compose'; + +export function SaveButton() { + return ( + + + + ); +} +``` diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/lazycolumn.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/lazycolumn.mdx new file mode 100644 index 00000000000000..1747e04460086c --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/lazycolumn.mdx @@ -0,0 +1,86 @@ +--- +title: LazyColumn +description: A Jetpack Compose LazyColumn component for displaying scrollable lists. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +A lazily-loaded vertical list component that only renders visible items for efficient scrolling. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/lists) for more information. + +## Installation + + + +## Usage + +### Basic lazy column + +```tsx BasicLazyColumn.tsx +import { Host, LazyColumn, ListItem } from '@expo/ui/jetpack-compose'; + +const items = Array.from({ length: 100 }, (_, i) => `Item ${i + 1}`); + +export default function BasicLazyColumn() { + return ( + + + {items.map(item => ( + + ))} + + + ); +} +``` + +### With arrangement + +Use the `verticalArrangement` prop to control how items are spaced within the list. Pass a string value like `'spaceBetween'` or an object like `{ spacedBy: 8 }` for fixed spacing in dp. + +```tsx LazyColumnArrangement.tsx +import { Host, LazyColumn, ListItem } from '@expo/ui/jetpack-compose'; + +export default function LazyColumnArrangement() { + return ( + + + + + + + + ); +} +``` + +### With content padding + +Use the `contentPadding` prop to add padding around the list content in dp. + +```tsx LazyColumnPadding.tsx +import { Host, LazyColumn, ListItem } from '@expo/ui/jetpack-compose'; + +export default function LazyColumnPadding() { + return ( + + + + + + + + ); +} +``` + +## API + +```tsx +import { LazyColumn } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/linearprogress.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/linearprogress.mdx index ed161da49ce77c..7a837c77f9d341 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/linearprogress.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/linearprogress.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A linear progress indicator component for displaying progress in a horizontal bar format. +Expo UI LinearProgress matches the official Jetpack Compose [Progress Indicator API](https://developer.android.com/develop/ui/compose/components/progress) and displays progress in a horizontal bar format. ## Installation @@ -19,30 +17,59 @@ A linear progress indicator component for displaying progress in a horizontal ba ## Usage - - - - - - ```tsx - import { LinearProgress } from '@expo/ui/jetpack-compose'; +### Indeterminate progress - - ``` +When no `progress` is provided, the progress indicator displays an indeterminate animating bar. - - +```tsx IndeterminateLinearExample.tsx +import { Host, LinearProgress } from '@expo/ui/jetpack-compose'; -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/progress) for more information. +export default function IndeterminateLinearExample() { + return ( + + + + ); +} +``` + +### Determinate progress + +Provide a `progress` value between `0` and `1` to show determinate progress. + +```tsx DeterminateLinearExample.tsx +import { Host, LinearProgress } from '@expo/ui/jetpack-compose'; + +export default function DeterminateLinearExample() { + return ( + + + + ); +} +``` + +### Wavy progress + +`LinearWavyProgress` renders a linear progress indicator with a wavy animation style. + +```tsx LinearWavyExample.tsx +import { Host, LinearWavyProgress } from '@expo/ui/jetpack-compose'; + +export default function LinearWavyExample() { + return ( + + + + ); +} +``` ## API ```tsx -import { LinearProgress } from '@expo/ui/jetpack-compose'; +import { LinearProgress, LinearWavyProgress } from '@expo/ui/jetpack-compose'; ``` + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/listitem.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/listitem.mdx new file mode 100644 index 00000000000000..bdc4307573cd13 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/listitem.mdx @@ -0,0 +1,83 @@ +--- +title: ListItem +description: A Jetpack Compose ListItem component for displaying structured list entries. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +A list item component that follows Material Design 3 guidelines for structured list entries with headline, supporting text, and leading/trailing slots. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/lists) for more information. + +## Installation + + + +## Usage + +### Basic list item + +```tsx BasicListItem.tsx +import { Host, ListItem } from '@expo/ui/jetpack-compose'; + +export default function BasicListItem() { + return ( + + + + ); +} +``` + +### With supporting text and overline + +Use the `supportingText` prop to add a secondary line and `overlineText` for a category label above the headline. + +```tsx ListItemWithText.tsx +import { Host, ListItem } from '@expo/ui/jetpack-compose'; + +export default function ListItemWithText() { + return ( + + + + ); +} +``` + +### With leading and trailing slots + +Use `ListItem.Leading` and `ListItem.Trailing` sub-components to add content to the start and end of the list item. + +```tsx ListItemWithSlots.tsx +import { Host, ListItem, Icon } from '@expo/ui/jetpack-compose'; + +export default function ListItemWithSlots() { + return ( + + + + + + + + + + + ); +} +``` + +## API + +```tsx +import { ListItem } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/modifiers.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/modifiers.mdx new file mode 100644 index 00000000000000..d3b9d1b0d32498 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/modifiers.mdx @@ -0,0 +1,460 @@ +--- +title: Modifiers +description: Jetpack Compose layout modifiers for @expo/ui components. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Jetpack Compose modifiers allow you to customize the layout, appearance, and behavior of UI components. Modifiers are the Compose equivalent of style properties โ€” they control sizing, padding, backgrounds, interactions, and more. + +## Installation + + + +## Usage + +Modifiers are applied to components using the `modifiers` prop with an array syntax. You can combine multiple modifiers to create complex styling and behavior. Modifiers are applied in the order they appear in the array, which can affect the final result (for example, applying `padding` before `background` produces different results than the reverse). + +```tsx +import { Button, Host } from '@expo/ui/jetpack-compose'; +import { + paddingAll, + fillMaxWidth, + background, + border, + shadow, + clickable, +} from '@expo/ui/jetpack-compose/modifiers'; + +function ModifiersExample() { + return ( + + {/* Basic styling modifiers */} + + + {/* Complex combination with border and shadow */} + + + ); +} +``` + +## Padding + +Control the spacing around a component's content. + +### `paddingAll(all)` + +Applies equal padding on all four sides. + +| Parameter | Type | Description | +| --------- | -------- | -------------------- | +| `all` | `number` | Padding value in dp. | + +```tsx +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `padding(start, top, end, bottom)` + +Applies individual padding to each side. + +| Parameter | Type | Description | +| --------- | -------- | ------------------------- | +| `start` | `number` | Left/start padding in dp. | +| `top` | `number` | Top padding in dp. | +| `end` | `number` | Right/end padding in dp. | +| `bottom` | `number` | Bottom padding in dp. | + +```tsx +import { padding } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Size + +Control the dimensions of a component. + +### `size(width, height)` + +Sets exact dimensions for the component. + +| Parameter | Type | Description | +| --------- | -------- | ------------- | +| `width` | `number` | Width in dp. | +| `height` | `number` | Height in dp. | + +```tsx +import { size } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `fillMaxSize(fraction?)` + +Fills all available space in both dimensions. + +| Parameter | Type | Description | +| ---------- | -------- | ----------------------------------------------------- | +| `fraction` | `number` | Fraction of available space (0.0โ€“1.0). Default `1.0`. | + +```tsx +import { fillMaxSize } from '@expo/ui/jetpack-compose/modifiers'; + + + +``` + +### `fillMaxWidth(fraction?)` + +Fills available width. + +| Parameter | Type | Description | +| ---------- | -------- | ----------------------------------------------------- | +| `fraction` | `number` | Fraction of available width (0.0โ€“1.0). Default `1.0`. | + +```tsx +import { fillMaxWidth } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `fillMaxHeight(fraction?)` + +Fills available height. + +| Parameter | Type | Description | +| ---------- | -------- | ------------------------------------------------------ | +| `fraction` | `number` | Fraction of available height (0.0โ€“1.0). Default `1.0`. | + +### `width(value)` + +Sets an exact width. + +| Parameter | Type | Description | +| --------- | -------- | ------------ | +| `value` | `number` | Width in dp. | + +### `height(value)` + +Sets an exact height. + +| Parameter | Type | Description | +| --------- | -------- | ------------- | +| `value` | `number` | Height in dp. | + +### `wrapContentWidth(alignment?)` + +Sizes the component to wrap its content width. + +| Parameter | Type | Description | +| ----------- | -------- | ------------------------------------ | +| `alignment` | `string` | Horizontal alignment of the content. | + +### `wrapContentHeight(alignment?)` + +Sizes the component to wrap its content height. + +| Parameter | Type | Description | +| ----------- | -------- | ---------------------------------- | +| `alignment` | `string` | Vertical alignment of the content. | + +## Position + +Control the position of a component relative to its natural placement. + +### `offset(x, y)` + +Offsets the component from its natural position without affecting the layout of surrounding components. + +| Parameter | Type | Description | +| --------- | -------- | ------------------------ | +| `x` | `number` | Horizontal offset in dp. | +| `y` | `number` | Vertical offset in dp. | + +```tsx +import { offset } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Appearance + +Control the visual appearance of a component. + +### `background(color)` + +Sets the background color. + +| Parameter | Type | Description | +| --------- | -------- | ------------------------------ | +| `color` | `string` | Background color (hex string). | + +```tsx +import { background } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `border(borderWidth, borderColor)` + +Adds a border around the component. + +| Parameter | Type | Description | +| ------------- | -------- | -------------------------- | +| `borderWidth` | `number` | Border width in dp. | +| `borderColor` | `string` | Border color (hex string). | + +```tsx +import { border } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `shadow(elevation)` + +Adds an elevation shadow beneath the component. + +| Parameter | Type | Description | +| ----------- | -------- | ----------------------- | +| `elevation` | `number` | Shadow elevation in dp. | + +```tsx +import { shadow } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `alpha(alpha)` + +Controls the opacity of the component. + +| Parameter | Type | Description | +| --------- | -------- | ------------------------ | +| `alpha` | `number` | Opacity value (0.0โ€“1.0). | + +```tsx +import { alpha } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `blur(radius)` + +Applies a blur effect to the component. + +| Parameter | Type | Description | +| --------- | -------- | ------------------ | +| `radius` | `number` | Blur radius in dp. | + +```tsx +import { blur } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Transform + +Apply visual transformations to a component. + +### `rotate(degrees)` + +Rotates the component. + +| Parameter | Type | Description | +| --------- | -------- | -------------------------- | +| `degrees` | `number` | Rotation angle in degrees. | + +```tsx +import { rotate } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `zIndex(index)` + +Controls the drawing order of overlapping components. + +| Parameter | Type | Description | +| --------- | -------- | ------------ | +| `index` | `number` | Layer index. | + +```tsx +import { zIndex } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Animation + +Animate layout changes within a component. + +### `animateContentSize(dampingRatio?, stiffness?)` + +Animates size changes of the component's content using a spring animation. + +| Parameter | Type | Description | +| -------------- | -------- | ------------------------------------------- | +| `dampingRatio` | `number` | Spring damping ratio. Controls bounciness. | +| `stiffness` | `number` | Spring stiffness. Controls animation speed. | + +```tsx +import { animateContentSize } from '@expo/ui/jetpack-compose/modifiers'; + + + +``` + +## Layout + +Control how a component is sized and positioned within its parent container. + +### `weight(weight)` + +Assigns a flexible weight to a component inside a `Row` or `Column`, distributing available space proportionally among weighted children. + +| Parameter | Type | Description | +| --------- | -------- | -------------- | +| `weight` | `number` | Weight factor. | + +```tsx +import { weight } from '@expo/ui/jetpack-compose/modifiers'; + +// In a Row, the first button takes 2/3 and the second takes 1/3 + + +``` + +### `align(alignment)` + +Sets the alignment of the component within its parent container. + +| Parameter | Type | Description | +| ----------- | -------- | ------------------------------- | +| `alignment` | `string` | Alignment within the container. | + +### `matchParentSize()` + +Sizes the component to match the size of its parent `Box`. Unlike `fillMaxSize`, this does not affect the parent's measurement. + +```tsx +import { matchParentSize } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Interaction + +Add user interaction handlers to a component. + +### `clickable(handler)` + +Makes the component respond to click events. + +| Parameter | Type | Description | +| --------- | ------------ | -------------------------- | +| `handler` | `() => void` | Callback invoked on click. | + +```tsx +import { clickable } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `selectable(selected, handler)` + +Makes the component selectable, similar to a radio button. + +| Parameter | Type | Description | +| ---------- | ------------ | ---------------------------------------------- | +| `selected` | `boolean` | Whether the component is currently selected. | +| `handler` | `() => void` | Callback invoked when selection state changes. | + +```tsx +import { selectable } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Clipping + +Clip a component's content to a specific shape. + +### `clip(shape)` + +Clips the component to the given shape. Content outside the shape boundary is not drawn. + +| Parameter | Type | Description | +| --------- | ------- | --------------------- | +| `shape` | `Shape` | The shape to clip to. | + +#### Available shapes + +| Shape | Description | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Shapes.Rectangle` | A rectangle with no rounded corners. | +| `Shapes.Circle` | A perfect circle. | +| `Shapes.RoundedCorner(radius)` | A rectangle with uniform rounded corners. Pass a `number` for equal radius or an object `{ topStart, topEnd, bottomStart, bottomEnd }` for individual corner radii. | +| `Shapes.CutCorner(radius)` | A rectangle with cut (chamfered) corners. Accepts the same radius options as `RoundedCorner`. | +| `Shapes.Material.Cookie4Sided` | Material Design cookie shape with 4 sides. | +| `Shapes.Material.Cookie6Sided` | Material Design cookie shape with 6 sides. | + +```tsx +import { clip } from '@expo/ui/jetpack-compose/modifiers'; +import { Shapes } from '@expo/ui/jetpack-compose/modifiers'; + +// Circular clipping + + +// Rounded corners with uniform radius + + +// Rounded corners with individual radii + + +// Cut corners + +``` + +## Utility + +### `testID(tag)` + +Assigns a test identifier to the component for use in UI testing. + +| Parameter | Type | Description | +| --------- | -------- | ------------ | +| `tag` | `string` | The test ID. | + +```tsx +import { testID } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## API + +{/* prettier-ignore */} +```tsx +import { paddingAll, padding, size, fillMaxWidth, background, clickable, clip, Shapes } from '@expo/ui/jetpack-compose/modifiers'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/picker.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/picker.mdx index 521663377c4d33..bdeef8ee236c80 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/picker.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/picker.mdx @@ -8,72 +8,93 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A picker component that allows users to select from a list of options with different display styles. +Expo UI Picker matches the official Jetpack Compose [Segmented Button](https://developer.android.com/develop/ui/compose/components/segmented-button) and [Radio Button](https://developer.android.com/develop/ui/compose/components/radio-button) APIs and supports segmented and radio picker variants. ## Installation -## Radio picker - - - - - - - ```tsx - import { Picker } from '@expo/ui/jetpack-compose'; - - { - setSelectedIndex(index); - }} - variant="radio" - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/radio-button) for more information. - -## Segmented picker - - - - - - - ```tsx - import { Picker } from '@expo/ui/jetpack-compose'; - - { - setSelectedIndex(index); - }} - variant="segmented" - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/segmented-button) for more information. +## Usage + +### Segmented picker + +Use the `variant="segmented"` prop to display a segmented button group. + +```tsx SegmentedPickerExample.tsx +import { useState } from 'react'; +import { Host, Picker } from '@expo/ui/jetpack-compose'; + +export default function SegmentedPickerExample() { + const [selectedIndex, setSelectedIndex] = useState(0); + + return ( + + { + setSelectedIndex(index); + }} + variant="segmented" + /> + + ); +} +``` + +### Radio picker + +Use the `variant="radio"` prop to display a list of radio buttons. + +```tsx RadioPickerExample.tsx +import { useState } from 'react'; +import { Host, Picker } from '@expo/ui/jetpack-compose'; + +export default function RadioPickerExample() { + const [selectedIndex, setSelectedIndex] = useState(0); + + return ( + + { + setSelectedIndex(index); + }} + variant="radio" + /> + + ); +} +``` + +### Picker with custom color + +Use the `color` prop to customize the picker's accent color. + +```tsx CustomColorPickerExample.tsx +import { useState } from 'react'; +import { Host, Picker } from '@expo/ui/jetpack-compose'; + +export default function CustomColorPickerExample() { + const [selectedIndex, setSelectedIndex] = useState(0); + + return ( + + { + setSelectedIndex(index); + }} + variant="segmented" + color="#6200EE" + /> + + ); +} +``` ## API diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/pulltorefreshbox.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/pulltorefreshbox.mdx new file mode 100644 index 00000000000000..559598a5a9f44c --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/pulltorefreshbox.mdx @@ -0,0 +1,58 @@ +--- +title: PullToRefreshBox +description: A Jetpack Compose PullToRefreshBox component for pull-to-refresh interactions. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +A pull-to-refresh container that wraps scrollable content and provides a standard refresh indicator when pulled. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/layouts/adaptive/support-different-screen-sizes) for more information. + +## Installation + + + +## Usage + +### Basic pull to refresh + +```tsx BasicPullToRefresh.tsx +import { useState, useCallback } from 'react'; +import { Host, PullToRefreshBox, LazyColumn, ListItem } from '@expo/ui/jetpack-compose'; + +export default function BasicPullToRefresh() { + const [refreshing, setRefreshing] = useState(false); + + const onRefresh = useCallback(() => { + setRefreshing(true); + setTimeout(() => { + setRefreshing(false); + }, 2000); + }, []); + + return ( + + + + + + + + + + + + ); +} +``` + +## API + +```tsx +import { PullToRefreshBox } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/radiobutton.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/radiobutton.mdx new file mode 100644 index 00000000000000..1254fb258a49ce --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/radiobutton.mdx @@ -0,0 +1,87 @@ +--- +title: RadioButton +description: A Jetpack Compose RadioButton component for single-selection controls. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +A radio button component for selecting a single option from a set. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/radio-button) for more information. + +## Installation + + + +## Usage + +### Basic radio button + +```tsx BasicRadioButton.tsx +import { useState } from 'react'; +import { Host, RadioButton } from '@expo/ui/jetpack-compose'; + +export default function BasicRadioButton() { + const [selected, setSelected] = useState(false); + + return ( + + setSelected(!selected)} /> + + ); +} +``` + +### Radio button group + +Combine multiple `RadioButton` components to create a single-selection group. + +```tsx RadioButtonGroup.tsx +import { useState } from 'react'; +import { Host, Column, RadioButton, ListItem } from '@expo/ui/jetpack-compose'; + +export default function RadioButtonGroup() { + const [selectedOption, setSelectedOption] = useState('option1'); + + return ( + + + setSelectedOption('option1')}> + + setSelectedOption('option1')} + /> + + + setSelectedOption('option2')}> + + setSelectedOption('option2')} + /> + + + setSelectedOption('option3')}> + + setSelectedOption('option3')} + /> + + + + + ); +} +``` + +## API + +```tsx +import { RadioButton } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/row.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/row.mdx new file mode 100644 index 00000000000000..45e03635187a5c --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/row.mdx @@ -0,0 +1,48 @@ +--- +title: Row +description: A Jetpack Compose Row component for placing children horizontally. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Row matches the official Jetpack Compose [Row](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Row) API and places children horizontally with configurable arrangement and alignment. + +## Installation + + + +## Usage + +`Row` places children horizontally. Use `horizontalArrangement` and `verticalAlignment` to control spacing and alignment. + +```tsx RowExample.tsx +import { Host, Row, Text } from '@expo/ui/jetpack-compose'; +import { fillMaxWidth, height } from '@expo/ui/jetpack-compose/modifiers'; + +export default function RowExample() { + return ( + + + Item 1 + Item 2 + Item 3 + + + ); +} +``` + +## API + +```tsx +import { Row } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/searchbar.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/searchbar.mdx new file mode 100644 index 00000000000000..e62c2248d751dc --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/searchbar.mdx @@ -0,0 +1,64 @@ +--- +title: SearchBar +description: A Jetpack Compose SearchBar component for search input functionality. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI SearchBar matches the official Jetpack Compose [Search](https://developer.android.com/develop/ui/compose/components/search) API and provides a search input with support for placeholder text and expanded full-screen search. + +## Installation + + + +## Usage + +### Basic search bar + +```tsx BasicSearchBarExample.tsx +import { useState } from 'react'; +import { Host, SearchBar } from '@expo/ui/jetpack-compose'; + +export default function BasicSearchBarExample() { + const [query, setQuery] = useState(''); + + return ( + + setQuery(searchText)} /> + + ); +} +``` + +### Search bar with placeholder + +Use the `SearchBar.Placeholder` sub-component to display hint text when the search field is empty. + +```tsx SearchBarPlaceholderExample.tsx +import { useState } from 'react'; +import { Host, SearchBar } from '@expo/ui/jetpack-compose'; + +export default function SearchBarPlaceholderExample() { + const [query, setQuery] = useState(''); + + return ( + + setQuery(searchText)}> + Search items... + + + ); +} +``` + +## API + +```tsx +import { SearchBar } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/shape.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/shape.mdx new file mode 100644 index 00000000000000..3ddb0f9664fcb3 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/shape.mdx @@ -0,0 +1,114 @@ +--- +title: Shape +description: A Jetpack Compose Shape component for drawing geometric shapes. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Shape matches the official Jetpack Compose [Shapes](https://developer.android.com/develop/ui/compose/graphics/draw/shapes) API and provides a set of sub-components for drawing geometric shapes such as stars, circles, rectangles, pills, and polygons. + +## Installation + + + +## Usage + +### Basic shapes + +Render common shapes using the `Shape` sub-components. + +```tsx BasicShapesExample.tsx +import { Host, Shape, Row } from '@expo/ui/jetpack-compose'; +import { size } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicShapesExample() { + return ( + + + + + + + + + ); +} +``` + +### Shapes with rounded corners + +Use `cornerRounding` and `smoothing` to customize the appearance of shapes. + +```tsx RoundedShapesExample.tsx +import { Host, Shape, Row } from '@expo/ui/jetpack-compose'; +import { size } from '@expo/ui/jetpack-compose/modifiers'; + +export default function RoundedShapesExample() { + return ( + + + + + + + ); +} +``` + +### Polygon and star variants + +Use `verticesCount` and `innerRadius` to control the shape geometry. + +```tsx PolygonShapesExample.tsx +import { Host, Shape, Row } from '@expo/ui/jetpack-compose'; +import { size } from '@expo/ui/jetpack-compose/modifiers'; + +export default function PolygonShapesExample() { + return ( + + + + + + + + ); +} +``` + +## API + +```tsx +import { Shape } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/slider.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/slider.mdx index ccbf3bf914aff9..eada5c39d07aba 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/slider.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/slider.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A slider component that allows users to select a value from a continuous range by dragging a thumb along a track. +Expo UI Slider matches the official Jetpack Compose [Slider API](https://developer.android.com/develop/ui/compose/components/slider) and allows selecting values from a bounded range. ## Installation @@ -19,31 +17,60 @@ A slider component that allows users to select a value from a continuous range b ## Usage - - - - - - ```tsx - import { Slider } from '@expo/ui/jetpack-compose'; - - { - setValue(value); - }} - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/slider) for more information. +### Basic slider + +```tsx BasicSliderExample.tsx +import { useState } from 'react'; +import { Host, Slider } from '@expo/ui/jetpack-compose'; + +export default function BasicSliderExample() { + const [value, setValue] = useState(0.5); + + return ( + + + + ); +} +``` + +### Slider with custom range + +Use the `min` and `max` props to define the slider's value range. + +```tsx CustomRangeSliderExample.tsx +import { useState } from 'react'; +import { Host, Slider } from '@expo/ui/jetpack-compose'; + +export default function CustomRangeSliderExample() { + const [value, setValue] = useState(50); + + return ( + + + + ); +} +``` + +### Slider with steps + +Use the `steps` prop to define discrete increments. Set `steps` to `0` for continuous values. + +```tsx SteppedSliderExample.tsx +import { useState } from 'react'; +import { Host, Slider } from '@expo/ui/jetpack-compose'; + +export default function SteppedSliderExample() { + const [value, setValue] = useState(0); + + return ( + + + + ); +} +``` ## API diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/spacer.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/spacer.mdx new file mode 100644 index 00000000000000..46abec5551ce85 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/spacer.mdx @@ -0,0 +1,68 @@ +--- +title: Spacer +description: A Jetpack Compose Spacer component for adding flexible space between elements. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Spacer matches the official Jetpack Compose [Spacer](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Spacer) API and is used to add flexible or fixed-size space between elements in a layout. + +## Installation + + + +## Usage + +### Spacer with weight + +Use the `weight()` modifier to make the spacer fill available space proportionally within a `Row` or `Column`. + +```tsx SpacerWeightExample.tsx +import { Host, Row, Spacer, Text } from '@expo/ui/jetpack-compose'; +import { fillMaxWidth, weight } from '@expo/ui/jetpack-compose/modifiers'; + +export default function SpacerWeightExample() { + return ( + + + Left + + Right + + + ); +} +``` + +### Spacer with fixed size + +Use a `height` or `width` modifier to create a spacer with a fixed dimension. + +```tsx SpacerFixedSizeExample.tsx +import { Host, Column, Spacer, Text } from '@expo/ui/jetpack-compose'; +import { height } from '@expo/ui/jetpack-compose/modifiers'; + +export default function SpacerFixedSizeExample() { + return ( + + + Above + + Below (24dp gap) + + + ); +} +``` + +## API + +```tsx +import { Spacer } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/surface.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/surface.mdx new file mode 100644 index 00000000000000..baafb447d46aec --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/surface.mdx @@ -0,0 +1,90 @@ +--- +title: Surface +description: A Jetpack Compose Surface component for styled content containers. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Surface matches the official Jetpack Compose [Surface](https://developer.android.com/develop/ui/compose/components/surfaces) API and provides a container that applies Material Design surface styling including color, elevation, and content color. + +## Installation + + + +## Usage + +### Basic surface + +```tsx BasicSurfaceExample.tsx +import { Host, Surface, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicSurfaceExample() { + return ( + + + Content on a surface + + + ); +} +``` + +### Surface with elevation + +Use `tonalElevation` and `shadowElevation` to control the visual depth of the surface. + +```tsx SurfaceElevationExample.tsx +import { Host, Surface, Column, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function SurfaceElevationExample() { + return ( + + + + Low elevation + + + High elevation + + + + ); +} +``` + +### Surface with custom colors + +Use the `color` and `contentColor` props to override the default Material theme colors. + +```tsx SurfaceCustomColorsExample.tsx +import { Host, Surface, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function SurfaceCustomColorsExample() { + return ( + + + Custom colored surface + + + ); +} +``` + +## API + +```tsx +import { Surface } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/switch.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/switch.mdx index 0a7795c5c78aba..29353f9ccc0d6b 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/switch.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/switch.mdx @@ -8,78 +8,89 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A switch component that provides toggle functionality with different visual styles. +Expo UI Switch matches the official Jetpack Compose [Switch](https://developer.android.com/develop/ui/compose/components/switch) and [Checkbox](https://developer.android.com/develop/ui/compose/components/checkbox) APIs and supports switch, checkbox, and button variants. ## Installation -## Toggle switch - -> **Note:** also known as **Toggle**. - - - - - - - - ```tsx - import { Switch } from '@expo/ui/jetpack-compose'; - - { - setChecked(checked); - }} - color="#ff0000" - label="Play music" - variant="switch" - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/switch) for more information. - -## Checkbox - - - - - - - - ```tsx - import { Switch } from '@expo/ui/jetpack-compose'; - - { - setChecked(checked); - }} - label="Play music" - color="#ff0000" - variant="checkbox" - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/checkbox) for more information. +## Usage + +### Toggle switch + +Use the `variant="switch"` prop to display a standard toggle switch. + +```tsx ToggleSwitchExample.tsx +import { useState } from 'react'; +import { Host, Switch } from '@expo/ui/jetpack-compose'; + +export default function ToggleSwitchExample() { + const [checked, setChecked] = useState(false); + + return ( + + + + ); +} +``` + +### Checkbox + +Use the `variant="checkbox"` prop to display a checkbox control. + +```tsx CheckboxExample.tsx +import { useState } from 'react'; +import { Host, Switch } from '@expo/ui/jetpack-compose'; + +export default function CheckboxExample() { + const [checked, setChecked] = useState(false); + + return ( + + + + ); +} +``` + +### Button variant + +Use the `variant="button"` prop to display a toggle button. + +```tsx ButtonVariantExample.tsx +import { useState } from 'react'; +import { Host, Switch } from '@expo/ui/jetpack-compose'; + +export default function ButtonVariantExample() { + const [checked, setChecked] = useState(false); + + return ( + + + + ); +} +``` ## API diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/text.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/text.mdx new file mode 100644 index 00000000000000..fbbabc9b231819 --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/text.mdx @@ -0,0 +1,107 @@ +--- +title: Text +description: A Jetpack Compose Text component for displaying styled text. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Text matches the official Jetpack Compose [Text styling](https://developer.android.com/develop/ui/compose/text/style-text) API and displays text with Material 3 typography styles, custom fonts, and text formatting options. + +## Installation + + + +## Usage + +### Basic text + +```tsx BasicTextExample.tsx +import { Host, Text } from '@expo/ui/jetpack-compose'; + +export default function BasicTextExample() { + return ( + + Hello, world! + + ); +} +``` + +### Typography styles + +Use the `style` prop with `typography` to apply Material 3 typography presets. + +```tsx TypographyExample.tsx +import { Host, Text, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function TypographyExample() { + return ( + + + Display Large + Headline Medium + Body Small + Label Large + + + ); +} +``` + +### Text with maxLines and overflow + +Control text truncation with `maxLines` and `overflow`. + +```tsx TextOverflowExample.tsx +import { Host, Text } from '@expo/ui/jetpack-compose'; +import { width } from '@expo/ui/jetpack-compose/modifiers'; + +export default function TextOverflowExample() { + return ( + + + This is a long paragraph of text that will be truncated after two lines with an ellipsis at + the end to indicate there is more content. + + + ); +} +``` + +### Styled text + +Apply custom text styles including font weight, style, size, and decoration. + +```tsx StyledTextExample.tsx +import { Host, Text, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function StyledTextExample() { + return ( + + + Bold text + Italic text + Underlined text + Spaced out text + + Colored and centered + + + + ); +} +``` + +## API + +```tsx +import { Text } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/textbutton.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/textbutton.mdx new file mode 100644 index 00000000000000..4e3d83388d854a --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/textbutton.mdx @@ -0,0 +1,81 @@ +--- +title: TextButton +description: A Jetpack Compose TextButton component for text-styled buttons. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI TextButton matches the official Jetpack Compose [Text Button](https://developer.android.com/develop/ui/compose/components/button#text) API and displays a button without a background container, using only text as the visual element. + +## Installation + + + +## Usage + +### Basic text button + +```tsx BasicTextButtonExample.tsx +import { Host, TextButton } from '@expo/ui/jetpack-compose'; + +export default function BasicTextButtonExample() { + return ( + + console.log('Pressed')}>Click me + + ); +} +``` + +### Disabled text button + +Set the `disabled` prop to prevent user interaction. + +```tsx DisabledTextButtonExample.tsx +import { Host, TextButton } from '@expo/ui/jetpack-compose'; + +export default function DisabledTextButtonExample() { + return ( + + console.log('Pressed')}> + Disabled + + + ); +} +``` + +### Text button with custom color + +Use the `color` prop to change the button text color. + +```tsx CustomColorTextButtonExample.tsx +import { Host, TextButton, Column } from '@expo/ui/jetpack-compose'; + +export default function CustomColorTextButtonExample() { + return ( + + + console.log('Pink')}> + Pink button + + console.log('Green')}> + Green button + + + + ); +} +``` + +## API + +```tsx +import { TextButton } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/textinput.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/textinput.mdx index 00f25ee0607568..2bff0268bc3339 100644 --- a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/textinput.mdx +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/textinput.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A text input component that allows users to enter and edit text using native Android text fields. +Expo UI TextInput matches the official Jetpack Compose [TextField API](https://developer.android.com/develop/ui/compose/text/user-input) and supports single-line and multiline text input with various keyboard types. ## Installation @@ -19,25 +17,56 @@ A text input component that allows users to enter and edit text using native And ## Usage - - - - - - ```tsx - import { TextInput } from '@expo/ui/jetpack-compose'; - - - ``` - - - - -> See [Official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/text/user-input) for more information. +### Basic text input + +```tsx BasicTextInputExample.tsx +import { useState } from 'react'; +import { Host, TextInput } from '@expo/ui/jetpack-compose'; + +export default function BasicTextInputExample() { + const [value, setValue] = useState('Hello, world!'); + + return ( + + + + ); +} +``` + +### Multiline text input + +```tsx MultilineTextInputExample.tsx +import { useState } from 'react'; +import { Host, TextInput } from '@expo/ui/jetpack-compose'; + +export default function MultilineTextInputExample() { + const [value, setValue] = useState(''); + + return ( + + + + ); +} +``` + +### Numeric keyboard + +```tsx NumericTextInputExample.tsx +import { useState } from 'react'; +import { Host, TextInput } from '@expo/ui/jetpack-compose'; + +export default function NumericTextInputExample() { + const [value, setValue] = useState(''); + + return ( + + + + ); +} +``` ## API diff --git a/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/togglebutton.mdx b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/togglebutton.mdx new file mode 100644 index 00000000000000..533dbb658d86fc --- /dev/null +++ b/docs/pages/versions/unversioned/sdk/ui/jetpack-compose/togglebutton.mdx @@ -0,0 +1,131 @@ +--- +title: ToggleButton +description: A Jetpack Compose ToggleButton component for togglable buttons. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI ToggleButton matches the official Jetpack Compose [Toggle Button](https://developer.android.com/develop/ui/compose/components/button#toggle) API and provides a button that switches between checked and unchecked states with multiple visual variants. + +## Installation + + + +## Usage + +### Basic toggle button + +```tsx BasicToggleButtonExample.tsx +import { useState } from 'react'; +import { Host, ToggleButton } from '@expo/ui/jetpack-compose'; + +export default function BasicToggleButtonExample() { + const [checked, setChecked] = useState(false); + + return ( + + setChecked(value)} + /> + + ); +} +``` + +### Toggle button variants + +Use the `variant` prop to switch between `'default'`, `'icon'`, `'filledIcon'`, and `'outlinedIcon'` styles. + +```tsx ToggleButtonVariantsExample.tsx +import { useState } from 'react'; +import { Host, ToggleButton, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function ToggleButtonVariantsExample() { + const [checked1, setChecked1] = useState(false); + const [checked2, setChecked2] = useState(true); + const [checked3, setChecked3] = useState(false); + const [checked4, setChecked4] = useState(true); + + return ( + + + setChecked1(value)} + /> + setChecked2(value)} + /> + setChecked3(value)} + /> + setChecked4(value)} + /> + + + ); +} +``` + +### Toggle button with custom color + +```tsx CustomColorToggleButtonExample.tsx +import { useState } from 'react'; +import { Host, ToggleButton } from '@expo/ui/jetpack-compose'; + +export default function CustomColorToggleButtonExample() { + const [checked, setChecked] = useState(true); + + return ( + + setChecked(value)} + /> + + ); +} +``` + +### Disabled toggle button + +```tsx DisabledToggleButtonExample.tsx +import { Host, ToggleButton } from '@expo/ui/jetpack-compose'; + +export default function DisabledToggleButtonExample() { + return ( + + + + ); +} +``` + +## API + +```tsx +import { ToggleButton } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/router-split-view.mdx b/docs/pages/versions/v55.0.0/sdk/router-split-view.mdx index b792dbbc11b554..455439cca9658a 100644 --- a/docs/pages/versions/v55.0.0/sdk/router-split-view.mdx +++ b/docs/pages/versions/v55.0.0/sdk/router-split-view.mdx @@ -16,7 +16,7 @@ import { Collapsible } from '~/ui/components/Collapsible'; import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; import { FileTree } from '~/ui/components/FileTree'; -> **important** SplitView is currently in [alpha](/more/release-statuses/#alpha) and available in [canary releases](/versions/latest/#using-pre-release-versions) of `expo-router`. You need to use a [development build](/develop/development-builds/introduction) since it is unavailable in Expo Go. +> **important** SplitView is an alpha API available on **iOS only** in **Expo SDK 55** and later. The API is subject to breaking changes and is not ready for production usage yet. `expo-router/unstable-split-view` is a submodule of `expo-router` and exports components to build split view layouts using [platform-native system split views](https://developer.apple.com/design/human-interface-guidelines/split-views). @@ -26,6 +26,45 @@ import { FileTree } from '~/ui/components/FileTree'; Split View is only available on iOS. On other platforms, the `SplitView` component automatically falls back to rendering as a standard `Slot` navigator, ensuring your app works across all platforms without conditional code. +## iPhone support + +On iPhone, `SplitView` automatically collapses all columns into a single view. Only one column is visible at a time. + +### Choosing the initial column + +Use the `topColumnForCollapsing` prop to control which column is displayed when the split view is collapsed: + +```tsx +{/* ... */} +``` + +Accepted values are `primary`, `supplementary`, and `secondary`. When not set, the system uses its default behavior. + +### Navigating between columns + +Use a `ref` to programmatically show a specific column with the `show` method: + +```tsx +import { useRef } from 'react'; +import { Pressable, Text } from 'react-native'; +import { SplitView } from 'expo-router/unstable-split-view'; +import type { SplitHostCommands } from 'react-native-screens/experimental'; + +export default function Layout() { + const ref = useRef(null); + + return ( + + + ref.current?.show('secondary')}> + Show main content + + + + ); +} +``` + ## Known limitations @@ -46,6 +85,26 @@ There can only be one `SplitView` in the navigation hierarchy. Attempting to nes + + +The header (navigation bar) within split view columns cannot be customized. Custom header configurations are not yet supported. + + + + + +The current API surface is minimal and may not cover all use cases. Additional props and configuration options will be added in future releases. + + + + + +To go back to a previous column, tap the system back button in the navigation bar. A future release will add more granular programmatic control over back navigation. + + + +> **info** **Note:** We are actively developing `SplitView` and looking for feedback. You can share your thoughts on [Discord](https://chat.expo.dev), [open an issue on GitHub](https://github.com/expo/expo/issues), or use the **Feedback** button at the bottom of this page. + ## Installation To use `expo-router/unstable-split-view` in your project, you need to install `expo-router` in your project. Follow the instructions from Expo Router's installation guide: @@ -81,7 +140,7 @@ export default function Layout() { return ( - + Inbox diff --git a/docs/pages/versions/v55.0.0/sdk/sqlite.mdx b/docs/pages/versions/v55.0.0/sdk/sqlite.mdx index fe699bc519ac8c..f36ae51d93e8f9 100644 --- a/docs/pages/versions/v55.0.0/sdk/sqlite.mdx +++ b/docs/pages/versions/v55.0.0/sdk/sqlite.mdx @@ -10,6 +10,7 @@ platforms: ['android', 'ios', 'macos', 'tvos', 'web', 'expo-go'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; import { ConfigPluginExample, ConfigPluginProperties } from '~/ui/components/ConfigSection'; +import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; import { DiffBlock } from '~/ui/components/Snippet'; import { Step } from '~/ui/components/Step'; @@ -99,6 +100,26 @@ Add the following configuration to your **metro.config.js**. If you don't have t If you deploy your app to web hosting services, you will also need to add the `Cross-Origin-Embedder-Policy` and `Cross-Origin-Opener-Policy` headers to your web server. [Learn more about the `COEP`, `COOP` headers, and `SharedArrayBuffer`](https://developer.chrome.com/blog/enabling-shared-array-buffer/). +If you deploy your app on [EAS Hosting](/eas/hosting/introduction/), you can configure the headers in your app config: + +```json app.json +{ + "expo": { + "plugins": [ + [ + "expo-router", + { + "headers": { + "Cross-Origin-Embedder-Policy": "credentialless", + "Cross-Origin-Opener-Policy": "same-origin" + } + } + ] + ] + } +} +``` + ## Usage Import the module from `expo-sqlite`. @@ -500,7 +521,14 @@ expect(row.data).toEqual(blob); ### Browse an on-device database -You can inspect a database, execute queries against it, and explore data with the [`drizzle-studio-expo` dev tools plugin](https://github.com/drizzle-team/drizzle-studio-expo). This plugin enables you to launch [Drizzle Studio](https://orm.drizzle.team/drizzle-studio/overview), connected to a database in your app, directly from Expo CLI. This plugin can be used with any `expo-sqlite` configuration. It does not require that you use [Drizzle ORM](#drizzle-orm) in your app. [Learn how to install and use the plugin](https://github.com/drizzle-team/drizzle-studio-expo). +The `expo-sqlite` library includes a built-in DevTools inspector plugin that is automatically enabled in development and requires no extra setup. It lets you browse tables, view and edit rows, run SQL queries, and export databases directly from your browser. To open it, press shift+m in the Expo CLI terminal to open the dev tools menu, and then select **Open expo-sqlite** to launch the inspector. + + + +Alternatively, you can also use the [`drizzle-studio-expo` dev tools plugin](https://github.com/drizzle-team/drizzle-studio-expo) to launch [Drizzle Studio](https://orm.drizzle.team/drizzle-studio/overview), connected to a database in your app, directly from Expo CLI. This plugin can be used with any `expo-sqlite` configuration and does not require [Drizzle ORM](#drizzle-orm). [Learn how to install and use the plugin](https://github.com/drizzle-team/drizzle-studio-expo). ### Key-value storage diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/alertdialog.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/alertdialog.mdx new file mode 100644 index 00000000000000..24377eaa735170 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/alertdialog.mdx @@ -0,0 +1,58 @@ +--- +title: AlertDialog +description: A Jetpack Compose AlertDialog component for displaying native alert dialogs. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI AlertDialog matches the official Jetpack Compose [AlertDialog API](https://developer.android.com/develop/ui/compose/components/dialog) and displays a modal dialog with a title, message text, and confirm/dismiss buttons. + +## Installation + + + +## Usage + +### Basic alert dialog + +```tsx BasicAlertDialogExample.tsx +import { useState } from 'react'; +import { Host, AlertDialog, Button } from '@expo/ui/jetpack-compose'; + +export default function BasicAlertDialogExample() { + const [visible, setVisible] = useState(false); + + return ( + + + { + console.log('Confirmed'); + setVisible(false); + }} + onDismissPressed={() => { + console.log('Dismissed'); + setVisible(false); + }} + /> + + ); +} +``` + +## API + +```tsx +import { AlertDialog } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/basicalertdialog.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/basicalertdialog.mdx new file mode 100644 index 00000000000000..10a980d49eff6e --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/basicalertdialog.mdx @@ -0,0 +1,55 @@ +--- +title: BasicAlertDialog +description: A Jetpack Compose BasicAlertDialog component for displaying dialogs with custom content. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI BasicAlertDialog matches the official Jetpack Compose [BasicAlertDialog API](https://developer.android.com/develop/ui/compose/components/dialog) and displays a minimal dialog that accepts custom children as its content, giving you full control over the dialog layout. + +## Installation + + + +## Usage + +### Basic dialog with custom content + +```tsx BasicAlertDialogExample.tsx +import { useState } from 'react'; +import { Host, BasicAlertDialog, Button, Text, Surface, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicAlertDialogExample() { + const [visible, setVisible] = useState(false); + + return ( + + + {visible && ( + setVisible(false)}> + + + Custom Dialog + This dialog contains fully custom content defined as children. + + + + + )} + + ); +} +``` + +## API + +```tsx +import { BasicAlertDialog } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/bottomsheet.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/bottomsheet.mdx index 6001ffbce042be..a1474fa3f74c06 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/bottomsheet.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/bottomsheet.mdx @@ -1,6 +1,6 @@ --- -title: BottomSheet -description: A Jetpack Compose BottomSheet component that presents content from the bottom of the screen. +title: ModalBottomSheet +description: A Jetpack Compose ModalBottomSheet component that presents content from the bottom of the screen. sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' packageName: '@expo/ui' platforms: ['android'] @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A bottom sheet component that slides up from the bottom of the screen to present content using native Android bottom sheet behavior. +Expo UI ModalBottomSheet matches the official Jetpack Compose [Bottom Sheet API](https://developer.android.com/develop/ui/compose/components/bottom-sheets) and displays content in a modal sheet that slides up from the bottom. ## Installation @@ -19,35 +17,64 @@ A bottom sheet component that slides up from the bottom of the screen to present ## Usage - - - - - - ```tsx - import { BottomSheet } from '@expo/ui/jetpack-compose'; - - - Hello from bottom sheet! - - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/bottom-sheets) for more information. +### Basic bottom sheet + +```tsx BasicBottomSheetExample.tsx +import { useState } from 'react'; +import { Host, ModalBottomSheet, Button, Column, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicBottomSheetExample() { + const [visible, setVisible] = useState(false); + + return ( + + + {visible && ( + setVisible(false)}> + + Hello from bottom sheet! + You can add more content here. + + + + )} + + ); +} +``` + +### Full-screen bottom sheet + +```tsx FullScreenBottomSheetExample.tsx +import { useState } from 'react'; +import { Host, ModalBottomSheet, Button, Column, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function FullScreenBottomSheetExample() { + const [visible, setVisible] = useState(false); + + return ( + + + {visible && ( + setVisible(false)}> + + This sheet expands to full screen. + Add as much content as you need. + + + + )} + + ); +} +``` ## API ```tsx -import { BottomSheet } from '@expo/ui/jetpack-compose'; +import { ModalBottomSheet } from '@expo/ui/jetpack-compose'; ``` diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/box.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/box.mdx new file mode 100644 index 00000000000000..c7c038f34a1c41 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/box.mdx @@ -0,0 +1,43 @@ +--- +title: Box +description: A Jetpack Compose Box component for stacking child elements. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Box matches the official Jetpack Compose [Box](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Box) API and stacks children on top of each other with configurable content alignment. + +## Installation + + + +## Usage + +`Box` stacks children on top of each other. Use `contentAlignment` to position them within the box. + +```tsx BoxExample.tsx +import { Host, Box, Text } from '@expo/ui/jetpack-compose'; +import { size, background } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BoxExample() { + return ( + + + Centered in Box + + + ); +} +``` + +## API + +```tsx +import { Box } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/button.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/button.mdx index 742dc7eb11f155..97c3c98fa127e7 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/button.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/button.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A button component for displaying native buttons. +Expo UI Button matches the official Jetpack Compose [Button API](https://developer.android.com/develop/ui/compose/components/button) and supports variants, icons, custom colors, and shapes. ## Installation @@ -19,41 +17,51 @@ A button component for displaying native buttons. ## Usage - - - - - - ```tsx - import { Button } from '@expo/ui/jetpack-compose'; +### Basic button - +```tsx BasicButtonExample.tsx +import { Host, Button } from '@expo/ui/jetpack-compose'; - {/* Button with both leading and trailing icons */} - - ``` +export default function BasicButtonExample() { + return ( + + + + ); +} +``` + +### Button variants - - +Use the `variant` prop to change the button's appearance. Available variants are: `default`, `bordered`, `borderless`, `outlined`, and `elevated`. -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/button) for more information. +```tsx ButtonVariantsExample.tsx +import { Host, Button, Column } from '@expo/ui/jetpack-compose'; + +export default function ButtonVariantsExample() { + return ( + + + + + + + + + + ); +} +``` ## API diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/card.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/card.mdx new file mode 100644 index 00000000000000..0f8a35587db5f5 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/card.mdx @@ -0,0 +1,70 @@ +--- +title: Card +description: A Jetpack Compose Card component for displaying content in a styled container. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Card matches the official Jetpack Compose [Card API](https://developer.android.com/develop/ui/compose/components/card) and displays content inside a styled surface container with optional elevation and outline. + +## Installation + + + +## Usage + +### Basic card + +```tsx BasicCardExample.tsx +import { Host, Card, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicCardExample() { + return ( + + + This is a basic card with default styling. + + + ); +} +``` + +### Card variants + +Use the `variant` prop to switch between `'default'`, `'elevated'`, and `'outlined'` styles. + +```tsx CardVariantsExample.tsx +import { Host, Card, Text, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function CardVariantsExample() { + return ( + + + + Default card + + + Elevated card + + + Outlined card + + + + ); +} +``` + +## API + +```tsx +import { Card } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/carousel.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/carousel.mdx new file mode 100644 index 00000000000000..96c7e23798882e --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/carousel.mdx @@ -0,0 +1,131 @@ +--- +title: Carousel +description: A Jetpack Compose Carousel component for displaying scrollable collections of items. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Carousel matches the official Jetpack Compose [Carousel API](https://developer.android.com/develop/ui/compose/layouts/pager) and displays a horizontally scrollable collection of items with configurable sizing and fling behavior. + +## Installation + + + +## Usage + +### Basic carousel + +```tsx BasicCarouselExample.tsx +import { Host, Carousel, Box, Text } from '@expo/ui/jetpack-compose'; +import { size, background } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicCarouselExample() { + const items = [ + { label: 'Item 1', color: '#6200EE' }, + { label: 'Item 2', color: '#03DAC5' }, + { label: 'Item 3', color: '#FF5722' }, + { label: 'Item 4', color: '#4CAF50' }, + { label: 'Item 5', color: '#2196F3' }, + ]; + + return ( + + + {items.map(item => ( + + + {item.label} + + + ))} + + + ); +} +``` + +### MultiBrowse variant + +The `multiBrowse` variant shows a large item alongside smaller peek items, letting users see what comes next. + +```tsx MultiBrowseCarouselExample.tsx +import { Host, Carousel, Box, Text } from '@expo/ui/jetpack-compose'; +import { size, background } from '@expo/ui/jetpack-compose/modifiers'; + +export default function MultiBrowseCarouselExample() { + const colors = ['#6200EE', '#03DAC5', '#FF5722', '#4CAF50', '#2196F3']; + + return ( + + + {colors.map((color, index) => ( + + + Card {index + 1} + + + ))} + + + ); +} +``` + +### Unconstrained variant + +The `unconstrained` variant gives each item a fixed width without snapping behavior, allowing free-form scrolling. + +```tsx UnconstrainedCarouselExample.tsx +import { Host, Carousel, Box, Text } from '@expo/ui/jetpack-compose'; +import { size, background } from '@expo/ui/jetpack-compose/modifiers'; + +export default function UnconstrainedCarouselExample() { + const items = ['Photo 1', 'Photo 2', 'Photo 3', 'Photo 4', 'Photo 5']; + + return ( + + + {items.map(item => ( + + + {item} + + + ))} + + + ); +} +``` + +## API + +```tsx +import { Carousel } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/chip.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/chip.mdx index 188197e98a2eec..b1bdee5383b272 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/chip.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/chip.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A chip component for displaying compact elements that represent inputs, attributes, or actions. +Expo UI Chip matches the official Jetpack Compose [Chip API](https://developer.android.com/develop/ui/compose/components/chip) and supports assist, filter, input, and suggestion chip variants. ## Installation @@ -19,56 +17,77 @@ A chip component for displaying compact elements that represent inputs, attribut ## Usage - - - - - - ```tsx - import { Chip } from '@expo/ui/jetpack-compose'; - - // Assist chip with icon - console.log('Opening flight booking...')} - /> - - // Filter chip with selection - handleFilterToggle('Images')} - /> - - // Input chip with dismiss - handleInputDismiss('Work')} - /> - - // Suggestion chip - console.log('Searching nearby...')} - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/chip) for more information. +### Assist chip + +```tsx AssistChipExample.tsx +import { Host, Chip } from '@expo/ui/jetpack-compose'; + +export default function AssistChipExample() { + return ( + + console.log('Opening flight booking...')} + /> + + ); +} +``` + +### Filter chip + +```tsx FilterChipExample.tsx +import { useState } from 'react'; +import { Host, Chip } from '@expo/ui/jetpack-compose'; + +export default function FilterChipExample() { + const [selected, setSelected] = useState(false); + + return ( + + setSelected(!selected)} + /> + + ); +} +``` + +### Input chip + +```tsx InputChipExample.tsx +import { Host, Chip } from '@expo/ui/jetpack-compose'; + +export default function InputChipExample() { + return ( + + console.log('Dismissed Work chip')} /> + + ); +} +``` + +### Suggestion chip + +```tsx SuggestionChipExample.tsx +import { Host, Chip } from '@expo/ui/jetpack-compose'; + +export default function SuggestionChipExample() { + return ( + + console.log('Searching nearby...')} + /> + + ); +} +``` ## API diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/circularprogress.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/circularprogress.mdx index dd1a9c53358e67..05468e2d700790 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/circularprogress.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/circularprogress.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A circular progress indicator component for displaying progress in a circular format. +Expo UI CircularProgress matches the official Jetpack Compose [Progress Indicator API](https://developer.android.com/develop/ui/compose/components/progress) and displays progress in a circular format. ## Installation @@ -19,30 +17,59 @@ A circular progress indicator component for displaying progress in a circular fo ## Usage - - - - - - ```tsx - import { CircularProgress } from '@expo/ui/jetpack-compose'; +### Indeterminate progress - - ``` +When no `progress` is provided, the progress indicator displays an indeterminate spinning animation. - - +```tsx IndeterminateCircularExample.tsx +import { Host, CircularProgress } from '@expo/ui/jetpack-compose'; -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/progress) for more information. +export default function IndeterminateCircularExample() { + return ( + + + + ); +} +``` + +### Determinate progress + +Provide a `progress` value between `0` and `1` to show determinate progress. + +```tsx DeterminateCircularExample.tsx +import { Host, CircularProgress } from '@expo/ui/jetpack-compose'; + +export default function DeterminateCircularExample() { + return ( + + + + ); +} +``` + +### Wavy progress + +`CircularWavyProgress` renders a circular progress indicator with a wavy animation style. + +```tsx CircularWavyExample.tsx +import { Host, CircularWavyProgress } from '@expo/ui/jetpack-compose'; + +export default function CircularWavyExample() { + return ( + + + + ); +} +``` ## API ```tsx -import { CircularProgress } from '@expo/ui/jetpack-compose'; +import { CircularProgress, CircularWavyProgress } from '@expo/ui/jetpack-compose'; ``` + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/column.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/column.mdx new file mode 100644 index 00000000000000..4298e18e359670 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/column.mdx @@ -0,0 +1,48 @@ +--- +title: Column +description: A Jetpack Compose Column component for placing children vertically. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Column matches the official Jetpack Compose [Column](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Column) API and places children vertically with configurable arrangement and alignment. + +## Installation + + + +## Usage + +`Column` places children vertically. Use `verticalArrangement` and `horizontalAlignment` to control spacing and alignment. + +```tsx ColumnExample.tsx +import { Host, Column, Text } from '@expo/ui/jetpack-compose'; +import { fillMaxWidth, paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function ColumnExample() { + return ( + + + First + Second + Third + + + ); +} +``` + +## API + +```tsx +import { Column } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/contextmenu.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/contextmenu.mdx index bf19d2738a1906..d26e4577bdb3b7 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/contextmenu.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/contextmenu.mdx @@ -8,12 +8,10 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -> **Note:** Also known as **DropdownMenu**. +Expo UI ContextMenu matches the official Jetpack Compose [Menu API](https://developer.android.com/develop/ui/compose/components/menu) and displays a context menu when a trigger element is long-pressed or clicked. -A context menu component that displays a menu when triggered, commonly used for actions and options. +> **Note:** Also known as **DropdownMenu**. ## Installation @@ -21,51 +19,31 @@ A context menu component that displays a menu when triggered, commonly used for ## Usage - - - - - - ```tsx - import { ContextMenu } from '@expo/ui/jetpack-compose'; - - - - - - setSelectedIndex(index)} - /> - - - - - - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/menu) for more information. +### Basic context menu + +```tsx BasicContextMenuExample.tsx +import { Host, ContextMenu, Button } from '@expo/ui/jetpack-compose'; + +export default function BasicContextMenuExample() { + return ( + + + + + + + + + + + + ); +} +``` ## API diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/datetimepicker.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/datetimepicker.mdx index 08bca9c41b623a..74b33e53ca7332 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/datetimepicker.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/datetimepicker.mdx @@ -8,72 +8,88 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A date and time picker component that allows users to select dates, times, or both using native Android dialogs. +Expo UI DateTimePicker matches the official Jetpack Compose [Date Picker](https://developer.android.com/develop/ui/compose/components/datepickers) and [Time Picker](https://developer.android.com/develop/ui/compose/components/time-pickers) APIs and supports date, time, and combined selection. ## Installation -## Date time picker - - - - - - - ```tsx - import { DateTimePicker } from '@expo/ui/jetpack-compose'; - - { - setSelectedDate(date); - }} - displayedComponents='date' - initialDate={selectedDate.toISOString()} - variant='picker' - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/datepickers) for more information. - -## Time picker - - - - - - - ```tsx - import { DateTimePicker } from '@expo/ui/jetpack-compose'; - - { - setSelectedDate(date); - }} - displayedComponents='hourAndMinute' - initialDate={selectedDate.toISOString()} - variant='picker' - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/time-pickers) for more information. +## Usage + +### Date picker + +```tsx DatePickerExample.tsx +import { useState } from 'react'; +import { Host, DateTimePicker } from '@expo/ui/jetpack-compose'; + +export default function DatePickerExample() { + const [selectedDate, setSelectedDate] = useState(new Date()); + + return ( + + { + setSelectedDate(date); + }} + displayedComponents="date" + initialDate={selectedDate.toISOString()} + variant="picker" + /> + + ); +} +``` + +### Time picker + +```tsx TimePickerExample.tsx +import { useState } from 'react'; +import { Host, DateTimePicker } from '@expo/ui/jetpack-compose'; + +export default function TimePickerExample() { + const [selectedDate, setSelectedDate] = useState(new Date()); + + return ( + + { + setSelectedDate(date); + }} + displayedComponents="hourAndMinute" + initialDate={selectedDate.toISOString()} + variant="picker" + /> + + ); +} +``` + +### Input variant + +Use `variant="input"` to display the picker as a text input field instead of the default picker UI. + +```tsx InputVariantExample.tsx +import { useState } from 'react'; +import { Host, DateTimePicker } from '@expo/ui/jetpack-compose'; + +export default function InputVariantExample() { + const [selectedDate, setSelectedDate] = useState(new Date()); + + return ( + + { + setSelectedDate(date); + }} + displayedComponents="date" + initialDate={selectedDate.toISOString()} + variant="input" + /> + + ); +} +``` ## API diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/divider.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/divider.mdx new file mode 100644 index 00000000000000..9fd32de4bb9a88 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/divider.mdx @@ -0,0 +1,67 @@ +--- +title: Divider +description: A Jetpack Compose Divider component for creating visual separators. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Divider matches the official Jetpack Compose [HorizontalDivider API](https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#HorizontalDivider) and creates a thin horizontal line to visually separate content. + +## Installation + + + +## Usage + +### Basic divider + +```tsx BasicDividerExample.tsx +import { Host, Divider, Column, Text } from '@expo/ui/jetpack-compose'; + +export default function BasicDividerExample() { + return ( + + + First section + + Second section + + + ); +} +``` + +### Divider with padding modifier + +Use the `modifiers` prop to add padding around the divider. + +```tsx DividerWithPaddingExample.tsx +import { Host, Divider, Column, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function DividerWithPaddingExample() { + return ( + + + Section A + + Section B + + Section C + + + ); +} +``` + +## API + +```tsx +import { Divider } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/dockedsearchbar.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/dockedsearchbar.mdx new file mode 100644 index 00000000000000..78de7aafad86fb --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/dockedsearchbar.mdx @@ -0,0 +1,69 @@ +--- +title: DockedSearchBar +description: A Jetpack Compose DockedSearchBar component for displaying an inline search input. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI DockedSearchBar matches the official Jetpack Compose [SearchBar API](https://developer.android.com/develop/ui/compose/components/search) and displays a search input that remains anchored in its parent layout rather than expanding to full screen. + +## Installation + + + +## Usage + +### Basic docked search bar + +```tsx BasicDockedSearchBarExample.tsx +import { useState } from 'react'; +import { Host, DockedSearchBar } from '@expo/ui/jetpack-compose'; + +export default function BasicDockedSearchBarExample() { + const [query, setQuery] = useState(''); + + return ( + + + + ); +} +``` + +### With placeholder and leading icon + +Use the `DockedSearchBar.Placeholder` and `DockedSearchBar.LeadingIcon` slot components to customize the search bar appearance. + +```tsx DockedSearchBarWithSlotsExample.tsx +import { useState } from 'react'; +import { Host, DockedSearchBar, Text } from '@expo/ui/jetpack-compose'; + +export default function DockedSearchBarWithSlotsExample() { + const [query, setQuery] = useState(''); + + return ( + + + + Search items... + + + ๐Ÿ” + + + + ); +} +``` + +## API + +```tsx +import { DockedSearchBar } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/filterchip.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/filterchip.mdx new file mode 100644 index 00000000000000..cbe6322bc55465 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/filterchip.mdx @@ -0,0 +1,87 @@ +--- +title: FilterChip +description: A Jetpack Compose FilterChip component for displaying toggleable filter options. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI FilterChip matches the official Jetpack Compose [FilterChip API](https://developer.android.com/develop/ui/compose/components/chip) and displays a compact, toggleable element used to filter content. + +## Installation + + + +## Usage + +### Basic filter chip + +```tsx BasicFilterChipExample.tsx +import { useState } from 'react'; +import { Host, FilterChip } from '@expo/ui/jetpack-compose'; + +export default function BasicFilterChipExample() { + const [selected, setSelected] = useState(false); + + return ( + + setSelected(!selected)} /> + + ); +} +``` + +### With leading icon + +Use the `FilterChip.LeadingIcon` slot component to display an icon before the label. + +```tsx FilterChipWithLeadingIconExample.tsx +import { useState } from 'react'; +import { Host, FilterChip, Text } from '@expo/ui/jetpack-compose'; + +export default function FilterChipWithLeadingIconExample() { + const [selected, setSelected] = useState(false); + + return ( + + setSelected(!selected)}> + + ๐Ÿ“ท + + + + ); +} +``` + +### Disabled chip + +Set the `enabled` prop to `false` to prevent user interaction. + +```tsx DisabledFilterChipExample.tsx +import { Host, FilterChip } from '@expo/ui/jetpack-compose'; + +export default function DisabledFilterChipExample() { + return ( + + console.log('This will not fire')} + /> + + ); +} +``` + +## API + +```tsx +import { FilterChip } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/flowrow.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/flowrow.mdx new file mode 100644 index 00000000000000..4f91972f6fca11 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/flowrow.mdx @@ -0,0 +1,50 @@ +--- +title: FlowRow +description: A Jetpack Compose FlowRow component for wrapping children horizontally. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI FlowRow matches the official Jetpack Compose [FlowRow](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#FlowRow) API and arranges children in a horizontal flow that wraps to the next line when it runs out of space. + +## Installation + + + +## Usage + +`FlowRow` arranges children in a horizontal flow that wraps to the next line when it runs out of space. + +```tsx FlowRowExample.tsx +import { Host, FlowRow, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function FlowRowExample() { + const tags = ['React Native', 'Expo', 'Android', 'Jetpack Compose', 'Material 3', 'Kotlin']; + + return ( + + + {tags.map(tag => ( + {tag} + ))} + + + ); +} +``` + +## API + +```tsx +import { FlowRow } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/horizontalfloatingtoolbar.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/horizontalfloatingtoolbar.mdx new file mode 100644 index 00000000000000..9aca4fd622bf06 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/horizontalfloatingtoolbar.mdx @@ -0,0 +1,55 @@ +--- +title: HorizontalFloatingToolbar +description: A Jetpack Compose HorizontalFloatingToolbar component for displaying a floating action bar. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI HorizontalFloatingToolbar matches the official Jetpack Compose [FloatingActionButton API](https://developer.android.com/develop/ui/compose/components/floating-action-button) and displays a horizontal toolbar that floats above content, containing action buttons. + +## Installation + + + +## Usage + +### Toolbar with FloatingActionButton + +Use `IconButton` as direct children for toolbar items, and `HorizontalFloatingToolbar.FloatingActionButton` for the primary action. + +```tsx ToolbarWithFABExample.tsx +import { Host, HorizontalFloatingToolbar, IconButton, Icon } from '@expo/ui/jetpack-compose'; + +export default function ToolbarWithFABExample() { + return ( + + + console.log('Edit pressed')}> + + + console.log('Share pressed')}> + + + console.log('Add pressed')}> + + + + + ); +} +``` + +## API + +```tsx +import { HorizontalFloatingToolbar } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/host.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/host.mdx new file mode 100644 index 00000000000000..293a92ab4e0525 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/host.mdx @@ -0,0 +1,58 @@ +--- +title: Host +description: A Jetpack Compose Host component for bridging React Native and Jetpack Compose. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +The `Host` component is the bridge between React Native and Jetpack Compose. Every Jetpack Compose component from `@expo/ui/jetpack-compose` must be wrapped in a `Host` to render correctly. + +## Installation + + + +## Usage + +### Match contents + +Use the `matchContents` prop to make the `Host` size itself to fit the content. You can pass a boolean or an object to control vertical and horizontal sizing independently. + +```tsx MatchContents.tsx +import { Host, Button } from '@expo/ui/jetpack-compose'; + +export default function MatchContents() { + return ( + + + + ); +} +``` + +### With style + +Apply standard React Native styles to the `Host` wrapper. + +```tsx HostWithStyle.tsx +import { Host, Button } from '@expo/ui/jetpack-compose'; + +export default function HostWithStyle() { + return ( + + + + ); +} +``` + +## API + +```tsx +import { Host } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/icon.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/icon.mdx new file mode 100644 index 00000000000000..c3a964e8599150 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/icon.mdx @@ -0,0 +1,78 @@ +--- +title: Icon +description: A Jetpack Compose Icon component for displaying icons. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +An icon component for rendering icons in Jetpack Compose. We recommend downloading icons as XML vector drawables from [Material Symbols](https://fonts.google.com/icons), which is the standard approach for Android development. + +## Installation + + + +## Usage + +### Basic icon + +Use `require()` to load an XML vector drawable downloaded from [Material Symbols](https://fonts.google.com/icons). + +```tsx BasicIcon.tsx +import { Host, Icon } from '@expo/ui/jetpack-compose'; + +export default function BasicIcon() { + return ( + + + + ); +} +``` + +### Icon with tint color + +Use the `tintColor` prop to apply a color overlay to the icon. + +```tsx TintedIcon.tsx +import { Host, Icon } from '@expo/ui/jetpack-compose'; + +export default function TintedIcon() { + return ( + + + + ); +} +``` + +### Icon with size + +Specify a custom size in dp using the `size` prop. + +```tsx SizedIcon.tsx +import { Host, Icon } from '@expo/ui/jetpack-compose'; + +export default function SizedIcon() { + return ( + + + + ); +} +``` + +## API + +```tsx +import { Icon } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/iconbutton.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/iconbutton.mdx new file mode 100644 index 00000000000000..50ee9aea57f5d7 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/iconbutton.mdx @@ -0,0 +1,84 @@ +--- +title: IconButton +description: A Jetpack Compose IconButton component for displaying tappable icon buttons. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +An icon button component that wraps an icon in a tappable container with different visual variants. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/button#icon) for more information. + +## Installation + + + +## Usage + +### Basic icon button + +```tsx BasicIconButton.tsx +import { Host, IconButton, Icon } from '@expo/ui/jetpack-compose'; + +export default function BasicIconButton() { + return ( + + console.log('Pressed')}> + + + + ); +} +``` + +### Variants + +Use the `variant` prop to change the visual style of the button. Available variants are `'default'`, `'bordered'`, and `'outlined'`. + +```tsx IconButtonVariants.tsx +import { Host, IconButton, Icon } from '@expo/ui/jetpack-compose'; + +export default function IconButtonVariants() { + return ( + + console.log('Default')}> + + + console.log('Bordered')}> + + + console.log('Outlined')}> + + + + ); +} +``` + +### Disabled + +Set the `disabled` prop to prevent interaction. + +```tsx DisabledIconButton.tsx +import { Host, IconButton, Icon } from '@expo/ui/jetpack-compose'; + +export default function DisabledIconButton() { + return ( + + console.log('Pressed')}> + + + + ); +} +``` + +## API + +```tsx +import { IconButton } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/index.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/index.mdx index fc8c8cd05cccee..c8c6dfdd4e949a 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/index.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/index.mdx @@ -18,3 +18,19 @@ The Jetpack Compose components in `@expo/ui/jetpack-compose` allow you to build ## Installation + +## Usage + +Using a component from `@expo/ui/jetpack-compose` requires wrapping it in a [`Host`](./host) component. The `Host` is a container for Jetpack Compose views. + +```tsx +import { Host, Button } from '@expo/ui/jetpack-compose'; + +export function SaveButton() { + return ( + + + + ); +} +``` diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/lazycolumn.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/lazycolumn.mdx new file mode 100644 index 00000000000000..1747e04460086c --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/lazycolumn.mdx @@ -0,0 +1,86 @@ +--- +title: LazyColumn +description: A Jetpack Compose LazyColumn component for displaying scrollable lists. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +A lazily-loaded vertical list component that only renders visible items for efficient scrolling. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/lists) for more information. + +## Installation + + + +## Usage + +### Basic lazy column + +```tsx BasicLazyColumn.tsx +import { Host, LazyColumn, ListItem } from '@expo/ui/jetpack-compose'; + +const items = Array.from({ length: 100 }, (_, i) => `Item ${i + 1}`); + +export default function BasicLazyColumn() { + return ( + + + {items.map(item => ( + + ))} + + + ); +} +``` + +### With arrangement + +Use the `verticalArrangement` prop to control how items are spaced within the list. Pass a string value like `'spaceBetween'` or an object like `{ spacedBy: 8 }` for fixed spacing in dp. + +```tsx LazyColumnArrangement.tsx +import { Host, LazyColumn, ListItem } from '@expo/ui/jetpack-compose'; + +export default function LazyColumnArrangement() { + return ( + + + + + + + + ); +} +``` + +### With content padding + +Use the `contentPadding` prop to add padding around the list content in dp. + +```tsx LazyColumnPadding.tsx +import { Host, LazyColumn, ListItem } from '@expo/ui/jetpack-compose'; + +export default function LazyColumnPadding() { + return ( + + + + + + + + ); +} +``` + +## API + +```tsx +import { LazyColumn } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/linearprogress.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/linearprogress.mdx index ed161da49ce77c..7a837c77f9d341 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/linearprogress.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/linearprogress.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A linear progress indicator component for displaying progress in a horizontal bar format. +Expo UI LinearProgress matches the official Jetpack Compose [Progress Indicator API](https://developer.android.com/develop/ui/compose/components/progress) and displays progress in a horizontal bar format. ## Installation @@ -19,30 +17,59 @@ A linear progress indicator component for displaying progress in a horizontal ba ## Usage - - - - - - ```tsx - import { LinearProgress } from '@expo/ui/jetpack-compose'; +### Indeterminate progress - - ``` +When no `progress` is provided, the progress indicator displays an indeterminate animating bar. - - +```tsx IndeterminateLinearExample.tsx +import { Host, LinearProgress } from '@expo/ui/jetpack-compose'; -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/progress) for more information. +export default function IndeterminateLinearExample() { + return ( + + + + ); +} +``` + +### Determinate progress + +Provide a `progress` value between `0` and `1` to show determinate progress. + +```tsx DeterminateLinearExample.tsx +import { Host, LinearProgress } from '@expo/ui/jetpack-compose'; + +export default function DeterminateLinearExample() { + return ( + + + + ); +} +``` + +### Wavy progress + +`LinearWavyProgress` renders a linear progress indicator with a wavy animation style. + +```tsx LinearWavyExample.tsx +import { Host, LinearWavyProgress } from '@expo/ui/jetpack-compose'; + +export default function LinearWavyExample() { + return ( + + + + ); +} +``` ## API ```tsx -import { LinearProgress } from '@expo/ui/jetpack-compose'; +import { LinearProgress, LinearWavyProgress } from '@expo/ui/jetpack-compose'; ``` + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/listitem.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/listitem.mdx new file mode 100644 index 00000000000000..bdc4307573cd13 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/listitem.mdx @@ -0,0 +1,83 @@ +--- +title: ListItem +description: A Jetpack Compose ListItem component for displaying structured list entries. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +A list item component that follows Material Design 3 guidelines for structured list entries with headline, supporting text, and leading/trailing slots. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/lists) for more information. + +## Installation + + + +## Usage + +### Basic list item + +```tsx BasicListItem.tsx +import { Host, ListItem } from '@expo/ui/jetpack-compose'; + +export default function BasicListItem() { + return ( + + + + ); +} +``` + +### With supporting text and overline + +Use the `supportingText` prop to add a secondary line and `overlineText` for a category label above the headline. + +```tsx ListItemWithText.tsx +import { Host, ListItem } from '@expo/ui/jetpack-compose'; + +export default function ListItemWithText() { + return ( + + + + ); +} +``` + +### With leading and trailing slots + +Use `ListItem.Leading` and `ListItem.Trailing` sub-components to add content to the start and end of the list item. + +```tsx ListItemWithSlots.tsx +import { Host, ListItem, Icon } from '@expo/ui/jetpack-compose'; + +export default function ListItemWithSlots() { + return ( + + + + + + + + + + + ); +} +``` + +## API + +```tsx +import { ListItem } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/modifiers.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/modifiers.mdx new file mode 100644 index 00000000000000..d3b9d1b0d32498 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/modifiers.mdx @@ -0,0 +1,460 @@ +--- +title: Modifiers +description: Jetpack Compose layout modifiers for @expo/ui components. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Jetpack Compose modifiers allow you to customize the layout, appearance, and behavior of UI components. Modifiers are the Compose equivalent of style properties โ€” they control sizing, padding, backgrounds, interactions, and more. + +## Installation + + + +## Usage + +Modifiers are applied to components using the `modifiers` prop with an array syntax. You can combine multiple modifiers to create complex styling and behavior. Modifiers are applied in the order they appear in the array, which can affect the final result (for example, applying `padding` before `background` produces different results than the reverse). + +```tsx +import { Button, Host } from '@expo/ui/jetpack-compose'; +import { + paddingAll, + fillMaxWidth, + background, + border, + shadow, + clickable, +} from '@expo/ui/jetpack-compose/modifiers'; + +function ModifiersExample() { + return ( + + {/* Basic styling modifiers */} + + + {/* Complex combination with border and shadow */} + + + ); +} +``` + +## Padding + +Control the spacing around a component's content. + +### `paddingAll(all)` + +Applies equal padding on all four sides. + +| Parameter | Type | Description | +| --------- | -------- | -------------------- | +| `all` | `number` | Padding value in dp. | + +```tsx +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `padding(start, top, end, bottom)` + +Applies individual padding to each side. + +| Parameter | Type | Description | +| --------- | -------- | ------------------------- | +| `start` | `number` | Left/start padding in dp. | +| `top` | `number` | Top padding in dp. | +| `end` | `number` | Right/end padding in dp. | +| `bottom` | `number` | Bottom padding in dp. | + +```tsx +import { padding } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Size + +Control the dimensions of a component. + +### `size(width, height)` + +Sets exact dimensions for the component. + +| Parameter | Type | Description | +| --------- | -------- | ------------- | +| `width` | `number` | Width in dp. | +| `height` | `number` | Height in dp. | + +```tsx +import { size } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `fillMaxSize(fraction?)` + +Fills all available space in both dimensions. + +| Parameter | Type | Description | +| ---------- | -------- | ----------------------------------------------------- | +| `fraction` | `number` | Fraction of available space (0.0โ€“1.0). Default `1.0`. | + +```tsx +import { fillMaxSize } from '@expo/ui/jetpack-compose/modifiers'; + + + +``` + +### `fillMaxWidth(fraction?)` + +Fills available width. + +| Parameter | Type | Description | +| ---------- | -------- | ----------------------------------------------------- | +| `fraction` | `number` | Fraction of available width (0.0โ€“1.0). Default `1.0`. | + +```tsx +import { fillMaxWidth } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `fillMaxHeight(fraction?)` + +Fills available height. + +| Parameter | Type | Description | +| ---------- | -------- | ------------------------------------------------------ | +| `fraction` | `number` | Fraction of available height (0.0โ€“1.0). Default `1.0`. | + +### `width(value)` + +Sets an exact width. + +| Parameter | Type | Description | +| --------- | -------- | ------------ | +| `value` | `number` | Width in dp. | + +### `height(value)` + +Sets an exact height. + +| Parameter | Type | Description | +| --------- | -------- | ------------- | +| `value` | `number` | Height in dp. | + +### `wrapContentWidth(alignment?)` + +Sizes the component to wrap its content width. + +| Parameter | Type | Description | +| ----------- | -------- | ------------------------------------ | +| `alignment` | `string` | Horizontal alignment of the content. | + +### `wrapContentHeight(alignment?)` + +Sizes the component to wrap its content height. + +| Parameter | Type | Description | +| ----------- | -------- | ---------------------------------- | +| `alignment` | `string` | Vertical alignment of the content. | + +## Position + +Control the position of a component relative to its natural placement. + +### `offset(x, y)` + +Offsets the component from its natural position without affecting the layout of surrounding components. + +| Parameter | Type | Description | +| --------- | -------- | ------------------------ | +| `x` | `number` | Horizontal offset in dp. | +| `y` | `number` | Vertical offset in dp. | + +```tsx +import { offset } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Appearance + +Control the visual appearance of a component. + +### `background(color)` + +Sets the background color. + +| Parameter | Type | Description | +| --------- | -------- | ------------------------------ | +| `color` | `string` | Background color (hex string). | + +```tsx +import { background } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `border(borderWidth, borderColor)` + +Adds a border around the component. + +| Parameter | Type | Description | +| ------------- | -------- | -------------------------- | +| `borderWidth` | `number` | Border width in dp. | +| `borderColor` | `string` | Border color (hex string). | + +```tsx +import { border } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `shadow(elevation)` + +Adds an elevation shadow beneath the component. + +| Parameter | Type | Description | +| ----------- | -------- | ----------------------- | +| `elevation` | `number` | Shadow elevation in dp. | + +```tsx +import { shadow } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `alpha(alpha)` + +Controls the opacity of the component. + +| Parameter | Type | Description | +| --------- | -------- | ------------------------ | +| `alpha` | `number` | Opacity value (0.0โ€“1.0). | + +```tsx +import { alpha } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `blur(radius)` + +Applies a blur effect to the component. + +| Parameter | Type | Description | +| --------- | -------- | ------------------ | +| `radius` | `number` | Blur radius in dp. | + +```tsx +import { blur } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Transform + +Apply visual transformations to a component. + +### `rotate(degrees)` + +Rotates the component. + +| Parameter | Type | Description | +| --------- | -------- | -------------------------- | +| `degrees` | `number` | Rotation angle in degrees. | + +```tsx +import { rotate } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `zIndex(index)` + +Controls the drawing order of overlapping components. + +| Parameter | Type | Description | +| --------- | -------- | ------------ | +| `index` | `number` | Layer index. | + +```tsx +import { zIndex } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Animation + +Animate layout changes within a component. + +### `animateContentSize(dampingRatio?, stiffness?)` + +Animates size changes of the component's content using a spring animation. + +| Parameter | Type | Description | +| -------------- | -------- | ------------------------------------------- | +| `dampingRatio` | `number` | Spring damping ratio. Controls bounciness. | +| `stiffness` | `number` | Spring stiffness. Controls animation speed. | + +```tsx +import { animateContentSize } from '@expo/ui/jetpack-compose/modifiers'; + + + +``` + +## Layout + +Control how a component is sized and positioned within its parent container. + +### `weight(weight)` + +Assigns a flexible weight to a component inside a `Row` or `Column`, distributing available space proportionally among weighted children. + +| Parameter | Type | Description | +| --------- | -------- | -------------- | +| `weight` | `number` | Weight factor. | + +```tsx +import { weight } from '@expo/ui/jetpack-compose/modifiers'; + +// In a Row, the first button takes 2/3 and the second takes 1/3 + + +``` + +### `align(alignment)` + +Sets the alignment of the component within its parent container. + +| Parameter | Type | Description | +| ----------- | -------- | ------------------------------- | +| `alignment` | `string` | Alignment within the container. | + +### `matchParentSize()` + +Sizes the component to match the size of its parent `Box`. Unlike `fillMaxSize`, this does not affect the parent's measurement. + +```tsx +import { matchParentSize } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Interaction + +Add user interaction handlers to a component. + +### `clickable(handler)` + +Makes the component respond to click events. + +| Parameter | Type | Description | +| --------- | ------------ | -------------------------- | +| `handler` | `() => void` | Callback invoked on click. | + +```tsx +import { clickable } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +### `selectable(selected, handler)` + +Makes the component selectable, similar to a radio button. + +| Parameter | Type | Description | +| ---------- | ------------ | ---------------------------------------------- | +| `selected` | `boolean` | Whether the component is currently selected. | +| `handler` | `() => void` | Callback invoked when selection state changes. | + +```tsx +import { selectable } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## Clipping + +Clip a component's content to a specific shape. + +### `clip(shape)` + +Clips the component to the given shape. Content outside the shape boundary is not drawn. + +| Parameter | Type | Description | +| --------- | ------- | --------------------- | +| `shape` | `Shape` | The shape to clip to. | + +#### Available shapes + +| Shape | Description | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Shapes.Rectangle` | A rectangle with no rounded corners. | +| `Shapes.Circle` | A perfect circle. | +| `Shapes.RoundedCorner(radius)` | A rectangle with uniform rounded corners. Pass a `number` for equal radius or an object `{ topStart, topEnd, bottomStart, bottomEnd }` for individual corner radii. | +| `Shapes.CutCorner(radius)` | A rectangle with cut (chamfered) corners. Accepts the same radius options as `RoundedCorner`. | +| `Shapes.Material.Cookie4Sided` | Material Design cookie shape with 4 sides. | +| `Shapes.Material.Cookie6Sided` | Material Design cookie shape with 6 sides. | + +```tsx +import { clip } from '@expo/ui/jetpack-compose/modifiers'; +import { Shapes } from '@expo/ui/jetpack-compose/modifiers'; + +// Circular clipping + + +// Rounded corners with uniform radius + + +// Rounded corners with individual radii + + +// Cut corners + +``` + +## Utility + +### `testID(tag)` + +Assigns a test identifier to the component for use in UI testing. + +| Parameter | Type | Description | +| --------- | -------- | ------------ | +| `tag` | `string` | The test ID. | + +```tsx +import { testID } from '@expo/ui/jetpack-compose/modifiers'; + +; +``` + +## API + +{/* prettier-ignore */} +```tsx +import { paddingAll, padding, size, fillMaxWidth, background, clickable, clip, Shapes } from '@expo/ui/jetpack-compose/modifiers'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/picker.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/picker.mdx index 521663377c4d33..bdeef8ee236c80 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/picker.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/picker.mdx @@ -8,72 +8,93 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A picker component that allows users to select from a list of options with different display styles. +Expo UI Picker matches the official Jetpack Compose [Segmented Button](https://developer.android.com/develop/ui/compose/components/segmented-button) and [Radio Button](https://developer.android.com/develop/ui/compose/components/radio-button) APIs and supports segmented and radio picker variants. ## Installation -## Radio picker - - - - - - - ```tsx - import { Picker } from '@expo/ui/jetpack-compose'; - - { - setSelectedIndex(index); - }} - variant="radio" - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/radio-button) for more information. - -## Segmented picker - - - - - - - ```tsx - import { Picker } from '@expo/ui/jetpack-compose'; - - { - setSelectedIndex(index); - }} - variant="segmented" - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/segmented-button) for more information. +## Usage + +### Segmented picker + +Use the `variant="segmented"` prop to display a segmented button group. + +```tsx SegmentedPickerExample.tsx +import { useState } from 'react'; +import { Host, Picker } from '@expo/ui/jetpack-compose'; + +export default function SegmentedPickerExample() { + const [selectedIndex, setSelectedIndex] = useState(0); + + return ( + + { + setSelectedIndex(index); + }} + variant="segmented" + /> + + ); +} +``` + +### Radio picker + +Use the `variant="radio"` prop to display a list of radio buttons. + +```tsx RadioPickerExample.tsx +import { useState } from 'react'; +import { Host, Picker } from '@expo/ui/jetpack-compose'; + +export default function RadioPickerExample() { + const [selectedIndex, setSelectedIndex] = useState(0); + + return ( + + { + setSelectedIndex(index); + }} + variant="radio" + /> + + ); +} +``` + +### Picker with custom color + +Use the `color` prop to customize the picker's accent color. + +```tsx CustomColorPickerExample.tsx +import { useState } from 'react'; +import { Host, Picker } from '@expo/ui/jetpack-compose'; + +export default function CustomColorPickerExample() { + const [selectedIndex, setSelectedIndex] = useState(0); + + return ( + + { + setSelectedIndex(index); + }} + variant="segmented" + color="#6200EE" + /> + + ); +} +``` ## API diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/pulltorefreshbox.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/pulltorefreshbox.mdx new file mode 100644 index 00000000000000..559598a5a9f44c --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/pulltorefreshbox.mdx @@ -0,0 +1,58 @@ +--- +title: PullToRefreshBox +description: A Jetpack Compose PullToRefreshBox component for pull-to-refresh interactions. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +A pull-to-refresh container that wraps scrollable content and provides a standard refresh indicator when pulled. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/layouts/adaptive/support-different-screen-sizes) for more information. + +## Installation + + + +## Usage + +### Basic pull to refresh + +```tsx BasicPullToRefresh.tsx +import { useState, useCallback } from 'react'; +import { Host, PullToRefreshBox, LazyColumn, ListItem } from '@expo/ui/jetpack-compose'; + +export default function BasicPullToRefresh() { + const [refreshing, setRefreshing] = useState(false); + + const onRefresh = useCallback(() => { + setRefreshing(true); + setTimeout(() => { + setRefreshing(false); + }, 2000); + }, []); + + return ( + + + + + + + + + + + + ); +} +``` + +## API + +```tsx +import { PullToRefreshBox } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/radiobutton.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/radiobutton.mdx new file mode 100644 index 00000000000000..1254fb258a49ce --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/radiobutton.mdx @@ -0,0 +1,87 @@ +--- +title: RadioButton +description: A Jetpack Compose RadioButton component for single-selection controls. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +A radio button component for selecting a single option from a set. See the [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/radio-button) for more information. + +## Installation + + + +## Usage + +### Basic radio button + +```tsx BasicRadioButton.tsx +import { useState } from 'react'; +import { Host, RadioButton } from '@expo/ui/jetpack-compose'; + +export default function BasicRadioButton() { + const [selected, setSelected] = useState(false); + + return ( + + setSelected(!selected)} /> + + ); +} +``` + +### Radio button group + +Combine multiple `RadioButton` components to create a single-selection group. + +```tsx RadioButtonGroup.tsx +import { useState } from 'react'; +import { Host, Column, RadioButton, ListItem } from '@expo/ui/jetpack-compose'; + +export default function RadioButtonGroup() { + const [selectedOption, setSelectedOption] = useState('option1'); + + return ( + + + setSelectedOption('option1')}> + + setSelectedOption('option1')} + /> + + + setSelectedOption('option2')}> + + setSelectedOption('option2')} + /> + + + setSelectedOption('option3')}> + + setSelectedOption('option3')} + /> + + + + + ); +} +``` + +## API + +```tsx +import { RadioButton } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/row.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/row.mdx new file mode 100644 index 00000000000000..45e03635187a5c --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/row.mdx @@ -0,0 +1,48 @@ +--- +title: Row +description: A Jetpack Compose Row component for placing children horizontally. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Row matches the official Jetpack Compose [Row](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Row) API and places children horizontally with configurable arrangement and alignment. + +## Installation + + + +## Usage + +`Row` places children horizontally. Use `horizontalArrangement` and `verticalAlignment` to control spacing and alignment. + +```tsx RowExample.tsx +import { Host, Row, Text } from '@expo/ui/jetpack-compose'; +import { fillMaxWidth, height } from '@expo/ui/jetpack-compose/modifiers'; + +export default function RowExample() { + return ( + + + Item 1 + Item 2 + Item 3 + + + ); +} +``` + +## API + +```tsx +import { Row } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/searchbar.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/searchbar.mdx new file mode 100644 index 00000000000000..e62c2248d751dc --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/searchbar.mdx @@ -0,0 +1,64 @@ +--- +title: SearchBar +description: A Jetpack Compose SearchBar component for search input functionality. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI SearchBar matches the official Jetpack Compose [Search](https://developer.android.com/develop/ui/compose/components/search) API and provides a search input with support for placeholder text and expanded full-screen search. + +## Installation + + + +## Usage + +### Basic search bar + +```tsx BasicSearchBarExample.tsx +import { useState } from 'react'; +import { Host, SearchBar } from '@expo/ui/jetpack-compose'; + +export default function BasicSearchBarExample() { + const [query, setQuery] = useState(''); + + return ( + + setQuery(searchText)} /> + + ); +} +``` + +### Search bar with placeholder + +Use the `SearchBar.Placeholder` sub-component to display hint text when the search field is empty. + +```tsx SearchBarPlaceholderExample.tsx +import { useState } from 'react'; +import { Host, SearchBar } from '@expo/ui/jetpack-compose'; + +export default function SearchBarPlaceholderExample() { + const [query, setQuery] = useState(''); + + return ( + + setQuery(searchText)}> + Search items... + + + ); +} +``` + +## API + +```tsx +import { SearchBar } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/shape.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/shape.mdx new file mode 100644 index 00000000000000..3ddb0f9664fcb3 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/shape.mdx @@ -0,0 +1,114 @@ +--- +title: Shape +description: A Jetpack Compose Shape component for drawing geometric shapes. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Shape matches the official Jetpack Compose [Shapes](https://developer.android.com/develop/ui/compose/graphics/draw/shapes) API and provides a set of sub-components for drawing geometric shapes such as stars, circles, rectangles, pills, and polygons. + +## Installation + + + +## Usage + +### Basic shapes + +Render common shapes using the `Shape` sub-components. + +```tsx BasicShapesExample.tsx +import { Host, Shape, Row } from '@expo/ui/jetpack-compose'; +import { size } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicShapesExample() { + return ( + + + + + + + + + ); +} +``` + +### Shapes with rounded corners + +Use `cornerRounding` and `smoothing` to customize the appearance of shapes. + +```tsx RoundedShapesExample.tsx +import { Host, Shape, Row } from '@expo/ui/jetpack-compose'; +import { size } from '@expo/ui/jetpack-compose/modifiers'; + +export default function RoundedShapesExample() { + return ( + + + + + + + ); +} +``` + +### Polygon and star variants + +Use `verticesCount` and `innerRadius` to control the shape geometry. + +```tsx PolygonShapesExample.tsx +import { Host, Shape, Row } from '@expo/ui/jetpack-compose'; +import { size } from '@expo/ui/jetpack-compose/modifiers'; + +export default function PolygonShapesExample() { + return ( + + + + + + + + ); +} +``` + +## API + +```tsx +import { Shape } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/slider.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/slider.mdx index ccbf3bf914aff9..eada5c39d07aba 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/slider.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/slider.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A slider component that allows users to select a value from a continuous range by dragging a thumb along a track. +Expo UI Slider matches the official Jetpack Compose [Slider API](https://developer.android.com/develop/ui/compose/components/slider) and allows selecting values from a bounded range. ## Installation @@ -19,31 +17,60 @@ A slider component that allows users to select a value from a continuous range b ## Usage - - - - - - ```tsx - import { Slider } from '@expo/ui/jetpack-compose'; - - { - setValue(value); - }} - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/slider) for more information. +### Basic slider + +```tsx BasicSliderExample.tsx +import { useState } from 'react'; +import { Host, Slider } from '@expo/ui/jetpack-compose'; + +export default function BasicSliderExample() { + const [value, setValue] = useState(0.5); + + return ( + + + + ); +} +``` + +### Slider with custom range + +Use the `min` and `max` props to define the slider's value range. + +```tsx CustomRangeSliderExample.tsx +import { useState } from 'react'; +import { Host, Slider } from '@expo/ui/jetpack-compose'; + +export default function CustomRangeSliderExample() { + const [value, setValue] = useState(50); + + return ( + + + + ); +} +``` + +### Slider with steps + +Use the `steps` prop to define discrete increments. Set `steps` to `0` for continuous values. + +```tsx SteppedSliderExample.tsx +import { useState } from 'react'; +import { Host, Slider } from '@expo/ui/jetpack-compose'; + +export default function SteppedSliderExample() { + const [value, setValue] = useState(0); + + return ( + + + + ); +} +``` ## API diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/spacer.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/spacer.mdx new file mode 100644 index 00000000000000..46abec5551ce85 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/spacer.mdx @@ -0,0 +1,68 @@ +--- +title: Spacer +description: A Jetpack Compose Spacer component for adding flexible space between elements. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Spacer matches the official Jetpack Compose [Spacer](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Spacer) API and is used to add flexible or fixed-size space between elements in a layout. + +## Installation + + + +## Usage + +### Spacer with weight + +Use the `weight()` modifier to make the spacer fill available space proportionally within a `Row` or `Column`. + +```tsx SpacerWeightExample.tsx +import { Host, Row, Spacer, Text } from '@expo/ui/jetpack-compose'; +import { fillMaxWidth, weight } from '@expo/ui/jetpack-compose/modifiers'; + +export default function SpacerWeightExample() { + return ( + + + Left + + Right + + + ); +} +``` + +### Spacer with fixed size + +Use a `height` or `width` modifier to create a spacer with a fixed dimension. + +```tsx SpacerFixedSizeExample.tsx +import { Host, Column, Spacer, Text } from '@expo/ui/jetpack-compose'; +import { height } from '@expo/ui/jetpack-compose/modifiers'; + +export default function SpacerFixedSizeExample() { + return ( + + + Above + + Below (24dp gap) + + + ); +} +``` + +## API + +```tsx +import { Spacer } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/surface.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/surface.mdx new file mode 100644 index 00000000000000..baafb447d46aec --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/surface.mdx @@ -0,0 +1,90 @@ +--- +title: Surface +description: A Jetpack Compose Surface component for styled content containers. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Surface matches the official Jetpack Compose [Surface](https://developer.android.com/develop/ui/compose/components/surfaces) API and provides a container that applies Material Design surface styling including color, elevation, and content color. + +## Installation + + + +## Usage + +### Basic surface + +```tsx BasicSurfaceExample.tsx +import { Host, Surface, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function BasicSurfaceExample() { + return ( + + + Content on a surface + + + ); +} +``` + +### Surface with elevation + +Use `tonalElevation` and `shadowElevation` to control the visual depth of the surface. + +```tsx SurfaceElevationExample.tsx +import { Host, Surface, Column, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function SurfaceElevationExample() { + return ( + + + + Low elevation + + + High elevation + + + + ); +} +``` + +### Surface with custom colors + +Use the `color` and `contentColor` props to override the default Material theme colors. + +```tsx SurfaceCustomColorsExample.tsx +import { Host, Surface, Text } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function SurfaceCustomColorsExample() { + return ( + + + Custom colored surface + + + ); +} +``` + +## API + +```tsx +import { Surface } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/switch.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/switch.mdx index 0a7795c5c78aba..29353f9ccc0d6b 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/switch.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/switch.mdx @@ -8,78 +8,89 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A switch component that provides toggle functionality with different visual styles. +Expo UI Switch matches the official Jetpack Compose [Switch](https://developer.android.com/develop/ui/compose/components/switch) and [Checkbox](https://developer.android.com/develop/ui/compose/components/checkbox) APIs and supports switch, checkbox, and button variants. ## Installation -## Toggle switch - -> **Note:** also known as **Toggle**. - - - - - - - - ```tsx - import { Switch } from '@expo/ui/jetpack-compose'; - - { - setChecked(checked); - }} - color="#ff0000" - label="Play music" - variant="switch" - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/switch) for more information. - -## Checkbox - - - - - - - - ```tsx - import { Switch } from '@expo/ui/jetpack-compose'; - - { - setChecked(checked); - }} - label="Play music" - color="#ff0000" - variant="checkbox" - /> - ``` - - - - -> See [official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/components/checkbox) for more information. +## Usage + +### Toggle switch + +Use the `variant="switch"` prop to display a standard toggle switch. + +```tsx ToggleSwitchExample.tsx +import { useState } from 'react'; +import { Host, Switch } from '@expo/ui/jetpack-compose'; + +export default function ToggleSwitchExample() { + const [checked, setChecked] = useState(false); + + return ( + + + + ); +} +``` + +### Checkbox + +Use the `variant="checkbox"` prop to display a checkbox control. + +```tsx CheckboxExample.tsx +import { useState } from 'react'; +import { Host, Switch } from '@expo/ui/jetpack-compose'; + +export default function CheckboxExample() { + const [checked, setChecked] = useState(false); + + return ( + + + + ); +} +``` + +### Button variant + +Use the `variant="button"` prop to display a toggle button. + +```tsx ButtonVariantExample.tsx +import { useState } from 'react'; +import { Host, Switch } from '@expo/ui/jetpack-compose'; + +export default function ButtonVariantExample() { + const [checked, setChecked] = useState(false); + + return ( + + + + ); +} +``` ## API diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/text.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/text.mdx new file mode 100644 index 00000000000000..fbbabc9b231819 --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/text.mdx @@ -0,0 +1,107 @@ +--- +title: Text +description: A Jetpack Compose Text component for displaying styled text. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI Text matches the official Jetpack Compose [Text styling](https://developer.android.com/develop/ui/compose/text/style-text) API and displays text with Material 3 typography styles, custom fonts, and text formatting options. + +## Installation + + + +## Usage + +### Basic text + +```tsx BasicTextExample.tsx +import { Host, Text } from '@expo/ui/jetpack-compose'; + +export default function BasicTextExample() { + return ( + + Hello, world! + + ); +} +``` + +### Typography styles + +Use the `style` prop with `typography` to apply Material 3 typography presets. + +```tsx TypographyExample.tsx +import { Host, Text, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function TypographyExample() { + return ( + + + Display Large + Headline Medium + Body Small + Label Large + + + ); +} +``` + +### Text with maxLines and overflow + +Control text truncation with `maxLines` and `overflow`. + +```tsx TextOverflowExample.tsx +import { Host, Text } from '@expo/ui/jetpack-compose'; +import { width } from '@expo/ui/jetpack-compose/modifiers'; + +export default function TextOverflowExample() { + return ( + + + This is a long paragraph of text that will be truncated after two lines with an ellipsis at + the end to indicate there is more content. + + + ); +} +``` + +### Styled text + +Apply custom text styles including font weight, style, size, and decoration. + +```tsx StyledTextExample.tsx +import { Host, Text, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function StyledTextExample() { + return ( + + + Bold text + Italic text + Underlined text + Spaced out text + + Colored and centered + + + + ); +} +``` + +## API + +```tsx +import { Text } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/textbutton.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/textbutton.mdx new file mode 100644 index 00000000000000..4e3d83388d854a --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/textbutton.mdx @@ -0,0 +1,81 @@ +--- +title: TextButton +description: A Jetpack Compose TextButton component for text-styled buttons. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI TextButton matches the official Jetpack Compose [Text Button](https://developer.android.com/develop/ui/compose/components/button#text) API and displays a button without a background container, using only text as the visual element. + +## Installation + + + +## Usage + +### Basic text button + +```tsx BasicTextButtonExample.tsx +import { Host, TextButton } from '@expo/ui/jetpack-compose'; + +export default function BasicTextButtonExample() { + return ( + + console.log('Pressed')}>Click me + + ); +} +``` + +### Disabled text button + +Set the `disabled` prop to prevent user interaction. + +```tsx DisabledTextButtonExample.tsx +import { Host, TextButton } from '@expo/ui/jetpack-compose'; + +export default function DisabledTextButtonExample() { + return ( + + console.log('Pressed')}> + Disabled + + + ); +} +``` + +### Text button with custom color + +Use the `color` prop to change the button text color. + +```tsx CustomColorTextButtonExample.tsx +import { Host, TextButton, Column } from '@expo/ui/jetpack-compose'; + +export default function CustomColorTextButtonExample() { + return ( + + + console.log('Pink')}> + Pink button + + console.log('Green')}> + Green button + + + + ); +} +``` + +## API + +```tsx +import { TextButton } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/textinput.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/textinput.mdx index 00f25ee0607568..2bff0268bc3339 100644 --- a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/textinput.mdx +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/textinput.mdx @@ -8,10 +8,8 @@ platforms: ['android'] import APISection from '~/components/plugins/APISection'; import { APIInstallSection } from '~/components/plugins/InstallSection'; -import { ContentSpotlight } from '~/ui/components/ContentSpotlight'; -import { Tabs, Tab } from '~/ui/components/Tabs'; -A text input component that allows users to enter and edit text using native Android text fields. +Expo UI TextInput matches the official Jetpack Compose [TextField API](https://developer.android.com/develop/ui/compose/text/user-input) and supports single-line and multiline text input with various keyboard types. ## Installation @@ -19,25 +17,56 @@ A text input component that allows users to enter and edit text using native And ## Usage - - - - - - ```tsx - import { TextInput } from '@expo/ui/jetpack-compose'; - - - ``` - - - - -> See [Official Jetpack Compose documentation](https://developer.android.com/develop/ui/compose/text/user-input) for more information. +### Basic text input + +```tsx BasicTextInputExample.tsx +import { useState } from 'react'; +import { Host, TextInput } from '@expo/ui/jetpack-compose'; + +export default function BasicTextInputExample() { + const [value, setValue] = useState('Hello, world!'); + + return ( + + + + ); +} +``` + +### Multiline text input + +```tsx MultilineTextInputExample.tsx +import { useState } from 'react'; +import { Host, TextInput } from '@expo/ui/jetpack-compose'; + +export default function MultilineTextInputExample() { + const [value, setValue] = useState(''); + + return ( + + + + ); +} +``` + +### Numeric keyboard + +```tsx NumericTextInputExample.tsx +import { useState } from 'react'; +import { Host, TextInput } from '@expo/ui/jetpack-compose'; + +export default function NumericTextInputExample() { + const [value, setValue] = useState(''); + + return ( + + + + ); +} +``` ## API diff --git a/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/togglebutton.mdx b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/togglebutton.mdx new file mode 100644 index 00000000000000..533dbb658d86fc --- /dev/null +++ b/docs/pages/versions/v55.0.0/sdk/ui/jetpack-compose/togglebutton.mdx @@ -0,0 +1,131 @@ +--- +title: ToggleButton +description: A Jetpack Compose ToggleButton component for togglable buttons. +sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-ui' +packageName: '@expo/ui' +platforms: ['android'] +--- + +import APISection from '~/components/plugins/APISection'; +import { APIInstallSection } from '~/components/plugins/InstallSection'; + +Expo UI ToggleButton matches the official Jetpack Compose [Toggle Button](https://developer.android.com/develop/ui/compose/components/button#toggle) API and provides a button that switches between checked and unchecked states with multiple visual variants. + +## Installation + + + +## Usage + +### Basic toggle button + +```tsx BasicToggleButtonExample.tsx +import { useState } from 'react'; +import { Host, ToggleButton } from '@expo/ui/jetpack-compose'; + +export default function BasicToggleButtonExample() { + const [checked, setChecked] = useState(false); + + return ( + + setChecked(value)} + /> + + ); +} +``` + +### Toggle button variants + +Use the `variant` prop to switch between `'default'`, `'icon'`, `'filledIcon'`, and `'outlinedIcon'` styles. + +```tsx ToggleButtonVariantsExample.tsx +import { useState } from 'react'; +import { Host, ToggleButton, Column } from '@expo/ui/jetpack-compose'; +import { paddingAll } from '@expo/ui/jetpack-compose/modifiers'; + +export default function ToggleButtonVariantsExample() { + const [checked1, setChecked1] = useState(false); + const [checked2, setChecked2] = useState(true); + const [checked3, setChecked3] = useState(false); + const [checked4, setChecked4] = useState(true); + + return ( + + + setChecked1(value)} + /> + setChecked2(value)} + /> + setChecked3(value)} + /> + setChecked4(value)} + /> + + + ); +} +``` + +### Toggle button with custom color + +```tsx CustomColorToggleButtonExample.tsx +import { useState } from 'react'; +import { Host, ToggleButton } from '@expo/ui/jetpack-compose'; + +export default function CustomColorToggleButtonExample() { + const [checked, setChecked] = useState(true); + + return ( + + setChecked(value)} + /> + + ); +} +``` + +### Disabled toggle button + +```tsx DisabledToggleButtonExample.tsx +import { Host, ToggleButton } from '@expo/ui/jetpack-compose'; + +export default function DisabledToggleButtonExample() { + return ( + + + + ); +} +``` + +## API + +```tsx +import { ToggleButton } from '@expo/ui/jetpack-compose'; +``` + + diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/alertdialog.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/alertdialog.json new file mode 100644 index 00000000000000..3b196592f2d7e7 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/alertdialog.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/alertdialog","variant":"project","kind":1,"children":[{"name":"AlertDialogButtonColors","variant":"declaration","kind":2097152,"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The background color of the button."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text color of the button."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"AlertDialogProps","variant":"declaration","kind":2097152,"children":[{"name":"confirmButtonColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The colors for the confirm button."}]},"type":{"type":"reference","name":"AlertDialogButtonColors","package":"@expo/ui"}},{"name":"confirmButtonText","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text of the confirm button of the alert dialog."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"dismissButtonColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The colors for the dismiss button."}]},"type":{"type":"reference","name":"AlertDialogButtonColors","package":"@expo/ui"}},{"name":"dismissButtonText","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text of the dismiss button of the alert dialog."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onConfirmPressed","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the user tries to confirm the dialog."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"onDismissPressed","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the user tries to dismiss the dialog."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"text","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text of the alert dialog."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"title","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The title of the alert dialog."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"visible","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the alert dialog is visible."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"NativeAlertDialogProps","variant":"declaration","kind":2097152,"type":{"type":"reference","name":"AlertDialogProps","package":"@expo/ui"}},{"name":"AlertDialog","variant":"declaration","kind":64,"signatures":[{"name":"AlertDialog","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders an "},{"kind":"code","text":"`AlertDialog`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"AlertDialogProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/basicalertdialog.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/basicalertdialog.json new file mode 100644 index 00000000000000..9e429561732ca8 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/basicalertdialog.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/basicalertdialog","variant":"project","kind":1,"children":[{"name":"BasicAlertDialogProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the dialog."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onDismissRequest","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the user tries to dismiss the dialog\n(e.g. by tapping outside of it or pressing the back button)."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"BasicAlertDialog","variant":"declaration","kind":64,"signatures":[{"name":"BasicAlertDialog","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A basic alert dialog that provides a blank container for custom content.\nUnlike "},{"kind":"code","text":"`AlertDialog`"},{"kind":"text","text":", this component does not have structured title/text/buttons slots."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"BasicAlertDialogProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/bottomsheet.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/bottomsheet.json index 7bc06de2e2647b..70bd3b3b8a1f54 100644 --- a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/bottomsheet.json +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/bottomsheet.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/bottomsheet","variant":"project","kind":1,"children":[{"name":"BottomSheetProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The children of the "},{"kind":"code","text":"`BottomSheet`"},{"kind":"text","text":" component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"isOpened","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Whether the "},{"kind":"code","text":"`BottomSheet`"},{"kind":"text","text":" is opened."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"onIsOpenedChange","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the "},{"kind":"code","text":"`BottomSheet`"},{"kind":"text","text":" is opened."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"isOpened","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"boolean"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"skipPartiallyExpanded","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Immediately opens the bottom sheet in full screen."}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"BottomSheet","variant":"declaration","kind":64,"signatures":[{"name":"BottomSheet","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"BottomSheetProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/bottomsheet","variant":"project","kind":1,"children":[{"name":"BottomSheetProps","variant":"declaration","kind":2097152,"comment":{"summary":[],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use "},{"kind":"code","text":"`ModalBottomSheetProps`"},{"kind":"text","text":" instead."}]}]},"type":{"type":"reference","name":"ModalBottomSheetProps","package":"@expo/ui"}},{"name":"ModalBottomSheetProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The children of the "},{"kind":"code","text":"`ModalBottomSheet`"},{"kind":"text","text":" component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onDismissRequest","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the bottom sheet is dismissed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"skipPartiallyExpanded","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Immediately opens the bottom sheet in full screen."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"BottomSheet","variant":"declaration","kind":32,"flags":{"isConst":true},"comment":{"summary":[],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use "},{"kind":"code","text":"`ModalBottomSheet`"},{"kind":"text","text":" instead."}]}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A Material Design modal bottom sheet."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ModalBottomSheetProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}},"defaultValue":"ModalBottomSheet"},{"name":"ModalBottomSheet","variant":"declaration","kind":64,"signatures":[{"name":"ModalBottomSheet","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A Material Design modal bottom sheet."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ModalBottomSheetProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/box.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/box.json new file mode 100644 index 00000000000000..840840c443f428 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/box.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/box","variant":"project","kind":1,"children":[{"name":"BoxProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"contentAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Alignment of children within the box."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"ContentAlignment"},"name":"ContentAlignment","package":"@expo/ui"}},{"name":"floatingToolbarExitAlwaysScrollBehavior","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Scroll behavior for the floating toolbar exit."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"FloatingToolbarExitAlwaysScrollBehavior"},"name":"FloatingToolbarExitAlwaysScrollBehavior","package":"@expo/ui"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Box","variant":"declaration","kind":64,"signatures":[{"name":"Box","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"BoxProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/button.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/button.json index 056bb677992788..9fe096c0dfdc70 100644 --- a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/button.json +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/button.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/button","variant":"project","kind":1,"children":[{"name":"ButtonElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}]},"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}}]},{"name":"ButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text to display inside the button."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"array","elementType":{"type":"intrinsic","name":"string"}},{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"React.JSX.Element","package":"@types/react"}]}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Button color."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Disabled state of the button."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","name":"ButtonElementColors","package":"@expo/ui"}},{"name":"leadingIcon","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the leading icon to display in the button.\nUses Material Icons on Android."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"shape","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"ShapeJSXElement"},"name":"ShapeJSXElement","package":"@expo/ui"}},{"name":"systemImage","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the system image to display in the button.\nUses Material Icons on Android."}],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use "},{"kind":"code","text":"`leadingIcon`"},{"kind":"text","text":" instead."}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"trailingIcon","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the trailing icon to display in the button.\nUses Material Icons on Android."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The button variant."}]},"type":{"type":"reference","name":"ButtonVariant","package":"@expo/ui"}}]},{"name":"ButtonVariant","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"The built-in button styles available on Android.\n- "},{"kind":"code","text":"`outlined`"},{"kind":"text","text":" - A button with an outline.\n- "},{"kind":"code","text":"`elevated`"},{"kind":"text","text":" - A filled button with a shadow."}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"bordered"},{"type":"literal","value":"borderless"},{"type":"literal","value":"outlined"},{"type":"literal","value":"elevated"}]}},{"name":"Button","variant":"declaration","kind":64,"signatures":[{"name":"Button","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native button component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/button","variant":"project","kind":1,"children":[{"name":"ButtonElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}]},"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"ButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text to display inside the button."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"array","elementType":{"type":"intrinsic","name":"string"}},{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"React.JSX.Element","package":"@types/react"}]}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Button color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Disabled state of the button."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","name":"ButtonElementColors","package":"@expo/ui"}},{"name":"leadingIcon","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the leading icon to display in the button.\nUses Material Icons on Android."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"shape","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"ShapeJSXElement"},"name":"ShapeJSXElement","package":"@expo/ui"}},{"name":"systemImage","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the system image to display in the button.\nUses Material Icons on Android."}],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use "},{"kind":"code","text":"`leadingIcon`"},{"kind":"text","text":" instead."}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"trailingIcon","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the trailing icon to display in the button.\nUses Material Icons on Android."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The button variant."}]},"type":{"type":"reference","name":"ButtonVariant","package":"@expo/ui"}}]},{"name":"ButtonVariant","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"The built-in button styles available on Android.\n- "},{"kind":"code","text":"`outlined`"},{"kind":"text","text":" - A button with an outline.\n- "},{"kind":"code","text":"`elevated`"},{"kind":"text","text":" - A filled button with a shadow."}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"bordered"},{"type":"literal","value":"borderless"},{"type":"literal","value":"outlined"},{"type":"literal","value":"elevated"}]}},{"name":"Button","variant":"declaration","kind":64,"signatures":[{"name":"Button","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native button component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/card.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/card.json new file mode 100644 index 00000000000000..ce22c1ee42b412 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/card.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/card","variant":"project","kind":1,"children":[{"name":"CardElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for card's core elements."}]},"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"CardProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the card."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The background color of the card."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for card's core elements."}]},"type":{"type":"reference","name":"CardElementColors","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the card.\n- 'default' - A filled card with no outline.\n- 'elevated' - A filled card with elevation/shadow.\n- 'outlined' - A card with an outline border."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'default'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"elevated"},{"type":"literal","value":"outlined"}]}}]},{"name":"Card","variant":"declaration","kind":64,"signatures":[{"name":"Card","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A card component that provides a surface for content."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"CardProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/carousel.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/carousel.json new file mode 100644 index 00000000000000..1ac2fa44cf3067 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/carousel.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/carousel","variant":"project","kind":1,"children":[{"name":"CarouselProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Children to render"}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"contentPadding","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Padding for carousel content (dp or object)"}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"reference","name":"PaddingValuesRecord","package":"@expo/ui"}]}},{"name":"flingBehavior","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Fling behavior type"}]},"type":{"type":"reference","name":"FlingBehaviorType","package":"@expo/ui"}},{"name":"itemSpacing","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Spacing between items (dp)"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"itemWidth","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Item width (dp) for unconstrained variant"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"maxSmallItemWidth","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Maximum small item width (dp)"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"minSmallItemWidth","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Minimum small item width (dp)"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"preferredItemWidth","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Preferred item width (dp) for multiBrowse variant"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Carousel variant"}]},"type":{"type":"reference","name":"CarouselVariant","package":"@expo/ui"}}]},{"name":"CarouselVariant","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"multiBrowse"},{"type":"literal","value":"unconstrained"}]}},{"name":"FlingBehaviorType","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"singleAdvance"},{"type":"literal","value":"noSnap"}]}},{"name":"PaddingValuesRecord","variant":"declaration","kind":2097152,"children":[{"name":"bottom","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"end","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"start","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"top","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}}]},{"name":"Carousel","variant":"declaration","kind":64,"signatures":[{"name":"Carousel","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"CarouselProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"transformCarouselProps","variant":"declaration","kind":64,"signatures":[{"name":"transformCarouselProps","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"CarouselProps","package":"@expo/ui"}}],"type":{"type":"reference","name":"CarouselProps","package":"@expo/ui"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/column.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/column.json new file mode 100644 index 00000000000000..3313d9bdbffdd6 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/column.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/column","variant":"project","kind":1,"children":[{"name":"ColumnProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"horizontalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal alignment of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalAlignment"},"name":"HorizontalAlignment","package":"@expo/ui"}},{"name":"horizontalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalArrangement"},"name":"HorizontalArrangement","package":"@expo/ui"}},{"name":"verticalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical alignment of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalAlignment"},"name":"VerticalAlignment","package":"@expo/ui"}},{"name":"verticalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalArrangement"},"name":"VerticalArrangement","package":"@expo/ui"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Column","variant":"declaration","kind":64,"signatures":[{"name":"Column","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ColumnProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/contextmenu.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/contextmenu.json index 7b8104fbce683c..3bf7a02324bdd0 100644 --- a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/contextmenu.json +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/contextmenu.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/contextmenu","variant":"project","kind":1,"children":[{"name":"ContextMenuContentProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"union","types":[{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/index.tsx","qualifiedName":"SubmenuElement"},"name":"SubmenuElement","package":"@expo/ui"},{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/index.tsx","qualifiedName":"SubmenuElement"},"name":"SubmenuElement","package":"@expo/ui"}}]}}]},{"name":"ContextMenuProps","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Props of the "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":" component."}]},"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The contents of the submenu are used as an anchor for the context menu.\nThe children will be wrapped in a pressable element, which triggers opening of the context menu."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the container holding the context menu items."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional styles to apply to the "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":"."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"StyleProp"},"typeArguments":[{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheetTypes.d.ts","qualifiedName":"ViewStyle"},"name":"ViewStyle","package":"react-native"}],"name":"StyleProp","package":"react-native"}}]},{"name":"ContextMenu","variant":"declaration","kind":64,"children":[{"name":"Items","variant":"declaration","kind":1024,"type":{"type":"query","queryType":{"type":"reference","name":"Items","package":"@expo/ui"}}},{"name":"Preview","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Trigger","variant":"declaration","kind":1024,"type":{"type":"query","queryType":{"type":"reference","name":"Trigger","package":"@expo/ui"}}}],"signatures":[{"name":"ContextMenu","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ContextMenuProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Items","variant":"declaration","kind":64,"children":[{"name":"tag","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}],"signatures":[{"name":"Items","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ContextMenuContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Preview","variant":"declaration","kind":64,"signatures":[{"name":"Preview","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Submenu","variant":"declaration","kind":64,"signatures":[{"name":"Submenu","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/Submenu.tsx","qualifiedName":"SubmenuProps"},"name":"SubmenuProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Trigger","variant":"declaration","kind":64,"children":[{"name":"tag","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}],"signatures":[{"name":"Trigger","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/contextmenu","variant":"project","kind":1,"children":[{"name":"ContextMenuContentProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"union","types":[{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/index.tsx","qualifiedName":"SubmenuElement"},"name":"SubmenuElement","package":"@expo/ui"},{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/index.tsx","qualifiedName":"SubmenuElement"},"name":"SubmenuElement","package":"@expo/ui"}}]}}]},{"name":"ContextMenuProps","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Props of the "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":" component."}]},"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The contents of the submenu are used as an anchor for the context menu.\nThe children will be wrapped in a pressable element, which triggers opening of the context menu."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the container holding the context menu items."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional styles to apply to the "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":"."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"StyleProp"},"typeArguments":[{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheetTypes.d.ts","qualifiedName":"ViewStyle"},"name":"ViewStyle","package":"react-native"}],"name":"StyleProp","package":"react-native"}}]},{"name":"ContextMenu","variant":"declaration","kind":64,"children":[{"name":"Items","variant":"declaration","kind":1024,"type":{"type":"query","queryType":{"type":"reference","name":"Items","package":"@expo/ui"}}},{"name":"Preview","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Trigger","variant":"declaration","kind":1024,"type":{"type":"query","queryType":{"type":"reference","name":"Trigger","package":"@expo/ui"}}}],"signatures":[{"name":"ContextMenu","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ContextMenuProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Items","variant":"declaration","kind":64,"children":[{"name":"tag","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}],"signatures":[{"name":"Items","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ContextMenuContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Preview","variant":"declaration","kind":64,"signatures":[{"name":"Preview","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Submenu","variant":"declaration","kind":64,"signatures":[{"name":"Submenu","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/Submenu.tsx","qualifiedName":"SubmenuProps"},"name":"SubmenuProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Trigger","variant":"declaration","kind":64,"children":[{"name":"tag","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}],"signatures":[{"name":"Trigger","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/datetimepicker.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/datetimepicker.json index 5fc41fd7147571..bc37658f4d5097 100644 --- a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/datetimepicker.json +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/datetimepicker.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/datetimepicker","variant":"project","kind":1,"children":[{"name":"AndroidVariant","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"picker"},{"type":"literal","value":"input"}]}},{"name":"DateTimePickerProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The tint color to use on the picker elements."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"displayedComponents","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The components that the picker should display.\nOn Android, you can have a picker that selects just the date or just the time.\n"},{"kind":"code","text":"`dateAndTime`"},{"kind":"text","text":" is only available on iOS and will result in a date picker on Android.\nOn iOS, you can have a picker that selects both date and time."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'date'"}]}]},"type":{"type":"reference","name":"DisplayedComponents","package":"@expo/ui"}},{"name":"initialDate","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The initial date to display on the picker."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"literal","value":null}]}},{"name":"is24Hour","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Determines what format the clock should be displayed in on Android."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onDateSelected","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when a date is selected."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"date","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Date"},"name":"Date","package":"typescript"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"showVariantToggle","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Show to button to toggle between variants on Android."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the picker, which determines its appearance and behavior."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'picker'"}]}]},"type":{"type":"reference","name":"AndroidVariant","package":"@expo/ui"}}]},{"name":"DisplayedComponents","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"date"},{"type":"literal","value":"hourAndMinute"},{"type":"literal","value":"dateAndTime"}]}},{"name":"DateTimePicker","variant":"declaration","kind":64,"signatures":[{"name":"DateTimePicker","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`DateTimePicker`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"DateTimePickerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/datetimepicker","variant":"project","kind":1,"children":[{"name":"AndroidVariant","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"picker"},{"type":"literal","value":"input"}]}},{"name":"DateTimePickerProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The tint color to use on the picker elements."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"displayedComponents","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The components that the picker should display.\nOn Android, you can have a picker that selects just the date or just the time.\n"},{"kind":"code","text":"`dateAndTime`"},{"kind":"text","text":" is only available on iOS and will result in a date picker on Android.\nOn iOS, you can have a picker that selects both date and time."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'date'"}]}]},"type":{"type":"reference","name":"DisplayedComponents","package":"@expo/ui"}},{"name":"initialDate","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The initial date to display on the picker."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"literal","value":null}]}},{"name":"is24Hour","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Determines what format the clock should be displayed in on Android."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onDateSelected","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when a date is selected."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"date","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Date"},"name":"Date","package":"typescript"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"showVariantToggle","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Show to button to toggle between variants on Android."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the picker, which determines its appearance and behavior."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'picker'"}]}]},"type":{"type":"reference","name":"AndroidVariant","package":"@expo/ui"}}]},{"name":"DisplayedComponents","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"date"},{"type":"literal","value":"hourAndMinute"},{"type":"literal","value":"dateAndTime"}]}},{"name":"DateTimePicker","variant":"declaration","kind":64,"signatures":[{"name":"DateTimePicker","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`DateTimePicker`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"DateTimePickerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/divider.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/divider.json new file mode 100644 index 00000000000000..dcf884d442bb23 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/divider.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/divider","variant":"project","kind":1,"children":[{"name":"DividerProps","variant":"declaration","kind":2097152,"children":[{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}}]},{"name":"Divider","variant":"declaration","kind":64,"signatures":[{"name":"Divider","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A visual element that can be used to separate other content."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"DividerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/dockedsearchbar.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/dockedsearchbar.json new file mode 100644 index 00000000000000..13d8a3587ec36e --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/dockedsearchbar.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/dockedsearchbar","variant":"project","kind":1,"children":[{"name":"DockedSearchBarProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The children of the component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onQueryChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the search query changes."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"query","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"DockedSearchBar","variant":"declaration","kind":64,"children":[{"name":"LeadingIcon","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/DockedSearchBar/index.tsx","qualifiedName":"LeadingIconProps"},"name":"LeadingIconProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Placeholder","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/DockedSearchBar/index.tsx","qualifiedName":"PlaceholderProps"},"name":"PlaceholderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"DockedSearchBar","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"DockedSearchBarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"DockedSearchBarLeadingIcon","variant":"declaration","kind":64,"signatures":[{"name":"DockedSearchBarLeadingIcon","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/DockedSearchBar/index.tsx","qualifiedName":"LeadingIconProps"},"name":"LeadingIconProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"DockedSearchBarPlaceholder","variant":"declaration","kind":64,"signatures":[{"name":"DockedSearchBarPlaceholder","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/DockedSearchBar/index.tsx","qualifiedName":"PlaceholderProps"},"name":"PlaceholderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/filterchip.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/filterchip.json new file mode 100644 index 00000000000000..1f6e5d8aa785af --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/filterchip.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/filterchip","variant":"project","kind":1,"children":[{"name":"FilterChipProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Children containing LeadingIcon and TrailingIcon slots."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"enabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the chip is enabled and can be interacted with."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"label","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The text label to display on the chip."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback fired when the chip is clicked."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"selected","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Whether the chip is currently selected."}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"FilterChip","variant":"declaration","kind":64,"children":[{"name":"LeadingIcon","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Leading icon slot for FilterChip."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/FilterChip/index.tsx","qualifiedName":"SlotChildProps"},"name":"SlotChildProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"TrailingIcon","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Trailing icon slot for FilterChip."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/FilterChip/index.tsx","qualifiedName":"SlotChildProps"},"name":"SlotChildProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"FilterChip","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A filter chip component following Material 3 design guidelines.\nSupports slot-based "},{"kind":"code","text":"`LeadingIcon`"},{"kind":"text","text":" and "},{"kind":"code","text":"`TrailingIcon`"},{"kind":"text","text":" children."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"FilterChipProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/flowrow.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/flowrow.json new file mode 100644 index 00000000000000..e0e29e85982f00 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/flowrow.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/flowrow","variant":"project","kind":1,"children":[{"name":"FlowRowProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"horizontalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalArrangement"},"name":"HorizontalArrangement","package":"@expo/ui"}},{"name":"verticalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalArrangement"},"name":"VerticalArrangement","package":"@expo/ui"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"FlowRow","variant":"declaration","kind":64,"signatures":[{"name":"FlowRow","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"FlowRowProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/horizontalfloatingtoolbar.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/horizontalfloatingtoolbar.json new file mode 100644 index 00000000000000..4334a33b016461 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/horizontalfloatingtoolbar.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/horizontalfloatingtoolbar","variant":"project","kind":1,"children":[{"name":"FloatingActionButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The children of the component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"HorizontalFloatingToolbarProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The children of the component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the horizontal floating toolbar."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'standard'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"standard"},{"type":"literal","value":"vibrant"}]}}]},{"name":"HorizontalFloatingToolbar","variant":"declaration","kind":64,"children":[{"name":"FloatingActionButton","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"FloatingActionButton component for HorizontalFloatingToolbar.\nThis component marks its children to be rendered in the FAB slot."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"FloatingActionButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"HorizontalFloatingToolbar","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`HorizontalFloatingToolbar`"},{"kind":"text","text":" component.\nA horizontal toolbar that floats above content, typically used for action buttons."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"HorizontalFloatingToolbarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"HorizontalFloatingToolbarFloatingActionButton","variant":"declaration","kind":64,"signatures":[{"name":"HorizontalFloatingToolbarFloatingActionButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"FloatingActionButton component for HorizontalFloatingToolbar.\nThis component marks its children to be rendered in the FAB slot."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"FloatingActionButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/host.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/host.json index 0d89ace06809bb..95fb36ef0c1662 100644 --- a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/host.json +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/host.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/host","variant":"project","kind":1,"children":[{"name":"HostProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"colorScheme","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color scheme of the host view."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/Utilities/Appearance.d.ts","qualifiedName":"ColorSchemeName"},"name":"ColorSchemeName","package":"react-native"}},{"name":"ignoreSafeAreaKeyboardInsets","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When "},{"kind":"code","text":"`true`"},{"kind":"text","text":", the Compose content will not perform keyboard avoidance behaviour when keyboard is shown.\nCan be only set once on mount."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"layoutDirection","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The layout direction for the content.\nDefaults to the current locale direction from I18nManager."}]},"type":{"type":"union","types":[{"type":"literal","value":"leftToRight"},{"type":"literal","value":"rightToLeft"}]}},{"name":"matchContents","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When true, the host view will update its size in the React Native view tree to match the content's layout from Jetpack Compose.\nCan be only set once on mount."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"horizontal","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"boolean"}},{"name":"vertical","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"boolean"}}]}}]}},{"name":"onLayoutContent","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is triggered when the Jetpack Compose content completes its layout.\nProvides the current dimensions of the content, which may change as the content updates."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"event","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"nativeEvent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"height","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}},{"name":"width","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}}]}}}]}}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"StyleProp"},"typeArguments":[{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheetTypes.d.ts","qualifiedName":"ViewStyle"},"name":"ViewStyle","package":"react-native"}],"name":"StyleProp","package":"react-native"}},{"name":"useViewportSizeMeasurement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When true and no explicit size is provided, the host will use the viewport size as the proposed size for Compose layout.\nThis is particularly useful for views that need to fill their available space."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout.tsx","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Host","variant":"declaration","kind":64,"signatures":[{"name":"Host","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"HostProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/host","variant":"project","kind":1,"children":[{"name":"HostProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"colorScheme","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color scheme of the host view."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/Utilities/Appearance.d.ts","qualifiedName":"ColorSchemeName"},"name":"ColorSchemeName","package":"react-native"}},{"name":"ignoreSafeAreaKeyboardInsets","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When "},{"kind":"code","text":"`true`"},{"kind":"text","text":", the Compose content will not perform keyboard avoidance behaviour when keyboard is shown.\nCan be only set once on mount."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"layoutDirection","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The layout direction for the content.\nDefaults to the current locale direction from I18nManager."}]},"type":{"type":"union","types":[{"type":"literal","value":"leftToRight"},{"type":"literal","value":"rightToLeft"}]}},{"name":"matchContents","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When true, the host view will update its size in the React Native view tree to match the content's layout from Jetpack Compose.\nCan be only set once on mount."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"horizontal","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"boolean"}},{"name":"vertical","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"boolean"}}]}}]}},{"name":"onLayoutContent","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is triggered when the Jetpack Compose content completes its layout.\nProvides the current dimensions of the content, which may change as the content updates."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"event","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"nativeEvent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"height","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}},{"name":"width","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}}]}}}]}}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"StyleProp"},"typeArguments":[{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheetTypes.d.ts","qualifiedName":"ViewStyle"},"name":"ViewStyle","package":"react-native"}],"name":"StyleProp","package":"react-native"}},{"name":"useViewportSizeMeasurement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When true and no explicit size is provided, the host will use the viewport size as the proposed size for Compose layout.\nThis is particularly useful for views that need to fill their available space."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Host","variant":"declaration","kind":64,"signatures":[{"name":"Host","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"HostProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/icon.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/icon.json new file mode 100644 index 00000000000000..6da3ec7c1b4ab4 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/icon.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/icon","variant":"project","kind":1,"children":[{"name":"IconProps","variant":"declaration","kind":2097152,"children":[{"name":"contentDescription","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Accessibility label for the icon.\nUsed by screen readers to describe the icon to users."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n```"}]}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component.\nAllows you to apply layout and styling modifiers to the icon."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n```"}]}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"size","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The size of the icon in density-independent pixels (dp).\nIf not specified, the icon will use its intrinsic size."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n```"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"source","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The source of the icon. Can be a URI string or the result of "},{"kind":"code","text":"`require()`"},{"kind":"text","text":".\nOn Android, supports XML vector drawables loaded via Metro bundler."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n\n```"}]}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/Image/Image.d.ts","qualifiedName":"ImageSourcePropType"},"name":"ImageSourcePropType","package":"react-native"}},{"name":"tintColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The tint color to apply to the icon.\nAccepts hex strings, named colors, or RGB arrays."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n\n```"}]}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"Icon","variant":"declaration","kind":64,"signatures":[{"name":"Icon","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays an icon from an XML vector drawable or other image source.\n\nThe Icon component renders vector graphics and images with support for\ntinting, sizing, and accessibility features. On Android, it natively\nsupports XML vector drawables loaded via Metro bundler using "},{"kind":"code","text":"`require()`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@example","content":[{"kind":"text","text":"Basic usage:\n"},{"kind":"code","text":"```tsx\nimport { Icon } from 'expo-ui';\n\n\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"With styling:\n"},{"kind":"code","text":"```tsx\n\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"With modifiers:\n"},{"kind":"code","text":"```tsx\n\n```"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"IconProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/iconbutton.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/iconbutton.json new file mode 100644 index 00000000000000..6fc644174d5639 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/iconbutton.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/iconbutton","variant":"project","kind":1,"children":[{"name":"IconButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text to display inside the button."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"React.JSX.Element","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Button color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Disabled state of the button."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/index.tsx","qualifiedName":"ButtonElementColors"},"name":"ButtonElementColors","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"shape","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"ShapeJSXElement"},"name":"ShapeJSXElement","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The button variant."}]},"type":{"type":"reference","name":"IconButtonVariant","package":"@expo/ui"}}]},{"name":"IconButtonVariant","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"The built-in button styles available on Android.\n- "},{"kind":"code","text":"`outlined`"},{"kind":"text","text":" - A button with an outline.\n- "},{"kind":"code","text":"`elevated`"},{"kind":"text","text":" - A filled button with a shadow."}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"bordered"},{"type":"literal","value":"outlined"}]}},{"name":"IconButton","variant":"declaration","kind":64,"signatures":[{"name":"IconButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native button component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"IconButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/lazycolumn.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/lazycolumn.json new file mode 100644 index 00000000000000..de2b7f868412e2 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/lazycolumn.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/lazycolumn","variant":"project","kind":1,"children":[{"name":"ContentPadding","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Content padding values for LazyColumn."}]},"children":[{"name":"bottom","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Bottom padding in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"end","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"End padding in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"start","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Start padding in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"top","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Top padding in dp."}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"LazyColumnProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the lazy column."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"contentPadding","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Content padding in dp."}]},"type":{"type":"reference","name":"ContentPadding","package":"@expo/ui"}},{"name":"horizontalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The horizontal alignment of items."}]},"type":{"type":"union","types":[{"type":"literal","value":"start"},{"type":"literal","value":"end"},{"type":"literal","value":"center"}]}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"verticalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The vertical arrangement of items.\nCan be a preset string or an object with "},{"kind":"code","text":"`spacedBy`"},{"kind":"text","text":" to specify spacing in dp."}]},"type":{"type":"union","types":[{"type":"literal","value":"top"},{"type":"literal","value":"bottom"},{"type":"literal","value":"center"},{"type":"literal","value":"spaceBetween"},{"type":"literal","value":"spaceAround"},{"type":"literal","value":"spaceEvenly"},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"spacedBy","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}}]}}]}}]},{"name":"LazyColumn","variant":"declaration","kind":64,"signatures":[{"name":"LazyColumn","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A lazy column component that efficiently displays a vertically scrolling list."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"LazyColumnProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/listitem.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/listitem.json new file mode 100644 index 00000000000000..0ffdffba87a6f9 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/listitem.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/listitem","variant":"project","kind":1,"children":[{"name":"ListItemColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for list item's core elements."}]},"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"headlineColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"leadingIconColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"overlineColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"supportingColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"trailingIconColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"ListItemProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Children containing Leading and Trailing slots."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The background color of the list item."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"colors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for list item's core elements."}]},"type":{"type":"reference","name":"ListItemColors","package":"@expo/ui"}},{"name":"headline","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The main text content of the list item."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the list item is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"overlineText","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional overline text displayed above the headline."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"supportingText","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional supporting text displayed below the headline."}]},"type":{"type":"intrinsic","name":"string"}}]},{"name":"ListItem","variant":"declaration","kind":64,"children":[{"name":"Leading","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Leading content slot for ListItem."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"LeadingProps"},"name":"LeadingProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"SupportingContent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Custom supporting content slot for ListItem.\nWhen provided, this takes precedence over the "},{"kind":"code","text":"`supportingText`"},{"kind":"text","text":" prop."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"SupportingContentProps"},"name":"SupportingContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Trailing","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Trailing content slot for ListItem."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"TrailingProps"},"name":"TrailingProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"ListItem","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A list item component following Material 3 design guidelines."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ListItemProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"ListItemLeading","variant":"declaration","kind":64,"signatures":[{"name":"ListItemLeading","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Leading content slot for ListItem."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"LeadingProps"},"name":"LeadingProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"ListItemSupportingContent","variant":"declaration","kind":64,"signatures":[{"name":"ListItemSupportingContent","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Custom supporting content slot for ListItem.\nWhen provided, this takes precedence over the "},{"kind":"code","text":"`supportingText`"},{"kind":"text","text":" prop."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"SupportingContentProps"},"name":"SupportingContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"ListItemTrailing","variant":"declaration","kind":64,"signatures":[{"name":"ListItemTrailing","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Trailing content slot for ListItem."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"TrailingProps"},"name":"TrailingProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/modifiers.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/modifiers.json new file mode 100644 index 00000000000000..0cbe57b4e29204 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/modifiers.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/modifiers","variant":"project","kind":1,"children":[{"name":"Alignment","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"topStart"},{"type":"literal","value":"topCenter"},{"type":"literal","value":"topEnd"},{"type":"literal","value":"centerStart"},{"type":"literal","value":"center"},{"type":"literal","value":"centerEnd"},{"type":"literal","value":"bottomStart"},{"type":"literal","value":"bottomCenter"},{"type":"literal","value":"bottomEnd"},{"type":"literal","value":"top"},{"type":"literal","value":"centerVertically"},{"type":"literal","value":"bottom"},{"type":"literal","value":"start"},{"type":"literal","value":"centerHorizontally"},{"type":"literal","value":"end"}]}},{"name":"BuiltinShape","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Built-in Jetpack Compose shape for the clip modifier."}]},"type":{"type":"union","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"rectangle"}}]}},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"circle"}}]}},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"bottomEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"bottomStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"radius","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"topEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"topStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"roundedCorner"}}]}},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"bottomEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"bottomStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"radius","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"topEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"topStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"cutCorner"}}]}},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"name","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/index.ts","qualifiedName":"MaterialShapeName"},"name":"MaterialShapeName","package":"@expo/ui"}},{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"material"}}]}}]}},{"name":"ExpoModifier","variant":"declaration","kind":2097152,"comment":{"summary":[],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use ModifierConfig instead. ExpoModifier (SharedRef pattern) has been replaced\nwith JSON Config pattern for better DX and platform consistency."}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}},{"name":"Shapes","variant":"declaration","kind":32,"flags":{"isConst":true},"comment":{"summary":[{"kind":"text","text":"Predefined shapes for use with the "},{"kind":"code","text":"`clip`"},{"kind":"text","text":" modifier."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\nclip(Shapes.Circle)\nclip(Shapes.RoundedCorner(16))\nclip(Shapes.RoundedCorner({ topStart: 8, bottomEnd: 16 }))\nclip(Shapes.Material.Heart)\n```"}]}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"Circle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"CutCorner","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"params","variant":"param","kind":32768,"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/index.ts","qualifiedName":"CornerRadii"},"name":"CornerRadii","package":"@expo/ui"}]}}],"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"}}]}},"defaultValue":"..."},{"name":"Material","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"Arch","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Boom","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Bun","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Clover4Leaf","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Clover8Leaf","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie12Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie4Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie6Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie7Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie9Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Diamond","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Fan","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Ghostish","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Heart","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Oval","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Pentagon","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Pill","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"PixelCircle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"PixelTriangle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Puffy","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"PuffyDiamond","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Slanted","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"SoftBurst","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Sunny","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Triangle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"VerySunny","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."}]}},"defaultValue":"..."},{"name":"Rectangle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"RoundedCorner","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"params","variant":"param","kind":32768,"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/index.ts","qualifiedName":"CornerRadii"},"name":"CornerRadii","package":"@expo/ui"}]}}],"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"}}]}},"defaultValue":"..."}]}},"defaultValue":"..."},{"name":"align","variant":"declaration","kind":64,"signatures":[{"name":"align","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Aligns the view within its container."}]},"parameters":[{"name":"alignment","variant":"param","kind":32768,"type":{"type":"reference","name":"Alignment","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"alpha","variant":"declaration","kind":64,"signatures":[{"name":"alpha","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the opacity/alpha of the view."}]},"parameters":[{"name":"alpha","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Opacity value (0.0 to 1.0)."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"animateContentSize","variant":"declaration","kind":64,"signatures":[{"name":"animateContentSize","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Animates size changes with spring animation."}]},"parameters":[{"name":"dampingRatio","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Spring damping ratio. Default is DampingRatioNoBouncy."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"stiffness","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Spring stiffness. Default is StiffnessMedium."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"background","variant":"declaration","kind":64,"signatures":[{"name":"background","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the background color."}]},"parameters":[{"name":"color","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Color string (hex, e.g., '#FF0000')."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"blur","variant":"declaration","kind":64,"signatures":[{"name":"blur","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Applies a blur effect."}]},"parameters":[{"name":"radius","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Blur radius in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"border","variant":"declaration","kind":64,"signatures":[{"name":"border","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Adds a border around the view."}]},"parameters":[{"name":"borderWidth","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Border width in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"borderColor","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Border color string (hex)."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"clickable","variant":"declaration","kind":64,"signatures":[{"name":"clickable","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Makes the view clickable."}]},"parameters":[{"name":"handler","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Function to call when clicked."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"clip","variant":"declaration","kind":64,"signatures":[{"name":"clip","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Clips the view to a built-in Jetpack Compose shape."}]},"parameters":[{"name":"shape","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"A shape from "},{"kind":"code","text":"`Shapes`"},{"kind":"text","text":", e.g. "},{"kind":"code","text":"`Shapes.Circle`"},{"kind":"text","text":" or "},{"kind":"code","text":"`Shapes.Material.Heart`"},{"kind":"text","text":"."}]},"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"fillMaxHeight","variant":"declaration","kind":64,"signatures":[{"name":"fillMaxHeight","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Fills the maximum available height."}]},"parameters":[{"name":"fraction","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Fraction of max height (0.0 to 1.0). Default is 1.0."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"fillMaxSize","variant":"declaration","kind":64,"signatures":[{"name":"fillMaxSize","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Fills the maximum available size."}]},"parameters":[{"name":"fraction","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Fraction of max size (0.0 to 1.0). Default is 1.0."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"fillMaxWidth","variant":"declaration","kind":64,"signatures":[{"name":"fillMaxWidth","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Fills the maximum available width."}]},"parameters":[{"name":"fraction","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Fraction of max width (0.0 to 1.0). Default is 1.0."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"height","variant":"declaration","kind":64,"signatures":[{"name":"height","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the exact height of the view."}]},"parameters":[{"name":"value","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Height in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"matchParentSize","variant":"declaration","kind":64,"signatures":[{"name":"matchParentSize","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Makes the view match the parent Box size.\nOnly works when used inside Box."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"offset","variant":"declaration","kind":64,"signatures":[{"name":"offset","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Offsets the view from its natural position."}]},"parameters":[{"name":"x","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Horizontal offset in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"y","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Vertical offset in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"padding","variant":"declaration","kind":64,"signatures":[{"name":"padding","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Applies padding with individual values for each side."}]},"parameters":[{"name":"start","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Left padding in dp (or right in RTL)."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"top","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Top padding in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"end","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Right padding in dp (or left in RTL)."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"bottom","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Bottom padding in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"paddingAll","variant":"declaration","kind":64,"signatures":[{"name":"paddingAll","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Applies equal padding on all sides."}]},"parameters":[{"name":"all","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Padding value in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"rotate","variant":"declaration","kind":64,"signatures":[{"name":"rotate","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Rotates the view."}]},"parameters":[{"name":"degrees","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Rotation angle in degrees."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"selectable","variant":"declaration","kind":64,"signatures":[{"name":"selectable","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Makes the view selectable, like a radio button row."}]},"parameters":[{"name":"selected","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Whether the item is currently selected."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"handler","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Function to call when the item is clicked."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"shadow","variant":"declaration","kind":64,"signatures":[{"name":"shadow","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Adds a shadow/elevation effect."}]},"parameters":[{"name":"elevation","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Shadow elevation in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"size","variant":"declaration","kind":64,"signatures":[{"name":"size","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets exact width and height."}]},"parameters":[{"name":"width","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Width in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"height","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Height in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"testID","variant":"declaration","kind":64,"signatures":[{"name":"testID","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the test ID for testing frameworks."}]},"parameters":[{"name":"tag","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Test ID string."}]},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"weight","variant":"declaration","kind":64,"signatures":[{"name":"weight","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the weight for flexible sizing in Row or Column.\nOnly works when used inside Row or Column."}]},"parameters":[{"name":"weight","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Weight value (relative to siblings)."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"width","variant":"declaration","kind":64,"signatures":[{"name":"width","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the exact width of the view."}]},"parameters":[{"name":"value","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Width in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"wrapContentHeight","variant":"declaration","kind":64,"signatures":[{"name":"wrapContentHeight","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Wraps the height to the content size."}]},"parameters":[{"name":"alignment","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional vertical alignment ('top', 'centerVertically', 'bottom')."}]},"type":{"type":"union","types":[{"type":"literal","value":"top"},{"type":"literal","value":"bottom"},{"type":"literal","value":"centerVertically"}]}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"wrapContentWidth","variant":"declaration","kind":64,"signatures":[{"name":"wrapContentWidth","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Wraps the width to the content size."}]},"parameters":[{"name":"alignment","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional horizontal alignment ('start', 'centerHorizontally', 'end')."}]},"type":{"type":"union","types":[{"type":"literal","value":"start"},{"type":"literal","value":"end"},{"type":"literal","value":"centerHorizontally"}]}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"zIndex","variant":"declaration","kind":64,"signatures":[{"name":"zIndex","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the z-index for layering."}]},"parameters":[{"name":"index","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Z-index value."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/picker.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/picker.json index 08493207e5efb7..d51c2971881e70 100644 --- a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/picker.json +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/picker.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/picker","variant":"project","kind":1,"children":[{"name":"PickerElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for picker's core elements."}]},"children":[{"name":"activeBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"activeContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"activeContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledActiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledActiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledActiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledInactiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledInactiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledInactiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}}]},{"name":"PickerProps","variant":"declaration","kind":2097152,"children":[{"name":"buttonModifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the individual buttons"}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Picker color."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for picker's core elements."}]},"type":{"type":"reference","name":"PickerElementColors","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onOptionSelected","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when an option is selected."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"event","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"nativeEvent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"index","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}},{"name":"label","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}]}}}]}}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"options","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"An array of options to be displayed in the picker."}]},"type":{"type":"array","elementType":{"type":"intrinsic","name":"string"}}},{"name":"selectedIndex","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The index of the currently selected option."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"literal","value":null}]}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the picker, which determines its appearance and behavior."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'segmented'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"segmented"},{"type":"literal","value":"radio"}]}}]},{"name":"Picker","variant":"declaration","kind":64,"signatures":[{"name":"Picker","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native picker component. Depending on the variant it can be a segmented button, an inline picker, a list of choices or a radio button."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"PickerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/picker","variant":"project","kind":1,"children":[{"name":"PickerElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for picker's core elements."}]},"children":[{"name":"activeBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"activeContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"activeContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledActiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledActiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledActiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledInactiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledInactiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledInactiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"PickerProps","variant":"declaration","kind":2097152,"children":[{"name":"buttonModifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the individual buttons"}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Picker color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for picker's core elements."}]},"type":{"type":"reference","name":"PickerElementColors","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onOptionSelected","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when an option is selected."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"event","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"nativeEvent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"index","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}},{"name":"label","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}]}}}]}}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"options","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"An array of options to be displayed in the picker."}]},"type":{"type":"array","elementType":{"type":"intrinsic","name":"string"}}},{"name":"selectedIndex","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The index of the currently selected option."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"literal","value":null}]}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the picker, which determines its appearance and behavior."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'segmented'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"segmented"},{"type":"literal","value":"radio"}]}}]},{"name":"Picker","variant":"declaration","kind":64,"signatures":[{"name":"Picker","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native picker component. Depending on the variant it can be a segmented button, an inline picker, a list of choices or a radio button."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"PickerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/pulltorefreshbox.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/pulltorefreshbox.json new file mode 100644 index 00000000000000..33d3dd08d418ba --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/pulltorefreshbox.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/pulltorefreshbox","variant":"project","kind":1,"children":[{"name":"PullToRefreshBoxProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The content to refresh."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"isRefreshing","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the content is refreshing."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"loadingIndicatorModifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the loading indicator."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"[align('topCenter'), padding(0, 10, 0, 0)]"}]}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onRefresh","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback to call when the content is refreshed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"PullToRefreshBox","variant":"declaration","kind":64,"signatures":[{"name":"PullToRefreshBox","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`PullToRefreshBox`"},{"kind":"text","text":" component.\nA box that allows the user to pull down to refresh the content."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"PullToRefreshBoxProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/radiobutton.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/radiobutton.json new file mode 100644 index 00000000000000..fddd85bf0c75df --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/radiobutton.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/radiobutton","variant":"project","kind":1,"children":[{"name":"RadioButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onClick","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the radio button is clicked."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"selected","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Whether the radio button is selected."}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"RadioButton","variant":"declaration","kind":64,"signatures":[{"name":"RadioButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A Material Design radio button."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"RadioButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/rnhostview.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/rnhostview.json new file mode 100644 index 00000000000000..9c2e95fee1ced5 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/rnhostview.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/rnhostview","variant":"project","kind":1,"children":[{"name":"RNHostView","variant":"declaration","kind":64,"signatures":[{"name":"RNHostView","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/RNHostView/index.tsx","qualifiedName":"RNHostProps"},"name":"RNHostProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/row.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/row.json new file mode 100644 index 00000000000000..5677e37f195317 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/row.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/row","variant":"project","kind":1,"children":[{"name":"RowProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"horizontalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal alignment of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalAlignment"},"name":"HorizontalAlignment","package":"@expo/ui"}},{"name":"horizontalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalArrangement"},"name":"HorizontalArrangement","package":"@expo/ui"}},{"name":"verticalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical alignment of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalAlignment"},"name":"VerticalAlignment","package":"@expo/ui"}},{"name":"verticalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalArrangement"},"name":"VerticalArrangement","package":"@expo/ui"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Row","variant":"declaration","kind":64,"signatures":[{"name":"Row","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"RowProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/searchbar.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/searchbar.json new file mode 100644 index 00000000000000..8c2c9bdb436d2d --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/searchbar.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/searchbar","variant":"project","kind":1,"children":[{"name":"SearchBarProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The children of the component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onSearch","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the search text is submitted."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"searchText","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"ExpandedFullScreenSearchBar","variant":"declaration","kind":64,"signatures":[{"name":"ExpandedFullScreenSearchBar","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"ExpandedFullScreenSearchBar component for SearchBar.\nThis component marks its children to be rendered in the expanded full-screen search bar."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/SearchBar/index.tsx","qualifiedName":"ExpandedFullScreenSearchBarProps"},"name":"ExpandedFullScreenSearchBarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"SearchBar","variant":"declaration","kind":64,"children":[{"name":"ExpandedFullScreenSearchBar","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"ExpandedFullScreenSearchBar component for SearchBar.\nThis component marks its children to be rendered in the expanded full-screen search bar."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/SearchBar/index.tsx","qualifiedName":"ExpandedFullScreenSearchBarProps"},"name":"ExpandedFullScreenSearchBarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Placeholder","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Placeholder component for SearchBar.\nThis component marks its children to be rendered in the placeholder slot."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/SearchBar/index.tsx","qualifiedName":"PlaceholderProps"},"name":"PlaceholderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"SearchBar","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`SearchBar`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SearchBarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"SearchBarPlaceholder","variant":"declaration","kind":64,"signatures":[{"name":"SearchBarPlaceholder","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Placeholder component for SearchBar.\nThis component marks its children to be rendered in the placeholder slot."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/SearchBar/index.tsx","qualifiedName":"PlaceholderProps"},"name":"PlaceholderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/shape.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/shape.json new file mode 100644 index 00000000000000..bad67ff9cca2a1 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/shape.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/shape","variant":"project","kind":1,"children":[{"name":"CornerRadii","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Corner radii for RoundedCorner shape."}]},"children":[{"name":"bottomEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Bottom-end corner radius in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"bottomStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Bottom-start corner radius in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"topEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Top-end corner radius in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"topStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Top-start corner radius in dp."}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"ShapeJSXElement","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactElement"},"typeArguments":[{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"NativeShapeProps"},"name":"NativeShapeProps","package":"@expo/ui"}],"name":"React.ReactElement","package":"@types/react"},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"__expo_shape_jsx_element_marker","variant":"declaration","kind":1024,"type":{"type":"literal","value":true}}]}}]}},{"name":"ShapeProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Color of the shape"}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"cornerRadii","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Corner radii for RoundedCorner shape. Values are in dp."}]},"type":{"type":"reference","name":"CornerRadii","package":"@expo/ui"}},{"name":"cornerRounding","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Corner rounding percentage. Multiplied by the shorter dimension of the view to produce pixel values."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0.0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"innerRadius","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Inner radius of star-related shapes ("},{"kind":"code","text":"`'STAR'`"},{"kind":"text","text":" and "},{"kind":"code","text":"`'PILL_STAR'`"},{"kind":"text","text":"). Multiplied by the shorter dimension of the view to produce pixel values."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"1.0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"radius","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Radius of the circular shape. Multiplied by the shorter dimension of the view to produce pixel values."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"1.0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"smoothing","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Number between "},{"kind":"code","text":"`0.0`"},{"kind":"text","text":" and "},{"kind":"code","text":"`1.0`"},{"kind":"text","text":" that determines how much each line between vertices is \"smoothed\"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0.0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"verticesCount","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Number of vertices. For "},{"kind":"code","text":"`'POLYGON'`"},{"kind":"text","text":" it must be at least "},{"kind":"code","text":"`3.0`"},{"kind":"text","text":". For "},{"kind":"code","text":"`'STAR'`"},{"kind":"text","text":" and "},{"kind":"code","text":"`'PILL_STAR'`"},{"kind":"text","text":" it is a number of vertices for each of two radii (A 5-pointed star has 10 vertices.)"}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"6.0"}]}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"ShapeRecordProps","variant":"declaration","kind":2097152,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"NativeShapeProps"},"name":"NativeShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"cornerRounding"},{"type":"literal","value":"smoothing"},{"type":"literal","value":"verticesCount"},{"type":"literal","value":"innerRadius"},{"type":"literal","value":"radius"},{"type":"literal","value":"cornerRadii"},{"type":"literal","value":"type"}]}],"name":"Pick","package":"typescript"}},{"name":"Shape","variant":"declaration","kind":32,"flags":{"isConst":true},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"Circle","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"radius"},{"type":"literal","value":"verticesCount"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"Pill","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"smoothing"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"PillStar","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ShapeProps","package":"@expo/ui"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"Polygon","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"smoothing"},{"type":"literal","value":"cornerRounding"},{"type":"literal","value":"verticesCount"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"Rectangle","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"smoothing"},{"type":"literal","value":"cornerRounding"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"RoundedCorner","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"cornerRadii"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"Star","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ShapeProps","package":"@expo/ui"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}}]}},"defaultValue":"..."},{"name":"parseJSXShape","variant":"declaration","kind":64,"signatures":[{"name":"parseJSXShape","variant":"signature","kind":4096,"parameters":[{"name":"shape","variant":"param","kind":32768,"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}],"type":{"type":"reference","name":"ShapeRecordProps","package":"@expo/ui"}},{"name":"parseJSXShape","variant":"signature","kind":4096,"parameters":[{"name":"shape","variant":"param","kind":32768,"flags":{"isOptional":true},"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}],"type":{"type":"union","types":[{"type":"reference","name":"ShapeRecordProps","package":"@expo/ui"},{"type":"intrinsic","name":"undefined"}]}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/slider.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/slider.json index 056e7c4c7aac03..4dc4d2d4ab6998 100644 --- a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/slider.json +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/slider.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/slider","variant":"project","kind":1,"children":[{"name":"SliderElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for slider's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"children":[{"name":"activeTickColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"activeTrackColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveTickColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveTrackColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"thumbColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}}]},{"name":"SliderProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Slider color."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for slider's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","name":"SliderElementColors","package":"@expo/ui"}},{"name":"max","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The maximum value of the slider. Updating this value does not trigger callbacks if the current value is above "},{"kind":"code","text":"`max`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"1"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"min","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The minimum value of the slider. Updating this value does not trigger callbacks if the current value is below "},{"kind":"code","text":"`min`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onValueChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback triggered on dragging along the slider."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"value","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"steps","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The number of steps between the minimum and maximum values, "},{"kind":"code","text":"`0`"},{"kind":"text","text":" signifies infinite steps."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"value","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The current value of the slider."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"Slider","variant":"declaration","kind":64,"signatures":[{"name":"Slider","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SliderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/slider","variant":"project","kind":1,"children":[{"name":"SliderElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for slider's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"children":[{"name":"activeTickColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"activeTrackColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveTickColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveTrackColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"thumbColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"SliderProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Slider color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for slider's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","name":"SliderElementColors","package":"@expo/ui"}},{"name":"max","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The maximum value of the slider. Updating this value does not trigger callbacks if the current value is above "},{"kind":"code","text":"`max`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"1"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"min","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The minimum value of the slider. Updating this value does not trigger callbacks if the current value is below "},{"kind":"code","text":"`min`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onValueChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback triggered on dragging along the slider."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"value","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"steps","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The number of steps between the minimum and maximum values, "},{"kind":"code","text":"`0`"},{"kind":"text","text":" signifies infinite steps."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"value","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The current value of the slider."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"Slider","variant":"declaration","kind":64,"signatures":[{"name":"Slider","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SliderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/spacer.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/spacer.json new file mode 100644 index 00000000000000..6fe94160ef03f1 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/spacer.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/spacer","variant":"project","kind":1,"children":[{"name":"SpacerProps","variant":"declaration","kind":2097152,"children":[{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component. Use weight() modifier to make the spacer flexible."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}}]},{"name":"Spacer","variant":"declaration","kind":64,"signatures":[{"name":"Spacer","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A spacer component that fills available space.\nUse with the weight() modifier to create flexible spacing in Row or Column layouts."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n Left\n \n Right\n\n```"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SpacerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/surface.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/surface.json new file mode 100644 index 00000000000000..5f051ef17f4f00 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/surface.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/surface","variant":"project","kind":1,"children":[{"name":"SurfaceProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the surface."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The background color of the surface.\nDefaults to "},{"kind":"code","text":"`MaterialTheme.colorScheme.surface`"},{"kind":"text","text":"."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the content inside the surface.\nDefaults to "},{"kind":"code","text":"`contentColorFor(color)`"},{"kind":"text","text":"."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"shadowElevation","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The shadow elevation of the surface. Value in dp."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"tonalElevation","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The tonal elevation of the surface, which affects its background color\nbased on the color scheme. Value in dp."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"Surface","variant":"declaration","kind":64,"signatures":[{"name":"Surface","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A Material Design surface container. Surface is responsible for:\n- Clipping content to the shape\n- Applying background color based on tonal elevation\n- Providing content color to its children"}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SurfaceProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/switch.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/switch.json index b084bc77c804ee..9cfa852e9429bd 100644 --- a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/switch.json +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/switch.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/switch","variant":"project","kind":1,"children":[{"name":"SwitchButtonVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"undefined"}},{"name":"variant","variant":"declaration","kind":1024,"type":{"type":"literal","value":"button"}}]},{"name":"SwitchCheckboxVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for checkbox core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"CheckboxElementColors"},"name":"CheckboxElementColors","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"type":{"type":"literal","value":"checkbox"}}]},{"name":"SwitchProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Picker color."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"label","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Label for the switch.\n\n> On Android, the label has an effect only when the "},{"kind":"code","text":"`Switch`"},{"kind":"text","text":" is used inside a "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":"."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onValueChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the checked state changes."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"value","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"boolean"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"value","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Indicates whether the switch is checked."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Type of the switch component. Can be "},{"kind":"code","text":"`'checkbox'`"},{"kind":"text","text":", "},{"kind":"code","text":"`'switch'`"},{"kind":"text","text":", or "},{"kind":"code","text":"`'button'`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'switch'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"checkbox"},{"type":"literal","value":"switch"},{"type":"literal","value":"button"}]}}]}},{"type":"union","types":[{"type":"reference","name":"SwitchSwitchVariantProps","package":"@expo/ui"},{"type":"reference","name":"SwitchCheckboxVariantProps","package":"@expo/ui"},{"type":"reference","name":"SwitchButtonVariantProps","package":"@expo/ui"}]}]}},{"name":"SwitchSwitchVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for switch's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"SwitchElementColors"},"name":"SwitchElementColors","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"literal","value":"switch"}}]},{"name":"Switch","variant":"declaration","kind":64,"signatures":[{"name":"Switch","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SwitchProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/switch","variant":"project","kind":1,"children":[{"name":"SwitchButtonVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"undefined"}},{"name":"variant","variant":"declaration","kind":1024,"type":{"type":"literal","value":"button"}}]},{"name":"SwitchCheckboxVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for checkbox core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"CheckboxElementColors"},"name":"CheckboxElementColors","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"type":{"type":"literal","value":"checkbox"}}]},{"name":"SwitchProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Children containing ThumbContent slot."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Picker color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"label","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Label for the switch.\n\n> On Android, the label has an effect only when the "},{"kind":"code","text":"`Switch`"},{"kind":"text","text":" is used inside a "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":"."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onValueChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the checked state changes."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"value","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"boolean"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"value","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Indicates whether the switch is checked."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Type of the switch component. Can be "},{"kind":"code","text":"`'checkbox'`"},{"kind":"text","text":", "},{"kind":"code","text":"`'switch'`"},{"kind":"text","text":", or "},{"kind":"code","text":"`'button'`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'switch'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"checkbox"},{"type":"literal","value":"switch"},{"type":"literal","value":"button"}]}}]}},{"type":"union","types":[{"type":"reference","name":"SwitchSwitchVariantProps","package":"@expo/ui"},{"type":"reference","name":"SwitchCheckboxVariantProps","package":"@expo/ui"},{"type":"reference","name":"SwitchButtonVariantProps","package":"@expo/ui"}]}]}},{"name":"SwitchSwitchVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for switch's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"SwitchElementColors"},"name":"SwitchElementColors","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"literal","value":"switch"}}]},{"name":"Switch","variant":"declaration","kind":64,"children":[{"name":"DefaultIconSize","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"any"}},{"name":"ThumbContent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Custom content to be displayed inside the switch thumb."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"ThumbContentProps"},"name":"ThumbContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"Switch","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SwitchProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"SwitchThumbContent","variant":"declaration","kind":64,"signatures":[{"name":"SwitchThumbContent","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Custom content to be displayed inside the switch thumb."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"ThumbContentProps"},"name":"ThumbContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/text.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/text.json new file mode 100644 index 00000000000000..f49239b4a77b2d --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/text.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/text","variant":"project","kind":1,"children":[{"name":"TextAlign","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Text alignment options."}]},"type":{"type":"union","types":[{"type":"literal","value":"left"},{"type":"literal","value":"right"},{"type":"literal","value":"center"},{"type":"literal","value":"justify"},{"type":"literal","value":"start"},{"type":"literal","value":"end"}]}},{"name":"TextDecoration","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Text decoration options."}]},"type":{"type":"union","types":[{"type":"literal","value":"none"},{"type":"literal","value":"underline"},{"type":"literal","value":"lineThrough"}]}},{"name":"TextFontStyle","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Font style options for text styling."}]},"type":{"type":"union","types":[{"type":"literal","value":"normal"},{"type":"literal","value":"italic"}]}},{"name":"TextFontWeight","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Font weight options for text styling."}]},"type":{"type":"union","types":[{"type":"literal","value":"normal"},{"type":"literal","value":"bold"},{"type":"literal","value":"100"},{"type":"literal","value":"200"},{"type":"literal","value":"300"},{"type":"literal","value":"400"},{"type":"literal","value":"500"},{"type":"literal","value":"600"},{"type":"literal","value":"700"},{"type":"literal","value":"800"},{"type":"literal","value":"900"}]}},{"name":"TextOverflow","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Text overflow behavior options."}]},"type":{"type":"union","types":[{"type":"literal","value":"clip"},{"type":"literal","value":"ellipsis"},{"type":"literal","value":"visible"}]}},{"name":"TextProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text content to display."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the text."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"maxLines","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"An optional maximum number of lines for the text to span, wrapping if necessary.\nIf the text exceeds the given number of lines, it will be truncated according to overflow."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"minLines","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The minimum height in terms of minimum number of visible lines."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"overflow","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"How visual overflow should be handled.\n- 'clip': Clips the overflowing text to fix its container\n- 'ellipsis': Uses an ellipsis to indicate that the text has overflowed\n- 'visible': Renders overflow text outside its container"}]},"type":{"type":"reference","name":"TextOverflow","package":"@expo/ui"}},{"name":"softWrap","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the text should break at soft line breaks.\nIf false, the glyphs in the text will be positioned as if there was unlimited horizontal space."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Style configuration for the text.\nCorresponds to Jetpack Compose's TextStyle parameter."}]},"type":{"type":"reference","name":"TextStyle","package":"@expo/ui"}}]},{"name":"TextStyle","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Text style properties that can be applied to text.\nCorresponds to Jetpack Compose's TextStyle."}]},"children":[{"name":"fontSize","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The font size in sp (scale-independent pixels)."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"fontStyle","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The font style of the text."}]},"type":{"type":"reference","name":"TextFontStyle","package":"@expo/ui"}},{"name":"fontWeight","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The font weight of the text."}]},"type":{"type":"reference","name":"TextFontWeight","package":"@expo/ui"}},{"name":"letterSpacing","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The letter spacing in sp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"lineHeight","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The line height in sp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"textAlign","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text alignment."}]},"type":{"type":"reference","name":"TextAlign","package":"@expo/ui"}},{"name":"textDecoration","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text decoration."}]},"type":{"type":"reference","name":"TextDecoration","package":"@expo/ui"}},{"name":"typography","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Material 3 Typography style to use as the base style.\nWhen specified, applies the predefined Material 3 typography style.\nOther properties in this style object will override specific values from the typography."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\nstyle={{ typography: \"bodyLarge\" }}\nstyle={{ typography: \"headlineMedium\", fontWeight: \"bold\" }}\n```"}]}]},"type":{"type":"reference","name":"TypographyStyle","package":"@expo/ui"}}]},{"name":"TypographyStyle","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Material 3 Typography scale styles.\nCorresponds to MaterialTheme.typography in Jetpack Compose."}]},"type":{"type":"union","types":[{"type":"literal","value":"displayLarge"},{"type":"literal","value":"displayMedium"},{"type":"literal","value":"displaySmall"},{"type":"literal","value":"headlineLarge"},{"type":"literal","value":"headlineMedium"},{"type":"literal","value":"headlineSmall"},{"type":"literal","value":"titleLarge"},{"type":"literal","value":"titleMedium"},{"type":"literal","value":"titleSmall"},{"type":"literal","value":"bodyLarge"},{"type":"literal","value":"bodyMedium"},{"type":"literal","value":"bodySmall"},{"type":"literal","value":"labelLarge"},{"type":"literal","value":"labelMedium"},{"type":"literal","value":"labelSmall"}]}},{"name":"Text","variant":"declaration","kind":64,"signatures":[{"name":"Text","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a Text component using Jetpack Compose.\n\nThe Text component provides comprehensive text styling capabilities.\nThe API is aligned with Jetpack Compose's Text composable, where:\n- Top-level props (color, maxLines, etc.) match Compose's Text parameters\n- "},{"kind":"code","text":"`style`"},{"kind":"text","text":" object corresponds to TextStyle, including typography, fontSize, fontWeight, textAlign, etc.\n- "},{"kind":"code","text":"`style.typography`"},{"kind":"text","text":" applies Material 3 typography styles (like MaterialTheme.typography)"}],"blockTags":[{"tag":"@example","content":[{"kind":"text","text":"Basic usage:\n"},{"kind":"code","text":"```tsx\nimport { Text } from 'expo-ui';\n\nHello World\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"Using Material 3 Typography (matches Jetpack Compose MaterialTheme.typography):\n"},{"kind":"code","text":"```tsx\nBody text\nHeadline\nSmall title\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"Typography with style overrides:\n"},{"kind":"code","text":"```tsx\n\n Custom styled body text\n\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"With custom style object (matches Jetpack Compose TextStyle):\n"},{"kind":"code","text":"```tsx\n\n Styled text\n\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"Text truncation with ellipsis:\n"},{"kind":"code","text":"```tsx\n\n This is a very long text that will be truncated after two lines\n with an ellipsis at the end to indicate there's more content...\n\n```"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"TextProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/textbutton.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/textbutton.json new file mode 100644 index 00000000000000..758b7959d86b4a --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/textbutton.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/textbutton","variant":"project","kind":1,"children":[{"name":"TextButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text content to display in the button."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"array","elementType":{"type":"intrinsic","name":"string"}},{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"React.JSX.Element","package":"@types/react"}]}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the button text."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the button is disabled."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"TextButton","variant":"declaration","kind":64,"signatures":[{"name":"TextButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A text button component that displays a clickable text label."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"TextButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/jetpack-compose/togglebutton.json b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/togglebutton.json new file mode 100644 index 00000000000000..e3cea8fa81d18f --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/jetpack-compose/togglebutton.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/togglebutton","variant":"project","kind":1,"children":[{"name":"ToggleButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"checked","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Whether the toggle button is checked."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the toggle button."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the toggle button when checked."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the button is disabled."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onCheckedChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the checked state changes."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"checked","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"boolean"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"text","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Text to display in the button."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the toggle button.\n- "},{"kind":"code","text":"`'default'`"},{"kind":"text","text":" - Material 3 ToggleButton\n- "},{"kind":"code","text":"`'icon'`"},{"kind":"text","text":" - Icon toggle button\n- "},{"kind":"code","text":"`'filledIcon'`"},{"kind":"text","text":" - Filled icon toggle button\n- "},{"kind":"code","text":"`'outlinedIcon'`"},{"kind":"text","text":" - Outlined icon toggle button"}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'default'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"icon"},{"type":"literal","value":"filledIcon"},{"type":"literal","value":"outlinedIcon"}]}}]},{"name":"ToggleButton","variant":"declaration","kind":64,"children":[{"name":"DefaultIconSize","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"any"}},{"name":"DefaultIconSpacing","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"any"}}],"signatures":[{"name":"ToggleButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A toggle button component that can be toggled on and off.\n\nWhen "},{"kind":"code","text":"`text`"},{"kind":"text","text":" prop is provided, it displays the text.\nOtherwise, custom children can be passed to render custom content."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ToggleButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/swift-ui/circularprogress.json b/docs/public/static/data/unversioned/expo-ui/swift-ui/circularprogress.json new file mode 100644 index 00000000000000..4647ccf7fd8566 --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/swift-ui/circularprogress.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/swift-ui/circularprogress","variant":"project","kind":1,"children":[{"name":"ClosedRangeDate","variant":"declaration","kind":2097152,"children":[{"name":"lower","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Date"},"name":"Date","package":"typescript"}},{"name":"upper","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Date"},"name":"Date","package":"typescript"}}]},{"name":"ProgressViewProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A label describing the progress view's purpose."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"countsDown","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A Boolean value that determines whether the view empties or fills as time passes. If "},{"kind":"code","text":"`true`"},{"kind":"text","text":", which is the default, the view empties."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]},{"tag":"@platform","content":[{"kind":"text","text":"ios 16.0+"}]},{"tag":"@platform","content":[{"kind":"text","text":"tvos 16.0+"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"timerInterval","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The lower and upper bounds for automatic timer progress."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"ios 16.0+"}]},{"tag":"@platform","content":[{"kind":"text","text":"tvos 16.0+"}]}]},"type":{"type":"reference","name":"ClosedRangeDate","package":"@expo/ui"}},{"name":"value","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The current progress value. A value between "},{"kind":"code","text":"`0`"},{"kind":"text","text":" and "},{"kind":"code","text":"`1`"},{"kind":"text","text":".\nWhen "},{"kind":"code","text":"`undefined`"},{"kind":"text","text":", the progress view displays an indeterminate indicator."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"literal","value":null}]}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/swift-ui/types.ts","qualifiedName":"CommonViewModifierProps"},"name":"CommonViewModifierProps","package":"@expo/ui"}]}},{"name":"ProgressView","variant":"declaration","kind":64,"signatures":[{"name":"ProgressView","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a SwiftUI "},{"kind":"code","text":"`ProgressView`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ProgressViewProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/unversioned/expo-ui/swift-ui/linearprogress.json b/docs/public/static/data/unversioned/expo-ui/swift-ui/linearprogress.json new file mode 100644 index 00000000000000..9dbbfeb407c78e --- /dev/null +++ b/docs/public/static/data/unversioned/expo-ui/swift-ui/linearprogress.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/swift-ui/linearprogress","variant":"project","kind":1,"children":[{"name":"ClosedRangeDate","variant":"declaration","kind":2097152,"children":[{"name":"lower","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Date"},"name":"Date","package":"typescript"}},{"name":"upper","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Date"},"name":"Date","package":"typescript"}}]},{"name":"ProgressViewProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A label describing the progress view's purpose."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"countsDown","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A Boolean value that determines whether the view empties or fills as time passes. If "},{"kind":"code","text":"`true`"},{"kind":"text","text":", which is the default, the view empties."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]},{"tag":"@platform","content":[{"kind":"text","text":"ios 16.0+"}]},{"tag":"@platform","content":[{"kind":"text","text":"tvos 16.0+"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"timerInterval","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The lower and upper bounds for automatic timer progress."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"ios 16.0+"}]},{"tag":"@platform","content":[{"kind":"text","text":"tvos 16.0+"}]}]},"type":{"type":"reference","name":"ClosedRangeDate","package":"@expo/ui"}},{"name":"value","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The current progress value. A value between "},{"kind":"code","text":"`0`"},{"kind":"text","text":" and "},{"kind":"code","text":"`1`"},{"kind":"text","text":".\nWhen "},{"kind":"code","text":"`undefined`"},{"kind":"text","text":", the progress view displays an indeterminate indicator."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"literal","value":null}]}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/swift-ui/types.ts","qualifiedName":"CommonViewModifierProps"},"name":"CommonViewModifierProps","package":"@expo/ui"}]}},{"name":"ProgressView","variant":"declaration","kind":64,"signatures":[{"name":"ProgressView","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a SwiftUI "},{"kind":"code","text":"`ProgressView`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ProgressViewProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/alertdialog.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/alertdialog.json new file mode 100644 index 00000000000000..3b196592f2d7e7 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/alertdialog.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/alertdialog","variant":"project","kind":1,"children":[{"name":"AlertDialogButtonColors","variant":"declaration","kind":2097152,"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The background color of the button."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text color of the button."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"AlertDialogProps","variant":"declaration","kind":2097152,"children":[{"name":"confirmButtonColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The colors for the confirm button."}]},"type":{"type":"reference","name":"AlertDialogButtonColors","package":"@expo/ui"}},{"name":"confirmButtonText","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text of the confirm button of the alert dialog."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"dismissButtonColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The colors for the dismiss button."}]},"type":{"type":"reference","name":"AlertDialogButtonColors","package":"@expo/ui"}},{"name":"dismissButtonText","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text of the dismiss button of the alert dialog."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onConfirmPressed","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the user tries to confirm the dialog."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"onDismissPressed","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the user tries to dismiss the dialog."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"text","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text of the alert dialog."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"title","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The title of the alert dialog."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"visible","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the alert dialog is visible."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"NativeAlertDialogProps","variant":"declaration","kind":2097152,"type":{"type":"reference","name":"AlertDialogProps","package":"@expo/ui"}},{"name":"AlertDialog","variant":"declaration","kind":64,"signatures":[{"name":"AlertDialog","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders an "},{"kind":"code","text":"`AlertDialog`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"AlertDialogProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/basicalertdialog.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/basicalertdialog.json new file mode 100644 index 00000000000000..9e429561732ca8 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/basicalertdialog.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/basicalertdialog","variant":"project","kind":1,"children":[{"name":"BasicAlertDialogProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the dialog."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onDismissRequest","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the user tries to dismiss the dialog\n(e.g. by tapping outside of it or pressing the back button)."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"BasicAlertDialog","variant":"declaration","kind":64,"signatures":[{"name":"BasicAlertDialog","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A basic alert dialog that provides a blank container for custom content.\nUnlike "},{"kind":"code","text":"`AlertDialog`"},{"kind":"text","text":", this component does not have structured title/text/buttons slots."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"BasicAlertDialogProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/bottomsheet.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/bottomsheet.json index 7bc06de2e2647b..70bd3b3b8a1f54 100644 --- a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/bottomsheet.json +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/bottomsheet.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/bottomsheet","variant":"project","kind":1,"children":[{"name":"BottomSheetProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The children of the "},{"kind":"code","text":"`BottomSheet`"},{"kind":"text","text":" component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"isOpened","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Whether the "},{"kind":"code","text":"`BottomSheet`"},{"kind":"text","text":" is opened."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"onIsOpenedChange","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the "},{"kind":"code","text":"`BottomSheet`"},{"kind":"text","text":" is opened."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"isOpened","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"boolean"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"skipPartiallyExpanded","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Immediately opens the bottom sheet in full screen."}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"BottomSheet","variant":"declaration","kind":64,"signatures":[{"name":"BottomSheet","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"BottomSheetProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/bottomsheet","variant":"project","kind":1,"children":[{"name":"BottomSheetProps","variant":"declaration","kind":2097152,"comment":{"summary":[],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use "},{"kind":"code","text":"`ModalBottomSheetProps`"},{"kind":"text","text":" instead."}]}]},"type":{"type":"reference","name":"ModalBottomSheetProps","package":"@expo/ui"}},{"name":"ModalBottomSheetProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The children of the "},{"kind":"code","text":"`ModalBottomSheet`"},{"kind":"text","text":" component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onDismissRequest","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the bottom sheet is dismissed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"skipPartiallyExpanded","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Immediately opens the bottom sheet in full screen."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"BottomSheet","variant":"declaration","kind":32,"flags":{"isConst":true},"comment":{"summary":[],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use "},{"kind":"code","text":"`ModalBottomSheet`"},{"kind":"text","text":" instead."}]}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A Material Design modal bottom sheet."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ModalBottomSheetProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}},"defaultValue":"ModalBottomSheet"},{"name":"ModalBottomSheet","variant":"declaration","kind":64,"signatures":[{"name":"ModalBottomSheet","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A Material Design modal bottom sheet."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ModalBottomSheetProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/box.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/box.json new file mode 100644 index 00000000000000..840840c443f428 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/box.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/box","variant":"project","kind":1,"children":[{"name":"BoxProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"contentAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Alignment of children within the box."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"ContentAlignment"},"name":"ContentAlignment","package":"@expo/ui"}},{"name":"floatingToolbarExitAlwaysScrollBehavior","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Scroll behavior for the floating toolbar exit."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"FloatingToolbarExitAlwaysScrollBehavior"},"name":"FloatingToolbarExitAlwaysScrollBehavior","package":"@expo/ui"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Box","variant":"declaration","kind":64,"signatures":[{"name":"Box","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"BoxProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/button.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/button.json index 056bb677992788..9fe096c0dfdc70 100644 --- a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/button.json +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/button.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/button","variant":"project","kind":1,"children":[{"name":"ButtonElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}]},"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}}]},{"name":"ButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text to display inside the button."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"array","elementType":{"type":"intrinsic","name":"string"}},{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"React.JSX.Element","package":"@types/react"}]}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Button color."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Disabled state of the button."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","name":"ButtonElementColors","package":"@expo/ui"}},{"name":"leadingIcon","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the leading icon to display in the button.\nUses Material Icons on Android."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"shape","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"ShapeJSXElement"},"name":"ShapeJSXElement","package":"@expo/ui"}},{"name":"systemImage","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the system image to display in the button.\nUses Material Icons on Android."}],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use "},{"kind":"code","text":"`leadingIcon`"},{"kind":"text","text":" instead."}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"trailingIcon","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the trailing icon to display in the button.\nUses Material Icons on Android."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The button variant."}]},"type":{"type":"reference","name":"ButtonVariant","package":"@expo/ui"}}]},{"name":"ButtonVariant","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"The built-in button styles available on Android.\n- "},{"kind":"code","text":"`outlined`"},{"kind":"text","text":" - A button with an outline.\n- "},{"kind":"code","text":"`elevated`"},{"kind":"text","text":" - A filled button with a shadow."}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"bordered"},{"type":"literal","value":"borderless"},{"type":"literal","value":"outlined"},{"type":"literal","value":"elevated"}]}},{"name":"Button","variant":"declaration","kind":64,"signatures":[{"name":"Button","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native button component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/button","variant":"project","kind":1,"children":[{"name":"ButtonElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}]},"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"ButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text to display inside the button."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"array","elementType":{"type":"intrinsic","name":"string"}},{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"React.JSX.Element","package":"@types/react"}]}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Button color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Disabled state of the button."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","name":"ButtonElementColors","package":"@expo/ui"}},{"name":"leadingIcon","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the leading icon to display in the button.\nUses Material Icons on Android."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"shape","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"ShapeJSXElement"},"name":"ShapeJSXElement","package":"@expo/ui"}},{"name":"systemImage","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the system image to display in the button.\nUses Material Icons on Android."}],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use "},{"kind":"code","text":"`leadingIcon`"},{"kind":"text","text":" instead."}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"trailingIcon","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A string describing the trailing icon to display in the button.\nUses Material Icons on Android."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/types.ts","qualifiedName":"MaterialIcon"},"name":"MaterialIcon","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The button variant."}]},"type":{"type":"reference","name":"ButtonVariant","package":"@expo/ui"}}]},{"name":"ButtonVariant","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"The built-in button styles available on Android.\n- "},{"kind":"code","text":"`outlined`"},{"kind":"text","text":" - A button with an outline.\n- "},{"kind":"code","text":"`elevated`"},{"kind":"text","text":" - A filled button with a shadow."}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"bordered"},{"type":"literal","value":"borderless"},{"type":"literal","value":"outlined"},{"type":"literal","value":"elevated"}]}},{"name":"Button","variant":"declaration","kind":64,"signatures":[{"name":"Button","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native button component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/card.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/card.json new file mode 100644 index 00000000000000..ce22c1ee42b412 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/card.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/card","variant":"project","kind":1,"children":[{"name":"CardElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for card's core elements."}]},"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"CardProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the card."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The background color of the card."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for card's core elements."}]},"type":{"type":"reference","name":"CardElementColors","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the card.\n- 'default' - A filled card with no outline.\n- 'elevated' - A filled card with elevation/shadow.\n- 'outlined' - A card with an outline border."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'default'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"elevated"},{"type":"literal","value":"outlined"}]}}]},{"name":"Card","variant":"declaration","kind":64,"signatures":[{"name":"Card","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A card component that provides a surface for content."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"CardProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/carousel.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/carousel.json new file mode 100644 index 00000000000000..1ac2fa44cf3067 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/carousel.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/carousel","variant":"project","kind":1,"children":[{"name":"CarouselProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Children to render"}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"contentPadding","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Padding for carousel content (dp or object)"}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"reference","name":"PaddingValuesRecord","package":"@expo/ui"}]}},{"name":"flingBehavior","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Fling behavior type"}]},"type":{"type":"reference","name":"FlingBehaviorType","package":"@expo/ui"}},{"name":"itemSpacing","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Spacing between items (dp)"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"itemWidth","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Item width (dp) for unconstrained variant"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"maxSmallItemWidth","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Maximum small item width (dp)"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"minSmallItemWidth","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Minimum small item width (dp)"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"preferredItemWidth","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Preferred item width (dp) for multiBrowse variant"}]},"type":{"type":"intrinsic","name":"number"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Carousel variant"}]},"type":{"type":"reference","name":"CarouselVariant","package":"@expo/ui"}}]},{"name":"CarouselVariant","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"multiBrowse"},{"type":"literal","value":"unconstrained"}]}},{"name":"FlingBehaviorType","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"singleAdvance"},{"type":"literal","value":"noSnap"}]}},{"name":"PaddingValuesRecord","variant":"declaration","kind":2097152,"children":[{"name":"bottom","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"end","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"start","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"top","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}}]},{"name":"Carousel","variant":"declaration","kind":64,"signatures":[{"name":"Carousel","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"CarouselProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"transformCarouselProps","variant":"declaration","kind":64,"signatures":[{"name":"transformCarouselProps","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"CarouselProps","package":"@expo/ui"}}],"type":{"type":"reference","name":"CarouselProps","package":"@expo/ui"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/column.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/column.json new file mode 100644 index 00000000000000..3313d9bdbffdd6 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/column.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/column","variant":"project","kind":1,"children":[{"name":"ColumnProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"horizontalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal alignment of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalAlignment"},"name":"HorizontalAlignment","package":"@expo/ui"}},{"name":"horizontalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalArrangement"},"name":"HorizontalArrangement","package":"@expo/ui"}},{"name":"verticalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical alignment of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalAlignment"},"name":"VerticalAlignment","package":"@expo/ui"}},{"name":"verticalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalArrangement"},"name":"VerticalArrangement","package":"@expo/ui"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Column","variant":"declaration","kind":64,"signatures":[{"name":"Column","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ColumnProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/contextmenu.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/contextmenu.json index 7b8104fbce683c..3bf7a02324bdd0 100644 --- a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/contextmenu.json +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/contextmenu.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/contextmenu","variant":"project","kind":1,"children":[{"name":"ContextMenuContentProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"union","types":[{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/index.tsx","qualifiedName":"SubmenuElement"},"name":"SubmenuElement","package":"@expo/ui"},{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/index.tsx","qualifiedName":"SubmenuElement"},"name":"SubmenuElement","package":"@expo/ui"}}]}}]},{"name":"ContextMenuProps","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Props of the "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":" component."}]},"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The contents of the submenu are used as an anchor for the context menu.\nThe children will be wrapped in a pressable element, which triggers opening of the context menu."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the container holding the context menu items."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional styles to apply to the "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":"."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"StyleProp"},"typeArguments":[{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheetTypes.d.ts","qualifiedName":"ViewStyle"},"name":"ViewStyle","package":"react-native"}],"name":"StyleProp","package":"react-native"}}]},{"name":"ContextMenu","variant":"declaration","kind":64,"children":[{"name":"Items","variant":"declaration","kind":1024,"type":{"type":"query","queryType":{"type":"reference","name":"Items","package":"@expo/ui"}}},{"name":"Preview","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Trigger","variant":"declaration","kind":1024,"type":{"type":"query","queryType":{"type":"reference","name":"Trigger","package":"@expo/ui"}}}],"signatures":[{"name":"ContextMenu","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ContextMenuProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Items","variant":"declaration","kind":64,"children":[{"name":"tag","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}],"signatures":[{"name":"Items","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ContextMenuContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Preview","variant":"declaration","kind":64,"signatures":[{"name":"Preview","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Submenu","variant":"declaration","kind":64,"signatures":[{"name":"Submenu","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/Submenu.tsx","qualifiedName":"SubmenuProps"},"name":"SubmenuProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Trigger","variant":"declaration","kind":64,"children":[{"name":"tag","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}],"signatures":[{"name":"Trigger","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/contextmenu","variant":"project","kind":1,"children":[{"name":"ContextMenuContentProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"union","types":[{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/index.tsx","qualifiedName":"SubmenuElement"},"name":"SubmenuElement","package":"@expo/ui"},{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/index.tsx","qualifiedName":"SubmenuElement"},"name":"SubmenuElement","package":"@expo/ui"}}]}}]},{"name":"ContextMenuProps","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Props of the "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":" component."}]},"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The contents of the submenu are used as an anchor for the context menu.\nThe children will be wrapped in a pressable element, which triggers opening of the context menu."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the container holding the context menu items."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional styles to apply to the "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":"."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"StyleProp"},"typeArguments":[{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheetTypes.d.ts","qualifiedName":"ViewStyle"},"name":"ViewStyle","package":"react-native"}],"name":"StyleProp","package":"react-native"}}]},{"name":"ContextMenu","variant":"declaration","kind":64,"children":[{"name":"Items","variant":"declaration","kind":1024,"type":{"type":"query","queryType":{"type":"reference","name":"Items","package":"@expo/ui"}}},{"name":"Preview","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Trigger","variant":"declaration","kind":1024,"type":{"type":"query","queryType":{"type":"reference","name":"Trigger","package":"@expo/ui"}}}],"signatures":[{"name":"ContextMenu","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ContextMenuProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Items","variant":"declaration","kind":64,"children":[{"name":"tag","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}],"signatures":[{"name":"Items","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ContextMenuContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Preview","variant":"declaration","kind":64,"signatures":[{"name":"Preview","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Submenu","variant":"declaration","kind":64,"signatures":[{"name":"Submenu","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ContextMenu/Submenu.tsx","qualifiedName":"SubmenuProps"},"name":"SubmenuProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"Trigger","variant":"declaration","kind":64,"children":[{"name":"tag","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}],"signatures":[{"name":"Trigger","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"ReactNode","package":"@types/react","qualifiedName":"React.ReactNode"}}]}}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/datetimepicker.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/datetimepicker.json index 5fc41fd7147571..bc37658f4d5097 100644 --- a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/datetimepicker.json +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/datetimepicker.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/datetimepicker","variant":"project","kind":1,"children":[{"name":"AndroidVariant","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"picker"},{"type":"literal","value":"input"}]}},{"name":"DateTimePickerProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The tint color to use on the picker elements."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"displayedComponents","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The components that the picker should display.\nOn Android, you can have a picker that selects just the date or just the time.\n"},{"kind":"code","text":"`dateAndTime`"},{"kind":"text","text":" is only available on iOS and will result in a date picker on Android.\nOn iOS, you can have a picker that selects both date and time."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'date'"}]}]},"type":{"type":"reference","name":"DisplayedComponents","package":"@expo/ui"}},{"name":"initialDate","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The initial date to display on the picker."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"literal","value":null}]}},{"name":"is24Hour","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Determines what format the clock should be displayed in on Android."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onDateSelected","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when a date is selected."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"date","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Date"},"name":"Date","package":"typescript"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"showVariantToggle","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Show to button to toggle between variants on Android."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the picker, which determines its appearance and behavior."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'picker'"}]}]},"type":{"type":"reference","name":"AndroidVariant","package":"@expo/ui"}}]},{"name":"DisplayedComponents","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"date"},{"type":"literal","value":"hourAndMinute"},{"type":"literal","value":"dateAndTime"}]}},{"name":"DateTimePicker","variant":"declaration","kind":64,"signatures":[{"name":"DateTimePicker","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`DateTimePicker`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"DateTimePickerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/datetimepicker","variant":"project","kind":1,"children":[{"name":"AndroidVariant","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"picker"},{"type":"literal","value":"input"}]}},{"name":"DateTimePickerProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The tint color to use on the picker elements."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"displayedComponents","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The components that the picker should display.\nOn Android, you can have a picker that selects just the date or just the time.\n"},{"kind":"code","text":"`dateAndTime`"},{"kind":"text","text":" is only available on iOS and will result in a date picker on Android.\nOn iOS, you can have a picker that selects both date and time."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'date'"}]}]},"type":{"type":"reference","name":"DisplayedComponents","package":"@expo/ui"}},{"name":"initialDate","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The initial date to display on the picker."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"literal","value":null}]}},{"name":"is24Hour","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Determines what format the clock should be displayed in on Android."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onDateSelected","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when a date is selected."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"date","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Date"},"name":"Date","package":"typescript"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"showVariantToggle","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Show to button to toggle between variants on Android."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"true"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the picker, which determines its appearance and behavior."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'picker'"}]}]},"type":{"type":"reference","name":"AndroidVariant","package":"@expo/ui"}}]},{"name":"DisplayedComponents","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"date"},{"type":"literal","value":"hourAndMinute"},{"type":"literal","value":"dateAndTime"}]}},{"name":"DateTimePicker","variant":"declaration","kind":64,"signatures":[{"name":"DateTimePicker","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`DateTimePicker`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"DateTimePickerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/divider.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/divider.json new file mode 100644 index 00000000000000..dcf884d442bb23 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/divider.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/divider","variant":"project","kind":1,"children":[{"name":"DividerProps","variant":"declaration","kind":2097152,"children":[{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}}]},{"name":"Divider","variant":"declaration","kind":64,"signatures":[{"name":"Divider","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A visual element that can be used to separate other content."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"DividerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/dockedsearchbar.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/dockedsearchbar.json new file mode 100644 index 00000000000000..13d8a3587ec36e --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/dockedsearchbar.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/dockedsearchbar","variant":"project","kind":1,"children":[{"name":"DockedSearchBarProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The children of the component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onQueryChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the search query changes."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"query","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"DockedSearchBar","variant":"declaration","kind":64,"children":[{"name":"LeadingIcon","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/DockedSearchBar/index.tsx","qualifiedName":"LeadingIconProps"},"name":"LeadingIconProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Placeholder","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/DockedSearchBar/index.tsx","qualifiedName":"PlaceholderProps"},"name":"PlaceholderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"DockedSearchBar","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"DockedSearchBarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"DockedSearchBarLeadingIcon","variant":"declaration","kind":64,"signatures":[{"name":"DockedSearchBarLeadingIcon","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/DockedSearchBar/index.tsx","qualifiedName":"LeadingIconProps"},"name":"LeadingIconProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"DockedSearchBarPlaceholder","variant":"declaration","kind":64,"signatures":[{"name":"DockedSearchBarPlaceholder","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/DockedSearchBar/index.tsx","qualifiedName":"PlaceholderProps"},"name":"PlaceholderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/filterchip.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/filterchip.json new file mode 100644 index 00000000000000..1f6e5d8aa785af --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/filterchip.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/filterchip","variant":"project","kind":1,"children":[{"name":"FilterChipProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Children containing LeadingIcon and TrailingIcon slots."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"enabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the chip is enabled and can be interacted with."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"label","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The text label to display on the chip."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback fired when the chip is clicked."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"selected","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Whether the chip is currently selected."}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"FilterChip","variant":"declaration","kind":64,"children":[{"name":"LeadingIcon","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Leading icon slot for FilterChip."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/FilterChip/index.tsx","qualifiedName":"SlotChildProps"},"name":"SlotChildProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"TrailingIcon","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Trailing icon slot for FilterChip."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/FilterChip/index.tsx","qualifiedName":"SlotChildProps"},"name":"SlotChildProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"FilterChip","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A filter chip component following Material 3 design guidelines.\nSupports slot-based "},{"kind":"code","text":"`LeadingIcon`"},{"kind":"text","text":" and "},{"kind":"code","text":"`TrailingIcon`"},{"kind":"text","text":" children."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"FilterChipProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/flowrow.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/flowrow.json new file mode 100644 index 00000000000000..e0e29e85982f00 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/flowrow.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/flowrow","variant":"project","kind":1,"children":[{"name":"FlowRowProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"horizontalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalArrangement"},"name":"HorizontalArrangement","package":"@expo/ui"}},{"name":"verticalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalArrangement"},"name":"VerticalArrangement","package":"@expo/ui"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"FlowRow","variant":"declaration","kind":64,"signatures":[{"name":"FlowRow","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"FlowRowProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/horizontalfloatingtoolbar.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/horizontalfloatingtoolbar.json new file mode 100644 index 00000000000000..4334a33b016461 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/horizontalfloatingtoolbar.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/horizontalfloatingtoolbar","variant":"project","kind":1,"children":[{"name":"FloatingActionButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The children of the component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"HorizontalFloatingToolbarProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The children of the component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the horizontal floating toolbar."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'standard'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"standard"},{"type":"literal","value":"vibrant"}]}}]},{"name":"HorizontalFloatingToolbar","variant":"declaration","kind":64,"children":[{"name":"FloatingActionButton","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"FloatingActionButton component for HorizontalFloatingToolbar.\nThis component marks its children to be rendered in the FAB slot."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"FloatingActionButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"HorizontalFloatingToolbar","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`HorizontalFloatingToolbar`"},{"kind":"text","text":" component.\nA horizontal toolbar that floats above content, typically used for action buttons."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"HorizontalFloatingToolbarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"HorizontalFloatingToolbarFloatingActionButton","variant":"declaration","kind":64,"signatures":[{"name":"HorizontalFloatingToolbarFloatingActionButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"FloatingActionButton component for HorizontalFloatingToolbar.\nThis component marks its children to be rendered in the FAB slot."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"FloatingActionButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/host.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/host.json index 0d89ace06809bb..95fb36ef0c1662 100644 --- a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/host.json +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/host.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/host","variant":"project","kind":1,"children":[{"name":"HostProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"colorScheme","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color scheme of the host view."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/Utilities/Appearance.d.ts","qualifiedName":"ColorSchemeName"},"name":"ColorSchemeName","package":"react-native"}},{"name":"ignoreSafeAreaKeyboardInsets","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When "},{"kind":"code","text":"`true`"},{"kind":"text","text":", the Compose content will not perform keyboard avoidance behaviour when keyboard is shown.\nCan be only set once on mount."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"layoutDirection","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The layout direction for the content.\nDefaults to the current locale direction from I18nManager."}]},"type":{"type":"union","types":[{"type":"literal","value":"leftToRight"},{"type":"literal","value":"rightToLeft"}]}},{"name":"matchContents","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When true, the host view will update its size in the React Native view tree to match the content's layout from Jetpack Compose.\nCan be only set once on mount."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"horizontal","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"boolean"}},{"name":"vertical","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"boolean"}}]}}]}},{"name":"onLayoutContent","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is triggered when the Jetpack Compose content completes its layout.\nProvides the current dimensions of the content, which may change as the content updates."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"event","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"nativeEvent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"height","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}},{"name":"width","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}}]}}}]}}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"StyleProp"},"typeArguments":[{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheetTypes.d.ts","qualifiedName":"ViewStyle"},"name":"ViewStyle","package":"react-native"}],"name":"StyleProp","package":"react-native"}},{"name":"useViewportSizeMeasurement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When true and no explicit size is provided, the host will use the viewport size as the proposed size for Compose layout.\nThis is particularly useful for views that need to fill their available space."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout.tsx","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Host","variant":"declaration","kind":64,"signatures":[{"name":"Host","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"HostProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/host","variant":"project","kind":1,"children":[{"name":"HostProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"colorScheme","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color scheme of the host view."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/Utilities/Appearance.d.ts","qualifiedName":"ColorSchemeName"},"name":"ColorSchemeName","package":"react-native"}},{"name":"ignoreSafeAreaKeyboardInsets","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When "},{"kind":"code","text":"`true`"},{"kind":"text","text":", the Compose content will not perform keyboard avoidance behaviour when keyboard is shown.\nCan be only set once on mount."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"layoutDirection","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The layout direction for the content.\nDefaults to the current locale direction from I18nManager."}]},"type":{"type":"union","types":[{"type":"literal","value":"leftToRight"},{"type":"literal","value":"rightToLeft"}]}},{"name":"matchContents","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When true, the host view will update its size in the React Native view tree to match the content's layout from Jetpack Compose.\nCan be only set once on mount."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"boolean"},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"horizontal","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"boolean"}},{"name":"vertical","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"boolean"}}]}}]}},{"name":"onLayoutContent","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is triggered when the Jetpack Compose content completes its layout.\nProvides the current dimensions of the content, which may change as the content updates."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"event","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"nativeEvent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"height","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}},{"name":"width","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}}]}}}]}}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"StyleProp"},"typeArguments":[{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheetTypes.d.ts","qualifiedName":"ViewStyle"},"name":"ViewStyle","package":"react-native"}],"name":"StyleProp","package":"react-native"}},{"name":"useViewportSizeMeasurement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"When true and no explicit size is provided, the host will use the viewport size as the proposed size for Compose layout.\nThis is particularly useful for views that need to fill their available space."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Host","variant":"declaration","kind":64,"signatures":[{"name":"Host","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"HostProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/icon.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/icon.json new file mode 100644 index 00000000000000..6da3ec7c1b4ab4 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/icon.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/icon","variant":"project","kind":1,"children":[{"name":"IconProps","variant":"declaration","kind":2097152,"children":[{"name":"contentDescription","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Accessibility label for the icon.\nUsed by screen readers to describe the icon to users."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n```"}]}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component.\nAllows you to apply layout and styling modifiers to the icon."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n```"}]}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"size","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The size of the icon in density-independent pixels (dp).\nIf not specified, the icon will use its intrinsic size."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n```"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"source","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The source of the icon. Can be a URI string or the result of "},{"kind":"code","text":"`require()`"},{"kind":"text","text":".\nOn Android, supports XML vector drawables loaded via Metro bundler."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n\n```"}]}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/Image/Image.d.ts","qualifiedName":"ImageSourcePropType"},"name":"ImageSourcePropType","package":"react-native"}},{"name":"tintColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The tint color to apply to the icon.\nAccepts hex strings, named colors, or RGB arrays."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n\n```"}]}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"Icon","variant":"declaration","kind":64,"signatures":[{"name":"Icon","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays an icon from an XML vector drawable or other image source.\n\nThe Icon component renders vector graphics and images with support for\ntinting, sizing, and accessibility features. On Android, it natively\nsupports XML vector drawables loaded via Metro bundler using "},{"kind":"code","text":"`require()`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@example","content":[{"kind":"text","text":"Basic usage:\n"},{"kind":"code","text":"```tsx\nimport { Icon } from 'expo-ui';\n\n\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"With styling:\n"},{"kind":"code","text":"```tsx\n\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"With modifiers:\n"},{"kind":"code","text":"```tsx\n\n```"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"IconProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/iconbutton.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/iconbutton.json new file mode 100644 index 00000000000000..6fc644174d5639 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/iconbutton.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/iconbutton","variant":"project","kind":1,"children":[{"name":"IconButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text to display inside the button."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"React.JSX.Element","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Button color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Disabled state of the button."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for button's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Button/index.tsx","qualifiedName":"ButtonElementColors"},"name":"ButtonElementColors","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"A callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"shape","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"ShapeJSXElement"},"name":"ShapeJSXElement","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The button variant."}]},"type":{"type":"reference","name":"IconButtonVariant","package":"@expo/ui"}}]},{"name":"IconButtonVariant","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"The built-in button styles available on Android.\n- "},{"kind":"code","text":"`outlined`"},{"kind":"text","text":" - A button with an outline.\n- "},{"kind":"code","text":"`elevated`"},{"kind":"text","text":" - A filled button with a shadow."}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"bordered"},{"type":"literal","value":"outlined"}]}},{"name":"IconButton","variant":"declaration","kind":64,"signatures":[{"name":"IconButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native button component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"IconButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/lazycolumn.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/lazycolumn.json new file mode 100644 index 00000000000000..de2b7f868412e2 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/lazycolumn.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/lazycolumn","variant":"project","kind":1,"children":[{"name":"ContentPadding","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Content padding values for LazyColumn."}]},"children":[{"name":"bottom","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Bottom padding in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"end","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"End padding in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"start","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Start padding in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"top","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Top padding in dp."}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"LazyColumnProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the lazy column."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"contentPadding","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Content padding in dp."}]},"type":{"type":"reference","name":"ContentPadding","package":"@expo/ui"}},{"name":"horizontalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The horizontal alignment of items."}]},"type":{"type":"union","types":[{"type":"literal","value":"start"},{"type":"literal","value":"end"},{"type":"literal","value":"center"}]}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"verticalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The vertical arrangement of items.\nCan be a preset string or an object with "},{"kind":"code","text":"`spacedBy`"},{"kind":"text","text":" to specify spacing in dp."}]},"type":{"type":"union","types":[{"type":"literal","value":"top"},{"type":"literal","value":"bottom"},{"type":"literal","value":"center"},{"type":"literal","value":"spaceBetween"},{"type":"literal","value":"spaceAround"},{"type":"literal","value":"spaceEvenly"},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"spacedBy","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}}]}}]}}]},{"name":"LazyColumn","variant":"declaration","kind":64,"signatures":[{"name":"LazyColumn","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A lazy column component that efficiently displays a vertically scrolling list."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"LazyColumnProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/listitem.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/listitem.json new file mode 100644 index 00000000000000..0ffdffba87a6f9 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/listitem.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/listitem","variant":"project","kind":1,"children":[{"name":"ListItemColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for list item's core elements."}]},"children":[{"name":"containerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"headlineColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"leadingIconColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"overlineColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"supportingColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"trailingIconColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"ListItemProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Children containing Leading and Trailing slots."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The background color of the list item."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"colors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for list item's core elements."}]},"type":{"type":"reference","name":"ListItemColors","package":"@expo/ui"}},{"name":"headline","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The main text content of the list item."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the list item is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"overlineText","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional overline text displayed above the headline."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"supportingText","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional supporting text displayed below the headline."}]},"type":{"type":"intrinsic","name":"string"}}]},{"name":"ListItem","variant":"declaration","kind":64,"children":[{"name":"Leading","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Leading content slot for ListItem."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"LeadingProps"},"name":"LeadingProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"SupportingContent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Custom supporting content slot for ListItem.\nWhen provided, this takes precedence over the "},{"kind":"code","text":"`supportingText`"},{"kind":"text","text":" prop."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"SupportingContentProps"},"name":"SupportingContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Trailing","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Trailing content slot for ListItem."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"TrailingProps"},"name":"TrailingProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"ListItem","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A list item component following Material 3 design guidelines."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ListItemProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"ListItemLeading","variant":"declaration","kind":64,"signatures":[{"name":"ListItemLeading","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Leading content slot for ListItem."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"LeadingProps"},"name":"LeadingProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"ListItemSupportingContent","variant":"declaration","kind":64,"signatures":[{"name":"ListItemSupportingContent","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Custom supporting content slot for ListItem.\nWhen provided, this takes precedence over the "},{"kind":"code","text":"`supportingText`"},{"kind":"text","text":" prop."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"SupportingContentProps"},"name":"SupportingContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"ListItemTrailing","variant":"declaration","kind":64,"signatures":[{"name":"ListItemTrailing","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Trailing content slot for ListItem."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/ListItem/index.tsx","qualifiedName":"TrailingProps"},"name":"TrailingProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/modifiers.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/modifiers.json new file mode 100644 index 00000000000000..0cbe57b4e29204 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/modifiers.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/modifiers","variant":"project","kind":1,"children":[{"name":"Alignment","variant":"declaration","kind":2097152,"type":{"type":"union","types":[{"type":"literal","value":"topStart"},{"type":"literal","value":"topCenter"},{"type":"literal","value":"topEnd"},{"type":"literal","value":"centerStart"},{"type":"literal","value":"center"},{"type":"literal","value":"centerEnd"},{"type":"literal","value":"bottomStart"},{"type":"literal","value":"bottomCenter"},{"type":"literal","value":"bottomEnd"},{"type":"literal","value":"top"},{"type":"literal","value":"centerVertically"},{"type":"literal","value":"bottom"},{"type":"literal","value":"start"},{"type":"literal","value":"centerHorizontally"},{"type":"literal","value":"end"}]}},{"name":"BuiltinShape","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Built-in Jetpack Compose shape for the clip modifier."}]},"type":{"type":"union","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"rectangle"}}]}},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"circle"}}]}},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"bottomEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"bottomStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"radius","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"topEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"topStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"roundedCorner"}}]}},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"bottomEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"bottomStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"radius","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"topEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"topStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"number"}},{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"cutCorner"}}]}},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"name","variant":"declaration","kind":1024,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/index.ts","qualifiedName":"MaterialShapeName"},"name":"MaterialShapeName","package":"@expo/ui"}},{"name":"type","variant":"declaration","kind":1024,"type":{"type":"literal","value":"material"}}]}}]}},{"name":"ExpoModifier","variant":"declaration","kind":2097152,"comment":{"summary":[],"blockTags":[{"tag":"@deprecated","content":[{"kind":"text","text":"Use ModifierConfig instead. ExpoModifier (SharedRef pattern) has been replaced\nwith JSON Config pattern for better DX and platform consistency."}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}},{"name":"Shapes","variant":"declaration","kind":32,"flags":{"isConst":true},"comment":{"summary":[{"kind":"text","text":"Predefined shapes for use with the "},{"kind":"code","text":"`clip`"},{"kind":"text","text":" modifier."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\nclip(Shapes.Circle)\nclip(Shapes.RoundedCorner(16))\nclip(Shapes.RoundedCorner({ topStart: 8, bottomEnd: 16 }))\nclip(Shapes.Material.Heart)\n```"}]}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"Circle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"CutCorner","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"params","variant":"param","kind":32768,"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/index.ts","qualifiedName":"CornerRadii"},"name":"CornerRadii","package":"@expo/ui"}]}}],"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"}}]}},"defaultValue":"..."},{"name":"Material","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"Arch","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Boom","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Bun","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Clover4Leaf","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Clover8Leaf","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie12Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie4Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie6Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie7Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Cookie9Sided","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Diamond","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Fan","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Ghostish","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Heart","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Oval","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Pentagon","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Pill","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"PixelCircle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"PixelTriangle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Puffy","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"PuffyDiamond","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Slanted","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"SoftBurst","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Sunny","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"Triangle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"VerySunny","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."}]}},"defaultValue":"..."},{"name":"Rectangle","variant":"declaration","kind":1024,"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"},"defaultValue":"..."},{"name":"RoundedCorner","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"params","variant":"param","kind":32768,"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/index.ts","qualifiedName":"CornerRadii"},"name":"CornerRadii","package":"@expo/ui"}]}}],"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"}}]}},"defaultValue":"..."}]}},"defaultValue":"..."},{"name":"align","variant":"declaration","kind":64,"signatures":[{"name":"align","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Aligns the view within its container."}]},"parameters":[{"name":"alignment","variant":"param","kind":32768,"type":{"type":"reference","name":"Alignment","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"alpha","variant":"declaration","kind":64,"signatures":[{"name":"alpha","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the opacity/alpha of the view."}]},"parameters":[{"name":"alpha","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Opacity value (0.0 to 1.0)."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"animateContentSize","variant":"declaration","kind":64,"signatures":[{"name":"animateContentSize","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Animates size changes with spring animation."}]},"parameters":[{"name":"dampingRatio","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Spring damping ratio. Default is DampingRatioNoBouncy."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"stiffness","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Spring stiffness. Default is StiffnessMedium."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"background","variant":"declaration","kind":64,"signatures":[{"name":"background","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the background color."}]},"parameters":[{"name":"color","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Color string (hex, e.g., '#FF0000')."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"blur","variant":"declaration","kind":64,"signatures":[{"name":"blur","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Applies a blur effect."}]},"parameters":[{"name":"radius","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Blur radius in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"border","variant":"declaration","kind":64,"signatures":[{"name":"border","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Adds a border around the view."}]},"parameters":[{"name":"borderWidth","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Border width in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"borderColor","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Border color string (hex)."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"clickable","variant":"declaration","kind":64,"signatures":[{"name":"clickable","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Makes the view clickable."}]},"parameters":[{"name":"handler","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Function to call when clicked."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"clip","variant":"declaration","kind":64,"signatures":[{"name":"clip","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Clips the view to a built-in Jetpack Compose shape."}]},"parameters":[{"name":"shape","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"A shape from "},{"kind":"code","text":"`Shapes`"},{"kind":"text","text":", e.g. "},{"kind":"code","text":"`Shapes.Circle`"},{"kind":"text","text":" or "},{"kind":"code","text":"`Shapes.Material.Heart`"},{"kind":"text","text":"."}]},"type":{"type":"reference","name":"BuiltinShape","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"fillMaxHeight","variant":"declaration","kind":64,"signatures":[{"name":"fillMaxHeight","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Fills the maximum available height."}]},"parameters":[{"name":"fraction","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Fraction of max height (0.0 to 1.0). Default is 1.0."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"fillMaxSize","variant":"declaration","kind":64,"signatures":[{"name":"fillMaxSize","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Fills the maximum available size."}]},"parameters":[{"name":"fraction","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Fraction of max size (0.0 to 1.0). Default is 1.0."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"fillMaxWidth","variant":"declaration","kind":64,"signatures":[{"name":"fillMaxWidth","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Fills the maximum available width."}]},"parameters":[{"name":"fraction","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Fraction of max width (0.0 to 1.0). Default is 1.0."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"height","variant":"declaration","kind":64,"signatures":[{"name":"height","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the exact height of the view."}]},"parameters":[{"name":"value","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Height in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"matchParentSize","variant":"declaration","kind":64,"signatures":[{"name":"matchParentSize","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Makes the view match the parent Box size.\nOnly works when used inside Box."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"offset","variant":"declaration","kind":64,"signatures":[{"name":"offset","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Offsets the view from its natural position."}]},"parameters":[{"name":"x","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Horizontal offset in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"y","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Vertical offset in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"padding","variant":"declaration","kind":64,"signatures":[{"name":"padding","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Applies padding with individual values for each side."}]},"parameters":[{"name":"start","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Left padding in dp (or right in RTL)."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"top","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Top padding in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"end","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Right padding in dp (or left in RTL)."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"bottom","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Bottom padding in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"paddingAll","variant":"declaration","kind":64,"signatures":[{"name":"paddingAll","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Applies equal padding on all sides."}]},"parameters":[{"name":"all","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Padding value in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"rotate","variant":"declaration","kind":64,"signatures":[{"name":"rotate","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Rotates the view."}]},"parameters":[{"name":"degrees","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Rotation angle in degrees."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"selectable","variant":"declaration","kind":64,"signatures":[{"name":"selectable","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Makes the view selectable, like a radio button row."}]},"parameters":[{"name":"selected","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Whether the item is currently selected."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"handler","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Function to call when the item is clicked."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"shadow","variant":"declaration","kind":64,"signatures":[{"name":"shadow","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Adds a shadow/elevation effect."}]},"parameters":[{"name":"elevation","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Shadow elevation in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"size","variant":"declaration","kind":64,"signatures":[{"name":"size","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets exact width and height."}]},"parameters":[{"name":"width","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Width in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"height","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Height in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"testID","variant":"declaration","kind":64,"signatures":[{"name":"testID","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the test ID for testing frameworks."}]},"parameters":[{"name":"tag","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Test ID string."}]},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"weight","variant":"declaration","kind":64,"signatures":[{"name":"weight","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the weight for flexible sizing in Row or Column.\nOnly works when used inside Row or Column."}]},"parameters":[{"name":"weight","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Weight value (relative to siblings)."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"width","variant":"declaration","kind":64,"signatures":[{"name":"width","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the exact width of the view."}]},"parameters":[{"name":"value","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Width in dp."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"wrapContentHeight","variant":"declaration","kind":64,"signatures":[{"name":"wrapContentHeight","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Wraps the height to the content size."}]},"parameters":[{"name":"alignment","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional vertical alignment ('top', 'centerVertically', 'bottom')."}]},"type":{"type":"union","types":[{"type":"literal","value":"top"},{"type":"literal","value":"bottom"},{"type":"literal","value":"centerVertically"}]}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"wrapContentWidth","variant":"declaration","kind":64,"signatures":[{"name":"wrapContentWidth","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Wraps the width to the content size."}]},"parameters":[{"name":"alignment","variant":"param","kind":32768,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Optional horizontal alignment ('start', 'centerHorizontally', 'end')."}]},"type":{"type":"union","types":[{"type":"literal","value":"start"},{"type":"literal","value":"end"},{"type":"literal","value":"centerHorizontally"}]}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]},{"name":"zIndex","variant":"declaration","kind":64,"signatures":[{"name":"zIndex","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Sets the z-index for layering."}]},"parameters":[{"name":"index","variant":"param","kind":32768,"comment":{"summary":[{"kind":"text","text":"Z-index value."}]},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/modifiers/createModifier.ts","qualifiedName":"ModifierConfig"},"name":"ModifierConfig","package":"@expo/ui"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/picker.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/picker.json index 08493207e5efb7..d51c2971881e70 100644 --- a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/picker.json +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/picker.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/picker","variant":"project","kind":1,"children":[{"name":"PickerElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for picker's core elements."}]},"children":[{"name":"activeBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"activeContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"activeContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledActiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledActiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledActiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledInactiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledInactiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"disabledInactiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}}]},{"name":"PickerProps","variant":"declaration","kind":2097152,"children":[{"name":"buttonModifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the individual buttons"}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Picker color."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for picker's core elements."}]},"type":{"type":"reference","name":"PickerElementColors","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onOptionSelected","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when an option is selected."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"event","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"nativeEvent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"index","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}},{"name":"label","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}]}}}]}}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"options","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"An array of options to be displayed in the picker."}]},"type":{"type":"array","elementType":{"type":"intrinsic","name":"string"}}},{"name":"selectedIndex","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The index of the currently selected option."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"literal","value":null}]}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the picker, which determines its appearance and behavior."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'segmented'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"segmented"},{"type":"literal","value":"radio"}]}}]},{"name":"Picker","variant":"declaration","kind":64,"signatures":[{"name":"Picker","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native picker component. Depending on the variant it can be a segmented button, an inline picker, a list of choices or a radio button."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"PickerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/picker","variant":"project","kind":1,"children":[{"name":"PickerElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for picker's core elements."}]},"children":[{"name":"activeBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"activeContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"activeContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledActiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledActiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledActiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledInactiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledInactiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabledInactiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveBorderColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveContainerColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveContentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"PickerProps","variant":"declaration","kind":2097152,"children":[{"name":"buttonModifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the individual buttons"}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Picker color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for picker's core elements."}]},"type":{"type":"reference","name":"PickerElementColors","package":"@expo/ui"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onOptionSelected","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when an option is selected."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"event","variant":"param","kind":32768,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"nativeEvent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"index","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"number"}},{"name":"label","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"string"}}]}}}]}}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"options","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"An array of options to be displayed in the picker."}]},"type":{"type":"array","elementType":{"type":"intrinsic","name":"string"}}},{"name":"selectedIndex","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The index of the currently selected option."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"number"},{"type":"literal","value":null}]}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the picker, which determines its appearance and behavior."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'segmented'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"segmented"},{"type":"literal","value":"radio"}]}}]},{"name":"Picker","variant":"declaration","kind":64,"signatures":[{"name":"Picker","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Displays a native picker component. Depending on the variant it can be a segmented button, an inline picker, a list of choices or a radio button."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"PickerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/pulltorefreshbox.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/pulltorefreshbox.json new file mode 100644 index 00000000000000..33d3dd08d418ba --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/pulltorefreshbox.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/pulltorefreshbox","variant":"project","kind":1,"children":[{"name":"PullToRefreshBoxProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"The content to refresh."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"isRefreshing","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the content is refreshing."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"false"}]}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"loadingIndicatorModifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the loading indicator."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"[align('topCenter'), padding(0, 10, 0, 0)]"}]}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onRefresh","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback to call when the content is refreshed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"PullToRefreshBox","variant":"declaration","kind":64,"signatures":[{"name":"PullToRefreshBox","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`PullToRefreshBox`"},{"kind":"text","text":" component.\nA box that allows the user to pull down to refresh the content."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"PullToRefreshBoxProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/radiobutton.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/radiobutton.json new file mode 100644 index 00000000000000..fddd85bf0c75df --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/radiobutton.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/radiobutton","variant":"project","kind":1,"children":[{"name":"RadioButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onClick","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the radio button is clicked."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"selected","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Whether the radio button is selected."}]},"type":{"type":"intrinsic","name":"boolean"}}]},{"name":"RadioButton","variant":"declaration","kind":64,"signatures":[{"name":"RadioButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A Material Design radio button."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"RadioButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/rnhostview.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/rnhostview.json new file mode 100644 index 00000000000000..9c2e95fee1ced5 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/rnhostview.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/rnhostview","variant":"project","kind":1,"children":[{"name":"RNHostView","variant":"declaration","kind":64,"signatures":[{"name":"RNHostView","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/RNHostView/index.tsx","qualifiedName":"RNHostProps"},"name":"RNHostProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/row.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/row.json new file mode 100644 index 00000000000000..5677e37f195317 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/row.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/row","variant":"project","kind":1,"children":[{"name":"RowProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"horizontalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal alignment of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalAlignment"},"name":"HorizontalAlignment","package":"@expo/ui"}},{"name":"horizontalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Horizontal arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"HorizontalArrangement"},"name":"HorizontalArrangement","package":"@expo/ui"}},{"name":"verticalAlignment","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical alignment of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalAlignment"},"name":"VerticalAlignment","package":"@expo/ui"}},{"name":"verticalArrangement","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Vertical arrangement of children."}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"VerticalArrangement"},"name":"VerticalArrangement","package":"@expo/ui"}}]}},{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/layout-types.ts","qualifiedName":"PrimitiveBaseProps"},"name":"PrimitiveBaseProps","package":"@expo/ui"}]}},{"name":"Row","variant":"declaration","kind":64,"signatures":[{"name":"Row","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"RowProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/searchbar.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/searchbar.json new file mode 100644 index 00000000000000..8c2c9bdb436d2d --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/searchbar.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/searchbar","variant":"project","kind":1,"children":[{"name":"SearchBarProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The children of the component."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onSearch","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the search text is submitted."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"searchText","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"ExpandedFullScreenSearchBar","variant":"declaration","kind":64,"signatures":[{"name":"ExpandedFullScreenSearchBar","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"ExpandedFullScreenSearchBar component for SearchBar.\nThis component marks its children to be rendered in the expanded full-screen search bar."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/SearchBar/index.tsx","qualifiedName":"ExpandedFullScreenSearchBarProps"},"name":"ExpandedFullScreenSearchBarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"SearchBar","variant":"declaration","kind":64,"children":[{"name":"ExpandedFullScreenSearchBar","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"ExpandedFullScreenSearchBar component for SearchBar.\nThis component marks its children to be rendered in the expanded full-screen search bar."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/SearchBar/index.tsx","qualifiedName":"ExpandedFullScreenSearchBarProps"},"name":"ExpandedFullScreenSearchBarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}},{"name":"Placeholder","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Placeholder component for SearchBar.\nThis component marks its children to be rendered in the placeholder slot."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/SearchBar/index.tsx","qualifiedName":"PlaceholderProps"},"name":"PlaceholderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"SearchBar","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a "},{"kind":"code","text":"`SearchBar`"},{"kind":"text","text":" component."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SearchBarProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"SearchBarPlaceholder","variant":"declaration","kind":64,"signatures":[{"name":"SearchBarPlaceholder","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Placeholder component for SearchBar.\nThis component marks its children to be rendered in the placeholder slot."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/SearchBar/index.tsx","qualifiedName":"PlaceholderProps"},"name":"PlaceholderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/shape.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/shape.json new file mode 100644 index 00000000000000..bad67ff9cca2a1 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/shape.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/shape","variant":"project","kind":1,"children":[{"name":"CornerRadii","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Corner radii for RoundedCorner shape."}]},"children":[{"name":"bottomEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Bottom-end corner radius in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"bottomStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Bottom-start corner radius in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"topEnd","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Top-end corner radius in dp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"topStart","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Top-start corner radius in dp."}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"ShapeJSXElement","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactElement"},"typeArguments":[{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"NativeShapeProps"},"name":"NativeShapeProps","package":"@expo/ui"}],"name":"React.ReactElement","package":"@types/react"},{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"__expo_shape_jsx_element_marker","variant":"declaration","kind":1024,"type":{"type":"literal","value":true}}]}}]}},{"name":"ShapeProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Color of the shape"}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"cornerRadii","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Corner radii for RoundedCorner shape. Values are in dp."}]},"type":{"type":"reference","name":"CornerRadii","package":"@expo/ui"}},{"name":"cornerRounding","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Corner rounding percentage. Multiplied by the shorter dimension of the view to produce pixel values."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0.0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"innerRadius","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Inner radius of star-related shapes ("},{"kind":"code","text":"`'STAR'`"},{"kind":"text","text":" and "},{"kind":"code","text":"`'PILL_STAR'`"},{"kind":"text","text":"). Multiplied by the shorter dimension of the view to produce pixel values."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"1.0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"radius","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Radius of the circular shape. Multiplied by the shorter dimension of the view to produce pixel values."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"1.0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"smoothing","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Number between "},{"kind":"code","text":"`0.0`"},{"kind":"text","text":" and "},{"kind":"code","text":"`1.0`"},{"kind":"text","text":" that determines how much each line between vertices is \"smoothed\"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0.0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"verticesCount","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Number of vertices. For "},{"kind":"code","text":"`'POLYGON'`"},{"kind":"text","text":" it must be at least "},{"kind":"code","text":"`3.0`"},{"kind":"text","text":". For "},{"kind":"code","text":"`'STAR'`"},{"kind":"text","text":" and "},{"kind":"code","text":"`'PILL_STAR'`"},{"kind":"text","text":" it is a number of vertices for each of two radii (A 5-pointed star has 10 vertices.)"}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"6.0"}]}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"ShapeRecordProps","variant":"declaration","kind":2097152,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Shape/index.tsx","qualifiedName":"NativeShapeProps"},"name":"NativeShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"cornerRounding"},{"type":"literal","value":"smoothing"},{"type":"literal","value":"verticesCount"},{"type":"literal","value":"innerRadius"},{"type":"literal","value":"radius"},{"type":"literal","value":"cornerRadii"},{"type":"literal","value":"type"}]}],"name":"Pick","package":"typescript"}},{"name":"Shape","variant":"declaration","kind":32,"flags":{"isConst":true},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"Circle","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"radius"},{"type":"literal","value":"verticesCount"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"Pill","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"smoothing"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"PillStar","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ShapeProps","package":"@expo/ui"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"Polygon","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"smoothing"},{"type":"literal","value":"cornerRounding"},{"type":"literal","value":"verticesCount"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"Rectangle","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"smoothing"},{"type":"literal","value":"cornerRounding"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"RoundedCorner","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"typescript","packagePath":"lib/lib.es5.d.ts","qualifiedName":"Pick"},"typeArguments":[{"type":"reference","name":"ShapeProps","package":"@expo/ui"},{"type":"union","types":[{"type":"literal","value":"cornerRadii"},{"type":"literal","value":"color"},{"type":"literal","value":"modifiers"}]}],"name":"Pick","package":"typescript"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}},{"name":"Star","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ShapeProps","package":"@expo/ui"}}],"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}]}}}]}},"defaultValue":"..."},{"name":"parseJSXShape","variant":"declaration","kind":64,"signatures":[{"name":"parseJSXShape","variant":"signature","kind":4096,"parameters":[{"name":"shape","variant":"param","kind":32768,"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}],"type":{"type":"reference","name":"ShapeRecordProps","package":"@expo/ui"}},{"name":"parseJSXShape","variant":"signature","kind":4096,"parameters":[{"name":"shape","variant":"param","kind":32768,"flags":{"isOptional":true},"type":{"type":"reference","name":"ShapeJSXElement","package":"@expo/ui"}}],"type":{"type":"union","types":[{"type":"reference","name":"ShapeRecordProps","package":"@expo/ui"},{"type":"intrinsic","name":"undefined"}]}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/slider.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/slider.json index 056e7c4c7aac03..4dc4d2d4ab6998 100644 --- a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/slider.json +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/slider.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/slider","variant":"project","kind":1,"children":[{"name":"SliderElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for slider's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"children":[{"name":"activeTickColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"activeTrackColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveTickColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"inactiveTrackColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}},{"name":"thumbColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"string"}}]},{"name":"SliderProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Slider color."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for slider's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","name":"SliderElementColors","package":"@expo/ui"}},{"name":"max","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The maximum value of the slider. Updating this value does not trigger callbacks if the current value is above "},{"kind":"code","text":"`max`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"1"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"min","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The minimum value of the slider. Updating this value does not trigger callbacks if the current value is below "},{"kind":"code","text":"`min`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onValueChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback triggered on dragging along the slider."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"value","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"steps","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The number of steps between the minimum and maximum values, "},{"kind":"code","text":"`0`"},{"kind":"text","text":" signifies infinite steps."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"value","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The current value of the slider."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"Slider","variant":"declaration","kind":64,"signatures":[{"name":"Slider","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SliderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/slider","variant":"project","kind":1,"children":[{"name":"SliderElementColors","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Colors for slider's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"children":[{"name":"activeTickColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"activeTrackColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveTickColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"inactiveTrackColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"thumbColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}}]},{"name":"SliderProps","variant":"declaration","kind":2097152,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Slider color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for slider's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","name":"SliderElementColors","package":"@expo/ui"}},{"name":"max","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The maximum value of the slider. Updating this value does not trigger callbacks if the current value is above "},{"kind":"code","text":"`max`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"1"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"min","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The minimum value of the slider. Updating this value does not trigger callbacks if the current value is below "},{"kind":"code","text":"`min`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onValueChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback triggered on dragging along the slider."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"value","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"steps","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The number of steps between the minimum and maximum values, "},{"kind":"code","text":"`0`"},{"kind":"text","text":" signifies infinite steps."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"value","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The current value of the slider."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"Slider","variant":"declaration","kind":64,"signatures":[{"name":"Slider","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SliderProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/spacer.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/spacer.json new file mode 100644 index 00000000000000..6fe94160ef03f1 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/spacer.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/spacer","variant":"project","kind":1,"children":[{"name":"SpacerProps","variant":"declaration","kind":2097152,"children":[{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component. Use weight() modifier to make the spacer flexible."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}}]},{"name":"Spacer","variant":"declaration","kind":64,"signatures":[{"name":"Spacer","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A spacer component that fills available space.\nUse with the weight() modifier to create flexible spacing in Row or Column layouts."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\n\n Left\n \n Right\n\n```"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SpacerProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/surface.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/surface.json new file mode 100644 index 00000000000000..5f051ef17f4f00 --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/surface.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/surface","variant":"project","kind":1,"children":[{"name":"SurfaceProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the surface."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The background color of the surface.\nDefaults to "},{"kind":"code","text":"`MaterialTheme.colorScheme.surface`"},{"kind":"text","text":"."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"contentColor","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the content inside the surface.\nDefaults to "},{"kind":"code","text":"`contentColorFor(color)`"},{"kind":"text","text":"."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"shadowElevation","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The shadow elevation of the surface. Value in dp."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}},{"name":"tonalElevation","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The tonal elevation of the surface, which affects its background color\nbased on the color scheme. Value in dp."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"0"}]}]},"type":{"type":"intrinsic","name":"number"}}]},{"name":"Surface","variant":"declaration","kind":64,"signatures":[{"name":"Surface","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A Material Design surface container. Surface is responsible for:\n- Clipping content to the shape\n- Applying background color based on tonal elevation\n- Providing content color to its children"}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SurfaceProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/switch.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/switch.json index b084bc77c804ee..9cfa852e9429bd 100644 --- a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/switch.json +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/switch.json @@ -1 +1 @@ -{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/switch","variant":"project","kind":1,"children":[{"name":"SwitchButtonVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"undefined"}},{"name":"variant","variant":"declaration","kind":1024,"type":{"type":"literal","value":"button"}}]},{"name":"SwitchCheckboxVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for checkbox core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"CheckboxElementColors"},"name":"CheckboxElementColors","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"type":{"type":"literal","value":"checkbox"}}]},{"name":"SwitchProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Picker color."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"label","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Label for the switch.\n\n> On Android, the label has an effect only when the "},{"kind":"code","text":"`Switch`"},{"kind":"text","text":" is used inside a "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":"."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onValueChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the checked state changes."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"value","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"boolean"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"value","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Indicates whether the switch is checked."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Type of the switch component. Can be "},{"kind":"code","text":"`'checkbox'`"},{"kind":"text","text":", "},{"kind":"code","text":"`'switch'`"},{"kind":"text","text":", or "},{"kind":"code","text":"`'button'`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'switch'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"checkbox"},{"type":"literal","value":"switch"},{"type":"literal","value":"button"}]}}]}},{"type":"union","types":[{"type":"reference","name":"SwitchSwitchVariantProps","package":"@expo/ui"},{"type":"reference","name":"SwitchCheckboxVariantProps","package":"@expo/ui"},{"type":"reference","name":"SwitchButtonVariantProps","package":"@expo/ui"}]}]}},{"name":"SwitchSwitchVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for switch's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"SwitchElementColors"},"name":"SwitchElementColors","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"literal","value":"switch"}}]},{"name":"Switch","variant":"declaration","kind":64,"signatures":[{"name":"Switch","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SwitchProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/switch","variant":"project","kind":1,"children":[{"name":"SwitchButtonVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"intrinsic","name":"undefined"}},{"name":"variant","variant":"declaration","kind":1024,"type":{"type":"literal","value":"button"}}]},{"name":"SwitchCheckboxVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for checkbox core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"CheckboxElementColors"},"name":"CheckboxElementColors","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"type":{"type":"literal","value":"checkbox"}}]},{"name":"SwitchProps","variant":"declaration","kind":2097152,"type":{"type":"intersection","types":[{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Children containing ThumbContent slot."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Picker color."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"label","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Label for the switch.\n\n> On Android, the label has an effect only when the "},{"kind":"code","text":"`Switch`"},{"kind":"text","text":" is used inside a "},{"kind":"code","text":"`ContextMenu`"},{"kind":"text","text":"."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onValueChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback function that is called when the checked state changes."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"value","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"boolean"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"value","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Indicates whether the switch is checked."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Type of the switch component. Can be "},{"kind":"code","text":"`'checkbox'`"},{"kind":"text","text":", "},{"kind":"code","text":"`'switch'`"},{"kind":"text","text":", or "},{"kind":"code","text":"`'button'`"},{"kind":"text","text":"."}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'switch'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"checkbox"},{"type":"literal","value":"switch"},{"type":"literal","value":"button"}]}}]}},{"type":"union","types":[{"type":"reference","name":"SwitchSwitchVariantProps","package":"@expo/ui"},{"type":"reference","name":"SwitchCheckboxVariantProps","package":"@expo/ui"},{"type":"reference","name":"SwitchButtonVariantProps","package":"@expo/ui"}]}]}},{"name":"SwitchSwitchVariantProps","variant":"declaration","kind":2097152,"children":[{"name":"elementColors","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Colors for switch's core elements."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"SwitchElementColors"},"name":"SwitchElementColors","package":"@expo/ui"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"type":{"type":"literal","value":"switch"}}]},{"name":"Switch","variant":"declaration","kind":64,"children":[{"name":"DefaultIconSize","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"any"}},{"name":"ThumbContent","variant":"declaration","kind":1024,"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Custom content to be displayed inside the switch thumb."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"ThumbContentProps"},"name":"ThumbContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}}}],"signatures":[{"name":"Switch","variant":"signature","kind":4096,"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"SwitchProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]},{"name":"SwitchThumbContent","variant":"declaration","kind":64,"signatures":[{"name":"SwitchThumbContent","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Custom content to be displayed inside the switch thumb."}],"blockTags":[{"tag":"@platform","content":[{"kind":"text","text":"android"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/jetpack-compose/Switch/index.tsx","qualifiedName":"ThumbContentProps"},"name":"ThumbContentProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/text.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/text.json new file mode 100644 index 00000000000000..f49239b4a77b2d --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/text.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/text","variant":"project","kind":1,"children":[{"name":"TextAlign","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Text alignment options."}]},"type":{"type":"union","types":[{"type":"literal","value":"left"},{"type":"literal","value":"right"},{"type":"literal","value":"center"},{"type":"literal","value":"justify"},{"type":"literal","value":"start"},{"type":"literal","value":"end"}]}},{"name":"TextDecoration","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Text decoration options."}]},"type":{"type":"union","types":[{"type":"literal","value":"none"},{"type":"literal","value":"underline"},{"type":"literal","value":"lineThrough"}]}},{"name":"TextFontStyle","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Font style options for text styling."}]},"type":{"type":"union","types":[{"type":"literal","value":"normal"},{"type":"literal","value":"italic"}]}},{"name":"TextFontWeight","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Font weight options for text styling."}]},"type":{"type":"union","types":[{"type":"literal","value":"normal"},{"type":"literal","value":"bold"},{"type":"literal","value":"100"},{"type":"literal","value":"200"},{"type":"literal","value":"300"},{"type":"literal","value":"400"},{"type":"literal","value":"500"},{"type":"literal","value":"600"},{"type":"literal","value":"700"},{"type":"literal","value":"800"},{"type":"literal","value":"900"}]}},{"name":"TextOverflow","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Text overflow behavior options."}]},"type":{"type":"union","types":[{"type":"literal","value":"clip"},{"type":"literal","value":"ellipsis"},{"type":"literal","value":"visible"}]}},{"name":"TextProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text content to display."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the text."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"maxLines","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"An optional maximum number of lines for the text to span, wrapping if necessary.\nIf the text exceeds the given number of lines, it will be truncated according to overflow."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"minLines","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The minimum height in terms of minimum number of visible lines."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"overflow","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"How visual overflow should be handled.\n- 'clip': Clips the overflowing text to fix its container\n- 'ellipsis': Uses an ellipsis to indicate that the text has overflowed\n- 'visible': Renders overflow text outside its container"}]},"type":{"type":"reference","name":"TextOverflow","package":"@expo/ui"}},{"name":"softWrap","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the text should break at soft line breaks.\nIf false, the glyphs in the text will be positioned as if there was unlimited horizontal space."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"style","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Style configuration for the text.\nCorresponds to Jetpack Compose's TextStyle parameter."}]},"type":{"type":"reference","name":"TextStyle","package":"@expo/ui"}}]},{"name":"TextStyle","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Text style properties that can be applied to text.\nCorresponds to Jetpack Compose's TextStyle."}]},"children":[{"name":"fontSize","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The font size in sp (scale-independent pixels)."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"fontStyle","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The font style of the text."}]},"type":{"type":"reference","name":"TextFontStyle","package":"@expo/ui"}},{"name":"fontWeight","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The font weight of the text."}]},"type":{"type":"reference","name":"TextFontWeight","package":"@expo/ui"}},{"name":"letterSpacing","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The letter spacing in sp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"lineHeight","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The line height in sp."}]},"type":{"type":"intrinsic","name":"number"}},{"name":"textAlign","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text alignment."}]},"type":{"type":"reference","name":"TextAlign","package":"@expo/ui"}},{"name":"textDecoration","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text decoration."}]},"type":{"type":"reference","name":"TextDecoration","package":"@expo/ui"}},{"name":"typography","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Material 3 Typography style to use as the base style.\nWhen specified, applies the predefined Material 3 typography style.\nOther properties in this style object will override specific values from the typography."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```tsx\nstyle={{ typography: \"bodyLarge\" }}\nstyle={{ typography: \"headlineMedium\", fontWeight: \"bold\" }}\n```"}]}]},"type":{"type":"reference","name":"TypographyStyle","package":"@expo/ui"}}]},{"name":"TypographyStyle","variant":"declaration","kind":2097152,"comment":{"summary":[{"kind":"text","text":"Material 3 Typography scale styles.\nCorresponds to MaterialTheme.typography in Jetpack Compose."}]},"type":{"type":"union","types":[{"type":"literal","value":"displayLarge"},{"type":"literal","value":"displayMedium"},{"type":"literal","value":"displaySmall"},{"type":"literal","value":"headlineLarge"},{"type":"literal","value":"headlineMedium"},{"type":"literal","value":"headlineSmall"},{"type":"literal","value":"titleLarge"},{"type":"literal","value":"titleMedium"},{"type":"literal","value":"titleSmall"},{"type":"literal","value":"bodyLarge"},{"type":"literal","value":"bodyMedium"},{"type":"literal","value":"bodySmall"},{"type":"literal","value":"labelLarge"},{"type":"literal","value":"labelMedium"},{"type":"literal","value":"labelSmall"}]}},{"name":"Text","variant":"declaration","kind":64,"signatures":[{"name":"Text","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"Renders a Text component using Jetpack Compose.\n\nThe Text component provides comprehensive text styling capabilities.\nThe API is aligned with Jetpack Compose's Text composable, where:\n- Top-level props (color, maxLines, etc.) match Compose's Text parameters\n- "},{"kind":"code","text":"`style`"},{"kind":"text","text":" object corresponds to TextStyle, including typography, fontSize, fontWeight, textAlign, etc.\n- "},{"kind":"code","text":"`style.typography`"},{"kind":"text","text":" applies Material 3 typography styles (like MaterialTheme.typography)"}],"blockTags":[{"tag":"@example","content":[{"kind":"text","text":"Basic usage:\n"},{"kind":"code","text":"```tsx\nimport { Text } from 'expo-ui';\n\nHello World\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"Using Material 3 Typography (matches Jetpack Compose MaterialTheme.typography):\n"},{"kind":"code","text":"```tsx\nBody text\nHeadline\nSmall title\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"Typography with style overrides:\n"},{"kind":"code","text":"```tsx\n\n Custom styled body text\n\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"With custom style object (matches Jetpack Compose TextStyle):\n"},{"kind":"code","text":"```tsx\n\n Styled text\n\n```"}]},{"tag":"@example","content":[{"kind":"text","text":"Text truncation with ellipsis:\n"},{"kind":"code","text":"```tsx\n\n This is a very long text that will be truncated after two lines\n with an ellipsis at the end to indicate there's more content...\n\n```"}]}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"TextProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/textbutton.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/textbutton.json new file mode 100644 index 00000000000000..758b7959d86b4a --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/textbutton.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/textbutton","variant":"project","kind":1,"children":[{"name":"TextButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The text content to display in the button."}]},"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"array","elementType":{"type":"intrinsic","name":"string"}},{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"React.JSX.Element","package":"@types/react"}]}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the button text."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the button is disabled."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onPress","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the button is pressed."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"type":{"type":"intrinsic","name":"void"}}]}}}]},{"name":"TextButton","variant":"declaration","kind":64,"signatures":[{"name":"TextButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A text button component that displays a clickable text label."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"TextButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/togglebutton.json b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/togglebutton.json new file mode 100644 index 00000000000000..e3cea8fa81d18f --- /dev/null +++ b/docs/public/static/data/v55.0.0/expo-ui/jetpack-compose/togglebutton.json @@ -0,0 +1 @@ +{"schemaVersion":"2.0","name":"expo-ui/jetpack-compose/togglebutton","variant":"project","kind":1,"children":[{"name":"ToggleButtonProps","variant":"declaration","kind":2097152,"children":[{"name":"checked","variant":"declaration","kind":1024,"comment":{"summary":[{"kind":"text","text":"Whether the toggle button is checked."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"children","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The content to display inside the toggle button."}]},"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.ReactNode"},"name":"React.ReactNode","package":"@types/react"}},{"name":"color","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The color of the toggle button when checked."}]},"type":{"type":"reference","target":{"packageName":"react-native","packagePath":"Libraries/StyleSheet/StyleSheet.d.ts","qualifiedName":"ColorValue"},"name":"ColorValue","package":"react-native"}},{"name":"disabled","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Whether the button is disabled."}]},"type":{"type":"intrinsic","name":"boolean"}},{"name":"modifiers","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Modifiers for the component."}]},"type":{"type":"array","elementType":{"type":"reference","target":{"packageName":"@expo/ui","packagePath":"src/types.ts","qualifiedName":"ExpoModifier"},"name":"ExpoModifier","package":"@expo/ui"}}},{"name":"onCheckedChange","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Callback that is called when the checked state changes."}]},"type":{"type":"reflection","declaration":{"name":"__type","variant":"declaration","kind":65536,"signatures":[{"name":"__type","variant":"signature","kind":4096,"parameters":[{"name":"checked","variant":"param","kind":32768,"type":{"type":"intrinsic","name":"boolean"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"name":"text","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"Text to display in the button."}]},"type":{"type":"intrinsic","name":"string"}},{"name":"variant","variant":"declaration","kind":1024,"flags":{"isOptional":true},"comment":{"summary":[{"kind":"text","text":"The variant of the toggle button.\n- "},{"kind":"code","text":"`'default'`"},{"kind":"text","text":" - Material 3 ToggleButton\n- "},{"kind":"code","text":"`'icon'`"},{"kind":"text","text":" - Icon toggle button\n- "},{"kind":"code","text":"`'filledIcon'`"},{"kind":"text","text":" - Filled icon toggle button\n- "},{"kind":"code","text":"`'outlinedIcon'`"},{"kind":"text","text":" - Outlined icon toggle button"}],"blockTags":[{"tag":"@default","content":[{"kind":"text","text":"'default'"}]}]},"type":{"type":"union","types":[{"type":"literal","value":"default"},{"type":"literal","value":"icon"},{"type":"literal","value":"filledIcon"},{"type":"literal","value":"outlinedIcon"}]}}]},{"name":"ToggleButton","variant":"declaration","kind":64,"children":[{"name":"DefaultIconSize","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"any"}},{"name":"DefaultIconSpacing","variant":"declaration","kind":1024,"type":{"type":"intrinsic","name":"any"}}],"signatures":[{"name":"ToggleButton","variant":"signature","kind":4096,"comment":{"summary":[{"kind":"text","text":"A toggle button component that can be toggled on and off.\n\nWhen "},{"kind":"code","text":"`text`"},{"kind":"text","text":" prop is provided, it displays the text.\nOtherwise, custom children can be passed to render custom content."}]},"parameters":[{"name":"props","variant":"param","kind":32768,"type":{"type":"reference","name":"ToggleButtonProps","package":"@expo/ui"}}],"type":{"type":"reference","target":{"packageName":"@types/react","packagePath":"index.d.ts","qualifiedName":"React.JSX.Element"},"name":"Element","package":"@types/react","qualifiedName":"React.JSX.Element"}}]}],"packageName":"@expo/ui"} \ No newline at end of file diff --git a/docs/public/static/images/sdk/sqlite/inspector.png b/docs/public/static/images/sdk/sqlite/inspector.png new file mode 100644 index 00000000000000..8ebdb5f8cdb8ee Binary files /dev/null and b/docs/public/static/images/sdk/sqlite/inspector.png differ diff --git a/packages/expo-brownfield/CHANGELOG.md b/packages/expo-brownfield/CHANGELOG.md index 72a8d733b509b1..52081bcc1e85ab 100644 --- a/packages/expo-brownfield/CHANGELOG.md +++ b/packages/expo-brownfield/CHANGELOG.md @@ -10,6 +10,8 @@ ### ๐Ÿ’ก Others +- [test] run brownfield e2e tests (cli + plugin) in sdk/check-packages workflow ([#43391](https://github.com/expo/expo/pull/43391) by [@pmleczek](https://github.com/pmleczek)) + ## 55.0.10 โ€” 2026-02-25 ### ๐ŸŽ‰ New features @@ -19,6 +21,7 @@ ### ๐Ÿ’ก Others - [test] setup maestro e2e tests for expo-brownfield on ios ([#43028](https://github.com/expo/expo/pull/43028) by [@pmleczek](https://github.com/pmleczek)) +- [state] add ios implementation & improvements ([#43236](https://github.com/expo/expo/pull/43236) by [@pmleczek](https://github.com/pmleczek)) ## 55.0.9 โ€” 2026-02-20 diff --git a/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/ExpoBrownfieldStateModule.kt b/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/ExpoBrownfieldStateModule.kt index 1106918e6b2b65..b1f08f7e603ca3 100644 --- a/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/ExpoBrownfieldStateModule.kt +++ b/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/ExpoBrownfieldStateModule.kt @@ -3,12 +3,16 @@ package expo.modules.brownfield import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition +const val KEY_RECREATED_EVENT_NAME = "onKeyRecreated" + class ExpoBrownfieldStateModule : Module() { override fun definition() = ModuleDefinition { Name("ExpoBrownfieldStateModule") + Events(KEY_RECREATED_EVENT_NAME) + Class(SharedState::class) { - Constructor { SharedState() } + Constructor { key: String -> SharedState(key) } Function("get") { state: SharedState -> return@Function state.get() @@ -17,10 +21,18 @@ class ExpoBrownfieldStateModule : Module() { Function("set") { state: SharedState, value: Any? -> state.set(value) } } + OnCreate { BrownfieldState.setExpoModule(this@ExpoBrownfieldStateModule) } + + OnDestroy { BrownfieldState.setExpoModule(null) } + Function("getSharedState") { key: String -> return@Function BrownfieldState.getOrCreate(key) } Function("deleteSharedState") { key: String -> BrownfieldState.delete(key) } } + + fun notifyKeyRecreated(key: String) { + sendEvent(KEY_RECREATED_EVENT_NAME, mapOf("key" to key)) + } } diff --git a/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/Removable.kt b/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/Removable.kt new file mode 100644 index 00000000000000..a501e84ed04b8c --- /dev/null +++ b/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/Removable.kt @@ -0,0 +1,5 @@ +package expo.modules.brownfield + +fun interface Removable { + fun remove() +} diff --git a/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/SharedState.kt b/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/SharedState.kt index aecb59c27c3840..4e55701e5f6b10 100644 --- a/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/SharedState.kt +++ b/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/SharedState.kt @@ -2,13 +2,8 @@ package expo.modules.brownfield import expo.modules.kotlin.sharedobjects.SharedObject -fun interface Removable { - fun remove() -} - -class SharedState : SharedObject() { +class SharedState(val key: String) : SharedObject() { private var value: Any? = null - private val listeners = mutableListOf<(Any?) -> Unit>() fun get(): Any? { synchronized(this) { @@ -17,23 +12,11 @@ class SharedState : SharedObject() { } fun set(newValue: Any?) { - val listenersSnapshot: List<(Any?) -> Unit> synchronized(this) { value = newValue - listenersSnapshot = listeners.toList() } emit("change", mapOf("value" to newValue)) - listenersSnapshot.forEach { it(newValue) } - } - - fun addListener(listener: ((Any?) -> Unit)): Removable { - synchronized(this) { - listeners.add(listener) - } - return Removable { - synchronized(this) { - listeners.remove(listener) - } - } + BrownfieldState.notifySubscribers(key, newValue) + BrownfieldState.maybeNotifyKeyRecreated(key) } } diff --git a/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/State.kt b/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/State.kt index 70af02067fe108..b96b1de1556108 100644 --- a/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/State.kt +++ b/packages/expo-brownfield/android/src/main/java/expo/modules/brownfield/State.kt @@ -1,11 +1,15 @@ package expo.modules.brownfield object BrownfieldState { + private var expoModule: ExpoBrownfieldStateModule? = null + private val registry = mutableMapOf() + private val subscriptions = mutableMapOf Unit>>() + private val deletedKeys = mutableSetOf() fun getOrCreate(key: String): SharedState { synchronized(this) { - return registry.getOrPut(key) { SharedState() } + return registry.getOrPut(key) { SharedState(key) } } } @@ -18,22 +22,49 @@ object BrownfieldState { fun set(key: String, value: Any?) { val state: SharedState synchronized(this) { - state = registry.getOrPut(key) { SharedState() } + state = registry.getOrPut(key) { SharedState(key) } } state.set(value) } fun subscribe(key: String, callback: (Any?) -> Unit): Removable { - val state: SharedState synchronized(this) { - state = registry.getOrPut(key) { SharedState() } + subscriptions.getOrPut(key) { mutableListOf() }.add(callback) + } + return Removable { + synchronized(this@BrownfieldState) { + subscriptions[key]?.remove(callback) + } } - return state.addListener(callback) } fun delete(key: String): Any? { synchronized(this) { + deletedKeys.add(key) return registry.remove(key)?.get() } } + + fun maybeNotifyKeyRecreated(key: String) { + synchronized(this) { + if (!deletedKeys.contains(key)) { + return + } + + deletedKeys.remove(key) + } + expoModule?.notifyKeyRecreated(key) + } + + internal fun setExpoModule(expoModule: ExpoBrownfieldStateModule?) { + this.expoModule = expoModule + } + + fun notifySubscribers(key: String, value: Any?) { + val snapshot: List<(Any?) -> Unit> + synchronized(this) { + snapshot = subscriptions[key]?.toList() ?: emptyList() + } + snapshot.forEach { it(value) } + } } diff --git a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.d.ts.map b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.d.ts.map index 32f2bf99cd3409..ee756b4a011c8c 100644 --- a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.d.ts.map +++ b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"ExpoBrownfieldStateModule.d.ts","sourceRoot":"","sources":["../src/ExpoBrownfieldStateModule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAoB3D;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAIvE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAGxE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGnD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,GAAG,GAAG,EAC5C,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,GACvC,iBAAiB,CAUnB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,GAAG,GAAG,EACpC,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,CAAC,GACf,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAmCpE"} \ No newline at end of file +{"version":3,"file":"ExpoBrownfieldStateModule.d.ts","sourceRoot":"","sources":["../src/ExpoBrownfieldStateModule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAuB3D;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAIvE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAGxE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGnD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,GAAG,GAAG,EAC5C,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,GACvC,iBAAiB,CASnB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,GAAG,GAAG,EACpC,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,CAAC,GACf,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CA6DpE"} \ No newline at end of file diff --git a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.js b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.js index 51748b596e060f..402ff476584912 100644 --- a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.js +++ b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.js @@ -1,5 +1,5 @@ import { requireNativeModule } from 'expo'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; const ExpoBrownfieldStateModule = requireNativeModule('ExpoBrownfieldStateModule'); const sharedObjectCache = new Map(); // SECTION: Shared State API @@ -76,15 +76,29 @@ export function useSharedState(key, initialValue) { return currentValue; }); useEffect(() => { - const subscription = state.addListener('change', (event) => { + let subscription = state.addListener('change', (event) => { setValue(event?.['value']); }); - return () => subscription.remove(); + const keyRecreatedSubscription = ExpoBrownfieldStateModule.addListener('onKeyRecreated', (event) => { + if (event.key === key) { + const newState = ExpoBrownfieldStateModule.getSharedState(key); + sharedObjectCache.set(key, newState); + subscription.remove(); + subscription = newState.addListener('change', (event) => { + setValue(event?.['value']); + }); + setValue(getSharedStateValue(key)); + } + }); + return () => { + subscription.remove(); + keyRecreatedSubscription.remove(); + }; }, [state]); - const setSharedValue = (newValue) => { + const setSharedValue = useCallback((newValue) => { const valueToSet = typeof newValue === 'function' ? newValue(value) : newValue; - state.set(valueToSet); - }; + getSharedObject(key).set(valueToSet); + }, [key, value]); return [value, setSharedValue]; } // END SECTION: Shared State API diff --git a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.js.map b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.js.map index b60d005206352d..94b11ab5c745ad 100644 --- a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.js.map +++ b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.js.map @@ -1 +1 @@ -{"version":3,"file":"ExpoBrownfieldStateModule.js","sourceRoot":"","sources":["../src/ExpoBrownfieldStateModule.ts"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeModule } from 'expo';\nimport type { EventSubscription } from 'expo-modules-core';\nimport { useEffect, useState } from 'react';\n\nimport type { ExpoBrownfieldStateModuleSpec } from './ExpoBrownfieldStateModule.types';\n\nconst ExpoBrownfieldStateModule = requireNativeModule(\n 'ExpoBrownfieldStateModule'\n);\n\nconst sharedObjectCache = new Map();\n\n// SECTION: Shared State API\n\nfunction getSharedObject(key: string): any {\n if (!sharedObjectCache.has(key)) {\n sharedObjectCache.set(key, ExpoBrownfieldStateModule.getSharedState(key));\n }\n return sharedObjectCache.get(key);\n}\n\n/**\n * Gets the value of shared state for a given key.\n *\n * @param key The key to get the value for.\n */\nexport function getSharedStateValue(key: string): T | undefined {\n const state = getSharedObject(key);\n const value = state?.get();\n return value === null ? undefined : (value as T);\n}\n\n/**\n * Sets the value of shared state for a given key.\n *\n * @param key The key to set the value for.\n * @param value The value to be set.\n */\nexport function setSharedStateValue(key: string, value: T): void {\n const state = getSharedObject(key);\n state.set(value);\n}\n\n/**\n * Deletes the shared state for a given key.\n *\n * @param key The key to delete the shared state for.\n */\nexport function deleteSharedState(key: string): void {\n ExpoBrownfieldStateModule.deleteSharedState(key);\n sharedObjectCache.delete(key);\n}\n\n/**\n * Adds a listener for changes to the shared state for a given key.\n *\n * @param key The key to add the listener for.\n * @param callback The callback to be called when the shared state changes.\n * @returns A subscription object that can be used to remove the listener.\n */\nexport function addSharedStateListener(\n key: string,\n callback: (value: T | undefined) => void\n): EventSubscription {\n const state = getSharedObject(key);\n\n const subscription = state.addListener('change', (event: T | undefined) => {\n callback(event);\n });\n\n return {\n remove: () => subscription.remove(),\n };\n}\n\n/**\n * Hook to observe and set the value of shared state for a given key.\n * Provides a synchronous API similar to `useState`.\n *\n * @param key The key to get the value for.\n * @param initialValue The initial value to be used if the shared state is not set.\n * @returns A tuple containing the value and a function to set the value.\n */\nexport function useSharedState(\n key: string,\n initialValue?: T\n): [T | undefined, (value: T | ((prev: T | undefined) => T)) => void] {\n const state = getSharedObject(key);\n\n const [value, setValue] = useState(() => {\n const currentValue = state.get();\n if (currentValue === null || currentValue === undefined) {\n if (initialValue !== undefined) {\n state.set(initialValue);\n return initialValue;\n }\n\n return undefined;\n }\n\n return currentValue as T;\n });\n\n useEffect(() => {\n const subscription = state.addListener(\n 'change',\n (event: Record | undefined) => {\n setValue(event?.['value']);\n }\n );\n\n return () => subscription.remove();\n }, [state]);\n\n const setSharedValue = (newValue: T | ((prev: T | undefined) => T)) => {\n const valueToSet =\n typeof newValue === 'function' ? (newValue as (prev: T | undefined) => T)(value) : newValue;\n state.set(valueToSet);\n };\n\n return [value, setSharedValue];\n}\n\n// END SECTION: Shared State API\n"]} \ No newline at end of file +{"version":3,"file":"ExpoBrownfieldStateModule.js","sourceRoot":"","sources":["../src/ExpoBrownfieldStateModule.ts"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeModule } from 'expo';\nimport type { EventSubscription } from 'expo-modules-core';\nimport { useCallback, useEffect, useState } from 'react';\n\nimport type {\n ExpoBrownfieldStateModuleSpec,\n KeyRecreatedEvent,\n} from './ExpoBrownfieldStateModule.types';\n\nconst ExpoBrownfieldStateModule = requireNativeModule(\n 'ExpoBrownfieldStateModule'\n);\n\nconst sharedObjectCache = new Map();\n\n// SECTION: Shared State API\n\nfunction getSharedObject(key: string): any {\n if (!sharedObjectCache.has(key)) {\n sharedObjectCache.set(key, ExpoBrownfieldStateModule.getSharedState(key));\n }\n return sharedObjectCache.get(key);\n}\n\n/**\n * Gets the value of shared state for a given key.\n *\n * @param key The key to get the value for.\n */\nexport function getSharedStateValue(key: string): T | undefined {\n const state = getSharedObject(key);\n const value = state?.get();\n return value === null ? undefined : (value as T);\n}\n\n/**\n * Sets the value of shared state for a given key.\n *\n * @param key The key to set the value for.\n * @param value The value to be set.\n */\nexport function setSharedStateValue(key: string, value: T): void {\n const state = getSharedObject(key);\n state.set(value);\n}\n\n/**\n * Deletes the shared state for a given key.\n *\n * @param key The key to delete the shared state for.\n */\nexport function deleteSharedState(key: string): void {\n ExpoBrownfieldStateModule.deleteSharedState(key);\n sharedObjectCache.delete(key);\n}\n\n/**\n * Adds a listener for changes to the shared state for a given key.\n *\n * @param key The key to add the listener for.\n * @param callback The callback to be called when the shared state changes.\n * @returns A subscription object that can be used to remove the listener.\n */\nexport function addSharedStateListener(\n key: string,\n callback: (value: T | undefined) => void\n): EventSubscription {\n const state = getSharedObject(key);\n const subscription = state.addListener('change', (event: T | undefined) => {\n callback(event);\n });\n\n return {\n remove: () => subscription.remove(),\n };\n}\n\n/**\n * Hook to observe and set the value of shared state for a given key.\n * Provides a synchronous API similar to `useState`.\n *\n * @param key The key to get the value for.\n * @param initialValue The initial value to be used if the shared state is not set.\n * @returns A tuple containing the value and a function to set the value.\n */\nexport function useSharedState(\n key: string,\n initialValue?: T\n): [T | undefined, (value: T | ((prev: T | undefined) => T)) => void] {\n const state = getSharedObject(key);\n\n const [value, setValue] = useState(() => {\n const currentValue = state.get();\n if (currentValue === null || currentValue === undefined) {\n if (initialValue !== undefined) {\n state.set(initialValue);\n return initialValue;\n }\n\n return undefined;\n }\n\n return currentValue as T;\n });\n\n useEffect(() => {\n let subscription = state.addListener(\n 'change',\n (event: Record | undefined) => {\n setValue(event?.['value']);\n }\n );\n\n const keyRecreatedSubscription = ExpoBrownfieldStateModule.addListener(\n 'onKeyRecreated',\n (event: KeyRecreatedEvent) => {\n if (event.key === key) {\n const newState = ExpoBrownfieldStateModule.getSharedState(key);\n sharedObjectCache.set(key, newState);\n\n subscription.remove();\n subscription = newState.addListener(\n 'change',\n (event: Record | undefined) => {\n setValue(event?.['value']);\n }\n );\n\n setValue(getSharedStateValue(key));\n }\n }\n );\n\n return () => {\n subscription.remove();\n keyRecreatedSubscription.remove();\n };\n }, [state]);\n\n const setSharedValue = useCallback(\n (newValue: T | ((prev: T | undefined) => T)) => {\n const valueToSet =\n typeof newValue === 'function' ? (newValue as (prev: T | undefined) => T)(value) : newValue;\n getSharedObject(key).set(valueToSet);\n },\n [key, value]\n );\n\n return [value, setSharedValue];\n}\n\n// END SECTION: Shared State API\n"]} \ No newline at end of file diff --git a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.d.ts b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.d.ts index 555dda53038102..256c772879ac89 100644 --- a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.d.ts +++ b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.d.ts @@ -1,5 +1,11 @@ import type { NativeModule } from 'expo'; -export declare class ExpoBrownfieldStateModuleSpec extends NativeModule { +export type KeyRecreatedEvent = { + key: string; +}; +export type Events = { + onKeyRecreated: (event: KeyRecreatedEvent) => void; +}; +export declare class ExpoBrownfieldStateModuleSpec extends NativeModule { getSharedState(key: string): any; deleteSharedState(key: string): void; } diff --git a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.d.ts.map b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.d.ts.map index 4c9e71c50eb548..cc8d0c07bea424 100644 --- a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.d.ts.map +++ b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"ExpoBrownfieldStateModule.types.d.ts","sourceRoot":"","sources":["../src/ExpoBrownfieldStateModule.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEzC,MAAM,CAAC,OAAO,OAAO,6BAA8B,SAAQ,YAAY;IACrE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;IAChC,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CACrC"} \ No newline at end of file +{"version":3,"file":"ExpoBrownfieldStateModule.types.d.ts","sourceRoot":"","sources":["../src/ExpoBrownfieldStateModule.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEzC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,cAAc,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACpD,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,6BAA8B,SAAQ,YAAY,CAAC,MAAM,CAAC;IAC7E,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;IAChC,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CACrC"} \ No newline at end of file diff --git a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.js.map b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.js.map index 283c5e67b4f065..57d01e6ac80c24 100644 --- a/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.js.map +++ b/packages/expo-brownfield/build/ExpoBrownfieldStateModule.types.js.map @@ -1 +1 @@ -{"version":3,"file":"ExpoBrownfieldStateModule.types.js","sourceRoot":"","sources":["../src/ExpoBrownfieldStateModule.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { NativeModule } from 'expo';\n\nexport declare class ExpoBrownfieldStateModuleSpec extends NativeModule {\n getSharedState(key: string): any;\n deleteSharedState(key: string): void;\n}\n"]} \ No newline at end of file +{"version":3,"file":"ExpoBrownfieldStateModule.types.js","sourceRoot":"","sources":["../src/ExpoBrownfieldStateModule.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { NativeModule } from 'expo';\n\nexport type KeyRecreatedEvent = {\n key: string;\n};\n\nexport type Events = {\n onKeyRecreated: (event: KeyRecreatedEvent) => void;\n};\n\nexport declare class ExpoBrownfieldStateModuleSpec extends NativeModule {\n getSharedState(key: string): any;\n deleteSharedState(key: string): void;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-brownfield/cli/build/utils/config.js b/packages/expo-brownfield/cli/build/utils/config.js index f71b0f16fb8b41..c7e0bfd89cae3f 100644 --- a/packages/expo-brownfield/cli/build/utils/config.js +++ b/packages/expo-brownfield/cli/build/utils/config.js @@ -86,6 +86,6 @@ const resolveScheme = (options) => { return options.scheme || (0, ios_1.findScheme)(); }; const resolveWorkspace = (options) => { - return options.xcworkspace || (0, ios_1.findWorkspace)(); + return options.xcworkspace || (0, ios_1.findWorkspace)(options.dryRun); }; // END SECTION: iOS Helpers diff --git a/packages/expo-brownfield/cli/build/utils/ios.d.ts b/packages/expo-brownfield/cli/build/utils/ios.d.ts index cd0680538c0e16..9e36e1dfc3c68c 100644 --- a/packages/expo-brownfield/cli/build/utils/ios.d.ts +++ b/packages/expo-brownfield/cli/build/utils/ios.d.ts @@ -4,6 +4,6 @@ export declare const buildFramework: (config: IosConfig) => Promise Promise; export declare const createXcframework: (config: IosConfig) => Promise; export declare const findScheme: () => string | undefined; -export declare const findWorkspace: () => string | undefined; +export declare const findWorkspace: (dryRun: boolean) => string | undefined; export declare const makeArtifactsDirectory: (config: IosConfig) => void; export declare const printIosConfig: (config: IosConfig) => void; diff --git a/packages/expo-brownfield/cli/build/utils/ios.js b/packages/expo-brownfield/cli/build/utils/ios.js index 0d91ba448b6c26..382a51387d1c0a 100644 --- a/packages/expo-brownfield/cli/build/utils/ios.js +++ b/packages/expo-brownfield/cli/build/utils/ios.js @@ -131,7 +131,12 @@ const findScheme = () => { } }; exports.findScheme = findScheme; -const findWorkspace = () => { +const findWorkspace = (dryRun) => { + // XCWorkspace cannot be inferred on Ubuntu runners + // as pods cannot be installed + if (dryRun) { + return node_path_1.default.join(process.cwd(), 'ios/testappbuildiospb.xcworkspace'); + } try { const iosPath = node_path_1.default.join(process.cwd(), 'ios'); if (!node_fs_1.default.existsSync(iosPath)) { diff --git a/packages/expo-brownfield/cli/jest.config.js b/packages/expo-brownfield/cli/jest.config.js new file mode 100644 index 00000000000000..e09c386c719214 --- /dev/null +++ b/packages/expo-brownfield/cli/jest.config.js @@ -0,0 +1,7 @@ +/** @type {import('jest').Config} */ +module.exports = { + ...require('../e2e/cli/jest.config.js'), + // When expo-module-test runs "yarn test cli" it passes --rootDir cli, so Jest's + // rootDir is cli/. Point roots at e2e/cli so the same cli tests run. + roots: ['../e2e/cli'], +}; diff --git a/packages/expo-brownfield/cli/src/utils/config.ts b/packages/expo-brownfield/cli/src/utils/config.ts index 4602725b68b184..e7268aca242b61 100644 --- a/packages/expo-brownfield/cli/src/utils/config.ts +++ b/packages/expo-brownfield/cli/src/utils/config.ts @@ -113,7 +113,7 @@ const resolveScheme = (options: OptionValues): string => { }; const resolveWorkspace = (options: OptionValues): string => { - return options.xcworkspace || findWorkspace(); + return options.xcworkspace || findWorkspace(options.dryRun); }; // END SECTION: iOS Helpers diff --git a/packages/expo-brownfield/cli/src/utils/ios.ts b/packages/expo-brownfield/cli/src/utils/ios.ts index 9d22f44e87ad91..87b8799ec9f105 100644 --- a/packages/expo-brownfield/cli/src/utils/ios.ts +++ b/packages/expo-brownfield/cli/src/utils/ios.ts @@ -143,7 +143,13 @@ export const findScheme = (): string | undefined => { } }; -export const findWorkspace = (): string | undefined => { +export const findWorkspace = (dryRun: boolean): string | undefined => { + // XCWorkspace cannot be inferred on Ubuntu runners + // as pods cannot be installed + if (dryRun) { + return path.join(process.cwd(), 'ios/testappbuildiospb.xcworkspace'); + } + try { const iosPath = path.join(process.cwd(), 'ios'); if (!fs.existsSync(iosPath)) { diff --git a/packages/expo-brownfield/e2e/cli/jest.config.js b/packages/expo-brownfield/e2e/cli/jest.config.js index c6545a835ef3d6..eee8eaca23751d 100644 --- a/packages/expo-brownfield/e2e/cli/jest.config.js +++ b/packages/expo-brownfield/e2e/cli/jest.config.js @@ -1,3 +1,5 @@ +const path = require('node:path'); + /** @type {import('jest').Config} */ module.exports = { ...require('expo-module-scripts/jest-preset-cli'), @@ -6,4 +8,5 @@ module.exports = { roots: ['.'], // E2E tests can take some time to run testTimeout: 600000, + globalSetup: path.resolve(__dirname, '../scripts/global-setup.js'), }; diff --git a/packages/expo-brownfield/e2e/plugin/jest.config.js b/packages/expo-brownfield/e2e/plugin/jest.config.js index c6545a835ef3d6..eee8eaca23751d 100644 --- a/packages/expo-brownfield/e2e/plugin/jest.config.js +++ b/packages/expo-brownfield/e2e/plugin/jest.config.js @@ -1,3 +1,5 @@ +const path = require('node:path'); + /** @type {import('jest').Config} */ module.exports = { ...require('expo-module-scripts/jest-preset-cli'), @@ -6,4 +8,5 @@ module.exports = { roots: ['.'], // E2E tests can take some time to run testTimeout: 600000, + globalSetup: path.resolve(__dirname, '../scripts/global-setup.js'), }; diff --git a/packages/expo-brownfield/e2e/scripts/global-setup.js b/packages/expo-brownfield/e2e/scripts/global-setup.js new file mode 100644 index 00000000000000..cf9abd62464366 --- /dev/null +++ b/packages/expo-brownfield/e2e/scripts/global-setup.js @@ -0,0 +1,8 @@ +const { execSync } = require('child_process'); + +module.exports = async () => { + console.log('\nRunning pre-test Yarn commands...\n'); + execSync('yarn workspace expo-brownfield prepare', { stdio: 'inherit' }); + execSync('yarn workspace @expo/cli prepare', { stdio: 'inherit' }); + execSync('yarn workspace create-expo build:prod', { stdio: 'inherit' }); +}; diff --git a/packages/expo-brownfield/e2e/utils/project.ts b/packages/expo-brownfield/e2e/utils/project.ts index e1ab0d42df560b..de50d7d21f9b7f 100644 --- a/packages/expo-brownfield/e2e/utils/project.ts +++ b/packages/expo-brownfield/e2e/utils/project.ts @@ -4,7 +4,12 @@ import fs from 'node:fs'; import path from 'node:path'; import tempDir from 'temp-dir'; -import { executeCreateExpoCLIAsync, executeExpoCLIAsync, sleep } from './process'; +import { + executeCommandAsync, + executeCreateExpoCLIAsync, + executeExpoCLIAsync, + sleep, +} from './process'; import type { PluginProps, TemplateEntry } from './types'; const PROJECT_NAME = 'testapp'; @@ -110,9 +115,13 @@ const createProjectWithTemplate = async (at: string, projectName: string) => { throw new Error(`Template directory not found at: ${templatePath}`); } - const tarballs = await glob('*.tgz', { cwd: templatePath }); + let tarballs = await glob('*.tgz', { cwd: templatePath }); if (tarballs.length === 0) { - throw new Error(`No tarballs found in template directory: ${templatePath}`); + await executeCommandAsync(templatePath, 'npm', ['pack', '--json']); + tarballs = await glob('*.tgz', { cwd: templatePath }); + if (tarballs.length === 0) { + throw new Error(`No tarballs found in template directory: ${templatePath}`); + } } await executeCreateExpoCLIAsync(at, [ @@ -127,11 +136,13 @@ const createProjectWithTemplate = async (at: string, projectName: string) => { */ const installPackage = async (projectRoot: string) => { const packageRoot = path.join(__dirname, '../../'); - const tarballs = await glob('*.tgz', { cwd: packageRoot }); - if (tarballs.length !== 1) { - throw new Error( - `Expected a single tarball to be created for 'expo-brownfield', received: ${tarballs.length}` - ); + let tarballs = await glob('*.tgz', { cwd: packageRoot }); + if (tarballs.length === 0) { + await executeCommandAsync(packageRoot, 'npm', ['pack', '--json']); + tarballs = await glob('*.tgz', { cwd: packageRoot }); + if (tarballs.length === 0) { + throw new Error(`No tarballs found in package directory: ${packageRoot}`); + } } const packageTarball = tarballs[0]; diff --git a/packages/expo-brownfield/ios/ExpoBrownfieldStateModule.swift b/packages/expo-brownfield/ios/ExpoBrownfieldStateModule.swift index b62bb3f458c7bb..fbfb29a751fa86 100644 --- a/packages/expo-brownfield/ios/ExpoBrownfieldStateModule.swift +++ b/packages/expo-brownfield/ios/ExpoBrownfieldStateModule.swift @@ -1,19 +1,47 @@ import ExpoModulesCore +let KEY_RECREATED_EVENT_NAME = "onKeyRecreated" + // MARK: - ExpoBrownfieldStateModule public class ExpoBrownfieldStateModule: Module { - private var stores: [String: Any] = [:] - public func definition() -> ModuleDefinition { Name("ExpoBrownfieldStateModule") - Function("getSharedState") { (key: String) -> Any? in - return nil + Events(KEY_RECREATED_EVENT_NAME) + + Class(SharedState.self) { + Constructor { (key: String) in + return SharedState(key) + } + + Function("get") { (state: SharedState) -> Any? in + return state.get() + } + + Function("set") { (state: SharedState, value: JavaScriptValue?) in + state.set(value?.getRaw()) + } + } + + OnCreate { + BrownfieldStateInternal.shared.setExpoModule(self) } - Function("deleteSharedState") { (key: String) -> Void in - self.stores.removeValue(forKey: key) + OnDestroy { + BrownfieldStateInternal.shared.setExpoModule(nil) } + + Function("getSharedState") { (key: String) -> SharedState in + return BrownfieldStateInternal.shared.getOrCreate(key) + } + + Function("deleteSharedState") { (key: String) in + BrownfieldStateInternal.shared.delete(key) + } + } + + public func notifyKeyRecreated(_ key: String) { + sendEvent(KEY_RECREATED_EVENT_NAME, ["key": key]) } } diff --git a/packages/expo-brownfield/ios/SharedState.swift b/packages/expo-brownfield/ios/SharedState.swift new file mode 100644 index 00000000000000..02317c163d1c09 --- /dev/null +++ b/packages/expo-brownfield/ios/SharedState.swift @@ -0,0 +1,28 @@ +import ExpoModulesCore + +public final class SharedState: SharedObject { + private let lock = NSLock() + private let key: String + private var value: Any? + + public init(_ key: String) { + self.key = key + super.init() + } + + public func get() -> Any? { + lock.lock() + defer { lock.unlock() } + return value + } + + public func set(_ newValue: Any?) { + lock.lock() + value = newValue + lock.unlock() + + emit(event: "change", arguments: ["value": newValue]) + BrownfieldStateInternal.shared.notifySubscribers(key, newValue) + BrownfieldStateInternal.shared.maybeNotifyKeyRecreated(key) + } +} diff --git a/packages/expo-brownfield/ios/State.swift b/packages/expo-brownfield/ios/State.swift new file mode 100644 index 00000000000000..7a055384831332 --- /dev/null +++ b/packages/expo-brownfield/ios/State.swift @@ -0,0 +1,104 @@ +import Combine +import Foundation + +public class ListenerRef { + let callback: (Any?) -> Void + init(_ callback: @escaping (Any?) -> Void) { + self.callback = callback + } +} + +public final class BrownfieldStateInternal { + public static let shared = BrownfieldStateInternal() + + private let lock = NSLock() + private var expoModule: ExpoBrownfieldStateModule? + + private var registry: [String: SharedState] = [:] + private var subscriptions: [String: [ListenerRef]] = [:] + private var deletedKeys: Set = [] + + public func getOrCreate(_ key: String) -> SharedState { + lock.lock() + defer { lock.unlock() } + + if let existing = registry[key] { + return existing + } + + let state = SharedState(key) + registry[key] = state + + return state + } + + public func get(_ key: String) -> Any? { + lock.lock() + defer { lock.unlock() } + return registry[key]?.get() + } + + public func set(_ key: String, _ value: Any?) { + let state: SharedState + lock.lock() + + if let existing = registry[key] { + state = existing + } else { + state = SharedState(key) + registry[key] = state + } + lock.unlock() + + state.set(value) + } + + public func subscribe( + _ key: String, + _ callback: @escaping (Any?) -> Void + ) -> AnyCancellable { + let listenerRef = ListenerRef(callback) + + lock.lock() + subscriptions[key, default: []].append(listenerRef) + lock.unlock() + + return AnyCancellable { [weak self] in + self?.lock.lock() + self?.subscriptions[key]?.removeAll { $0 === listenerRef } + self?.lock.unlock() + } + } + + public func delete(_ key: String) -> Any? { + lock.lock() + defer { lock.unlock() } + deletedKeys.insert(key) + return registry.removeValue(forKey: key)?.get() + } + + public func maybeNotifyKeyRecreated(_ key: String) { + lock.lock() + if !deletedKeys.contains(key) { + lock.unlock() + return + } + deletedKeys.remove(key) + lock.unlock() + + expoModule?.notifyKeyRecreated(key) + } + + public func setExpoModule(_ expoModule: ExpoBrownfieldStateModule?) { + self.expoModule = expoModule + } + + public func notifySubscribers(_ key: String, _ value: Any?) { + var snapshot: [ListenerRef] + lock.lock() + snapshot = Array(subscriptions[key, default: []]) + lock.unlock() + + snapshot.forEach { $0.callback(value) } + } +} diff --git a/packages/expo-brownfield/plugin/build/ios/plugins/withXcodeProjectPlugin.js b/packages/expo-brownfield/plugin/build/ios/plugins/withXcodeProjectPlugin.js index 25c9b2d8fc2c5d..ea190229f05812 100644 --- a/packages/expo-brownfield/plugin/build/ios/plugins/withXcodeProjectPlugin.js +++ b/packages/expo-brownfield/plugin/build/ios/plugins/withXcodeProjectPlugin.js @@ -21,6 +21,8 @@ const withXcodeProjectPlugin = (config, pluginConfig) => { 'ReactNativeHostManager.swift', // Messaging proxy 'Messaging.swift', + // State proxy + 'State.swift', //SwiftUI brownfield entrypoint 'ReactNativeView.swift', // UIKit brownfield view controller diff --git a/packages/expo-brownfield/plugin/jest.config.js b/packages/expo-brownfield/plugin/jest.config.js new file mode 100644 index 00000000000000..1cfce7b33a1347 --- /dev/null +++ b/packages/expo-brownfield/plugin/jest.config.js @@ -0,0 +1,7 @@ +/** @type {import('jest').Config} */ +module.exports = { + ...require('../e2e/plugin/jest.config.js'), + // When expo-module-test runs "yarn test plugin" it passes --rootDir plugin, so Jest's + // rootDir is plugin/. Point roots at e2e/plugin so the same plugin tests run. + roots: ['../e2e/plugin'], +}; diff --git a/packages/expo-brownfield/plugin/src/ios/plugins/withXcodeProjectPlugin.ts b/packages/expo-brownfield/plugin/src/ios/plugins/withXcodeProjectPlugin.ts index 192646ca270194..8939897abb164d 100644 --- a/packages/expo-brownfield/plugin/src/ios/plugins/withXcodeProjectPlugin.ts +++ b/packages/expo-brownfield/plugin/src/ios/plugins/withXcodeProjectPlugin.ts @@ -37,6 +37,8 @@ const withXcodeProjectPlugin: ConfigPlugin = (config, pluginConfig 'ReactNativeHostManager.swift', // Messaging proxy 'Messaging.swift', + // State proxy + 'State.swift', //SwiftUI brownfield entrypoint 'ReactNativeView.swift', // UIKit brownfield view controller diff --git a/packages/expo-brownfield/plugin/templates/ios/State.swift b/packages/expo-brownfield/plugin/templates/ios/State.swift new file mode 100644 index 00000000000000..91a3dd79f9e225 --- /dev/null +++ b/packages/expo-brownfield/plugin/templates/ios/State.swift @@ -0,0 +1,24 @@ +import Combine +internal import ExpoBrownfield + +public struct BrownfieldState { + public static func get(_ key: String) -> Any? { + return BrownfieldStateInternal.shared.get(key) + } + + public static func set(_ key: String, _ value: Any?) { + BrownfieldStateInternal.shared.set(key, value) + } + + @discardableResult + public static func subscribe( + _ key: String, + _ callback: @escaping (Any?) -> Void + ) -> AnyCancellable { + return BrownfieldStateInternal.shared.subscribe(key, callback) + } + + public static func delete(_ key: String) -> Any? { + return BrownfieldStateInternal.shared.delete(key) + } +} diff --git a/packages/expo-brownfield/src/ExpoBrownfieldStateModule.ts b/packages/expo-brownfield/src/ExpoBrownfieldStateModule.ts index 8f1f4e4849fcf2..267b63897dd87c 100644 --- a/packages/expo-brownfield/src/ExpoBrownfieldStateModule.ts +++ b/packages/expo-brownfield/src/ExpoBrownfieldStateModule.ts @@ -1,8 +1,11 @@ import { requireNativeModule } from 'expo'; import type { EventSubscription } from 'expo-modules-core'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; -import type { ExpoBrownfieldStateModuleSpec } from './ExpoBrownfieldStateModule.types'; +import type { + ExpoBrownfieldStateModuleSpec, + KeyRecreatedEvent, +} from './ExpoBrownfieldStateModule.types'; const ExpoBrownfieldStateModule = requireNativeModule( 'ExpoBrownfieldStateModule' @@ -63,7 +66,6 @@ export function addSharedStateListener( callback: (value: T | undefined) => void ): EventSubscription { const state = getSharedObject(key); - const subscription = state.addListener('change', (event: T | undefined) => { callback(event); }); @@ -102,21 +104,47 @@ export function useSharedState( }); useEffect(() => { - const subscription = state.addListener( + let subscription = state.addListener( 'change', (event: Record | undefined) => { setValue(event?.['value']); } ); - return () => subscription.remove(); + const keyRecreatedSubscription = ExpoBrownfieldStateModule.addListener( + 'onKeyRecreated', + (event: KeyRecreatedEvent) => { + if (event.key === key) { + const newState = ExpoBrownfieldStateModule.getSharedState(key); + sharedObjectCache.set(key, newState); + + subscription.remove(); + subscription = newState.addListener( + 'change', + (event: Record | undefined) => { + setValue(event?.['value']); + } + ); + + setValue(getSharedStateValue(key)); + } + } + ); + + return () => { + subscription.remove(); + keyRecreatedSubscription.remove(); + }; }, [state]); - const setSharedValue = (newValue: T | ((prev: T | undefined) => T)) => { - const valueToSet = - typeof newValue === 'function' ? (newValue as (prev: T | undefined) => T)(value) : newValue; - state.set(valueToSet); - }; + const setSharedValue = useCallback( + (newValue: T | ((prev: T | undefined) => T)) => { + const valueToSet = + typeof newValue === 'function' ? (newValue as (prev: T | undefined) => T)(value) : newValue; + getSharedObject(key).set(valueToSet); + }, + [key, value] + ); return [value, setSharedValue]; } diff --git a/packages/expo-brownfield/src/ExpoBrownfieldStateModule.types.ts b/packages/expo-brownfield/src/ExpoBrownfieldStateModule.types.ts index 198009eccb8603..4a9f773dd9e912 100644 --- a/packages/expo-brownfield/src/ExpoBrownfieldStateModule.types.ts +++ b/packages/expo-brownfield/src/ExpoBrownfieldStateModule.types.ts @@ -1,6 +1,14 @@ import type { NativeModule } from 'expo'; -export declare class ExpoBrownfieldStateModuleSpec extends NativeModule { +export type KeyRecreatedEvent = { + key: string; +}; + +export type Events = { + onKeyRecreated: (event: KeyRecreatedEvent) => void; +}; + +export declare class ExpoBrownfieldStateModuleSpec extends NativeModule { getSharedState(key: string): any; deleteSharedState(key: string): void; } diff --git a/packages/expo-camera/CHANGELOG.md b/packages/expo-camera/CHANGELOG.md index 4ba1146c628ace..509ed9e0093f98 100644 --- a/packages/expo-camera/CHANGELOG.md +++ b/packages/expo-camera/CHANGELOG.md @@ -6,6 +6,8 @@ ### ๐ŸŽ‰ New features +- [Web] Expands support for barcode types that can be scanned. ([#43403](https://github.com/expo/expo/pull/43403) by [@alanjhughes](https://github.com/alanjhughes)) + ### ๐Ÿ› Bug fixes ### ๐Ÿ’ก Others diff --git a/packages/expo-camera/android/src/main/java/expo/modules/camera/CameraViewHelper.kt b/packages/expo-camera/android/src/main/java/expo/modules/camera/CameraViewHelper.kt index 48cf1b0c52bb4e..56e5eec4cd2db1 100644 --- a/packages/expo-camera/android/src/main/java/expo/modules/camera/CameraViewHelper.kt +++ b/packages/expo-camera/android/src/main/java/expo/modules/camera/CameraViewHelper.kt @@ -4,22 +4,12 @@ import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint -import expo.modules.camera.records.CameraType import java.io.ByteArrayOutputStream import java.text.SimpleDateFormat import java.util.Calendar import java.util.Locale object CameraViewHelper { - // Utilities - @JvmStatic - fun getCorrectCameraRotation(rotation: Int, facing: CameraType) = - if (facing == CameraType.FRONT) { - (rotation - 90 + 360) % 360 - } else { - (-rotation + 90 + 360) % 360 - } - fun generateSimulatorPhoto(width: Int, height: Int): ByteArray { val fakePhotoBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val canvas = Canvas(fakePhotoBitmap) diff --git a/packages/expo-camera/android/src/main/java/expo/modules/camera/ExpoCameraView.kt b/packages/expo-camera/android/src/main/java/expo/modules/camera/ExpoCameraView.kt index bb6cd813194742..1ff8116fb7c756 100644 --- a/packages/expo-camera/android/src/main/java/expo/modules/camera/ExpoCameraView.kt +++ b/packages/expo-camera/android/src/main/java/expo/modules/camera/ExpoCameraView.kt @@ -542,7 +542,7 @@ class ExpoCameraView( try { analyzer.setAnalyzer( ContextCompat.getMainExecutor(context), - BarcodeAnalyzer(lensFacing, barcodeFormats) { + BarcodeAnalyzer(barcodeFormats) { onBarcodeScanned(it) } ) @@ -696,6 +696,8 @@ class ExpoCameraView( val scaleX: Float val scaleY: Float + var offsetX = 0f + var offsetY = 0f when (previewView.scaleType) { PreviewView.ScaleType.FIT_CENTER -> { @@ -705,10 +707,11 @@ class ExpoCameraView( if (previewAspectRatio > imageAspectRatio) { scaleY = previewHeight / imageHeight scaleX = scaleY + offsetX = (previewWidth - imageWidth * scaleX) / 2f } else { - // Preview is taller - letterbox on top/bottom scaleX = previewWidth / imageWidth scaleY = scaleX + offsetY = (previewHeight - imageHeight * scaleY) / 2f } } PreviewView.ScaleType.FILL_CENTER -> { @@ -716,13 +719,13 @@ class ExpoCameraView( val imageAspectRatio = imageWidth / imageHeight if (previewAspectRatio > imageAspectRatio) { - // Preview is wider - scale to fill width, crop top/bottom scaleX = previewWidth / imageWidth scaleY = scaleX + offsetY = (previewHeight - imageHeight * scaleY) / 2f } else { - // Preview is taller - scale to fill height, crop left/right scaleY = previewHeight / imageHeight scaleX = scaleY + offsetX = (previewWidth - imageWidth * scaleX) / 2f } } else -> { @@ -733,12 +736,12 @@ class ExpoCameraView( cornerPoints.mapX { index -> val originalX = cornerPoints[index] - (originalX * scaleX).roundToInt() + (originalX * scaleX + offsetX).roundToInt() } cornerPoints.mapY { index -> val originalY = cornerPoints[index] - (originalY * scaleY).roundToInt() + (originalY * scaleY + offsetY).roundToInt() } barcode.cornerPoints = cornerPoints @@ -753,8 +756,8 @@ class ExpoCameraView( val density = previewView.resources.displayMetrics.density val convertedCornerPoints = ArrayList() for (i in cornerPoints.indices step 2) { - val y = cornerPoints[i].toFloat() / density - val x = cornerPoints[i + 1].toFloat() / density + val x = cornerPoints[i].toFloat() / density + val y = cornerPoints[i + 1].toFloat() / density convertedCornerPoints.add( Bundle().apply { putFloat("x", x) @@ -784,10 +787,12 @@ class ExpoCameraView( private fun onBarcodeScanned(barcode: BarCodeScannerResult) { if (shouldScanBarcodes) { transformBarcodeScannerResultToViewCoordinates(barcode) + val (cornerPoints, boundingBox) = getCornerPointsAndBoundingBox( barcode.cornerPoints, barcode.boundingBox ) + onBarcodeScanned( BarcodeScannedEvent( target = id, diff --git a/packages/expo-camera/android/src/main/java/expo/modules/camera/analyzers/BarcodeAnalyzer.kt b/packages/expo-camera/android/src/main/java/expo/modules/camera/analyzers/BarcodeAnalyzer.kt index 5167a59fc3985b..00a70f6558042f 100644 --- a/packages/expo-camera/android/src/main/java/expo/modules/camera/analyzers/BarcodeAnalyzer.kt +++ b/packages/expo-camera/android/src/main/java/expo/modules/camera/analyzers/BarcodeAnalyzer.kt @@ -8,13 +8,11 @@ import androidx.camera.core.ImageProxy import com.google.mlkit.vision.barcode.BarcodeScannerOptions import com.google.mlkit.vision.barcode.BarcodeScanning import com.google.mlkit.vision.common.InputImage -import expo.modules.camera.CameraViewHelper import expo.modules.camera.records.BarcodeType -import expo.modules.camera.records.CameraType import expo.modules.camera.utils.BarCodeScannerResult @OptIn(ExperimentalGetImage::class) -class BarcodeAnalyzer(private val lensFacing: CameraType, formats: List, val onComplete: (BarCodeScannerResult) -> Unit) : ImageAnalysis.Analyzer { +class BarcodeAnalyzer(formats: List, val onComplete: (BarCodeScannerResult) -> Unit) : ImageAnalysis.Analyzer { private val barcodeFormats = if (formats.isEmpty()) { 0 } else { @@ -32,8 +30,14 @@ class BarcodeAnalyzer(private val lensFacing: CameraType, formats: List @@ -61,8 +65,8 @@ class BarcodeAnalyzer(private val lensFacing: CameraType, formats: List | any;\n};\n\n// @needsAudit\nexport type CameraPictureOptions = {\n /**\n * Specify the compression quality from `0` to `1`. `0` means compress for small size, and `1` means compress for maximum quality.\n * @default 1\n */\n quality?: number;\n /**\n * Whether to also include the image data in Base64 format.\n */\n base64?: boolean;\n /**\n * Whether to also include the EXIF data for the image.\n */\n exif?: boolean;\n /**\n * Additional EXIF data to be included for the image. Only useful when `exif` option is set to `true`.\n * @platform android\n * @platform ios\n */\n additionalExif?: Record;\n /**\n * A callback invoked when picture is saved. If set, the promise of this method will resolve immediately with no data after picture is captured.\n * The data that it should contain will be passed to this callback. If displaying or processing a captured photo right after taking it\n * is not your case, this callback lets you skip waiting for it to be saved.\n * @param picture\n */\n onPictureSaved?: (picture: CameraCapturedPicture) => void;\n // TODO(Bacon): Is it possible to implement this in the browser?\n /**\n * If set to `true`, camera skips orientation adjustment and returns an image straight from the device's camera.\n * If enabled, `quality` option is discarded (processing pipeline is skipped as a whole).\n * Although enabling this option reduces image delivery time significantly, it may cause the image to appear in a wrong orientation\n * in the `Image` component (at the time of writing, it does not respect EXIF orientation of the images).\n * > **Note**: Enabling `skipProcessing` would cause orientation uncertainty. `Image` component does not respect EXIF\n * > stored orientation information, that means obtained image would be displayed wrongly (rotated by 90ยฐ, 180ยฐ or 270ยฐ).\n * > Different devices provide different orientations. For example some Sony Xperia or Samsung devices don't provide\n * > correctly oriented images by default. To always obtain correctly oriented image disable `skipProcessing` option.\n */\n skipProcessing?: boolean;\n /**\n * @platform web\n */\n scale?: number;\n /**\n * @platform web\n */\n imageType?: ImageType;\n /**\n * @platform web\n */\n isImageMirror?: boolean;\n /**\n * When set to `true`, the output image will be flipped along the vertical axis when using the front camera.\n * @default false\n * @platform ios\n * @platform android\n * @deprecated Use `mirror` prop on `CameraView` instead.\n */\n mirror?: boolean;\n /**\n * @hidden\n */\n id?: number;\n /**\n * @hidden\n */\n fastMode?: boolean;\n /**\n * @hidden\n */\n maxDownsampling?: number;\n /**\n * To programmatically disable the camera shutter sound\n * @default true\n */\n shutterSound?: boolean;\n /**\n * Whether the camera should return an image ref that can be used directly in the `Image` component.\n */\n pictureRef?: boolean;\n};\n\n// @needsAudit\nexport type CameraRecordingOptions = {\n /**\n * Maximum video duration in seconds.\n */\n maxDuration?: number;\n /**\n * Maximum video file size in bytes.\n */\n maxFileSize?: number;\n /**\n * If `true`, the recorded video will be flipped along the vertical axis. iOS flips videos recorded with the front camera by default,\n * but you can reverse that back by setting this to `true`. On Android, this is handled in the user's device settings.\n * @deprecated Use `mirror` prop on `CameraView` instead.\n */\n mirror?: boolean;\n /**\n * This option specifies what codec to use when recording the video. See [`VideoCodec`](#videocodec) for the possible values.\n * @platform ios\n */\n codec?: VideoCodec;\n};\n\n/**\n * @hidden\n */\nexport type PictureSavedListener = (event: {\n nativeEvent: { data: CameraCapturedPicture; id: number };\n}) => void;\n\n/**\n * @hidden\n */\nexport type AvailableLensesChangedListener = (event: { nativeEvent: AvailableLenses }) => void;\n\n// @docsMissing\nexport type AvailableLenses = { lenses: string[] };\n\n/**\n * @hidden\n */\nexport type CameraReadyListener = () => void;\n\n/**\n * @hidden\n */\nexport type ResponsiveOrientationChangedListener = (event: {\n nativeEvent: ResponsiveOrientationChanged;\n}) => void;\n\nexport type ResponsiveOrientationChanged = { orientation: CameraOrientation };\n\n/**\n * @hidden\n */\nexport type MountErrorListener = (event: { nativeEvent: CameraMountError }) => void;\n\n// @docsMissing\nexport type CameraMountError = { message: string };\n\n// @docsMissing\nexport type Point = {\n x: number;\n y: number;\n};\n\nexport type BarcodeSize = {\n /**\n * The height value.\n */\n height: number;\n /**\n * The width value.\n */\n width: number;\n};\n\n/**\n * These coordinates are represented in the coordinate space of the camera source (e.g. when you\n * are using the camera view, these values are adjusted to the dimensions of the view).\n */\nexport type BarcodePoint = Point;\n\nexport type BarcodeBounds = {\n /**\n * The origin point of the bounding box.\n */\n origin: BarcodePoint;\n /**\n * The size of the bounding box.\n */\n size: BarcodeSize;\n};\n\n// @needsAudit\nexport type BarcodeScanningResult = {\n /**\n * The barcode type.\n */\n type: string;\n /**\n * The parsed information encoded in the barcode.\n */\n data: string;\n /**\n * The raw information encoded in the barcode.\n * May be different from `data` depending on the barcode type.\n * @platform android\n * @hidden\n */\n raw?: string;\n /**\n * Corner points of the bounding box.\n * `cornerPoints` is not always available and may be empty. On iOS, for `code39` and `pdf417`\n * you don't get this value.\n *\n * **Note:** Corner points order is currently different across platforms. On Android,\n * [Google MLKit's native order](https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/common/Barcode#getCornerPoints())\n * is used, which is `topLeft`, `topRight`, `bottomRight`, `bottomLeft`.\n * On iOS, the order is `bottomLeft`, `bottomRight`, `topLeft`, `topRight`. On Web, the order is\n * `topLeft`, `bottomLeft`, `topRight`, `bottomRight`.\n *\n */\n cornerPoints: BarcodePoint[];\n /**\n * The [`BarcodeBounds`](#barcodebounds) object.\n * `bounds` in some case will be representing an empty rectangle.\n * Moreover, `bounds` doesn't have to bound the whole barcode.\n * For some types, they will represent the area used by the scanner.\n */\n bounds: BarcodeBounds;\n\n /**\n * Extra information returned by the specific type of barcode.\n * @platform android\n */\n extra?: AndroidBarcode;\n};\n\nexport type ScanningResult = Omit;\n\n// @needsAudit\nexport type CameraViewProps = ViewProps & {\n /**\n * Camera facing. Use one of `CameraType`. When `front`, use the front-facing camera.\n * When `back`, use the back-facing camera.\n * @default 'back'\n */\n facing?: CameraType;\n /**\n * Camera flash mode. Use one of `FlashMode` values. When `on`, the flash on your device will\n * turn on when taking a picture. When `off`, it won't. Setting it to `auto` will fire flash if required.\n * @default 'off'\n */\n flash?: FlashMode;\n /**\n * A value between `0` and `1` being a percentage of device's max zoom, where `0` means not zoomed and `1` means maximum zoom.\n * @default 0\n */\n zoom?: number;\n /**\n * Used to select image or video output.\n * @default 'picture'\n */\n mode?: CameraMode;\n /**\n * If present, video will be recorded with no sound.\n * @default false\n */\n mute?: boolean;\n /**\n * A boolean that determines whether the camera should mirror the image when using the front camera.\n * @default false\n */\n mirror?: boolean;\n /**\n * Indicates the focus mode to use.\n * @default off\n * @platform ios\n */\n autofocus?: FocusMode;\n /**\n * A boolean that determines whether the camera should be active.\n * Useful in situations where the camera may not have unmounted but you still want to stop the camera session.\n * @default true\n * @platform ios\n */\n active?: boolean;\n /**\n * Specify the quality of the recorded video. Use one of `VideoQuality` possible values:\n * for 16:9 resolution `2160p`, `1080p`, `720p`, `480p` : `Android only` and for 4:3 `4:3` (the size is 640x480).\n * If the chosen quality is not available for a device, the highest available is chosen.\n */\n videoQuality?: VideoQuality;\n /**\n * The bitrate of the video recording in bits per second.\n * Note: On iOS, you must specify the video codec when calling `recordAsync` to use this option.\n * @example 10_000_000\n */\n videoBitrate?: number;\n /**\n * A boolean that determines whether the camera shutter animation should be enabled.\n * @default true\n */\n animateShutter?: boolean;\n /**\n * A string representing the size of pictures [`takePictureAsync`](#takepictureasyncoptions) will take.\n * Available sizes can be fetched with [`getAvailablePictureSizesAsync`](#getavailablepicturesizesasync).\n * Setting this prop will cause the `ratio` prop to be ignored as the aspect ratio is determined by the selected size.\n */\n pictureSize?: string;\n /**\n * Available lenses are emitted to the `onAvailableLensesChanged` callback whenever the currently selected camera changes or by calling [`getAvailableLensesAsync`](#getavailablelensesasync).\n * You can read more about the available lenses in the [Apple documentation](https://developer.apple.com/documentation/avfoundation/avcapturedevice/devicetype-swift.struct).\n * @platform ios\n * @default 'builtInWideAngleCamera'\n */\n selectedLens?: string;\n /**\n * A boolean to enable or disable the torch.\n * @default false\n */\n enableTorch?: boolean;\n /**\n * The video stabilization mode used for a video recording. Use one of [`VideoStabilization.`](#videostabilization).\n * You can read more about each stabilization type in [Apple Documentation](https://developer.apple.com/documentation/avfoundation/avcapturevideostabilizationmode).\n * @default 'auto'\n */\n videoStabilizationMode?: VideoStabilization;\n /**\n * @example\n * ```tsx\n * \n * ```\n */\n barcodeScannerSettings?: BarcodeSettings;\n /**\n * A URL for an image to be shown while the camera is loading.\n * @platform web\n */\n poster?: string;\n /**\n * Whether to allow responsive orientation of the camera when the screen orientation is locked (that is, when set to `true`,\n * landscape photos will be taken if the device is turned that way, even if the app or device orientation is locked to portrait).\n * @platform ios\n */\n responsiveOrientationWhenOrientationLocked?: boolean;\n /**\n * A string representing the aspect ratio of the preview. For example, `4:3` and `16:9`.\n * Note: Setting the aspect ratio here will change the scaleType of the camera preview from `FILL` to `FIT`.\n * Also, when using 1:1, devices only support certain sizes. If you specify an unsupported size, the closest supported ratio will be used.\n * @platform android\n */\n ratio?: CameraRatio;\n /**\n * Callback invoked when camera preview has been set.\n */\n onCameraReady?: () => void;\n /**\n * Callback invoked when camera preview could not start.\n * @param event Error object that contains a `message`.\n */\n onMountError?: (event: CameraMountError) => void;\n /**\n * Callback that is invoked when a barcode has been successfully scanned. The callback is provided with\n * an object of the [`BarcodeScanningResult`](#barcodescanningresult) shape, where the `type`\n * refers to the barcode type that was scanned, and the `data` is the information encoded in the barcode\n * (in this case of QR codes, this is often a URL). See [`BarcodeType`](#barcodetype) for supported values.\n * @param scanningResult\n */\n onBarcodeScanned?: (scanningResult: BarcodeScanningResult) => void;\n /**\n * Callback invoked when responsive orientation changes. Only applicable if `responsiveOrientationWhenOrientationLocked` is `true`.\n * @param event result object that contains updated orientation of camera\n * @platform ios\n */\n onResponsiveOrientationChanged?: (event: ResponsiveOrientationChanged) => void;\n /**\n * Callback invoked when the cameras available lenses change.\n * @param event result object that contains a `lenses` property containing an array of available lenses.\n * @platform ios\n */\n onAvailableLensesChanged?: (event: AvailableLenses) => void;\n};\n\n/**\n * @hidden\n */\nexport interface CameraViewRef {\n readonly takePicture: (options: CameraPictureOptions) => Promise;\n readonly takePictureRef?: (options: CameraPictureOptions) => Promise;\n readonly getAvailablePictureSizes: () => Promise;\n readonly getAvailableLenses: () => Promise;\n readonly record: (options?: CameraRecordingOptions) => Promise<{ uri: string }>;\n readonly toggleRecording: () => Promise;\n readonly stopRecording: () => Promise;\n readonly launchModernScanner: () => Promise;\n readonly resumePreview: () => Promise;\n readonly pausePreview: () => Promise;\n}\n\n/**\n * @hidden\n */\nexport type CameraNativeProps = {\n pointerEvents?: any;\n style?: any;\n ref?: Ref;\n onCameraReady?: CameraReadyListener;\n onMountError?: MountErrorListener;\n onBarcodeScanned?: (event: { nativeEvent: BarcodeScanningResult }) => void;\n onPictureSaved?: PictureSavedListener;\n onResponsiveOrientationChanged?: ResponsiveOrientationChangedListener;\n onAvailableLensesChanged?: AvailableLensesChangedListener;\n facing?: string;\n flashMode?: string;\n enableTorch?: boolean;\n animateShutter?: boolean;\n autoFocus?: FocusMode;\n mute?: boolean;\n zoom?: number;\n ratio?: CameraRatio;\n barcodeScannerSettings?: BarcodeSettings;\n barcodeScannerEnabled?: boolean;\n poster?: string;\n responsiveOrientationWhenOrientationLocked?: boolean;\n};\n\n// @docsMissing\nexport type BarcodeSettings = {\n barcodeTypes: BarcodeType[];\n};\n\n/**\n * @platform ios\n */\nexport type ScanningOptions = {\n /**\n * The type of codes to scan for.\n */\n barcodeTypes: BarcodeType[];\n /**\n * Indicates whether people can use a two-finger pinch-to-zoom gesture.\n * @platform ios\n * @default true\n */\n isPinchToZoomEnabled?: boolean;\n /**\n * Guidance text, such as โ€œSlow Down,โ€ appears over the live video.\n * @platform ios\n * @default true\n */\n isGuidanceEnabled?: boolean;\n /**\n * Indicates whether the scanner displays highlights around recognized items.\n * @platform ios\n * @default false\n */\n isHighlightingEnabled?: boolean;\n};\n\n/**\n * The available barcode types that can be scanned.\n */\nexport type BarcodeType =\n | 'aztec'\n | 'ean13'\n | 'ean8'\n | 'qr'\n | 'pdf417'\n | 'upc_e'\n | 'datamatrix'\n | 'code39'\n | 'code93'\n | 'itf14'\n | 'codabar'\n | 'code128'\n | 'upc_a';\n\nexport {\n PermissionResponse,\n PermissionStatus,\n PermissionExpiration,\n PermissionHookOptions,\n EventSubscription as Subscription,\n};\n\nexport type PhotoResult = {\n /**\n * A URI to the modified image (usable as the source for an `Image` or `Video` element).\n */\n uri: string;\n /**\n * Width of the image.\n */\n width: number;\n /**\n * Height of the image.\n */\n height: number;\n /**\n * A Base64 representation of the image.\n */\n base64?: string;\n};\n\n// @needsAudit\n/**\n * A map defining how modified image should be saved.\n */\nexport type SavePictureOptions = {\n /**\n * Specify the compression quality from `0` to `1`. `0` means compress for small size, and `1` means compress for maximum quality.\n */\n quality?: number;\n /**\n * Additional metadata to be included for the image.\n */\n metadata?: Record;\n /**\n * Whether to also include the image data in Base64 format.\n */\n base64?: boolean;\n};\n\nexport type CameraEvents = {\n onModernBarcodeScanned: (event: ScanningResult) => void;\n};\nexport declare class CameraNativeModule extends NativeModule {\n /**\n * @hidden\n */\n Picture: typeof PictureRef;\n\n readonly isModernBarcodeScannerAvailable: boolean;\n readonly toggleRecordingAsyncAvailable: boolean;\n readonly isAvailableAsync: () => Promise;\n readonly launchScanner: (options?: ScanningOptions) => Promise;\n readonly dismissScanner: () => Promise;\n readonly scanFromURLAsync: (\n url: string,\n barcodeTypes?: BarcodeType[]\n ) => Promise;\n readonly getCameraPermissionsAsync: () => Promise;\n readonly requestCameraPermissionsAsync: () => Promise;\n readonly getMicrophonePermissionsAsync: () => Promise;\n readonly requestMicrophonePermissionsAsync: () => Promise;\n readonly getAvailableVideoCodecsAsync: () => Promise;\n\n readonly Type: Record;\n readonly FlashMode: Record;\n}\n"]} \ No newline at end of file +{"version":3,"file":"Camera.types.js","sourceRoot":"","sources":["../src/Camera.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gBAAgB,GAKjB,MAAM,mBAAmB,CAAC;AA0kB3B,OAAO,EAEL,gBAAgB,GAIjB,CAAC","sourcesContent":["import {\n PermissionResponse,\n PermissionStatus,\n PermissionExpiration,\n PermissionHookOptions,\n EventSubscription,\n NativeModule,\n} from 'expo-modules-core';\nimport type { Ref } from 'react';\nimport type { ViewProps } from 'react-native';\n\nimport { AndroidBarcode } from './AndroidBarcode.types';\nimport { PictureRef } from './PictureRef';\n\nexport type CameraType = 'front' | 'back';\n\n/**\n * Flash mode for the camera.\n * - `off` - Flash is disabled.\n * - `on` - Flash will fire for every capture.\n * - `auto` - Flash will fire automatically when required.\n * - `screen` - Uses the device screen as a flash for front camera selfies.\n * On Android, this uses CameraX's dedicated screen flash mode.\n * On iOS, this maps to 'on' which triggers Retina Flash automatically.\n */\nexport type FlashMode = 'off' | 'on' | 'auto' | 'screen';\n\nexport type ImageType = 'png' | 'jpg';\n\nexport type CameraMode = 'picture' | 'video';\n\nexport type CameraRatio = '4:3' | '16:9' | '1:1';\n\n/**\n * This option specifies the mode of focus on the device.\n * - `on` - Indicates that the device should autofocus once and then lock the focus.\n * - `off` - Indicates that the device should automatically focus when needed.\n * @default off\n */\nexport type FocusMode = 'on' | 'off';\n\n/**\n * This option specifies what codec to use when recording a video.\n * @platform ios\n */\nexport type VideoCodec = 'avc1' | 'hvc1' | 'jpeg' | 'apcn' | 'ap4h';\n\n/**\n * This option specifies the stabilization mode to use when recording a video.\n * - `off` - No stabilization.\n * - `standard` - Standard stabilization.\n * - `cinematic` - Cinematic stabilization (provides more aggressive stabilization).\n * - `auto` - The system automatically chooses the best stabilization mode.\n *\n * On Android, `standard`, `cinematic`, and `auto` all enable video stabilization,\n * while `off` disables it. The specific stabilization method is determined by the device.\n */\nexport type VideoStabilization = 'off' | 'standard' | 'cinematic' | 'auto';\n\n// @docsMissing\nexport type VideoQuality = '2160p' | '1080p' | '720p' | '480p' | '4:3';\n\nexport type CameraOrientation =\n | 'portrait'\n | 'portraitUpsideDown'\n | 'landscapeLeft'\n | 'landscapeRight';\n\n// @docsMissing\n/**\n * @hidden We do not expose related web methods in docs.\n * @platform web\n */\nexport type ImageSize = {\n width: number;\n height: number;\n};\n\n// @docsMissing\n/**\n * @hidden We do not expose related web methods in docs.\n * @platform web\n */\nexport type WebCameraSettings = {\n autoFocus?: string;\n flashMode?: string;\n whiteBalance?: string;\n exposureCompensation?: number;\n colorTemperature?: number;\n iso?: number;\n brightness?: number;\n contrast?: number;\n saturation?: number;\n sharpness?: number;\n focusDistance?: number;\n zoom?: number;\n};\n\n// @needsAudit\nexport type CameraCapturedPicture = {\n /**\n * Captured image width.\n */\n width: number;\n /**\n * Captured image height.\n */\n height: number;\n /**\n * The format of the captured image.\n */\n format: 'jpg' | 'png';\n /**\n * On web, the value of `uri` is the same as `base64` because file system URLs are not supported in the browser.\n */\n uri: string;\n /**\n * A Base64 representation of the image.\n */\n base64?: string;\n /**\n * On Android and iOS this object may include various fields based on the device and operating system.\n * On web, it is a partial representation of the [`MediaTrackSettings`](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings) dictionary.\n */\n exif?: Partial | any;\n};\n\n// @needsAudit\nexport type CameraPictureOptions = {\n /**\n * Specify the compression quality from `0` to `1`. `0` means compress for small size, and `1` means compress for maximum quality.\n * @default 1\n */\n quality?: number;\n /**\n * Whether to also include the image data in Base64 format.\n */\n base64?: boolean;\n /**\n * Whether to also include the EXIF data for the image.\n */\n exif?: boolean;\n /**\n * Additional EXIF data to be included for the image. Only useful when `exif` option is set to `true`.\n * @platform android\n * @platform ios\n */\n additionalExif?: Record;\n /**\n * A callback invoked when picture is saved. If set, the promise of this method will resolve immediately with no data after picture is captured.\n * The data that it should contain will be passed to this callback. If displaying or processing a captured photo right after taking it\n * is not your case, this callback lets you skip waiting for it to be saved.\n * @param picture\n */\n onPictureSaved?: (picture: CameraCapturedPicture) => void;\n // TODO(Bacon): Is it possible to implement this in the browser?\n /**\n * If set to `true`, camera skips orientation adjustment and returns an image straight from the device's camera.\n * If enabled, `quality` option is discarded (processing pipeline is skipped as a whole).\n * Although enabling this option reduces image delivery time significantly, it may cause the image to appear in a wrong orientation\n * in the `Image` component (at the time of writing, it does not respect EXIF orientation of the images).\n * > **Note**: Enabling `skipProcessing` would cause orientation uncertainty. `Image` component does not respect EXIF\n * > stored orientation information, that means obtained image would be displayed wrongly (rotated by 90ยฐ, 180ยฐ or 270ยฐ).\n * > Different devices provide different orientations. For example some Sony Xperia or Samsung devices don't provide\n * > correctly oriented images by default. To always obtain correctly oriented image disable `skipProcessing` option.\n */\n skipProcessing?: boolean;\n /**\n * @platform web\n */\n scale?: number;\n /**\n * @platform web\n */\n imageType?: ImageType;\n /**\n * @platform web\n */\n isImageMirror?: boolean;\n /**\n * When set to `true`, the output image will be flipped along the vertical axis when using the front camera.\n * @default false\n * @platform ios\n * @platform android\n * @deprecated Use `mirror` prop on `CameraView` instead.\n */\n mirror?: boolean;\n /**\n * @hidden\n */\n id?: number;\n /**\n * @hidden\n */\n fastMode?: boolean;\n /**\n * @hidden\n */\n maxDownsampling?: number;\n /**\n * To programmatically disable the camera shutter sound\n * @default true\n */\n shutterSound?: boolean;\n /**\n * Whether the camera should return an image ref that can be used directly in the `Image` component.\n */\n pictureRef?: boolean;\n};\n\n// @needsAudit\nexport type CameraRecordingOptions = {\n /**\n * Maximum video duration in seconds.\n */\n maxDuration?: number;\n /**\n * Maximum video file size in bytes.\n */\n maxFileSize?: number;\n /**\n * If `true`, the recorded video will be flipped along the vertical axis. iOS flips videos recorded with the front camera by default,\n * but you can reverse that back by setting this to `true`. On Android, this is handled in the user's device settings.\n * @deprecated Use `mirror` prop on `CameraView` instead.\n */\n mirror?: boolean;\n /**\n * This option specifies what codec to use when recording the video. See [`VideoCodec`](#videocodec) for the possible values.\n * @platform ios\n */\n codec?: VideoCodec;\n};\n\n/**\n * @hidden\n */\nexport type PictureSavedListener = (event: {\n nativeEvent: { data: CameraCapturedPicture; id: number };\n}) => void;\n\n/**\n * @hidden\n */\nexport type AvailableLensesChangedListener = (event: { nativeEvent: AvailableLenses }) => void;\n\n// @docsMissing\nexport type AvailableLenses = { lenses: string[] };\n\n/**\n * @hidden\n */\nexport type CameraReadyListener = () => void;\n\n/**\n * @hidden\n */\nexport type ResponsiveOrientationChangedListener = (event: {\n nativeEvent: ResponsiveOrientationChanged;\n}) => void;\n\nexport type ResponsiveOrientationChanged = { orientation: CameraOrientation };\n\n/**\n * @hidden\n */\nexport type MountErrorListener = (event: { nativeEvent: CameraMountError }) => void;\n\n// @docsMissing\nexport type CameraMountError = { message: string };\n\n// @docsMissing\nexport type Point = {\n x: number;\n y: number;\n};\n\nexport type BarcodeSize = {\n /**\n * The height value.\n */\n height: number;\n /**\n * The width value.\n */\n width: number;\n};\n\n/**\n * These coordinates are represented in the coordinate space of the camera source (e.g. when you\n * are using the camera view, these values are adjusted to the dimensions of the view).\n */\nexport type BarcodePoint = Point;\n\nexport type BarcodeBounds = {\n /**\n * The origin point of the bounding box.\n */\n origin: BarcodePoint;\n /**\n * The size of the bounding box.\n */\n size: BarcodeSize;\n};\n\n// @needsAudit\nexport type BarcodeScanningResult = {\n /**\n * The barcode type.\n */\n type: string;\n /**\n * The parsed information encoded in the barcode.\n */\n data: string;\n /**\n * The raw information encoded in the barcode.\n * May be different from `data` depending on the barcode type.\n * @platform android\n * @hidden\n */\n raw?: string;\n /**\n * Corner points of the bounding box.\n * `cornerPoints` is not always available and may be empty. On iOS, for `code39` and `pdf417`\n * you don't get this value.\n *\n * **Note:** Corner points order is currently different across platforms. On Android,\n * [Google MLKit's native order](https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/common/Barcode#getCornerPoints())\n * is used, which is `topLeft`, `topRight`, `bottomRight`, `bottomLeft`.\n * On iOS, the order is `bottomLeft`, `bottomRight`, `topLeft`, `topRight`. On Web, the order is\n * `topLeft`, `topRight`, `bottomRight`, `bottomLeft` (matching Android/BarcodeDetector order).\n *\n */\n cornerPoints: BarcodePoint[];\n /**\n * The [`BarcodeBounds`](#barcodebounds) object.\n * `bounds` in some case will be representing an empty rectangle.\n * Moreover, `bounds` doesn't have to bound the whole barcode.\n * For some types, they will represent the area used by the scanner.\n */\n bounds: BarcodeBounds;\n\n /**\n * Extra information returned by the specific type of barcode.\n * @platform android\n */\n extra?: AndroidBarcode;\n};\n\nexport type ScanningResult = Omit;\n\n// @needsAudit\nexport type CameraViewProps = ViewProps & {\n /**\n * Camera facing. Use one of `CameraType`. When `front`, use the front-facing camera.\n * When `back`, use the back-facing camera.\n * @default 'back'\n */\n facing?: CameraType;\n /**\n * Camera flash mode. Use one of `FlashMode` values. When `on`, the flash on your device will\n * turn on when taking a picture. When `off`, it won't. Setting it to `auto` will fire flash if required.\n * @default 'off'\n */\n flash?: FlashMode;\n /**\n * A value between `0` and `1` being a percentage of device's max zoom, where `0` means not zoomed and `1` means maximum zoom.\n * @default 0\n */\n zoom?: number;\n /**\n * Used to select image or video output.\n * @default 'picture'\n */\n mode?: CameraMode;\n /**\n * If present, video will be recorded with no sound.\n * @default false\n */\n mute?: boolean;\n /**\n * A boolean that determines whether the camera should mirror the image when using the front camera.\n * @default false\n */\n mirror?: boolean;\n /**\n * Indicates the focus mode to use.\n * @default off\n * @platform ios\n */\n autofocus?: FocusMode;\n /**\n * A boolean that determines whether the camera should be active.\n * Useful in situations where the camera may not have unmounted but you still want to stop the camera session.\n * @default true\n * @platform ios\n */\n active?: boolean;\n /**\n * Specify the quality of the recorded video. Use one of `VideoQuality` possible values:\n * for 16:9 resolution `2160p`, `1080p`, `720p`, `480p` : `Android only` and for 4:3 `4:3` (the size is 640x480).\n * If the chosen quality is not available for a device, the highest available is chosen.\n */\n videoQuality?: VideoQuality;\n /**\n * The bitrate of the video recording in bits per second.\n * Note: On iOS, you must specify the video codec when calling `recordAsync` to use this option.\n * @example 10_000_000\n */\n videoBitrate?: number;\n /**\n * A boolean that determines whether the camera shutter animation should be enabled.\n * @default true\n */\n animateShutter?: boolean;\n /**\n * A string representing the size of pictures [`takePictureAsync`](#takepictureasyncoptions) will take.\n * Available sizes can be fetched with [`getAvailablePictureSizesAsync`](#getavailablepicturesizesasync).\n * Setting this prop will cause the `ratio` prop to be ignored as the aspect ratio is determined by the selected size.\n */\n pictureSize?: string;\n /**\n * Available lenses are emitted to the `onAvailableLensesChanged` callback whenever the currently selected camera changes or by calling [`getAvailableLensesAsync`](#getavailablelensesasync).\n * You can read more about the available lenses in the [Apple documentation](https://developer.apple.com/documentation/avfoundation/avcapturedevice/devicetype-swift.struct).\n * @platform ios\n * @default 'builtInWideAngleCamera'\n */\n selectedLens?: string;\n /**\n * A boolean to enable or disable the torch.\n * @default false\n */\n enableTorch?: boolean;\n /**\n * The video stabilization mode used for a video recording. Use one of [`VideoStabilization.`](#videostabilization).\n * You can read more about each stabilization type in [Apple Documentation](https://developer.apple.com/documentation/avfoundation/avcapturevideostabilizationmode).\n * @default 'auto'\n */\n videoStabilizationMode?: VideoStabilization;\n /**\n * @example\n * ```tsx\n * \n * ```\n */\n barcodeScannerSettings?: BarcodeSettings;\n /**\n * A URL for an image to be shown while the camera is loading.\n * @platform web\n */\n poster?: string;\n /**\n * Whether to allow responsive orientation of the camera when the screen orientation is locked (that is, when set to `true`,\n * landscape photos will be taken if the device is turned that way, even if the app or device orientation is locked to portrait).\n * @platform ios\n */\n responsiveOrientationWhenOrientationLocked?: boolean;\n /**\n * A string representing the aspect ratio of the preview. For example, `4:3` and `16:9`.\n * Note: Setting the aspect ratio here will change the scaleType of the camera preview from `FILL` to `FIT`.\n * Also, when using 1:1, devices only support certain sizes. If you specify an unsupported size, the closest supported ratio will be used.\n * @platform android\n */\n ratio?: CameraRatio;\n /**\n * Callback invoked when camera preview has been set.\n */\n onCameraReady?: () => void;\n /**\n * Callback invoked when camera preview could not start.\n * @param event Error object that contains a `message`.\n */\n onMountError?: (event: CameraMountError) => void;\n /**\n * Callback that is invoked when a barcode has been successfully scanned. The callback is provided with\n * an object of the [`BarcodeScanningResult`](#barcodescanningresult) shape, where the `type`\n * refers to the barcode type that was scanned, and the `data` is the information encoded in the barcode\n * (in this case of QR codes, this is often a URL). See [`BarcodeType`](#barcodetype) for supported values.\n * @param scanningResult\n */\n onBarcodeScanned?: (scanningResult: BarcodeScanningResult) => void;\n /**\n * Callback invoked when responsive orientation changes. Only applicable if `responsiveOrientationWhenOrientationLocked` is `true`.\n * @param event result object that contains updated orientation of camera\n * @platform ios\n */\n onResponsiveOrientationChanged?: (event: ResponsiveOrientationChanged) => void;\n /**\n * Callback invoked when the cameras available lenses change.\n * @param event result object that contains a `lenses` property containing an array of available lenses.\n * @platform ios\n */\n onAvailableLensesChanged?: (event: AvailableLenses) => void;\n};\n\n/**\n * @hidden\n */\nexport interface CameraViewRef {\n readonly takePicture: (options: CameraPictureOptions) => Promise;\n readonly takePictureRef?: (options: CameraPictureOptions) => Promise;\n readonly getAvailablePictureSizes: () => Promise;\n readonly getAvailableLenses: () => Promise;\n readonly record: (options?: CameraRecordingOptions) => Promise<{ uri: string }>;\n readonly toggleRecording: () => Promise;\n readonly stopRecording: () => Promise;\n readonly launchModernScanner: () => Promise;\n readonly resumePreview: () => Promise;\n readonly pausePreview: () => Promise;\n}\n\n/**\n * @hidden\n */\nexport type CameraNativeProps = {\n pointerEvents?: any;\n style?: any;\n ref?: Ref;\n onCameraReady?: CameraReadyListener;\n onMountError?: MountErrorListener;\n onBarcodeScanned?: (event: { nativeEvent: BarcodeScanningResult }) => void;\n onPictureSaved?: PictureSavedListener;\n onResponsiveOrientationChanged?: ResponsiveOrientationChangedListener;\n onAvailableLensesChanged?: AvailableLensesChangedListener;\n facing?: string;\n flashMode?: string;\n enableTorch?: boolean;\n animateShutter?: boolean;\n autoFocus?: FocusMode;\n mute?: boolean;\n zoom?: number;\n ratio?: CameraRatio;\n barcodeScannerSettings?: BarcodeSettings;\n barcodeScannerEnabled?: boolean;\n poster?: string;\n responsiveOrientationWhenOrientationLocked?: boolean;\n};\n\n// @docsMissing\nexport type BarcodeSettings = {\n barcodeTypes: BarcodeType[];\n};\n\n/**\n * @platform ios\n */\nexport type ScanningOptions = {\n /**\n * The type of codes to scan for.\n */\n barcodeTypes: BarcodeType[];\n /**\n * Indicates whether people can use a two-finger pinch-to-zoom gesture.\n * @platform ios\n * @default true\n */\n isPinchToZoomEnabled?: boolean;\n /**\n * Guidance text, such as โ€œSlow Down,โ€ appears over the live video.\n * @platform ios\n * @default true\n */\n isGuidanceEnabled?: boolean;\n /**\n * Indicates whether the scanner displays highlights around recognized items.\n * @platform ios\n * @default false\n */\n isHighlightingEnabled?: boolean;\n};\n\n/**\n * The available barcode types that can be scanned.\n */\nexport type BarcodeType =\n | 'aztec'\n | 'ean13'\n | 'ean8'\n | 'qr'\n | 'pdf417'\n | 'upc_e'\n | 'datamatrix'\n | 'code39'\n | 'code93'\n | 'itf14'\n | 'codabar'\n | 'code128'\n | 'upc_a';\n\nexport {\n PermissionResponse,\n PermissionStatus,\n PermissionExpiration,\n PermissionHookOptions,\n EventSubscription as Subscription,\n};\n\nexport type PhotoResult = {\n /**\n * A URI to the modified image (usable as the source for an `Image` or `Video` element).\n */\n uri: string;\n /**\n * Width of the image.\n */\n width: number;\n /**\n * Height of the image.\n */\n height: number;\n /**\n * A Base64 representation of the image.\n */\n base64?: string;\n};\n\n// @needsAudit\n/**\n * A map defining how modified image should be saved.\n */\nexport type SavePictureOptions = {\n /**\n * Specify the compression quality from `0` to `1`. `0` means compress for small size, and `1` means compress for maximum quality.\n */\n quality?: number;\n /**\n * Additional metadata to be included for the image.\n */\n metadata?: Record;\n /**\n * Whether to also include the image data in Base64 format.\n */\n base64?: boolean;\n};\n\nexport type CameraEvents = {\n onModernBarcodeScanned: (event: ScanningResult) => void;\n};\nexport declare class CameraNativeModule extends NativeModule {\n /**\n * @hidden\n */\n Picture: typeof PictureRef;\n\n readonly isModernBarcodeScannerAvailable: boolean;\n readonly toggleRecordingAsyncAvailable: boolean;\n readonly isAvailableAsync: () => Promise;\n readonly launchScanner: (options?: ScanningOptions) => Promise;\n readonly dismissScanner: () => Promise;\n readonly scanFromURLAsync: (\n url: string,\n barcodeTypes?: BarcodeType[]\n ) => Promise;\n readonly getCameraPermissionsAsync: () => Promise;\n readonly requestCameraPermissionsAsync: () => Promise;\n readonly getMicrophonePermissionsAsync: () => Promise;\n readonly requestMicrophonePermissionsAsync: () => Promise;\n readonly getAvailableVideoCodecsAsync: () => Promise;\n\n readonly Type: Record;\n readonly FlashMode: Record;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/ExpoCamera.web.d.ts.map b/packages/expo-camera/build/ExpoCamera.web.d.ts.map index 82e28bf43e9340..58adb52805d294 100644 --- a/packages/expo-camera/build/ExpoCamera.web.d.ts.map +++ b/packages/expo-camera/build/ExpoCamera.web.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"ExpoCamera.web.d.ts","sourceRoot":"","sources":["../src/ExpoCamera.web.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,iBAAiB,EAMvB,MAAM,OAAO,CAAC;AAIf,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EAErB,MAAM,gBAAgB,CAAC;AAOxB,MAAM,WAAW,iBAAiB;IAChC,wBAAwB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/D,WAAW,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC/E,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED,QAAA,MAAM,cAAc,GAAI,mCAKrB,iBAAiB,CAAC,iBAAiB,CAAC,gCAkHtC,CAAC;AAEF,eAAe,cAAc,CAAC"} \ No newline at end of file +{"version":3,"file":"ExpoCamera.web.d.ts","sourceRoot":"","sources":["../src/ExpoCamera.web.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,iBAAiB,EAMvB,MAAM,OAAO,CAAC;AAIf,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EAErB,MAAM,gBAAgB,CAAC;AAOxB,MAAM,WAAW,iBAAiB;IAChC,wBAAwB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/D,WAAW,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC/E,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED,QAAA,MAAM,cAAc,GAAI,mCAKrB,iBAAiB,CAAC,iBAAiB,CAAC,gCA0HtC,CAAC;AAEF,eAAe,cAAc,CAAC"} \ No newline at end of file diff --git a/packages/expo-camera/build/ExpoCamera.web.js b/packages/expo-camera/build/ExpoCamera.web.js index 415c5aee8a8be3..8b87a101f4670e 100644 --- a/packages/expo-camera/build/ExpoCamera.web.js +++ b/packages/expo-camera/build/ExpoCamera.web.js @@ -5,11 +5,17 @@ import createElement from 'react-native-web/dist/exports/createElement'; import CameraManager from './ExpoCameraManager.web'; import { capture } from './web/WebCameraUtils'; import { PictureSizes } from './web/WebConstants'; +import { useWebBarcodeScanner } from './web/useWebBarcodeScanner'; import { useWebCameraStream } from './web/useWebCameraStream'; -import { useWebQRScanner } from './web/useWebQRScanner'; const ExponentCamera = ({ facing, poster, ref, ...props }) => { const video = useRef(null); - const native = useWebCameraStream(video, facing, props, { + const cameraSettings = useMemo(() => { + return { + ...props, + flashMode: props.enableTorch ? 'torch' : props.flashMode, + }; + }, [props.enableTorch, props.flashMode, props.zoom, props.autoFocus]); + const native = useWebCameraStream(video, facing, cameraSettings, { onCameraReady() { if (props.onCameraReady) { props.onCameraReady(); @@ -17,13 +23,15 @@ const ExponentCamera = ({ facing, poster, ref, ...props }) => { }, onMountError: props.onMountError, }); - const isQRScannerEnabled = useMemo(() => { - return Boolean(props.barcodeScannerSettings?.barcodeTypes?.includes('qr') && !!props.onBarcodeScanned); - }, [props.barcodeScannerSettings?.barcodeTypes, props.onBarcodeScanned]); - useWebQRScanner(video, { + const barcodeTypes = props.barcodeScannerSettings?.barcodeTypes; + const isScannerEnabled = useMemo(() => { + return Boolean(barcodeTypes?.length && !!props.onBarcodeScanned); + }, [barcodeTypes, props.onBarcodeScanned]); + useWebBarcodeScanner(video, { interval: 300, - isEnabled: isQRScannerEnabled, - captureOptions: { scale: 1, isImageMirror: native.type === 'front' }, + isEnabled: isScannerEnabled, + barcodeTypes: barcodeTypes ?? [], + isMirrored: native.type === 'front', onScanned(event) { if (props.onBarcodeScanned) { props.onBarcodeScanned(event); diff --git a/packages/expo-camera/build/ExpoCamera.web.js.map b/packages/expo-camera/build/ExpoCamera.web.js.map index 37167fa8e243b7..fa14176d3f5f9e 100644 --- a/packages/expo-camera/build/ExpoCamera.web.js.map +++ b/packages/expo-camera/build/ExpoCamera.web.js.map @@ -1 +1 @@ -{"version":3,"file":"ExpoCamera.web.js","sourceRoot":"","sources":["../src/ExpoCamera.web.tsx"],"names":[],"mappings":"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","sourcesContent":["import { CodedError } from 'expo-modules-core';\nimport {\n type PropsWithChildren,\n useRef,\n useMemo,\n useImperativeHandle,\n type ComponentProps,\n type Ref,\n} from 'react';\nimport { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';\nimport createElement from 'react-native-web/dist/exports/createElement';\n\nimport {\n CameraNativeProps,\n CameraCapturedPicture,\n CameraPictureOptions,\n CameraType,\n} from './Camera.types';\nimport CameraManager from './ExpoCameraManager.web';\nimport { capture } from './web/WebCameraUtils';\nimport { PictureSizes } from './web/WebConstants';\nimport { useWebCameraStream } from './web/useWebCameraStream';\nimport { useWebQRScanner } from './web/useWebQRScanner';\n\nexport interface ExponentCameraRef {\n getAvailablePictureSizes: (ratio: string) => Promise;\n takePicture: (options: CameraPictureOptions) => Promise;\n resumePreview: () => Promise;\n pausePreview: () => Promise;\n}\n\nconst ExponentCamera = ({\n facing,\n poster,\n ref,\n ...props\n}: PropsWithChildren) => {\n const video = useRef(null);\n\n const native = useWebCameraStream(video, facing as CameraType, props, {\n onCameraReady() {\n if (props.onCameraReady) {\n props.onCameraReady();\n }\n },\n onMountError: props.onMountError,\n });\n\n const isQRScannerEnabled = useMemo(() => {\n return Boolean(\n props.barcodeScannerSettings?.barcodeTypes?.includes('qr') && !!props.onBarcodeScanned\n );\n }, [props.barcodeScannerSettings?.barcodeTypes, props.onBarcodeScanned]);\n\n useWebQRScanner(video, {\n interval: 300,\n isEnabled: isQRScannerEnabled,\n captureOptions: { scale: 1, isImageMirror: native.type === 'front' },\n onScanned(event) {\n if (props.onBarcodeScanned) {\n props.onBarcodeScanned(event);\n }\n },\n });\n\n useImperativeHandle(\n ref,\n () => ({\n async getAvailablePictureSizes(): Promise {\n return PictureSizes;\n },\n async takePicture(options: CameraPictureOptions): Promise {\n if (!video.current || video.current?.readyState !== video.current?.HAVE_ENOUGH_DATA) {\n throw new CodedError(\n 'ERR_CAMERA_NOT_READY',\n 'HTMLVideoElement does not have enough camera data to construct an image yet.'\n );\n }\n const settings = native.mediaTrackSettings;\n if (!settings) {\n throw new CodedError('ERR_CAMERA_NOT_READY', 'MediaStream is not ready yet.');\n }\n\n return capture(video.current, settings, {\n ...options,\n // This will always be defined, the option gets added to a queue in the upper-level. We should replace the original so it isn't called twice.\n onPictureSaved(picture) {\n if (options.onPictureSaved) {\n options.onPictureSaved(picture);\n }\n if (props.onPictureSaved) {\n props.onPictureSaved({ nativeEvent: { data: picture, id: -1 } });\n }\n },\n });\n },\n async resumePreview(): Promise {\n if (video.current) {\n video.current.play();\n }\n },\n async pausePreview(): Promise {\n if (video.current) {\n video.current.pause();\n }\n },\n async stopRecording(): Promise {\n console.warn('stopRecording is not supported on web.');\n },\n async record(): Promise<{ uri: string }> {\n console.warn('record is not supported on web.');\n return { uri: '' };\n },\n async toggleRecording() {\n console.warn('toggleRecording is not supported on web.');\n },\n async launchModernScanner() {\n console.warn('launchModernScanner is not supported on web.');\n },\n async getAvailableLenses() {\n console.warn('getAvailableLenses is not supported on web.');\n return [];\n },\n }),\n [native.mediaTrackSettings, props.onPictureSaved]\n );\n\n // TODO(Bacon): Create a universal prop, on native the microphone is only used when recording videos.\n // Because we don't support recording video in the browser we don't need the user to give microphone permissions.\n const isMuted = true;\n\n const style = useMemo>(() => {\n const isFrontFacingCamera = native.type === CameraManager.Type.front;\n return [\n StyleSheet.absoluteFill,\n styles.video,\n {\n pointerEvents: props.pointerEvents,\n // Flip the camera\n transform: isFrontFacingCamera ? [{ scaleX: -1 }] : undefined,\n },\n ];\n }, [props.pointerEvents, native.type]);\n\n return (\n \n \n );\n};\n\nexport default ExponentCamera;\n\nconst Video = (\n props: ComponentProps & {\n autoPlay?: boolean;\n playsInline?: boolean;\n muted?: boolean;\n poster?: string;\n ref: Ref;\n }\n) => createElement('video', { ...props });\n\nconst styles = StyleSheet.create({\n videoWrapper: {\n flex: 1,\n alignItems: 'stretch',\n pointerEvents: 'box-none',\n },\n video: {\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n },\n});\n"]} \ No newline at end of file +{"version":3,"file":"ExpoCamera.web.js","sourceRoot":"","sources":["../src/ExpoCamera.web.tsx"],"names":[],"mappings":"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","sourcesContent":["import { CodedError } from 'expo-modules-core';\nimport {\n type PropsWithChildren,\n useRef,\n useMemo,\n useImperativeHandle,\n type ComponentProps,\n type Ref,\n} from 'react';\nimport { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';\nimport createElement from 'react-native-web/dist/exports/createElement';\n\nimport {\n CameraNativeProps,\n CameraCapturedPicture,\n CameraPictureOptions,\n CameraType,\n} from './Camera.types';\nimport CameraManager from './ExpoCameraManager.web';\nimport { capture } from './web/WebCameraUtils';\nimport { PictureSizes } from './web/WebConstants';\nimport { useWebBarcodeScanner } from './web/useWebBarcodeScanner';\nimport { useWebCameraStream } from './web/useWebCameraStream';\n\nexport interface ExponentCameraRef {\n getAvailablePictureSizes: (ratio: string) => Promise;\n takePicture: (options: CameraPictureOptions) => Promise;\n resumePreview: () => Promise;\n pausePreview: () => Promise;\n}\n\nconst ExponentCamera = ({\n facing,\n poster,\n ref,\n ...props\n}: PropsWithChildren) => {\n const video = useRef(null);\n\n const cameraSettings = useMemo(() => {\n return {\n ...props,\n flashMode: props.enableTorch ? 'torch' : props.flashMode,\n };\n }, [props.enableTorch, props.flashMode, props.zoom, props.autoFocus]);\n\n const native = useWebCameraStream(video, facing as CameraType, cameraSettings, {\n onCameraReady() {\n if (props.onCameraReady) {\n props.onCameraReady();\n }\n },\n onMountError: props.onMountError,\n });\n\n const barcodeTypes = props.barcodeScannerSettings?.barcodeTypes;\n\n const isScannerEnabled = useMemo(() => {\n return Boolean(barcodeTypes?.length && !!props.onBarcodeScanned);\n }, [barcodeTypes, props.onBarcodeScanned]);\n\n useWebBarcodeScanner(video, {\n interval: 300,\n isEnabled: isScannerEnabled,\n barcodeTypes: barcodeTypes ?? [],\n isMirrored: native.type === 'front',\n onScanned(event) {\n if (props.onBarcodeScanned) {\n props.onBarcodeScanned(event);\n }\n },\n });\n\n useImperativeHandle(\n ref,\n () => ({\n async getAvailablePictureSizes(): Promise {\n return PictureSizes;\n },\n async takePicture(options: CameraPictureOptions): Promise {\n if (!video.current || video.current?.readyState !== video.current?.HAVE_ENOUGH_DATA) {\n throw new CodedError(\n 'ERR_CAMERA_NOT_READY',\n 'HTMLVideoElement does not have enough camera data to construct an image yet.'\n );\n }\n const settings = native.mediaTrackSettings;\n if (!settings) {\n throw new CodedError('ERR_CAMERA_NOT_READY', 'MediaStream is not ready yet.');\n }\n\n return capture(video.current, settings, {\n ...options,\n // This will always be defined, the option gets added to a queue in the upper-level. We should replace the original so it isn't called twice.\n onPictureSaved(picture) {\n if (options.onPictureSaved) {\n options.onPictureSaved(picture);\n }\n if (props.onPictureSaved) {\n props.onPictureSaved({ nativeEvent: { data: picture, id: -1 } });\n }\n },\n });\n },\n async resumePreview(): Promise {\n if (video.current) {\n video.current.play();\n }\n },\n async pausePreview(): Promise {\n if (video.current) {\n video.current.pause();\n }\n },\n async stopRecording(): Promise {\n console.warn('stopRecording is not supported on web.');\n },\n async record(): Promise<{ uri: string }> {\n console.warn('record is not supported on web.');\n return { uri: '' };\n },\n async toggleRecording() {\n console.warn('toggleRecording is not supported on web.');\n },\n async launchModernScanner() {\n console.warn('launchModernScanner is not supported on web.');\n },\n async getAvailableLenses() {\n console.warn('getAvailableLenses is not supported on web.');\n return [];\n },\n }),\n [native.mediaTrackSettings, props.onPictureSaved]\n );\n\n // TODO(Bacon): Create a universal prop, on native the microphone is only used when recording videos.\n // Because we don't support recording video in the browser we don't need the user to give microphone permissions.\n const isMuted = true;\n\n const style = useMemo>(() => {\n const isFrontFacingCamera = native.type === CameraManager.Type.front;\n return [\n StyleSheet.absoluteFill,\n styles.video,\n {\n pointerEvents: props.pointerEvents,\n // Flip the camera\n transform: isFrontFacingCamera ? [{ scaleX: -1 }] : undefined,\n },\n ];\n }, [props.pointerEvents, native.type]);\n\n return (\n \n \n );\n};\n\nexport default ExponentCamera;\n\nconst Video = (\n props: ComponentProps & {\n autoPlay?: boolean;\n playsInline?: boolean;\n muted?: boolean;\n poster?: string;\n ref: Ref;\n }\n) => createElement('video', { ...props });\n\nconst styles = StyleSheet.create({\n videoWrapper: {\n flex: 1,\n alignItems: 'stretch',\n pointerEvents: 'box-none',\n },\n video: {\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n },\n});\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/ExpoCameraManager.web.d.ts b/packages/expo-camera/build/ExpoCameraManager.web.d.ts index 89e6681ce8055a..5b078cd5e148e8 100644 --- a/packages/expo-camera/build/ExpoCameraManager.web.d.ts +++ b/packages/expo-camera/build/ExpoCameraManager.web.d.ts @@ -1,6 +1,11 @@ -import { CameraCapturedPicture, CameraPictureOptions, PermissionResponse } from './Camera.types'; +import { BarcodeType, BarcodeScanningResult, CameraCapturedPicture, CameraPictureOptions, PermissionResponse } from './Camera.types'; import { ExponentCameraRef } from './ExpoCamera.web'; declare const _default: { + isModernBarcodeScannerAvailable: boolean; + toggleRecordingAsyncAvailable: boolean; + addListener(_eventName: string, _listener: (...args: any[]) => any): { + remove: () => void; + }; readonly Type: { back: string; front: string; @@ -37,6 +42,7 @@ declare const _default: { requestCameraPermissionsAsync(): Promise; getMicrophonePermissionsAsync(): Promise; requestMicrophonePermissionsAsync(): Promise; + scanFromURLAsync(url: string, barcodeTypes?: BarcodeType[]): Promise; }; export default _default; //# sourceMappingURL=ExpoCameraManager.web.d.ts.map \ No newline at end of file diff --git a/packages/expo-camera/build/ExpoCameraManager.web.d.ts.map b/packages/expo-camera/build/ExpoCameraManager.web.d.ts.map index 0cc98a0288cf5b..4e7604d727df3a 100644 --- a/packages/expo-camera/build/ExpoCameraManager.web.d.ts.map +++ b/packages/expo-camera/build/ExpoCameraManager.web.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"ExpoCameraManager.web.d.ts","sourceRoot":"","sources":["../src/ExpoCameraManager.web.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAEnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;wBAoKzB,OAAO,CAAC,OAAO,CAAC;yBAI/B,oBAAoB,UACrB,iBAAiB,GACxB,OAAO,CAAC,qBAAqB,CAAC;yBAGN,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;0BAGhC,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;oCAGvB,OAAO,CAAC,MAAM,EAAE,CAAC;oCAYjB,MAAM,UAAU,iBAAiB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;2BAa9D,OAAO,CAAC,kBAAkB,CAAC;+BAGvB,OAAO,CAAC,kBAAkB,CAAC;iCAGzB,OAAO,CAAC,kBAAkB,CAAC;qCAGvB,OAAO,CAAC,kBAAkB,CAAC;qCAG3B,OAAO,CAAC,kBAAkB,CAAC;yCAGvB,OAAO,CAAC,kBAAkB,CAAC;;AA5FxE,wBA2GE"} \ No newline at end of file +{"version":3,"file":"ExpoCameraManager.web.d.ts","sourceRoot":"","sources":["../src/ExpoCameraManager.web.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAEnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;;;;4BA0G3B,MAAM,aAAa,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAuCxC,OAAO,CAAC,OAAO,CAAC;yBAI/B,oBAAoB,UACrB,iBAAiB,GACxB,OAAO,CAAC,qBAAqB,CAAC;yBAGN,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;0BAGhC,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;oCAGvB,OAAO,CAAC,MAAM,EAAE,CAAC;oCAYjB,MAAM,UAAU,iBAAiB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;2BAa9D,OAAO,CAAC,kBAAkB,CAAC;+BAGvB,OAAO,CAAC,kBAAkB,CAAC;iCAGzB,OAAO,CAAC,kBAAkB,CAAC;qCAGvB,OAAO,CAAC,kBAAkB,CAAC;qCAG3B,OAAO,CAAC,kBAAkB,CAAC;yCAGvB,OAAO,CAAC,kBAAkB,CAAC;0BAgB/D,MAAM,iBACI,WAAW,EAAE,GAC3B,OAAO,CAAC,qBAAqB,EAAE,CAAC;;AAnHrC,wBA6HE"} \ No newline at end of file diff --git a/packages/expo-camera/build/ExpoCameraManager.web.js b/packages/expo-camera/build/ExpoCameraManager.web.js index b200fb29f70f06..3f7c8ba89fc116 100644 --- a/packages/expo-camera/build/ExpoCameraManager.web.js +++ b/packages/expo-camera/build/ExpoCameraManager.web.js @@ -1,31 +1,9 @@ import { UnavailabilityError } from 'expo-modules-core'; import { PermissionStatus, } from './Camera.types'; +import * as WebBarcodeScanner from './web/WebBarcodeScanner'; import { canGetUserMedia, isBackCameraAvailableAsync, isFrontCameraAvailableAsync, } from './web/WebUserMediaManager'; function getUserMedia(constraints) { - if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - return navigator.mediaDevices.getUserMedia(constraints); - } - // Some browsers partially implement mediaDevices. We can't just assign an object - // with getUserMedia as it would overwrite existing properties. - // Here, we will just add the getUserMedia property if it's missing. - // First get ahold of the legacy getUserMedia, if present - const getUserMedia = - // TODO: this method is deprecated, migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia - navigator.getUserMedia || - navigator.webkitGetUserMedia || - navigator.mozGetUserMedia || - function () { - const error = new Error('Permission unimplemented'); - error.code = 0; - error.name = 'NotAllowedError'; - throw error; - }; - return new Promise((resolve, reject) => { - // TODO(@kitten): The types indicates that this is incorrect. - // Please check whether this is correct! - // @ts-expect-error: The `successCallback` doesn't match a `resolve` function - getUserMedia.call(navigator, constraints, resolve, reject); - }); + return navigator.mediaDevices.getUserMedia(constraints); } function handleGetUserMediaError({ message }) { // name: NotAllowedError @@ -116,6 +94,11 @@ async function handlePermissionsQueryAsync(query) { } } export default { + isModernBarcodeScannerAvailable: false, + toggleRecordingAsyncAvailable: false, + addListener(_eventName, _listener) { + return { remove: () => { } }; + }, get Type() { return { back: 'back', @@ -218,5 +201,14 @@ export default { return handleGetUserMediaError(error.message); } }, + async scanFromURLAsync(url, barcodeTypes) { + const response = await fetch(url); + const blob = await response.blob(); + const bitmap = await createImageBitmap(blob); + const types = barcodeTypes && barcodeTypes.length > 0 ? barcodeTypes : WebBarcodeScanner.ALL_BARCODE_TYPES; + const results = await WebBarcodeScanner.detect(bitmap, types); + bitmap.close(); + return results; + }, }; //# sourceMappingURL=ExpoCameraManager.web.js.map \ No newline at end of file diff --git a/packages/expo-camera/build/ExpoCameraManager.web.js.map b/packages/expo-camera/build/ExpoCameraManager.web.js.map index 7d29e915ad2d63..fd5dfc0b025bac 100644 --- a/packages/expo-camera/build/ExpoCameraManager.web.js.map +++ b/packages/expo-camera/build/ExpoCameraManager.web.js.map @@ -1 +1 @@ -{"version":3,"file":"ExpoCameraManager.web.js","sourceRoot":"","sources":["../src/ExpoCameraManager.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport {\n CameraCapturedPicture,\n CameraPictureOptions,\n PermissionResponse,\n PermissionStatus,\n} from './Camera.types';\nimport { ExponentCameraRef } from './ExpoCamera.web';\nimport {\n canGetUserMedia,\n isBackCameraAvailableAsync,\n isFrontCameraAvailableAsync,\n} from './web/WebUserMediaManager';\n\nfunction getUserMedia(constraints: MediaStreamConstraints): Promise {\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n return navigator.mediaDevices.getUserMedia(constraints);\n }\n\n // Some browsers partially implement mediaDevices. We can't just assign an object\n // with getUserMedia as it would overwrite existing properties.\n // Here, we will just add the getUserMedia property if it's missing.\n\n // First get ahold of the legacy getUserMedia, if present\n const getUserMedia =\n // TODO: this method is deprecated, migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia\n navigator.getUserMedia ||\n navigator.webkitGetUserMedia ||\n navigator.mozGetUserMedia ||\n function () {\n const error: any = new Error('Permission unimplemented');\n error.code = 0;\n error.name = 'NotAllowedError';\n throw error;\n };\n return new Promise((resolve, reject) => {\n // TODO(@kitten): The types indicates that this is incorrect.\n // Please check whether this is correct!\n // @ts-expect-error: The `successCallback` doesn't match a `resolve` function\n getUserMedia.call(navigator, constraints, resolve, reject);\n });\n}\n\nfunction handleGetUserMediaError({ message }: { message: string }): PermissionResponse {\n // name: NotAllowedError\n // code: 0\n if (message === 'Permission dismissed') {\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n } else {\n // TODO: Bacon: [OSX] The system could deny access to chrome.\n // TODO: Bacon: add: { status: 'unimplemented' }\n return {\n status: PermissionStatus.DENIED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n}\n\nasync function handleRequestPermissionsAsync(): Promise {\n try {\n const streams = await getUserMedia({\n video: true,\n });\n // We need to close the media stream returned by getUserMedia\n // to avoid using the camera since we won't use these streams now\n // https://developer.mozilla.org/fr/docs/Web/API/MediaDevices/getUserMedia\n streams.getTracks().forEach((track) => {\n track.stop();\n streams.removeTrack(track);\n });\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n } catch (error: any) {\n return handleGetUserMediaError(error.message);\n }\n}\n\nasync function handlePermissionsQueryAsync(\n query: 'camera' | 'microphone'\n): Promise {\n if (!navigator?.permissions?.query) {\n throw new UnavailabilityError('expo-camera', 'navigator.permissions API is not available');\n }\n\n try {\n const { state } = await navigator.permissions.query({ name: query });\n switch (state) {\n case 'prompt':\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n case 'granted':\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n case 'denied':\n return {\n status: PermissionStatus.DENIED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n } catch (e) {\n // Firefox doesn't support querying for the camera permission, so return undetermined status\n if (e instanceof TypeError) {\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n throw e;\n }\n}\n\nexport default {\n get Type() {\n return {\n back: 'back',\n front: 'front',\n };\n },\n get FlashMode() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n torch: 'torch',\n screen: 'on',\n };\n },\n get AutoFocus() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n singleShot: 'singleShot',\n };\n },\n get WhiteBalance() {\n return {\n auto: 'auto',\n continuous: 'continuous',\n manual: 'manual',\n };\n },\n get VideoQuality() {\n return {};\n },\n get VideoStabilization() {\n return {};\n },\n async isAvailableAsync(): Promise {\n return canGetUserMedia();\n },\n async takePicture(\n options: CameraPictureOptions,\n camera: ExponentCameraRef\n ): Promise {\n return await camera.takePicture(options);\n },\n async pausePreview(camera: ExponentCameraRef): Promise {\n await camera.pausePreview();\n },\n async resumePreview(camera: ExponentCameraRef): Promise {\n return await camera.resumePreview();\n },\n async getAvailableCameraTypesAsync(): Promise {\n if (!canGetUserMedia() || !navigator.mediaDevices.enumerateDevices) return [];\n\n const devices = await navigator.mediaDevices.enumerateDevices();\n\n const types: (string | null)[] = await Promise.all([\n (await isFrontCameraAvailableAsync(devices)) && 'front',\n (await isBackCameraAvailableAsync()) && 'back',\n ]);\n\n return types.filter(Boolean) as string[];\n },\n async getAvailablePictureSizes(ratio: string, camera: ExponentCameraRef): Promise {\n return await camera.getAvailablePictureSizes(ratio);\n },\n /*\n async record(\n options?: CameraRecordingOptions,\n camera: ExponentCameraRef\n ): Promise<{ uri: string }> {\n // TODO: Support on web\n },\n async stopRecording(camera: ExponentCameraRef): Promise {\n // TODO: Support on web\n }, */\n async getPermissionsAsync(): Promise {\n return handlePermissionsQueryAsync('camera');\n },\n async requestPermissionsAsync(): Promise {\n return handleRequestPermissionsAsync();\n },\n async getCameraPermissionsAsync(): Promise {\n return handlePermissionsQueryAsync('camera');\n },\n async requestCameraPermissionsAsync(): Promise {\n return handleRequestPermissionsAsync();\n },\n async getMicrophonePermissionsAsync(): Promise {\n return handlePermissionsQueryAsync('microphone');\n },\n async requestMicrophonePermissionsAsync(): Promise {\n try {\n await getUserMedia({\n audio: true,\n });\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n } catch (error: any) {\n return handleGetUserMediaError(error.message);\n }\n },\n};\n"]} \ No newline at end of file +{"version":3,"file":"ExpoCameraManager.web.js","sourceRoot":"","sources":["../src/ExpoCameraManager.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAML,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,eAAe,EACf,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,2BAA2B,CAAC;AAEnC,SAAS,YAAY,CAAC,WAAmC;IACvD,OAAO,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,uBAAuB,CAAC,EAAE,OAAO,EAAuB;IAC/D,wBAAwB;IACxB,UAAU;IACV,IAAI,OAAO,KAAK,sBAAsB,EAAE,CAAC;QACvC,OAAO;YACL,MAAM,EAAE,gBAAgB,CAAC,YAAY;YACrC,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,6DAA6D;QAC7D,gDAAgD;QAChD,OAAO;YACL,MAAM,EAAE,gBAAgB,CAAC,MAAM;YAC/B,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,6BAA6B;IAC1C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC;YACjC,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QACH,6DAA6D;QAC7D,iEAAiE;QACjE,0EAA0E;QAC1E,OAAO,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,IAAI,EAAE,CAAC;YACb,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,OAAO;YACL,MAAM,EAAE,gBAAgB,CAAC,OAAO;YAChC,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,KAA8B;IAE9B,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QACnC,MAAM,IAAI,mBAAmB,CAAC,aAAa,EAAE,4CAA4C,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACrE,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,QAAQ;gBACX,OAAO;oBACL,MAAM,EAAE,gBAAgB,CAAC,YAAY;oBACrC,OAAO,EAAE,OAAO;oBAChB,WAAW,EAAE,IAAI;oBACjB,OAAO,EAAE,KAAK;iBACf,CAAC;YACJ,KAAK,SAAS;gBACZ,OAAO;oBACL,MAAM,EAAE,gBAAgB,CAAC,OAAO;oBAChC,OAAO,EAAE,OAAO;oBAChB,WAAW,EAAE,IAAI;oBACjB,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,KAAK,QAAQ;gBACX,OAAO;oBACL,MAAM,EAAE,gBAAgB,CAAC,MAAM;oBAC/B,OAAO,EAAE,OAAO;oBAChB,WAAW,EAAE,IAAI;oBACjB,OAAO,EAAE,KAAK;iBACf,CAAC;QACN,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,4FAA4F;QAC5F,IAAI,CAAC,YAAY,SAAS,EAAE,CAAC;YAC3B,OAAO;gBACL,MAAM,EAAE,gBAAgB,CAAC,YAAY;gBACrC,OAAO,EAAE,OAAO;gBAChB,WAAW,EAAE,IAAI;gBACjB,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,eAAe;IACb,+BAA+B,EAAE,KAAK;IACtC,6BAA6B,EAAE,KAAK;IACpC,WAAW,CAAC,UAAkB,EAAE,SAAkC;QAChE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;IAC9B,CAAC;IACD,IAAI,IAAI;QACN,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;SACf,CAAC;IACJ,CAAC;IACD,IAAI,SAAS;QACX,OAAO;YACL,EAAE,EAAE,IAAI;YACR,GAAG,EAAE,KAAK;YACV,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,IAAI;SACb,CAAC;IACJ,CAAC;IACD,IAAI,SAAS;QACX,OAAO;YACL,EAAE,EAAE,IAAI;YACR,GAAG,EAAE,KAAK;YACV,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,YAAY;SACzB,CAAC;IACJ,CAAC;IACD,IAAI,YAAY;QACd,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,YAAY;YACxB,MAAM,EAAE,QAAQ;SACjB,CAAC;IACJ,CAAC;IACD,IAAI,YAAY;QACd,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,kBAAkB;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,gBAAgB;QACpB,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;IACD,KAAK,CAAC,WAAW,CACf,OAA6B,EAC7B,MAAyB;QAEzB,OAAO,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IACD,KAAK,CAAC,YAAY,CAAC,MAAyB;QAC1C,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;IAC9B,CAAC;IACD,KAAK,CAAC,aAAa,CAAC,MAAyB;QAC3C,OAAO,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;IACD,KAAK,CAAC,4BAA4B;QAChC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,gBAAgB;YAAE,OAAO,EAAE,CAAC;QAE9E,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;QAEhE,MAAM,KAAK,GAAsB,MAAM,OAAO,CAAC,GAAG,CAAC;YACjD,CAAC,MAAM,2BAA2B,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO;YACvD,CAAC,MAAM,0BAA0B,EAAE,CAAC,IAAI,MAAM;SAC/C,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;IAC3C,CAAC;IACD,KAAK,CAAC,wBAAwB,CAAC,KAAa,EAAE,MAAyB;QACrE,OAAO,MAAM,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;IACD;;;;;;;;;SASK;IACL,KAAK,CAAC,mBAAmB;QACvB,OAAO,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IACD,KAAK,CAAC,uBAAuB;QAC3B,OAAO,6BAA6B,EAAE,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,yBAAyB;QAC7B,OAAO,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IACD,KAAK,CAAC,6BAA6B;QACjC,OAAO,6BAA6B,EAAE,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,6BAA6B;QACjC,OAAO,2BAA2B,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC;IACD,KAAK,CAAC,iCAAiC;QACrC,IAAI,CAAC;YACH,MAAM,YAAY,CAAC;gBACjB,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;YACH,OAAO;gBACL,MAAM,EAAE,gBAAgB,CAAC,OAAO;gBAChC,OAAO,EAAE,OAAO;gBAChB,WAAW,EAAE,IAAI;gBACjB,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IACD,KAAK,CAAC,gBAAgB,CACpB,GAAW,EACX,YAA4B;QAE5B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,KAAK,GACT,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;QAC/F,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC9D,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport {\n BarcodeType,\n BarcodeScanningResult,\n CameraCapturedPicture,\n CameraPictureOptions,\n PermissionResponse,\n PermissionStatus,\n} from './Camera.types';\nimport { ExponentCameraRef } from './ExpoCamera.web';\nimport * as WebBarcodeScanner from './web/WebBarcodeScanner';\nimport {\n canGetUserMedia,\n isBackCameraAvailableAsync,\n isFrontCameraAvailableAsync,\n} from './web/WebUserMediaManager';\n\nfunction getUserMedia(constraints: MediaStreamConstraints): Promise {\n return navigator.mediaDevices.getUserMedia(constraints);\n}\n\nfunction handleGetUserMediaError({ message }: { message: string }): PermissionResponse {\n // name: NotAllowedError\n // code: 0\n if (message === 'Permission dismissed') {\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n } else {\n // TODO: Bacon: [OSX] The system could deny access to chrome.\n // TODO: Bacon: add: { status: 'unimplemented' }\n return {\n status: PermissionStatus.DENIED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n}\n\nasync function handleRequestPermissionsAsync(): Promise {\n try {\n const streams = await getUserMedia({\n video: true,\n });\n // We need to close the media stream returned by getUserMedia\n // to avoid using the camera since we won't use these streams now\n // https://developer.mozilla.org/fr/docs/Web/API/MediaDevices/getUserMedia\n streams.getTracks().forEach((track) => {\n track.stop();\n streams.removeTrack(track);\n });\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n } catch (error: any) {\n return handleGetUserMediaError(error.message);\n }\n}\n\nasync function handlePermissionsQueryAsync(\n query: 'camera' | 'microphone'\n): Promise {\n if (!navigator?.permissions?.query) {\n throw new UnavailabilityError('expo-camera', 'navigator.permissions API is not available');\n }\n\n try {\n const { state } = await navigator.permissions.query({ name: query });\n switch (state) {\n case 'prompt':\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n case 'granted':\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n case 'denied':\n return {\n status: PermissionStatus.DENIED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n } catch (e) {\n // Firefox doesn't support querying for the camera permission, so return undetermined status\n if (e instanceof TypeError) {\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n throw e;\n }\n}\n\nexport default {\n isModernBarcodeScannerAvailable: false,\n toggleRecordingAsyncAvailable: false,\n addListener(_eventName: string, _listener: (...args: any[]) => any) {\n return { remove: () => {} };\n },\n get Type() {\n return {\n back: 'back',\n front: 'front',\n };\n },\n get FlashMode() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n torch: 'torch',\n screen: 'on',\n };\n },\n get AutoFocus() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n singleShot: 'singleShot',\n };\n },\n get WhiteBalance() {\n return {\n auto: 'auto',\n continuous: 'continuous',\n manual: 'manual',\n };\n },\n get VideoQuality() {\n return {};\n },\n get VideoStabilization() {\n return {};\n },\n async isAvailableAsync(): Promise {\n return canGetUserMedia();\n },\n async takePicture(\n options: CameraPictureOptions,\n camera: ExponentCameraRef\n ): Promise {\n return await camera.takePicture(options);\n },\n async pausePreview(camera: ExponentCameraRef): Promise {\n await camera.pausePreview();\n },\n async resumePreview(camera: ExponentCameraRef): Promise {\n return await camera.resumePreview();\n },\n async getAvailableCameraTypesAsync(): Promise {\n if (!canGetUserMedia() || !navigator.mediaDevices.enumerateDevices) return [];\n\n const devices = await navigator.mediaDevices.enumerateDevices();\n\n const types: (string | null)[] = await Promise.all([\n (await isFrontCameraAvailableAsync(devices)) && 'front',\n (await isBackCameraAvailableAsync()) && 'back',\n ]);\n\n return types.filter(Boolean) as string[];\n },\n async getAvailablePictureSizes(ratio: string, camera: ExponentCameraRef): Promise {\n return await camera.getAvailablePictureSizes(ratio);\n },\n /*\n async record(\n options?: CameraRecordingOptions,\n camera: ExponentCameraRef\n ): Promise<{ uri: string }> {\n // TODO: Support on web\n },\n async stopRecording(camera: ExponentCameraRef): Promise {\n // TODO: Support on web\n }, */\n async getPermissionsAsync(): Promise {\n return handlePermissionsQueryAsync('camera');\n },\n async requestPermissionsAsync(): Promise {\n return handleRequestPermissionsAsync();\n },\n async getCameraPermissionsAsync(): Promise {\n return handlePermissionsQueryAsync('camera');\n },\n async requestCameraPermissionsAsync(): Promise {\n return handleRequestPermissionsAsync();\n },\n async getMicrophonePermissionsAsync(): Promise {\n return handlePermissionsQueryAsync('microphone');\n },\n async requestMicrophonePermissionsAsync(): Promise {\n try {\n await getUserMedia({\n audio: true,\n });\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n } catch (error: any) {\n return handleGetUserMediaError(error.message);\n }\n },\n async scanFromURLAsync(\n url: string,\n barcodeTypes?: BarcodeType[]\n ): Promise {\n const response = await fetch(url);\n const blob = await response.blob();\n const bitmap = await createImageBitmap(blob);\n const types: BarcodeType[] =\n barcodeTypes && barcodeTypes.length > 0 ? barcodeTypes : WebBarcodeScanner.ALL_BARCODE_TYPES;\n const results = await WebBarcodeScanner.detect(bitmap, types);\n bitmap.close();\n return results;\n },\n};\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/web/WebBarcodeScanner.d.ts b/packages/expo-camera/build/web/WebBarcodeScanner.d.ts new file mode 100644 index 00000000000000..2cc17a8d78b34b --- /dev/null +++ b/packages/expo-camera/build/web/WebBarcodeScanner.d.ts @@ -0,0 +1,4 @@ +import type { BarcodeType, BarcodeScanningResult } from '../Camera.types'; +export declare const ALL_BARCODE_TYPES: BarcodeType[]; +export declare function detect(source: ImageBitmapSource, barcodeTypes: BarcodeType[]): Promise; +//# sourceMappingURL=WebBarcodeScanner.d.ts.map \ No newline at end of file diff --git a/packages/expo-camera/build/web/WebBarcodeScanner.d.ts.map b/packages/expo-camera/build/web/WebBarcodeScanner.d.ts.map new file mode 100644 index 00000000000000..ccd35a14bd9351 --- /dev/null +++ b/packages/expo-camera/build/web/WebBarcodeScanner.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"WebBarcodeScanner.d.ts","sourceRoot":"","sources":["../../src/web/WebBarcodeScanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA0B1E,eAAO,MAAM,iBAAiB,EAAsC,WAAW,EAAE,CAAC;AAgDlF,wBAAsB,MAAM,CAC1B,MAAM,EAAE,iBAAiB,EACzB,YAAY,EAAE,WAAW,EAAE,GAC1B,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAgBlC"} \ No newline at end of file diff --git a/packages/expo-camera/build/web/WebBarcodeScanner.js b/packages/expo-camera/build/web/WebBarcodeScanner.js new file mode 100644 index 00000000000000..43a7dd6cae1fbe --- /dev/null +++ b/packages/expo-camera/build/web/WebBarcodeScanner.js @@ -0,0 +1,67 @@ +/** + * Mapping from expo BarcodeType to BarcodeDetector format string. + * @see https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API#supported_barcode_formats + */ +const EXPO_TO_WEB_FORMAT = { + aztec: 'aztec', + codabar: 'codabar', + code39: 'code_39', + code93: 'code_93', + code128: 'code_128', + datamatrix: 'data_matrix', + ean8: 'ean_8', + ean13: 'ean_13', + itf14: 'itf', + pdf417: 'pdf417', + qr: 'qr_code', + upc_a: 'upc_a', + upc_e: 'upc_e', +}; +const WEB_TO_EXPO_FORMAT = Object.fromEntries(Object.entries(EXPO_TO_WEB_FORMAT).map(([expo, web]) => [web, expo])); +export const ALL_BARCODE_TYPES = Object.keys(EXPO_TO_WEB_FORMAT); +let cachedDetector = null; +let cachedFormats = null; +function formatsChanged(barcodeTypes) { + const webFormats = barcodeTypes.map((t) => EXPO_TO_WEB_FORMAT[t]).sort(); + if (!cachedFormats) { + return true; + } + if (cachedFormats.length !== webFormats.length) { + return true; + } + return webFormats.some((f, i) => f !== cachedFormats[i]); +} +async function getDetector(barcodeTypes) { + if (cachedDetector && !formatsChanged(barcodeTypes)) { + return cachedDetector; + } + const webFormats = barcodeTypes.map((t) => EXPO_TO_WEB_FORMAT[t]); + cachedFormats = [...webFormats].sort(); + const NativeBarcodeDetector = globalThis.BarcodeDetector; + if (typeof NativeBarcodeDetector !== 'undefined') { + const detector = new NativeBarcodeDetector({ formats: webFormats }); + cachedDetector = detector; + return detector; + } + const { BarcodeDetector } = await import('barcode-detector'); + const detector = new BarcodeDetector({ formats: webFormats }); + cachedDetector = detector; + return detector; +} +export async function detect(source, barcodeTypes) { + const detector = await getDetector(barcodeTypes); + const barcodes = await detector.detect(source); + return barcodes.map((barcode) => { + const { x, y, width, height } = barcode.boundingBox; + return { + type: WEB_TO_EXPO_FORMAT[barcode.format] ?? barcode.format, + data: barcode.rawValue, + bounds: { + origin: { x, y }, + size: { width, height }, + }, + cornerPoints: barcode.cornerPoints?.map((p) => ({ x: p.x, y: p.y })) ?? [], + }; + }); +} +//# sourceMappingURL=WebBarcodeScanner.js.map \ No newline at end of file diff --git a/packages/expo-camera/build/web/WebBarcodeScanner.js.map b/packages/expo-camera/build/web/WebBarcodeScanner.js.map new file mode 100644 index 00000000000000..d6d5454e35040a --- /dev/null +++ b/packages/expo-camera/build/web/WebBarcodeScanner.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WebBarcodeScanner.js","sourceRoot":"","sources":["../../src/web/WebBarcodeScanner.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BarcodeType, BarcodeScanningResult } from '../Camera.types';\n\n/**\n * Mapping from expo BarcodeType to BarcodeDetector format string.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API#supported_barcode_formats\n */\nconst EXPO_TO_WEB_FORMAT: Record = {\n aztec: 'aztec',\n codabar: 'codabar',\n code39: 'code_39',\n code93: 'code_93',\n code128: 'code_128',\n datamatrix: 'data_matrix',\n ean8: 'ean_8',\n ean13: 'ean_13',\n itf14: 'itf',\n pdf417: 'pdf417',\n qr: 'qr_code',\n upc_a: 'upc_a',\n upc_e: 'upc_e',\n};\n\nconst WEB_TO_EXPO_FORMAT: Record = Object.fromEntries(\n Object.entries(EXPO_TO_WEB_FORMAT).map(([expo, web]) => [web, expo as BarcodeType])\n);\n\nexport const ALL_BARCODE_TYPES = Object.keys(EXPO_TO_WEB_FORMAT) as BarcodeType[];\n\ntype BarcodeDetectorLike = {\n detect(source: ImageBitmapSource): Promise;\n};\n\ntype DetectedBarcodeLike = {\n format: string;\n rawValue: string;\n boundingBox: DOMRectReadOnly;\n cornerPoints: { x: number; y: number }[];\n};\n\nlet cachedDetector: BarcodeDetectorLike | null = null;\nlet cachedFormats: string[] | null = null;\n\nfunction formatsChanged(barcodeTypes: BarcodeType[]): boolean {\n const webFormats = barcodeTypes.map((t) => EXPO_TO_WEB_FORMAT[t]).sort();\n if (!cachedFormats) {\n return true;\n }\n if (cachedFormats.length !== webFormats.length) {\n return true;\n }\n return webFormats.some((f, i) => f !== cachedFormats![i]);\n}\n\nasync function getDetector(barcodeTypes: BarcodeType[]): Promise {\n if (cachedDetector && !formatsChanged(barcodeTypes)) {\n return cachedDetector;\n }\n\n const webFormats = barcodeTypes.map((t) => EXPO_TO_WEB_FORMAT[t]);\n cachedFormats = [...webFormats].sort();\n\n const NativeBarcodeDetector = (globalThis as any).BarcodeDetector;\n if (typeof NativeBarcodeDetector !== 'undefined') {\n const detector: BarcodeDetectorLike = new NativeBarcodeDetector({ formats: webFormats });\n cachedDetector = detector;\n return detector;\n }\n\n const { BarcodeDetector } = await import('barcode-detector');\n const detector: BarcodeDetectorLike = new BarcodeDetector({ formats: webFormats as any });\n cachedDetector = detector;\n return detector;\n}\n\nexport async function detect(\n source: ImageBitmapSource,\n barcodeTypes: BarcodeType[]\n): Promise {\n const detector = await getDetector(barcodeTypes);\n const barcodes = await detector.detect(source);\n\n return barcodes.map((barcode) => {\n const { x, y, width, height } = barcode.boundingBox;\n return {\n type: WEB_TO_EXPO_FORMAT[barcode.format] ?? barcode.format,\n data: barcode.rawValue,\n bounds: {\n origin: { x, y },\n size: { width, height },\n },\n cornerPoints: barcode.cornerPoints?.map((p) => ({ x: p.x, y: p.y })) ?? [],\n };\n });\n}\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/web/WebCameraUtils.d.ts b/packages/expo-camera/build/web/WebCameraUtils.d.ts index 04032d4aea0d76..72fe34ce2f2926 100644 --- a/packages/expo-camera/build/web/WebCameraUtils.d.ts +++ b/packages/expo-camera/build/web/WebCameraUtils.d.ts @@ -8,7 +8,6 @@ interface ConstrainLongRange { export declare function getImageSize(videoWidth: number, videoHeight: number, scale: number): ImageSize; export declare function toDataURL(canvas: HTMLCanvasElement, imageType: ImageType, quality: number): string; export declare function hasValidConstraints(preferredCameraType?: CameraType, width?: number | ConstrainLongRange, height?: number | ConstrainLongRange): boolean; -export declare function captureImageData(video: HTMLVideoElement | null, pictureOptions?: Pick): ImageData | null; export declare function captureImageContext(video: HTMLVideoElement, { scale, isImageMirror }: Pick): HTMLCanvasElement; export declare function captureImage(video: HTMLVideoElement, pictureOptions: CameraPictureOptions): string; export declare function getIdealConstraints(preferredCameraType: CameraType, width?: number | ConstrainLongRange, height?: number | ConstrainLongRange): MediaStreamConstraints; @@ -26,7 +25,7 @@ export declare function compareStreams(a: MediaStream | null, b: MediaStream | n export declare function capture(video: HTMLVideoElement, settings: MediaTrackSettings, config: CameraPictureOptions): CameraCapturedPicture; export declare function syncTrackCapabilities(cameraType: CameraType, stream: MediaStream | null, settings?: WebCameraSettings): Promise; export declare function stopMediaStream(stream: MediaStream | null): void; -export declare function setVideoSource(video: HTMLVideoElement, stream: MediaStream | MediaSource | Blob | null): void; +export declare function setVideoSource(video: HTMLVideoElement, stream: MediaStream | null): void; export declare function isCapabilityAvailable(video: HTMLVideoElement, keyName: keyof MediaTrackCapabilities): boolean; export {}; //# sourceMappingURL=WebCameraUtils.d.ts.map \ No newline at end of file diff --git a/packages/expo-camera/build/web/WebCameraUtils.d.ts.map b/packages/expo-camera/build/web/WebCameraUtils.d.ts.map index c26abe11e8e08d..fc42b175f9cdb4 100644 --- a/packages/expo-camera/build/web/WebCameraUtils.d.ts.map +++ b/packages/expo-camera/build/web/WebCameraUtils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"WebCameraUtils.d.ts","sourceRoot":"","sources":["../../src/web/WebCameraUtils.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAEzB,UAAU,kBAAkB;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAS9F;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,CAiBR;AAED,wBAAgB,mBAAmB,CACjC,mBAAmB,CAAC,EAAE,UAAU,EAChC,KAAK,CAAC,EAAE,MAAM,GAAG,kBAAkB,EACnC,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,GACnC,OAAO,CAET;AAmBD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAC9B,cAAc,GAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,eAAe,CAAM,GACzE,SAAS,GAAG,IAAI,CAalB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,gBAAgB,EACvB,EAAE,KAAS,EAAE,aAAqB,EAAE,EAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,eAAe,CAAC,GAC1F,iBAAiB,CAyBnB;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,gBAAgB,EACvB,cAAc,EAAE,oBAAoB,GACnC,MAAM,CAKR;AASD,wBAAgB,mBAAmB,CACjC,mBAAmB,EAAE,UAAU,EAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,kBAAkB,EACnC,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,GACnC,sBAAsB,CAoCxB;AAMD;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,mBAAmB,EAAE,UAAU,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,kBAAkB,EAC5C,eAAe,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAC5C,OAAO,CAAC,WAAW,CAAC,CAYtB;AAED,wBAAsB,eAAe,CACnC,mBAAmB,EAAE,UAAU,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,kBAAkB,EAC5C,eAAe,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAC5C,OAAO,CAAC,WAAW,CAAC,CAQtB;AAED,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,EAAE,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAOpF;AAED,wBAAgB,OAAO,CACrB,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,oBAAoB,GAC3B,qBAAqB,CAsBvB;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,QAAQ,GAAE,iBAAsB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAMf;AAiFD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,QAazD;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,GAAG,IAAI,GAC9C,IAAI,CAkBN;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,MAAM,sBAAsB,GACpC,OAAO,CAST"} \ No newline at end of file +{"version":3,"file":"WebCameraUtils.d.ts","sourceRoot":"","sources":["../../src/web/WebCameraUtils.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAEzB,UAAU,kBAAkB;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAS9F;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,CAOR;AAED,wBAAgB,mBAAmB,CACjC,mBAAmB,CAAC,EAAE,UAAU,EAChC,KAAK,CAAC,EAAE,MAAM,GAAG,kBAAkB,EACnC,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,GACnC,OAAO,CAET;AAmBD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,gBAAgB,EACvB,EAAE,KAAS,EAAE,aAAqB,EAAE,EAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,eAAe,CAAC,GAC1F,iBAAiB,CAyBnB;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,gBAAgB,EACvB,cAAc,EAAE,oBAAoB,GACnC,MAAM,CAKR;AASD,wBAAgB,mBAAmB,CACjC,mBAAmB,EAAE,UAAU,EAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,kBAAkB,EACnC,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,GACnC,sBAAsB,CAoCxB;AAMD;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,mBAAmB,EAAE,UAAU,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,kBAAkB,EAC5C,eAAe,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAC5C,OAAO,CAAC,WAAW,CAAC,CAYtB;AAED,wBAAsB,eAAe,CACnC,mBAAmB,EAAE,UAAU,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,kBAAkB,EAC5C,eAAe,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAC5C,OAAO,CAAC,WAAW,CAAC,CAQtB;AAED,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,EAAE,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAOpF;AAED,wBAAgB,OAAO,CACrB,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,oBAAoB,GAC3B,qBAAqB,CAsBvB;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,QAAQ,GAAE,iBAAsB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAMf;AAiFD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,QAMzD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAExF;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,MAAM,sBAAsB,GACpC,OAAO,CAST"} \ No newline at end of file diff --git a/packages/expo-camera/build/web/WebCameraUtils.js b/packages/expo-camera/build/web/WebCameraUtils.js index 9701b69b5df268..a6a7ac48a855b2 100644 --- a/packages/expo-camera/build/web/WebCameraUtils.js +++ b/packages/expo-camera/build/web/WebCameraUtils.js @@ -1,5 +1,4 @@ /* eslint-env browser */ -import invariant from 'invariant'; import * as CapabilityUtils from './WebCapabilityUtils'; import { CameraTypeToFacingMode, ImageTypeFormat, MinimumConstraints } from './WebConstants'; import { requestUserMediaAsync } from './WebUserMediaManager'; @@ -13,11 +12,8 @@ export function getImageSize(videoWidth, videoHeight, scale) { }; } export function toDataURL(canvas, imageType, quality) { - const types = ['png', 'jpg']; - invariant(types.includes(imageType), `expo-camera: ${imageType} is not a valid ImageType. Expected a string from: ${types.join(', ')}`); const format = ImageTypeFormat[imageType]; if (imageType === 'jpg') { - invariant(quality <= 1 && quality >= 0, `expo-camera: ${quality} is not a valid image quality. Expected a number from 0...1`); return canvas.toDataURL(format, quality); } else { @@ -42,18 +38,6 @@ function ensureCameraPictureOptions(config) { return captureOptions; } const DEFAULT_QUALITY = 0.92; -export function captureImageData(video, pictureOptions = {}) { - if (!video || video.readyState !== video.HAVE_ENOUGH_DATA) { - return null; - } - const canvas = captureImageContext(video, pictureOptions); - const context = canvas.getContext('2d', { alpha: false }); - if (!context || !canvas.width || !canvas.height) { - return null; - } - const imageData = context.getImageData(0, 0, canvas.width, canvas.height); - return imageData; -} export function captureImageContext(video, { scale = 1, isImageMirror = false }) { const { videoWidth, videoHeight } = video; const { width, height } = getImageSize(videoWidth, videoHeight, scale); @@ -243,34 +227,11 @@ export function stopMediaStream(stream) { if (!stream) { return; } - if (stream.getAudioTracks) { - stream.getAudioTracks().forEach((track) => track.stop()); - } - if (stream.getVideoTracks) { - stream.getVideoTracks().forEach((track) => track.stop()); - } - if (isMediaStreamTrack(stream)) { - stream.stop(); - } + stream.getAudioTracks().forEach((track) => track.stop()); + stream.getVideoTracks().forEach((track) => track.stop()); } export function setVideoSource(video, stream) { - const createObjectURL = window.URL.createObjectURL ?? window.webkitURL.createObjectURL; - if (typeof video.srcObject !== 'undefined') { - video.srcObject = stream; - } - else if (typeof video.mozSrcObject !== 'undefined') { - video.mozSrcObject = stream; - } - else if (stream && createObjectURL) { - video.src = createObjectURL(stream); - } - if (!stream) { - const revokeObjectURL = window.URL.revokeObjectURL ?? window.webkitURL.revokeObjectURL; - const source = video.src ?? video.srcObject ?? video.mozSrcObject; - if (revokeObjectURL && typeof source === 'string') { - revokeObjectURL(source); - } - } + video.srcObject = stream; } export function isCapabilityAvailable(video, keyName) { const stream = video.srcObject; @@ -280,9 +241,6 @@ export function isCapabilityAvailable(video, keyName) { } return false; } -function isMediaStreamTrack(input) { - return typeof input.stop === 'function'; -} function convertNormalizedSetting(range, value) { if (!value) { return; diff --git a/packages/expo-camera/build/web/WebCameraUtils.js.map b/packages/expo-camera/build/web/WebCameraUtils.js.map index 2f5cbe102e7f5c..0e39c1d2863db8 100644 --- a/packages/expo-camera/build/web/WebCameraUtils.js.map +++ b/packages/expo-camera/build/web/WebCameraUtils.js.map @@ -1 +1 @@ -{"version":3,"file":"WebCameraUtils.js","sourceRoot":"","sources":["../../src/web/WebCameraUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\nimport invariant from 'invariant';\n\nimport * as CapabilityUtils from './WebCapabilityUtils';\nimport { CameraTypeToFacingMode, ImageTypeFormat, MinimumConstraints } from './WebConstants';\nimport { requestUserMediaAsync } from './WebUserMediaManager';\nimport {\n CameraType,\n CameraCapturedPicture,\n ImageSize,\n ImageType,\n WebCameraSettings,\n CameraPictureOptions,\n} from '../Camera.types';\n\ninterface ConstrainLongRange {\n max?: number;\n min?: number;\n exact?: number;\n ideal?: number;\n}\n\nexport function getImageSize(videoWidth: number, videoHeight: number, scale: number): ImageSize {\n const width = videoWidth * scale;\n const ratio = videoWidth / width;\n const height = videoHeight / ratio;\n\n return {\n width,\n height,\n };\n}\n\nexport function toDataURL(\n canvas: HTMLCanvasElement,\n imageType: ImageType,\n quality: number\n): string {\n const types = ['png', 'jpg'];\n invariant(\n types.includes(imageType),\n `expo-camera: ${imageType} is not a valid ImageType. Expected a string from: ${types.join(', ')}`\n );\n\n const format = ImageTypeFormat[imageType];\n if (imageType === 'jpg') {\n invariant(\n quality <= 1 && quality >= 0,\n `expo-camera: ${quality} is not a valid image quality. Expected a number from 0...1`\n );\n return canvas.toDataURL(format, quality);\n } else {\n return canvas.toDataURL(format);\n }\n}\n\nexport function hasValidConstraints(\n preferredCameraType?: CameraType,\n width?: number | ConstrainLongRange,\n height?: number | ConstrainLongRange\n): boolean {\n return preferredCameraType !== undefined && width !== undefined && height !== undefined;\n}\n\nfunction ensureCameraPictureOptions(config: CameraPictureOptions): CameraPictureOptions {\n const captureOptions: CameraPictureOptions = {\n scale: 1,\n imageType: 'png' as ImageType,\n isImageMirror: false,\n };\n for (const key in config) {\n const prop = key as keyof CameraPictureOptions;\n if (prop in config && config[prop] !== undefined && prop in captureOptions) {\n captureOptions[prop] = config[prop] as any;\n }\n }\n return captureOptions;\n}\n\nconst DEFAULT_QUALITY = 0.92;\n\nexport function captureImageData(\n video: HTMLVideoElement | null,\n pictureOptions: Pick = {}\n): ImageData | null {\n if (!video || video.readyState !== video.HAVE_ENOUGH_DATA) {\n return null;\n }\n const canvas = captureImageContext(video, pictureOptions);\n\n const context = canvas.getContext('2d', { alpha: false });\n if (!context || !canvas.width || !canvas.height) {\n return null;\n }\n\n const imageData = context.getImageData(0, 0, canvas.width, canvas.height);\n return imageData;\n}\n\nexport function captureImageContext(\n video: HTMLVideoElement,\n { scale = 1, isImageMirror = false }: Pick\n): HTMLCanvasElement {\n const { videoWidth, videoHeight } = video;\n const { width, height } = getImageSize(videoWidth, videoHeight, scale!);\n\n // Build the canvas size and draw the camera image to the context from video\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext('2d', { alpha: false });\n\n if (!context) {\n // Should never be called\n throw new Error('Context is not defined');\n }\n // sharp image details\n // context.imageSmoothingEnabled = false;\n\n // Flip horizontally (as css transform: rotateY(180deg))\n if (isImageMirror) {\n context.setTransform(-1, 0, 0, 1, canvas.width, 0);\n }\n\n context.drawImage(video, 0, 0, width, height);\n\n return canvas;\n}\n\nexport function captureImage(\n video: HTMLVideoElement,\n pictureOptions: CameraPictureOptions\n): string {\n const config = ensureCameraPictureOptions(pictureOptions);\n const canvas = captureImageContext(video, config);\n const { imageType, quality = DEFAULT_QUALITY } = config;\n return toDataURL(canvas, imageType!, quality);\n}\n\nfunction getSupportedConstraints(): MediaTrackSupportedConstraints | null {\n if (navigator.mediaDevices && navigator.mediaDevices.getSupportedConstraints) {\n return navigator.mediaDevices.getSupportedConstraints();\n }\n return null;\n}\n\nexport function getIdealConstraints(\n preferredCameraType: CameraType,\n width?: number | ConstrainLongRange,\n height?: number | ConstrainLongRange\n): MediaStreamConstraints {\n const preferredConstraints: MediaStreamConstraints = {\n audio: false,\n video: {},\n };\n\n if (hasValidConstraints(preferredCameraType, width, height)) {\n return MinimumConstraints;\n }\n\n const supports = getSupportedConstraints();\n // TODO(Bacon): Test this\n if (!supports || !supports.facingMode || !supports.width || !supports.height) {\n return MinimumConstraints;\n }\n const types = ['front', 'back'];\n if (preferredCameraType && types.includes(preferredCameraType)) {\n const facingMode = CameraTypeToFacingMode[preferredCameraType];\n if (isWebKit()) {\n const key = facingMode === 'user' ? 'exact' : 'ideal';\n (preferredConstraints.video as MediaTrackConstraints).facingMode = {\n [key]: facingMode,\n };\n } else {\n (preferredConstraints.video as MediaTrackConstraints).facingMode = {\n ideal: CameraTypeToFacingMode[preferredCameraType],\n };\n }\n }\n\n if (isMediaTrackConstraints(preferredConstraints.video)) {\n preferredConstraints.video.width = width;\n preferredConstraints.video.height = height;\n }\n\n return preferredConstraints;\n}\n\nfunction isMediaTrackConstraints(input: any): input is MediaTrackConstraints {\n return input && typeof input.video !== 'boolean';\n}\n\n/**\n * Invoke getStreamDevice a second time with the opposing camera type if the preferred type cannot be retrieved.\n *\n * @param preferredCameraType\n * @param preferredWidth\n * @param preferredHeight\n */\nexport async function getPreferredStreamDevice(\n preferredCameraType: CameraType,\n preferredWidth?: number | ConstrainLongRange,\n preferredHeight?: number | ConstrainLongRange\n): Promise {\n try {\n return await getStreamDevice(preferredCameraType, preferredWidth, preferredHeight);\n } catch (error) {\n // A hack on desktop browsers to ensure any camera is used.\n // eslint-disable-next-line no-undef\n if (error instanceof OverconstrainedError && error.constraint === 'facingMode') {\n const nextCameraType = preferredCameraType === 'back' ? 'front' : 'back';\n return await getStreamDevice(nextCameraType, preferredWidth, preferredHeight);\n }\n throw error;\n }\n}\n\nexport async function getStreamDevice(\n preferredCameraType: CameraType,\n preferredWidth?: number | ConstrainLongRange,\n preferredHeight?: number | ConstrainLongRange\n): Promise {\n const constraints: MediaStreamConstraints = getIdealConstraints(\n preferredCameraType,\n preferredWidth,\n preferredHeight\n );\n const stream: MediaStream = await requestUserMediaAsync(constraints);\n return stream;\n}\n\nexport function isWebKit(): boolean {\n return /WebKit/.test(navigator.userAgent) && !/Edg/.test(navigator.userAgent);\n}\n\nexport function compareStreams(a: MediaStream | null, b: MediaStream | null): boolean {\n if (!a || !b) {\n return false;\n }\n const settingsA = a.getTracks()[0].getSettings();\n const settingsB = b.getTracks()[0].getSettings();\n return settingsA.deviceId === settingsB.deviceId;\n}\n\nexport function capture(\n video: HTMLVideoElement,\n settings: MediaTrackSettings,\n config: CameraPictureOptions\n): CameraCapturedPicture {\n const base64 = captureImage(video, config);\n\n const capturedPicture: CameraCapturedPicture = {\n uri: base64,\n base64,\n width: 0,\n height: 0,\n format: config.imageType ?? 'jpg',\n };\n\n if (settings) {\n const { width = 0, height = 0 } = settings;\n capturedPicture.width = width;\n capturedPicture.height = height;\n capturedPicture.exif = settings;\n }\n\n if (config.onPictureSaved) {\n config.onPictureSaved(capturedPicture);\n }\n return capturedPicture;\n}\n\nexport async function syncTrackCapabilities(\n cameraType: CameraType,\n stream: MediaStream | null,\n settings: WebCameraSettings = {}\n): Promise {\n if (stream?.getVideoTracks) {\n await Promise.all(\n stream.getVideoTracks().map((track) => onCapabilitiesReady(cameraType, track, settings))\n );\n }\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints\nasync function onCapabilitiesReady(\n cameraType: CameraType,\n track: MediaStreamTrack,\n settings: WebCameraSettings = {}\n): Promise {\n if (typeof track.getCapabilities !== 'function') {\n return;\n }\n\n const capabilities = track.getCapabilities();\n\n // Create an empty object because if you set a constraint that isn't available an error will be thrown.\n const constraints: MediaTrackConstraintSet = {};\n\n // TODO(Bacon): Add `pointsOfInterest` support\n const clampedValues = [\n 'exposureCompensation',\n 'colorTemperature',\n 'iso',\n 'brightness',\n 'contrast',\n 'saturation',\n 'sharpness',\n 'focusDistance',\n 'zoom',\n ] as const;\n\n for (const property of clampedValues) {\n if (capabilities[property]) {\n constraints[property] = convertNormalizedSetting(capabilities[property], settings[property]);\n }\n }\n\n function validatedInternalConstrainedValue(\n constraintKey: keyof MediaTrackCapabilities,\n settingsKey: keyof WebCameraSettings,\n converter: (settingValue: any) => IConvertedType\n ) {\n const convertedSetting = converter(settings[settingsKey]);\n return validatedConstrainedValue({\n constraintKey,\n settingsKey,\n convertedSetting,\n capabilities,\n settings,\n cameraType,\n });\n }\n\n if (capabilities.focusMode && settings.autoFocus !== undefined) {\n constraints.focusMode = validatedInternalConstrainedValue(\n 'focusMode',\n 'autoFocus',\n CapabilityUtils.convertAutoFocusJSONToNative\n );\n }\n\n if (capabilities.torch && settings.flashMode !== undefined) {\n constraints.torch = validatedInternalConstrainedValue(\n 'torch',\n 'flashMode',\n CapabilityUtils.convertFlashModeJSONToNative\n );\n }\n\n if (capabilities.whiteBalanceMode && settings.whiteBalance !== undefined) {\n constraints.whiteBalanceMode = validatedInternalConstrainedValue<\n MediaTrackConstraintSet['whiteBalanceMode']\n >('whiteBalanceMode', 'whiteBalance', CapabilityUtils.convertWhiteBalanceJSONToNative);\n }\n\n try {\n await track.applyConstraints({ advanced: [constraints] });\n } catch (error) {\n if (__DEV__) console.warn('Failed to apply constraints', error);\n }\n}\n\nexport function stopMediaStream(stream: MediaStream | null) {\n if (!stream) {\n return;\n }\n if (stream.getAudioTracks) {\n stream.getAudioTracks().forEach((track) => track.stop());\n }\n if (stream.getVideoTracks) {\n stream.getVideoTracks().forEach((track) => track.stop());\n }\n if (isMediaStreamTrack(stream)) {\n stream.stop();\n }\n}\n\nexport function setVideoSource(\n video: HTMLVideoElement,\n stream: MediaStream | MediaSource | Blob | null\n): void {\n const createObjectURL = window.URL.createObjectURL ?? window.webkitURL.createObjectURL;\n\n if (typeof video.srcObject !== 'undefined') {\n video.srcObject = stream;\n } else if (typeof (video as any).mozSrcObject !== 'undefined') {\n (video as any).mozSrcObject = stream;\n } else if (stream && createObjectURL) {\n video.src = createObjectURL(stream as MediaSource | Blob);\n }\n\n if (!stream) {\n const revokeObjectURL = window.URL.revokeObjectURL ?? window.webkitURL.revokeObjectURL;\n const source = video.src ?? video.srcObject ?? (video as any).mozSrcObject;\n if (revokeObjectURL && typeof source === 'string') {\n revokeObjectURL(source);\n }\n }\n}\n\nexport function isCapabilityAvailable(\n video: HTMLVideoElement,\n keyName: keyof MediaTrackCapabilities\n): boolean {\n const stream = video.srcObject;\n\n if (stream instanceof MediaStream) {\n const videoTrack = stream.getVideoTracks()[0];\n return !!videoTrack.getCapabilities?.()?.[keyName];\n }\n\n return false;\n}\n\nfunction isMediaStreamTrack(input: any): input is MediaStreamTrack {\n return typeof input.stop === 'function';\n}\n\nfunction convertNormalizedSetting(range: MediaSettingsRange, value?: number): number | undefined {\n if (!value) {\n return;\n }\n // TODO(@kitten): Handle undefined values / normalize explicitly\n // convert the normalized incoming setting to the native camera zoom range\n const converted = convertRange(value, [range.min!, range.max!]);\n // clamp value so we don't get an error\n return Math.min(range.max!, Math.max(range.min!, converted));\n}\n\nfunction convertRange(value: number, r2: [number, number], r1: [number, number] = [0, 1]): number {\n return ((value - r1[0]) * (r2[1] - r2[0])) / (r1[1] - r1[0]) + r2[0];\n}\n\nfunction validatedConstrainedValue(props: {\n constraintKey: keyof MediaTrackCapabilities;\n settingsKey: keyof WebCameraSettings;\n convertedSetting: T;\n capabilities: MediaTrackCapabilities;\n settings: WebCameraSettings;\n cameraType: string;\n}): T | undefined {\n const { constraintKey, settingsKey, convertedSetting, capabilities, settings, cameraType } =\n props;\n const setting = settings[settingsKey];\n if (\n Array.isArray(capabilities[constraintKey]) &&\n convertedSetting &&\n !capabilities[constraintKey].includes(convertedSetting)\n ) {\n if (__DEV__) {\n // Only warn in dev mode.\n console.warn(\n ` { ${settingsKey}: \"${setting}\" } (converted to \"${convertedSetting}\" in the browser) is not supported for camera type \"${cameraType}\" in your browser. Using the default value instead.`\n );\n }\n return undefined;\n }\n return convertedSetting;\n}\n"]} \ No newline at end of file +{"version":3,"file":"WebCameraUtils.js","sourceRoot":"","sources":["../../src/web/WebCameraUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\nimport * as CapabilityUtils from './WebCapabilityUtils';\nimport { CameraTypeToFacingMode, ImageTypeFormat, MinimumConstraints } from './WebConstants';\nimport { requestUserMediaAsync } from './WebUserMediaManager';\nimport {\n CameraType,\n CameraCapturedPicture,\n ImageSize,\n ImageType,\n WebCameraSettings,\n CameraPictureOptions,\n} from '../Camera.types';\n\ninterface ConstrainLongRange {\n max?: number;\n min?: number;\n exact?: number;\n ideal?: number;\n}\n\nexport function getImageSize(videoWidth: number, videoHeight: number, scale: number): ImageSize {\n const width = videoWidth * scale;\n const ratio = videoWidth / width;\n const height = videoHeight / ratio;\n\n return {\n width,\n height,\n };\n}\n\nexport function toDataURL(\n canvas: HTMLCanvasElement,\n imageType: ImageType,\n quality: number\n): string {\n const format = ImageTypeFormat[imageType];\n if (imageType === 'jpg') {\n return canvas.toDataURL(format, quality);\n } else {\n return canvas.toDataURL(format);\n }\n}\n\nexport function hasValidConstraints(\n preferredCameraType?: CameraType,\n width?: number | ConstrainLongRange,\n height?: number | ConstrainLongRange\n): boolean {\n return preferredCameraType !== undefined && width !== undefined && height !== undefined;\n}\n\nfunction ensureCameraPictureOptions(config: CameraPictureOptions): CameraPictureOptions {\n const captureOptions: CameraPictureOptions = {\n scale: 1,\n imageType: 'png' as ImageType,\n isImageMirror: false,\n };\n for (const key in config) {\n const prop = key as keyof CameraPictureOptions;\n if (prop in config && config[prop] !== undefined && prop in captureOptions) {\n captureOptions[prop] = config[prop] as any;\n }\n }\n return captureOptions;\n}\n\nconst DEFAULT_QUALITY = 0.92;\n\nexport function captureImageContext(\n video: HTMLVideoElement,\n { scale = 1, isImageMirror = false }: Pick\n): HTMLCanvasElement {\n const { videoWidth, videoHeight } = video;\n const { width, height } = getImageSize(videoWidth, videoHeight, scale!);\n\n // Build the canvas size and draw the camera image to the context from video\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext('2d', { alpha: false });\n\n if (!context) {\n // Should never be called\n throw new Error('Context is not defined');\n }\n // sharp image details\n // context.imageSmoothingEnabled = false;\n\n // Flip horizontally (as css transform: rotateY(180deg))\n if (isImageMirror) {\n context.setTransform(-1, 0, 0, 1, canvas.width, 0);\n }\n\n context.drawImage(video, 0, 0, width, height);\n\n return canvas;\n}\n\nexport function captureImage(\n video: HTMLVideoElement,\n pictureOptions: CameraPictureOptions\n): string {\n const config = ensureCameraPictureOptions(pictureOptions);\n const canvas = captureImageContext(video, config);\n const { imageType, quality = DEFAULT_QUALITY } = config;\n return toDataURL(canvas, imageType!, quality);\n}\n\nfunction getSupportedConstraints(): MediaTrackSupportedConstraints | null {\n if (navigator.mediaDevices && navigator.mediaDevices.getSupportedConstraints) {\n return navigator.mediaDevices.getSupportedConstraints();\n }\n return null;\n}\n\nexport function getIdealConstraints(\n preferredCameraType: CameraType,\n width?: number | ConstrainLongRange,\n height?: number | ConstrainLongRange\n): MediaStreamConstraints {\n const preferredConstraints: MediaStreamConstraints = {\n audio: false,\n video: {},\n };\n\n if (hasValidConstraints(preferredCameraType, width, height)) {\n return MinimumConstraints;\n }\n\n const supports = getSupportedConstraints();\n // TODO(Bacon): Test this\n if (!supports || !supports.facingMode || !supports.width || !supports.height) {\n return MinimumConstraints;\n }\n const types = ['front', 'back'];\n if (preferredCameraType && types.includes(preferredCameraType)) {\n const facingMode = CameraTypeToFacingMode[preferredCameraType];\n if (isWebKit()) {\n const key = facingMode === 'user' ? 'exact' : 'ideal';\n (preferredConstraints.video as MediaTrackConstraints).facingMode = {\n [key]: facingMode,\n };\n } else {\n (preferredConstraints.video as MediaTrackConstraints).facingMode = {\n ideal: CameraTypeToFacingMode[preferredCameraType],\n };\n }\n }\n\n if (isMediaTrackConstraints(preferredConstraints.video)) {\n preferredConstraints.video.width = width;\n preferredConstraints.video.height = height;\n }\n\n return preferredConstraints;\n}\n\nfunction isMediaTrackConstraints(input: any): input is MediaTrackConstraints {\n return input && typeof input.video !== 'boolean';\n}\n\n/**\n * Invoke getStreamDevice a second time with the opposing camera type if the preferred type cannot be retrieved.\n *\n * @param preferredCameraType\n * @param preferredWidth\n * @param preferredHeight\n */\nexport async function getPreferredStreamDevice(\n preferredCameraType: CameraType,\n preferredWidth?: number | ConstrainLongRange,\n preferredHeight?: number | ConstrainLongRange\n): Promise {\n try {\n return await getStreamDevice(preferredCameraType, preferredWidth, preferredHeight);\n } catch (error) {\n // A hack on desktop browsers to ensure any camera is used.\n // eslint-disable-next-line no-undef\n if (error instanceof OverconstrainedError && error.constraint === 'facingMode') {\n const nextCameraType = preferredCameraType === 'back' ? 'front' : 'back';\n return await getStreamDevice(nextCameraType, preferredWidth, preferredHeight);\n }\n throw error;\n }\n}\n\nexport async function getStreamDevice(\n preferredCameraType: CameraType,\n preferredWidth?: number | ConstrainLongRange,\n preferredHeight?: number | ConstrainLongRange\n): Promise {\n const constraints: MediaStreamConstraints = getIdealConstraints(\n preferredCameraType,\n preferredWidth,\n preferredHeight\n );\n const stream: MediaStream = await requestUserMediaAsync(constraints);\n return stream;\n}\n\nexport function isWebKit(): boolean {\n return /WebKit/.test(navigator.userAgent) && !/Edg/.test(navigator.userAgent);\n}\n\nexport function compareStreams(a: MediaStream | null, b: MediaStream | null): boolean {\n if (!a || !b) {\n return false;\n }\n const settingsA = a.getTracks()[0].getSettings();\n const settingsB = b.getTracks()[0].getSettings();\n return settingsA.deviceId === settingsB.deviceId;\n}\n\nexport function capture(\n video: HTMLVideoElement,\n settings: MediaTrackSettings,\n config: CameraPictureOptions\n): CameraCapturedPicture {\n const base64 = captureImage(video, config);\n\n const capturedPicture: CameraCapturedPicture = {\n uri: base64,\n base64,\n width: 0,\n height: 0,\n format: config.imageType ?? 'jpg',\n };\n\n if (settings) {\n const { width = 0, height = 0 } = settings;\n capturedPicture.width = width;\n capturedPicture.height = height;\n capturedPicture.exif = settings;\n }\n\n if (config.onPictureSaved) {\n config.onPictureSaved(capturedPicture);\n }\n return capturedPicture;\n}\n\nexport async function syncTrackCapabilities(\n cameraType: CameraType,\n stream: MediaStream | null,\n settings: WebCameraSettings = {}\n): Promise {\n if (stream?.getVideoTracks) {\n await Promise.all(\n stream.getVideoTracks().map((track) => onCapabilitiesReady(cameraType, track, settings))\n );\n }\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints\nasync function onCapabilitiesReady(\n cameraType: CameraType,\n track: MediaStreamTrack,\n settings: WebCameraSettings = {}\n): Promise {\n if (typeof track.getCapabilities !== 'function') {\n return;\n }\n\n const capabilities = track.getCapabilities();\n\n // Create an empty object because if you set a constraint that isn't available an error will be thrown.\n const constraints: MediaTrackConstraintSet = {};\n\n // TODO(Bacon): Add `pointsOfInterest` support\n const clampedValues = [\n 'exposureCompensation',\n 'colorTemperature',\n 'iso',\n 'brightness',\n 'contrast',\n 'saturation',\n 'sharpness',\n 'focusDistance',\n 'zoom',\n ] as const;\n\n for (const property of clampedValues) {\n if (capabilities[property]) {\n constraints[property] = convertNormalizedSetting(capabilities[property], settings[property]);\n }\n }\n\n function validatedInternalConstrainedValue(\n constraintKey: keyof MediaTrackCapabilities,\n settingsKey: keyof WebCameraSettings,\n converter: (settingValue: any) => IConvertedType\n ) {\n const convertedSetting = converter(settings[settingsKey]);\n return validatedConstrainedValue({\n constraintKey,\n settingsKey,\n convertedSetting,\n capabilities,\n settings,\n cameraType,\n });\n }\n\n if (capabilities.focusMode && settings.autoFocus !== undefined) {\n constraints.focusMode = validatedInternalConstrainedValue(\n 'focusMode',\n 'autoFocus',\n CapabilityUtils.convertAutoFocusJSONToNative\n );\n }\n\n if (capabilities.torch && settings.flashMode !== undefined) {\n constraints.torch = validatedInternalConstrainedValue(\n 'torch',\n 'flashMode',\n CapabilityUtils.convertFlashModeJSONToNative\n );\n }\n\n if (capabilities.whiteBalanceMode && settings.whiteBalance !== undefined) {\n constraints.whiteBalanceMode = validatedInternalConstrainedValue<\n MediaTrackConstraintSet['whiteBalanceMode']\n >('whiteBalanceMode', 'whiteBalance', CapabilityUtils.convertWhiteBalanceJSONToNative);\n }\n\n try {\n await track.applyConstraints({ advanced: [constraints] });\n } catch (error) {\n if (__DEV__) console.warn('Failed to apply constraints', error);\n }\n}\n\nexport function stopMediaStream(stream: MediaStream | null) {\n if (!stream) {\n return;\n }\n stream.getAudioTracks().forEach((track) => track.stop());\n stream.getVideoTracks().forEach((track) => track.stop());\n}\n\nexport function setVideoSource(video: HTMLVideoElement, stream: MediaStream | null): void {\n video.srcObject = stream;\n}\n\nexport function isCapabilityAvailable(\n video: HTMLVideoElement,\n keyName: keyof MediaTrackCapabilities\n): boolean {\n const stream = video.srcObject;\n\n if (stream instanceof MediaStream) {\n const videoTrack = stream.getVideoTracks()[0];\n return !!videoTrack.getCapabilities?.()?.[keyName];\n }\n\n return false;\n}\n\nfunction convertNormalizedSetting(range: MediaSettingsRange, value?: number): number | undefined {\n if (!value) {\n return;\n }\n // TODO(@kitten): Handle undefined values / normalize explicitly\n // convert the normalized incoming setting to the native camera zoom range\n const converted = convertRange(value, [range.min!, range.max!]);\n // clamp value so we don't get an error\n return Math.min(range.max!, Math.max(range.min!, converted));\n}\n\nfunction convertRange(value: number, r2: [number, number], r1: [number, number] = [0, 1]): number {\n return ((value - r1[0]) * (r2[1] - r2[0])) / (r1[1] - r1[0]) + r2[0];\n}\n\nfunction validatedConstrainedValue(props: {\n constraintKey: keyof MediaTrackCapabilities;\n settingsKey: keyof WebCameraSettings;\n convertedSetting: T;\n capabilities: MediaTrackCapabilities;\n settings: WebCameraSettings;\n cameraType: string;\n}): T | undefined {\n const { constraintKey, settingsKey, convertedSetting, capabilities, settings, cameraType } =\n props;\n const setting = settings[settingsKey];\n if (\n Array.isArray(capabilities[constraintKey]) &&\n convertedSetting &&\n !capabilities[constraintKey].includes(convertedSetting)\n ) {\n if (__DEV__) {\n // Only warn in dev mode.\n console.warn(\n ` { ${settingsKey}: \"${setting}\" } (converted to \"${convertedSetting}\" in the browser) is not supported for camera type \"${cameraType}\" in your browser. Using the default value instead.`\n );\n }\n return undefined;\n }\n return convertedSetting;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/web/WebUserMediaManager.d.ts b/packages/expo-camera/build/web/WebUserMediaManager.d.ts index 068d78d35436e4..c9923d29259418 100644 --- a/packages/expo-camera/build/web/WebUserMediaManager.d.ts +++ b/packages/expo-camera/build/web/WebUserMediaManager.d.ts @@ -1,11 +1,8 @@ -export declare const userMediaRequested: boolean; -export declare const mountedInstances: any[]; export declare function requestUserMediaAsync(props: { audio?: any; video?: any; }, isMuted?: boolean): Promise; export declare function getAnyUserMediaAsync(constraints: MediaStreamConstraints, ignoreConstraints?: boolean): Promise; -export declare function getUserMediaAsync(constraints: MediaStreamConstraints): Promise; export declare function canGetUserMedia(): boolean; export declare function isFrontCameraAvailableAsync(devices?: MediaDeviceInfo[]): Promise; export declare function isBackCameraAvailableAsync(devices?: MediaDeviceInfo[]): Promise; diff --git a/packages/expo-camera/build/web/WebUserMediaManager.d.ts.map b/packages/expo-camera/build/web/WebUserMediaManager.d.ts.map index 18a42b187acbbc..d94f7c4f158203 100644 --- a/packages/expo-camera/build/web/WebUserMediaManager.d.ts.map +++ b/packages/expo-camera/build/web/WebUserMediaManager.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"WebUserMediaManager.d.ts","sourceRoot":"","sources":["../../src/web/WebUserMediaManager.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,kBAAkB,EAAE,OAAe,CAAC;AAEjD,eAAO,MAAM,gBAAgB,EAAE,GAAG,EAAO,CAAC;AA0E1C,wBAAsB,qBAAqB,CAEzC,KAAK,EAAE;IAAE,KAAK,CAAC,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,CAAA;CAAE,EACnC,OAAO,GAAE,OAAc,GACtB,OAAO,CAAC,WAAW,CAAC,CAQtB;AAED,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,sBAAsB,EACnC,iBAAiB,GAAE,OAAe,GACjC,OAAO,CAAC,WAAW,CAAC,CAgBtB;AAED,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC,CAajG;AAED,wBAAgB,eAAe,IAAI,OAAO,CAczC;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,CAAC,EAAE,eAAe,EAAE,GAC1B,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAExB;AAED,wBAAsB,0BAA0B,CAC9C,OAAO,CAAC,EAAE,eAAe,EAAE,GAC1B,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAExB"} \ No newline at end of file +{"version":3,"file":"WebUserMediaManager.d.ts","sourceRoot":"","sources":["../../src/web/WebUserMediaManager.ts"],"names":[],"mappings":"AAmBA,wBAAsB,qBAAqB,CACzC,KAAK,EAAE;IAAE,KAAK,CAAC,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,CAAA;CAAE,EACnC,OAAO,GAAE,OAAc,GACtB,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,sBAAsB,EACnC,iBAAiB,GAAE,OAAe,GACjC,OAAO,CAAC,WAAW,CAAC,CAgBtB;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,CAAC,EAAE,eAAe,EAAE,GAC1B,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAExB;AAED,wBAAsB,0BAA0B,CAC9C,OAAO,CAAC,EAAE,eAAe,EAAE,GAC1B,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAExB"} \ No newline at end of file diff --git a/packages/expo-camera/build/web/WebUserMediaManager.js b/packages/expo-camera/build/web/WebUserMediaManager.js index 8c84f2c09a28b7..e4ad4fbf6f6812 100644 --- a/packages/expo-camera/build/web/WebUserMediaManager.js +++ b/packages/expo-camera/build/web/WebUserMediaManager.js @@ -1,55 +1,5 @@ /* eslint-env browser */ -/** - * A web-only module for ponyfilling the UserMedia API. - */ import { Platform } from 'expo-modules-core'; -export const userMediaRequested = false; -export const mountedInstances = []; -async function requestLegacyUserMediaAsync( -// TODO(@kitten): Type this properly -props) { - // TODO(@kitten): This is never type checked against DOM types - const optionalSource = (id) => ({ optional: [{ sourceId: id }] }); - const constraintToSourceId = (constraint) => { - const { deviceId } = constraint; - if (typeof deviceId === 'string') { - return deviceId; - } - if (Array.isArray(deviceId)) { - return deviceId[0] ?? null; - } - else if (typeof deviceId === 'object' && deviceId.ideal) { - return deviceId.ideal; - } - return null; - }; - const sources = await new Promise((resolve) => - // @ts-ignore: https://caniuse.com/#search=getSources Chrome for Android (78) & Samsung Internet (10.1) use this - MediaStreamTrack.getSources((sources) => resolve(sources))); - let audioSource = null; - let videoSource = null; - sources.forEach((source) => { - if (source.kind === 'audio') { - audioSource = source.id; - } - else if (source.kind === 'video') { - videoSource = source.id; - } - }); - // NOTE(@kitten): This doesn't seem right. The types that should be used here don't contain `audioConstraints` - // If this is legacy, the type shouldn't have been dropped but marked as `@deprecated`. Alternatively, remove this code path - const audioSourceId = constraintToSourceId(props.audioConstraints); - if (audioSourceId) { - audioSource = audioSourceId; - } - // NOTE(@kitten): This doesn't seem right. The types that should be used here don't contain `videoConstraints` - // If this is legacy, the type shouldn't have been dropped but marked as `@deprecated`. Alternatively, remove this code path - const videoSourceId = constraintToSourceId(props.videoConstraints); - if (videoSourceId) { - videoSource = videoSourceId; - } - return [optionalSource(audioSource), optionalSource(videoSource)]; -} async function sourceSelectedAsync(isMuted, audioConstraints, videoConstraints) { const constraints = { video: typeof videoConstraints !== 'undefined' ? videoConstraints : true, @@ -59,20 +9,12 @@ async function sourceSelectedAsync(isMuted, audioConstraints, videoConstraints) } return await getAnyUserMediaAsync(constraints); } -export async function requestUserMediaAsync( -// TODO(@kitten): Type this properly -props, isMuted = true) { - if (canGetUserMedia()) { - return await sourceSelectedAsync(isMuted, props.audio, props.video); - } - // NOTE(@kitten): This doesn't seem right. The types that should be used here don't contain `videoConstraints` - // If this is legacy, the type shouldn't have been dropped but marked as `@deprecated`. Alternatively, remove this code path - const [audio, video] = await requestLegacyUserMediaAsync(props); - return await sourceSelectedAsync(isMuted, audio, video); +export async function requestUserMediaAsync(props, isMuted = true) { + return await sourceSelectedAsync(isMuted, props.audio, props.video); } export async function getAnyUserMediaAsync(constraints, ignoreConstraints = false) { try { - return await getUserMediaAsync({ + return await navigator.mediaDevices.getUserMedia({ ...constraints, video: ignoreConstraints || constraints.video, }); @@ -86,27 +28,8 @@ export async function getAnyUserMediaAsync(constraints, ignoreConstraints = fals throw error; } } -export async function getUserMediaAsync(constraints) { - if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - return navigator.mediaDevices.getUserMedia(constraints); - } - const _getUserMedia = navigator['mozGetUserMedia'] || - navigator['webkitGetUserMedia'] || - // @ts-expect-error: TODO(@kitten): Remove / Drop IE support - navigator['msGetUserMedia']; - return new Promise((resolve, reject) => _getUserMedia.call(navigator, constraints, resolve, reject)); -} export function canGetUserMedia() { - // TODO(@kitten): This is misaligned with the implementations in `expo-audio/src/AudioModule.web.ts` and `expo-av` - return ( - // SSR - Platform.isDOMAvailable && - // Has any form of media API - !!((navigator.mediaDevices && navigator.mediaDevices.getUserMedia) || - navigator['mozGetUserMedia'] || - navigator['webkitGetUserMedia'] || - // @ts-expect-error: TODO(@kitten): Remove / Drop IE support - navigator['msGetUserMedia'])); + return Platform.isDOMAvailable && !!navigator.mediaDevices?.getUserMedia; } export async function isFrontCameraAvailableAsync(devices) { return await supportsCameraType(['front', 'user', 'facetime'], 'user', devices); diff --git a/packages/expo-camera/build/web/WebUserMediaManager.js.map b/packages/expo-camera/build/web/WebUserMediaManager.js.map index 6be390396356ba..2df23ec42c1f58 100644 --- a/packages/expo-camera/build/web/WebUserMediaManager.js.map +++ b/packages/expo-camera/build/web/WebUserMediaManager.js.map @@ -1 +1 @@ -{"version":3,"file":"WebUserMediaManager.js","sourceRoot":"","sources":["../../src/web/WebUserMediaManager.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\n/**\n * A web-only module for ponyfilling the UserMedia API.\n */\nimport { Platform } from 'expo-modules-core';\n\nexport const userMediaRequested: boolean = false;\n\nexport const mountedInstances: any[] = [];\n\nasync function requestLegacyUserMediaAsync(\n // TODO(@kitten): Type this properly\n props: { audioConstraints?: any; videoConstraints?: any }\n): Promise {\n // TODO(@kitten): This is never type checked against DOM types\n const optionalSource = (id: string | string[] | null) => ({ optional: [{ sourceId: id }] });\n\n const constraintToSourceId = (constraint: MediaTrackConstraintSet) => {\n const { deviceId } = constraint;\n\n if (typeof deviceId === 'string') {\n return deviceId;\n }\n\n if (Array.isArray(deviceId)) {\n return deviceId[0] ?? null;\n } else if (typeof deviceId === 'object' && deviceId.ideal) {\n return deviceId.ideal;\n }\n\n return null;\n };\n\n const sources: any[] = await new Promise((resolve) =>\n // @ts-ignore: https://caniuse.com/#search=getSources Chrome for Android (78) & Samsung Internet (10.1) use this\n MediaStreamTrack.getSources((sources) => resolve(sources))\n );\n\n let audioSource = null;\n let videoSource = null;\n\n sources.forEach((source) => {\n if (source.kind === 'audio') {\n audioSource = source.id;\n } else if (source.kind === 'video') {\n videoSource = source.id;\n }\n });\n\n // NOTE(@kitten): This doesn't seem right. The types that should be used here don't contain `audioConstraints`\n // If this is legacy, the type shouldn't have been dropped but marked as `@deprecated`. Alternatively, remove this code path\n const audioSourceId = constraintToSourceId(props.audioConstraints);\n if (audioSourceId) {\n audioSource = audioSourceId;\n }\n\n // NOTE(@kitten): This doesn't seem right. The types that should be used here don't contain `videoConstraints`\n // If this is legacy, the type shouldn't have been dropped but marked as `@deprecated`. Alternatively, remove this code path\n const videoSourceId = constraintToSourceId(props.videoConstraints);\n if (videoSourceId) {\n videoSource = videoSourceId;\n }\n\n return [optionalSource(audioSource), optionalSource(videoSource)];\n}\n\nasync function sourceSelectedAsync(\n isMuted: boolean,\n audioConstraints?: MediaTrackConstraints | boolean,\n videoConstraints?: MediaTrackConstraints | boolean\n): Promise {\n const constraints: MediaStreamConstraints = {\n video: typeof videoConstraints !== 'undefined' ? videoConstraints : true,\n };\n\n if (!isMuted) {\n constraints.audio = typeof audioConstraints !== 'undefined' ? audioConstraints : true;\n }\n\n return await getAnyUserMediaAsync(constraints);\n}\n\nexport async function requestUserMediaAsync(\n // TODO(@kitten): Type this properly\n props: { audio?: any; video?: any },\n isMuted: boolean = true\n): Promise {\n if (canGetUserMedia()) {\n return await sourceSelectedAsync(isMuted, props.audio, props.video);\n }\n // NOTE(@kitten): This doesn't seem right. The types that should be used here don't contain `videoConstraints`\n // If this is legacy, the type shouldn't have been dropped but marked as `@deprecated`. Alternatively, remove this code path\n const [audio, video] = await requestLegacyUserMediaAsync(props as any);\n return await sourceSelectedAsync(isMuted, audio, video);\n}\n\nexport async function getAnyUserMediaAsync(\n constraints: MediaStreamConstraints,\n ignoreConstraints: boolean = false\n): Promise {\n try {\n return await getUserMediaAsync({\n ...constraints,\n video: ignoreConstraints || constraints.video,\n });\n } catch (error: any) {\n if (\n !ignoreConstraints &&\n typeof error === 'object' &&\n error?.name === 'ConstraintNotSatisfiedError'\n ) {\n return await getAnyUserMediaAsync(constraints, true);\n }\n throw error;\n }\n}\n\nexport async function getUserMediaAsync(constraints: MediaStreamConstraints): Promise {\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n return navigator.mediaDevices.getUserMedia(constraints);\n }\n\n const _getUserMedia =\n navigator['mozGetUserMedia'] ||\n navigator['webkitGetUserMedia'] ||\n // @ts-expect-error: TODO(@kitten): Remove / Drop IE support\n navigator['msGetUserMedia'];\n return new Promise((resolve, reject) =>\n _getUserMedia.call(navigator, constraints, resolve, reject)\n );\n}\n\nexport function canGetUserMedia(): boolean {\n // TODO(@kitten): This is misaligned with the implementations in `expo-audio/src/AudioModule.web.ts` and `expo-av`\n return (\n // SSR\n Platform.isDOMAvailable &&\n // Has any form of media API\n !!(\n (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) ||\n navigator['mozGetUserMedia'] ||\n navigator['webkitGetUserMedia'] ||\n // @ts-expect-error: TODO(@kitten): Remove / Drop IE support\n navigator['msGetUserMedia']\n )\n );\n}\n\nexport async function isFrontCameraAvailableAsync(\n devices?: MediaDeviceInfo[]\n): Promise {\n return await supportsCameraType(['front', 'user', 'facetime'], 'user', devices);\n}\n\nexport async function isBackCameraAvailableAsync(\n devices?: MediaDeviceInfo[]\n): Promise {\n return await supportsCameraType(['back', 'rear'], 'environment', devices);\n}\n\nasync function supportsCameraType(\n labels: string[],\n type: string,\n devices?: MediaDeviceInfo[]\n): Promise {\n if (!devices) {\n if (!navigator.mediaDevices.enumerateDevices) {\n return null;\n }\n devices = await navigator.mediaDevices.enumerateDevices();\n }\n const cameras = devices.filter((t) => t.kind === 'videoinput');\n const [hasCamera] = cameras.filter((camera) =>\n labels.some((label) => camera.label.toLowerCase().includes(label))\n );\n const [isCapable] = cameras.filter((camera) => {\n if (!('getCapabilities' in camera)) {\n return null;\n }\n\n const capabilities = (camera as any).getCapabilities();\n if (!capabilities.facingMode) {\n return null;\n }\n\n return capabilities.facingMode.find((_: string) => type);\n });\n\n return isCapable?.deviceId || hasCamera?.deviceId || null;\n}\n"]} \ No newline at end of file +{"version":3,"file":"WebUserMediaManager.js","sourceRoot":"","sources":["../../src/web/WebUserMediaManager.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\nimport { Platform } from 'expo-modules-core';\n\nasync function sourceSelectedAsync(\n isMuted: boolean,\n audioConstraints?: MediaTrackConstraints | boolean,\n videoConstraints?: MediaTrackConstraints | boolean\n): Promise {\n const constraints: MediaStreamConstraints = {\n video: typeof videoConstraints !== 'undefined' ? videoConstraints : true,\n };\n\n if (!isMuted) {\n constraints.audio = typeof audioConstraints !== 'undefined' ? audioConstraints : true;\n }\n\n return await getAnyUserMediaAsync(constraints);\n}\n\nexport async function requestUserMediaAsync(\n props: { audio?: any; video?: any },\n isMuted: boolean = true\n): Promise {\n return await sourceSelectedAsync(isMuted, props.audio, props.video);\n}\n\nexport async function getAnyUserMediaAsync(\n constraints: MediaStreamConstraints,\n ignoreConstraints: boolean = false\n): Promise {\n try {\n return await navigator.mediaDevices.getUserMedia({\n ...constraints,\n video: ignoreConstraints || constraints.video,\n });\n } catch (error: any) {\n if (\n !ignoreConstraints &&\n typeof error === 'object' &&\n error?.name === 'ConstraintNotSatisfiedError'\n ) {\n return await getAnyUserMediaAsync(constraints, true);\n }\n throw error;\n }\n}\n\nexport function canGetUserMedia(): boolean {\n return Platform.isDOMAvailable && !!navigator.mediaDevices?.getUserMedia;\n}\n\nexport async function isFrontCameraAvailableAsync(\n devices?: MediaDeviceInfo[]\n): Promise {\n return await supportsCameraType(['front', 'user', 'facetime'], 'user', devices);\n}\n\nexport async function isBackCameraAvailableAsync(\n devices?: MediaDeviceInfo[]\n): Promise {\n return await supportsCameraType(['back', 'rear'], 'environment', devices);\n}\n\nasync function supportsCameraType(\n labels: string[],\n type: string,\n devices?: MediaDeviceInfo[]\n): Promise {\n if (!devices) {\n if (!navigator.mediaDevices.enumerateDevices) {\n return null;\n }\n devices = await navigator.mediaDevices.enumerateDevices();\n }\n const cameras = devices.filter((t) => t.kind === 'videoinput');\n const [hasCamera] = cameras.filter((camera) =>\n labels.some((label) => camera.label.toLowerCase().includes(label))\n );\n const [isCapable] = cameras.filter((camera) => {\n if (!('getCapabilities' in camera)) {\n return null;\n }\n\n const capabilities = (camera as any).getCapabilities();\n if (!capabilities.facingMode) {\n return null;\n }\n\n return capabilities.facingMode.find((_: string) => type);\n });\n\n return isCapable?.deviceId || hasCamera?.deviceId || null;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/web/useWebBarcodeScanner.d.ts b/packages/expo-camera/build/web/useWebBarcodeScanner.d.ts new file mode 100644 index 00000000000000..bfeec0b72bde78 --- /dev/null +++ b/packages/expo-camera/build/web/useWebBarcodeScanner.d.ts @@ -0,0 +1,13 @@ +import * as React from 'react'; +import { BarcodeType, BarcodeScanningResult, MountErrorListener } from '../Camera.types'; +export declare function useWebBarcodeScanner(video: React.RefObject, { isEnabled, barcodeTypes, interval, isMirrored, onScanned, onError, }: { + isEnabled: boolean; + barcodeTypes: BarcodeType[]; + interval?: number; + isMirrored?: boolean; + onScanned?: (scanningResult: { + nativeEvent: BarcodeScanningResult; + }) => void; + onError?: MountErrorListener; +}): void; +//# sourceMappingURL=useWebBarcodeScanner.d.ts.map \ No newline at end of file diff --git a/packages/expo-camera/build/web/useWebBarcodeScanner.d.ts.map b/packages/expo-camera/build/web/useWebBarcodeScanner.d.ts.map new file mode 100644 index 00000000000000..468cbcd1c9b397 --- /dev/null +++ b/packages/expo-camera/build/web/useWebBarcodeScanner.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"useWebBarcodeScanner.d.ts","sourceRoot":"","sources":["../../src/web/useWebBarcodeScanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAoCzF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,EAC/C,EACE,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,UAAkB,EAClB,SAAS,EACT,OAAO,GACR,EAAE;IACD,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,cAAc,EAAE;QAAE,WAAW,EAAE,qBAAqB,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7E,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B,QAwEF"} \ No newline at end of file diff --git a/packages/expo-camera/build/web/useWebBarcodeScanner.js b/packages/expo-camera/build/web/useWebBarcodeScanner.js new file mode 100644 index 00000000000000..75bb232cad6bc8 --- /dev/null +++ b/packages/expo-camera/build/web/useWebBarcodeScanner.js @@ -0,0 +1,84 @@ +import * as React from 'react'; +import * as WebBarcodeScanner from './WebBarcodeScanner'; +function mapToViewCoordinates(result, videoWidth, viewHeight, height, width, isMirrored) { + const scaleX = width / videoWidth; + const scaleY = viewHeight / height; + const mapPoint = (p) => { + const x = isMirrored ? width - p.x * scaleX : p.x * scaleX; + const y = p.y * scaleY; + return { x, y }; + }; + const origin = mapPoint(result.bounds.origin); + const size = { + width: result.bounds.size.width * scaleX, + height: result.bounds.size.height * scaleY, + }; + if (isMirrored) { + origin.x -= size.width; + } + return { + ...result, + bounds: { origin, size }, + cornerPoints: result.cornerPoints.map(mapPoint), + }; +} +export function useWebBarcodeScanner(video, { isEnabled, barcodeTypes, interval, isMirrored = false, onScanned, onError, }) { + const isRunning = React.useRef(false); + const timeout = React.useRef(undefined); + async function scanAsync() { + if (!isRunning.current || !onScanned) { + stop(); + return; + } + try { + const videoEl = video.current; + if (!videoEl || videoEl.readyState !== videoEl.HAVE_ENOUGH_DATA) { + return; + } + const { videoWidth, videoHeight } = videoEl; + if (!videoWidth || !videoHeight) { + return; + } + const bitmap = await createImageBitmap(videoEl); + const results = await WebBarcodeScanner.detect(bitmap, barcodeTypes); + bitmap.close(); + const viewWidth = videoEl.clientWidth || videoWidth; + const viewHeight = videoEl.clientHeight || videoHeight; + for (const raw of results) { + const nativeEvent = mapToViewCoordinates(raw, videoWidth, videoHeight, viewWidth, viewHeight, isMirrored); + onScanned({ nativeEvent }); + } + } + catch (error) { + if (onError) { + onError({ nativeEvent: error }); + } + } + finally { + if (interval === 0) { + stop(); + return; + } + const intervalToUse = !interval || interval < 0 ? 16 : interval; + timeout.current = setTimeout(() => { + scanAsync(); + }, intervalToUse); + } + } + function stop() { + isRunning.current = false; + clearTimeout(timeout.current); + } + React.useEffect(() => { + if (isEnabled) { + isRunning.current = true; + scanAsync(); + } + return () => { + if (isEnabled) { + stop(); + } + }; + }, [isEnabled]); +} +//# sourceMappingURL=useWebBarcodeScanner.js.map \ No newline at end of file diff --git a/packages/expo-camera/build/web/useWebBarcodeScanner.js.map b/packages/expo-camera/build/web/useWebBarcodeScanner.js.map new file mode 100644 index 00000000000000..302722810762a0 --- /dev/null +++ b/packages/expo-camera/build/web/useWebBarcodeScanner.js.map @@ -0,0 +1 @@ +{"version":3,"file":"useWebBarcodeScanner.js","sourceRoot":"","sources":["../../src/web/useWebBarcodeScanner.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport * as WebBarcodeScanner from './WebBarcodeScanner';\nimport { BarcodeType, BarcodeScanningResult, MountErrorListener } from '../Camera.types';\n\nfunction mapToViewCoordinates(\n result: BarcodeScanningResult,\n videoWidth: number,\n viewHeight: number,\n height: number,\n width: number,\n isMirrored: boolean\n): BarcodeScanningResult {\n const scaleX = width / videoWidth;\n const scaleY = viewHeight / height;\n\n const mapPoint = (p: { x: number; y: number }) => {\n const x = isMirrored ? width - p.x * scaleX : p.x * scaleX;\n const y = p.y * scaleY;\n return { x, y };\n };\n\n const origin = mapPoint(result.bounds.origin);\n const size = {\n width: result.bounds.size.width * scaleX,\n height: result.bounds.size.height * scaleY,\n };\n\n if (isMirrored) {\n origin.x -= size.width;\n }\n\n return {\n ...result,\n bounds: { origin, size },\n cornerPoints: result.cornerPoints.map(mapPoint),\n };\n}\n\nexport function useWebBarcodeScanner(\n video: React.RefObject,\n {\n isEnabled,\n barcodeTypes,\n interval,\n isMirrored = false,\n onScanned,\n onError,\n }: {\n isEnabled: boolean;\n barcodeTypes: BarcodeType[];\n interval?: number;\n isMirrored?: boolean;\n onScanned?: (scanningResult: { nativeEvent: BarcodeScanningResult }) => void;\n onError?: MountErrorListener;\n }\n) {\n const isRunning = React.useRef(false);\n const timeout = React.useRef | undefined>(undefined);\n\n async function scanAsync() {\n if (!isRunning.current || !onScanned) {\n stop();\n return;\n }\n try {\n const videoEl = video.current;\n if (!videoEl || videoEl.readyState !== videoEl.HAVE_ENOUGH_DATA) {\n return;\n }\n\n const { videoWidth, videoHeight } = videoEl;\n if (!videoWidth || !videoHeight) {\n return;\n }\n\n const bitmap = await createImageBitmap(videoEl);\n const results = await WebBarcodeScanner.detect(bitmap, barcodeTypes);\n bitmap.close();\n\n const viewWidth = videoEl.clientWidth || videoWidth;\n const viewHeight = videoEl.clientHeight || videoHeight;\n\n for (const raw of results) {\n const nativeEvent = mapToViewCoordinates(\n raw,\n videoWidth,\n videoHeight,\n viewWidth,\n viewHeight,\n isMirrored\n );\n onScanned({ nativeEvent });\n }\n } catch (error: any) {\n if (onError) {\n onError({ nativeEvent: error });\n }\n } finally {\n if (interval === 0) {\n stop();\n return;\n }\n const intervalToUse = !interval || interval < 0 ? 16 : interval;\n timeout.current = setTimeout(() => {\n scanAsync();\n }, intervalToUse);\n }\n }\n\n function stop() {\n isRunning.current = false;\n clearTimeout(timeout.current);\n }\n\n React.useEffect(() => {\n if (isEnabled) {\n isRunning.current = true;\n scanAsync();\n }\n\n return () => {\n if (isEnabled) {\n stop();\n }\n };\n }, [isEnabled]);\n}\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/web/useWebCameraStream.js b/packages/expo-camera/build/web/useWebCameraStream.js index e32f1177439105..7927fc3a783a6f 100644 --- a/packages/expo-camera/build/web/useWebCameraStream.js +++ b/packages/expo-camera/build/web/useWebCameraStream.js @@ -37,7 +37,7 @@ export function useWebCameraStream(video, preferredType, settings, { onCameraRea autoFocus: 'continuous', flashMode: 'off', whiteBalance: 'continuous', - zoom: 1, + zoom: 0, }); const [stream, setStream] = React.useState(null); const mediaTrackSettings = React.useMemo(() => { diff --git a/packages/expo-camera/build/web/useWebCameraStream.js.map b/packages/expo-camera/build/web/useWebCameraStream.js.map index d2d2f4a4f36f6c..bda14955790f65 100644 --- a/packages/expo-camera/build/web/useWebCameraStream.js.map +++ b/packages/expo-camera/build/web/useWebCameraStream.js.map @@ -1 +1 @@ -{"version":3,"file":"useWebCameraStream.js","sourceRoot":"","sources":["../../src/web/useWebCameraStream.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\nimport * as React from 'react';\n\nimport * as Utils from './WebCameraUtils';\nimport { FacingModeToCameraType } from './WebConstants';\nimport {\n CameraReadyListener,\n CameraType,\n MountErrorListener,\n WebCameraSettings,\n} from '../Camera.types';\n\nconst VALID_SETTINGS_KEYS = [\n 'autoFocus',\n 'flashMode',\n 'exposureCompensation',\n 'colorTemperature',\n 'iso',\n 'brightness',\n 'contrast',\n 'saturation',\n 'sharpness',\n 'focusDistance',\n 'whiteBalance',\n 'zoom',\n] as const;\n\nfunction useLoadedVideo(video: HTMLVideoElement | null, onLoaded: () => void) {\n React.useEffect(() => {\n if (video) {\n video.addEventListener('loadedmetadata', () => {\n // without this async block the constraints aren't properly applied to the camera,\n // this means that if you were to turn on the torch and swap to the front camera,\n // then swap back to the rear camera the torch setting wouldn't be applied.\n requestAnimationFrame(() => {\n onLoaded();\n });\n });\n }\n }, [video]);\n}\n\nexport function useWebCameraStream(\n video: React.MutableRefObject,\n preferredType: CameraType,\n settings: Record,\n {\n onCameraReady,\n onMountError,\n }: { onCameraReady?: CameraReadyListener; onMountError?: MountErrorListener }\n): {\n type: CameraType | null;\n mediaTrackSettings: MediaTrackSettings | null;\n} {\n const isStartingCamera = React.useRef(false);\n const activeStreams = React.useRef([]);\n const capabilities = React.useRef({\n autoFocus: 'continuous',\n flashMode: 'off',\n whiteBalance: 'continuous',\n zoom: 1,\n });\n const [stream, setStream] = React.useState(null);\n\n const mediaTrackSettings = React.useMemo(() => {\n return stream ? stream.getTracks()[0].getSettings() : null;\n }, [stream]);\n\n // The actual camera type - this can be different from the incoming camera type.\n const type = React.useMemo(() => {\n if (!mediaTrackSettings) {\n return null;\n }\n // On desktop no value will be returned, in this case we should assume the cameraType is 'front'\n const { facingMode = 'user' } = mediaTrackSettings;\n return FacingModeToCameraType[facingMode];\n }, [mediaTrackSettings]);\n\n const getStreamDeviceAsync = React.useCallback(async (): Promise => {\n try {\n return await Utils.getPreferredStreamDevice(preferredType);\n } catch (nativeEvent: any) {\n if (__DEV__) {\n console.warn(`Error requesting UserMedia for type \"${preferredType}\":`, nativeEvent);\n }\n if (onMountError) {\n onMountError({ nativeEvent });\n }\n return null;\n }\n }, [preferredType, onMountError]);\n\n const resumeAsync = React.useCallback(async (): Promise => {\n const nextStream = await getStreamDeviceAsync();\n if (Utils.compareStreams(nextStream, stream)) {\n // Do nothing if the streams are the same.\n // This happens when the device only supports one camera (i.e. desktop) and the mode was toggled between front/back while already active.\n // Without this check there is a screen flash while the video switches.\n return false;\n }\n\n // Save a history of all active streams (usually 2+) so we can close them later.\n // Keeping them open makes swapping camera types much faster.\n if (!activeStreams.current.some((value) => value.id === nextStream?.id)) {\n activeStreams.current.push(nextStream!);\n }\n\n // Set the new stream -> update the video, settings, and actual camera type.\n setStream(nextStream);\n if (onCameraReady) {\n onCameraReady();\n }\n return false;\n }, [getStreamDeviceAsync, setStream, onCameraReady, stream, activeStreams.current]);\n\n React.useEffect(() => {\n // Restart the camera and guard concurrent actions.\n if (isStartingCamera.current) {\n return;\n }\n isStartingCamera.current = true;\n\n resumeAsync()\n .then((isStarting) => {\n isStartingCamera.current = isStarting;\n })\n .catch(() => {\n // ensure the camera can be started again.\n isStartingCamera.current = false;\n });\n }, [preferredType]);\n\n // Update the native camera with any custom capabilities.\n React.useEffect(() => {\n const changes: WebCameraSettings = {};\n\n for (const key of VALID_SETTINGS_KEYS) {\n if (key in settings) {\n const nextValue = settings[key];\n if (nextValue !== capabilities.current[key]) {\n changes[key] = nextValue;\n }\n }\n }\n\n // Only update the native camera if changes were found\n const hasChanges = !!Object.keys(changes).length;\n\n const nextWebCameraSettings = { ...capabilities.current, ...changes };\n if (hasChanges) {\n Utils.syncTrackCapabilities(preferredType, stream, changes);\n }\n\n capabilities.current = nextWebCameraSettings;\n }, [\n settings.autoFocus,\n settings.flashMode,\n settings.exposureCompensation,\n settings.colorTemperature,\n settings.iso,\n settings.brightness,\n settings.contrast,\n settings.saturation,\n settings.sharpness,\n settings.focusDistance,\n settings.whiteBalance,\n settings.zoom,\n ]);\n\n React.useEffect(() => {\n // set or unset the video source.\n if (!video.current) {\n return;\n }\n Utils.setVideoSource(video.current, stream);\n }, [video.current, stream]);\n\n React.useEffect(() => {\n return () => {\n // Clean up on dismount, this is important for making sure the camera light goes off when the component is removed.\n for (const stream of activeStreams.current) {\n // Close all open streams.\n Utils.stopMediaStream(stream);\n }\n if (video.current) {\n // Invalidate the video source.\n Utils.setVideoSource(video.current, stream);\n }\n };\n }, []);\n\n // Update props when the video loads.\n useLoadedVideo(video.current, () => {\n Utils.syncTrackCapabilities(preferredType, stream, capabilities.current);\n });\n\n return {\n type,\n mediaTrackSettings,\n };\n}\n"]} \ No newline at end of file +{"version":3,"file":"useWebCameraStream.js","sourceRoot":"","sources":["../../src/web/useWebCameraStream.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\nimport * as React from 'react';\n\nimport * as Utils from './WebCameraUtils';\nimport { FacingModeToCameraType } from './WebConstants';\nimport {\n CameraReadyListener,\n CameraType,\n MountErrorListener,\n WebCameraSettings,\n} from '../Camera.types';\n\nconst VALID_SETTINGS_KEYS = [\n 'autoFocus',\n 'flashMode',\n 'exposureCompensation',\n 'colorTemperature',\n 'iso',\n 'brightness',\n 'contrast',\n 'saturation',\n 'sharpness',\n 'focusDistance',\n 'whiteBalance',\n 'zoom',\n] as const;\n\nfunction useLoadedVideo(video: HTMLVideoElement | null, onLoaded: () => void) {\n React.useEffect(() => {\n if (video) {\n video.addEventListener('loadedmetadata', () => {\n // without this async block the constraints aren't properly applied to the camera,\n // this means that if you were to turn on the torch and swap to the front camera,\n // then swap back to the rear camera the torch setting wouldn't be applied.\n requestAnimationFrame(() => {\n onLoaded();\n });\n });\n }\n }, [video]);\n}\n\nexport function useWebCameraStream(\n video: React.MutableRefObject,\n preferredType: CameraType,\n settings: Record,\n {\n onCameraReady,\n onMountError,\n }: { onCameraReady?: CameraReadyListener; onMountError?: MountErrorListener }\n): {\n type: CameraType | null;\n mediaTrackSettings: MediaTrackSettings | null;\n} {\n const isStartingCamera = React.useRef(false);\n const activeStreams = React.useRef([]);\n const capabilities = React.useRef({\n autoFocus: 'continuous',\n flashMode: 'off',\n whiteBalance: 'continuous',\n zoom: 0,\n });\n const [stream, setStream] = React.useState(null);\n\n const mediaTrackSettings = React.useMemo(() => {\n return stream ? stream.getTracks()[0].getSettings() : null;\n }, [stream]);\n\n // The actual camera type - this can be different from the incoming camera type.\n const type = React.useMemo(() => {\n if (!mediaTrackSettings) {\n return null;\n }\n // On desktop no value will be returned, in this case we should assume the cameraType is 'front'\n const { facingMode = 'user' } = mediaTrackSettings;\n return FacingModeToCameraType[facingMode];\n }, [mediaTrackSettings]);\n\n const getStreamDeviceAsync = React.useCallback(async (): Promise => {\n try {\n return await Utils.getPreferredStreamDevice(preferredType);\n } catch (nativeEvent: any) {\n if (__DEV__) {\n console.warn(`Error requesting UserMedia for type \"${preferredType}\":`, nativeEvent);\n }\n if (onMountError) {\n onMountError({ nativeEvent });\n }\n return null;\n }\n }, [preferredType, onMountError]);\n\n const resumeAsync = React.useCallback(async (): Promise => {\n const nextStream = await getStreamDeviceAsync();\n if (Utils.compareStreams(nextStream, stream)) {\n // Do nothing if the streams are the same.\n // This happens when the device only supports one camera (i.e. desktop) and the mode was toggled between front/back while already active.\n // Without this check there is a screen flash while the video switches.\n return false;\n }\n\n // Save a history of all active streams (usually 2+) so we can close them later.\n // Keeping them open makes swapping camera types much faster.\n if (!activeStreams.current.some((value) => value.id === nextStream?.id)) {\n activeStreams.current.push(nextStream!);\n }\n\n // Set the new stream -> update the video, settings, and actual camera type.\n setStream(nextStream);\n if (onCameraReady) {\n onCameraReady();\n }\n return false;\n }, [getStreamDeviceAsync, setStream, onCameraReady, stream, activeStreams.current]);\n\n React.useEffect(() => {\n // Restart the camera and guard concurrent actions.\n if (isStartingCamera.current) {\n return;\n }\n isStartingCamera.current = true;\n\n resumeAsync()\n .then((isStarting) => {\n isStartingCamera.current = isStarting;\n })\n .catch(() => {\n // ensure the camera can be started again.\n isStartingCamera.current = false;\n });\n }, [preferredType]);\n\n // Update the native camera with any custom capabilities.\n React.useEffect(() => {\n const changes: WebCameraSettings = {};\n\n for (const key of VALID_SETTINGS_KEYS) {\n if (key in settings) {\n const nextValue = settings[key];\n if (nextValue !== capabilities.current[key]) {\n changes[key] = nextValue;\n }\n }\n }\n\n // Only update the native camera if changes were found\n const hasChanges = !!Object.keys(changes).length;\n\n const nextWebCameraSettings = { ...capabilities.current, ...changes };\n if (hasChanges) {\n Utils.syncTrackCapabilities(preferredType, stream, changes);\n }\n\n capabilities.current = nextWebCameraSettings;\n }, [\n settings.autoFocus,\n settings.flashMode,\n settings.exposureCompensation,\n settings.colorTemperature,\n settings.iso,\n settings.brightness,\n settings.contrast,\n settings.saturation,\n settings.sharpness,\n settings.focusDistance,\n settings.whiteBalance,\n settings.zoom,\n ]);\n\n React.useEffect(() => {\n // set or unset the video source.\n if (!video.current) {\n return;\n }\n Utils.setVideoSource(video.current, stream);\n }, [video.current, stream]);\n\n React.useEffect(() => {\n return () => {\n // Clean up on dismount, this is important for making sure the camera light goes off when the component is removed.\n for (const stream of activeStreams.current) {\n // Close all open streams.\n Utils.stopMediaStream(stream);\n }\n if (video.current) {\n // Invalidate the video source.\n Utils.setVideoSource(video.current, stream);\n }\n };\n }, []);\n\n // Update props when the video loads.\n useLoadedVideo(video.current, () => {\n Utils.syncTrackCapabilities(preferredType, stream, capabilities.current);\n });\n\n return {\n type,\n mediaTrackSettings,\n };\n}\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/web/useWebQRScanner.d.ts b/packages/expo-camera/build/web/useWebQRScanner.d.ts deleted file mode 100644 index 18a948801c31b9..00000000000000 --- a/packages/expo-camera/build/web/useWebQRScanner.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as React from 'react'; -import { BarcodeScanningResult, CameraPictureOptions, MountErrorListener } from '../Camera.types'; -export declare function useWebQRScanner(video: React.MutableRefObject, { isEnabled, captureOptions, interval, onScanned, onError, }: { - isEnabled: boolean; - captureOptions: Pick; - interval?: number; - onScanned?: (scanningResult: { - nativeEvent: BarcodeScanningResult; - }) => void; - onError?: MountErrorListener; -}): void; -//# sourceMappingURL=useWebQRScanner.d.ts.map \ No newline at end of file diff --git a/packages/expo-camera/build/web/useWebQRScanner.d.ts.map b/packages/expo-camera/build/web/useWebQRScanner.d.ts.map deleted file mode 100644 index 603e649e893102..00000000000000 --- a/packages/expo-camera/build/web/useWebQRScanner.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"useWebQRScanner.d.ts","sourceRoot":"","sources":["../../src/web/useWebQRScanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AA6ElG,wBAAgB,eAAe,CAC7B,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,gBAAgB,GAAG,IAAI,CAAC,EACtD,EACE,SAAS,EACT,cAAc,EACd,QAAQ,EACR,SAAS,EACT,OAAO,GACR,EAAE;IACD,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,eAAe,CAAC,CAAC;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,CAAC,cAAc,EAAE;QAAE,WAAW,EAAE,qBAAqB,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7E,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B,QAyDF"} \ No newline at end of file diff --git a/packages/expo-camera/build/web/useWebQRScanner.js b/packages/expo-camera/build/web/useWebQRScanner.js deleted file mode 100644 index ae13c400a850c9..00000000000000 --- a/packages/expo-camera/build/web/useWebQRScanner.js +++ /dev/null @@ -1,119 +0,0 @@ -import * as React from 'react'; -import { captureImageData } from './WebCameraUtils'; -const qrWorkerMethod = ({ data, width, height }) => { - // eslint-disable-next-line no-undef - const decoded = self.jsQR(data, width, height, { - inversionAttempts: 'attemptBoth', - }); - let parsed; - try { - parsed = JSON.parse(decoded); - } - catch { - parsed = decoded; - } - if (parsed?.data) { - const nativeEvent = { - type: 'qr', - data: parsed.data, - cornerPoints: [], - bounds: { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 } }, - }; - if (parsed.location) { - nativeEvent.cornerPoints = [ - parsed.location.topLeftCorner, - parsed.location.bottomLeftCorner, - parsed.location.topRightCorner, - parsed.location.bottomRightCorner, - ]; - } - return nativeEvent; - } - return parsed; -}; -const createWorkerAsyncFunction = (fn, deps) => { - if (typeof window === 'undefined') { - return async () => { - throw new Error('Cannot use createWorkerAsyncFunction in a non-browser environment'); - }; - } - const stringifiedFn = [ - `self.func = ${fn.toString()};`, - 'self.onmessage = (e) => {', - ' const result = self.func(e.data);', - ' self.postMessage(result);', - '};', - ]; - if (deps.length > 0) { - stringifiedFn.unshift(`importScripts(${deps.map((dep) => `'${dep}'`).join(', ')});`); - } - const blob = new Blob(stringifiedFn, { type: 'text/javascript' }); - const worker = new Worker(URL.createObjectURL(blob)); - // First-In First-Out queue of promises - const promises = []; - worker.onmessage = (e) => promises.shift()?.resolve(e.data); - return (data) => { - return new Promise((resolve, reject) => { - promises.push({ resolve, reject }); - worker.postMessage(data); - }); - }; -}; -const decode = createWorkerAsyncFunction(qrWorkerMethod, [ - 'https://cdn.jsdelivr.net/npm/jsqr@1.2.0/dist/jsQR.min.js', -]); -export function useWebQRScanner(video, { isEnabled, captureOptions, interval, onScanned, onError, }) { - const isRunning = React.useRef(false); - const timeout = React.useRef(undefined); - async function scanAsync() { - // If interval is 0 then only scan once. - if (!isRunning.current || !onScanned) { - stop(); - return; - } - try { - const data = captureImageData(video.current, captureOptions); - if (data) { - const nativeEvent = await decode(data); - if (nativeEvent?.data) { - onScanned({ - nativeEvent, - }); - } - } - } - catch (error) { - if (onError) { - onError({ nativeEvent: error }); - } - } - finally { - // If interval is 0 then only scan once. - if (interval === 0) { - stop(); - return; - } - const intervalToUse = !interval || interval < 0 ? 16 : interval; - // @ts-ignore: Type 'Timeout' is not assignable to type 'number' - timeout.current = setTimeout(() => { - scanAsync(); - }, intervalToUse); - } - } - function stop() { - isRunning.current = false; - clearTimeout(timeout.current); - } - React.useEffect(() => { - if (isEnabled) { - isRunning.current = true; - scanAsync(); - } - return () => { - if (isEnabled) { - stop(); - } - }; - }, [isEnabled]); -} -//# sourceMappingURL=useWebQRScanner.js.map \ No newline at end of file diff --git a/packages/expo-camera/build/web/useWebQRScanner.js.map b/packages/expo-camera/build/web/useWebQRScanner.js.map deleted file mode 100644 index f04c532eefa8ec..00000000000000 --- a/packages/expo-camera/build/web/useWebQRScanner.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"useWebQRScanner.js","sourceRoot":"","sources":["../../src/web/useWebQRScanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,cAAc,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAa,EAAO,EAAE;IACjE,oCAAoC;IACpC,MAAM,OAAO,GAAI,IAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;QACtD,iBAAiB,EAAE,aAAa;KACjC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,OAAO,CAAC;IACnB,CAAC;IAED,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;QACjB,MAAM,WAAW,GAA0B;YACzC,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,YAAY,EAAE,EAAE;YAChB,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;SAClE,CAAC;QACF,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,WAAW,CAAC,YAAY,GAAG;gBACzB,MAAM,CAAC,QAAQ,CAAC,aAAa;gBAC7B,MAAM,CAAC,QAAQ,CAAC,gBAAgB;gBAChC,MAAM,CAAC,QAAQ,CAAC,cAAc;gBAC9B,MAAM,CAAC,QAAQ,CAAC,iBAAiB;aAClC,CAAC;QACJ,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAA+B,EAAK,EAAE,IAAc,EAAE,EAAE;IACxF,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,KAAK,IAAI,EAAE;YAChB,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACvF,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG;QACpB,eAAe,EAAE,CAAC,QAAQ,EAAE,GAAG;QAC/B,2BAA2B;QAC3B,qCAAqC;QACrC,6BAA6B;QAC7B,IAAI;KACL,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,aAAa,CAAC,OAAO,CAAC,iBAAiB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IAErD,uCAAuC;IACvC,MAAM,QAAQ,GAGR,EAAE,CAAC;IAET,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE5D,OAAO,CAAC,IAAsB,EAAE,EAAE;QAChC,OAAO,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACnC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,yBAAyB,CAAC,cAAc,EAAE;IACvD,0DAA0D;CAC3D,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe,CAC7B,KAAsD,EACtD,EACE,SAAS,EACT,cAAc,EACd,QAAQ,EACR,SAAS,EACT,OAAO,GAOR;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAU,KAAK,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAqB,SAAS,CAAC,CAAC;IAE5D,KAAK,UAAU,SAAS;QACtB,wCAAwC;QACxC,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;YACrC,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YAE7D,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,WAAW,GAAgC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;gBACpE,IAAI,WAAW,EAAE,IAAI,EAAE,CAAC;oBACtB,SAAS,CAAC;wBACR,WAAW;qBACZ,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,wCAAwC;YACxC,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,IAAI,EAAE,CAAC;gBACP,OAAO;YACT,CAAC;YACD,MAAM,aAAa,GAAG,CAAC,QAAQ,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;YAChE,gEAAgE;YAChE,OAAO,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAChC,SAAS,EAAE,CAAC;YACd,CAAC,EAAE,aAAa,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,SAAS,IAAI;QACX,SAAS,CAAC,OAAO,GAAG,KAAK,CAAC;QAC1B,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;YACzB,SAAS,EAAE,CAAC;QACd,CAAC;QAED,OAAO,GAAG,EAAE;YACV,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,EAAE,CAAC;YACT,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;AAClB,CAAC","sourcesContent":["import * as React from 'react';\n\nimport { captureImageData } from './WebCameraUtils';\nimport { BarcodeScanningResult, CameraPictureOptions, MountErrorListener } from '../Camera.types';\n\nconst qrWorkerMethod = ({ data, width, height }: ImageData): any => {\n // eslint-disable-next-line no-undef\n const decoded = (self as any).jsQR(data, width, height, {\n inversionAttempts: 'attemptBoth',\n });\n\n let parsed;\n try {\n parsed = JSON.parse(decoded);\n } catch {\n parsed = decoded;\n }\n\n if (parsed?.data) {\n const nativeEvent: BarcodeScanningResult = {\n type: 'qr',\n data: parsed.data,\n cornerPoints: [],\n bounds: { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 } },\n };\n if (parsed.location) {\n nativeEvent.cornerPoints = [\n parsed.location.topLeftCorner,\n parsed.location.bottomLeftCorner,\n parsed.location.topRightCorner,\n parsed.location.bottomRightCorner,\n ];\n }\n return nativeEvent;\n }\n return parsed;\n};\n\nconst createWorkerAsyncFunction = any>(fn: T, deps: string[]) => {\n if (typeof window === 'undefined') {\n return async () => {\n throw new Error('Cannot use createWorkerAsyncFunction in a non-browser environment');\n };\n }\n\n const stringifiedFn = [\n `self.func = ${fn.toString()};`,\n 'self.onmessage = (e) => {',\n ' const result = self.func(e.data);',\n ' self.postMessage(result);',\n '};',\n ];\n\n if (deps.length > 0) {\n stringifiedFn.unshift(`importScripts(${deps.map((dep) => `'${dep}'`).join(', ')});`);\n }\n\n const blob = new Blob(stringifiedFn, { type: 'text/javascript' });\n const worker = new Worker(URL.createObjectURL(blob));\n\n // First-In First-Out queue of promises\n const promises: {\n resolve: (value: ReturnType) => void;\n reject: (reason?: any) => void;\n }[] = [];\n\n worker.onmessage = (e) => promises.shift()?.resolve(e.data);\n\n return (data: Parameters[0]) => {\n return new Promise>((resolve, reject) => {\n promises.push({ resolve, reject });\n worker.postMessage(data);\n });\n };\n};\n\nconst decode = createWorkerAsyncFunction(qrWorkerMethod, [\n 'https://cdn.jsdelivr.net/npm/jsqr@1.2.0/dist/jsQR.min.js',\n]);\n\nexport function useWebQRScanner(\n video: React.MutableRefObject,\n {\n isEnabled,\n captureOptions,\n interval,\n onScanned,\n onError,\n }: {\n isEnabled: boolean;\n captureOptions: Pick;\n interval?: number;\n onScanned?: (scanningResult: { nativeEvent: BarcodeScanningResult }) => void;\n onError?: MountErrorListener;\n }\n) {\n const isRunning = React.useRef(false);\n const timeout = React.useRef(undefined);\n\n async function scanAsync() {\n // If interval is 0 then only scan once.\n if (!isRunning.current || !onScanned) {\n stop();\n return;\n }\n try {\n const data = captureImageData(video.current, captureOptions);\n\n if (data) {\n const nativeEvent: BarcodeScanningResult | any = await decode(data);\n if (nativeEvent?.data) {\n onScanned({\n nativeEvent,\n });\n }\n }\n } catch (error: any) {\n if (onError) {\n onError({ nativeEvent: error });\n }\n } finally {\n // If interval is 0 then only scan once.\n if (interval === 0) {\n stop();\n return;\n }\n const intervalToUse = !interval || interval < 0 ? 16 : interval;\n // @ts-ignore: Type 'Timeout' is not assignable to type 'number'\n timeout.current = setTimeout(() => {\n scanAsync();\n }, intervalToUse);\n }\n }\n\n function stop() {\n isRunning.current = false;\n clearTimeout(timeout.current);\n }\n\n React.useEffect(() => {\n if (isEnabled) {\n isRunning.current = true;\n scanAsync();\n }\n\n return () => {\n if (isEnabled) {\n stop();\n }\n };\n }, [isEnabled]);\n}\n"]} \ No newline at end of file diff --git a/packages/expo-camera/package.json b/packages/expo-camera/package.json index 942366eb40826e..34cf736c0529df 100644 --- a/packages/expo-camera/package.json +++ b/packages/expo-camera/package.json @@ -34,7 +34,7 @@ "preset": "expo-module-scripts" }, "dependencies": { - "invariant": "^2.2.4" + "barcode-detector": "^3.0.0" }, "devDependencies": { "expo-module-scripts": "^55.0.2" diff --git a/packages/expo-camera/src/Camera.types.ts b/packages/expo-camera/src/Camera.types.ts index 803294b6e7d8e5..a02d21baaa93af 100644 --- a/packages/expo-camera/src/Camera.types.ts +++ b/packages/expo-camera/src/Camera.types.ts @@ -328,7 +328,7 @@ export type BarcodeScanningResult = { * [Google MLKit's native order](https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/common/Barcode#getCornerPoints()) * is used, which is `topLeft`, `topRight`, `bottomRight`, `bottomLeft`. * On iOS, the order is `bottomLeft`, `bottomRight`, `topLeft`, `topRight`. On Web, the order is - * `topLeft`, `bottomLeft`, `topRight`, `bottomRight`. + * `topLeft`, `topRight`, `bottomRight`, `bottomLeft` (matching Android/BarcodeDetector order). * */ cornerPoints: BarcodePoint[]; diff --git a/packages/expo-camera/src/ExpoCamera.web.tsx b/packages/expo-camera/src/ExpoCamera.web.tsx index ed6aadfa444aba..c61c18a992ff4e 100644 --- a/packages/expo-camera/src/ExpoCamera.web.tsx +++ b/packages/expo-camera/src/ExpoCamera.web.tsx @@ -19,8 +19,8 @@ import { import CameraManager from './ExpoCameraManager.web'; import { capture } from './web/WebCameraUtils'; import { PictureSizes } from './web/WebConstants'; +import { useWebBarcodeScanner } from './web/useWebBarcodeScanner'; import { useWebCameraStream } from './web/useWebCameraStream'; -import { useWebQRScanner } from './web/useWebQRScanner'; export interface ExponentCameraRef { getAvailablePictureSizes: (ratio: string) => Promise; @@ -37,7 +37,14 @@ const ExponentCamera = ({ }: PropsWithChildren) => { const video = useRef(null); - const native = useWebCameraStream(video, facing as CameraType, props, { + const cameraSettings = useMemo(() => { + return { + ...props, + flashMode: props.enableTorch ? 'torch' : props.flashMode, + }; + }, [props.enableTorch, props.flashMode, props.zoom, props.autoFocus]); + + const native = useWebCameraStream(video, facing as CameraType, cameraSettings, { onCameraReady() { if (props.onCameraReady) { props.onCameraReady(); @@ -46,16 +53,17 @@ const ExponentCamera = ({ onMountError: props.onMountError, }); - const isQRScannerEnabled = useMemo(() => { - return Boolean( - props.barcodeScannerSettings?.barcodeTypes?.includes('qr') && !!props.onBarcodeScanned - ); - }, [props.barcodeScannerSettings?.barcodeTypes, props.onBarcodeScanned]); + const barcodeTypes = props.barcodeScannerSettings?.barcodeTypes; + + const isScannerEnabled = useMemo(() => { + return Boolean(barcodeTypes?.length && !!props.onBarcodeScanned); + }, [barcodeTypes, props.onBarcodeScanned]); - useWebQRScanner(video, { + useWebBarcodeScanner(video, { interval: 300, - isEnabled: isQRScannerEnabled, - captureOptions: { scale: 1, isImageMirror: native.type === 'front' }, + isEnabled: isScannerEnabled, + barcodeTypes: barcodeTypes ?? [], + isMirrored: native.type === 'front', onScanned(event) { if (props.onBarcodeScanned) { props.onBarcodeScanned(event); diff --git a/packages/expo-camera/src/ExpoCameraManager.web.ts b/packages/expo-camera/src/ExpoCameraManager.web.ts index 84808acb461cc5..8ee1f6bfd307aa 100644 --- a/packages/expo-camera/src/ExpoCameraManager.web.ts +++ b/packages/expo-camera/src/ExpoCameraManager.web.ts @@ -1,12 +1,15 @@ import { UnavailabilityError } from 'expo-modules-core'; import { + BarcodeType, + BarcodeScanningResult, CameraCapturedPicture, CameraPictureOptions, PermissionResponse, PermissionStatus, } from './Camera.types'; import { ExponentCameraRef } from './ExpoCamera.web'; +import * as WebBarcodeScanner from './web/WebBarcodeScanner'; import { canGetUserMedia, isBackCameraAvailableAsync, @@ -14,32 +17,7 @@ import { } from './web/WebUserMediaManager'; function getUserMedia(constraints: MediaStreamConstraints): Promise { - if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - return navigator.mediaDevices.getUserMedia(constraints); - } - - // Some browsers partially implement mediaDevices. We can't just assign an object - // with getUserMedia as it would overwrite existing properties. - // Here, we will just add the getUserMedia property if it's missing. - - // First get ahold of the legacy getUserMedia, if present - const getUserMedia = - // TODO: this method is deprecated, migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia - navigator.getUserMedia || - navigator.webkitGetUserMedia || - navigator.mozGetUserMedia || - function () { - const error: any = new Error('Permission unimplemented'); - error.code = 0; - error.name = 'NotAllowedError'; - throw error; - }; - return new Promise((resolve, reject) => { - // TODO(@kitten): The types indicates that this is incorrect. - // Please check whether this is correct! - // @ts-expect-error: The `successCallback` doesn't match a `resolve` function - getUserMedia.call(navigator, constraints, resolve, reject); - }); + return navigator.mediaDevices.getUserMedia(constraints); } function handleGetUserMediaError({ message }: { message: string }): PermissionResponse { @@ -134,6 +112,11 @@ async function handlePermissionsQueryAsync( } export default { + isModernBarcodeScannerAvailable: false, + toggleRecordingAsyncAvailable: false, + addListener(_eventName: string, _listener: (...args: any[]) => any) { + return { remove: () => {} }; + }, get Type() { return { back: 'back', @@ -240,4 +223,17 @@ export default { return handleGetUserMediaError(error.message); } }, + async scanFromURLAsync( + url: string, + barcodeTypes?: BarcodeType[] + ): Promise { + const response = await fetch(url); + const blob = await response.blob(); + const bitmap = await createImageBitmap(blob); + const types: BarcodeType[] = + barcodeTypes && barcodeTypes.length > 0 ? barcodeTypes : WebBarcodeScanner.ALL_BARCODE_TYPES; + const results = await WebBarcodeScanner.detect(bitmap, types); + bitmap.close(); + return results; + }, }; diff --git a/packages/expo-camera/src/ts-declarations/lib.dom.d.ts b/packages/expo-camera/src/ts-declarations/lib.dom.d.ts index b8a5418529102d..597d259f5bba2a 100644 --- a/packages/expo-camera/src/ts-declarations/lib.dom.d.ts +++ b/packages/expo-camera/src/ts-declarations/lib.dom.d.ts @@ -2,24 +2,9 @@ export {}; /** - * Handle deprecations and missing typings that not available in the main lib.dom.d.ts file. + * Handle missing typings that are not available in the main lib.dom.d.ts file. */ declare global { - type GetUserMediaFunctionType = ( - constraints: MediaStreamConstraints, - successCallback: () => MediaStream, - failureCallback: () => DOMException - ) => undefined; - interface Navigator { - /** - * This method has been deprecated: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getUserMedia - * TODO: migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia - */ - getUserMedia?: GetUserMediaFunctionType; - webkitGetUserMedia?: GetUserMediaFunctionType; - mozGetUserMedia?: GetUserMediaFunctionType; - } - type PermissionNameWithAdditionalValues = PermissionName | 'camera' | 'microphone'; // TODO: remove once "microphone" name is added to the PermissionName union type exposed by the main lib.dom.d.ts file. diff --git a/packages/expo-camera/src/web/WebBarcodeScanner.ts b/packages/expo-camera/src/web/WebBarcodeScanner.ts new file mode 100644 index 00000000000000..c334b8749af891 --- /dev/null +++ b/packages/expo-camera/src/web/WebBarcodeScanner.ts @@ -0,0 +1,94 @@ +import type { BarcodeType, BarcodeScanningResult } from '../Camera.types'; + +/** + * Mapping from expo BarcodeType to BarcodeDetector format string. + * @see https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API#supported_barcode_formats + */ +const EXPO_TO_WEB_FORMAT: Record = { + aztec: 'aztec', + codabar: 'codabar', + code39: 'code_39', + code93: 'code_93', + code128: 'code_128', + datamatrix: 'data_matrix', + ean8: 'ean_8', + ean13: 'ean_13', + itf14: 'itf', + pdf417: 'pdf417', + qr: 'qr_code', + upc_a: 'upc_a', + upc_e: 'upc_e', +}; + +const WEB_TO_EXPO_FORMAT: Record = Object.fromEntries( + Object.entries(EXPO_TO_WEB_FORMAT).map(([expo, web]) => [web, expo as BarcodeType]) +); + +export const ALL_BARCODE_TYPES = Object.keys(EXPO_TO_WEB_FORMAT) as BarcodeType[]; + +type BarcodeDetectorLike = { + detect(source: ImageBitmapSource): Promise; +}; + +type DetectedBarcodeLike = { + format: string; + rawValue: string; + boundingBox: DOMRectReadOnly; + cornerPoints: { x: number; y: number }[]; +}; + +let cachedDetector: BarcodeDetectorLike | null = null; +let cachedFormats: string[] | null = null; + +function formatsChanged(barcodeTypes: BarcodeType[]): boolean { + const webFormats = barcodeTypes.map((t) => EXPO_TO_WEB_FORMAT[t]).sort(); + if (!cachedFormats) { + return true; + } + if (cachedFormats.length !== webFormats.length) { + return true; + } + return webFormats.some((f, i) => f !== cachedFormats![i]); +} + +async function getDetector(barcodeTypes: BarcodeType[]): Promise { + if (cachedDetector && !formatsChanged(barcodeTypes)) { + return cachedDetector; + } + + const webFormats = barcodeTypes.map((t) => EXPO_TO_WEB_FORMAT[t]); + cachedFormats = [...webFormats].sort(); + + const NativeBarcodeDetector = (globalThis as any).BarcodeDetector; + if (typeof NativeBarcodeDetector !== 'undefined') { + const detector: BarcodeDetectorLike = new NativeBarcodeDetector({ formats: webFormats }); + cachedDetector = detector; + return detector; + } + + const { BarcodeDetector } = await import('barcode-detector'); + const detector: BarcodeDetectorLike = new BarcodeDetector({ formats: webFormats as any }); + cachedDetector = detector; + return detector; +} + +export async function detect( + source: ImageBitmapSource, + barcodeTypes: BarcodeType[] +): Promise { + const detector = await getDetector(barcodeTypes); + const barcodes = await detector.detect(source); + + return barcodes.map((barcode) => { + const { x, y, width, height } = barcode.boundingBox; + return { + type: WEB_TO_EXPO_FORMAT[barcode.format] ?? barcode.format, + data: barcode.rawValue, + bounds: { + origin: { x, y }, + size: { width, height }, + }, + cornerPoints: barcode.cornerPoints?.map((p) => ({ x: p.x, y: p.y })) ?? [], + }; + }); +} diff --git a/packages/expo-camera/src/web/WebCameraUtils.ts b/packages/expo-camera/src/web/WebCameraUtils.ts index 685e54c4dc1a2a..3132b33f4faf9c 100644 --- a/packages/expo-camera/src/web/WebCameraUtils.ts +++ b/packages/expo-camera/src/web/WebCameraUtils.ts @@ -1,6 +1,4 @@ /* eslint-env browser */ -import invariant from 'invariant'; - import * as CapabilityUtils from './WebCapabilityUtils'; import { CameraTypeToFacingMode, ImageTypeFormat, MinimumConstraints } from './WebConstants'; import { requestUserMediaAsync } from './WebUserMediaManager'; @@ -36,18 +34,8 @@ export function toDataURL( imageType: ImageType, quality: number ): string { - const types = ['png', 'jpg']; - invariant( - types.includes(imageType), - `expo-camera: ${imageType} is not a valid ImageType. Expected a string from: ${types.join(', ')}` - ); - const format = ImageTypeFormat[imageType]; if (imageType === 'jpg') { - invariant( - quality <= 1 && quality >= 0, - `expo-camera: ${quality} is not a valid image quality. Expected a number from 0...1` - ); return canvas.toDataURL(format, quality); } else { return canvas.toDataURL(format); @@ -79,24 +67,6 @@ function ensureCameraPictureOptions(config: CameraPictureOptions): CameraPicture const DEFAULT_QUALITY = 0.92; -export function captureImageData( - video: HTMLVideoElement | null, - pictureOptions: Pick = {} -): ImageData | null { - if (!video || video.readyState !== video.HAVE_ENOUGH_DATA) { - return null; - } - const canvas = captureImageContext(video, pictureOptions); - - const context = canvas.getContext('2d', { alpha: false }); - if (!context || !canvas.width || !canvas.height) { - return null; - } - - const imageData = context.getImageData(0, 0, canvas.width, canvas.height); - return imageData; -} - export function captureImageContext( video: HTMLVideoElement, { scale = 1, isImageMirror = false }: Pick @@ -365,38 +335,12 @@ export function stopMediaStream(stream: MediaStream | null) { if (!stream) { return; } - if (stream.getAudioTracks) { - stream.getAudioTracks().forEach((track) => track.stop()); - } - if (stream.getVideoTracks) { - stream.getVideoTracks().forEach((track) => track.stop()); - } - if (isMediaStreamTrack(stream)) { - stream.stop(); - } + stream.getAudioTracks().forEach((track) => track.stop()); + stream.getVideoTracks().forEach((track) => track.stop()); } -export function setVideoSource( - video: HTMLVideoElement, - stream: MediaStream | MediaSource | Blob | null -): void { - const createObjectURL = window.URL.createObjectURL ?? window.webkitURL.createObjectURL; - - if (typeof video.srcObject !== 'undefined') { - video.srcObject = stream; - } else if (typeof (video as any).mozSrcObject !== 'undefined') { - (video as any).mozSrcObject = stream; - } else if (stream && createObjectURL) { - video.src = createObjectURL(stream as MediaSource | Blob); - } - - if (!stream) { - const revokeObjectURL = window.URL.revokeObjectURL ?? window.webkitURL.revokeObjectURL; - const source = video.src ?? video.srcObject ?? (video as any).mozSrcObject; - if (revokeObjectURL && typeof source === 'string') { - revokeObjectURL(source); - } - } +export function setVideoSource(video: HTMLVideoElement, stream: MediaStream | null): void { + video.srcObject = stream; } export function isCapabilityAvailable( @@ -413,10 +357,6 @@ export function isCapabilityAvailable( return false; } -function isMediaStreamTrack(input: any): input is MediaStreamTrack { - return typeof input.stop === 'function'; -} - function convertNormalizedSetting(range: MediaSettingsRange, value?: number): number | undefined { if (!value) { return; diff --git a/packages/expo-camera/src/web/WebUserMediaManager.ts b/packages/expo-camera/src/web/WebUserMediaManager.ts index 2e1e80b53ff2c6..9dfbb1fde2ac6b 100644 --- a/packages/expo-camera/src/web/WebUserMediaManager.ts +++ b/packages/expo-camera/src/web/WebUserMediaManager.ts @@ -1,69 +1,6 @@ /* eslint-env browser */ -/** - * A web-only module for ponyfilling the UserMedia API. - */ import { Platform } from 'expo-modules-core'; -export const userMediaRequested: boolean = false; - -export const mountedInstances: any[] = []; - -async function requestLegacyUserMediaAsync( - // TODO(@kitten): Type this properly - props: { audioConstraints?: any; videoConstraints?: any } -): Promise { - // TODO(@kitten): This is never type checked against DOM types - const optionalSource = (id: string | string[] | null) => ({ optional: [{ sourceId: id }] }); - - const constraintToSourceId = (constraint: MediaTrackConstraintSet) => { - const { deviceId } = constraint; - - if (typeof deviceId === 'string') { - return deviceId; - } - - if (Array.isArray(deviceId)) { - return deviceId[0] ?? null; - } else if (typeof deviceId === 'object' && deviceId.ideal) { - return deviceId.ideal; - } - - return null; - }; - - const sources: any[] = await new Promise((resolve) => - // @ts-ignore: https://caniuse.com/#search=getSources Chrome for Android (78) & Samsung Internet (10.1) use this - MediaStreamTrack.getSources((sources) => resolve(sources)) - ); - - let audioSource = null; - let videoSource = null; - - sources.forEach((source) => { - if (source.kind === 'audio') { - audioSource = source.id; - } else if (source.kind === 'video') { - videoSource = source.id; - } - }); - - // NOTE(@kitten): This doesn't seem right. The types that should be used here don't contain `audioConstraints` - // If this is legacy, the type shouldn't have been dropped but marked as `@deprecated`. Alternatively, remove this code path - const audioSourceId = constraintToSourceId(props.audioConstraints); - if (audioSourceId) { - audioSource = audioSourceId; - } - - // NOTE(@kitten): This doesn't seem right. The types that should be used here don't contain `videoConstraints` - // If this is legacy, the type shouldn't have been dropped but marked as `@deprecated`. Alternatively, remove this code path - const videoSourceId = constraintToSourceId(props.videoConstraints); - if (videoSourceId) { - videoSource = videoSourceId; - } - - return [optionalSource(audioSource), optionalSource(videoSource)]; -} - async function sourceSelectedAsync( isMuted: boolean, audioConstraints?: MediaTrackConstraints | boolean, @@ -81,17 +18,10 @@ async function sourceSelectedAsync( } export async function requestUserMediaAsync( - // TODO(@kitten): Type this properly props: { audio?: any; video?: any }, isMuted: boolean = true ): Promise { - if (canGetUserMedia()) { - return await sourceSelectedAsync(isMuted, props.audio, props.video); - } - // NOTE(@kitten): This doesn't seem right. The types that should be used here don't contain `videoConstraints` - // If this is legacy, the type shouldn't have been dropped but marked as `@deprecated`. Alternatively, remove this code path - const [audio, video] = await requestLegacyUserMediaAsync(props as any); - return await sourceSelectedAsync(isMuted, audio, video); + return await sourceSelectedAsync(isMuted, props.audio, props.video); } export async function getAnyUserMediaAsync( @@ -99,7 +29,7 @@ export async function getAnyUserMediaAsync( ignoreConstraints: boolean = false ): Promise { try { - return await getUserMediaAsync({ + return await navigator.mediaDevices.getUserMedia({ ...constraints, video: ignoreConstraints || constraints.video, }); @@ -115,35 +45,8 @@ export async function getAnyUserMediaAsync( } } -export async function getUserMediaAsync(constraints: MediaStreamConstraints): Promise { - if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - return navigator.mediaDevices.getUserMedia(constraints); - } - - const _getUserMedia = - navigator['mozGetUserMedia'] || - navigator['webkitGetUserMedia'] || - // @ts-expect-error: TODO(@kitten): Remove / Drop IE support - navigator['msGetUserMedia']; - return new Promise((resolve, reject) => - _getUserMedia.call(navigator, constraints, resolve, reject) - ); -} - export function canGetUserMedia(): boolean { - // TODO(@kitten): This is misaligned with the implementations in `expo-audio/src/AudioModule.web.ts` and `expo-av` - return ( - // SSR - Platform.isDOMAvailable && - // Has any form of media API - !!( - (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) || - navigator['mozGetUserMedia'] || - navigator['webkitGetUserMedia'] || - // @ts-expect-error: TODO(@kitten): Remove / Drop IE support - navigator['msGetUserMedia'] - ) - ); + return Platform.isDOMAvailable && !!navigator.mediaDevices?.getUserMedia; } export async function isFrontCameraAvailableAsync( diff --git a/packages/expo-camera/src/web/useWebBarcodeScanner.ts b/packages/expo-camera/src/web/useWebBarcodeScanner.ts new file mode 100644 index 00000000000000..5d011e02e1ac54 --- /dev/null +++ b/packages/expo-camera/src/web/useWebBarcodeScanner.ts @@ -0,0 +1,128 @@ +import * as React from 'react'; + +import * as WebBarcodeScanner from './WebBarcodeScanner'; +import { BarcodeType, BarcodeScanningResult, MountErrorListener } from '../Camera.types'; + +function mapToViewCoordinates( + result: BarcodeScanningResult, + videoWidth: number, + viewHeight: number, + height: number, + width: number, + isMirrored: boolean +): BarcodeScanningResult { + const scaleX = width / videoWidth; + const scaleY = viewHeight / height; + + const mapPoint = (p: { x: number; y: number }) => { + const x = isMirrored ? width - p.x * scaleX : p.x * scaleX; + const y = p.y * scaleY; + return { x, y }; + }; + + const origin = mapPoint(result.bounds.origin); + const size = { + width: result.bounds.size.width * scaleX, + height: result.bounds.size.height * scaleY, + }; + + if (isMirrored) { + origin.x -= size.width; + } + + return { + ...result, + bounds: { origin, size }, + cornerPoints: result.cornerPoints.map(mapPoint), + }; +} + +export function useWebBarcodeScanner( + video: React.RefObject, + { + isEnabled, + barcodeTypes, + interval, + isMirrored = false, + onScanned, + onError, + }: { + isEnabled: boolean; + barcodeTypes: BarcodeType[]; + interval?: number; + isMirrored?: boolean; + onScanned?: (scanningResult: { nativeEvent: BarcodeScanningResult }) => void; + onError?: MountErrorListener; + } +) { + const isRunning = React.useRef(false); + const timeout = React.useRef | undefined>(undefined); + + async function scanAsync() { + if (!isRunning.current || !onScanned) { + stop(); + return; + } + try { + const videoEl = video.current; + if (!videoEl || videoEl.readyState !== videoEl.HAVE_ENOUGH_DATA) { + return; + } + + const { videoWidth, videoHeight } = videoEl; + if (!videoWidth || !videoHeight) { + return; + } + + const bitmap = await createImageBitmap(videoEl); + const results = await WebBarcodeScanner.detect(bitmap, barcodeTypes); + bitmap.close(); + + const viewWidth = videoEl.clientWidth || videoWidth; + const viewHeight = videoEl.clientHeight || videoHeight; + + for (const raw of results) { + const nativeEvent = mapToViewCoordinates( + raw, + videoWidth, + videoHeight, + viewWidth, + viewHeight, + isMirrored + ); + onScanned({ nativeEvent }); + } + } catch (error: any) { + if (onError) { + onError({ nativeEvent: error }); + } + } finally { + if (interval === 0) { + stop(); + return; + } + const intervalToUse = !interval || interval < 0 ? 16 : interval; + timeout.current = setTimeout(() => { + scanAsync(); + }, intervalToUse); + } + } + + function stop() { + isRunning.current = false; + clearTimeout(timeout.current); + } + + React.useEffect(() => { + if (isEnabled) { + isRunning.current = true; + scanAsync(); + } + + return () => { + if (isEnabled) { + stop(); + } + }; + }, [isEnabled]); +} diff --git a/packages/expo-camera/src/web/useWebCameraStream.ts b/packages/expo-camera/src/web/useWebCameraStream.ts index 29cc6b1af393e6..ae405849c4e2bf 100644 --- a/packages/expo-camera/src/web/useWebCameraStream.ts +++ b/packages/expo-camera/src/web/useWebCameraStream.ts @@ -58,7 +58,7 @@ export function useWebCameraStream( autoFocus: 'continuous', flashMode: 'off', whiteBalance: 'continuous', - zoom: 1, + zoom: 0, }); const [stream, setStream] = React.useState(null); diff --git a/packages/expo-camera/src/web/useWebQRScanner.ts b/packages/expo-camera/src/web/useWebQRScanner.ts deleted file mode 100644 index cf65a621efcf72..00000000000000 --- a/packages/expo-camera/src/web/useWebQRScanner.ts +++ /dev/null @@ -1,152 +0,0 @@ -import * as React from 'react'; - -import { captureImageData } from './WebCameraUtils'; -import { BarcodeScanningResult, CameraPictureOptions, MountErrorListener } from '../Camera.types'; - -const qrWorkerMethod = ({ data, width, height }: ImageData): any => { - // eslint-disable-next-line no-undef - const decoded = (self as any).jsQR(data, width, height, { - inversionAttempts: 'attemptBoth', - }); - - let parsed; - try { - parsed = JSON.parse(decoded); - } catch { - parsed = decoded; - } - - if (parsed?.data) { - const nativeEvent: BarcodeScanningResult = { - type: 'qr', - data: parsed.data, - cornerPoints: [], - bounds: { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 } }, - }; - if (parsed.location) { - nativeEvent.cornerPoints = [ - parsed.location.topLeftCorner, - parsed.location.bottomLeftCorner, - parsed.location.topRightCorner, - parsed.location.bottomRightCorner, - ]; - } - return nativeEvent; - } - return parsed; -}; - -const createWorkerAsyncFunction = any>(fn: T, deps: string[]) => { - if (typeof window === 'undefined') { - return async () => { - throw new Error('Cannot use createWorkerAsyncFunction in a non-browser environment'); - }; - } - - const stringifiedFn = [ - `self.func = ${fn.toString()};`, - 'self.onmessage = (e) => {', - ' const result = self.func(e.data);', - ' self.postMessage(result);', - '};', - ]; - - if (deps.length > 0) { - stringifiedFn.unshift(`importScripts(${deps.map((dep) => `'${dep}'`).join(', ')});`); - } - - const blob = new Blob(stringifiedFn, { type: 'text/javascript' }); - const worker = new Worker(URL.createObjectURL(blob)); - - // First-In First-Out queue of promises - const promises: { - resolve: (value: ReturnType) => void; - reject: (reason?: any) => void; - }[] = []; - - worker.onmessage = (e) => promises.shift()?.resolve(e.data); - - return (data: Parameters[0]) => { - return new Promise>((resolve, reject) => { - promises.push({ resolve, reject }); - worker.postMessage(data); - }); - }; -}; - -const decode = createWorkerAsyncFunction(qrWorkerMethod, [ - 'https://cdn.jsdelivr.net/npm/jsqr@1.2.0/dist/jsQR.min.js', -]); - -export function useWebQRScanner( - video: React.MutableRefObject, - { - isEnabled, - captureOptions, - interval, - onScanned, - onError, - }: { - isEnabled: boolean; - captureOptions: Pick; - interval?: number; - onScanned?: (scanningResult: { nativeEvent: BarcodeScanningResult }) => void; - onError?: MountErrorListener; - } -) { - const isRunning = React.useRef(false); - const timeout = React.useRef(undefined); - - async function scanAsync() { - // If interval is 0 then only scan once. - if (!isRunning.current || !onScanned) { - stop(); - return; - } - try { - const data = captureImageData(video.current, captureOptions); - - if (data) { - const nativeEvent: BarcodeScanningResult | any = await decode(data); - if (nativeEvent?.data) { - onScanned({ - nativeEvent, - }); - } - } - } catch (error: any) { - if (onError) { - onError({ nativeEvent: error }); - } - } finally { - // If interval is 0 then only scan once. - if (interval === 0) { - stop(); - return; - } - const intervalToUse = !interval || interval < 0 ? 16 : interval; - // @ts-ignore: Type 'Timeout' is not assignable to type 'number' - timeout.current = setTimeout(() => { - scanAsync(); - }, intervalToUse); - } - } - - function stop() { - isRunning.current = false; - clearTimeout(timeout.current); - } - - React.useEffect(() => { - if (isEnabled) { - isRunning.current = true; - scanAsync(); - } - - return () => { - if (isEnabled) { - stop(); - } - }; - }, [isEnabled]); -} diff --git a/packages/expo-router/CHANGELOG.md b/packages/expo-router/CHANGELOG.md index d8ed55f65b4daa..6532f3319d1ae2 100644 --- a/packages/expo-router/CHANGELOG.md +++ b/packages/expo-router/CHANGELOG.md @@ -6,8 +6,12 @@ ### ๐ŸŽ‰ New features +- [ios] support custom images in submenus ([#43414](https://github.com/expo/expo/pull/43414) by [@Ubax](https://github.com/Ubax)) + ### ๐Ÿ› Bug fixes +- [ios] add better modal and preview handling when using zoom transition ([#43370](https://github.com/expo/expo/pull/43370) by [@Ubax](https://github.com/Ubax)) + ### ๐Ÿ’ก Others ## 55.0.0 โ€” 2026-02-25 diff --git a/packages/expo-router/CLAUDE.md b/packages/expo-router/CLAUDE.md index c1ec1f9ca0514a..2f03efb529a0b0 100644 --- a/packages/expo-router/CLAUDE.md +++ b/packages/expo-router/CLAUDE.md @@ -310,6 +310,7 @@ To run the docs site locally run `yarn dev` in the `docs/` directory of the mono - Always use latest React 19 hooks and patterns - `use` instead of `useContext`, `useId`, etc. - Make sure the code works with and without React Compiler enabled. - Don't use `any` types, unless strictly necessary. Use `unknown` instead and narrow types as much as possible. +- Never import files with platform-specific extensions directly. Always import from the base path and let the bundler resolve the correct file. Correct `import { Component } from './Component'`, not `import { Component } from './Component.ios'`. ## Maintaining This Document diff --git a/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.d.ts.map b/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.d.ts.map index eb4fe407e70a59..efdc41f8ef0c2a 100644 --- a/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.d.ts.map +++ b/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"StackToolbarMenu.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"StackToolbarMenu.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.js b/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.js index 85a3542cda2a84..a0a73ca1e28d50 100644 --- a/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.js +++ b/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.js @@ -118,6 +118,15 @@ function convertStackToolbarMenuPropsToRNHeaderItem(props, isBottomPlacement = f } return item; } +// Custom menu action icons are not supported in react-navigation yet +// But they are supported in react-native-screens +// TODO(@ubax): Remove this workaround once react-navigation supports custom icons for menu actions. +// https://linear.app/expo/issue/ENG-19853/remove-custom-conversion-logic-for-icon-from-packagesexpo +function convertImageIconToPlatformIcon(icon) { + return icon.tinted + ? { type: 'templateSource', templateSource: icon.source } + : { type: 'imageSource', imageSource: icon.source }; +} function convertStackToolbarSubmenuMenuPropsToRNHeaderItem(props) { if (props.hidden) { return undefined; @@ -148,13 +157,11 @@ function convertStackToolbarSubmenuMenuPropsToRNHeaderItem(props) { } // TODO: Add elementSize to react-native-screens if (sharedProps.icon) { - // Only SF Symbols are supported in submenu icons - // TODO(@ubax): Add support for other images in react-native-screens if (sharedProps.icon.type === 'sfSymbol') { item.icon = sharedProps.icon; } else { - console.warn('When Icon is used inside Stack.Toolbar.Menu used as a submenu, only sfSymbol icons are supported. This is a limitation of React Native Screens.'); + item.icon = convertImageIconToPlatformIcon(sharedProps.icon); } } return item; @@ -209,13 +216,11 @@ function convertStackToolbarMenuActionPropsToRNHeaderItem(props) { item.keepsMenuPresented = unstable_keepPresented; } if (sharedProps.icon) { - // Only SF Symbols are supported in submenu icons - // TODO(@ubax): Add support for other images in react-native-screens if (sharedProps.icon.type === 'sfSymbol') { item.icon = sharedProps.icon; } else { - console.warn('When Icon is used inside Stack.Toolbar.MenuAction, only sfSymbol icons are supported. This is a limitation of React Native Screens.'); + item.icon = convertImageIconToPlatformIcon(sharedProps.icon); } } return item; diff --git a/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.js.map b/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.js.map index 15dec22d4576de..4dc73e809b88be 100644 --- a/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.js.map +++ b/packages/expo-router/build/layouts/stack-utils/toolbar/StackToolbarMenu.js.map @@ -1 +1 @@ -{"version":3,"file":"StackToolbarMenu.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport type {\n NativeStackHeaderItemMenu,\n NativeStackHeaderItemMenuAction,\n NativeStackHeaderItemMenuSubmenu,\n} from '@react-navigation/native-stack';\nimport type { ImageRef } from 'expo-image';\nimport { Children, useId, useMemo, type ReactNode } from 'react';\nimport {\n StyleSheet,\n type ColorValue,\n type ImageSourcePropType,\n type StyleProp,\n type TextStyle,\n} from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport { useToolbarPlacement } from './context';\nimport {\n convertStackHeaderSharedPropsToRNSharedHeaderItem,\n extractIconRenderingMode,\n extractXcassetName,\n type StackHeaderItemSharedProps,\n} from './shared';\nimport { StackToolbarLabel, StackToolbarIcon, StackToolbarBadge } from './toolbar-primitives';\nimport { LinkMenuAction } from '../../../link/elements';\nimport { NativeLinkPreviewAction } from '../../../link/preview/native';\nimport {\n filterAllowedChildrenElements,\n getFirstChildOfType,\n isChildOfType,\n} from '../../../utils/children';\n\n/**\n * Computes the label and menu title from children and title prop.\n *\n * - If only `title` prop is provided, it is used for both the label (button text) and menu title\n * - If only `.Label` child is provided, it is used for the label and the menu title is an empty string\n * - If both `.Label` child and `title` prop are provided. `.Label` is used for the label, and `title` is used for the menu title\n */\nfunction computeMenuLabelAndTitle(\n children: ReactNode,\n title: string | undefined\n): { label: string; menuTitle: string } {\n const labelChild = getFirstChildOfType(children, StackToolbarLabel);\n const labelFromChild = labelChild?.props.children;\n return {\n label: labelFromChild ?? title ?? '',\n menuTitle: title ?? '',\n };\n}\n\nexport interface StackToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n /**\n * Menu content - can include icons, labels, badges and menu actions.\n *\n * @example\n * ```tsx\n * \n * \n * Options\n * {}}>Action 1\n * \n * ```\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n disabled?: boolean;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n *\n * > **Note**: This prop is only supported in toolbar with `placement=\"bottom\"`.\n */\n image?: ImageRef;\n /**\n * Whether to hide the shared background.\n *\n * @see [Official Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/hidessharedbackground) for more information.\n *\n * @platform iOS 26+\n */\n hidesSharedBackground?: boolean;\n /**\n * Whether the menu should be hidden.\n *\n * @default false\n */\n hidden?: boolean;\n /**\n * Icon for the menu item.\n *\n * Can be an SF Symbol name or an image source.\n *\n * > **Note**: When used in `placement=\"bottom\"`, only string SFSymbols are supported. Use the `image` prop to provide custom images.\n */\n icon?: StackHeaderItemSharedProps['icon'];\n /**\n * Controls how image-based icons are rendered on iOS.\n *\n * - `'template'`: iOS applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: Preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\n /**\n * If `true`, the menu will be displayed inline.\n * This means that the menu will not be collapsed\n *\n * > **Note**: Inline menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayinline) for more information.\n */\n inline?: boolean;\n /**\n * If `true`, the menu will be displayed as a palette.\n * This means that the menu will be displayed as one row\n *\n * > **Note**: Palette menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayaspalette) for more information.\n */\n palette?: boolean;\n /**\n * Whether to separate the background of this item from other header items.\n *\n * @default false\n */\n separateBackground?: boolean;\n /**\n * Style for the label of the header item.\n */\n style?: StackHeaderItemSharedProps['style'];\n /**\n * The tint color to apply to the button item\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/tintcolor) for more information.\n */\n tintColor?: StackHeaderItemSharedProps['tintColor'];\n /**\n * Optional title to show on top of the menu.\n */\n title?: string;\n /**\n * @default 'plain'\n */\n variant?: StackHeaderItemSharedProps['variant'];\n // TODO(@ubax): Add elementSize support in react-native-screens for header menus.\n /**\n * The preferred size of the menu elements.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/preferredelementsize) for more information.\n *\n * @platform iOS 16.0+\n */\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Use as `Stack.Toolbar.Menu` to provide menus in iOS toolbar.\n * It accepts `Stack.Toolbar.MenuAction` and nested `Stack.Toolbar.Menu`\n * elements. Menu can be configured using both component props and child\n * elements.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n * import { Alert } from 'react-native';\n *\n * export default function Page() {\n * return (\n * <>\n * \n * \n * Alert.alert('Action pressed!')}>\n * Action 1\n * \n * \n * \n * \n * \n * );\n * }\n * ```\n *\n * @see [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/menus) for more information about menus on iOS.\n *\n * @platform ios\n */\nexport const StackToolbarMenu: React.FC = (props) => {\n const placement = useToolbarPlacement();\n\n if (placement !== 'bottom') {\n // For placement other than bottom, this component will not render, and should be\n // converted to RN header item using convertStackToolbarMenuPropsToRNHeaderItem.\n // So if we reach here, it means we're not inside a toolbar or something else is wrong.\n throw new Error('Stack.Toolbar.Menu must be used inside a Stack.Toolbar');\n }\n\n const validChildren = useMemo(\n () => filterAllowedChildrenElements(props.children, ALLOWED_CHILDREN),\n [props.children]\n );\n\n const sharedProps = convertStackToolbarMenuPropsToRNHeaderItem(props, true);\n\n const computedLabel = sharedProps?.label;\n const computedMenuTitle = sharedProps?.menu?.title;\n const icon = sharedProps?.icon?.type === 'sfSymbol' ? sharedProps.icon.name : undefined;\n const xcassetName = extractXcassetName(props);\n const imageRenderingMode = extractIconRenderingMode(props) ?? props.iconRenderingMode;\n\n if (process.env.NODE_ENV !== 'production') {\n const allChildren = Children.toArray(props.children);\n if (allChildren.length !== validChildren.length) {\n throw new Error(\n `Stack.Toolbar.Menu only accepts Stack.Toolbar.Menu, Stack.Toolbar.MenuAction, Stack.Toolbar.Label, Stack.Toolbar.Icon, and Stack.Toolbar.Badge as its children.`\n );\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n const hasBadge = getFirstChildOfType(props.children, StackToolbarBadge);\n if (hasBadge) {\n console.warn(\n 'Stack.Toolbar.Badge is not supported in bottom toolbar (iOS limitation). The badge will be ignored.'\n );\n }\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n return (\n \n );\n};\n\nexport function convertStackToolbarMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps,\n isBottomPlacement: boolean = false\n): NativeStackHeaderItemMenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const { title, ...rest } = props;\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n\n const { label: computedLabel, menuTitle: computedMenuTitle } = computeMenuLabelAndTitle(\n props.children,\n title\n );\n\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(rest, isBottomPlacement);\n\n const item: NativeStackHeaderItemMenu = {\n ...sharedProps,\n label: computedLabel,\n type: 'menu',\n menu: {\n multiselectable: true,\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n },\n };\n if (computedMenuTitle) {\n item.menu.title = computedMenuTitle;\n }\n\n return item;\n}\n\nfunction convertStackToolbarSubmenuMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps\n): NativeStackHeaderItemMenuSubmenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n\n const item: NativeStackHeaderItemMenuSubmenu = {\n type: 'submenu',\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n label: sharedProps.label || props.title || '',\n multiselectable: true,\n };\n\n if (props.inline !== undefined) {\n item.inline = props.inline;\n }\n if (props.palette !== undefined) {\n item.layout = props.palette ? 'palette' : 'default';\n }\n if (props.destructive !== undefined) {\n item.destructive = props.destructive;\n }\n // TODO: Add elementSize to react-native-screens\n\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n // TODO(@ubax): Add support for other images in react-native-screens\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Toolbar.Menu used as a submenu, only sfSymbol icons are supported. This is a limitation of React Native Screens.'\n );\n }\n }\n\n return item;\n}\n\nexport interface StackToolbarMenuActionProps {\n /**\n * Can be an Icon, Label or string title.\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be disabled and not selectable.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/disabled) for more information.\n */\n disabled?: boolean;\n icon?: SFSymbol | ImageSourcePropType;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu action.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n */\n image?: ImageRef;\n /**\n * Controls how image-based icons are rendered on iOS.\n *\n * - `'template'`: iOS applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: Preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n /**\n * If `true`, the menu will be kept presented after the action is selected.\n *\n * This is marked as unstable, because when action is selected it will recreate the menu,\n * which will close all opened submenus and reset the scroll position.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/keepsmenupresented) for more information.\n */\n unstable_keepPresented?: boolean;\n /**\n * If `true`, the menu item will be displayed as selected.\n */\n isOn?: boolean;\n onPress?: () => void;\n /**\n * An elaborated title that explains the purpose of the action.\n */\n discoverabilityLabel?: string;\n /**\n * An optional subtitle for the menu item.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/subtitle) for more information.\n */\n subtitle?: string;\n hidden?: boolean;\n}\n\n/**\n * An action item for a `Stack.Toolbar.Menu`.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * \n * \n * alert('Action pressed!')}>\n * Action 1\n * \n * \n * \n * \n * \n * );\n * }\n * ```\n *\n * @platform ios\n */\nexport const StackToolbarMenuAction: React.FC = (props) => {\n const placement = useToolbarPlacement();\n\n if (placement !== 'bottom') {\n throw new Error('Stack.Toolbar.MenuAction must be used inside a Stack.Toolbar.Menu');\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n const icon = typeof props.icon === 'string' ? props.icon : undefined;\n return (\n \n );\n};\n\nexport function convertStackToolbarMenuActionPropsToRNHeaderItem(\n props: StackToolbarMenuActionProps\n): NativeStackHeaderItemMenuAction {\n const { children, isOn, unstable_keepPresented, icon, ...rest } = props;\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const item: NativeStackHeaderItemMenuAction = {\n ...rest,\n description: props.subtitle,\n type: 'action',\n label: sharedProps.label,\n state: isOn ? 'on' : 'off',\n onPress: props.onPress ?? (() => {}),\n };\n if (unstable_keepPresented !== undefined) {\n item.keepsMenuPresented = unstable_keepPresented;\n }\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n // TODO(@ubax): Add support for other images in react-native-screens\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Toolbar.MenuAction, only sfSymbol icons are supported. This is a limitation of React Native Screens.'\n );\n }\n }\n return item;\n}\n\n// #region NativeToolbarMenu\n\ninterface NativeToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n children?: ReactNode;\n subtitle?: string;\n destructive?: boolean;\n disabled?: boolean;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n icon?: SFSymbol;\n xcassetName?: string;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n */\n image?: ImageRef;\n imageRenderingMode?: 'template' | 'original';\n inline?: boolean;\n label?: string;\n palette?: boolean;\n separateBackground?: boolean;\n style?: StyleProp;\n title?: string;\n tintColor?: ColorValue;\n variant?: 'plain' | 'done' | 'prominent';\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Native toolbar menu component for bottom toolbar.\n * Renders as NativeLinkPreviewAction.\n */\nconst NativeToolbarMenu: React.FC = ({\n accessibilityHint,\n accessibilityLabel,\n separateBackground,\n hidesSharedBackground,\n palette,\n inline,\n hidden,\n subtitle,\n title,\n label,\n destructive,\n children,\n icon,\n xcassetName,\n image,\n imageRenderingMode,\n tintColor,\n variant,\n style,\n elementSize,\n}) => {\n const identifier = useId();\n\n const titleStyle = StyleSheet.flatten(style);\n const renderingMode = imageRenderingMode ?? (tintColor !== undefined ? 'template' : 'original');\n return (\n