@studio-piot/native-ui 0.2.4 → 0.16.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 +8 -0
- package/dist/components/Choice/Choice.d.ts.map +1 -0
- package/dist/components/Choice/Choice.js +60 -0
- package/dist/components/Choice/Choice.js.map +1 -0
- package/dist/components/Choice/choiceLayout.d.ts +7 -0
- package/dist/components/Choice/choiceLayout.d.ts.map +1 -0
- package/dist/components/Choice/choiceLayout.js +13 -0
- package/dist/components/Choice/choiceLayout.js.map +1 -0
- package/dist/components/Choice/choiceThemeRoles.d.ts +8 -0
- package/dist/components/Choice/choiceThemeRoles.d.ts.map +1 -0
- package/dist/components/Choice/choiceThemeRoles.js +10 -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 +26 -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/SegmentedControl/types.d.ts +0 -1
- package/dist/components/SegmentedControl/types.d.ts.map +1 -1
- 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 +88 -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 +109 -0
- package/src/components/Choice/choiceLayout.test.ts +14 -0
- package/src/components/Choice/choiceLayout.ts +9 -0
- package/src/components/Choice/choiceThemeRoles.test.ts +14 -0
- package/src/components/Choice/choiceThemeRoles.ts +8 -0
- package/src/components/Choice/index.ts +4 -0
- package/src/components/Choice/types.ts +26 -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/SegmentedControl/types.ts +0 -1
- 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
|
@@ -22,20 +22,19 @@ import {
|
|
|
22
22
|
type BottomSheetHandleProps,
|
|
23
23
|
} from "@gorhom/bottom-sheet";
|
|
24
24
|
import { FullWindowOverlay } from "react-native-screens";
|
|
25
|
+
import { SHEET_TOP_RADIUS } from "../../layout/sheet";
|
|
25
26
|
import { buttonRadiusValue } from "../Button/buttonRadius";
|
|
26
27
|
import {
|
|
27
28
|
useErrorBannerDismiss,
|
|
28
29
|
useErrorBannerField,
|
|
29
30
|
} from "../ErrorBanner";
|
|
30
31
|
import { useResolvedFieldColor } from "../Field/useResolvedFieldColor";
|
|
31
|
-
import { useThemeColor } from "../../theme/useThemeColor";
|
|
32
32
|
import { DEFAULT_SELECT_DETENTS } from "./resolveSelectDetentIndex";
|
|
33
33
|
import { SelectCloseButton } from "./SelectCloseButton";
|
|
34
34
|
import { SELECT_THEME_ROLES } from "./selectThemeRoles";
|
|
35
35
|
import type { SelectOption, SelectProps } from "./types";
|
|
36
36
|
|
|
37
37
|
const BACKDROP_OPACITY = 0.72;
|
|
38
|
-
const SHEET_TOP_RADIUS = 20;
|
|
39
38
|
|
|
40
39
|
/** Renders the sheet above React Navigation native modals (iOS). */
|
|
41
40
|
function SheetContainer({ children }: { children?: ReactNode }) {
|
|
@@ -69,6 +68,8 @@ export function Select({
|
|
|
69
68
|
borderColor: borderColorProp,
|
|
70
69
|
errorColor: errorColorProp,
|
|
71
70
|
selectedColor: selectedColorProp,
|
|
71
|
+
closeBackgroundColor: closeBackgroundColorProp,
|
|
72
|
+
closeIconColor: closeIconColorProp,
|
|
72
73
|
style,
|
|
73
74
|
}: SelectProps) {
|
|
74
75
|
const modalRef = useRef<ElementRef<typeof BottomSheetModal>>(null);
|
|
@@ -107,8 +108,14 @@ export function Select({
|
|
|
107
108
|
SELECT_THEME_ROLES.selectedColor,
|
|
108
109
|
);
|
|
109
110
|
// Resolved on the trigger tree (has ThemeProvider), then passed into the portal.
|
|
110
|
-
const closeDiscColor =
|
|
111
|
-
|
|
111
|
+
const closeDiscColor = useResolvedFieldColor(
|
|
112
|
+
closeBackgroundColorProp,
|
|
113
|
+
SELECT_THEME_ROLES.closeBackgroundColor,
|
|
114
|
+
);
|
|
115
|
+
const closeIconColor = useResolvedFieldColor(
|
|
116
|
+
closeIconColorProp,
|
|
117
|
+
SELECT_THEME_ROLES.closeIconColor,
|
|
118
|
+
);
|
|
112
119
|
|
|
113
120
|
const dismissBanner = useErrorBannerDismiss();
|
|
114
121
|
const { viewRef, listed } = useErrorBannerField(name, () => {
|
|
@@ -13,4 +13,9 @@ describe("SELECT_THEME_ROLES", () => {
|
|
|
13
13
|
assert.equal(SELECT_THEME_ROLES.errorColor, "fieldError");
|
|
14
14
|
assert.equal(SELECT_THEME_ROLES.selectedColor, "fieldSelectSelected");
|
|
15
15
|
});
|
|
16
|
+
|
|
17
|
+
it("gives the sheet close button its own select-prefixed roles", () => {
|
|
18
|
+
assert.equal(SELECT_THEME_ROLES.closeBackgroundColor, "selectCloseBackground");
|
|
19
|
+
assert.equal(SELECT_THEME_ROLES.closeIconColor, "selectCloseIcon");
|
|
20
|
+
});
|
|
16
21
|
});
|
|
@@ -7,6 +7,8 @@ export const SELECT_THEME_ROLES = {
|
|
|
7
7
|
borderColor: "fieldBorder",
|
|
8
8
|
errorColor: "fieldError",
|
|
9
9
|
selectedColor: "fieldSelectSelected",
|
|
10
|
+
closeBackgroundColor: "selectCloseBackground",
|
|
11
|
+
closeIconColor: "selectCloseIcon",
|
|
10
12
|
} as const;
|
|
11
13
|
|
|
12
14
|
export type SelectThemeColorProp = keyof typeof SELECT_THEME_ROLES;
|
|
@@ -39,5 +39,9 @@ export type SelectProps = {
|
|
|
39
39
|
borderColor?: string;
|
|
40
40
|
errorColor?: string;
|
|
41
41
|
selectedColor?: string;
|
|
42
|
+
/** Sheet close disc. Defaults to theme role `selectCloseBackground`. */
|
|
43
|
+
closeBackgroundColor?: string;
|
|
44
|
+
/** Sheet close cross. Defaults to theme role `selectCloseIcon`. */
|
|
45
|
+
closeIconColor?: string;
|
|
42
46
|
style?: StyleProp<ViewStyle>;
|
|
43
47
|
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { Platform, Pressable, StyleSheet, Text, View } from "react-native";
|
|
2
|
+
import { useThemeSpacing } from "../../theme/useThemeSpacing";
|
|
3
|
+
import { Button } from "../Button";
|
|
4
|
+
import { useResolvedFieldColor } from "../Field/useResolvedFieldColor";
|
|
5
|
+
import { supportsLiquidGlass } from "../HeaderButton/headerButtonLayout";
|
|
6
|
+
import {
|
|
7
|
+
TAB_ACCESSORY_FONT_SIZE,
|
|
8
|
+
TAB_ACCESSORY_ICON_SIZE,
|
|
9
|
+
tabAccessoryVisible,
|
|
10
|
+
} from "./tabAccessoryLayout";
|
|
11
|
+
import { tabAccessoryRoles } from "./tabAccessoryThemeRoles";
|
|
12
|
+
import type { TabAccessoryButtonProps } from "./types";
|
|
13
|
+
|
|
14
|
+
const GLASS = supportsLiquidGlass(Platform.OS, Platform.Version);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Action above the bottom tabs. On iOS 26+ it is content for
|
|
18
|
+
* `NativeTabs.BottomAccessory`, which draws the glass. Elsewhere it floats
|
|
19
|
+
* a filled pill at the bottom of the screen.
|
|
20
|
+
*/
|
|
21
|
+
export function TabAccessoryButton(props: TabAccessoryButtonProps) {
|
|
22
|
+
if (!tabAccessoryVisible(props.placement, GLASS)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
if (props.placement === "screen") {
|
|
26
|
+
return <FloatingPill {...props} />;
|
|
27
|
+
}
|
|
28
|
+
return props.variant === "filled" ? (
|
|
29
|
+
<FilledContent {...props} />
|
|
30
|
+
) : (
|
|
31
|
+
<GlassContent {...props} />
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function GlassContent({
|
|
36
|
+
label,
|
|
37
|
+
onPress,
|
|
38
|
+
icon,
|
|
39
|
+
disabled = false,
|
|
40
|
+
color: colorProp,
|
|
41
|
+
}: TabAccessoryButtonProps) {
|
|
42
|
+
const color = useResolvedFieldColor(colorProp, tabAccessoryRoles("glass").content);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<Pressable
|
|
46
|
+
accessibilityLabel={label}
|
|
47
|
+
accessibilityRole="button"
|
|
48
|
+
accessibilityState={{ disabled }}
|
|
49
|
+
disabled={disabled}
|
|
50
|
+
onPress={onPress}
|
|
51
|
+
style={({ pressed }) => [
|
|
52
|
+
styles.content,
|
|
53
|
+
{ opacity: disabled ? 0.4 : pressed ? 0.5 : 1 },
|
|
54
|
+
]}
|
|
55
|
+
>
|
|
56
|
+
{icon?.({ color, size: TAB_ACCESSORY_ICON_SIZE })}
|
|
57
|
+
<Text style={[styles.label, { color }]}>{label}</Text>
|
|
58
|
+
</Pressable>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Covers the accessory glass edge to edge, so there is no shape inside the glass. */
|
|
63
|
+
function FilledContent({
|
|
64
|
+
label,
|
|
65
|
+
onPress,
|
|
66
|
+
icon,
|
|
67
|
+
disabled = false,
|
|
68
|
+
backgroundColor: backgroundColorProp,
|
|
69
|
+
labelColor: labelColorProp,
|
|
70
|
+
}: TabAccessoryButtonProps) {
|
|
71
|
+
const roles = tabAccessoryRoles("filled");
|
|
72
|
+
const fill = useResolvedFieldColor(backgroundColorProp, roles.fill as string);
|
|
73
|
+
const color = useResolvedFieldColor(labelColorProp, roles.content);
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<Pressable
|
|
77
|
+
accessibilityLabel={label}
|
|
78
|
+
accessibilityRole="button"
|
|
79
|
+
accessibilityState={{ disabled }}
|
|
80
|
+
disabled={disabled}
|
|
81
|
+
onPress={onPress}
|
|
82
|
+
style={({ pressed }) => [
|
|
83
|
+
styles.content,
|
|
84
|
+
styles.filled,
|
|
85
|
+
{ backgroundColor: fill, opacity: disabled ? 0.4 : pressed ? 0.75 : 1 },
|
|
86
|
+
]}
|
|
87
|
+
>
|
|
88
|
+
{icon?.({ color, size: TAB_ACCESSORY_ICON_SIZE })}
|
|
89
|
+
<Text style={[styles.label, { color }]}>{label}</Text>
|
|
90
|
+
</Pressable>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function FloatingPill({
|
|
95
|
+
label,
|
|
96
|
+
onPress,
|
|
97
|
+
icon,
|
|
98
|
+
disabled,
|
|
99
|
+
backgroundColor,
|
|
100
|
+
labelColor,
|
|
101
|
+
}: TabAccessoryButtonProps) {
|
|
102
|
+
const { screen } = useThemeSpacing();
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<View
|
|
106
|
+
pointerEvents="box-none"
|
|
107
|
+
style={[styles.floating, { left: screen, right: screen, bottom: screen }]}
|
|
108
|
+
>
|
|
109
|
+
<Button
|
|
110
|
+
backgroundColor={backgroundColor}
|
|
111
|
+
disabled={disabled}
|
|
112
|
+
icon={icon}
|
|
113
|
+
label={label}
|
|
114
|
+
labelColor={labelColor}
|
|
115
|
+
onPress={onPress}
|
|
116
|
+
radius="full"
|
|
117
|
+
style={styles.pillShadow}
|
|
118
|
+
/>
|
|
119
|
+
</View>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const styles = StyleSheet.create({
|
|
124
|
+
content: {
|
|
125
|
+
flex: 1,
|
|
126
|
+
alignSelf: "stretch",
|
|
127
|
+
flexDirection: "row",
|
|
128
|
+
alignItems: "center",
|
|
129
|
+
justifyContent: "center",
|
|
130
|
+
gap: 8,
|
|
131
|
+
paddingHorizontal: 16,
|
|
132
|
+
},
|
|
133
|
+
filled: {
|
|
134
|
+
borderRadius: 999,
|
|
135
|
+
},
|
|
136
|
+
label: {
|
|
137
|
+
fontSize: TAB_ACCESSORY_FONT_SIZE,
|
|
138
|
+
fontWeight: "600",
|
|
139
|
+
},
|
|
140
|
+
floating: {
|
|
141
|
+
position: "absolute",
|
|
142
|
+
},
|
|
143
|
+
pillShadow: {
|
|
144
|
+
shadowColor: "#000000",
|
|
145
|
+
shadowOpacity: 0.18,
|
|
146
|
+
shadowRadius: 12,
|
|
147
|
+
shadowOffset: { width: 0, height: 6 },
|
|
148
|
+
elevation: 6,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { TabAccessoryButton } from "./TabAccessoryButton";
|
|
2
|
+
export {
|
|
3
|
+
TAB_ACCESSORY_SCREEN_INSET,
|
|
4
|
+
tabAccessoryScreenInset,
|
|
5
|
+
type TabAccessoryPlacement,
|
|
6
|
+
} from "./tabAccessoryLayout";
|
|
7
|
+
export {
|
|
8
|
+
TAB_ACCESSORY_THEME_ROLES,
|
|
9
|
+
type TabAccessoryThemeColorProp,
|
|
10
|
+
type TabAccessoryVariant,
|
|
11
|
+
} from "./tabAccessoryThemeRoles";
|
|
12
|
+
export type { TabAccessoryButtonProps } from "./types";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import {
|
|
4
|
+
TAB_ACCESSORY_FALLBACK_HEIGHT,
|
|
5
|
+
TAB_ACCESSORY_SCREEN_INSET,
|
|
6
|
+
tabAccessoryScreenClearance,
|
|
7
|
+
tabAccessoryScreenInset,
|
|
8
|
+
tabAccessoryVisible,
|
|
9
|
+
} from "./tabAccessoryLayout.ts";
|
|
10
|
+
|
|
11
|
+
describe("tabAccessoryVisible", () => {
|
|
12
|
+
it("shows the accessory copy only where iOS draws glass", () => {
|
|
13
|
+
assert.equal(tabAccessoryVisible("accessory", true), true);
|
|
14
|
+
assert.equal(tabAccessoryVisible("accessory", false), false);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("shows the in-screen copy only where there is no glass", () => {
|
|
18
|
+
assert.equal(tabAccessoryVisible("screen", false), true);
|
|
19
|
+
assert.equal(tabAccessoryVisible("screen", true), false);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("tabAccessoryScreenInset", () => {
|
|
24
|
+
it("leaves the pill height plus an even gap above and below it", () => {
|
|
25
|
+
assert.equal(tabAccessoryScreenInset(16), TAB_ACCESSORY_FALLBACK_HEIGHT + 32);
|
|
26
|
+
assert.equal(tabAccessoryScreenInset(20), TAB_ACCESSORY_FALLBACK_HEIGHT + 40);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("matches TAB_ACCESSORY_SCREEN_INSET with the default 16 spacing", () => {
|
|
30
|
+
assert.equal(tabAccessoryScreenInset(16), TAB_ACCESSORY_SCREEN_INSET);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("tabAccessoryScreenClearance", () => {
|
|
35
|
+
it("clears the floating fallback pill where there is no glass", () => {
|
|
36
|
+
assert.equal(tabAccessoryScreenClearance(false, 20), tabAccessoryScreenInset(20));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("adds nothing on iOS 26, where the accessory is in the native tab bar", () => {
|
|
40
|
+
assert.equal(tabAccessoryScreenClearance(true, 20), 0);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type TabAccessoryPlacement = "accessory" | "screen";
|
|
2
|
+
|
|
3
|
+
export const TAB_ACCESSORY_ICON_SIZE = 20;
|
|
4
|
+
export const TAB_ACCESSORY_FONT_SIZE = 17;
|
|
5
|
+
/** Same minimum height as `Button`. */
|
|
6
|
+
export const TAB_ACCESSORY_FALLBACK_HEIGHT = 52;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Bottom padding for a screen's scroll content so the fallback pill never
|
|
10
|
+
* hides the last item. The pill sits `screen` above the tabs (the same gap
|
|
11
|
+
* as its sides), so the content needs that gap below and above it.
|
|
12
|
+
* Pass `useThemeSpacing().screen`. Pure so it can be unit-tested.
|
|
13
|
+
*/
|
|
14
|
+
export function tabAccessoryScreenInset(screen: number): number {
|
|
15
|
+
return TAB_ACCESSORY_FALLBACK_HEIGHT + screen * 2;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** `tabAccessoryScreenInset` with the default 16 spacing. */
|
|
19
|
+
export const TAB_ACCESSORY_SCREEN_INSET = tabAccessoryScreenInset(16);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Mount one copy in `NativeTabs.BottomAccessory` and one in the screen;
|
|
23
|
+
* each renders only where it belongs. iOS 26+ has the glass accessory,
|
|
24
|
+
* other platforms float a pill inside the screen. Pure so it can be unit-tested.
|
|
25
|
+
*/
|
|
26
|
+
export function tabAccessoryVisible(
|
|
27
|
+
placement: TabAccessoryPlacement,
|
|
28
|
+
glass: boolean,
|
|
29
|
+
): boolean {
|
|
30
|
+
return placement === "accessory" ? glass : !glass;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Extra bottom room a scrolling screen needs for its in-screen copy.
|
|
35
|
+
* Only the fallback pill floats over the screen; on iOS 26+ the accessory
|
|
36
|
+
* is part of the native tab bar. Pure so it can be unit-tested.
|
|
37
|
+
*/
|
|
38
|
+
export function tabAccessoryScreenClearance(
|
|
39
|
+
glass: boolean,
|
|
40
|
+
screen: number,
|
|
41
|
+
): number {
|
|
42
|
+
return glass ? 0 : tabAccessoryScreenInset(screen);
|
|
43
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import {
|
|
4
|
+
TAB_ACCESSORY_THEME_ROLES,
|
|
5
|
+
tabAccessoryRoles,
|
|
6
|
+
} from "./tabAccessoryThemeRoles.ts";
|
|
7
|
+
|
|
8
|
+
describe("TAB_ACCESSORY_THEME_ROLES", () => {
|
|
9
|
+
it("maps the glass content colour to a dedicated role", () => {
|
|
10
|
+
assert.equal(TAB_ACCESSORY_THEME_ROLES.color, "tabAccessoryLabel");
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe("tabAccessoryRoles", () => {
|
|
15
|
+
it("draws glass content in the accessory label colour with no fill", () => {
|
|
16
|
+
assert.deepEqual(tabAccessoryRoles("glass"), {
|
|
17
|
+
fill: undefined,
|
|
18
|
+
content: "tabAccessoryLabel",
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("fills with the button colours so it matches the fallback pill", () => {
|
|
23
|
+
assert.deepEqual(tabAccessoryRoles("filled"), {
|
|
24
|
+
fill: "buttonBackground",
|
|
25
|
+
content: "buttonLabel",
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const TAB_ACCESSORY_THEME_ROLES = {
|
|
2
|
+
color: "tabAccessoryLabel",
|
|
3
|
+
} as const;
|
|
4
|
+
|
|
5
|
+
export type TabAccessoryThemeColorProp = keyof typeof TAB_ACCESSORY_THEME_ROLES;
|
|
6
|
+
|
|
7
|
+
export type TabAccessoryVariant = "glass" | "filled";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Theme roles for the accessory content. Glass draws only an icon and label
|
|
11
|
+
* on the system glass; filled covers the glass with the button colours.
|
|
12
|
+
*/
|
|
13
|
+
export function tabAccessoryRoles(variant: TabAccessoryVariant): {
|
|
14
|
+
fill: string | undefined;
|
|
15
|
+
content: string;
|
|
16
|
+
} {
|
|
17
|
+
if (variant === "filled") {
|
|
18
|
+
// Same roles as Button (BUTTON_THEME_ROLES), so it matches the fallback pill.
|
|
19
|
+
return { fill: "buttonBackground", content: "buttonLabel" };
|
|
20
|
+
}
|
|
21
|
+
return { fill: undefined, content: TAB_ACCESSORY_THEME_ROLES.color };
|
|
22
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ButtonIcon } from "../Button";
|
|
2
|
+
import type { TabAccessoryPlacement } from "./tabAccessoryLayout";
|
|
3
|
+
import type { TabAccessoryVariant } from "./tabAccessoryThemeRoles";
|
|
4
|
+
|
|
5
|
+
export type TabAccessoryButtonProps = {
|
|
6
|
+
/**
|
|
7
|
+
* `"accessory"` inside `NativeTabs.BottomAccessory` (renders on iOS 26+ only).
|
|
8
|
+
* `"screen"` inside the tab screen (renders on Android and iOS 18 and earlier only).
|
|
9
|
+
*/
|
|
10
|
+
placement: TabAccessoryPlacement;
|
|
11
|
+
label: string;
|
|
12
|
+
onPress: () => void;
|
|
13
|
+
icon?: ButtonIcon;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* iOS 26+ look. `"glass"` (default): icon and label on the system glass.
|
|
17
|
+
* `"filled"`: a pill in the button colours covers the glass. The fallback
|
|
18
|
+
* pill on other platforms is always filled.
|
|
19
|
+
*/
|
|
20
|
+
variant?: TabAccessoryVariant;
|
|
21
|
+
/** Glass variant content colour. Defaults to theme role `tabAccessoryLabel`. */
|
|
22
|
+
color?: string;
|
|
23
|
+
/** Filled pill fill (filled variant and fallback). Defaults to theme role `buttonBackground`. */
|
|
24
|
+
backgroundColor?: string;
|
|
25
|
+
/** Filled pill label and icon (filled variant and fallback). Defaults to theme role `buttonLabel`. */
|
|
26
|
+
labelColor?: string;
|
|
27
|
+
};
|
package/src/components/index.ts
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
export {
|
|
2
2
|
Button,
|
|
3
|
-
|
|
3
|
+
BUTTON_ICON_SIZE,
|
|
4
|
+
BUTTON_THEME_ROLES,
|
|
4
5
|
buttonRadiusValue,
|
|
6
|
+
type ButtonIcon,
|
|
7
|
+
type ButtonIconPosition,
|
|
8
|
+
type ButtonProps,
|
|
5
9
|
type ButtonRadius,
|
|
10
|
+
type ButtonThemeColorProp,
|
|
11
|
+
type ButtonVariant,
|
|
6
12
|
} from "./Button";
|
|
13
|
+
export {
|
|
14
|
+
Choice,
|
|
15
|
+
CHOICE_ICON_SIZE,
|
|
16
|
+
CHOICE_THEME_ROLES,
|
|
17
|
+
type ChoiceProps,
|
|
18
|
+
type ChoiceThemeColorProp,
|
|
19
|
+
} from "./Choice";
|
|
7
20
|
export {
|
|
8
21
|
LinkBlocks,
|
|
9
22
|
filterLinkBlockGroups,
|
|
@@ -20,7 +33,23 @@ export {
|
|
|
20
33
|
type FieldTextProps,
|
|
21
34
|
type FieldTextareaProps,
|
|
22
35
|
} from "./Field";
|
|
23
|
-
export {
|
|
36
|
+
export {
|
|
37
|
+
Form,
|
|
38
|
+
FormCloseButton,
|
|
39
|
+
FORM_THEME_ROLES,
|
|
40
|
+
type FormProps,
|
|
41
|
+
type FormThemeColorProp,
|
|
42
|
+
} from "./Form";
|
|
43
|
+
export {
|
|
44
|
+
FormSheet,
|
|
45
|
+
FORM_SHEET_THEME_ROLES,
|
|
46
|
+
formSheetSnapPoints,
|
|
47
|
+
type FormSheetInset,
|
|
48
|
+
type FormSheetProps,
|
|
49
|
+
type FormSheetSnapIndex,
|
|
50
|
+
type FormSheetSnapInput,
|
|
51
|
+
type FormSheetThemeColorProp,
|
|
52
|
+
} from "./FormSheet";
|
|
24
53
|
export {
|
|
25
54
|
ErrorBanner,
|
|
26
55
|
ErrorBannerField,
|
|
@@ -32,6 +61,7 @@ export {
|
|
|
32
61
|
useErrorBannerField,
|
|
33
62
|
type ErrorBannerThemeColorProp,
|
|
34
63
|
type ErrorBannerProps,
|
|
64
|
+
type ErrorBannerScrollTarget,
|
|
35
65
|
type FieldError,
|
|
36
66
|
} from "./ErrorBanner";
|
|
37
67
|
export {
|
|
@@ -67,3 +97,35 @@ export {
|
|
|
67
97
|
type SliderThemeColorProp,
|
|
68
98
|
type SliderProps,
|
|
69
99
|
} from "./Slider";
|
|
100
|
+
export {
|
|
101
|
+
HeaderCapsule,
|
|
102
|
+
HeaderGroup,
|
|
103
|
+
HeaderIcon,
|
|
104
|
+
HEADER_BUTTON_THEME_ROLES,
|
|
105
|
+
supportsLiquidGlass,
|
|
106
|
+
type HeaderButtonThemeColorProp,
|
|
107
|
+
type HeaderButtonIcon,
|
|
108
|
+
type HeaderCapsuleProps,
|
|
109
|
+
type HeaderGroupProps,
|
|
110
|
+
type HeaderIconProps,
|
|
111
|
+
} from "./HeaderButton";
|
|
112
|
+
export { HeaderWash } from "./HeaderWash";
|
|
113
|
+
export {
|
|
114
|
+
TabAccessoryButton,
|
|
115
|
+
TAB_ACCESSORY_SCREEN_INSET,
|
|
116
|
+
TAB_ACCESSORY_THEME_ROLES,
|
|
117
|
+
tabAccessoryScreenInset,
|
|
118
|
+
type TabAccessoryButtonProps,
|
|
119
|
+
type TabAccessoryPlacement,
|
|
120
|
+
type TabAccessoryThemeColorProp,
|
|
121
|
+
type TabAccessoryVariant,
|
|
122
|
+
} from "./TabAccessoryButton";
|
|
123
|
+
export {
|
|
124
|
+
Page,
|
|
125
|
+
PageBleed,
|
|
126
|
+
PAGE_THEME_ROLES,
|
|
127
|
+
type PageBleedProps,
|
|
128
|
+
type PageProps,
|
|
129
|
+
type PageTabAccessory,
|
|
130
|
+
type PageThemeColorProp,
|
|
131
|
+
} from "./Page";
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
|
-
export const version = "0.
|
|
1
|
+
export const version = "0.16.0";
|
|
2
2
|
|
|
3
3
|
export * from "./theme";
|
|
4
|
+
export { SHEET_TOP_RADIUS, screenPaddingHorizontal } from "./layout";
|
|
4
5
|
export {
|
|
5
6
|
Button,
|
|
6
|
-
|
|
7
|
+
BUTTON_ICON_SIZE,
|
|
8
|
+
BUTTON_THEME_ROLES,
|
|
7
9
|
buttonRadiusValue,
|
|
10
|
+
type ButtonIcon,
|
|
11
|
+
type ButtonIconPosition,
|
|
12
|
+
type ButtonProps,
|
|
8
13
|
type ButtonRadius,
|
|
14
|
+
type ButtonThemeColorProp,
|
|
15
|
+
type ButtonVariant,
|
|
9
16
|
} from "./components/Button";
|
|
17
|
+
export {
|
|
18
|
+
Choice,
|
|
19
|
+
CHOICE_ICON_SIZE,
|
|
20
|
+
CHOICE_THEME_ROLES,
|
|
21
|
+
type ChoiceProps,
|
|
22
|
+
type ChoiceThemeColorProp,
|
|
23
|
+
} from "./components/Choice";
|
|
10
24
|
export {
|
|
11
25
|
LinkBlocks,
|
|
12
26
|
filterLinkBlockGroups,
|
|
@@ -26,8 +40,20 @@ export {
|
|
|
26
40
|
export {
|
|
27
41
|
Form,
|
|
28
42
|
FormCloseButton,
|
|
43
|
+
FORM_THEME_ROLES,
|
|
44
|
+
type FormThemeColorProp,
|
|
29
45
|
type FormProps,
|
|
30
46
|
} from "./components/Form";
|
|
47
|
+
export {
|
|
48
|
+
FormSheet,
|
|
49
|
+
FORM_SHEET_THEME_ROLES,
|
|
50
|
+
formSheetSnapPoints,
|
|
51
|
+
type FormSheetInset,
|
|
52
|
+
type FormSheetProps,
|
|
53
|
+
type FormSheetSnapIndex,
|
|
54
|
+
type FormSheetSnapInput,
|
|
55
|
+
type FormSheetThemeColorProp,
|
|
56
|
+
} from "./components/FormSheet";
|
|
31
57
|
export {
|
|
32
58
|
ErrorBanner,
|
|
33
59
|
ErrorBannerField,
|
|
@@ -39,6 +65,7 @@ export {
|
|
|
39
65
|
useErrorBannerField,
|
|
40
66
|
type ErrorBannerThemeColorProp,
|
|
41
67
|
type ErrorBannerProps,
|
|
68
|
+
type ErrorBannerScrollTarget,
|
|
42
69
|
type FieldError,
|
|
43
70
|
} from "./components/ErrorBanner";
|
|
44
71
|
export {
|
|
@@ -74,4 +101,36 @@ export {
|
|
|
74
101
|
type SliderThemeColorProp,
|
|
75
102
|
type SliderProps,
|
|
76
103
|
} from "./components/Slider";
|
|
104
|
+
export {
|
|
105
|
+
HeaderCapsule,
|
|
106
|
+
HeaderGroup,
|
|
107
|
+
HeaderIcon,
|
|
108
|
+
HEADER_BUTTON_THEME_ROLES,
|
|
109
|
+
supportsLiquidGlass,
|
|
110
|
+
type HeaderButtonThemeColorProp,
|
|
111
|
+
type HeaderButtonIcon,
|
|
112
|
+
type HeaderCapsuleProps,
|
|
113
|
+
type HeaderGroupProps,
|
|
114
|
+
type HeaderIconProps,
|
|
115
|
+
} from "./components/HeaderButton";
|
|
116
|
+
export { HeaderWash } from "./components/HeaderWash";
|
|
117
|
+
export {
|
|
118
|
+
TabAccessoryButton,
|
|
119
|
+
TAB_ACCESSORY_SCREEN_INSET,
|
|
120
|
+
TAB_ACCESSORY_THEME_ROLES,
|
|
121
|
+
tabAccessoryScreenInset,
|
|
122
|
+
type TabAccessoryButtonProps,
|
|
123
|
+
type TabAccessoryPlacement,
|
|
124
|
+
type TabAccessoryThemeColorProp,
|
|
125
|
+
type TabAccessoryVariant,
|
|
126
|
+
} from "./components/TabAccessoryButton";
|
|
127
|
+
export {
|
|
128
|
+
Page,
|
|
129
|
+
PageBleed,
|
|
130
|
+
PAGE_THEME_ROLES,
|
|
131
|
+
type PageBleedProps,
|
|
132
|
+
type PageProps,
|
|
133
|
+
type PageTabAccessory,
|
|
134
|
+
type PageThemeColorProp,
|
|
135
|
+
} from "./components/Page";
|
|
77
136
|
export * as components from "./components";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { estimateHeaderHeight, formFieldScrollY } from "./headerInset.ts";
|
|
4
|
+
|
|
5
|
+
describe("formFieldScrollY", () => {
|
|
6
|
+
// iOS, transparent header ending at 100, banner in a window overlay.
|
|
7
|
+
const ios = { scrollTop: 0, visibleTop: 100, bannerBottom: 0, minScrollY: -100, gap: 12 };
|
|
8
|
+
|
|
9
|
+
it("puts the field just under the header when there is no banner", () => {
|
|
10
|
+
assert.equal(formFieldScrollY({ ...ios, fieldY: 400 }), 400 - 100 - 12);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("puts the field under the banner when the banner reaches lower than the header", () => {
|
|
14
|
+
assert.equal(formFieldScrollY({ ...ios, fieldY: 400, bannerBottom: 180 }), 400 - 180 - 12);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("never scrolls above the top of the content", () => {
|
|
18
|
+
assert.equal(formFieldScrollY({ ...ios, fieldY: 20, bannerBottom: 180 }), -100);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("accounts for a scroll view that starts below an opaque header", () => {
|
|
22
|
+
// Scroll view starts at window y 100, no inset; overlay banner to 180.
|
|
23
|
+
assert.equal(
|
|
24
|
+
formFieldScrollY({
|
|
25
|
+
fieldY: 400,
|
|
26
|
+
scrollTop: 100,
|
|
27
|
+
visibleTop: 100,
|
|
28
|
+
bannerBottom: 180,
|
|
29
|
+
minScrollY: 0,
|
|
30
|
+
gap: 12,
|
|
31
|
+
}),
|
|
32
|
+
400 + 100 - 180 - 12,
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("clears a transparent Android header and the banner below it", () => {
|
|
37
|
+
// Content starts at window 0 under an 80pt header; banner from 80 to 200.
|
|
38
|
+
assert.equal(
|
|
39
|
+
formFieldScrollY({
|
|
40
|
+
fieldY: 500,
|
|
41
|
+
scrollTop: 0,
|
|
42
|
+
visibleTop: 80,
|
|
43
|
+
bannerBottom: 200,
|
|
44
|
+
minScrollY: 0,
|
|
45
|
+
gap: 12,
|
|
46
|
+
}),
|
|
47
|
+
500 - 200 - 12,
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe("estimateHeaderHeight", () => {
|
|
53
|
+
it("adds the standard iOS navigation bar to the status bar", () => {
|
|
54
|
+
assert.equal(estimateHeaderHeight("ios", 59), 59 + 44);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("adds the standard Android toolbar to the status bar", () => {
|
|
58
|
+
assert.equal(estimateHeaderHeight("android", 24), 24 + 56);
|
|
59
|
+
});
|
|
60
|
+
});
|