panelui-native 0.71.0 → 0.75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/lib/module/components/accordion/index.js +10 -4
- package/lib/module/components/accordion/index.js.map +1 -1
- package/lib/module/components/area-chart/index.js +1 -0
- package/lib/module/components/area-chart/index.js.map +1 -1
- package/lib/module/components/avatar/avatar-group.js +64 -0
- package/lib/module/components/avatar/avatar-group.js.map +1 -0
- package/lib/module/components/avatar/index.js +84 -2
- package/lib/module/components/avatar/index.js.map +1 -1
- package/lib/module/components/breadcrumb/index.js +2 -1
- package/lib/module/components/breadcrumb/index.js.map +1 -1
- package/lib/module/components/button/index.js +7 -5
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/carousel/index.js +1 -1
- package/lib/module/components/carousel/index.js.map +1 -1
- package/lib/module/components/chip/index.js +2 -2
- package/lib/module/components/chip/index.js.map +1 -1
- package/lib/module/components/code-block/index.js.map +1 -1
- package/lib/module/components/collapsible/index.js +5 -1
- package/lib/module/components/collapsible/index.js.map +1 -1
- package/lib/module/components/color-picker/color-picker-accessibility.js +12 -0
- package/lib/module/components/color-picker/color-picker-accessibility.js.map +1 -0
- package/lib/module/components/color-picker/index.js +9 -5
- package/lib/module/components/color-picker/index.js.map +1 -1
- package/lib/module/components/date-time-picker/index.js +11 -3
- package/lib/module/components/date-time-picker/index.js.map +1 -1
- package/lib/module/components/drawer/index.js +58 -13
- package/lib/module/components/drawer/index.js.map +1 -1
- package/lib/module/components/fab/index.js +7 -6
- package/lib/module/components/fab/index.js.map +1 -1
- package/lib/module/components/flow/index.js +1 -1
- package/lib/module/components/flow/index.js.map +1 -1
- package/lib/module/components/frame/index.js +2 -2
- package/lib/module/components/frame/index.js.map +1 -1
- package/lib/module/components/grid-item/index.js +2 -2
- package/lib/module/components/grid-item/index.js.map +1 -1
- package/lib/module/components/heatmap-chart/index.js +1 -0
- package/lib/module/components/heatmap-chart/index.js.map +1 -1
- package/lib/module/components/hex-chart/index.js +1 -0
- package/lib/module/components/hex-chart/index.js.map +1 -1
- package/lib/module/components/input/index.js +7 -4
- package/lib/module/components/input/index.js.map +1 -1
- package/lib/module/components/input/input-content-padding.js +6 -0
- package/lib/module/components/input/input-content-padding.js.map +1 -0
- package/lib/module/components/input-group/index.js +21 -11
- package/lib/module/components/input-group/index.js.map +1 -1
- package/lib/module/components/input-group/input-group-measurements.js +60 -0
- package/lib/module/components/input-group/input-group-measurements.js.map +1 -0
- package/lib/module/components/item/index.js +2 -2
- package/lib/module/components/item/index.js.map +1 -1
- package/lib/module/components/line-chart/index.js +1 -0
- package/lib/module/components/line-chart/index.js.map +1 -1
- package/lib/module/components/marker/index.js +2 -2
- package/lib/module/components/marker/index.js.map +1 -1
- package/lib/module/components/marquee/index.js +9 -12
- package/lib/module/components/marquee/index.js.map +1 -1
- package/lib/module/components/marquee/marquee-math.js +39 -0
- package/lib/module/components/marquee/marquee-math.js.map +1 -0
- package/lib/module/components/menu/index.js +11 -3
- package/lib/module/components/menu/index.js.map +1 -1
- package/lib/module/components/otp-input/index.js +3 -1
- package/lib/module/components/otp-input/index.js.map +1 -1
- package/lib/module/components/otp-input/otp-input-state.js +7 -0
- package/lib/module/components/otp-input/otp-input-state.js.map +1 -0
- package/lib/module/components/pagination/index.js +27 -11
- package/lib/module/components/pagination/index.js.map +1 -1
- package/lib/module/components/panelside/index.js +7 -2
- package/lib/module/components/panelside/index.js.map +1 -1
- package/lib/module/components/planner/index.js +46 -11
- package/lib/module/components/planner/index.js.map +1 -1
- package/lib/module/components/planner/planner-today.js +8 -0
- package/lib/module/components/planner/planner-today.js.map +1 -0
- package/lib/module/components/plot/index.js +113 -53
- package/lib/module/components/plot/index.js.map +1 -1
- package/lib/module/components/plot/plot-series-registry.js +32 -0
- package/lib/module/components/plot/plot-series-registry.js.map +1 -0
- package/lib/module/components/post/index.js +4 -4
- package/lib/module/components/post/index.js.map +1 -1
- package/lib/module/components/radio-group/index.js +2 -1
- package/lib/module/components/radio-group/index.js.map +1 -1
- package/lib/module/components/radio-group/radio-group-value.js +8 -0
- package/lib/module/components/radio-group/radio-group-value.js.map +1 -0
- package/lib/module/components/rating/index.js +7 -4
- package/lib/module/components/rating/index.js.map +1 -1
- package/lib/module/components/rating/rating-inputs.js +15 -0
- package/lib/module/components/rating/rating-inputs.js.map +1 -0
- package/lib/module/components/search-bar/index.js +331 -0
- package/lib/module/components/search-bar/index.js.map +1 -0
- package/lib/module/components/search-bar/search-bar-debounce.js +23 -0
- package/lib/module/components/search-bar/search-bar-debounce.js.map +1 -0
- package/lib/module/components/select/index.js +9 -1
- package/lib/module/components/select/index.js.map +1 -1
- package/lib/module/components/select/native-select-contract.js +11 -0
- package/lib/module/components/select/native-select-contract.js.map +1 -0
- package/lib/module/components/split-view/index.js +439 -0
- package/lib/module/components/split-view/index.js.map +1 -0
- package/lib/module/components/split-view/split-view-math.js +132 -0
- package/lib/module/components/split-view/split-view-math.js.map +1 -0
- package/lib/module/components/splitter/index.js +433 -0
- package/lib/module/components/splitter/index.js.map +1 -0
- package/lib/module/components/splitter/splitter-math.js +206 -0
- package/lib/module/components/splitter/splitter-math.js.map +1 -0
- package/lib/module/components/steps/index.js +16 -5
- package/lib/module/components/steps/index.js.map +1 -1
- package/lib/module/components/steps/steps-trigger.js +6 -0
- package/lib/module/components/steps/steps-trigger.js.map +1 -0
- package/lib/module/components/table/index.js +3 -4
- package/lib/module/components/table/index.js.map +1 -1
- package/lib/module/components/tag-input/index.js +15 -10
- package/lib/module/components/tag-input/index.js.map +1 -1
- package/lib/module/components/tag-input/tag-input-state.js +14 -0
- package/lib/module/components/tag-input/tag-input-state.js.map +1 -0
- package/lib/module/components/textarea/index.js +9 -4
- package/lib/module/components/textarea/index.js.map +1 -1
- package/lib/module/components/textarea/textarea-disabled.js +6 -0
- package/lib/module/components/textarea/textarea-disabled.js.map +1 -0
- package/lib/module/components/timeline/index.js +352 -47
- package/lib/module/components/timeline/index.js.map +1 -1
- package/lib/module/components/timeline/timeline-geometry.js +11 -0
- package/lib/module/components/timeline/timeline-geometry.js.map +1 -0
- package/lib/module/components/toast/index.js +18 -1
- package/lib/module/components/toast/index.js.map +1 -1
- package/lib/module/components/toast/toast-store.js +36 -4
- package/lib/module/components/toast/toast-store.js.map +1 -1
- package/lib/module/components/toggle-button/index.js +1 -1
- package/lib/module/components/toggle-button/index.js.map +1 -1
- package/lib/module/components/tour/index.js +4 -2
- package/lib/module/components/tour/index.js.map +1 -1
- package/lib/module/components/tour/tour-card-measurement.js +24 -0
- package/lib/module/components/tour/tour-card-measurement.js.map +1 -0
- package/lib/module/components/tree/index.js +13 -8
- package/lib/module/components/tree/index.js.map +1 -1
- package/lib/module/hooks/use-keyboard-avoidance.js.map +1 -1
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/chart.js +50 -7
- package/lib/module/utils/chart.js.map +1 -1
- package/lib/typescript/src/components/accordion/index.d.ts +2 -2
- package/lib/typescript/src/components/accordion/index.d.ts.map +1 -1
- package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/avatar/avatar-group.d.ts +46 -0
- package/lib/typescript/src/components/avatar/avatar-group.d.ts.map +1 -0
- package/lib/typescript/src/components/avatar/index.d.ts +23 -1
- package/lib/typescript/src/components/avatar/index.d.ts.map +1 -1
- package/lib/typescript/src/components/breadcrumb/index.d.ts.map +1 -1
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/code-block/index.d.ts +3 -3
- package/lib/typescript/src/components/code-block/index.d.ts.map +1 -1
- package/lib/typescript/src/components/collapsible/index.d.ts +2 -2
- package/lib/typescript/src/components/collapsible/index.d.ts.map +1 -1
- package/lib/typescript/src/components/color-picker/color-picker-accessibility.d.ts +8 -0
- package/lib/typescript/src/components/color-picker/color-picker-accessibility.d.ts.map +1 -0
- package/lib/typescript/src/components/color-picker/index.d.ts.map +1 -1
- package/lib/typescript/src/components/date-time-picker/index.d.ts.map +1 -1
- package/lib/typescript/src/components/drawer/index.d.ts.map +1 -1
- package/lib/typescript/src/components/fab/index.d.ts +4 -2
- package/lib/typescript/src/components/fab/index.d.ts.map +1 -1
- package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/hex-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/input/index.d.ts.map +1 -1
- package/lib/typescript/src/components/input/input-content-padding.d.ts +2 -0
- package/lib/typescript/src/components/input/input-content-padding.d.ts.map +1 -0
- package/lib/typescript/src/components/input-group/index.d.ts.map +1 -1
- package/lib/typescript/src/components/input-group/input-group-measurements.d.ts +16 -0
- package/lib/typescript/src/components/input-group/input-group-measurements.d.ts.map +1 -0
- package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/marquee/index.d.ts +1 -1
- package/lib/typescript/src/components/marquee/index.d.ts.map +1 -1
- package/lib/typescript/src/components/marquee/marquee-math.d.ts +21 -0
- package/lib/typescript/src/components/marquee/marquee-math.d.ts.map +1 -0
- package/lib/typescript/src/components/menu/index.d.ts +1 -1
- package/lib/typescript/src/components/menu/index.d.ts.map +1 -1
- package/lib/typescript/src/components/otp-input/index.d.ts.map +1 -1
- package/lib/typescript/src/components/otp-input/otp-input-state.d.ts +3 -0
- package/lib/typescript/src/components/otp-input/otp-input-state.d.ts.map +1 -0
- package/lib/typescript/src/components/pagination/index.d.ts.map +1 -1
- package/lib/typescript/src/components/panelside/index.d.ts +1 -1
- package/lib/typescript/src/components/panelside/index.d.ts.map +1 -1
- package/lib/typescript/src/components/plan/index.d.ts +2 -2
- package/lib/typescript/src/components/planner/index.d.ts.map +1 -1
- package/lib/typescript/src/components/planner/planner-today.d.ts +2 -0
- package/lib/typescript/src/components/planner/planner-today.d.ts.map +1 -0
- package/lib/typescript/src/components/plot/index.d.ts +60 -6
- package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
- package/lib/typescript/src/components/plot/plot-series-registry.d.ts +8 -0
- package/lib/typescript/src/components/plot/plot-series-registry.d.ts.map +1 -0
- package/lib/typescript/src/components/radio-group/index.d.ts.map +1 -1
- package/lib/typescript/src/components/radio-group/radio-group-value.d.ts +2 -0
- package/lib/typescript/src/components/radio-group/radio-group-value.d.ts.map +1 -0
- package/lib/typescript/src/components/rating/index.d.ts.map +1 -1
- package/lib/typescript/src/components/rating/rating-inputs.d.ts +4 -0
- package/lib/typescript/src/components/rating/rating-inputs.d.ts.map +1 -0
- package/lib/typescript/src/components/search-bar/index.d.ts +216 -0
- package/lib/typescript/src/components/search-bar/index.d.ts.map +1 -0
- package/lib/typescript/src/components/search-bar/search-bar-debounce.d.ts +7 -0
- package/lib/typescript/src/components/search-bar/search-bar-debounce.d.ts.map +1 -0
- package/lib/typescript/src/components/select/index.d.ts.map +1 -1
- package/lib/typescript/src/components/select/native-select-contract.d.ts +11 -0
- package/lib/typescript/src/components/select/native-select-contract.d.ts.map +1 -0
- package/lib/typescript/src/components/split-view/index.d.ts +159 -0
- package/lib/typescript/src/components/split-view/index.d.ts.map +1 -0
- package/lib/typescript/src/components/split-view/split-view-math.d.ts +54 -0
- package/lib/typescript/src/components/split-view/split-view-math.d.ts.map +1 -0
- package/lib/typescript/src/components/splitter/index.d.ts +78 -0
- package/lib/typescript/src/components/splitter/index.d.ts.map +1 -0
- package/lib/typescript/src/components/splitter/splitter-math.d.ts +67 -0
- package/lib/typescript/src/components/splitter/splitter-math.d.ts.map +1 -0
- package/lib/typescript/src/components/steps/index.d.ts +2 -2
- package/lib/typescript/src/components/steps/index.d.ts.map +1 -1
- package/lib/typescript/src/components/steps/steps-trigger.d.ts +2 -0
- package/lib/typescript/src/components/steps/steps-trigger.d.ts.map +1 -0
- package/lib/typescript/src/components/tag-input/index.d.ts.map +1 -1
- package/lib/typescript/src/components/tag-input/tag-input-state.d.ts +12 -0
- package/lib/typescript/src/components/tag-input/tag-input-state.d.ts.map +1 -0
- package/lib/typescript/src/components/textarea/index.d.ts.map +1 -1
- package/lib/typescript/src/components/textarea/textarea-disabled.d.ts +2 -0
- package/lib/typescript/src/components/textarea/textarea-disabled.d.ts.map +1 -0
- package/lib/typescript/src/components/timeline/index.d.ts +36 -2
- package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
- package/lib/typescript/src/components/timeline/timeline-geometry.d.ts +4 -0
- package/lib/typescript/src/components/timeline/timeline-geometry.d.ts.map +1 -0
- package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
- package/lib/typescript/src/components/toast/toast-store.d.ts +7 -2
- package/lib/typescript/src/components/toast/toast-store.d.ts.map +1 -1
- package/lib/typescript/src/components/tour/index.d.ts.map +1 -1
- package/lib/typescript/src/components/tour/tour-card-measurement.d.ts +14 -0
- package/lib/typescript/src/components/tour/tour-card-measurement.d.ts.map +1 -0
- package/lib/typescript/src/components/tree/index.d.ts +3 -4
- package/lib/typescript/src/components/tree/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-keyboard-avoidance.d.ts +2 -2
- package/lib/typescript/src/hooks/use-keyboard-avoidance.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +5 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/chart.d.ts +28 -3
- package/lib/typescript/src/utils/chart.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/accordion/index.tsx +17 -7
- package/src/components/area-chart/index.tsx +8 -0
- package/src/components/avatar/avatar-group.ts +78 -0
- package/src/components/avatar/index.tsx +121 -1
- package/src/components/breadcrumb/index.tsx +2 -1
- package/src/components/button/index.tsx +3 -2
- package/src/components/carousel/index.tsx +1 -1
- package/src/components/chip/index.tsx +2 -2
- package/src/components/code-block/index.tsx +3 -3
- package/src/components/collapsible/index.tsx +13 -4
- package/src/components/color-picker/color-picker-accessibility.ts +12 -0
- package/src/components/color-picker/index.tsx +30 -10
- package/src/components/date-time-picker/index.tsx +11 -3
- package/src/components/drawer/index.tsx +42 -14
- package/src/components/fab/index.tsx +21 -11
- package/src/components/flow/index.tsx +1 -1
- package/src/components/frame/index.tsx +2 -2
- package/src/components/grid-item/index.tsx +2 -2
- package/src/components/heatmap-chart/index.tsx +7 -1
- package/src/components/hex-chart/index.tsx +7 -1
- package/src/components/input/index.tsx +6 -2
- package/src/components/input/input-content-padding.ts +3 -0
- package/src/components/input-group/index.tsx +45 -12
- package/src/components/input-group/input-group-measurements.ts +98 -0
- package/src/components/item/index.tsx +2 -2
- package/src/components/line-chart/index.tsx +9 -0
- package/src/components/marker/index.tsx +2 -2
- package/src/components/marquee/index.tsx +14 -12
- package/src/components/marquee/marquee-math.ts +37 -0
- package/src/components/menu/index.tsx +11 -3
- package/src/components/otp-input/index.tsx +3 -1
- package/src/components/otp-input/otp-input-state.ts +7 -0
- package/src/components/pagination/index.tsx +26 -13
- package/src/components/panelside/index.tsx +7 -2
- package/src/components/plan/index.tsx +2 -2
- package/src/components/planner/index.tsx +44 -11
- package/src/components/planner/planner-today.ts +5 -0
- package/src/components/plot/index.tsx +199 -51
- package/src/components/plot/plot-series-registry.ts +41 -0
- package/src/components/post/index.tsx +4 -4
- package/src/components/radio-group/index.tsx +4 -1
- package/src/components/radio-group/radio-group-value.ts +9 -0
- package/src/components/rating/index.tsx +11 -4
- package/src/components/rating/rating-inputs.ts +19 -0
- package/src/components/search-bar/index.tsx +441 -0
- package/src/components/search-bar/search-bar-debounce.ts +35 -0
- package/src/components/select/index.tsx +10 -1
- package/src/components/select/native-select-contract.ts +12 -0
- package/src/components/split-view/index.tsx +565 -0
- package/src/components/split-view/split-view-math.ts +146 -0
- package/src/components/splitter/index.tsx +589 -0
- package/src/components/splitter/splitter-math.ts +244 -0
- package/src/components/steps/index.tsx +35 -9
- package/src/components/steps/steps-trigger.ts +6 -0
- package/src/components/table/index.tsx +2 -2
- package/src/components/tag-input/index.tsx +13 -11
- package/src/components/tag-input/tag-input-state.ts +18 -0
- package/src/components/textarea/index.tsx +8 -4
- package/src/components/textarea/textarea-disabled.ts +6 -0
- package/src/components/timeline/index.tsx +405 -46
- package/src/components/timeline/timeline-geometry.ts +9 -0
- package/src/components/toast/index.tsx +26 -1
- package/src/components/toast/toast-store.ts +43 -8
- package/src/components/toggle-button/index.tsx +1 -1
- package/src/components/tour/index.tsx +11 -3
- package/src/components/tour/tour-card-measurement.ts +29 -0
- package/src/components/tree/index.tsx +17 -12
- package/src/hooks/use-keyboard-avoidance.ts +7 -2
- package/src/index.ts +19 -0
- package/src/utils/chart.ts +66 -7
|
@@ -71,6 +71,7 @@ import {
|
|
|
71
71
|
View,
|
|
72
72
|
type AccessibilityActionEvent,
|
|
73
73
|
type LayoutChangeEvent,
|
|
74
|
+
type ViewStyle,
|
|
74
75
|
} from 'react-native';
|
|
75
76
|
import MaskedView from '@react-native-masked-view/masked-view';
|
|
76
77
|
import { LinearGradient } from 'expo-linear-gradient';
|
|
@@ -107,6 +108,7 @@ import {
|
|
|
107
108
|
import { cn } from '../../utils/cn';
|
|
108
109
|
import { selectionTick } from '../../utils/haptics';
|
|
109
110
|
import { Popover, type PopoverContentProps } from '../popover';
|
|
111
|
+
import { enabledColorPickerAction } from './color-picker-accessibility';
|
|
110
112
|
|
|
111
113
|
/** Settles a thumb that was moved by something other than a finger. */
|
|
112
114
|
const TIMING = { duration: 140 } as const;
|
|
@@ -585,7 +587,10 @@ const ColorPickerArea = forwardRef<View, ColorPickerAreaProps>(
|
|
|
585
587
|
};
|
|
586
588
|
|
|
587
589
|
const onAccessibilityAction = (event: AccessibilityActionEvent) => {
|
|
588
|
-
const action =
|
|
590
|
+
const action = enabledColorPickerAction(
|
|
591
|
+
event.nativeEvent.actionName,
|
|
592
|
+
ctx.disabled
|
|
593
|
+
);
|
|
589
594
|
if (action === 'increment') nudge('saturation', 1);
|
|
590
595
|
else if (action === 'decrement') nudge('saturation', -1);
|
|
591
596
|
else if (action === 'brighter') nudge('brightness', 1);
|
|
@@ -663,8 +668,8 @@ interface ChannelTrackProps {
|
|
|
663
668
|
/** What fills the track — a hue ramp, or a masked translucency ramp. */
|
|
664
669
|
children: ReactNode;
|
|
665
670
|
gesture: ReturnType<typeof Gesture.Race>;
|
|
666
|
-
thumbStyle: ReturnType<typeof useAnimatedStyle
|
|
667
|
-
thumbFillStyle: ReturnType<typeof useAnimatedStyle
|
|
671
|
+
thumbStyle: ReturnType<typeof useAnimatedStyle<ViewStyle>>;
|
|
672
|
+
thumbFillStyle: ReturnType<typeof useAnimatedStyle<ViewStyle>>;
|
|
668
673
|
onLayout: (event: LayoutChangeEvent) => void;
|
|
669
674
|
size: ColorPickerSize;
|
|
670
675
|
className?: string;
|
|
@@ -828,8 +833,12 @@ const ColorPickerHue = forwardRef<View, ColorPickerHueProps>(
|
|
|
828
833
|
disabled={ctx.disabled}
|
|
829
834
|
accessibilityValue={{ min: 0, max: 360, now: announced, text: `${announced}°` }}
|
|
830
835
|
onAccessibilityAction={(event) => {
|
|
831
|
-
|
|
832
|
-
|
|
836
|
+
const action = enabledColorPickerAction(
|
|
837
|
+
event.nativeEvent.actionName,
|
|
838
|
+
ctx.disabled
|
|
839
|
+
);
|
|
840
|
+
if (action === 'increment') nudge(1);
|
|
841
|
+
else if (action === 'decrement') nudge(-1);
|
|
833
842
|
}}
|
|
834
843
|
>
|
|
835
844
|
<LinearGradient
|
|
@@ -947,8 +956,12 @@ const ColorPickerAlpha = forwardRef<View, ColorPickerAlphaProps>(
|
|
|
947
956
|
text: `${announced}%`,
|
|
948
957
|
}}
|
|
949
958
|
onAccessibilityAction={(event) => {
|
|
950
|
-
|
|
951
|
-
|
|
959
|
+
const action = enabledColorPickerAction(
|
|
960
|
+
event.nativeEvent.actionName,
|
|
961
|
+
ctx.disabled
|
|
962
|
+
);
|
|
963
|
+
if (action === 'increment') nudge(1);
|
|
964
|
+
else if (action === 'decrement') nudge(-1);
|
|
952
965
|
}}
|
|
953
966
|
>
|
|
954
967
|
<Checkerboard />
|
|
@@ -1503,8 +1516,12 @@ const ColorPickerBrightness = forwardRef<View, ColorPickerBrightnessProps>(
|
|
|
1503
1516
|
text: `${announced}%`,
|
|
1504
1517
|
}}
|
|
1505
1518
|
onAccessibilityAction={(event) => {
|
|
1506
|
-
|
|
1507
|
-
|
|
1519
|
+
const action = enabledColorPickerAction(
|
|
1520
|
+
event.nativeEvent.actionName,
|
|
1521
|
+
ctx.disabled
|
|
1522
|
+
);
|
|
1523
|
+
if (action === 'increment') nudge(1);
|
|
1524
|
+
else if (action === 'decrement') nudge(-1);
|
|
1508
1525
|
}}
|
|
1509
1526
|
>
|
|
1510
1527
|
<LinearGradient
|
|
@@ -1666,7 +1683,10 @@ const ColorPickerWheel = forwardRef<View, ColorPickerWheelProps>(
|
|
|
1666
1683
|
};
|
|
1667
1684
|
|
|
1668
1685
|
const onAccessibilityAction = (event: AccessibilityActionEvent) => {
|
|
1669
|
-
const action =
|
|
1686
|
+
const action = enabledColorPickerAction(
|
|
1687
|
+
event.nativeEvent.actionName,
|
|
1688
|
+
ctx.disabled
|
|
1689
|
+
);
|
|
1670
1690
|
if (action === 'increment') nudge('hue', 1);
|
|
1671
1691
|
else if (action === 'decrement') nudge('hue', -1);
|
|
1672
1692
|
else if (action === 'saturate') nudge('saturation', 1);
|
|
@@ -84,6 +84,9 @@ const DEFAULT_PLACEHOLDER = 'Pick a date and time';
|
|
|
84
84
|
*/
|
|
85
85
|
const PANEL_WIDTH = 308;
|
|
86
86
|
|
|
87
|
+
/** A stable rule that makes every calendar day unavailable while disabled. */
|
|
88
|
+
const DISABLE_ALL_DATES = () => true;
|
|
89
|
+
|
|
87
90
|
/** How a `Date` is written on the closed trigger. */
|
|
88
91
|
function describe(
|
|
89
92
|
value: Date,
|
|
@@ -204,18 +207,23 @@ function DateTimePickerRoot({
|
|
|
204
207
|
|
|
205
208
|
const setOpen = useCallback(
|
|
206
209
|
(next: boolean) => {
|
|
210
|
+
if (disabled && next) return;
|
|
207
211
|
if (!isOpenControlled) setInternalOpen(next);
|
|
208
212
|
onOpenChange?.(next);
|
|
209
213
|
},
|
|
210
|
-
[isOpenControlled, onOpenChange]
|
|
214
|
+
[disabled, isOpenControlled, onOpenChange]
|
|
211
215
|
);
|
|
212
216
|
|
|
213
217
|
const commit = useCallback(
|
|
214
218
|
(next: Date) => {
|
|
219
|
+
// A controlled caller can keep the panel mounted or open while disabled.
|
|
220
|
+
// Guard the value boundary as well as the visible controls so a stale
|
|
221
|
+
// press cannot commit during the same render that disables the picker.
|
|
222
|
+
if (disabled) return;
|
|
215
223
|
if (!isValueControlled) setInternalValue(next);
|
|
216
224
|
onValueChange?.(next);
|
|
217
225
|
},
|
|
218
|
-
[isValueControlled, onValueChange]
|
|
226
|
+
[disabled, isValueControlled, onValueChange]
|
|
219
227
|
);
|
|
220
228
|
|
|
221
229
|
/*
|
|
@@ -281,7 +289,7 @@ function DateTimePickerRoot({
|
|
|
281
289
|
mode="single"
|
|
282
290
|
selected={value}
|
|
283
291
|
onSelect={handleDay}
|
|
284
|
-
disabled={disabledDates}
|
|
292
|
+
disabled={disabled ? DISABLE_ALL_DATES : disabledDates}
|
|
285
293
|
minDate={minDate}
|
|
286
294
|
maxDate={maxDate}
|
|
287
295
|
startMonth={minDate}
|
|
@@ -66,14 +66,11 @@ import {
|
|
|
66
66
|
} from 'react-native';
|
|
67
67
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
68
68
|
import Animated, {
|
|
69
|
+
Easing,
|
|
69
70
|
SlideInDown,
|
|
70
71
|
SlideInLeft,
|
|
71
72
|
SlideInRight,
|
|
72
73
|
SlideInUp,
|
|
73
|
-
SlideOutDown,
|
|
74
|
-
SlideOutLeft,
|
|
75
|
-
SlideOutRight,
|
|
76
|
-
SlideOutUp,
|
|
77
74
|
runOnJS,
|
|
78
75
|
useAnimatedStyle,
|
|
79
76
|
useSharedValue,
|
|
@@ -96,6 +93,9 @@ import {
|
|
|
96
93
|
import { cn } from '../../utils/cn';
|
|
97
94
|
|
|
98
95
|
const SPRING = { damping: 24, stiffness: 300, mass: 0.7 } as const;
|
|
96
|
+
/** How long the panel takes to leave, whether by a drag or a press. */
|
|
97
|
+
const EXIT_DURATION = 200;
|
|
98
|
+
|
|
99
99
|
/** How far a drag has to travel outward before releasing it dismisses. */
|
|
100
100
|
const DISMISS_DISTANCE = 80;
|
|
101
101
|
/** A flick this fast dismisses regardless of how far it got. */
|
|
@@ -375,9 +375,11 @@ function DrawerContent({
|
|
|
375
375
|
const velocity =
|
|
376
376
|
(horizontal ? event.velocityX : event.velocityY) * outward;
|
|
377
377
|
if (travel.value > DISMISS_DISTANCE || velocity > DISMISS_VELOCITY) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
378
|
+
// Straight to the exit, without finishing the slide first. The exit
|
|
379
|
+
// starts from wherever `travel` is and carries it the rest of the
|
|
380
|
+
// way, so driving it to `extent` here would be the same distance
|
|
381
|
+
// animated twice.
|
|
382
|
+
runOnJS(close)();
|
|
381
383
|
} else {
|
|
382
384
|
travel.value = withSpring(0, SPRING);
|
|
383
385
|
}
|
|
@@ -433,12 +435,38 @@ function DrawerContent({
|
|
|
433
435
|
bottom: SlideInDown,
|
|
434
436
|
}[physical];
|
|
435
437
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
438
|
+
/*
|
|
439
|
+
* The slide out is written by hand, because the panel is not always at rest
|
|
440
|
+
* when it starts.
|
|
441
|
+
*
|
|
442
|
+
* A preset animates from the view's *layout* position and applies its own
|
|
443
|
+
* transform, which overrides the one the drag was already using. So a
|
|
444
|
+
* swipe-dismiss played twice: the gesture carried the panel off-screen, and
|
|
445
|
+
* then the exit put it back at zero and slid it out again. Seeding the
|
|
446
|
+
* initial transform from `travel` makes the two one animation — the exit
|
|
447
|
+
* picks the panel up wherever the finger left it and carries it the rest of
|
|
448
|
+
* the way. A press on the close button or the backdrop leaves `travel` at
|
|
449
|
+
* zero, so that path is the same slide it always was.
|
|
450
|
+
*/
|
|
451
|
+
const exiting = useCallback(() => {
|
|
452
|
+
'worklet';
|
|
453
|
+
const shift = extent * outward;
|
|
454
|
+
const from = travel.value * outward;
|
|
455
|
+
const timing = { duration: EXIT_DURATION, easing: Easing.out(Easing.quad) };
|
|
456
|
+
|
|
457
|
+
return {
|
|
458
|
+
initialValues: {
|
|
459
|
+
transform: horizontal
|
|
460
|
+
? [{ translateX: from }, { translateY: 0 }]
|
|
461
|
+
: [{ translateX: 0 }, { translateY: from }],
|
|
462
|
+
},
|
|
463
|
+
animations: {
|
|
464
|
+
transform: horizontal
|
|
465
|
+
? [{ translateX: withTiming(shift, timing) }, { translateY: 0 }]
|
|
466
|
+
: [{ translateX: 0 }, { translateY: withTiming(shift, timing) }],
|
|
467
|
+
},
|
|
468
|
+
};
|
|
469
|
+
}, [extent, horizontal, outward, travel]);
|
|
442
470
|
|
|
443
471
|
/*
|
|
444
472
|
* The inset and the panel's own padding stack rather than compete.
|
|
@@ -499,7 +527,7 @@ function DrawerContent({
|
|
|
499
527
|
.damping(24)
|
|
500
528
|
.stiffness(260)
|
|
501
529
|
.mass(0.7)}
|
|
502
|
-
exiting={exiting
|
|
530
|
+
exiting={exiting}
|
|
503
531
|
accessibilityViewIsModal
|
|
504
532
|
className={panelVariants({ side, className })}
|
|
505
533
|
{...props}
|
|
@@ -85,7 +85,10 @@ import { tv, type VariantProps } from 'tailwind-variants';
|
|
|
85
85
|
import { useCSSVariable } from 'uniwind';
|
|
86
86
|
import { IconColorProvider } from '../../icons';
|
|
87
87
|
import { useBackHandler } from '../../hooks/use-back-handler';
|
|
88
|
-
import {
|
|
88
|
+
import {
|
|
89
|
+
AnimatedPressable,
|
|
90
|
+
type AnimatedPressableProps,
|
|
91
|
+
} from '../../primitives/animated-pressable';
|
|
89
92
|
import { Scrim } from '../../primitives/scrim';
|
|
90
93
|
import { Text } from '../../primitives/text';
|
|
91
94
|
import { cn } from '../../utils/cn';
|
|
@@ -180,7 +183,9 @@ function anchor(placement: FabPlacement, offset: number) {
|
|
|
180
183
|
* Fab
|
|
181
184
|
* -------------------------------------------------------------------------- */
|
|
182
185
|
|
|
183
|
-
export interface FabProps
|
|
186
|
+
export interface FabProps
|
|
187
|
+
extends Omit<AnimatedPressableProps, 'children' | 'style' | 'disabled'>,
|
|
188
|
+
Omit<FabVariantProps, 'disabled'> {
|
|
184
189
|
className?: string;
|
|
185
190
|
/** The glyph. Sized by you — this is the one thing that should not guess. */
|
|
186
191
|
icon?: ReactNode;
|
|
@@ -201,7 +206,8 @@ export interface FabProps extends Omit<ViewProps, 'children'>, FabVariantProps {
|
|
|
201
206
|
placement?: FabPlacement;
|
|
202
207
|
/** Distance from the edges when `placement` is set, in points. */
|
|
203
208
|
offset?: number;
|
|
204
|
-
|
|
209
|
+
/** Placement-aware view style. Press-state styling belongs in `className`. */
|
|
210
|
+
style?: ViewProps['style'];
|
|
205
211
|
disabled?: boolean;
|
|
206
212
|
/**
|
|
207
213
|
* A tick on press. Off by default — needs the optional `expo-haptics`, and
|
|
@@ -231,33 +237,37 @@ const FabRoot = forwardRef<View, FabProps>(
|
|
|
231
237
|
},
|
|
232
238
|
ref
|
|
233
239
|
) => {
|
|
240
|
+
const isDisabled = Boolean(disabled);
|
|
234
241
|
const { root, label } = fabVariants({
|
|
235
242
|
size,
|
|
236
243
|
variant,
|
|
237
244
|
extended: extended && !!children,
|
|
238
|
-
disabled,
|
|
245
|
+
disabled: isDisabled,
|
|
239
246
|
});
|
|
240
247
|
|
|
241
248
|
const themed = useCSSVariable(CONTENT_COLOR_VAR[variant ?? 'primary']);
|
|
242
249
|
const contentColor =
|
|
243
250
|
typeof themed === 'string' ? themed : undefined;
|
|
244
251
|
|
|
245
|
-
const handlePress = useCallback(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
252
|
+
const handlePress = useCallback<NonNullable<AnimatedPressableProps['onPress']>>(
|
|
253
|
+
(event) => {
|
|
254
|
+
if (haptics) selectionTick();
|
|
255
|
+
onPress?.(event);
|
|
256
|
+
},
|
|
257
|
+
[haptics, onPress]
|
|
258
|
+
);
|
|
249
259
|
|
|
250
260
|
return (
|
|
251
261
|
<IconColorProvider color={contentColor}>
|
|
252
262
|
<AnimatedPressable
|
|
253
263
|
ref={ref}
|
|
264
|
+
{...props}
|
|
254
265
|
accessibilityRole="button"
|
|
255
|
-
accessibilityState={{ disabled }}
|
|
256
|
-
disabled={
|
|
266
|
+
accessibilityState={{ disabled: isDisabled }}
|
|
267
|
+
disabled={isDisabled}
|
|
257
268
|
onPress={handlePress}
|
|
258
269
|
className={root({ className })}
|
|
259
270
|
style={[placement ? anchor(placement, offset) : null, style]}
|
|
260
|
-
{...props}
|
|
261
271
|
>
|
|
262
272
|
{icon}
|
|
263
273
|
{extended && children ? (
|
|
@@ -1254,6 +1254,7 @@ function FlowNode({
|
|
|
1254
1254
|
<FlowNodeContext.Provider value={id}>
|
|
1255
1255
|
<GestureDetector gesture={gesture}>
|
|
1256
1256
|
<Animated.View
|
|
1257
|
+
{...props}
|
|
1257
1258
|
collapsable={false}
|
|
1258
1259
|
onLayout={onLayout}
|
|
1259
1260
|
style={[{ position: 'absolute', top: 0, left: 0 }, style]}
|
|
@@ -1267,7 +1268,6 @@ function FlowNode({
|
|
|
1267
1268
|
accessibilityState={{ selected }}
|
|
1268
1269
|
accessibilityActions={nodeActions}
|
|
1269
1270
|
onAccessibilityAction={handleAccessibilityAction}
|
|
1270
|
-
{...props}
|
|
1271
1271
|
>
|
|
1272
1272
|
{textChildren(children)}
|
|
1273
1273
|
</Animated.View>
|
|
@@ -398,7 +398,7 @@ const FrameRow = forwardRef<View, FrameRowProps>(
|
|
|
398
398
|
|
|
399
399
|
if (!onPress) {
|
|
400
400
|
return (
|
|
401
|
-
<View ref={ref}
|
|
401
|
+
<View ref={ref} {...(props as ViewProps)} className={classes}>
|
|
402
402
|
{body}
|
|
403
403
|
</View>
|
|
404
404
|
);
|
|
@@ -407,10 +407,10 @@ const FrameRow = forwardRef<View, FrameRowProps>(
|
|
|
407
407
|
return (
|
|
408
408
|
<Pressable
|
|
409
409
|
ref={ref}
|
|
410
|
+
{...props}
|
|
410
411
|
accessibilityRole="button"
|
|
411
412
|
onPress={onPress}
|
|
412
413
|
className={classes}
|
|
413
|
-
{...props}
|
|
414
414
|
>
|
|
415
415
|
{body}
|
|
416
416
|
</Pressable>
|
|
@@ -334,9 +334,9 @@ const GridItemRoot = forwardRef<View, GridItemProps>(
|
|
|
334
334
|
return (
|
|
335
335
|
<View
|
|
336
336
|
ref={ref}
|
|
337
|
+
{...(props as ViewProps)}
|
|
337
338
|
accessibilityState={{ disabled: !!disabled }}
|
|
338
339
|
className={root({ className })}
|
|
339
|
-
{...(props as ViewProps)}
|
|
340
340
|
>
|
|
341
341
|
{textChildren(children)}
|
|
342
342
|
</View>
|
|
@@ -346,12 +346,12 @@ const GridItemRoot = forwardRef<View, GridItemProps>(
|
|
|
346
346
|
return (
|
|
347
347
|
<AnimatedPressable
|
|
348
348
|
ref={ref}
|
|
349
|
+
{...props}
|
|
349
350
|
accessibilityRole="button"
|
|
350
351
|
accessibilityState={{ disabled: !!disabled }}
|
|
351
352
|
disabled={disabled}
|
|
352
353
|
onPress={onPress}
|
|
353
354
|
className={root({ className })}
|
|
354
|
-
{...props}
|
|
355
355
|
>
|
|
356
356
|
{textChildren(children)}
|
|
357
357
|
</AnimatedPressable>
|
|
@@ -628,7 +628,13 @@ const HeatmapChartRoot = forwardRef<View, HeatmapChartProps>(function HeatmapCha
|
|
|
628
628
|
<Svg width={grid.width} height={grid.height} style={StyleSheet.absoluteFill}>
|
|
629
629
|
<Defs>
|
|
630
630
|
<ClipPath id={clipId}>
|
|
631
|
-
<AnimatedRect
|
|
631
|
+
<AnimatedRect
|
|
632
|
+
x={0}
|
|
633
|
+
y={0}
|
|
634
|
+
width={grid.width}
|
|
635
|
+
height={grid.height}
|
|
636
|
+
animatedProps={clipProps}
|
|
637
|
+
/>
|
|
632
638
|
</ClipPath>
|
|
633
639
|
</Defs>
|
|
634
640
|
<G clipPath={`url(#${clipId})`}>
|
|
@@ -534,7 +534,13 @@ const HexChartRoot = forwardRef<HexChartHandle, HexChartProps>(function HexChart
|
|
|
534
534
|
animatedProps={ellipseProps}
|
|
535
535
|
/>
|
|
536
536
|
) : (
|
|
537
|
-
<AnimatedRect
|
|
537
|
+
<AnimatedRect
|
|
538
|
+
x={0}
|
|
539
|
+
y={0}
|
|
540
|
+
width={width}
|
|
541
|
+
height={height}
|
|
542
|
+
animatedProps={rectProps}
|
|
543
|
+
/>
|
|
538
544
|
)}
|
|
539
545
|
</ClipPath>
|
|
540
546
|
</Defs>
|
|
@@ -59,6 +59,7 @@ import { IconColorProvider } from '../../icons';
|
|
|
59
59
|
import { KeyboardAvoider } from '../../primitives/keyboard-avoider';
|
|
60
60
|
import { Text, textChildren } from '../../primitives/text';
|
|
61
61
|
import { Label } from '../label';
|
|
62
|
+
import { inputContentPadding } from './input-content-padding';
|
|
62
63
|
|
|
63
64
|
/** Long enough to read as a transition, short enough not to lag a fast tab. */
|
|
64
65
|
const FOCUS_DURATION = 150;
|
|
@@ -303,6 +304,9 @@ export const Input = forwardRef<TextInput, InputProps>(
|
|
|
303
304
|
setEndWidth(event.nativeEvent.layout.width);
|
|
304
305
|
}, []);
|
|
305
306
|
|
|
307
|
+
const startPadding = inputContentPadding(startWidth, !!startContent);
|
|
308
|
+
const endPadding = inputContentPadding(endWidth, !!endContent);
|
|
309
|
+
|
|
306
310
|
/*
|
|
307
311
|
* The content is quieter than the value. An icon at the same weight as the
|
|
308
312
|
* text reads as part of what was typed, and the placeholder colour is
|
|
@@ -325,8 +329,8 @@ export const Input = forwardRef<TextInput, InputProps>(
|
|
|
325
329
|
borderStyle,
|
|
326
330
|
// Only the side that has content, and only once it has been
|
|
327
331
|
// measured — a 0 here would wipe out the field's own padding.
|
|
328
|
-
|
|
329
|
-
|
|
332
|
+
startPadding ? { paddingStart: startPadding } : null,
|
|
333
|
+
endPadding ? { paddingEnd: endPadding } : null,
|
|
330
334
|
// Caller styles come last so InputGroup can pad the field around its
|
|
331
335
|
// decorators, but never last enough to drop the animated border.
|
|
332
336
|
style,
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
useCallback,
|
|
12
12
|
useContext,
|
|
13
13
|
useMemo,
|
|
14
|
-
useState,
|
|
15
14
|
type ReactNode,
|
|
16
15
|
} from 'react';
|
|
17
16
|
import {
|
|
@@ -23,6 +22,12 @@ import {
|
|
|
23
22
|
import { tv } from 'tailwind-variants';
|
|
24
23
|
import { Input, type InputProps } from '../input';
|
|
25
24
|
import { textChildren } from '../../primitives/text';
|
|
25
|
+
import {
|
|
26
|
+
useInputGroupDecoratorMeasurement,
|
|
27
|
+
useInputGroupMeasurements,
|
|
28
|
+
type InputGroupDecoratorOwner,
|
|
29
|
+
type InputGroupDecoratorSide,
|
|
30
|
+
} from './input-group-measurements';
|
|
26
31
|
|
|
27
32
|
const inputGroupVariants = tv({
|
|
28
33
|
slots: {
|
|
@@ -41,8 +46,15 @@ interface InputGroupState {
|
|
|
41
46
|
isDisabled: boolean;
|
|
42
47
|
prefixWidth: number;
|
|
43
48
|
suffixWidth: number;
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
measureDecorator: (
|
|
50
|
+
side: InputGroupDecoratorSide,
|
|
51
|
+
owner: InputGroupDecoratorOwner,
|
|
52
|
+
width: number
|
|
53
|
+
) => void;
|
|
54
|
+
removeDecorator: (
|
|
55
|
+
side: InputGroupDecoratorSide,
|
|
56
|
+
owner: InputGroupDecoratorOwner
|
|
57
|
+
) => void;
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
const InputGroupContext = createContext<InputGroupState | null>(null);
|
|
@@ -61,12 +73,24 @@ export interface InputGroupProps extends ViewProps {
|
|
|
61
73
|
const InputGroupRoot = forwardRef<View, InputGroupProps>(
|
|
62
74
|
({ className, isDisabled = false, children, ...props }, ref) => {
|
|
63
75
|
const { root } = inputGroupVariants();
|
|
64
|
-
const
|
|
65
|
-
|
|
76
|
+
const { prefixWidth, suffixWidth, measureDecorator, removeDecorator } =
|
|
77
|
+
useInputGroupMeasurements();
|
|
66
78
|
|
|
67
79
|
const value = useMemo<InputGroupState>(
|
|
68
|
-
() => ({
|
|
69
|
-
|
|
80
|
+
() => ({
|
|
81
|
+
isDisabled,
|
|
82
|
+
prefixWidth,
|
|
83
|
+
suffixWidth,
|
|
84
|
+
measureDecorator,
|
|
85
|
+
removeDecorator,
|
|
86
|
+
}),
|
|
87
|
+
[
|
|
88
|
+
isDisabled,
|
|
89
|
+
prefixWidth,
|
|
90
|
+
suffixWidth,
|
|
91
|
+
measureDecorator,
|
|
92
|
+
removeDecorator,
|
|
93
|
+
]
|
|
70
94
|
);
|
|
71
95
|
|
|
72
96
|
return (
|
|
@@ -97,14 +121,18 @@ function createDecorator(side: 'prefix' | 'suffix') {
|
|
|
97
121
|
({ className, isDecorative = false, onLayout, children, ...props }, ref) => {
|
|
98
122
|
const group = useInputGroup();
|
|
99
123
|
const slots = inputGroupVariants({ isDisabled: group?.isDisabled ?? false });
|
|
100
|
-
const
|
|
124
|
+
const measure = useInputGroupDecoratorMeasurement(
|
|
125
|
+
side,
|
|
126
|
+
group?.measureDecorator,
|
|
127
|
+
group?.removeDecorator
|
|
128
|
+
);
|
|
101
129
|
|
|
102
130
|
const handleLayout = useCallback(
|
|
103
131
|
(event: LayoutChangeEvent) => {
|
|
104
|
-
|
|
132
|
+
measure(event.nativeEvent.layout.width);
|
|
105
133
|
onLayout?.(event);
|
|
106
134
|
},
|
|
107
|
-
[
|
|
135
|
+
[measure, onLayout]
|
|
108
136
|
);
|
|
109
137
|
|
|
110
138
|
return (
|
|
@@ -146,8 +174,13 @@ const InputGroupInput = forwardRef<TextInput, InputGroupInputProps>(
|
|
|
146
174
|
style={[
|
|
147
175
|
// Only override padding on the side that actually has a decorator —
|
|
148
176
|
// a 0 here would wipe out the field's default horizontal padding.
|
|
149
|
-
|
|
150
|
-
|
|
177
|
+
//
|
|
178
|
+
// `paddingStart`/`paddingEnd`, not left/right: the decorators are
|
|
179
|
+
// inset with `start-0`/`end-0`, so under `Direction dir="rtl"` Yoga
|
|
180
|
+
// moves them to the other edge. Physical padding stays where it was
|
|
181
|
+
// written and leaves the value running underneath them.
|
|
182
|
+
group?.prefixWidth ? { paddingStart: group.prefixWidth } : null,
|
|
183
|
+
group?.suffixWidth ? { paddingEnd: group.suffixWidth } : null,
|
|
151
184
|
style,
|
|
152
185
|
]}
|
|
153
186
|
{...props}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export type InputGroupDecoratorSide = 'prefix' | 'suffix';
|
|
4
|
+
export type InputGroupDecoratorOwner = symbol;
|
|
5
|
+
|
|
6
|
+
type Widths = Record<InputGroupDecoratorSide, number>;
|
|
7
|
+
type Registries = Record<
|
|
8
|
+
InputGroupDecoratorSide,
|
|
9
|
+
Map<InputGroupDecoratorOwner, number>
|
|
10
|
+
>;
|
|
11
|
+
|
|
12
|
+
export interface InputGroupMeasurements {
|
|
13
|
+
prefixWidth: number;
|
|
14
|
+
suffixWidth: number;
|
|
15
|
+
measureDecorator: (
|
|
16
|
+
side: InputGroupDecoratorSide,
|
|
17
|
+
owner: InputGroupDecoratorOwner,
|
|
18
|
+
width: number
|
|
19
|
+
) => void;
|
|
20
|
+
removeDecorator: (
|
|
21
|
+
side: InputGroupDecoratorSide,
|
|
22
|
+
owner: InputGroupDecoratorOwner
|
|
23
|
+
) => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type MeasureDecorator = InputGroupMeasurements['measureDecorator'];
|
|
27
|
+
type RemoveDecorator = InputGroupMeasurements['removeDecorator'];
|
|
28
|
+
|
|
29
|
+
const emptyWidths = (): Widths => ({ prefix: 0, suffix: 0 });
|
|
30
|
+
|
|
31
|
+
function measuredWidth(registry: Map<InputGroupDecoratorOwner, number>) {
|
|
32
|
+
let width = 0;
|
|
33
|
+
for (const candidate of registry.values()) width = Math.max(width, candidate);
|
|
34
|
+
return width;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Keeps measured padding tied to the decorators that are still mounted. */
|
|
38
|
+
export function useInputGroupMeasurements(): InputGroupMeasurements {
|
|
39
|
+
const registries = useRef<Registries>({ prefix: new Map(), suffix: new Map() });
|
|
40
|
+
const [widths, setWidths] = useState<Widths>(emptyWidths);
|
|
41
|
+
|
|
42
|
+
const commitWidth = useCallback((side: InputGroupDecoratorSide) => {
|
|
43
|
+
const width = measuredWidth(registries.current[side]);
|
|
44
|
+
setWidths((current) =>
|
|
45
|
+
current[side] === width ? current : { ...current, [side]: width }
|
|
46
|
+
);
|
|
47
|
+
}, []);
|
|
48
|
+
|
|
49
|
+
const measureDecorator = useCallback(
|
|
50
|
+
(side: InputGroupDecoratorSide, owner: InputGroupDecoratorOwner, width: number) => {
|
|
51
|
+
const registry = registries.current[side];
|
|
52
|
+
if (Number.isFinite(width) && width > 0) registry.set(owner, width);
|
|
53
|
+
else registry.delete(owner);
|
|
54
|
+
commitWidth(side);
|
|
55
|
+
},
|
|
56
|
+
[commitWidth]
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const removeDecorator = useCallback(
|
|
60
|
+
(side: InputGroupDecoratorSide, owner: InputGroupDecoratorOwner) => {
|
|
61
|
+
if (!registries.current[side].delete(owner)) return;
|
|
62
|
+
commitWidth(side);
|
|
63
|
+
},
|
|
64
|
+
[commitWidth]
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
prefixWidth: widths.prefix,
|
|
69
|
+
suffixWidth: widths.suffix,
|
|
70
|
+
measureDecorator,
|
|
71
|
+
removeDecorator,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Gives one mounted decorator an owner token and unregisters only that owner. */
|
|
76
|
+
export function useInputGroupDecoratorMeasurement(
|
|
77
|
+
side: InputGroupDecoratorSide,
|
|
78
|
+
measureDecorator: MeasureDecorator | undefined,
|
|
79
|
+
removeDecorator: RemoveDecorator | undefined
|
|
80
|
+
) {
|
|
81
|
+
const owner = useRef<InputGroupDecoratorOwner>(Symbol(side));
|
|
82
|
+
const width = useRef(0);
|
|
83
|
+
|
|
84
|
+
useLayoutEffect(() => {
|
|
85
|
+
// Re-register the last layout if React replays effects in Strict Mode or
|
|
86
|
+
// the decorator moves between InputGroup providers.
|
|
87
|
+
if (width.current > 0) measureDecorator?.(side, owner.current, width.current);
|
|
88
|
+
return () => removeDecorator?.(side, owner.current);
|
|
89
|
+
}, [measureDecorator, removeDecorator, side]);
|
|
90
|
+
|
|
91
|
+
return useCallback(
|
|
92
|
+
(nextWidth: number) => {
|
|
93
|
+
width.current = nextWidth;
|
|
94
|
+
measureDecorator?.(side, owner.current, nextWidth);
|
|
95
|
+
},
|
|
96
|
+
[measureDecorator, side]
|
|
97
|
+
);
|
|
98
|
+
}
|
|
@@ -148,21 +148,21 @@ const ItemRoot = forwardRef<View, ItemProps>(
|
|
|
148
148
|
const body = !onPress ? (
|
|
149
149
|
<View
|
|
150
150
|
ref={ref}
|
|
151
|
+
{...(props as ViewProps)}
|
|
151
152
|
accessibilityState={{ disabled: !!disabled }}
|
|
152
153
|
className={root({ className })}
|
|
153
|
-
{...(props as ViewProps)}
|
|
154
154
|
>
|
|
155
155
|
{textChildren(children)}
|
|
156
156
|
</View>
|
|
157
157
|
) : (
|
|
158
158
|
<AnimatedPressable
|
|
159
159
|
ref={ref}
|
|
160
|
+
{...props}
|
|
160
161
|
accessibilityRole="button"
|
|
161
162
|
accessibilityState={{ disabled: !!disabled }}
|
|
162
163
|
disabled={disabled}
|
|
163
164
|
onPress={onPress}
|
|
164
165
|
className={root({ className })}
|
|
165
|
-
{...props}
|
|
166
166
|
>
|
|
167
167
|
{textChildren(children)}
|
|
168
168
|
</AnimatedPressable>
|