orn-ui 0.2.9 → 0.3.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/AGENTS.md +67 -52
- package/README.md +5 -9
- package/lib/commonjs/atoms/Avatar.js +77 -5
- package/lib/commonjs/atoms/Avatar.js.map +1 -1
- package/lib/commonjs/atoms/Badge.js +17 -8
- package/lib/commonjs/atoms/Badge.js.map +1 -1
- package/lib/commonjs/atoms/Button.js +108 -39
- package/lib/commonjs/atoms/Button.js.map +1 -1
- package/lib/commonjs/atoms/Card.js +24 -2
- package/lib/commonjs/atoms/Card.js.map +1 -1
- package/lib/commonjs/atoms/Checkbox.js +41 -10
- package/lib/commonjs/atoms/Checkbox.js.map +1 -1
- package/lib/commonjs/atoms/Divider.js +30 -5
- package/lib/commonjs/atoms/Divider.js.map +1 -1
- package/lib/commonjs/atoms/EmptyState.js +58 -20
- package/lib/commonjs/atoms/EmptyState.js.map +1 -1
- package/lib/commonjs/atoms/Fab.js +32 -12
- package/lib/commonjs/atoms/Fab.js.map +1 -1
- package/lib/commonjs/atoms/Gradient.js +102 -36
- package/lib/commonjs/atoms/Gradient.js.map +1 -1
- package/lib/commonjs/atoms/IconButton.js +25 -4
- package/lib/commonjs/atoms/IconButton.js.map +1 -1
- package/lib/commonjs/atoms/Image.js +61 -25
- package/lib/commonjs/atoms/Image.js.map +1 -1
- package/lib/commonjs/atoms/Input.js +105 -17
- package/lib/commonjs/atoms/Input.js.map +1 -1
- package/lib/commonjs/atoms/KeyValueRow.js +37 -9
- package/lib/commonjs/atoms/KeyValueRow.js.map +1 -1
- package/lib/commonjs/atoms/PressableScale.js +25 -5
- package/lib/commonjs/atoms/PressableScale.js.map +1 -1
- package/lib/commonjs/atoms/ShinyText.js +29 -29
- package/lib/commonjs/atoms/Skeleton.js +28 -13
- package/lib/commonjs/atoms/Skeleton.js.map +1 -1
- package/lib/commonjs/atoms/Spinner.js +81 -22
- package/lib/commonjs/atoms/Spinner.js.map +1 -1
- package/lib/commonjs/atoms/Text.js +56 -5
- package/lib/commonjs/atoms/Text.js.map +1 -1
- package/lib/commonjs/atoms/Transition.js +46 -43
- package/lib/commonjs/atoms/Transition.js.map +1 -1
- package/lib/commonjs/atoms/index.js +6 -0
- package/lib/commonjs/atoms/index.js.map +1 -1
- package/lib/commonjs/atoms/inputValidation.js +56 -0
- package/lib/commonjs/atoms/inputValidation.js.map +1 -0
- package/lib/commonjs/icons/Icon.js +4 -4
- package/lib/commonjs/icons/defaultIcons.js +576 -24
- package/lib/commonjs/icons/defaultIcons.js.map +1 -1
- package/lib/commonjs/icons/index.js +6 -0
- package/lib/commonjs/icons/index.js.map +1 -1
- package/lib/commonjs/molecules/AvatarHeader.js +47 -14
- package/lib/commonjs/molecules/AvatarHeader.js.map +1 -1
- package/lib/commonjs/molecules/FormActions.js +25 -9
- package/lib/commonjs/molecules/FormActions.js.map +1 -1
- package/lib/commonjs/molecules/InfoRow.js +30 -14
- package/lib/commonjs/molecules/InfoRow.js.map +1 -1
- package/lib/commonjs/molecules/OptionCard.js +37 -22
- package/lib/commonjs/molecules/OptionCard.js.map +1 -1
- package/lib/commonjs/molecules/SegmentedControl.js +103 -14
- package/lib/commonjs/molecules/SegmentedControl.js.map +1 -1
- package/lib/commonjs/molecules/Stepper.js +61 -16
- package/lib/commonjs/molecules/Stepper.js.map +1 -1
- package/lib/commonjs/molecules/Steps.js +105 -41
- package/lib/commonjs/molecules/Steps.js.map +1 -1
- package/lib/commonjs/molecules/SymmetricGrid.js +26 -18
- package/lib/commonjs/molecules/SymmetricGrid.js.map +1 -1
- package/lib/commonjs/organisms/Alert.js +49 -35
- package/lib/commonjs/organisms/Alert.js.map +1 -1
- package/lib/commonjs/organisms/AlertProvider.js +10 -10
- package/lib/commonjs/organisms/BottomSheet.js +137 -85
- package/lib/commonjs/organisms/BottomSheet.js.map +1 -1
- package/lib/commonjs/organisms/Chart.js +197 -156
- package/lib/commonjs/organisms/Chart.js.map +1 -1
- package/lib/commonjs/organisms/DateField.js +36 -20
- package/lib/commonjs/organisms/DateField.js.map +1 -1
- package/lib/commonjs/organisms/DatePicker.js +56 -33
- package/lib/commonjs/organisms/DatePicker.js.map +1 -1
- package/lib/commonjs/organisms/List.js +62 -34
- package/lib/commonjs/organisms/List.js.map +1 -1
- package/lib/commonjs/organisms/Modal.js +120 -82
- package/lib/commonjs/organisms/Modal.js.map +1 -1
- package/lib/commonjs/organisms/NavigationBar.js +63 -24
- package/lib/commonjs/organisms/NavigationBar.js.map +1 -1
- package/lib/commonjs/organisms/OptionWheel.js +64 -64
- package/lib/commonjs/organisms/OptionWheel.js.map +1 -1
- package/lib/commonjs/organisms/ReorderableList.js +48 -27
- package/lib/commonjs/organisms/ReorderableList.js.map +1 -1
- package/lib/commonjs/organisms/Screen.js +68 -35
- package/lib/commonjs/organisms/Screen.js.map +1 -1
- package/lib/commonjs/organisms/SearchList.js +56 -26
- package/lib/commonjs/organisms/SearchList.js.map +1 -1
- package/lib/commonjs/organisms/Select.js +45 -24
- package/lib/commonjs/organisms/Select.js.map +1 -1
- package/lib/commonjs/organisms/Slides.js +36 -23
- package/lib/commonjs/organisms/Slides.js.map +1 -1
- package/lib/commonjs/organisms/ThemeToggle.js +10 -9
- package/lib/commonjs/organisms/ThemeToggle.js.map +1 -1
- package/lib/commonjs/organisms/Timeline.js +73 -56
- package/lib/commonjs/organisms/Timeline.js.map +1 -1
- package/lib/commonjs/organisms/Toast.js +46 -15
- package/lib/commonjs/organisms/Toast.js.map +1 -1
- package/lib/commonjs/organisms/ToastProvider.js +14 -10
- package/lib/commonjs/organisms/ToastProvider.js.map +1 -1
- package/lib/commonjs/organisms/Wizard.js +40 -15
- package/lib/commonjs/organisms/Wizard.js.map +1 -1
- package/lib/commonjs/organisms/chart/frame.js +25 -25
- package/lib/commonjs/organisms/chart/frame.js.map +1 -1
- package/lib/commonjs/organisms/chart/marks.js +42 -42
- package/lib/commonjs/organisms/chart/math.js +84 -85
- package/lib/commonjs/organisms/chart/math.js.map +1 -1
- package/lib/commonjs/organisms/chart/palette.js +28 -28
- package/lib/commonjs/organisms/imperativeBridge.js +5 -5
- package/lib/commonjs/organisms/imperativeBridge.js.map +1 -1
- package/lib/commonjs/organisms/useSlides.js +53 -21
- package/lib/commonjs/organisms/useSlides.js.map +1 -1
- package/lib/commonjs/safe-area/SafeAreaUIProvider.js +9 -66
- package/lib/commonjs/safe-area/SafeAreaUIProvider.js.map +1 -1
- package/lib/commonjs/safe-area/index.js.map +1 -1
- package/lib/commonjs/theme/KeyboardAvoidance.js +206 -0
- package/lib/commonjs/theme/KeyboardAvoidance.js.map +1 -0
- package/lib/commonjs/theme/NativeOverlay.js +263 -0
- package/lib/commonjs/theme/NativeOverlay.js.map +1 -0
- package/lib/commonjs/theme/UIProvider.js +86 -33
- package/lib/commonjs/theme/UIProvider.js.map +1 -1
- package/lib/commonjs/theme/colors.js +17 -17
- package/lib/commonjs/theme/colors.js.map +1 -1
- package/lib/commonjs/theme/createStyles.js +19 -16
- package/lib/commonjs/theme/createStyles.js.map +1 -1
- package/lib/commonjs/theme/createTheme.js +6 -6
- package/lib/commonjs/theme/index.js +6 -0
- package/lib/commonjs/theme/index.js.map +1 -1
- package/lib/commonjs/theme/insets.js +1 -1
- package/lib/commonjs/theme/labels.js +29 -1
- package/lib/commonjs/theme/labels.js.map +1 -1
- package/lib/commonjs/theme/palettes.js +25 -23
- package/lib/commonjs/theme/palettes.js.map +1 -1
- package/lib/commonjs/theme/tokens.js +28 -14
- package/lib/commonjs/theme/tokens.js.map +1 -1
- package/lib/commonjs/theme/useKeyboardField.js +36 -0
- package/lib/commonjs/theme/useKeyboardField.js.map +1 -0
- package/lib/commonjs/theme/useReduceMotion.js +31 -0
- package/lib/commonjs/theme/useReduceMotion.js.map +1 -0
- package/lib/module/atoms/Avatar.js +79 -8
- package/lib/module/atoms/Avatar.js.map +1 -1
- package/lib/module/atoms/Badge.js +17 -8
- package/lib/module/atoms/Badge.js.map +1 -1
- package/lib/module/atoms/Button.js +110 -41
- package/lib/module/atoms/Button.js.map +1 -1
- package/lib/module/atoms/Card.js +24 -2
- package/lib/module/atoms/Card.js.map +1 -1
- package/lib/module/atoms/Checkbox.js +42 -11
- package/lib/module/atoms/Checkbox.js.map +1 -1
- package/lib/module/atoms/Divider.js +31 -6
- package/lib/module/atoms/Divider.js.map +1 -1
- package/lib/module/atoms/EmptyState.js +58 -20
- package/lib/module/atoms/EmptyState.js.map +1 -1
- package/lib/module/atoms/Fab.js +33 -13
- package/lib/module/atoms/Fab.js.map +1 -1
- package/lib/module/atoms/Gradient.js +103 -37
- package/lib/module/atoms/Gradient.js.map +1 -1
- package/lib/module/atoms/IconButton.js +25 -4
- package/lib/module/atoms/IconButton.js.map +1 -1
- package/lib/module/atoms/Image.js +61 -25
- package/lib/module/atoms/Image.js.map +1 -1
- package/lib/module/atoms/Input.js +108 -20
- package/lib/module/atoms/Input.js.map +1 -1
- package/lib/module/atoms/KeyValueRow.js +37 -9
- package/lib/module/atoms/KeyValueRow.js.map +1 -1
- package/lib/module/atoms/PressableScale.js +25 -5
- package/lib/module/atoms/PressableScale.js.map +1 -1
- package/lib/module/atoms/ShinyText.js +29 -29
- package/lib/module/atoms/Skeleton.js +30 -13
- package/lib/module/atoms/Skeleton.js.map +1 -1
- package/lib/module/atoms/Spinner.js +82 -23
- package/lib/module/atoms/Spinner.js.map +1 -1
- package/lib/module/atoms/Text.js +56 -5
- package/lib/module/atoms/Text.js.map +1 -1
- package/lib/module/atoms/Transition.js +41 -42
- package/lib/module/atoms/Transition.js.map +1 -1
- package/lib/module/atoms/index.js +1 -1
- package/lib/module/atoms/index.js.map +1 -1
- package/lib/module/atoms/inputValidation.js +52 -0
- package/lib/module/atoms/inputValidation.js.map +1 -0
- package/lib/module/icons/Icon.js +4 -4
- package/lib/module/icons/defaultIcons.js +574 -24
- package/lib/module/icons/defaultIcons.js.map +1 -1
- package/lib/module/icons/index.js +1 -1
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/molecules/AvatarHeader.js +47 -14
- package/lib/module/molecules/AvatarHeader.js.map +1 -1
- package/lib/module/molecules/FormActions.js +25 -9
- package/lib/module/molecules/FormActions.js.map +1 -1
- package/lib/module/molecules/InfoRow.js +30 -14
- package/lib/module/molecules/InfoRow.js.map +1 -1
- package/lib/module/molecules/OptionCard.js +37 -22
- package/lib/module/molecules/OptionCard.js.map +1 -1
- package/lib/module/molecules/SegmentedControl.js +107 -18
- package/lib/module/molecules/SegmentedControl.js.map +1 -1
- package/lib/module/molecules/Stepper.js +63 -18
- package/lib/module/molecules/Stepper.js.map +1 -1
- package/lib/module/molecules/Steps.js +107 -43
- package/lib/module/molecules/Steps.js.map +1 -1
- package/lib/module/molecules/SymmetricGrid.js +26 -18
- package/lib/module/molecules/SymmetricGrid.js.map +1 -1
- package/lib/module/organisms/Alert.js +51 -37
- package/lib/module/organisms/Alert.js.map +1 -1
- package/lib/module/organisms/AlertProvider.js +10 -10
- package/lib/module/organisms/BottomSheet.js +142 -88
- package/lib/module/organisms/BottomSheet.js.map +1 -1
- package/lib/module/organisms/Chart.js +199 -158
- package/lib/module/organisms/Chart.js.map +1 -1
- package/lib/module/organisms/DateField.js +36 -20
- package/lib/module/organisms/DateField.js.map +1 -1
- package/lib/module/organisms/DatePicker.js +56 -33
- package/lib/module/organisms/DatePicker.js.map +1 -1
- package/lib/module/organisms/List.js +62 -34
- package/lib/module/organisms/List.js.map +1 -1
- package/lib/module/organisms/Modal.js +122 -84
- package/lib/module/organisms/Modal.js.map +1 -1
- package/lib/module/organisms/NavigationBar.js +64 -25
- package/lib/module/organisms/NavigationBar.js.map +1 -1
- package/lib/module/organisms/OptionWheel.js +64 -64
- package/lib/module/organisms/OptionWheel.js.map +1 -1
- package/lib/module/organisms/ReorderableList.js +48 -27
- package/lib/module/organisms/ReorderableList.js.map +1 -1
- package/lib/module/organisms/Screen.js +70 -37
- package/lib/module/organisms/Screen.js.map +1 -1
- package/lib/module/organisms/SearchList.js +56 -26
- package/lib/module/organisms/SearchList.js.map +1 -1
- package/lib/module/organisms/Select.js +46 -25
- package/lib/module/organisms/Select.js.map +1 -1
- package/lib/module/organisms/Slides.js +37 -24
- package/lib/module/organisms/Slides.js.map +1 -1
- package/lib/module/organisms/ThemeToggle.js +11 -10
- package/lib/module/organisms/ThemeToggle.js.map +1 -1
- package/lib/module/organisms/Timeline.js +73 -56
- package/lib/module/organisms/Timeline.js.map +1 -1
- package/lib/module/organisms/Toast.js +47 -16
- package/lib/module/organisms/Toast.js.map +1 -1
- package/lib/module/organisms/ToastProvider.js +15 -11
- package/lib/module/organisms/ToastProvider.js.map +1 -1
- package/lib/module/organisms/Wizard.js +41 -16
- package/lib/module/organisms/Wizard.js.map +1 -1
- package/lib/module/organisms/chart/frame.js +25 -25
- package/lib/module/organisms/chart/frame.js.map +1 -1
- package/lib/module/organisms/chart/marks.js +42 -42
- package/lib/module/organisms/chart/math.js +84 -85
- package/lib/module/organisms/chart/math.js.map +1 -1
- package/lib/module/organisms/chart/palette.js +28 -28
- package/lib/module/organisms/imperativeBridge.js +5 -5
- package/lib/module/organisms/imperativeBridge.js.map +1 -1
- package/lib/module/organisms/useSlides.js +53 -21
- package/lib/module/organisms/useSlides.js.map +1 -1
- package/lib/module/safe-area/SafeAreaUIProvider.js +10 -65
- package/lib/module/safe-area/SafeAreaUIProvider.js.map +1 -1
- package/lib/module/safe-area/index.js +1 -0
- package/lib/module/safe-area/index.js.map +1 -1
- package/lib/module/theme/KeyboardAvoidance.js +198 -0
- package/lib/module/theme/KeyboardAvoidance.js.map +1 -0
- package/lib/module/theme/NativeOverlay.js +257 -0
- package/lib/module/theme/NativeOverlay.js.map +1 -0
- package/lib/module/theme/UIProvider.js +88 -35
- package/lib/module/theme/UIProvider.js.map +1 -1
- package/lib/module/theme/colors.js +17 -17
- package/lib/module/theme/colors.js.map +1 -1
- package/lib/module/theme/createStyles.js +20 -16
- package/lib/module/theme/createStyles.js.map +1 -1
- package/lib/module/theme/createTheme.js +6 -6
- package/lib/module/theme/index.js +1 -1
- package/lib/module/theme/index.js.map +1 -1
- package/lib/module/theme/insets.js +1 -1
- package/lib/module/theme/labels.js +29 -1
- package/lib/module/theme/labels.js.map +1 -1
- package/lib/module/theme/palettes.js +25 -23
- package/lib/module/theme/palettes.js.map +1 -1
- package/lib/module/theme/tokens.js +27 -13
- package/lib/module/theme/tokens.js.map +1 -1
- package/lib/module/theme/useKeyboardField.js +33 -0
- package/lib/module/theme/useKeyboardField.js.map +1 -0
- package/lib/module/theme/useReduceMotion.js +28 -0
- package/lib/module/theme/useReduceMotion.js.map +1 -0
- package/lib/typescript/atoms/Avatar.d.ts +35 -5
- package/lib/typescript/atoms/Avatar.d.ts.map +1 -1
- package/lib/typescript/atoms/Badge.d.ts +14 -3
- package/lib/typescript/atoms/Badge.d.ts.map +1 -1
- package/lib/typescript/atoms/Button.d.ts +34 -3
- package/lib/typescript/atoms/Button.d.ts.map +1 -1
- package/lib/typescript/atoms/Card.d.ts +13 -2
- package/lib/typescript/atoms/Card.d.ts.map +1 -1
- package/lib/typescript/atoms/Checkbox.d.ts +26 -1
- package/lib/typescript/atoms/Checkbox.d.ts.map +1 -1
- package/lib/typescript/atoms/Divider.d.ts +18 -1
- package/lib/typescript/atoms/Divider.d.ts.map +1 -1
- package/lib/typescript/atoms/EmptyState.d.ts +30 -3
- package/lib/typescript/atoms/EmptyState.d.ts.map +1 -1
- package/lib/typescript/atoms/Fab.d.ts +24 -4
- package/lib/typescript/atoms/Fab.d.ts.map +1 -1
- package/lib/typescript/atoms/Gradient.d.ts +21 -15
- package/lib/typescript/atoms/Gradient.d.ts.map +1 -1
- package/lib/typescript/atoms/IconButton.d.ts +18 -4
- package/lib/typescript/atoms/IconButton.d.ts.map +1 -1
- package/lib/typescript/atoms/Image.d.ts +39 -17
- package/lib/typescript/atoms/Image.d.ts.map +1 -1
- package/lib/typescript/atoms/Input.d.ts +57 -7
- package/lib/typescript/atoms/Input.d.ts.map +1 -1
- package/lib/typescript/atoms/KeyValueRow.d.ts +16 -4
- package/lib/typescript/atoms/KeyValueRow.d.ts.map +1 -1
- package/lib/typescript/atoms/PressableScale.d.ts +12 -5
- package/lib/typescript/atoms/PressableScale.d.ts.map +1 -1
- package/lib/typescript/atoms/ShinyText.d.ts +17 -17
- package/lib/typescript/atoms/ShinyText.d.ts.map +1 -1
- package/lib/typescript/atoms/Skeleton.d.ts +12 -7
- package/lib/typescript/atoms/Skeleton.d.ts.map +1 -1
- package/lib/typescript/atoms/Spinner.d.ts +29 -1
- package/lib/typescript/atoms/Spinner.d.ts.map +1 -1
- package/lib/typescript/atoms/Text.d.ts +46 -0
- package/lib/typescript/atoms/Text.d.ts.map +1 -1
- package/lib/typescript/atoms/Transition.d.ts +19 -15
- package/lib/typescript/atoms/Transition.d.ts.map +1 -1
- package/lib/typescript/atoms/index.d.ts +3 -3
- package/lib/typescript/atoms/index.d.ts.map +1 -1
- package/lib/typescript/atoms/inputValidation.d.ts +29 -0
- package/lib/typescript/atoms/inputValidation.d.ts.map +1 -0
- package/lib/typescript/icons/Icon.d.ts +4 -4
- package/lib/typescript/icons/defaultIcons.d.ts +19 -2
- package/lib/typescript/icons/defaultIcons.d.ts.map +1 -1
- package/lib/typescript/icons/index.d.ts +2 -2
- package/lib/typescript/icons/index.d.ts.map +1 -1
- package/lib/typescript/icons/types.d.ts +13 -3
- package/lib/typescript/icons/types.d.ts.map +1 -1
- package/lib/typescript/molecules/AvatarHeader.d.ts +23 -4
- package/lib/typescript/molecules/AvatarHeader.d.ts.map +1 -1
- package/lib/typescript/molecules/FormActions.d.ts +21 -4
- package/lib/typescript/molecules/FormActions.d.ts.map +1 -1
- package/lib/typescript/molecules/InfoRow.d.ts +17 -3
- package/lib/typescript/molecules/InfoRow.d.ts.map +1 -1
- package/lib/typescript/molecules/OptionCard.d.ts +20 -5
- package/lib/typescript/molecules/OptionCard.d.ts.map +1 -1
- package/lib/typescript/molecules/SegmentedControl.d.ts +18 -2
- package/lib/typescript/molecules/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/molecules/Stepper.d.ts +23 -7
- package/lib/typescript/molecules/Stepper.d.ts.map +1 -1
- package/lib/typescript/molecules/Steps.d.ts +18 -4
- package/lib/typescript/molecules/Steps.d.ts.map +1 -1
- package/lib/typescript/molecules/SymmetricGrid.d.ts +15 -5
- package/lib/typescript/molecules/SymmetricGrid.d.ts.map +1 -1
- package/lib/typescript/organisms/Alert.d.ts +28 -2
- package/lib/typescript/organisms/Alert.d.ts.map +1 -1
- package/lib/typescript/organisms/AlertProvider.d.ts +10 -10
- package/lib/typescript/organisms/AlertProvider.d.ts.map +1 -1
- package/lib/typescript/organisms/BottomSheet.d.ts +20 -5
- package/lib/typescript/organisms/BottomSheet.d.ts.map +1 -1
- package/lib/typescript/organisms/Chart.d.ts +86 -75
- package/lib/typescript/organisms/Chart.d.ts.map +1 -1
- package/lib/typescript/organisms/DateField.d.ts +17 -3
- package/lib/typescript/organisms/DateField.d.ts.map +1 -1
- package/lib/typescript/organisms/DatePicker.d.ts +7 -11
- package/lib/typescript/organisms/DatePicker.d.ts.map +1 -1
- package/lib/typescript/organisms/List.d.ts +30 -3
- package/lib/typescript/organisms/List.d.ts.map +1 -1
- package/lib/typescript/organisms/Modal.d.ts +30 -3
- package/lib/typescript/organisms/Modal.d.ts.map +1 -1
- package/lib/typescript/organisms/NavigationBar.d.ts +26 -7
- package/lib/typescript/organisms/NavigationBar.d.ts.map +1 -1
- package/lib/typescript/organisms/OptionWheel.d.ts +20 -16
- package/lib/typescript/organisms/OptionWheel.d.ts.map +1 -1
- package/lib/typescript/organisms/ReorderableList.d.ts +20 -11
- package/lib/typescript/organisms/ReorderableList.d.ts.map +1 -1
- package/lib/typescript/organisms/Screen.d.ts +27 -8
- package/lib/typescript/organisms/Screen.d.ts.map +1 -1
- package/lib/typescript/organisms/SearchList.d.ts +46 -3
- package/lib/typescript/organisms/SearchList.d.ts.map +1 -1
- package/lib/typescript/organisms/Select.d.ts +26 -6
- package/lib/typescript/organisms/Select.d.ts.map +1 -1
- package/lib/typescript/organisms/Slides.d.ts +44 -26
- package/lib/typescript/organisms/Slides.d.ts.map +1 -1
- package/lib/typescript/organisms/ThemeToggle.d.ts +6 -2
- package/lib/typescript/organisms/ThemeToggle.d.ts.map +1 -1
- package/lib/typescript/organisms/Timeline.d.ts +26 -9
- package/lib/typescript/organisms/Timeline.d.ts.map +1 -1
- package/lib/typescript/organisms/Toast.d.ts +19 -4
- package/lib/typescript/organisms/Toast.d.ts.map +1 -1
- package/lib/typescript/organisms/ToastProvider.d.ts +8 -8
- package/lib/typescript/organisms/ToastProvider.d.ts.map +1 -1
- package/lib/typescript/organisms/Wizard.d.ts +24 -6
- package/lib/typescript/organisms/Wizard.d.ts.map +1 -1
- package/lib/typescript/organisms/chart/frame.d.ts +21 -21
- package/lib/typescript/organisms/chart/frame.d.ts.map +1 -1
- package/lib/typescript/organisms/chart/marks.d.ts +28 -28
- package/lib/typescript/organisms/chart/marks.d.ts.map +1 -1
- package/lib/typescript/organisms/chart/math.d.ts +69 -70
- package/lib/typescript/organisms/chart/math.d.ts.map +1 -1
- package/lib/typescript/organisms/chart/palette.d.ts +2 -2
- package/lib/typescript/organisms/chart/palette.d.ts.map +1 -1
- package/lib/typescript/organisms/imperativeBridge.d.ts +4 -4
- package/lib/typescript/organisms/useSlides.d.ts +8 -16
- package/lib/typescript/organisms/useSlides.d.ts.map +1 -1
- package/lib/typescript/safe-area/SafeAreaUIProvider.d.ts +9 -7
- package/lib/typescript/safe-area/SafeAreaUIProvider.d.ts.map +1 -1
- package/lib/typescript/safe-area/index.d.ts.map +1 -1
- package/lib/typescript/theme/KeyboardAvoidance.d.ts +62 -0
- package/lib/typescript/theme/KeyboardAvoidance.d.ts.map +1 -0
- package/lib/typescript/theme/NativeOverlay.d.ts +43 -0
- package/lib/typescript/theme/NativeOverlay.d.ts.map +1 -0
- package/lib/typescript/theme/UIProvider.d.ts +38 -20
- package/lib/typescript/theme/UIProvider.d.ts.map +1 -1
- package/lib/typescript/theme/colors.d.ts +13 -13
- package/lib/typescript/theme/colors.d.ts.map +1 -1
- package/lib/typescript/theme/createStyles.d.ts +20 -14
- package/lib/typescript/theme/createStyles.d.ts.map +1 -1
- package/lib/typescript/theme/createTheme.d.ts +5 -5
- package/lib/typescript/theme/index.d.ts +1 -1
- package/lib/typescript/theme/index.d.ts.map +1 -1
- package/lib/typescript/theme/insets.d.ts +1 -1
- package/lib/typescript/theme/insets.d.ts.map +1 -1
- package/lib/typescript/theme/labels.d.ts +57 -2
- package/lib/typescript/theme/labels.d.ts.map +1 -1
- package/lib/typescript/theme/palettes.d.ts +25 -19
- package/lib/typescript/theme/palettes.d.ts.map +1 -1
- package/lib/typescript/theme/tokens.d.ts +15 -8
- package/lib/typescript/theme/tokens.d.ts.map +1 -1
- package/lib/typescript/theme/types.d.ts +7 -7
- package/lib/typescript/theme/types.d.ts.map +1 -1
- package/lib/typescript/theme/useKeyboardField.d.ts +17 -0
- package/lib/typescript/theme/useKeyboardField.d.ts.map +1 -0
- package/lib/typescript/theme/useReduceMotion.d.ts +7 -0
- package/lib/typescript/theme/useReduceMotion.d.ts.map +1 -0
- package/llms.txt +4 -4
- package/package.json +15 -14
- package/registry/alert-provider.json +4 -3
- package/registry/alert.json +3 -2
- package/registry/avatar-header.json +1 -1
- package/registry/avatar.json +3 -2
- package/registry/badge.json +1 -1
- package/registry/bottom-sheet.json +1 -1
- package/registry/button.json +3 -2
- package/registry/card.json +1 -1
- package/registry/chart.json +5 -5
- package/registry/checkbox.json +3 -2
- package/registry/core.json +31 -15
- package/registry/date-field.json +1 -1
- package/registry/date-picker.json +3 -2
- package/registry/divider.json +1 -1
- package/registry/empty-state.json +4 -2
- package/registry/fab.json +3 -2
- package/registry/form-actions.json +3 -2
- package/registry/gradient.json +1 -1
- package/registry/icon-button.json +3 -2
- package/registry/image.json +1 -1
- package/registry/index.json +79 -61
- package/registry/info-row.json +1 -1
- package/registry/input.json +5 -1
- package/registry/key-value-row.json +1 -1
- package/registry/list.json +3 -1
- package/registry/manifest.json +3 -1
- package/registry/modal.json +1 -1
- package/registry/navigation-bar.json +1 -1
- package/registry/option-card.json +3 -2
- package/registry/option-wheel.json +1 -1
- package/registry/pressable-scale.json +3 -2
- package/registry/reorderable-list.json +1 -1
- package/registry/screen.json +1 -1
- package/registry/search-list.json +7 -1
- package/registry/segmented-control.json +1 -1
- package/registry/select.json +1 -1
- package/registry/shiny-text.json +1 -1
- package/registry/skeleton.json +3 -2
- package/registry/slides.json +2 -2
- package/registry/spinner.json +1 -1
- package/registry/stepper.json +1 -1
- package/registry/steps.json +1 -1
- package/registry/symmetric-grid.json +1 -1
- package/registry/theme-toggle.json +1 -1
- package/registry/timeline.json +1 -1
- package/registry/title.json +1 -1
- package/registry/toast-provider.json +2 -2
- package/registry/toast.json +1 -1
- package/registry/transition.json +1 -1
- package/registry/wizard.json +1 -1
- package/src/atoms/Avatar.tsx +117 -26
- package/src/atoms/Badge.tsx +20 -9
- package/src/atoms/Button.tsx +102 -30
- package/src/atoms/Card.tsx +23 -3
- package/src/atoms/Checkbox.tsx +49 -12
- package/src/atoms/Divider.tsx +34 -4
- package/src/atoms/EmptyState.tsx +63 -16
- package/src/atoms/Fab.tsx +56 -9
- package/src/atoms/Gradient.tsx +92 -41
- package/src/atoms/IconButton.tsx +27 -4
- package/src/atoms/Image.tsx +74 -28
- package/src/atoms/Input.tsx +129 -19
- package/src/atoms/KeyValueRow.tsx +72 -28
- package/src/atoms/PressableScale.tsx +31 -7
- package/src/atoms/ShinyText.tsx +31 -31
- package/src/atoms/Skeleton.tsx +37 -17
- package/src/atoms/Spinner.tsx +87 -24
- package/src/atoms/Text.tsx +66 -6
- package/src/atoms/Transition.tsx +40 -44
- package/src/atoms/index.ts +3 -3
- package/src/atoms/inputValidation.ts +59 -0
- package/src/icons/Icon.tsx +4 -4
- package/src/icons/defaultIcons.tsx +445 -22
- package/src/icons/index.ts +2 -2
- package/src/icons/types.ts +26 -4
- package/src/molecules/AvatarHeader.tsx +88 -34
- package/src/molecules/FormActions.tsx +36 -6
- package/src/molecules/InfoRow.tsx +39 -12
- package/src/molecules/OptionCard.tsx +55 -20
- package/src/molecules/SegmentedControl.tsx +135 -15
- package/src/molecules/Stepper.tsx +73 -19
- package/src/molecules/Steps.tsx +121 -39
- package/src/molecules/SymmetricGrid.tsx +28 -12
- package/src/organisms/Alert.tsx +97 -26
- package/src/organisms/AlertProvider.tsx +13 -13
- package/src/organisms/BottomSheet.tsx +115 -43
- package/src/organisms/Chart.tsx +223 -165
- package/src/organisms/DateField.tsx +40 -15
- package/src/organisms/DatePicker.tsx +53 -32
- package/src/organisms/List.tsx +64 -15
- package/src/organisms/Modal.tsx +122 -63
- package/src/organisms/NavigationBar.tsx +73 -23
- package/src/organisms/OptionWheel.tsx +70 -66
- package/src/organisms/ReorderableList.tsx +49 -27
- package/src/organisms/Screen.tsx +79 -42
- package/src/organisms/SearchList.tsx +84 -20
- package/src/organisms/Select.tsx +63 -29
- package/src/organisms/Slides.tsx +63 -44
- package/src/organisms/ThemeToggle.tsx +15 -6
- package/src/organisms/Timeline.tsx +79 -62
- package/src/organisms/Toast.tsx +50 -15
- package/src/organisms/ToastProvider.tsx +17 -13
- package/src/organisms/Wizard.tsx +58 -21
- package/src/organisms/chart/frame.tsx +35 -35
- package/src/organisms/chart/marks.tsx +53 -53
- package/src/organisms/chart/math.ts +93 -94
- package/src/organisms/chart/palette.ts +28 -28
- package/src/organisms/imperativeBridge.ts +5 -5
- package/src/organisms/useSlides.ts +66 -31
- package/src/safe-area/SafeAreaUIProvider.tsx +9 -70
- package/src/safe-area/index.ts +1 -0
- package/src/theme/KeyboardAvoidance.tsx +216 -0
- package/src/theme/NativeOverlay.tsx +269 -0
- package/src/theme/UIProvider.tsx +109 -46
- package/src/theme/colors.ts +21 -21
- package/src/theme/createStyles.ts +23 -19
- package/src/theme/createTheme.ts +6 -6
- package/src/theme/index.ts +1 -1
- package/src/theme/insets.ts +1 -1
- package/src/theme/labels.ts +85 -2
- package/src/theme/palettes.ts +33 -25
- package/src/theme/tokens.ts +27 -13
- package/src/theme/types.ts +7 -7
- package/src/theme/useKeyboardField.ts +33 -0
- package/src/theme/useReduceMotion.ts +27 -0
package/src/atoms/Button.tsx
CHANGED
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
Animated,
|
|
5
5
|
Pressable,
|
|
6
6
|
Text,
|
|
7
|
+
View,
|
|
8
|
+
type Insets,
|
|
7
9
|
type GestureResponderEvent,
|
|
8
10
|
type StyleProp,
|
|
9
11
|
type TextStyle,
|
|
@@ -12,6 +14,7 @@ import {
|
|
|
12
14
|
import { createStyles } from '../theme/createStyles';
|
|
13
15
|
import { useAllowFontScaling, useColors, useTheme } from '../theme/UIProvider';
|
|
14
16
|
import { Icon } from '../icons/Icon';
|
|
17
|
+
import { useReduceMotion } from './Transition';
|
|
15
18
|
import type { IconName } from '../icons/types';
|
|
16
19
|
|
|
17
20
|
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
|
|
@@ -20,20 +23,36 @@ export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'lin
|
|
|
20
23
|
export type ButtonSize = 'sm' | 'md' | 'lg';
|
|
21
24
|
|
|
22
25
|
export interface ButtonProps {
|
|
26
|
+
/** Visible label. Also the accessible name unless `accessibilityLabel` is set. */
|
|
23
27
|
title: string;
|
|
28
|
+
/** Called on press. Not called while `disabled` or `loading`. */
|
|
24
29
|
onPress: (e: GestureResponderEvent) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Semantic style: `primary` is the filled focal action; the others step the visual weight down.
|
|
32
|
+
* @default 'primary'
|
|
33
|
+
*/
|
|
25
34
|
variant?: ButtonVariant;
|
|
35
|
+
/** Density: padding and font size. `sm` gets extra touch area through `hitSlop`. @default 'md' */
|
|
26
36
|
size?: ButtonSize;
|
|
37
|
+
/** Shows a spinner over the hidden label (the width doesn't change) and blocks presses. @default false */
|
|
27
38
|
loading?: boolean;
|
|
39
|
+
/** Paints the disabled colors and ignores presses. @default false */
|
|
28
40
|
disabled?: boolean;
|
|
29
41
|
style?: StyleProp<ViewStyle>;
|
|
42
|
+
/** Extra style for the label text. */
|
|
30
43
|
textStyle?: StyleProp<TextStyle>;
|
|
44
|
+
/** Custom node to the left of the label. Takes precedence over `leftIconName`. */
|
|
31
45
|
leftIcon?: React.ReactNode;
|
|
46
|
+
/** Custom node to the right of the label. Takes precedence over `rightIconName`. */
|
|
32
47
|
rightIcon?: React.ReactNode;
|
|
48
|
+
/** Icon from the library's set to the left of the label, sized to match `size`. */
|
|
33
49
|
leftIconName?: IconName;
|
|
50
|
+
/** Icon from the library's set to the right of the label, sized to match `size`. */
|
|
34
51
|
rightIconName?: IconName;
|
|
52
|
+
/** Color of `leftIconName`/`rightIconName`. Defaults to the label color of the variant. */
|
|
35
53
|
iconColor?: string;
|
|
36
54
|
testID?: string;
|
|
55
|
+
/** What screen readers announce. @default title */
|
|
37
56
|
accessibilityLabel?: string;
|
|
38
57
|
}
|
|
39
58
|
|
|
@@ -46,11 +65,11 @@ const useStyles = createStyles((theme) => ({
|
|
|
46
65
|
borderWidth: 0,
|
|
47
66
|
},
|
|
48
67
|
sm: { paddingVertical: theme.tokens.spacing.sm, paddingHorizontal: theme.tokens.spacing.md },
|
|
49
|
-
md: { paddingVertical: theme.tokens.spacing.lg
|
|
50
|
-
lg: { paddingVertical: theme.tokens.spacing.
|
|
68
|
+
md: { paddingVertical: theme.tokens.spacing.lg, paddingHorizontal: theme.tokens.spacing.xl },
|
|
69
|
+
lg: { paddingVertical: theme.tokens.spacing.xl, paddingHorizontal: theme.tokens.spacing.xxl },
|
|
51
70
|
link: { paddingVertical: theme.tokens.spacing.xs, paddingHorizontal: 0, justifyContent: 'flex-start' },
|
|
52
71
|
outline: { borderWidth: 1 },
|
|
53
|
-
filledShadow:
|
|
72
|
+
filledShadow: theme.tokens.shadow.md,
|
|
54
73
|
text: { fontWeight: theme.tokens.fontWeight.semibold, textAlign: 'center' },
|
|
55
74
|
textSm: { fontSize: theme.tokens.fontSize.sm },
|
|
56
75
|
textMd: { fontSize: theme.tokens.fontSize.lg },
|
|
@@ -58,15 +77,37 @@ const useStyles = createStyles((theme) => ({
|
|
|
58
77
|
underline: { textDecorationLine: 'underline' },
|
|
59
78
|
iconLeft: { marginRight: theme.tokens.spacing.sm },
|
|
60
79
|
iconRight: { marginLeft: theme.tokens.spacing.sm },
|
|
80
|
+
// The label keeps taking its space (invisible) while loading: the button
|
|
81
|
+
// doesn't change width and the spinner is centered on top.
|
|
82
|
+
hidden: { opacity: 0 },
|
|
83
|
+
spinner: { position: 'absolute', top: 0, bottom: 0, left: 0, right: 0, alignItems: 'center', justifyContent: 'center' },
|
|
61
84
|
}));
|
|
62
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Extra touch area for the sizes that fall below 44pt in height
|
|
88
|
+
* (Fitts): `sm` measures ~30pt and `link` ~27pt. hitSlop enlarges the area
|
|
89
|
+
* that receives the touch without changing how it looks.
|
|
90
|
+
*/
|
|
91
|
+
function useHitSlop(size: ButtonSize, variant: ButtonVariant): Insets | undefined {
|
|
92
|
+
const theme = useTheme();
|
|
93
|
+
if (variant === 'link') {
|
|
94
|
+
const v = theme.tokens.spacing.md;
|
|
95
|
+
return { top: v, bottom: v, left: theme.tokens.spacing.sm, right: theme.tokens.spacing.sm };
|
|
96
|
+
}
|
|
97
|
+
if (size === 'sm') {
|
|
98
|
+
const v = theme.tokens.spacing.sm;
|
|
99
|
+
return { top: v, bottom: v };
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
63
104
|
function resolveColors(variant: ButtonVariant, disabled: boolean, colors: ReturnType<typeof useColors>) {
|
|
64
105
|
if (disabled) {
|
|
65
106
|
return { background: colors.inputBackground, text: colors.textLight, border: 'transparent' };
|
|
66
107
|
}
|
|
67
108
|
switch (variant) {
|
|
68
|
-
//
|
|
69
|
-
//
|
|
109
|
+
// The unfilled variants paint text over the screen background: they
|
|
110
|
+
// use the `*Text` role. The filled ones use `on*` over the accent.
|
|
70
111
|
case 'outline':
|
|
71
112
|
return { background: 'transparent', text: colors.primaryText, border: colors.primary };
|
|
72
113
|
case 'ghost':
|
|
@@ -85,9 +126,24 @@ function resolveColors(variant: ButtonVariant, disabled: boolean, colors: Return
|
|
|
85
126
|
|
|
86
127
|
/**
|
|
87
128
|
* Button
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
129
|
+
* The library's only button component. `variant` sets the semantic style,
|
|
130
|
+
* `size` the density. The "pressed" feedback animates only `transform`
|
|
131
|
+
* (Animated.spring, useNativeDriver) — never opacity or layout — and is
|
|
132
|
+
* skipped when Reduce Motion is on.
|
|
133
|
+
*
|
|
134
|
+
* Gestalt:
|
|
135
|
+
* - Focal point (Von Restorff): `primary` is the only one filled with the
|
|
136
|
+
* accent and a shadow; there should be one per screen or group. The other
|
|
137
|
+
* variants step the visual weight down (secondary → outline → ghost → link).
|
|
138
|
+
* - Similarity: all variants share shape, radius and typography, so a row of
|
|
139
|
+
* buttons reads as a single group of actions; only what conveys the
|
|
140
|
+
* hierarchy changes (fill, border, color).
|
|
141
|
+
* - Proximity: icon and label sit `spacing.sm` apart, much less than the
|
|
142
|
+
* padding, so they read as a single label.
|
|
143
|
+
*
|
|
144
|
+
* Fitts: `sm` and `link` are less than 44pt tall and make up for it with `hitSlop`.
|
|
145
|
+
* While `loading`, the label is invisible but keeps its space: the button
|
|
146
|
+
* doesn't change width (no layout jumps).
|
|
91
147
|
*/
|
|
92
148
|
export const Button = memo(
|
|
93
149
|
({
|
|
@@ -112,6 +168,8 @@ export const Button = memo(
|
|
|
112
168
|
const theme = useTheme();
|
|
113
169
|
const allowFontScaling = useAllowFontScaling();
|
|
114
170
|
const scale = useRef(new Animated.Value(1)).current;
|
|
171
|
+
const reduceMotion = useReduceMotion();
|
|
172
|
+
const hitSlop = useHitSlop(size, variant);
|
|
115
173
|
const isDisabled = disabled || loading;
|
|
116
174
|
const isFilled = variant === 'primary' || variant === 'secondary' || variant === 'destructive';
|
|
117
175
|
|
|
@@ -119,6 +177,7 @@ export const Button = memo(
|
|
|
119
177
|
const effectiveIconColor = iconColor ?? resolved.text;
|
|
120
178
|
|
|
121
179
|
const animateTo = (value: number) => {
|
|
180
|
+
if (reduceMotion) return;
|
|
122
181
|
Animated.spring(scale, { toValue: value, useNativeDriver: true, speed: 50, bounciness: 6 }).start();
|
|
123
182
|
};
|
|
124
183
|
|
|
@@ -129,7 +188,10 @@ export const Button = memo(
|
|
|
129
188
|
variant === 'outline' && [styles.outline, { borderColor: resolved.border }],
|
|
130
189
|
{ backgroundColor: resolved.background },
|
|
131
190
|
isFilled && !disabled && styles.filledShadow,
|
|
132
|
-
|
|
191
|
+
// Disabled is already marked by its colors (resolveColors); lowering the
|
|
192
|
+
// opacity on top of that left it almost invisible (figure and ground).
|
|
193
|
+
// Only `loading` dims it, to signal that the button is busy.
|
|
194
|
+
{ opacity: loading && !disabled ? 0.7 : 1 },
|
|
133
195
|
style,
|
|
134
196
|
];
|
|
135
197
|
|
|
@@ -144,11 +206,11 @@ export const Button = memo(
|
|
|
144
206
|
const iconSize = size === 'sm' ? 16 : size === 'lg' ? 22 : 20;
|
|
145
207
|
|
|
146
208
|
return (
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
//
|
|
209
|
+
// The Pressable IS the animated container, not a wrapper around one.
|
|
210
|
+
// With an inner Animated.View, a layout `style` (flex, width, margin)
|
|
211
|
+
// landed on the child while the Pressable — which is what takes up
|
|
212
|
+
// space in the parent's layout — was left without it: the width
|
|
213
|
+
// collapsed and the label disappeared (visible in the Alert's row of buttons).
|
|
152
214
|
<AnimatedPressable
|
|
153
215
|
onPress={onPress}
|
|
154
216
|
onPressIn={() => {
|
|
@@ -158,28 +220,38 @@ export const Button = memo(
|
|
|
158
220
|
if (!isDisabled) animateTo(1);
|
|
159
221
|
}}
|
|
160
222
|
disabled={isDisabled}
|
|
223
|
+
hitSlop={hitSlop}
|
|
161
224
|
testID={testID}
|
|
162
225
|
accessibilityRole="button"
|
|
163
226
|
accessibilityLabel={accessibilityLabel ?? title}
|
|
164
227
|
accessibilityState={{ disabled: isDisabled, busy: loading }}
|
|
165
228
|
style={[containerStyle, { transform: [{ scale }] }]}
|
|
166
229
|
>
|
|
167
|
-
{
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
{
|
|
172
|
-
{
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
230
|
+
{leftIcon ? <View style={[styles.iconLeft, loading && styles.hidden]}>{leftIcon}</View> : null}
|
|
231
|
+
{!leftIcon && leftIconName && (
|
|
232
|
+
<Icon
|
|
233
|
+
name={leftIconName}
|
|
234
|
+
size={iconSize}
|
|
235
|
+
color={effectiveIconColor}
|
|
236
|
+
style={[styles.iconLeft, loading && styles.hidden]}
|
|
237
|
+
/>
|
|
238
|
+
)}
|
|
239
|
+
<Text allowFontScaling={allowFontScaling} style={[labelStyle, loading && styles.hidden]}>
|
|
240
|
+
{title}
|
|
241
|
+
</Text>
|
|
242
|
+
{rightIcon ? <View style={[styles.iconRight, loading && styles.hidden]}>{rightIcon}</View> : null}
|
|
243
|
+
{!rightIcon && rightIconName && (
|
|
244
|
+
<Icon
|
|
245
|
+
name={rightIconName}
|
|
246
|
+
size={iconSize}
|
|
247
|
+
color={effectiveIconColor}
|
|
248
|
+
style={[styles.iconRight, loading && styles.hidden]}
|
|
249
|
+
/>
|
|
250
|
+
)}
|
|
251
|
+
{loading && (
|
|
252
|
+
<View style={styles.spinner} pointerEvents="none">
|
|
253
|
+
<ActivityIndicator size="small" color={resolved.text} />
|
|
254
|
+
</View>
|
|
183
255
|
)}
|
|
184
256
|
</AnimatedPressable>
|
|
185
257
|
);
|
package/src/atoms/Card.tsx
CHANGED
|
@@ -1,21 +1,41 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
|
-
import { View, type ViewProps, type ViewStyle } from 'react-native';
|
|
2
|
+
import { View, type StyleProp, type ViewProps, type ViewStyle } from 'react-native';
|
|
3
3
|
import { createStyles } from '../theme/createStyles';
|
|
4
4
|
|
|
5
5
|
export interface CardProps extends ViewProps {
|
|
6
|
+
/** Content of the card, inside its padding, background and border. */
|
|
6
7
|
children: React.ReactNode;
|
|
7
|
-
style?: ViewStyle
|
|
8
|
+
style?: StyleProp<ViewStyle>;
|
|
8
9
|
}
|
|
9
10
|
|
|
11
|
+
const CARD_BORDER_DARK = 1;
|
|
12
|
+
|
|
10
13
|
const useStyles = createStyles((theme) => ({
|
|
11
14
|
card: {
|
|
12
|
-
|
|
15
|
+
// surfaceRaised: lighter than surface in dark, so a card on a sheet or
|
|
16
|
+
// on another card still reads as a separate tile (figure and ground).
|
|
17
|
+
backgroundColor: theme.colors.surfaceRaised,
|
|
13
18
|
borderRadius: theme.tokens.radius.xl,
|
|
14
19
|
padding: theme.tokens.spacing.lg,
|
|
15
20
|
...theme.tokens.shadow.sm,
|
|
21
|
+
// In dark the shadow isn't visible and surface barely stands out from the
|
|
22
|
+
// background (or not at all, on another surface): a 1pt border restores
|
|
23
|
+
// the outline (figure and ground). A hairline was invisible.
|
|
24
|
+
...(theme.scheme === 'dark' && { borderWidth: CARD_BORDER_DARK, borderColor: theme.colors.border }),
|
|
16
25
|
},
|
|
17
26
|
}));
|
|
18
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Card
|
|
30
|
+
* Surface container: groups related content.
|
|
31
|
+
*
|
|
32
|
+
* Gestalt, common region: everything inside the same background and border
|
|
33
|
+
* reads as a group, even when other elements are nearby. Figure and ground:
|
|
34
|
+
* in light the shadow sets it apart; in dark (where the shadow isn't visible)
|
|
35
|
+
* a thin border does. The inner padding (`spacing.lg`) must be larger than the
|
|
36
|
+
* spacing between the elements inside, so the content reads as one block.
|
|
37
|
+
*/
|
|
38
|
+
|
|
19
39
|
export const Card = memo(({ children, style, ...props }: CardProps) => {
|
|
20
40
|
const styles = useStyles();
|
|
21
41
|
return (
|
package/src/atoms/Checkbox.tsx
CHANGED
|
@@ -1,20 +1,34 @@
|
|
|
1
1
|
import React, { memo, useEffect, useRef } from 'react';
|
|
2
2
|
import { Animated, Text, TouchableOpacity } from 'react-native';
|
|
3
3
|
import { createStyles } from '../theme/createStyles';
|
|
4
|
-
import { useAllowFontScaling, useColors } from '../theme/UIProvider';
|
|
4
|
+
import { useAllowFontScaling, useColors, useTheme } from '../theme/UIProvider';
|
|
5
5
|
import { Icon } from '../icons/Icon';
|
|
6
|
+
import { onColor } from '../icons/defaultIcons';
|
|
7
|
+
import { useReduceMotion } from './Transition';
|
|
6
8
|
|
|
7
9
|
export interface CheckboxProps {
|
|
10
|
+
/** Whether the box is checked (controlled). */
|
|
8
11
|
value: boolean;
|
|
12
|
+
/** Called with the new value when the row is pressed. */
|
|
9
13
|
onValueChange: (value: boolean) => void;
|
|
14
|
+
/** Text next to the box; the whole row is touchable. Also the accessible name. */
|
|
10
15
|
label?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Fill and border color when checked. The check turns black or white for contrast. @default
|
|
18
|
+
* colors.primary
|
|
19
|
+
*/
|
|
11
20
|
color?: string;
|
|
21
|
+
/** Dims the box and the label and ignores presses. */
|
|
12
22
|
disabled?: boolean;
|
|
23
|
+
/** Effectively required without `label`: it is all a screen reader announces. */
|
|
24
|
+
accessibilityLabel?: string;
|
|
13
25
|
testID?: string;
|
|
14
26
|
}
|
|
15
27
|
|
|
16
28
|
const useStyles = createStyles((theme) => ({
|
|
17
|
-
|
|
29
|
+
// 44pt tall: the whole row is the touch area (Fitts). Replaces the
|
|
30
|
+
// marginBottom that separated stacked checkboxes; now the row provides the room.
|
|
31
|
+
container: { flexDirection: 'row', alignItems: 'center', minHeight: 44 },
|
|
18
32
|
box: {
|
|
19
33
|
width: 24,
|
|
20
34
|
height: 24,
|
|
@@ -22,31 +36,54 @@ const useStyles = createStyles((theme) => ({
|
|
|
22
36
|
borderWidth: 2,
|
|
23
37
|
justifyContent: 'center',
|
|
24
38
|
alignItems: 'center',
|
|
25
|
-
marginRight: theme.tokens.spacing.
|
|
39
|
+
marginRight: theme.tokens.spacing.md,
|
|
26
40
|
},
|
|
27
41
|
label: { fontSize: theme.tokens.fontSize.md, color: theme.colors.text },
|
|
42
|
+
labelDisabled: { color: theme.colors.textLight },
|
|
28
43
|
}));
|
|
29
44
|
|
|
30
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Checkbox
|
|
47
|
+
* Box + optional label; the whole row is touchable.
|
|
48
|
+
*
|
|
49
|
+
* Gestalt:
|
|
50
|
+
* - Proximity: the box and its label sit `spacing.md` apart, less than the
|
|
51
|
+
* spacing between rows, so each label reads with its box.
|
|
52
|
+
* - Common region: the whole row is the touch area, not just the box, and it
|
|
53
|
+
* is at least 44pt tall (Fitts).
|
|
54
|
+
* - Figure and ground: when checked, the box fills with the accent and the
|
|
55
|
+
* check turns black or white depending on that fill (also with a custom `color`).
|
|
56
|
+
*
|
|
57
|
+
* `disabled` dims the box and the label (not just the box). The check
|
|
58
|
+
* animation is skipped with Reduce Motion.
|
|
59
|
+
*/
|
|
60
|
+
export const Checkbox = memo(({ value, onValueChange, label, color, disabled, accessibilityLabel, testID }: CheckboxProps) => {
|
|
31
61
|
const colors = useColors();
|
|
32
62
|
const styles = useStyles();
|
|
33
63
|
const allowFontScaling = useAllowFontScaling();
|
|
34
64
|
const activeColor = color || colors.primary;
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
const checkColor = color ?
|
|
65
|
+
// The check sits on top of the fill: with a custom `color`, black or white is
|
|
66
|
+
// picked by luminance (a fixed white disappeared over light colors).
|
|
67
|
+
const checkColor = color ? onColor(color) : colors.onPrimary;
|
|
68
|
+
const theme = useTheme();
|
|
69
|
+
const reduceMotion = useReduceMotion();
|
|
38
70
|
const progress = useRef(new Animated.Value(value ? 1 : 0)).current;
|
|
39
71
|
const checkScale = useRef(new Animated.Value(value ? 1 : 0)).current;
|
|
40
72
|
|
|
41
73
|
useEffect(() => {
|
|
42
|
-
|
|
74
|
+
if (reduceMotion) {
|
|
75
|
+
progress.setValue(value ? 1 : 0);
|
|
76
|
+
checkScale.setValue(value ? 1 : 0);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
Animated.timing(progress, { toValue: value ? 1 : 0, duration: theme.tokens.duration.fast, useNativeDriver: false }).start();
|
|
43
80
|
Animated.spring(checkScale, {
|
|
44
81
|
toValue: value ? 1 : 0,
|
|
45
82
|
useNativeDriver: true,
|
|
46
83
|
speed: 40,
|
|
47
84
|
bounciness: 10,
|
|
48
85
|
}).start();
|
|
49
|
-
}, [value]);
|
|
86
|
+
}, [value, reduceMotion]);
|
|
50
87
|
|
|
51
88
|
const backgroundColor = progress.interpolate({ inputRange: [0, 1], outputRange: [colors.surface, activeColor] });
|
|
52
89
|
const borderColor = progress.interpolate({ inputRange: [0, 1], outputRange: [colors.border, activeColor] });
|
|
@@ -59,7 +96,7 @@ export const Checkbox = memo(({ value, onValueChange, label, color, disabled, te
|
|
|
59
96
|
onPress={() => onValueChange(!value)}
|
|
60
97
|
accessibilityRole="checkbox"
|
|
61
98
|
accessibilityState={{ checked: value, disabled: !!disabled }}
|
|
62
|
-
accessibilityLabel={label}
|
|
99
|
+
accessibilityLabel={accessibilityLabel ?? label}
|
|
63
100
|
testID={testID}
|
|
64
101
|
>
|
|
65
102
|
<Animated.View style={[styles.box, { backgroundColor, borderColor, opacity: disabled ? 0.5 : 1 }]}>
|
|
@@ -67,8 +104,8 @@ export const Checkbox = memo(({ value, onValueChange, label, color, disabled, te
|
|
|
67
104
|
<Icon name="check" size={16} color={checkColor} />
|
|
68
105
|
</Animated.View>
|
|
69
106
|
</Animated.View>
|
|
70
|
-
{label && (
|
|
71
|
-
<Text allowFontScaling={allowFontScaling} style={styles.label}>
|
|
107
|
+
{!!label && (
|
|
108
|
+
<Text allowFontScaling={allowFontScaling} style={[styles.label, disabled && styles.labelDisabled]}>
|
|
72
109
|
{label}
|
|
73
110
|
</Text>
|
|
74
111
|
)}
|
package/src/atoms/Divider.tsx
CHANGED
|
@@ -1,14 +1,44 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
2
|
import { View, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
-
import {
|
|
3
|
+
import { useTheme } from '../theme/UIProvider';
|
|
4
|
+
import type { Tokens } from '../theme/tokens';
|
|
4
5
|
|
|
5
6
|
export interface DividerProps {
|
|
7
|
+
/** `vertical` separates items in a row and stretches to the row's height. @default 'horizontal' */
|
|
8
|
+
orientation?: 'horizontal' | 'vertical';
|
|
9
|
+
/** Space on each side of the line, from the spacing scale. Unset, the line adds no margin. */
|
|
10
|
+
spacing?: keyof Tokens['spacing'];
|
|
6
11
|
style?: StyleProp<ViewStyle>;
|
|
7
12
|
testID?: string;
|
|
8
13
|
}
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Divider
|
|
17
|
+
* 1pt line in `colors.border`.
|
|
18
|
+
*
|
|
19
|
+
* Gestalt: separates groups when proximity alone isn't enough (dense lists,
|
|
20
|
+
* rows spanning the whole screen). If spacing already separates the groups,
|
|
21
|
+
* prefer spacing: one line too many fragments what should read together.
|
|
22
|
+
* `spacing` takes its room from the token scale so the separation is the
|
|
23
|
+
* same across the whole app, instead of a different margin on each screen.
|
|
24
|
+
*
|
|
25
|
+
* It is decorative: it doesn't enter the accessibility tree.
|
|
26
|
+
*/
|
|
27
|
+
export const Divider = memo(({ orientation = 'horizontal', spacing, style, testID }: DividerProps) => {
|
|
28
|
+
const theme = useTheme();
|
|
29
|
+
const gap = spacing ? theme.tokens.spacing[spacing] : 0;
|
|
30
|
+
const line: ViewStyle =
|
|
31
|
+
orientation === 'vertical'
|
|
32
|
+
? { width: 1, alignSelf: 'stretch', marginHorizontal: gap }
|
|
33
|
+
: { height: 1, width: '100%', marginVertical: gap };
|
|
34
|
+
return (
|
|
35
|
+
<View
|
|
36
|
+
testID={testID}
|
|
37
|
+
accessible={false}
|
|
38
|
+
importantForAccessibility="no-hide-descendants"
|
|
39
|
+
accessibilityElementsHidden
|
|
40
|
+
style={[line, { backgroundColor: theme.colors.border }, style]}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
13
43
|
});
|
|
14
44
|
Divider.displayName = 'Divider';
|
package/src/atoms/EmptyState.tsx
CHANGED
|
@@ -1,43 +1,80 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
|
-
import { Text, View, type ViewStyle } from 'react-native';
|
|
2
|
+
import { Text, View, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
3
|
import { createStyles } from '../theme/createStyles';
|
|
4
4
|
import { useAllowFontScaling, useColors, useLabels } from '../theme/UIProvider';
|
|
5
5
|
import { Icon } from '../icons/Icon';
|
|
6
6
|
import type { IconName } from '../icons/types';
|
|
7
|
+
import { Button, type ButtonVariant } from './Button';
|
|
8
|
+
|
|
9
|
+
export interface EmptyStateAction {
|
|
10
|
+
label: string;
|
|
11
|
+
onPress: () => void;
|
|
12
|
+
/** @default 'primary' */
|
|
13
|
+
variant?: ButtonVariant;
|
|
14
|
+
}
|
|
7
15
|
|
|
8
16
|
export interface EmptyStateProps {
|
|
17
|
+
/** Main line. @default labels.noResultsTitle */
|
|
9
18
|
title?: string;
|
|
19
|
+
/** Supporting line under the title. @default labels.noResultsDescription */
|
|
10
20
|
description?: string;
|
|
21
|
+
/** Built-in or custom icon name. Ignored when `icon` is passed. @default 'search' */
|
|
11
22
|
iconName?: IconName;
|
|
23
|
+
/** Any node in place of the icon (an Image, an illustration). */
|
|
12
24
|
icon?: React.ReactNode;
|
|
13
|
-
|
|
25
|
+
/** The next step, shown as a button under the text (e.g. "Add client"). */
|
|
26
|
+
action?: EmptyStateAction;
|
|
27
|
+
style?: StyleProp<ViewStyle>;
|
|
28
|
+
testID?: string;
|
|
14
29
|
}
|
|
15
30
|
|
|
31
|
+
/** Icon size: the block's focal point without competing with the title. */
|
|
32
|
+
const ICON_SIZE = 48;
|
|
33
|
+
/** Minimum height: the block doesn't get squashed inside a short empty list. */
|
|
34
|
+
const MIN_HEIGHT = 200;
|
|
35
|
+
|
|
16
36
|
const useStyles = createStyles((theme) => ({
|
|
17
37
|
container: {
|
|
18
38
|
flex: 1,
|
|
19
39
|
justifyContent: 'center',
|
|
20
40
|
alignItems: 'center',
|
|
21
|
-
padding: theme.tokens.spacing.
|
|
22
|
-
minHeight:
|
|
41
|
+
padding: theme.tokens.spacing.xl,
|
|
42
|
+
minHeight: MIN_HEIGHT,
|
|
23
43
|
},
|
|
24
44
|
title: {
|
|
25
45
|
fontSize: theme.tokens.fontSize.lg,
|
|
26
46
|
fontWeight: theme.tokens.fontWeight.semibold,
|
|
27
|
-
|
|
28
|
-
|
|
47
|
+
lineHeight: theme.tokens.lineHeight.lg,
|
|
48
|
+
color: theme.colors.text,
|
|
49
|
+
marginTop: theme.tokens.spacing.md,
|
|
29
50
|
textAlign: 'center',
|
|
30
51
|
},
|
|
31
52
|
description: {
|
|
32
53
|
fontSize: theme.tokens.fontSize.md,
|
|
54
|
+
lineHeight: theme.tokens.lineHeight.md,
|
|
33
55
|
color: theme.colors.textLight,
|
|
34
|
-
marginTop: theme.tokens.spacing.xs
|
|
56
|
+
marginTop: theme.tokens.spacing.xs,
|
|
35
57
|
textAlign: 'center',
|
|
36
58
|
},
|
|
59
|
+
message: { alignItems: 'center' },
|
|
60
|
+
action: { marginTop: theme.tokens.spacing.lg },
|
|
37
61
|
}));
|
|
38
62
|
|
|
63
|
+
/**
|
|
64
|
+
* EmptyState
|
|
65
|
+
* Centered icon + title + description for a list or screen with no data.
|
|
66
|
+
*
|
|
67
|
+
* Gestalt, proximity: title and description sit close together (`spacing.xs`)
|
|
68
|
+
* and the icon one step further (`spacing.md`), so they read as a message
|
|
69
|
+
* with its image and not as three loose pieces. Similarity: the title in
|
|
70
|
+
* `text` and the description in `textLight` mark the hierarchy. The action,
|
|
71
|
+
* if any, is set further apart (`spacing.lg`): it is the next step, not part
|
|
72
|
+
* of the message.
|
|
73
|
+
* The message is a single accessibility node (title and description together;
|
|
74
|
+
* the icon is decorative) and the button a separate, focusable one.
|
|
75
|
+
*/
|
|
39
76
|
export const EmptyState = memo(
|
|
40
|
-
({ title, description, iconName = 'search', icon, style }: EmptyStateProps) => {
|
|
77
|
+
({ title, description, iconName = 'search', icon, action, style, testID }: EmptyStateProps) => {
|
|
41
78
|
const colors = useColors();
|
|
42
79
|
const styles = useStyles();
|
|
43
80
|
const labels = useLabels();
|
|
@@ -45,14 +82,24 @@ export const EmptyState = memo(
|
|
|
45
82
|
const resolvedTitle = title ?? labels.noResultsTitle;
|
|
46
83
|
const resolvedDescription = description ?? labels.noResultsDescription;
|
|
47
84
|
return (
|
|
48
|
-
<View style={[styles.container, style]}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{
|
|
55
|
-
|
|
85
|
+
<View style={[styles.container, style]} testID={testID}>
|
|
86
|
+
<View style={styles.message} accessible accessibilityRole="text">
|
|
87
|
+
{icon ?? <Icon name={iconName} size={ICON_SIZE} color={colors.textLight} />}
|
|
88
|
+
<Text allowFontScaling={allowFontScaling} style={styles.title}>
|
|
89
|
+
{resolvedTitle}
|
|
90
|
+
</Text>
|
|
91
|
+
<Text allowFontScaling={allowFontScaling} style={styles.description}>
|
|
92
|
+
{resolvedDescription}
|
|
93
|
+
</Text>
|
|
94
|
+
</View>
|
|
95
|
+
{action && (
|
|
96
|
+
<Button
|
|
97
|
+
title={action.label}
|
|
98
|
+
onPress={action.onPress}
|
|
99
|
+
variant={action.variant ?? 'primary'}
|
|
100
|
+
style={styles.action}
|
|
101
|
+
/>
|
|
102
|
+
)}
|
|
56
103
|
</View>
|
|
57
104
|
);
|
|
58
105
|
}
|