@studio-piot/native-ui 0.2.5 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -18
- package/dist/components/Button/Button.d.ts +20 -4
- package/dist/components/Button/Button.d.ts.map +1 -1
- package/dist/components/Button/Button.js +34 -21
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Button/buttonAppearance.d.ts +20 -0
- package/dist/components/Button/buttonAppearance.d.ts.map +1 -0
- package/dist/components/Button/buttonAppearance.js +28 -0
- package/dist/components/Button/buttonAppearance.js.map +1 -0
- package/dist/components/Button/buttonThemeRoles.d.ts +6 -0
- package/dist/components/Button/buttonThemeRoles.d.ts.map +1 -0
- package/dist/components/Button/buttonThemeRoles.js +8 -0
- package/dist/components/Button/buttonThemeRoles.js.map +1 -0
- package/dist/components/Button/index.d.ts +3 -1
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +4 -1
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/Choice/Choice.d.ts +10 -0
- package/dist/components/Choice/Choice.d.ts.map +1 -0
- package/dist/components/Choice/Choice.js +66 -0
- package/dist/components/Choice/Choice.js.map +1 -0
- package/dist/components/Choice/choiceLayout.d.ts +23 -0
- package/dist/components/Choice/choiceLayout.d.ts.map +1 -0
- package/dist/components/Choice/choiceLayout.js +32 -0
- package/dist/components/Choice/choiceLayout.js.map +1 -0
- package/dist/components/Choice/choiceThemeRoles.d.ts +9 -0
- package/dist/components/Choice/choiceThemeRoles.d.ts.map +1 -0
- package/dist/components/Choice/choiceThemeRoles.js +11 -0
- package/dist/components/Choice/choiceThemeRoles.js.map +1 -0
- package/dist/components/Choice/index.d.ts +5 -0
- package/dist/components/Choice/index.d.ts.map +1 -0
- package/dist/components/Choice/index.js +10 -0
- package/dist/components/Choice/index.js.map +1 -0
- package/dist/components/Choice/types.d.ts +33 -0
- package/dist/components/Choice/types.d.ts.map +1 -0
- package/dist/components/Choice/types.js +3 -0
- package/dist/components/Choice/types.js.map +1 -0
- package/dist/components/ErrorBanner/ErrorBanner.d.ts +1 -1
- package/dist/components/ErrorBanner/ErrorBanner.d.ts.map +1 -1
- package/dist/components/ErrorBanner/ErrorBanner.js +19 -19
- package/dist/components/ErrorBanner/ErrorBanner.js.map +1 -1
- package/dist/components/ErrorBanner/errorBannerContext.d.ts +23 -3
- package/dist/components/ErrorBanner/errorBannerContext.d.ts.map +1 -1
- package/dist/components/ErrorBanner/errorBannerContext.js +9 -5
- package/dist/components/ErrorBanner/errorBannerContext.js.map +1 -1
- package/dist/components/ErrorBanner/errorBannerLayout.d.ts +18 -0
- package/dist/components/ErrorBanner/errorBannerLayout.d.ts.map +1 -0
- package/dist/components/ErrorBanner/errorBannerLayout.js +54 -0
- package/dist/components/ErrorBanner/errorBannerLayout.js.map +1 -0
- package/dist/components/ErrorBanner/icons.d.ts +7 -5
- package/dist/components/ErrorBanner/icons.d.ts.map +1 -1
- package/dist/components/ErrorBanner/icons.js +8 -4
- package/dist/components/ErrorBanner/icons.js.map +1 -1
- package/dist/components/ErrorBanner/index.d.ts +1 -1
- package/dist/components/ErrorBanner/index.d.ts.map +1 -1
- package/dist/components/ErrorBanner/index.js.map +1 -1
- package/dist/components/Form/Form.d.ts +9 -1
- package/dist/components/Form/Form.d.ts.map +1 -1
- package/dist/components/Form/Form.js +56 -78
- package/dist/components/Form/Form.js.map +1 -1
- package/dist/components/Form/FormCloseButton.d.ts +3 -1
- package/dist/components/Form/FormCloseButton.d.ts.map +1 -1
- package/dist/components/Form/FormCloseButton.js +5 -4
- package/dist/components/Form/FormCloseButton.js.map +1 -1
- package/dist/components/Form/FormErrorBanner.d.ts +15 -0
- package/dist/components/Form/FormErrorBanner.d.ts.map +1 -0
- package/dist/components/Form/FormErrorBanner.js +30 -0
- package/dist/components/Form/FormErrorBanner.js.map +1 -0
- package/dist/components/Form/FormSubmitFooter.d.ts +17 -0
- package/dist/components/Form/FormSubmitFooter.d.ts.map +1 -0
- package/dist/components/Form/FormSubmitFooter.js +32 -0
- package/dist/components/Form/FormSubmitFooter.js.map +1 -0
- package/dist/components/Form/formThemeRoles.d.ts +7 -0
- package/dist/components/Form/formThemeRoles.d.ts.map +1 -0
- package/dist/components/Form/formThemeRoles.js +9 -0
- package/dist/components/Form/formThemeRoles.js.map +1 -0
- package/dist/components/Form/index.d.ts +1 -0
- package/dist/components/Form/index.d.ts.map +1 -1
- package/dist/components/Form/index.js +3 -1
- package/dist/components/Form/index.js.map +1 -1
- package/dist/components/Form/types.d.ts +14 -10
- package/dist/components/Form/types.d.ts.map +1 -1
- package/dist/components/FormSheet/FormSheet.d.ts +10 -0
- package/dist/components/FormSheet/FormSheet.d.ts.map +1 -0
- package/dist/components/FormSheet/FormSheet.js +153 -0
- package/dist/components/FormSheet/FormSheet.js.map +1 -0
- package/dist/components/FormSheet/formSheetLayout.d.ts +32 -0
- package/dist/components/FormSheet/formSheetLayout.d.ts.map +1 -0
- package/dist/components/FormSheet/formSheetLayout.js +43 -0
- package/dist/components/FormSheet/formSheetLayout.js.map +1 -0
- package/dist/components/FormSheet/formSheetThemeRoles.d.ts +8 -0
- package/dist/components/FormSheet/formSheetThemeRoles.d.ts.map +1 -0
- package/dist/components/FormSheet/formSheetThemeRoles.js +10 -0
- package/dist/components/FormSheet/formSheetThemeRoles.js.map +1 -0
- package/dist/components/FormSheet/index.d.ts +5 -0
- package/dist/components/FormSheet/index.d.ts.map +1 -0
- package/dist/components/FormSheet/index.js +10 -0
- package/dist/components/FormSheet/index.js.map +1 -0
- package/dist/components/FormSheet/types.d.ts +64 -0
- package/dist/components/FormSheet/types.d.ts.map +1 -0
- package/dist/components/FormSheet/types.js +3 -0
- package/dist/components/FormSheet/types.js.map +1 -0
- package/dist/components/HeaderButton/HeaderCapsule.d.ts +4 -0
- package/dist/components/HeaderButton/HeaderCapsule.d.ts.map +1 -0
- package/dist/components/HeaderButton/HeaderCapsule.js +32 -0
- package/dist/components/HeaderButton/HeaderCapsule.js.map +1 -0
- package/dist/components/HeaderButton/HeaderGroup.d.ts +4 -0
- package/dist/components/HeaderButton/HeaderGroup.d.ts.map +1 -0
- package/dist/components/HeaderButton/HeaderGroup.js +23 -0
- package/dist/components/HeaderButton/HeaderGroup.js.map +1 -0
- package/dist/components/HeaderButton/HeaderIcon.d.ts +4 -0
- package/dist/components/HeaderButton/HeaderIcon.d.ts.map +1 -0
- package/dist/components/HeaderButton/HeaderIcon.js +28 -0
- package/dist/components/HeaderButton/HeaderIcon.js.map +1 -0
- package/dist/components/HeaderButton/headerButtonLayout.d.ts +21 -0
- package/dist/components/HeaderButton/headerButtonLayout.d.ts.map +1 -0
- package/dist/components/HeaderButton/headerButtonLayout.js +34 -0
- package/dist/components/HeaderButton/headerButtonLayout.js.map +1 -0
- package/dist/components/HeaderButton/headerButtonThemeRoles.d.ts +5 -0
- package/dist/components/HeaderButton/headerButtonThemeRoles.d.ts.map +1 -0
- package/dist/components/HeaderButton/headerButtonThemeRoles.js +7 -0
- package/dist/components/HeaderButton/headerButtonThemeRoles.js.map +1 -0
- package/dist/components/HeaderButton/index.d.ts +7 -0
- package/dist/components/HeaderButton/index.d.ts.map +1 -0
- package/dist/components/HeaderButton/index.js +14 -0
- package/dist/components/HeaderButton/index.js.map +1 -0
- package/dist/components/HeaderButton/types.d.ts +40 -0
- package/dist/components/HeaderButton/types.d.ts.map +1 -0
- package/dist/components/HeaderButton/types.js +3 -0
- package/dist/components/HeaderButton/types.js.map +1 -0
- package/dist/components/HeaderWash/HeaderWash.d.ts +10 -0
- package/dist/components/HeaderWash/HeaderWash.d.ts.map +1 -0
- package/dist/components/HeaderWash/HeaderWash.js +19 -0
- package/dist/components/HeaderWash/HeaderWash.js.map +1 -0
- package/dist/components/HeaderWash/headerWashGradient.d.ts +8 -0
- package/dist/components/HeaderWash/headerWashGradient.d.ts.map +1 -0
- package/dist/components/HeaderWash/headerWashGradient.js +21 -0
- package/dist/components/HeaderWash/headerWashGradient.js.map +1 -0
- package/dist/components/HeaderWash/index.d.ts +2 -0
- package/dist/components/HeaderWash/index.d.ts.map +1 -0
- package/dist/components/HeaderWash/index.js +6 -0
- package/dist/components/HeaderWash/index.js.map +1 -0
- package/dist/components/Page/Page.d.ts +13 -0
- package/dist/components/Page/Page.d.ts.map +1 -0
- package/dist/components/Page/Page.js +49 -0
- package/dist/components/Page/Page.js.map +1 -0
- package/dist/components/Page/PageBleed.d.ts +9 -0
- package/dist/components/Page/PageBleed.d.ts.map +1 -0
- package/dist/components/Page/PageBleed.js +12 -0
- package/dist/components/Page/PageBleed.js.map +1 -0
- package/dist/components/Page/index.d.ts +5 -0
- package/dist/components/Page/index.d.ts.map +1 -0
- package/dist/components/Page/index.js +10 -0
- package/dist/components/Page/index.js.map +1 -0
- package/dist/components/Page/pageContext.d.ts +4 -0
- package/dist/components/Page/pageContext.d.ts.map +1 -0
- package/dist/components/Page/pageContext.js +11 -0
- package/dist/components/Page/pageContext.js.map +1 -0
- package/dist/components/Page/pageInsets.d.ts +26 -0
- package/dist/components/Page/pageInsets.d.ts.map +1 -0
- package/dist/components/Page/pageInsets.js +37 -0
- package/dist/components/Page/pageInsets.js.map +1 -0
- package/dist/components/Page/pageLayout.d.ts +5 -0
- package/dist/components/Page/pageLayout.d.ts.map +1 -0
- package/dist/components/Page/pageLayout.js +8 -0
- package/dist/components/Page/pageLayout.js.map +1 -0
- package/dist/components/Page/pageThemeRoles.d.ts +5 -0
- package/dist/components/Page/pageThemeRoles.d.ts.map +1 -0
- package/dist/components/Page/pageThemeRoles.js +7 -0
- package/dist/components/Page/pageThemeRoles.js.map +1 -0
- package/dist/components/Page/types.d.ts +22 -0
- package/dist/components/Page/types.d.ts.map +1 -0
- package/dist/components/Page/types.js +3 -0
- package/dist/components/Page/types.js.map +1 -0
- package/dist/components/Select/Select.d.ts +1 -1
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/Select.js +8 -9
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Select/selectThemeRoles.d.ts +2 -0
- package/dist/components/Select/selectThemeRoles.d.ts.map +1 -1
- package/dist/components/Select/selectThemeRoles.js +2 -0
- package/dist/components/Select/selectThemeRoles.js.map +1 -1
- package/dist/components/Select/types.d.ts +4 -0
- package/dist/components/Select/types.d.ts.map +1 -1
- package/dist/components/TabAccessoryButton/TabAccessoryButton.d.ts +8 -0
- package/dist/components/TabAccessoryButton/TabAccessoryButton.d.ts.map +1 -0
- package/dist/components/TabAccessoryButton/TabAccessoryButton.js +77 -0
- package/dist/components/TabAccessoryButton/TabAccessoryButton.js.map +1 -0
- package/dist/components/TabAccessoryButton/index.d.ts +5 -0
- package/dist/components/TabAccessoryButton/index.d.ts.map +1 -0
- package/dist/components/TabAccessoryButton/index.js +11 -0
- package/dist/components/TabAccessoryButton/index.js.map +1 -0
- package/dist/components/TabAccessoryButton/tabAccessoryLayout.d.ts +27 -0
- package/dist/components/TabAccessoryButton/tabAccessoryLayout.d.ts.map +1 -0
- package/dist/components/TabAccessoryButton/tabAccessoryLayout.js +38 -0
- package/dist/components/TabAccessoryButton/tabAccessoryLayout.js.map +1 -0
- package/dist/components/TabAccessoryButton/tabAccessoryThemeRoles.d.ts +14 -0
- package/dist/components/TabAccessoryButton/tabAccessoryThemeRoles.d.ts.map +1 -0
- package/dist/components/TabAccessoryButton/tabAccessoryThemeRoles.js +19 -0
- package/dist/components/TabAccessoryButton/tabAccessoryThemeRoles.js.map +1 -0
- package/dist/components/TabAccessoryButton/types.d.ts +27 -0
- package/dist/components/TabAccessoryButton/types.d.ts.map +1 -0
- package/dist/components/TabAccessoryButton/types.js +3 -0
- package/dist/components/TabAccessoryButton/types.js.map +1 -0
- package/dist/components/index.d.ts +9 -3
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +30 -1
- package/dist/components/index.js.map +1 -1
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -2
- package/dist/index.js.map +1 -1
- package/dist/layout/HeaderInsetProbe.d.ts +15 -0
- package/dist/layout/HeaderInsetProbe.d.ts.map +1 -0
- package/dist/layout/HeaderInsetProbe.js +28 -0
- package/dist/layout/HeaderInsetProbe.js.map +1 -0
- package/dist/layout/headerInset.d.ts +26 -0
- package/dist/layout/headerInset.d.ts.map +1 -0
- package/dist/layout/headerInset.js +29 -0
- package/dist/layout/headerInset.js.map +1 -0
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +3 -1
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/sheet.d.ts +3 -0
- package/dist/layout/sheet.d.ts.map +1 -0
- package/dist/layout/sheet.js +6 -0
- package/dist/layout/sheet.js.map +1 -0
- package/dist/theme/ThemeProvider.d.ts +4 -1
- package/dist/theme/ThemeProvider.d.ts.map +1 -1
- package/dist/theme/ThemeProvider.js +5 -2
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/index.d.ts +2 -0
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +6 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/resolveThemeSpacing.d.ts +12 -0
- package/dist/theme/resolveThemeSpacing.d.ts.map +1 -0
- package/dist/theme/resolveThemeSpacing.js +14 -0
- package/dist/theme/resolveThemeSpacing.js.map +1 -0
- package/dist/theme/types.d.ts +2 -0
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/theme/useThemeSpacing.d.ts +4 -0
- package/dist/theme/useThemeSpacing.d.ts.map +1 -0
- package/dist/theme/useThemeSpacing.js +11 -0
- package/dist/theme/useThemeSpacing.js.map +1 -0
- package/docs/components/button.md +92 -38
- package/docs/components/choice.md +111 -0
- package/docs/components/error-banner.md +46 -3
- package/docs/components/form-sheet.md +140 -0
- package/docs/components/form.md +80 -45
- package/docs/components/header-button.md +310 -0
- package/docs/components/header-wash.md +40 -0
- package/docs/components/page.md +183 -0
- package/docs/components/select.md +2 -2
- package/docs/components/tab-accessory-button.md +146 -0
- package/docs/specifications/Liquid Glass header buttons in Expo Router.md +327 -0
- package/package.json +1 -1
- package/src/components/Button/Button.tsx +82 -38
- package/src/components/Button/buttonAppearance.test.ts +44 -0
- package/src/components/Button/buttonAppearance.ts +38 -0
- package/src/components/Button/buttonThemeRoles.test.ts +10 -0
- package/src/components/Button/buttonThemeRoles.ts +6 -0
- package/src/components/Button/index.ts +12 -1
- package/src/components/Choice/Choice.tsx +120 -0
- package/src/components/Choice/choiceLayout.test.ts +49 -0
- package/src/components/Choice/choiceLayout.ts +34 -0
- package/src/components/Choice/choiceThemeRoles.test.ts +15 -0
- package/src/components/Choice/choiceThemeRoles.ts +9 -0
- package/src/components/Choice/index.ts +4 -0
- package/src/components/Choice/types.ts +33 -0
- package/src/components/ErrorBanner/ErrorBanner.tsx +32 -22
- package/src/components/ErrorBanner/errorBannerContext.tsx +31 -6
- package/src/components/ErrorBanner/errorBannerLayout.test.ts +49 -0
- package/src/components/ErrorBanner/errorBannerLayout.ts +59 -0
- package/src/components/ErrorBanner/icons.tsx +25 -6
- package/src/components/ErrorBanner/index.ts +1 -0
- package/src/components/Form/Form.tsx +77 -173
- package/src/components/Form/FormCloseButton.tsx +12 -4
- package/src/components/Form/FormErrorBanner.tsx +57 -0
- package/src/components/Form/FormSubmitFooter.tsx +70 -0
- package/src/components/Form/formThemeRoles.test.ts +13 -0
- package/src/components/Form/formThemeRoles.ts +7 -0
- package/src/components/Form/index.ts +1 -0
- package/src/components/Form/types.ts +14 -10
- package/src/components/FormSheet/FormSheet.tsx +279 -0
- package/src/components/FormSheet/formSheetLayout.test.ts +66 -0
- package/src/components/FormSheet/formSheetLayout.ts +55 -0
- package/src/components/FormSheet/formSheetThemeRoles.test.ts +14 -0
- package/src/components/FormSheet/formSheetThemeRoles.ts +8 -0
- package/src/components/FormSheet/index.ts +7 -0
- package/src/components/FormSheet/types.ts +66 -0
- package/src/components/HeaderButton/HeaderCapsule.tsx +63 -0
- package/src/components/HeaderButton/HeaderGroup.tsx +36 -0
- package/src/components/HeaderButton/HeaderIcon.tsx +56 -0
- package/src/components/HeaderButton/headerButtonLayout.test.ts +47 -0
- package/src/components/HeaderButton/headerButtonLayout.ts +36 -0
- package/src/components/HeaderButton/headerButtonThemeRoles.test.ts +9 -0
- package/src/components/HeaderButton/headerButtonThemeRoles.ts +5 -0
- package/src/components/HeaderButton/index.ts +14 -0
- package/src/components/HeaderButton/types.ts +40 -0
- package/src/components/HeaderWash/HeaderWash.tsx +20 -0
- package/src/components/HeaderWash/headerWashGradient.test.ts +22 -0
- package/src/components/{Form/withAlpha.ts → HeaderWash/headerWashGradient.ts} +9 -0
- package/src/components/HeaderWash/index.ts +1 -0
- package/src/components/Page/Page.tsx +80 -0
- package/src/components/Page/PageBleed.tsx +14 -0
- package/src/components/Page/index.ts +4 -0
- package/src/components/Page/pageContext.ts +8 -0
- package/src/components/Page/pageInsets.test.ts +73 -0
- package/src/components/Page/pageInsets.ts +52 -0
- package/src/components/Page/pageThemeRoles.test.ts +9 -0
- package/src/components/Page/pageThemeRoles.ts +5 -0
- package/src/components/Page/types.ts +26 -0
- package/src/components/Select/Select.tsx +11 -4
- package/src/components/Select/selectThemeRoles.test.ts +5 -0
- package/src/components/Select/selectThemeRoles.ts +2 -0
- package/src/components/Select/types.ts +4 -0
- package/src/components/TabAccessoryButton/TabAccessoryButton.tsx +150 -0
- package/src/components/TabAccessoryButton/index.ts +12 -0
- package/src/components/TabAccessoryButton/tabAccessoryLayout.test.ts +42 -0
- package/src/components/TabAccessoryButton/tabAccessoryLayout.ts +43 -0
- package/src/components/TabAccessoryButton/tabAccessoryThemeRoles.test.ts +28 -0
- package/src/components/TabAccessoryButton/tabAccessoryThemeRoles.ts +22 -0
- package/src/components/TabAccessoryButton/types.ts +27 -0
- package/src/components/index.ts +64 -2
- package/src/index.ts +61 -2
- package/src/layout/headerInset.test.ts +60 -0
- package/src/layout/headerInset.ts +41 -0
- package/src/layout/index.ts +1 -0
- package/src/layout/sheet.ts +2 -0
- package/src/theme/ThemeProvider.tsx +9 -1
- package/src/theme/index.ts +6 -0
- package/src/theme/resolveThemeSpacing.test.ts +29 -0
- package/src/theme/resolveThemeSpacing.ts +21 -0
- package/src/theme/types.ts +3 -0
- package/src/theme/useThemeSpacing.ts +8 -0
- package/src/components/Form/withAlpha.test.ts +0 -13
|
@@ -1,55 +1,20 @@
|
|
|
1
|
-
import { useRef, useState
|
|
2
|
-
import {
|
|
3
|
-
StyleSheet,
|
|
4
|
-
Text,
|
|
5
|
-
View,
|
|
6
|
-
type LayoutChangeEvent,
|
|
7
|
-
} from "react-native";
|
|
1
|
+
import { useCallback, useRef, useState } from "react";
|
|
2
|
+
import { Platform, StyleSheet, View, type LayoutChangeEvent } from "react-native";
|
|
8
3
|
import {
|
|
9
4
|
KeyboardAwareScrollView,
|
|
10
|
-
KeyboardStickyView,
|
|
11
5
|
type KeyboardAwareScrollViewRef,
|
|
12
6
|
} from "react-native-keyboard-controller";
|
|
13
|
-
import {
|
|
14
|
-
ErrorBanner,
|
|
15
|
-
ErrorBannerProvider,
|
|
16
|
-
useErrorBanner,
|
|
17
|
-
useErrorBannerContext,
|
|
18
|
-
type FieldError,
|
|
19
|
-
} from "../ErrorBanner";
|
|
20
7
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
8
|
+
import { estimateHeaderHeight, formFieldScrollY } from "../../layout/headerInset";
|
|
9
|
+
import { useThemeSpacing } from "../../theme/useThemeSpacing";
|
|
10
|
+
import { ErrorBannerProvider, useErrorBanner } from "../ErrorBanner";
|
|
11
|
+
import { ERROR_BANNER_SCROLL_GAP } from "../ErrorBanner/errorBannerCopy";
|
|
12
|
+
import { FormErrorBanner } from "./FormErrorBanner";
|
|
13
|
+
import { FormSubmitFooter } from "./FormSubmitFooter";
|
|
14
|
+
import { FORM_THEME_ROLES } from "./formThemeRoles";
|
|
24
15
|
import type { FormProps } from "./types";
|
|
25
16
|
import { useResolvedThemeColor } from "./useResolvedThemeColor";
|
|
26
|
-
import { withAlpha } from "./withAlpha";
|
|
27
17
|
|
|
28
|
-
/** How far the header wash continues below the buttons. */
|
|
29
|
-
const FADE_TAIL = 32;
|
|
30
|
-
|
|
31
|
-
function FormErrorBanner({
|
|
32
|
-
open,
|
|
33
|
-
errors,
|
|
34
|
-
onDismiss,
|
|
35
|
-
onHeightChange,
|
|
36
|
-
}: {
|
|
37
|
-
open: boolean;
|
|
38
|
-
errors: readonly FieldError[];
|
|
39
|
-
onDismiss: () => void;
|
|
40
|
-
onHeightChange: (height: number) => void;
|
|
41
|
-
}) {
|
|
42
|
-
const ctx = useErrorBannerContext();
|
|
43
|
-
return (
|
|
44
|
-
<ErrorBanner
|
|
45
|
-
errors={errors}
|
|
46
|
-
onDismiss={onDismiss}
|
|
47
|
-
onHeightChange={onHeightChange}
|
|
48
|
-
onJump={(field) => ctx?.jump(field)}
|
|
49
|
-
open={open}
|
|
50
|
-
/>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
18
|
|
|
54
19
|
/** Space kept between the focused field and the top of the footer. */
|
|
55
20
|
const FIELD_GAP = 12;
|
|
@@ -60,55 +25,79 @@ const FIELD_GAP = 12;
|
|
|
60
25
|
*/
|
|
61
26
|
const FIELD_BELOW_CARET = 36;
|
|
62
27
|
|
|
28
|
+
/**
|
|
29
|
+
* A full-screen form under the native stack header. Set the title and the
|
|
30
|
+
* close button in the screen's stack options. The scroll view is the
|
|
31
|
+
* screen's first child, so iOS insets it for the header (including a large
|
|
32
|
+
* title) and content scrolls behind the bar. Render `Form` as the screen's
|
|
33
|
+
* root element. For a wash behind a transparent header, use `HeaderWash` as
|
|
34
|
+
* the stack's `headerBackground`.
|
|
35
|
+
*/
|
|
63
36
|
export function Form({
|
|
64
|
-
title,
|
|
65
37
|
children,
|
|
66
|
-
onClose,
|
|
67
38
|
onSubmit,
|
|
68
39
|
errors = [],
|
|
69
40
|
submitLabel = "Save",
|
|
70
41
|
submitting = false,
|
|
71
42
|
submitDisabled = false,
|
|
72
|
-
closeButton,
|
|
73
43
|
submitRadius = "lg",
|
|
74
|
-
|
|
44
|
+
headerHeight: headerHeightProp,
|
|
45
|
+
paddingHorizontal: paddingHorizontalProp,
|
|
75
46
|
backgroundColor: backgroundColorProp,
|
|
76
|
-
titleColor: titleColorProp,
|
|
77
47
|
footerBackgroundColor: footerBackgroundColorProp,
|
|
78
|
-
buttonBackgroundColor
|
|
79
|
-
buttonLabelColor
|
|
48
|
+
buttonBackgroundColor,
|
|
49
|
+
buttonLabelColor,
|
|
80
50
|
}: FormProps) {
|
|
51
|
+
const spacing = useThemeSpacing();
|
|
81
52
|
const insets = useSafeAreaInsets();
|
|
82
|
-
const
|
|
83
|
-
const
|
|
53
|
+
const paddingHorizontal = paddingHorizontalProp ?? spacing.screen;
|
|
54
|
+
const background = useResolvedThemeColor(
|
|
55
|
+
backgroundColorProp,
|
|
56
|
+
FORM_THEME_ROLES.backgroundColor,
|
|
57
|
+
);
|
|
84
58
|
const footerBackground = useResolvedThemeColor(
|
|
85
59
|
footerBackgroundColorProp,
|
|
86
|
-
|
|
87
|
-
);
|
|
88
|
-
const buttonBackground = useResolvedThemeColor(
|
|
89
|
-
buttonBackgroundColorProp,
|
|
90
|
-
"buttonBackground",
|
|
91
|
-
);
|
|
92
|
-
const buttonLabel = useResolvedThemeColor(
|
|
93
|
-
buttonLabelColorProp,
|
|
94
|
-
"buttonLabel",
|
|
60
|
+
FORM_THEME_ROLES.footerBackgroundColor,
|
|
95
61
|
);
|
|
96
62
|
const scrollRef = useRef<KeyboardAwareScrollViewRef>(null);
|
|
97
63
|
const bannerHeightRef = useRef(0);
|
|
64
|
+
const scrollTopRef = useRef(0);
|
|
65
|
+
const headerHeight =
|
|
66
|
+
headerHeightProp ?? estimateHeaderHeight(Platform.OS, insets.top);
|
|
67
|
+
const headerHeightRef = useRef(headerHeight);
|
|
68
|
+
headerHeightRef.current = headerHeight;
|
|
98
69
|
const banner = useErrorBanner(errors);
|
|
99
70
|
const [footerHeight, setFooterHeight] = useState(0);
|
|
100
|
-
const [cancelWidth, setCancelWidth] = useState(0);
|
|
101
|
-
const [barHeight, setBarHeight] = useState(0);
|
|
102
|
-
const resolvedBar = barHeight || insets.top + 52;
|
|
103
71
|
|
|
104
72
|
const onFooterLayout = (event: LayoutChangeEvent) => {
|
|
105
73
|
const next = Math.round(event.nativeEvent.layout.height);
|
|
106
74
|
setFooterHeight((current) => (current === next ? current : next));
|
|
107
75
|
};
|
|
108
76
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
77
|
+
// Window y of the scroll view: 0 under a transparent header, the header's
|
|
78
|
+
// bottom under an opaque one.
|
|
79
|
+
const onScrollLayout = (event: LayoutChangeEvent) => {
|
|
80
|
+
(event.currentTarget as unknown as View).measureInWindow((_x, y) => {
|
|
81
|
+
scrollTopRef.current = Math.round(y);
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// A banner row scrolls its field clear of the header and the banner.
|
|
86
|
+
const scrollYForField = useCallback((fieldY: number) => {
|
|
87
|
+
const scrollTop = scrollTopRef.current;
|
|
88
|
+
const header = headerHeightRef.current;
|
|
89
|
+
// iOS draws the banner over the window top; Android inside the screen.
|
|
90
|
+
const bannerTop = Platform.OS === "ios" ? 0 : scrollTop;
|
|
91
|
+
return formFieldScrollY({
|
|
92
|
+
fieldY,
|
|
93
|
+
scrollTop,
|
|
94
|
+
visibleTop: Math.max(scrollTop, header),
|
|
95
|
+
bannerBottom: bannerTop + bannerHeightRef.current,
|
|
96
|
+
// Under a transparent header iOS rests the content at -(header).
|
|
97
|
+
minScrollY: Math.min(0, scrollTop - header),
|
|
98
|
+
gap: ERROR_BANNER_SCROLL_GAP,
|
|
99
|
+
});
|
|
100
|
+
}, []);
|
|
112
101
|
|
|
113
102
|
return (
|
|
114
103
|
<ErrorBannerProvider
|
|
@@ -116,96 +105,42 @@ export function Form({
|
|
|
116
105
|
errors={errors}
|
|
117
106
|
onDismiss={banner.dismiss}
|
|
118
107
|
scrollRef={scrollRef}
|
|
108
|
+
scrollYForField={scrollYForField}
|
|
119
109
|
>
|
|
120
|
-
<View style={[styles.screen, { backgroundColor: background }]}>
|
|
121
110
|
<KeyboardAwareScrollView
|
|
122
111
|
ref={scrollRef}
|
|
123
112
|
automaticallyAdjustKeyboardInsets={false}
|
|
124
113
|
bottomOffset={footerHeight + FIELD_GAP + FIELD_BELOW_CARET}
|
|
125
114
|
contentContainerStyle={[
|
|
126
115
|
styles.content,
|
|
127
|
-
{
|
|
128
|
-
paddingTop: resolvedBar + FADE_TAIL,
|
|
129
|
-
paddingHorizontal,
|
|
130
|
-
},
|
|
116
|
+
{ paddingTop: spacing.pageTop, paddingHorizontal },
|
|
131
117
|
]}
|
|
132
|
-
contentInsetAdjustmentBehavior="
|
|
118
|
+
contentInsetAdjustmentBehavior="automatic"
|
|
133
119
|
keyboardDismissMode="interactive"
|
|
134
120
|
keyboardShouldPersistTaps="handled"
|
|
121
|
+
onLayout={onScrollLayout}
|
|
135
122
|
showsVerticalScrollIndicator={false}
|
|
136
|
-
style={styles.scroll}
|
|
123
|
+
style={[styles.scroll, { backgroundColor: background }]}
|
|
137
124
|
>
|
|
138
125
|
{children}
|
|
139
126
|
</KeyboardAwareScrollView>
|
|
140
127
|
|
|
141
|
-
<
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
pointerEvents="box-none"
|
|
157
|
-
style={[
|
|
158
|
-
styles.header,
|
|
159
|
-
{ paddingTop: insets.top, paddingHorizontal },
|
|
160
|
-
]}
|
|
161
|
-
>
|
|
162
|
-
<View
|
|
163
|
-
onLayout={(event) => {
|
|
164
|
-
const next = Math.round(event.nativeEvent.layout.width);
|
|
165
|
-
setCancelWidth((current) => (current === next ? current : next));
|
|
166
|
-
}}
|
|
167
|
-
>
|
|
168
|
-
{resolvedClose}
|
|
169
|
-
</View>
|
|
170
|
-
<Text
|
|
171
|
-
accessibilityRole="header"
|
|
172
|
-
numberOfLines={1}
|
|
173
|
-
pointerEvents="none"
|
|
174
|
-
style={[styles.title, { flex: 1, color: titleColor }]}
|
|
175
|
-
>
|
|
176
|
-
{title}
|
|
177
|
-
</Text>
|
|
178
|
-
<View style={{ width: cancelWidth }} />
|
|
179
|
-
</View>
|
|
180
|
-
</View>
|
|
128
|
+
<FormSubmitFooter
|
|
129
|
+
backgroundColor={footerBackground}
|
|
130
|
+
buttonBackgroundColor={buttonBackgroundColor}
|
|
131
|
+
buttonLabelColor={buttonLabelColor}
|
|
132
|
+
disabled={submitDisabled}
|
|
133
|
+
label={submitLabel}
|
|
134
|
+
onLayout={onFooterLayout}
|
|
135
|
+
onPress={() => {
|
|
136
|
+
banner.present();
|
|
137
|
+
onSubmit();
|
|
138
|
+
}}
|
|
139
|
+
paddingHorizontal={paddingHorizontal}
|
|
140
|
+
radius={submitRadius}
|
|
141
|
+
submitting={submitting}
|
|
142
|
+
/>
|
|
181
143
|
|
|
182
|
-
{/*
|
|
183
|
-
The spacer is the home-indicator clearance. `opened` equals that
|
|
184
|
-
spacer, so once the keyboard is up the spacer sits inside the
|
|
185
|
-
keyboard and the button rests on whatever height the keyboard is.
|
|
186
|
-
*/}
|
|
187
|
-
<KeyboardStickyView offset={{ closed: 0, opened: insets.bottom }}>
|
|
188
|
-
<View style={[styles.footerShell, { backgroundColor: footerBackground }]}>
|
|
189
|
-
<View
|
|
190
|
-
onLayout={onFooterLayout}
|
|
191
|
-
style={[styles.footer, { paddingHorizontal }]}
|
|
192
|
-
>
|
|
193
|
-
<Button
|
|
194
|
-
backgroundColor={buttonBackground}
|
|
195
|
-
disabled={submitDisabled}
|
|
196
|
-
label={submitLabel}
|
|
197
|
-
labelColor={buttonLabel}
|
|
198
|
-
loading={submitting}
|
|
199
|
-
onPress={() => {
|
|
200
|
-
banner.present();
|
|
201
|
-
onSubmit();
|
|
202
|
-
}}
|
|
203
|
-
radius={submitRadius}
|
|
204
|
-
/>
|
|
205
|
-
</View>
|
|
206
|
-
<View style={{ height: insets.bottom }} />
|
|
207
|
-
</View>
|
|
208
|
-
</KeyboardStickyView>
|
|
209
144
|
<FormErrorBanner
|
|
210
145
|
errors={errors}
|
|
211
146
|
onDismiss={banner.dismiss}
|
|
@@ -214,46 +149,15 @@ export function Form({
|
|
|
214
149
|
}}
|
|
215
150
|
open={banner.open}
|
|
216
151
|
/>
|
|
217
|
-
</View>
|
|
218
152
|
</ErrorBannerProvider>
|
|
219
153
|
);
|
|
220
154
|
}
|
|
221
155
|
|
|
222
156
|
const styles = StyleSheet.create({
|
|
223
|
-
screen: {
|
|
224
|
-
flex: 1,
|
|
225
|
-
},
|
|
226
157
|
scroll: {
|
|
227
158
|
flex: 1,
|
|
228
159
|
},
|
|
229
160
|
content: {
|
|
230
|
-
paddingTop: 20,
|
|
231
161
|
paddingBottom: 24,
|
|
232
162
|
},
|
|
233
|
-
fade: {
|
|
234
|
-
position: "absolute",
|
|
235
|
-
top: 0,
|
|
236
|
-
left: 0,
|
|
237
|
-
right: 0,
|
|
238
|
-
},
|
|
239
|
-
header: {
|
|
240
|
-
flexDirection: "row",
|
|
241
|
-
alignItems: "center",
|
|
242
|
-
},
|
|
243
|
-
title: {
|
|
244
|
-
fontSize: 17,
|
|
245
|
-
fontWeight: "600",
|
|
246
|
-
textAlign: "center",
|
|
247
|
-
},
|
|
248
|
-
footerShell: {
|
|
249
|
-
// Cast upward so the sticky footer separates from the scroll body.
|
|
250
|
-
shadowColor: "#000",
|
|
251
|
-
shadowOffset: { width: 0, height: -4 },
|
|
252
|
-
shadowOpacity: 0.08,
|
|
253
|
-
shadowRadius: 12,
|
|
254
|
-
elevation: 8,
|
|
255
|
-
},
|
|
256
|
-
footer: {
|
|
257
|
-
paddingVertical: 12,
|
|
258
|
-
},
|
|
259
163
|
});
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { Pressable, StyleSheet, Text } from "react-native";
|
|
2
|
-
import {
|
|
2
|
+
import { useResolvedFieldColor } from "../Field/useResolvedFieldColor";
|
|
3
|
+
import { FORM_THEME_ROLES } from "./formThemeRoles";
|
|
3
4
|
|
|
4
|
-
export function FormCloseButton({
|
|
5
|
-
|
|
5
|
+
export function FormCloseButton({
|
|
6
|
+
onPress,
|
|
7
|
+
color: colorProp,
|
|
8
|
+
}: {
|
|
9
|
+
onPress: () => void;
|
|
10
|
+
/** Defaults to theme role `formClose`. */
|
|
11
|
+
color?: string;
|
|
12
|
+
}) {
|
|
13
|
+
const color = useResolvedFieldColor(colorProp, FORM_THEME_ROLES.closeColor);
|
|
6
14
|
|
|
7
15
|
return (
|
|
8
16
|
<Pressable accessibilityRole="button" hitSlop={8} onPress={onPress}>
|
|
9
|
-
<Text style={[styles.label, { color
|
|
17
|
+
<Text style={[styles.label, { color }]}>Cancel</Text>
|
|
10
18
|
</Pressable>
|
|
11
19
|
);
|
|
12
20
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Platform, StyleSheet, View } from "react-native";
|
|
2
|
+
import { FullWindowOverlay } from "react-native-screens";
|
|
3
|
+
import {
|
|
4
|
+
ErrorBanner,
|
|
5
|
+
useErrorBannerContext,
|
|
6
|
+
type FieldError,
|
|
7
|
+
} from "../ErrorBanner";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The screen banner wired to the nearest `ErrorBannerProvider`. Shared by
|
|
11
|
+
* `Form` and `FormSheet`. On iOS it renders in a native overlay window so it
|
|
12
|
+
* covers the native header. Android native headers do not overlap the
|
|
13
|
+
* screen, so there it sits `androidTop` below the screen top, under the header.
|
|
14
|
+
*/
|
|
15
|
+
export function FormErrorBanner({
|
|
16
|
+
open,
|
|
17
|
+
errors,
|
|
18
|
+
onDismiss,
|
|
19
|
+
onHeightChange,
|
|
20
|
+
androidTop = 0,
|
|
21
|
+
}: {
|
|
22
|
+
open: boolean;
|
|
23
|
+
errors: readonly FieldError[];
|
|
24
|
+
onDismiss: () => void;
|
|
25
|
+
onHeightChange: (height: number) => void;
|
|
26
|
+
androidTop?: number;
|
|
27
|
+
}) {
|
|
28
|
+
const ctx = useErrorBannerContext();
|
|
29
|
+
const banner = (
|
|
30
|
+
<ErrorBanner
|
|
31
|
+
errors={errors}
|
|
32
|
+
onDismiss={onDismiss}
|
|
33
|
+
onHeightChange={onHeightChange}
|
|
34
|
+
onJump={(field) => ctx?.jump(field)}
|
|
35
|
+
open={open}
|
|
36
|
+
safeAreaTop={Platform.OS === "ios" ? undefined : 0}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (Platform.OS === "ios") {
|
|
41
|
+
return <FullWindowOverlay>{banner}</FullWindowOverlay>;
|
|
42
|
+
}
|
|
43
|
+
return (
|
|
44
|
+
<View pointerEvents="box-none" style={[styles.below, { top: androidTop }]}>
|
|
45
|
+
{banner}
|
|
46
|
+
</View>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const styles = StyleSheet.create({
|
|
51
|
+
below: {
|
|
52
|
+
position: "absolute",
|
|
53
|
+
left: 0,
|
|
54
|
+
right: 0,
|
|
55
|
+
bottom: 0,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { StyleSheet, View, type LayoutChangeEvent } from "react-native";
|
|
2
|
+
import { KeyboardStickyView } from "react-native-keyboard-controller";
|
|
3
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
4
|
+
import { Button } from "../Button";
|
|
5
|
+
import type { ButtonRadius } from "../Button/buttonRadius";
|
|
6
|
+
|
|
7
|
+
/** Sticky submit footer shared by `Form` and `FormSheet`. */
|
|
8
|
+
export function FormSubmitFooter({
|
|
9
|
+
label,
|
|
10
|
+
onPress,
|
|
11
|
+
submitting,
|
|
12
|
+
disabled,
|
|
13
|
+
radius,
|
|
14
|
+
paddingHorizontal,
|
|
15
|
+
backgroundColor,
|
|
16
|
+
buttonBackgroundColor,
|
|
17
|
+
buttonLabelColor,
|
|
18
|
+
onLayout,
|
|
19
|
+
}: {
|
|
20
|
+
label: string;
|
|
21
|
+
onPress: () => void;
|
|
22
|
+
submitting: boolean;
|
|
23
|
+
disabled: boolean;
|
|
24
|
+
radius: ButtonRadius;
|
|
25
|
+
paddingHorizontal: number;
|
|
26
|
+
backgroundColor: string;
|
|
27
|
+
buttonBackgroundColor?: string;
|
|
28
|
+
buttonLabelColor?: string;
|
|
29
|
+
/** Height of the bar above the home indicator, for scroll clearance. */
|
|
30
|
+
onLayout?: (event: LayoutChangeEvent) => void;
|
|
31
|
+
}) {
|
|
32
|
+
const insets = useSafeAreaInsets();
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
// The spacer is the home-indicator clearance. `opened` equals that
|
|
36
|
+
// spacer, so once the keyboard is up the spacer sits inside the
|
|
37
|
+
// keyboard and the button rests on whatever height the keyboard is.
|
|
38
|
+
<KeyboardStickyView offset={{ closed: 0, opened: insets.bottom }}>
|
|
39
|
+
<View style={[styles.shell, { backgroundColor }]}>
|
|
40
|
+
<View onLayout={onLayout} style={[styles.bar, { paddingHorizontal }]}>
|
|
41
|
+
<Button
|
|
42
|
+
backgroundColor={buttonBackgroundColor}
|
|
43
|
+
disabled={disabled}
|
|
44
|
+
label={label}
|
|
45
|
+
labelColor={buttonLabelColor}
|
|
46
|
+
loading={submitting}
|
|
47
|
+
onPress={onPress}
|
|
48
|
+
radius={radius}
|
|
49
|
+
/>
|
|
50
|
+
</View>
|
|
51
|
+
<View style={{ height: insets.bottom }} />
|
|
52
|
+
</View>
|
|
53
|
+
</KeyboardStickyView>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const styles = StyleSheet.create({
|
|
58
|
+
shell: {
|
|
59
|
+
zIndex: 2,
|
|
60
|
+
// Cast upward so the sticky footer separates from the scroll body.
|
|
61
|
+
shadowColor: "#000",
|
|
62
|
+
shadowOffset: { width: 0, height: -4 },
|
|
63
|
+
shadowOpacity: 0.08,
|
|
64
|
+
shadowRadius: 12,
|
|
65
|
+
elevation: 8,
|
|
66
|
+
},
|
|
67
|
+
bar: {
|
|
68
|
+
paddingVertical: 12,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { FORM_THEME_ROLES } from "./formThemeRoles.ts";
|
|
4
|
+
|
|
5
|
+
describe("FORM_THEME_ROLES", () => {
|
|
6
|
+
it("maps colour props to form-prefixed roles, not the app's own names", () => {
|
|
7
|
+
assert.deepEqual(FORM_THEME_ROLES, {
|
|
8
|
+
backgroundColor: "formBackground",
|
|
9
|
+
footerBackgroundColor: "formFooterBackground",
|
|
10
|
+
closeColor: "formClose",
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -2,10 +2,12 @@ import type { ReactNode } from "react";
|
|
|
2
2
|
import type { ButtonRadius } from "../Button/buttonRadius";
|
|
3
3
|
import type { FieldError } from "../ErrorBanner/types";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Set the title and close button in the screen's stack options
|
|
7
|
+
* (`title`, `headerLeft`), not here.
|
|
8
|
+
*/
|
|
5
9
|
export type FormProps = {
|
|
6
|
-
title: string;
|
|
7
10
|
children: ReactNode;
|
|
8
|
-
onClose: () => void;
|
|
9
11
|
onSubmit: () => void;
|
|
10
12
|
/**
|
|
11
13
|
* Field errors for the screen banner. Empty hides it.
|
|
@@ -16,19 +18,21 @@ export type FormProps = {
|
|
|
16
18
|
submitLabel?: string;
|
|
17
19
|
submitting?: boolean;
|
|
18
20
|
submitDisabled?: boolean;
|
|
19
|
-
/** App-specific Cancel control. Defaults to a plain text Cancel. */
|
|
20
|
-
closeButton?: ReactNode;
|
|
21
21
|
submitRadius?: ButtonRadius;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* Native header height, from `useHeaderHeight()` in
|
|
24
|
+
* `expo-router/react-navigation`. Used to scroll an error's field clear of
|
|
25
|
+
* the header. Defaults to the status bar plus a standard bar.
|
|
26
|
+
*/
|
|
27
|
+
headerHeight?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Horizontal inset for the scroll content and footer.
|
|
30
|
+
* Defaults to theme `spacing.screen`. Pass a value to override.
|
|
25
31
|
*/
|
|
26
32
|
paddingHorizontal?: number;
|
|
27
|
-
/** Defaults to theme role `
|
|
33
|
+
/** Defaults to theme role `formBackground`. */
|
|
28
34
|
backgroundColor?: string;
|
|
29
|
-
/** Defaults to theme role `
|
|
30
|
-
titleColor?: string;
|
|
31
|
-
/** Defaults to theme role `surface`. Footer ground. */
|
|
35
|
+
/** Defaults to theme role `formFooterBackground`. Footer ground. */
|
|
32
36
|
footerBackgroundColor?: string;
|
|
33
37
|
/** Defaults to theme role `buttonBackground`. */
|
|
34
38
|
buttonBackgroundColor?: string;
|