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/Skeleton.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { memo, useEffect, useRef } from 'react';
|
|
1
|
+
import React, { memo, useEffect, useRef, type ComponentProps } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Animated,
|
|
4
4
|
Easing,
|
|
@@ -9,15 +9,19 @@ import {
|
|
|
9
9
|
} from 'react-native';
|
|
10
10
|
import { createStyles } from '../theme/createStyles';
|
|
11
11
|
import { useTheme } from '../theme/UIProvider';
|
|
12
|
+
import { useReduceMotion } from './Transition';
|
|
13
|
+
|
|
14
|
+
/** Half a pulse cycle (opaque → faint). A loading loop, not a transition: it doesn't come from `duration`. */
|
|
15
|
+
const PULSE_HALF_MS = 700;
|
|
12
16
|
|
|
13
17
|
export type SkeletonVariant = 'rect' | 'text' | 'circle';
|
|
14
18
|
|
|
15
19
|
export interface SkeletonProps {
|
|
16
|
-
/** @default '100%' ('circle' also uses this as the diameter) */
|
|
20
|
+
/** Width of the placeholder. @default '100%' ('circle' also uses this as the diameter) */
|
|
17
21
|
width?: DimensionValue;
|
|
18
|
-
/** @default 16 ('text' uses
|
|
22
|
+
/** Height of the placeholder. @default 16 ('text' uses Body's line height; 'circle', the width) */
|
|
19
23
|
height?: DimensionValue;
|
|
20
|
-
/** @default 'rect' */
|
|
24
|
+
/** Shape: a block, a line of text or a circle. @default 'rect' */
|
|
21
25
|
variant?: SkeletonVariant;
|
|
22
26
|
/** Override of the theme's radius. */
|
|
23
27
|
radius?: number;
|
|
@@ -25,7 +29,7 @@ export interface SkeletonProps {
|
|
|
25
29
|
lines?: number;
|
|
26
30
|
/** Width of the last line, so the paragraph doesn't end as a solid block. @default '60%' */
|
|
27
31
|
lastLineWidth?: DimensionValue;
|
|
28
|
-
/** @default true */
|
|
32
|
+
/** Pulses while waiting. Off when the system's Reduce Motion is on. @default true */
|
|
29
33
|
animated?: boolean;
|
|
30
34
|
style?: StyleProp<ViewStyle>;
|
|
31
35
|
testID?: string;
|
|
@@ -33,14 +37,24 @@ export interface SkeletonProps {
|
|
|
33
37
|
|
|
34
38
|
const useStyles = createStyles((theme) => ({
|
|
35
39
|
block: { backgroundColor: theme.colors.skeleton },
|
|
36
|
-
|
|
40
|
+
// Each line takes exactly `lineHeight.md` (Body's): a `fontSize.md` bar
|
|
41
|
+
// plus half the leading above and below. That way the fake paragraph
|
|
42
|
+
// measures the same as the real one and nothing jumps when the content arrives.
|
|
43
|
+
textLine: {
|
|
44
|
+
marginVertical: (theme.tokens.lineHeight.md - theme.tokens.fontSize.md) / 2,
|
|
45
|
+
},
|
|
37
46
|
}));
|
|
38
47
|
|
|
39
48
|
/**
|
|
40
49
|
* Skeleton
|
|
41
|
-
* Placeholder
|
|
42
|
-
*
|
|
43
|
-
*
|
|
50
|
+
* Placeholder that pulses while the real content arrives. It reserves the
|
|
51
|
+
* exact space of what it replaces, so the screen doesn't jump when the data
|
|
52
|
+
* shows up — which is precisely what a centered Spinner can't do.
|
|
53
|
+
*
|
|
54
|
+
* Gestalt, similarity: the silhouette repeats the shape and size of the
|
|
55
|
+
* content (a circle for avatars, Body-height lines for text), so the eye
|
|
56
|
+
* already groups the screen before the data arrives. Respects Reduce Motion:
|
|
57
|
+
* no pulse, a static block.
|
|
44
58
|
*/
|
|
45
59
|
export const Skeleton = memo(
|
|
46
60
|
({
|
|
@@ -56,39 +70,45 @@ export const Skeleton = memo(
|
|
|
56
70
|
}: SkeletonProps) => {
|
|
57
71
|
const theme = useTheme();
|
|
58
72
|
const styles = useStyles();
|
|
73
|
+
const reduceMotion = useReduceMotion();
|
|
74
|
+
const pulsing = animated && !reduceMotion;
|
|
59
75
|
const pulse = useRef(new Animated.Value(0)).current;
|
|
60
76
|
|
|
61
77
|
useEffect(() => {
|
|
62
|
-
if (!
|
|
78
|
+
if (!pulsing) return;
|
|
63
79
|
const loop = Animated.loop(
|
|
64
80
|
Animated.sequence([
|
|
65
81
|
Animated.timing(pulse, {
|
|
66
82
|
toValue: 1,
|
|
67
|
-
duration:
|
|
83
|
+
duration: PULSE_HALF_MS,
|
|
68
84
|
useNativeDriver: true,
|
|
69
85
|
easing: Easing.inOut(Easing.quad),
|
|
70
86
|
}),
|
|
71
87
|
Animated.timing(pulse, {
|
|
72
88
|
toValue: 0,
|
|
73
|
-
duration:
|
|
89
|
+
duration: PULSE_HALF_MS,
|
|
74
90
|
useNativeDriver: true,
|
|
75
91
|
easing: Easing.inOut(Easing.quad),
|
|
76
92
|
}),
|
|
77
93
|
])
|
|
78
94
|
);
|
|
79
95
|
loop.start();
|
|
80
|
-
return () =>
|
|
81
|
-
|
|
96
|
+
return () => {
|
|
97
|
+
loop.stop();
|
|
98
|
+
pulse.setValue(0);
|
|
99
|
+
};
|
|
100
|
+
}, [pulsing, pulse]);
|
|
82
101
|
|
|
83
102
|
const isCircle = variant === 'circle';
|
|
84
103
|
const isText = variant === 'text';
|
|
85
|
-
const opacity =
|
|
104
|
+
const opacity = pulsing ? pulse.interpolate({ inputRange: [0, 1], outputRange: [1, 0.4] }) : 1;
|
|
86
105
|
const resolvedHeight = isCircle ? width : isText ? theme.tokens.fontSize.md : height;
|
|
87
106
|
const resolvedRadius =
|
|
88
107
|
radius ?? (isCircle ? theme.tokens.radius.full : isText ? theme.tokens.radius.xs : theme.tokens.radius.sm);
|
|
89
108
|
|
|
90
|
-
const barStyle = (barWidth: DimensionValue):
|
|
109
|
+
const barStyle = (barWidth: DimensionValue): ComponentProps<typeof Animated.View>['style'] => [
|
|
91
110
|
styles.block,
|
|
111
|
+
isText && styles.textLine,
|
|
92
112
|
{ width: barWidth, height: resolvedHeight, borderRadius: resolvedRadius, opacity },
|
|
93
113
|
];
|
|
94
114
|
|
|
@@ -96,7 +116,7 @@ export const Skeleton = memo(
|
|
|
96
116
|
|
|
97
117
|
if (isText && lines > 1) {
|
|
98
118
|
return (
|
|
99
|
-
<View style={
|
|
119
|
+
<View style={style} testID={testID} {...a11y}>
|
|
100
120
|
{Array.from({ length: lines }, (_, i) => (
|
|
101
121
|
<Animated.View
|
|
102
122
|
key={i}
|
package/src/atoms/Spinner.tsx
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import React, { memo, useEffect, useRef } from 'react';
|
|
2
2
|
import { ActivityIndicator, Animated, Easing, Text, View } from 'react-native';
|
|
3
3
|
import { createStyles } from '../theme/createStyles';
|
|
4
|
-
import { useAllowFontScaling, useColors } from '../theme/UIProvider';
|
|
4
|
+
import { useAllowFontScaling, useColors, useLabels } from '../theme/UIProvider';
|
|
5
5
|
|
|
6
6
|
export type SpinnerVariant = 'native' | 'dots' | 'ring';
|
|
7
7
|
|
|
8
8
|
export interface SpinnerProps {
|
|
9
|
+
/** Indicator size; also scales the `dots` and `ring` variants. @default 'large' */
|
|
9
10
|
size?: 'small' | 'large';
|
|
11
|
+
/** Indicator color. @default colors.primary */
|
|
10
12
|
color?: string;
|
|
13
|
+
/** Message under the indicator. Also what screen readers announce. */
|
|
11
14
|
text?: string;
|
|
12
15
|
/** @default true. When false, doesn't take up flex:1 (useful inline, inside a button/row). */
|
|
13
16
|
fullscreen?: boolean;
|
|
@@ -19,16 +22,30 @@ export interface SpinnerProps {
|
|
|
19
22
|
variant?: SpinnerVariant;
|
|
20
23
|
/** Fully custom indicator. Takes precedence over `variant`. */
|
|
21
24
|
indicator?: React.ReactNode;
|
|
25
|
+
/**
|
|
26
|
+
* Shown above the indicator — typically the app logo on a splash or
|
|
27
|
+
* first-load screen (an `<Image>`, an `<Avatar>`, any node).
|
|
28
|
+
*/
|
|
29
|
+
logo?: React.ReactNode;
|
|
30
|
+
/** What screen readers announce. @default text ?? labels.loading */
|
|
31
|
+
accessibilityLabel?: string;
|
|
22
32
|
testID?: string;
|
|
23
33
|
}
|
|
24
34
|
|
|
35
|
+
// Rhythm of the looping indicators. They are not UI transitions (those use
|
|
36
|
+
// theme.tokens.duration): they are the pulse of a continuous animation.
|
|
37
|
+
const DOT_PULSE_MS = 320;
|
|
38
|
+
const DOT_STAGGER_MS = 140;
|
|
39
|
+
const RING_TURN_MS = 900;
|
|
40
|
+
|
|
25
41
|
const useStyles = createStyles((theme) => ({
|
|
26
42
|
container: { justifyContent: 'center', alignItems: 'center', padding: theme.tokens.spacing.xl },
|
|
27
43
|
text: { marginTop: theme.tokens.spacing.md, color: theme.colors.textLight, fontSize: theme.tokens.fontSize.md },
|
|
44
|
+
logo: { marginBottom: theme.tokens.spacing.xl },
|
|
28
45
|
dots: { flexDirection: 'row', gap: theme.tokens.spacing.sm },
|
|
29
46
|
}));
|
|
30
47
|
|
|
31
|
-
/**
|
|
48
|
+
/** Three dots that pulse in sequence. Animated + useNativeDriver: runs on the native thread. */
|
|
32
49
|
const DotsIndicator = memo(({ color, dotSize }: { color: string; dotSize: number }) => {
|
|
33
50
|
const dots = [useRef(new Animated.Value(0)).current, useRef(new Animated.Value(0)).current, useRef(new Animated.Value(0)).current];
|
|
34
51
|
|
|
@@ -36,16 +53,16 @@ const DotsIndicator = memo(({ color, dotSize }: { color: string; dotSize: number
|
|
|
36
53
|
const animations = dots.map((dot, i) =>
|
|
37
54
|
Animated.loop(
|
|
38
55
|
Animated.sequence([
|
|
39
|
-
Animated.delay(i *
|
|
40
|
-
Animated.timing(dot, { toValue: 1, duration:
|
|
41
|
-
Animated.timing(dot, { toValue: 0, duration:
|
|
42
|
-
Animated.delay((2 - i) *
|
|
56
|
+
Animated.delay(i * DOT_STAGGER_MS),
|
|
57
|
+
Animated.timing(dot, { toValue: 1, duration: DOT_PULSE_MS, useNativeDriver: true, easing: Easing.out(Easing.quad) }),
|
|
58
|
+
Animated.timing(dot, { toValue: 0, duration: DOT_PULSE_MS, useNativeDriver: true, easing: Easing.in(Easing.quad) }),
|
|
59
|
+
Animated.delay((2 - i) * DOT_STAGGER_MS),
|
|
43
60
|
])
|
|
44
61
|
)
|
|
45
62
|
);
|
|
46
63
|
animations.forEach((a) => a.start());
|
|
47
|
-
//
|
|
48
|
-
//
|
|
64
|
+
// Without stop() the loops keep running after unmount and keep the
|
|
65
|
+
// Animated tree alive.
|
|
49
66
|
return () => animations.forEach((a) => a.stop());
|
|
50
67
|
}, []);
|
|
51
68
|
|
|
@@ -69,37 +86,74 @@ const DotsIndicator = memo(({ color, dotSize }: { color: string; dotSize: number
|
|
|
69
86
|
});
|
|
70
87
|
DotsIndicator.displayName = 'DotsIndicator';
|
|
71
88
|
|
|
72
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* Spinning ring: a faint fixed track and, on top, an arc (a single side of
|
|
91
|
+
* the border) that spins. The track uses `opacity` instead of appending alpha
|
|
92
|
+
* to the color (`color + '33'`), which only worked with 6-digit hex and broke
|
|
93
|
+
* with `rgb()` or color names.
|
|
94
|
+
*/
|
|
73
95
|
const RingIndicator = memo(({ color, diameter }: { color: string; diameter: number }) => {
|
|
74
96
|
const spin = useRef(new Animated.Value(0)).current;
|
|
75
97
|
|
|
76
98
|
useEffect(() => {
|
|
77
99
|
const animation = Animated.loop(
|
|
78
|
-
Animated.timing(spin, { toValue: 1, duration:
|
|
100
|
+
Animated.timing(spin, { toValue: 1, duration: RING_TURN_MS, useNativeDriver: true, easing: Easing.linear })
|
|
79
101
|
);
|
|
80
102
|
animation.start();
|
|
81
103
|
return () => animation.stop();
|
|
82
104
|
}, []);
|
|
83
105
|
|
|
106
|
+
const ring = { width: diameter, height: diameter, borderRadius: diameter / 2, borderWidth: Math.max(2, diameter / 10) };
|
|
84
107
|
return (
|
|
85
|
-
<
|
|
86
|
-
style={{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
108
|
+
<View style={{ width: diameter, height: diameter }}>
|
|
109
|
+
<View style={[ring, { position: 'absolute', borderColor: color, opacity: 0.2 }]} />
|
|
110
|
+
<Animated.View
|
|
111
|
+
style={[
|
|
112
|
+
ring,
|
|
113
|
+
{
|
|
114
|
+
borderColor: 'transparent',
|
|
115
|
+
borderTopColor: color,
|
|
116
|
+
transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }) }],
|
|
117
|
+
},
|
|
118
|
+
]}
|
|
119
|
+
/>
|
|
120
|
+
</View>
|
|
96
121
|
);
|
|
97
122
|
});
|
|
98
123
|
RingIndicator.displayName = 'RingIndicator';
|
|
99
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Spinner
|
|
127
|
+
* Indeterminate loading indicator, with optional text below.
|
|
128
|
+
*
|
|
129
|
+
* Gestalt:
|
|
130
|
+
* - Common fate: the three `dots` pulse in sequence, at the same rhythm, and
|
|
131
|
+
* read as a single indicator moving forward.
|
|
132
|
+
* - Proximity: the text sits `spacing.md` from the indicator, so it reads as
|
|
133
|
+
* its explanation and not as loose text on the screen. The `logo` sits
|
|
134
|
+
* further away (`spacing.xl`): it is the screen's brand, not part of the indicator.
|
|
135
|
+
* - Focal point: with `logo`, the logo is the first thing seen and the
|
|
136
|
+
* indicator stays as a secondary signal that the app is loading.
|
|
137
|
+
*
|
|
138
|
+
* Accessibility: it is announced as a busy `progressbar`, with `text` (or
|
|
139
|
+
* `labels.loading`) as its name. The animation doesn't stop with Reduce
|
|
140
|
+
* Motion: it is the signal that something is happening, like the system's
|
|
141
|
+
* ActivityIndicator.
|
|
142
|
+
*/
|
|
100
143
|
export const Spinner = memo(
|
|
101
|
-
({
|
|
144
|
+
({
|
|
145
|
+
size = 'large',
|
|
146
|
+
color,
|
|
147
|
+
text,
|
|
148
|
+
fullscreen = true,
|
|
149
|
+
variant = 'native',
|
|
150
|
+
indicator,
|
|
151
|
+
logo,
|
|
152
|
+
accessibilityLabel,
|
|
153
|
+
testID,
|
|
154
|
+
}: SpinnerProps) => {
|
|
102
155
|
const colors = useColors();
|
|
156
|
+
const labels = useLabels();
|
|
103
157
|
const styles = useStyles();
|
|
104
158
|
const allowFontScaling = useAllowFontScaling();
|
|
105
159
|
const resolvedColor = color || colors.primary;
|
|
@@ -113,9 +167,18 @@ export const Spinner = memo(
|
|
|
113
167
|
};
|
|
114
168
|
|
|
115
169
|
return (
|
|
116
|
-
<View
|
|
170
|
+
<View
|
|
171
|
+
style={[styles.container, fullscreen && { flex: 1 }]}
|
|
172
|
+
testID={testID}
|
|
173
|
+
accessible
|
|
174
|
+
accessibilityRole="progressbar"
|
|
175
|
+
accessibilityLabel={accessibilityLabel ?? (text || labels.loading)}
|
|
176
|
+
accessibilityState={{ busy: true }}
|
|
177
|
+
accessibilityLiveRegion="polite"
|
|
178
|
+
>
|
|
179
|
+
{logo != null && <View style={styles.logo}>{logo}</View>}
|
|
117
180
|
{renderIndicator()}
|
|
118
|
-
{text && (
|
|
181
|
+
{!!text && (
|
|
119
182
|
<Text allowFontScaling={allowFontScaling} style={styles.text}>
|
|
120
183
|
{text}
|
|
121
184
|
</Text>
|
package/src/atoms/Text.tsx
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Text as RNText,
|
|
4
|
+
type AccessibilityRole,
|
|
5
|
+
type StyleProp,
|
|
6
|
+
type TextProps,
|
|
7
|
+
type TextStyle,
|
|
8
|
+
} from 'react-native';
|
|
3
9
|
import { createStyles } from '../theme/createStyles';
|
|
4
10
|
import { useAllowFontScaling, useColors } from '../theme/UIProvider';
|
|
5
11
|
|
|
@@ -13,13 +19,15 @@ export interface TypographyProps extends TextProps {
|
|
|
13
19
|
const useStyles = createStyles((theme) => ({
|
|
14
20
|
title: {
|
|
15
21
|
fontSize: theme.tokens.fontSize.xxl,
|
|
22
|
+
lineHeight: theme.tokens.lineHeight.xl,
|
|
16
23
|
fontWeight: theme.tokens.fontWeight.bold,
|
|
17
|
-
letterSpacing:
|
|
24
|
+
letterSpacing: theme.tokens.letterSpacing.tight,
|
|
18
25
|
color: theme.colors.text,
|
|
19
26
|
},
|
|
20
27
|
subtitle: {
|
|
21
28
|
fontSize: theme.tokens.fontSize.lg,
|
|
22
|
-
|
|
29
|
+
lineHeight: theme.tokens.lineHeight.lg,
|
|
30
|
+
fontWeight: theme.tokens.fontWeight.semibold,
|
|
23
31
|
color: theme.colors.text,
|
|
24
32
|
},
|
|
25
33
|
body: {
|
|
@@ -29,11 +37,16 @@ const useStyles = createStyles((theme) => ({
|
|
|
29
37
|
},
|
|
30
38
|
caption: {
|
|
31
39
|
fontSize: theme.tokens.fontSize.sm,
|
|
40
|
+
lineHeight: theme.tokens.lineHeight.sm,
|
|
32
41
|
color: theme.colors.textLight,
|
|
33
42
|
},
|
|
34
43
|
}));
|
|
35
44
|
|
|
36
|
-
function makeVariant(
|
|
45
|
+
function makeVariant(
|
|
46
|
+
variant: keyof ReturnType<typeof useStyles>,
|
|
47
|
+
defaultColor: 'text' | 'textLight',
|
|
48
|
+
defaultRole?: AccessibilityRole,
|
|
49
|
+
) {
|
|
37
50
|
const Component = memo(({ children, style, color, align = 'left', ...props }: TypographyProps) => {
|
|
38
51
|
const styles = useStyles();
|
|
39
52
|
const colors = useColors();
|
|
@@ -41,6 +54,7 @@ function makeVariant(variant: keyof ReturnType<typeof useStyles>, defaultColor:
|
|
|
41
54
|
return (
|
|
42
55
|
<RNText
|
|
43
56
|
allowFontScaling={allowFontScaling}
|
|
57
|
+
accessibilityRole={defaultRole}
|
|
44
58
|
style={[styles[variant], { color: color || colors[defaultColor], textAlign: align }, style]}
|
|
45
59
|
{...props}
|
|
46
60
|
>
|
|
@@ -48,11 +62,57 @@ function makeVariant(variant: keyof ReturnType<typeof useStyles>, defaultColor:
|
|
|
48
62
|
</RNText>
|
|
49
63
|
);
|
|
50
64
|
});
|
|
51
|
-
Component.displayName = variant;
|
|
65
|
+
Component.displayName = String(variant);
|
|
52
66
|
return Component;
|
|
53
67
|
}
|
|
54
68
|
|
|
55
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Screen or section title: the highest step of the typographic hierarchy.
|
|
71
|
+
*
|
|
72
|
+
* Gestalt, focal point (Von Restorff): it is the only text in its block with
|
|
73
|
+
* size `xxl` and weight `bold`, so it breaks the series of Body/Caption and is
|
|
74
|
+
* the first thing read. That is why there should be only one per block: two
|
|
75
|
+
* Titles together cancel each other out. The `tight` tracking offsets the room
|
|
76
|
+
* the large size opens between letters so the word reads as a single shape
|
|
77
|
+
* (Prägnanz), and `lineHeight.xl` keeps the block compact when the title wraps.
|
|
78
|
+
*
|
|
79
|
+
* Accessibility: it is announced with `accessibilityRole="header"`, so
|
|
80
|
+
* VoiceOver/TalkBack can jump from title to title. It can be overridden by
|
|
81
|
+
* passing a different `accessibilityRole`.
|
|
82
|
+
*/
|
|
83
|
+
export const Title = makeVariant('title', 'text', 'header');
|
|
84
|
+
/**
|
|
85
|
+
* Second step of the hierarchy: heads a group within the screen or
|
|
86
|
+
* accompanies a Title with a short piece of data.
|
|
87
|
+
*
|
|
88
|
+
* Gestalt, similarity: it shares its color with Body but steps up size (`lg`)
|
|
89
|
+
* and weight (`semibold`), so it is perceived as part of the same family and,
|
|
90
|
+
* at the same time, as the label of the block that follows. Proximity: it
|
|
91
|
+
* should sit closer to the content it heads than to the previous block. It is
|
|
92
|
+
* not an accessibility heading: if it marks a navigable section, use Title (or
|
|
93
|
+
* pass `accessibilityRole="header"`).
|
|
94
|
+
* `lineHeight.lg` (1.5×) keeps the text legible when it spans several lines.
|
|
95
|
+
*/
|
|
56
96
|
export const Subtitle = makeVariant('subtitle', 'text');
|
|
97
|
+
/**
|
|
98
|
+
* Running text: the default style for paragraphs, descriptions and values.
|
|
99
|
+
*
|
|
100
|
+
* Gestalt, similarity: all reading content shares size (`md`), regular weight
|
|
101
|
+
* and the `text` color, so it is perceived as a single level and the steps
|
|
102
|
+
* above (Title, Subtitle) and below (Caption) stand out by contrast.
|
|
103
|
+
* `lineHeight.md` (≈1.43×) gives the room between lines to read long
|
|
104
|
+
* paragraphs. If `color` is passed, the color/background pair must meet WCAG
|
|
105
|
+
* AA (4.5:1); the theme colors already guarantee it.
|
|
106
|
+
*/
|
|
57
107
|
export const Body = makeVariant('body', 'text');
|
|
108
|
+
/**
|
|
109
|
+
* Secondary text: hints, metadata, dates, help below a field.
|
|
110
|
+
*
|
|
111
|
+
* Gestalt, figure and ground: size `sm` and color `textLight` bring it one
|
|
112
|
+
* step below Body, so it reads as context and doesn't compete with the
|
|
113
|
+
* content. Proximity: it sits right next to the element it explains.
|
|
114
|
+
* `textLight` meets WCAG AA over `surface` and `background` in light and dark
|
|
115
|
+
* (palettes tests); don't lighten it further. `lineHeight.sm` (≈1.33×) keeps
|
|
116
|
+
* the lines together when the hint spans several.
|
|
117
|
+
*/
|
|
58
118
|
export const Caption = makeVariant('caption', 'textLight');
|
package/src/atoms/Transition.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { memo, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Animated, Easing, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
3
|
import { useTheme } from '../theme/UIProvider';
|
|
4
|
+
import { useReduceMotion } from '../theme/useReduceMotion';
|
|
4
5
|
|
|
5
6
|
export type TransitionPreset =
|
|
6
7
|
| 'fade'
|
|
@@ -12,6 +13,7 @@ export type TransitionPreset =
|
|
|
12
13
|
| 'slide-right';
|
|
13
14
|
|
|
14
15
|
export interface TransitionProps {
|
|
16
|
+
/** Content that enters and exits. */
|
|
15
17
|
children: React.ReactNode;
|
|
16
18
|
/** Enters when true, exits (and unmounts) when false. @default true */
|
|
17
19
|
visible?: boolean;
|
|
@@ -21,7 +23,7 @@ export interface TransitionProps {
|
|
|
21
23
|
duration?: number;
|
|
22
24
|
/** ms before starting. A per-index delay staggers a list. @default 0 */
|
|
23
25
|
delay?: number;
|
|
24
|
-
/** Pixels traveled by the slide presets. @default 24 */
|
|
26
|
+
/** Pixels traveled by the slide presets. @default tokens.spacing.xxl (24) */
|
|
25
27
|
distance?: number;
|
|
26
28
|
/** Spring instead of timing (implicit in 'pop'). */
|
|
27
29
|
spring?: boolean;
|
|
@@ -34,50 +36,39 @@ export interface TransitionProps {
|
|
|
34
36
|
* whoever passes it decides when and how it advances (a PanResponder, for example).
|
|
35
37
|
*/
|
|
36
38
|
value?: Animated.Value;
|
|
39
|
+
/** Called when the enter animation finishes. Not called when driven by `value`. */
|
|
37
40
|
onEntered?: () => void;
|
|
41
|
+
/** Called when the exit animation finishes, before unmounting. Not called when driven by `value`. */
|
|
38
42
|
onExited?: () => void;
|
|
39
43
|
style?: StyleProp<ViewStyle>;
|
|
40
44
|
testID?: string;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
const SCALE_FROM: Record<'scale' | 'pop', number> = { scale: 0.92, pop: 0.8 };
|
|
48
|
+
const hiddenStyle: ViewStyle = { pointerEvents: 'none' };
|
|
49
|
+
/** 'pop' spring: bounces once and settles (~350 ms), without oscillating. */
|
|
50
|
+
const POP_SPRING = { friction: 9, tension: 90 } as const;
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
* callbacks y el desmontaje siguen ocurriendo igual.
|
|
49
|
-
*/
|
|
50
|
-
export function useReduceMotion(): boolean {
|
|
51
|
-
const [reduceMotion, setReduceMotion] = useState(false);
|
|
52
|
-
|
|
53
|
-
useEffect(() => {
|
|
54
|
-
let alive = true;
|
|
55
|
-
// Sólo se actualiza el estado si el ajuste está activo: el valor inicial ya
|
|
56
|
-
// es `false` y un setState de false a false costaría un render por montaje.
|
|
57
|
-
AccessibilityInfo.isReduceMotionEnabled().then((enabled) => {
|
|
58
|
-
if (alive && enabled) setReduceMotion(true);
|
|
59
|
-
});
|
|
60
|
-
const sub = AccessibilityInfo.addEventListener('reduceMotionChanged', setReduceMotion);
|
|
61
|
-
return () => {
|
|
62
|
-
alive = false;
|
|
63
|
-
sub.remove();
|
|
64
|
-
};
|
|
65
|
-
}, []);
|
|
66
|
-
|
|
67
|
-
return reduceMotion;
|
|
68
|
-
}
|
|
52
|
+
// Lives in theme/ (UIProvider uses it too); re-exported here so existing
|
|
53
|
+
// imports don't break.
|
|
54
|
+
export { useReduceMotion };
|
|
69
55
|
|
|
70
56
|
/**
|
|
71
57
|
* Transition
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
58
|
+
* Wraps any tree and animates it on enter and exit. Every preset boils down
|
|
59
|
+
* to `opacity` and `transform` over a single Animated.Value, which is what
|
|
60
|
+
* `useNativeDriver` knows how to send to the native thread: the animation runs
|
|
61
|
+
* there and the JS thread takes part in no frame — that is why there are no
|
|
62
|
+
* height, width or color presets, which would force a return to JS every frame.
|
|
63
|
+
*
|
|
64
|
+
* The node stays mounted until the exit animation finishes, and the behavior
|
|
65
|
+
* is identical on iOS and Android: there is no per-platform branch. While
|
|
66
|
+
* exiting (or hidden with `keepMounted`) it stops receiving touches and leaves
|
|
67
|
+
* the accessibility tree: what is invisible isn't read.
|
|
77
68
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
69
|
+
* Gestalt, common fate: what enters or exits together is perceived as a group;
|
|
70
|
+
* with a per-index `delay` the list enters in reading order (continuity).
|
|
71
|
+
* Respects Reduce Motion: jumps to the final state, callbacks still fire.
|
|
81
72
|
*/
|
|
82
73
|
export const Transition = memo(
|
|
83
74
|
({
|
|
@@ -86,7 +77,7 @@ export const Transition = memo(
|
|
|
86
77
|
preset = 'fade',
|
|
87
78
|
duration,
|
|
88
79
|
delay = 0,
|
|
89
|
-
distance
|
|
80
|
+
distance,
|
|
90
81
|
spring,
|
|
91
82
|
appear = true,
|
|
92
83
|
keepMounted = false,
|
|
@@ -97,6 +88,10 @@ export const Transition = memo(
|
|
|
97
88
|
testID,
|
|
98
89
|
}: TransitionProps) => {
|
|
99
90
|
const theme = useTheme();
|
|
91
|
+
const travel = distance ?? theme.tokens.spacing.xxl;
|
|
92
|
+
// Resolved here, not inside the effect: depending on `theme` restarted the
|
|
93
|
+
// animation (and fired onEntered again) every time the theme changed.
|
|
94
|
+
const resolvedDuration = duration ?? theme.tokens.duration.base;
|
|
100
95
|
const reduceMotion = useReduceMotion();
|
|
101
96
|
const internal = useRef(new Animated.Value(visible && !appear ? 1 : 0)).current;
|
|
102
97
|
const progress = value ?? internal;
|
|
@@ -104,8 +99,8 @@ export const Transition = memo(
|
|
|
104
99
|
|
|
105
100
|
const [mounted, setMounted] = useState(visible || keepMounted);
|
|
106
101
|
|
|
107
|
-
//
|
|
108
|
-
//
|
|
102
|
+
// The callbacks live in a ref: passed inline they change identity on
|
|
103
|
+
// every render and, as effect dependencies, would restart the animation.
|
|
109
104
|
const callbacks = useRef({ onEntered, onExited });
|
|
110
105
|
useEffect(() => {
|
|
111
106
|
callbacks.current = { onEntered, onExited };
|
|
@@ -126,11 +121,11 @@ export const Transition = memo(
|
|
|
126
121
|
const animation = reduceMotion
|
|
127
122
|
? Animated.timing(progress, { toValue, duration: 0, delay, useNativeDriver: true })
|
|
128
123
|
: useSpring
|
|
129
|
-
? Animated.spring(progress, { toValue, delay,
|
|
124
|
+
? Animated.spring(progress, { toValue, delay, ...POP_SPRING, useNativeDriver: true })
|
|
130
125
|
: Animated.timing(progress, {
|
|
131
126
|
toValue,
|
|
132
127
|
delay,
|
|
133
|
-
duration:
|
|
128
|
+
duration: resolvedDuration,
|
|
134
129
|
easing: visible ? Easing.out(Easing.cubic) : Easing.in(Easing.cubic),
|
|
135
130
|
useNativeDriver: true,
|
|
136
131
|
});
|
|
@@ -146,7 +141,7 @@ export const Transition = memo(
|
|
|
146
141
|
});
|
|
147
142
|
|
|
148
143
|
return () => animation.stop();
|
|
149
|
-
}, [visible, driven, reduceMotion, spring, delay,
|
|
144
|
+
}, [visible, driven, reduceMotion, spring, delay, resolvedDuration, keepMounted, presets, progress]);
|
|
150
145
|
|
|
151
146
|
const animatedStyle = useMemo(() => {
|
|
152
147
|
type Interpolated = Animated.AnimatedInterpolation<number>;
|
|
@@ -165,21 +160,22 @@ export const Transition = memo(
|
|
|
165
160
|
continue;
|
|
166
161
|
}
|
|
167
162
|
const vertical = item === 'slide-up' || item === 'slide-down';
|
|
168
|
-
const from = item === 'slide-up' || item === 'slide-left' ?
|
|
163
|
+
const from = item === 'slide-up' || item === 'slide-left' ? travel : -travel;
|
|
169
164
|
const offset = progress.interpolate({ inputRange: [0, 1], outputRange: [from, 0] });
|
|
170
165
|
transform.push(vertical ? { translateY: offset } : { translateX: offset });
|
|
171
166
|
}
|
|
172
167
|
|
|
173
168
|
return { opacity, transform };
|
|
174
|
-
}, [presets, progress,
|
|
169
|
+
}, [presets, progress, travel]);
|
|
175
170
|
|
|
176
171
|
if (!mounted) return null;
|
|
177
172
|
|
|
178
173
|
return (
|
|
179
174
|
<Animated.View
|
|
180
175
|
testID={testID}
|
|
181
|
-
|
|
182
|
-
|
|
176
|
+
accessibilityElementsHidden={!visible}
|
|
177
|
+
importantForAccessibility={visible ? 'auto' : 'no-hide-descendants'}
|
|
178
|
+
style={[style, animatedStyle, !visible && hiddenStyle]}
|
|
183
179
|
>
|
|
184
180
|
{children}
|
|
185
181
|
</Animated.View>
|
package/src/atoms/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type { ButtonProps, ButtonVariant, ButtonSize } from './Button';
|
|
|
5
5
|
export { IconButton } from './IconButton';
|
|
6
6
|
export type { IconButtonProps } from './IconButton';
|
|
7
7
|
export { Input } from './Input';
|
|
8
|
-
export type { InputProps } from './Input';
|
|
8
|
+
export type { InputProps, InputHandle, InputRules, InputRuleValue } from './Input';
|
|
9
9
|
export { Checkbox } from './Checkbox';
|
|
10
10
|
export type { CheckboxProps } from './Checkbox';
|
|
11
11
|
export { Badge } from './Badge';
|
|
@@ -16,7 +16,7 @@ export { Divider } from './Divider';
|
|
|
16
16
|
export type { DividerProps } from './Divider';
|
|
17
17
|
export { Gradient } from './Gradient';
|
|
18
18
|
export type { GradientProps, GradientDirection } from './Gradient';
|
|
19
|
-
export { Avatar } from './Avatar';
|
|
19
|
+
export { Avatar, initialsOf } from './Avatar';
|
|
20
20
|
export type { AvatarProps } from './Avatar';
|
|
21
21
|
export { Image, prefetchImage } from './Image';
|
|
22
22
|
export type { ImageProps } from './Image';
|
|
@@ -29,7 +29,7 @@ export type { TransitionProps, TransitionPreset } from './Transition';
|
|
|
29
29
|
export { ShinyText } from './ShinyText';
|
|
30
30
|
export type { ShinyTextProps } from './ShinyText';
|
|
31
31
|
export { EmptyState } from './EmptyState';
|
|
32
|
-
export type { EmptyStateProps } from './EmptyState';
|
|
32
|
+
export type { EmptyStateProps, EmptyStateAction } from './EmptyState';
|
|
33
33
|
export { KeyValueRow } from './KeyValueRow';
|
|
34
34
|
export type { KeyValueRowProps } from './KeyValueRow';
|
|
35
35
|
export { Fab } from './Fab';
|