@kanso-labs/react-native-kanso-ui 0.8.0 → 0.10.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 +4 -3
- package/dist/autocomplete/index.js +15 -1
- package/dist/autocomplete/index.js.map +1 -1
- package/dist/badge/index.js +9 -70
- package/dist/badge/index.js.map +1 -1
- package/dist/button/group.d.ts +5 -0
- package/dist/button/group.js +115 -0
- package/dist/button/group.js.map +1 -0
- package/dist/button/index.d.ts +4 -1
- package/dist/button/index.js +45 -23
- package/dist/button/index.js.map +1 -1
- package/dist/button/palettes.d.ts +2 -0
- package/dist/button/slots.js +2 -1
- package/dist/button/slots.js.map +1 -1
- package/dist/calendar/index.js +351 -182
- package/dist/calendar/index.js.map +1 -1
- package/dist/calendar/styles.js +33 -2
- package/dist/calendar/styles.js.map +1 -1
- package/dist/carousel/arrangement.d.ts +5 -0
- package/dist/carousel/arrangement.js +123 -0
- package/dist/carousel/arrangement.js.map +1 -0
- package/dist/chequer/index.js +95 -0
- package/dist/chequer/index.js.map +1 -0
- package/dist/collection/index.d.ts +157 -0
- package/dist/collection/index.js +1331 -0
- package/dist/collection/index.js.map +1 -0
- package/dist/color-thumb/index.js +56 -0
- package/dist/color-thumb/index.js.map +1 -0
- package/dist/components/badge/index.d.ts +48 -0
- package/dist/components/badge/index.js +122 -0
- package/dist/components/badge/index.js.map +1 -0
- package/dist/{badge → components/badge}/styles.js +10 -6
- package/dist/components/badge/styles.js.map +1 -0
- package/dist/components/breadcrumbs/index.d.ts +66 -0
- package/dist/components/breadcrumbs/index.js +285 -0
- package/dist/components/breadcrumbs/index.js.map +1 -0
- package/dist/components/button/index.d.ts +4 -2
- package/dist/components/button/index.js +227 -188
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/button-group/index.d.ts +87 -0
- package/dist/components/button-group/index.js +275 -0
- package/dist/components/button-group/index.js.map +1 -0
- package/dist/components/calendar/index.d.ts +11 -3
- package/dist/components/calendar/index.js +60 -45
- package/dist/components/calendar/index.js.map +1 -1
- package/dist/components/carousel/index.d.ts +72 -0
- package/dist/components/carousel/index.js +496 -0
- package/dist/components/carousel/index.js.map +1 -0
- package/dist/components/checkbox/index.d.ts +7 -1
- package/dist/components/checkbox/index.js +183 -138
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox-group/index.d.ts +92 -0
- package/dist/components/checkbox-group/index.js +306 -0
- package/dist/components/checkbox-group/index.js.map +1 -0
- package/dist/components/code/index.d.ts +25 -0
- package/dist/components/code/index.js +87 -0
- package/dist/components/code/index.js.map +1 -0
- package/dist/components/color-area/index.d.ts +85 -0
- package/dist/components/color-area/index.js +630 -0
- package/dist/components/color-area/index.js.map +1 -0
- package/dist/components/color-field/index.d.ts +144 -0
- package/dist/components/color-field/index.js +516 -0
- package/dist/components/color-field/index.js.map +1 -0
- package/dist/components/color-picker/index.d.ts +74 -0
- package/dist/components/color-picker/index.js +317 -0
- package/dist/components/color-picker/index.js.map +1 -0
- package/dist/components/color-slider/index.d.ts +82 -0
- package/dist/components/color-slider/index.js +456 -0
- package/dist/components/color-slider/index.js.map +1 -0
- package/dist/components/color-swatch/index.d.ts +46 -0
- package/dist/components/color-swatch/index.js +127 -0
- package/dist/components/color-swatch/index.js.map +1 -0
- package/dist/components/color-swatch-picker/index.d.ts +81 -0
- package/dist/components/color-swatch-picker/index.js +287 -0
- package/dist/components/color-swatch-picker/index.js.map +1 -0
- package/dist/components/color-wheel/index.d.ts +71 -0
- package/dist/components/color-wheel/index.js +407 -0
- package/dist/components/color-wheel/index.js.map +1 -0
- package/dist/components/combo-box/index.d.ts +193 -0
- package/dist/components/combo-box/index.js +616 -0
- package/dist/components/combo-box/index.js.map +1 -0
- package/dist/components/container/index.d.ts +47 -0
- package/dist/components/container/index.js +85 -0
- package/dist/components/container/index.js.map +1 -0
- package/dist/components/date-field/index.d.ts +120 -0
- package/dist/components/date-field/index.js +111 -0
- package/dist/components/date-field/index.js.map +1 -0
- package/dist/components/date-picker/index.d.ts +130 -0
- package/dist/components/date-picker/index.js +310 -0
- package/dist/components/date-picker/index.js.map +1 -0
- package/dist/components/date-range-picker/index.d.ts +139 -0
- package/dist/components/date-range-picker/index.js +421 -0
- package/dist/components/date-range-picker/index.js.map +1 -0
- package/dist/components/disclosure/index.d.ts +94 -0
- package/dist/components/disclosure/index.js +365 -0
- package/dist/components/disclosure/index.js.map +1 -0
- package/dist/components/disclosure-group/index.d.ts +61 -0
- package/dist/components/disclosure-group/index.js +100 -0
- package/dist/components/disclosure-group/index.js.map +1 -0
- package/dist/components/drop-zone/index.d.ts +113 -0
- package/dist/components/drop-zone/index.js +304 -0
- package/dist/components/drop-zone/index.js.map +1 -0
- package/dist/components/fab/index.d.ts +80 -0
- package/dist/components/fab/index.js +246 -0
- package/dist/components/fab/index.js.map +1 -0
- package/dist/components/fab-menu/index.d.ts +120 -0
- package/dist/components/fab-menu/index.js +640 -0
- package/dist/components/fab-menu/index.js.map +1 -0
- package/dist/components/feed/index.d.ts +57 -0
- package/dist/components/feed/index.js +167 -0
- package/dist/components/feed/index.js.map +1 -0
- package/dist/components/form/index.d.ts +3 -2
- package/dist/components/form/index.js.map +1 -1
- package/dist/components/icon-button/index.d.ts +4 -2
- package/dist/components/icon-button/index.js +204 -171
- package/dist/components/icon-button/index.js.map +1 -1
- package/dist/components/keycap/index.d.ts +27 -0
- package/dist/components/keycap/index.js +136 -0
- package/dist/components/keycap/index.js.map +1 -0
- package/dist/components/list/index.d.ts +15 -158
- package/dist/components/list/index.js +21 -1047
- package/dist/components/list/index.js.map +1 -1
- package/dist/components/list-box/index.d.ts +73 -0
- package/dist/components/list-box/index.js +82 -0
- package/dist/components/list-box/index.js.map +1 -0
- package/dist/components/loading-indicator/index.d.ts +32 -0
- package/dist/components/loading-indicator/index.js +174 -0
- package/dist/components/loading-indicator/index.js.map +1 -0
- package/dist/components/menu/index.js +1 -1
- package/dist/components/navigation-tree/index.d.ts +117 -0
- package/dist/components/navigation-tree/index.js +135 -0
- package/dist/components/navigation-tree/index.js.map +1 -0
- package/dist/components/number-field/index.js +132 -143
- package/dist/components/number-field/index.js.map +1 -1
- package/dist/components/range-calendar/index.d.ts +69 -0
- package/dist/components/range-calendar/index.js +144 -0
- package/dist/components/range-calendar/index.js.map +1 -0
- package/dist/components/search-view/index.d.ts +78 -0
- package/dist/components/search-view/index.js +570 -0
- package/dist/components/search-view/index.js.map +1 -0
- package/dist/components/select/index.d.ts +152 -0
- package/dist/components/select/index.js +419 -0
- package/dist/components/select/index.js.map +1 -0
- package/dist/components/separator/index.d.ts +3 -2
- package/dist/components/separator/index.js +29 -26
- package/dist/components/separator/index.js.map +1 -1
- package/dist/components/slider/index.d.ts +111 -0
- package/dist/components/slider/index.js +673 -0
- package/dist/components/slider/index.js.map +1 -0
- package/dist/components/split-button/index.d.ts +77 -0
- package/dist/components/split-button/index.js +354 -0
- package/dist/components/split-button/index.js.map +1 -0
- package/dist/components/supporting-pane/index.d.ts +44 -0
- package/dist/components/supporting-pane/index.js +109 -0
- package/dist/components/supporting-pane/index.js.map +1 -0
- package/dist/components/tabs/index.d.ts +196 -0
- package/dist/components/tabs/index.js +1137 -0
- package/dist/components/tabs/index.js.map +1 -0
- package/dist/components/text/index.d.ts +1 -1
- package/dist/components/text/index.js +49 -21
- package/dist/components/text/index.js.map +1 -1
- package/dist/components/text-area/index.d.ts +145 -0
- package/dist/components/text-area/index.js +231 -0
- package/dist/components/text-area/index.js.map +1 -0
- package/dist/components/time-field/index.d.ts +43 -0
- package/dist/components/time-field/index.js +107 -0
- package/dist/components/time-field/index.js.map +1 -0
- package/dist/components/time-picker/index.d.ts +65 -0
- package/dist/components/time-picker/index.js +1168 -0
- package/dist/components/time-picker/index.js.map +1 -0
- package/dist/components/toolbar/index.d.ts +53 -0
- package/dist/components/toolbar/index.js +185 -0
- package/dist/components/toolbar/index.js.map +1 -0
- package/dist/components/tooltip/index.d.ts +101 -0
- package/dist/components/tooltip/index.js +223 -0
- package/dist/components/tooltip/index.js.map +1 -0
- package/dist/components/tree/index.d.ts +112 -0
- package/dist/components/tree/index.js +157 -0
- package/dist/components/tree/index.js.map +1 -0
- package/dist/control/group.js +23 -0
- package/dist/control/group.js.map +1 -0
- package/dist/disclosure/chevron.js +75 -0
- package/dist/disclosure/chevron.js.map +1 -0
- package/dist/disclosure/index.js +7 -0
- package/dist/disclosure/index.js.map +1 -0
- package/dist/drop/index.d.ts +54 -0
- package/dist/drop/index.js +161 -0
- package/dist/drop/index.js.map +1 -0
- package/dist/fab/index.d.ts +19 -0
- package/dist/fab/index.js +147 -0
- package/dist/fab/index.js.map +1 -0
- package/dist/field/chevron.js +74 -0
- package/dist/field/chevron.js.map +1 -0
- package/dist/field/index.d.ts +2 -1
- package/dist/field/index.js +350 -153
- package/dist/field/index.js.map +1 -1
- package/dist/field/styles.js +27 -0
- package/dist/field/styles.js.map +1 -1
- package/dist/files/index.d.ts +18 -0
- package/dist/files/index.js +107 -0
- package/dist/files/index.js.map +1 -0
- package/dist/form/index.d.ts +6 -4
- package/dist/form/index.js +64 -85
- package/dist/form/index.js.map +1 -1
- package/dist/glyphs/index.js +92 -1
- package/dist/glyphs/index.js.map +1 -1
- package/dist/i18n/index.js +20 -1
- package/dist/i18n/index.js.map +1 -1
- package/dist/i18n/messages.js +1394 -34
- package/dist/i18n/messages.js.map +1 -1
- package/dist/index.d.ts +51 -6
- package/dist/index.js +47 -4
- package/dist/indicator/paths.js +23 -1
- package/dist/indicator/paths.js.map +1 -1
- package/dist/modal/index.js +96 -68
- package/dist/modal/index.js.map +1 -1
- package/dist/navigation/index.js +8 -5
- package/dist/navigation/index.js.map +1 -1
- package/dist/number/keyboard.js +16 -0
- package/dist/number/keyboard.js.map +1 -0
- package/dist/overlay/anchored.js +68 -38
- package/dist/overlay/anchored.js.map +1 -1
- package/dist/overlay/keyboard.js +57 -0
- package/dist/overlay/keyboard.js.map +1 -0
- package/dist/overlay/panel.js +173 -19
- package/dist/overlay/panel.js.map +1 -1
- package/dist/overlay/placement.js +16 -2
- package/dist/overlay/placement.js.map +1 -1
- package/dist/picker/index.js +322 -0
- package/dist/picker/index.js.map +1 -0
- package/dist/press/index.d.ts +2 -0
- package/dist/press/index.js +102 -100
- package/dist/press/index.js.map +1 -1
- package/dist/row/index.js +77 -69
- package/dist/row/index.js.map +1 -1
- package/dist/row/styles.js +13 -2
- package/dist/row/styles.js.map +1 -1
- package/dist/segments/field.js +277 -0
- package/dist/segments/field.js.map +1 -0
- package/dist/segments/index.js +574 -0
- package/dist/segments/index.js.map +1 -0
- package/dist/segments/styles.js +24 -0
- package/dist/segments/styles.js.map +1 -0
- package/dist/separator/index.js +7 -0
- package/dist/separator/index.js.map +1 -0
- package/dist/slider/index.js +145 -0
- package/dist/slider/index.js.map +1 -0
- package/dist/swatch/index.js +56 -0
- package/dist/swatch/index.js.map +1 -0
- package/dist/typography/size.js +14 -0
- package/dist/typography/size.js.map +1 -0
- package/package.json +11 -2
- package/dist/badge/styles.js.map +0 -1
package/dist/navigation/index.js
CHANGED
|
@@ -4,8 +4,9 @@ import { composeStyles } from "../theme/styles.js";
|
|
|
4
4
|
import { hitSlop, usePressFeedback } from "../press/index.js";
|
|
5
5
|
import { useTypeRole } from "../typography/roles.js";
|
|
6
6
|
import { withOpacity } from "../theme/color.js";
|
|
7
|
+
import { BadgeInFlowContext } from "../badge/index.js";
|
|
8
|
+
import { Badge } from "../components/badge/index.js";
|
|
7
9
|
import { useLinkPress } from "../router/index.js";
|
|
8
|
-
import { Badge } from "../badge/index.js";
|
|
9
10
|
import { INDICATOR, styles, stylesOf } from "./styles.js";
|
|
10
11
|
import { c } from "react/compiler-runtime";
|
|
11
12
|
import { Pressable, Text, View } from "react-native";
|
|
@@ -123,10 +124,12 @@ function DestinationContent(t0) {
|
|
|
123
124
|
} else t2 = $[9];
|
|
124
125
|
let t3;
|
|
125
126
|
if ($[10] !== badge || $[11] !== beside || $[12] !== icon) {
|
|
126
|
-
t3 = badge === void 0 || badge === false ? icon : /* @__PURE__ */ jsx(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
t3 = badge === void 0 || badge === false ? icon : /* @__PURE__ */ jsx(BadgeInFlowContext, {
|
|
128
|
+
value: beside,
|
|
129
|
+
children: /* @__PURE__ */ jsx(Badge, {
|
|
130
|
+
count: badge === true ? void 0 : badge,
|
|
131
|
+
children: icon
|
|
132
|
+
})
|
|
130
133
|
});
|
|
131
134
|
$[10] = badge;
|
|
132
135
|
$[11] = beside;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","ColorValue","PressableProps","StyleProp","TextStyle","ViewStyle","AnimatedStyle","createContext","use","useEffect","Text","NativeText","Pressable","View","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","IconStyle","ResolvedTheme","Badge","IconStyleContext","hitSlop","usePressFeedback","useLinkPress","withOpacity","useTheme","composeStyles","useTypeRole","INDICATOR","PILL_HEIGHT","styles","stylesOf","NavigationContextValue","form","NavigationForm","measuring","selectedRoute","NavigationDestinationProps","Omit","badge","children","icon","isDisabled","ref","style","NavigationItemProps","href","GROWN_FROM","FADE_SHARE","ICON_SIZE","BESIDE","Readonly","Record","collapsed","expanded","horizontal","vertical","NavigationContext","ActiveIndicator","t0","$","_c","selected","theme","colors","motion","reduceMotion","progress","t1","t2","target","set","duration","durationLong2","easing","bezier","easingEmphasized","motionStyle","grown","get","opacity","Math","min","transform","scaleX","t3","secondaryContainer","fill","pill","backgroundColor","t4","DestinationContent","label","beside","iconStyleOf","iconColorOf","undefined","t5","stateLayerOpacity","onSurface","disabledContent","onSecondaryContainer","onSurfaceVariant","color","size","Label","role","labelColorOf","secondary","nameOf","NavigationDestination","ariaLabel","onBlur","onFocus","onHoverIn","onHoverOut","onPressIn","onPressOut","props","own","feedback","area","corners","disabled","content","handlers","ring","layer","T0","t6","t7","T1","t8","indicator","t9","t10","t11","NavigationItem","onPress","press","_c","NativeText"],"sources":["../../src/navigation/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type {\n ColorValue,\n PressableProps,\n StyleProp,\n TextStyle,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle } from 'react-native-reanimated'\n\nimport { createContext, use, useEffect } from 'react'\nimport { Text as NativeText, Pressable, View } from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\n\nimport type { IconStyle } from '../glyphs/icon-style'\nimport type { ResolvedTheme } from '../theme/scope'\n\nimport { Badge } from '../badge'\nimport { IconStyleContext } from '../glyphs/icon-style'\nimport { hitSlop, usePressFeedback } from '../press'\nimport { useLinkPress } from '../router'\nimport { withOpacity } from '../theme/color'\nimport { useTheme } from '../theme/scope'\nimport { composeStyles } from '../theme/styles'\nimport { useTypeRole } from '../typography/roles'\nimport { INDICATOR, PILL_HEIGHT, styles, stylesOf } from './styles'\n\n// The destination NavigationBar and NavigationRail both draw, in the four\n// forms their pages give it, as kanso-ui's src/navigation draws it. Apart\n// from either component, so the two cannot drift.\n//\n// A vertical destination puts its icon in the page's 56dp by 32dp active\n// indicator with the label 4dp under it, in label medium: the bar in a\n// compact window, sharing its width with the others, and the collapsed rail,\n// as wide as the rail. A horizontal one is a pill holding the icon and the\n// label side by side, 16dp in at either end: the bar from the medium window\n// size class at 40dp with 4dp between the two in label medium, and the\n// expanded rail at 56dp with 8dp between them in label large. Which form a\n// destination draws is its bar's or its rail's to say, through the context\n// it hands them.\n//\n// The current destination's indicator is the secondary container, with its\n// icon in on secondary container and, under the indicator, its label in\n// secondary; every other is on surface variant. A label set inside the pill,\n// as a horizontal destination sets it, takes on secondary container instead,\n// as on web: secondary over secondary container is not a pair a scheme is\n// held to, and on secondary container is.\n//\n// **The indicator grows** when its destination becomes current, and shrinks\n// back when another does: from 40% of its width to the whole of it from its\n// centre over `durationLong2` on the emphasized curve, fading in over the\n// first fifth of that, as Material's Android components draw it. Web draws it\n// at once. Under reduced motion it does here too.\n//\n// The state layer, the ripple and the focus ring are src/press's, in on\n// secondary container, drawn on the pill: the indicator in a vertical\n// destination, which its ripple grows from the centre of wherever it is\n// pressed, and the whole destination in a horizontal one. The bar's 40dp\n// pill's press reaches 4dp above and below it, to the 48dp target; a\n// vertical destination is the bar's full height already, and the other two\n// forms are 56dp and 64dp tall. A disabled one draws its icon\n// and label on surface at the disabled content opacity, with no layer.\n//\n// A destination is a `tab`, reporting whether it is the selected one, and is\n// named by its label, or by `aria-label` where that is given: the badge on\n// its icon is hidden from a screen reader, so what it says belongs there.\n//\n// **The label comes first in the tree and is drawn after the icon**, through\n// a reversed column or row, so the text inside a destination starts with its\n// name. A badge's count is text, hidden from a screen reader but still\n// written inside the destination under React Native Web, and first in the\n// tree it put the count ahead of the name: a destination named \"Second item,\n// 3 new\" read \"3 Second item\", which is not what a speech-input user would\n// say, and is what axe's label-in-name check fails. src/badge sets the count\n// apart from the label with a space for the same reason.\n\n/** What a bar hands each of its destinations. */\ntype NavigationContextValue = {\n readonly form: NavigationForm\n /**\n * Whether the destinations are being drawn off screen to measure the\n * horizontal form, which draws each one's content and nothing else.\n */\n readonly measuring: boolean\n /** The route of the current destination, matched against an `href`. */\n readonly selectedRoute?: string | undefined\n}\n\ntype NavigationDestinationProps = Omit<\n PressableProps,\n 'children' | 'disabled' | 'style'\n> & {\n /**\n * A badge on the icon: `true` for the badges page's small dot, a number\n * for the large badge holding it. The badge is hidden from a screen\n * reader, so say what it says in the destination's `aria-label` too:\n * \"First item, 3 new\".\n */\n readonly badge?: boolean | number | undefined\n /** The destination's name, drawn as its label. */\n readonly children?: ReactNode\n /**\n * The destination's icon, at the page's 24dp, which the destination hands\n * its colour and size through `useIconStyle()`.\n */\n readonly icon?: ReactNode\n /**\n * Draws the destination disabled, and it takes no press.\n * @default false\n */\n readonly isDisabled?: boolean\n readonly ref?: Ref<ComponentRef<typeof View>>\n readonly style?: StyleProp<ViewStyle>\n}\n\n/**\n * Which form a destination draws: the bar's `vertical` and `horizontal`,\n * and the rail's `collapsed` and `expanded`. The label is under the icon in\n * the first and the third, and beside it in the other two.\n */\ntype NavigationForm = 'collapsed' | 'expanded' | 'horizontal' | 'vertical'\n\ntype NavigationItemProps = NavigationDestinationProps & {\n /**\n * Where the destination goes, through the app's router, and what the\n * `selectedRoute` around it is matched against.\n */\n readonly href: string\n}\n\n// The indicator's width when it starts to grow, as a share of its whole\n// width, and the share of the move it fades in over.\nconst GROWN_FROM = 0.4\nconst FADE_SHARE = 0.2\n\nconst ICON_SIZE = 24\n\n// Whether a form sets the label beside the icon rather than under it.\nconst BESIDE: Readonly<Record<NavigationForm, boolean>> = {\n collapsed: false,\n expanded: true,\n horizontal: true,\n vertical: false,\n}\n\nconst NavigationContext = createContext<NavigationContextValue>({\n form: 'vertical',\n measuring: false,\n})\n\n/**\n * The active indicator's fill, which grows from its centre while its\n * destination is current and shrinks back once it is not.\n */\nfunction ActiveIndicator({ selected }: { readonly selected: boolean }) {\n const theme = useTheme()\n const { colors, motion } = theme\n const reduceMotion = useReducedMotion()\n const progress = useSharedValue(selected ? 1 : 0)\n\n useEffect(() => {\n const target = selected ? 1 : 0\n\n progress.set(\n reduceMotion\n ? target\n : withTiming(target, {\n duration: motion.durationLong2,\n easing: Easing.bezier(...motion.easingEmphasized),\n }),\n )\n }, [motion, progress, reduceMotion, selected])\n\n const motionStyle = useAnimatedStyle(() => {\n 'worklet'\n const grown = progress.get()\n\n return {\n opacity: Math.min(1, grown / FADE_SHARE),\n transform: [{ scaleX: GROWN_FROM + (1 - GROWN_FROM) * grown }],\n }\n })\n\n return (\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.fill,\n stylesOf(theme).pill,\n { backgroundColor: colors.secondaryContainer },\n motionStyle,\n )}\n />\n )\n}\n\n/**\n * What a destination draws over its indicator: the icon and its badge, and\n * where the label is beside the icon the label before them in the tree,\n * which the pill's reversed row draws after them.\n */\nfunction DestinationContent({\n badge,\n form,\n icon,\n isDisabled,\n label,\n selected,\n}: {\n readonly badge: boolean | number | undefined\n readonly form: NavigationForm\n readonly icon: ReactNode\n readonly isDisabled: boolean\n readonly label: ReactNode\n readonly selected: boolean\n}) {\n const theme = useTheme()\n const beside = BESIDE[form]\n\n return (\n <>\n {beside ? (\n <Label form={form} isDisabled={isDisabled} selected={selected}>\n {label}\n </Label>\n ) : null}\n <View style={styles.icon}>\n <IconStyleContext\n value={iconStyleOf(iconColorOf(theme, isDisabled, selected))}\n >\n {badge === undefined || badge === false ? (\n icon\n ) : (\n <Badge count={badge === true ? undefined : badge} inFlow={beside}>\n {icon}\n </Badge>\n )}\n </IconStyleContext>\n </View>\n </>\n )\n}\n\n/** The colour a destination draws its icon in. */\nfunction iconColorOf(\n { colors, stateLayerOpacity }: ResolvedTheme,\n isDisabled: boolean,\n selected: boolean,\n): string {\n if (isDisabled) {\n return withOpacity(colors.onSurface, stateLayerOpacity.disabledContent)\n }\n return selected ? colors.onSecondaryContainer : colors.onSurfaceVariant\n}\n\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's jsx-no-new-object-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction iconStyleOf(color: ColorValue): IconStyle {\n return { color, size: ICON_SIZE }\n}\n\n/**\n * A destination's label, on one line: in label large in an expanded rail,\n * and in label medium everywhere else.\n */\nfunction Label({\n children,\n form,\n isDisabled,\n selected,\n}: {\n readonly children: ReactNode\n readonly form: NavigationForm\n readonly isDisabled: boolean\n readonly selected: boolean\n}) {\n const theme = useTheme()\n const role = useTypeRole(form === 'expanded' ? 'labelLarge' : 'labelMedium')\n\n return (\n <NativeText\n numberOfLines={1}\n style={composeStyles<TextStyle>(role, styles.label, {\n color: labelColorOf(theme, form, isDisabled, selected),\n })}\n >\n {children}\n </NativeText>\n )\n}\n\n/** The colour a destination draws its label in, which its form decides. */\nfunction labelColorOf(\n theme: ResolvedTheme,\n form: NavigationForm,\n isDisabled: boolean,\n selected: boolean,\n): string {\n return selected && !isDisabled && !BESIDE[form]\n ? theme.colors.secondary\n : iconColorOf(theme, isDisabled, selected)\n}\n\n// A label that is a string names its destination; anything else leaves the\n// name to `aria-label`.\nfunction nameOf(children: ReactNode): string | undefined {\n return typeof children === 'string' ? children : undefined\n}\n\n/**\n * One destination, in the form the bar around it asks for: an icon and a\n * label, and the active indicator behind the icon while it is current. A\n * `tab` reporting whether it is selected.\n */\nfunction NavigationDestination({\n 'aria-label': ariaLabel,\n badge,\n children,\n icon,\n isDisabled = false,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onPressIn,\n onPressOut,\n selected,\n style,\n ...props\n}: NavigationDestinationProps & { readonly selected: boolean }) {\n const theme = useTheme()\n const { form, measuring } = use(NavigationContext)\n const own = stylesOf(theme)\n const beside = BESIDE[form]\n const feedback = usePressFeedback({\n area: beside ? undefined : INDICATOR,\n color: theme.colors.onSecondaryContainer,\n corners: own.pill,\n disabled: isDisabled,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onPressIn,\n onPressOut,\n })\n const content = (\n <DestinationContent\n badge={badge}\n form={form}\n icon={icon}\n isDisabled={isDisabled}\n label={children}\n selected={selected}\n />\n )\n\n if (measuring) {\n return <View style={own.horizontal}>{content}</View>\n }\n\n if (beside) {\n return (\n <Pressable\n aria-label={ariaLabel ?? nameOf(children)}\n aria-selected={selected}\n hitSlop={form === 'horizontal' ? hitSlop(PILL_HEIGHT) : undefined}\n role=\"tab\"\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n style={composeStyles<ViewStyle>(own[form], feedback.ring, style)}\n >\n <ActiveIndicator selected={selected} />\n {feedback.layer}\n {content}\n </Pressable>\n )\n }\n\n return (\n <Pressable\n aria-label={ariaLabel ?? nameOf(children)}\n aria-selected={selected}\n role=\"tab\"\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n style={composeStyles<ViewStyle>(own[form], style)}\n >\n <Label form={form} isDisabled={isDisabled} selected={selected}>\n {children}\n </Label>\n <View style={composeStyles<ViewStyle>(own.indicator, feedback.ring)}>\n <ActiveIndicator selected={selected} />\n {feedback.layer}\n {content}\n </View>\n </Pressable>\n )\n}\n\n/**\n * A destination that goes to its `href` through the app's router, selected\n * while the `selectedRoute` around it is that `href`: the item of a bar and\n * of a rail alike.\n */\nfunction NavigationItem({ href, onPress, ...props }: NavigationItemProps) {\n const { selectedRoute } = use(NavigationContext)\n const press = useLinkPress(href, onPress)\n\n return (\n <NavigationDestination\n {...props}\n onPress={press}\n selected={selectedRoute !== undefined && href === selectedRoute}\n />\n )\n}\n\nexport type {\n NavigationContextValue,\n NavigationDestinationProps,\n NavigationForm,\n NavigationItemProps,\n}\n\nexport {\n iconColorOf,\n labelColorOf,\n NavigationContext,\n NavigationDestination,\n NavigationItem,\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","ColorValue","PressableProps","StyleProp","TextStyle","ViewStyle","AnimatedStyle","createContext","use","useEffect","Text","NativeText","Pressable","View","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","IconStyle","ResolvedTheme","BadgeInFlowContext","Badge","IconStyleContext","hitSlop","usePressFeedback","useLinkPress","withOpacity","useTheme","composeStyles","useTypeRole","INDICATOR","PILL_HEIGHT","styles","stylesOf","NavigationContextValue","form","NavigationForm","measuring","selectedRoute","NavigationDestinationProps","Omit","badge","children","icon","isDisabled","ref","style","NavigationItemProps","href","GROWN_FROM","FADE_SHARE","ICON_SIZE","BESIDE","Readonly","Record","collapsed","expanded","horizontal","vertical","NavigationContext","ActiveIndicator","t0","$","_c","selected","theme","colors","motion","reduceMotion","progress","t1","t2","target","set","duration","durationLong2","easing","bezier","easingEmphasized","motionStyle","grown","get","opacity","Math","min","transform","scaleX","t3","secondaryContainer","fill","pill","backgroundColor","t4","DestinationContent","label","beside","iconStyleOf","iconColorOf","undefined","t5","stateLayerOpacity","onSurface","disabledContent","onSecondaryContainer","onSurfaceVariant","color","size","Label","role","labelColorOf","secondary","nameOf","NavigationDestination","ariaLabel","onBlur","onFocus","onHoverIn","onHoverOut","onPressIn","onPressOut","props","own","feedback","area","corners","disabled","content","handlers","ring","layer","T0","t6","t7","T1","t8","indicator","t9","t10","t11","NavigationItem","onPress","press","_c","NativeText"],"sources":["../../src/navigation/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type {\n ColorValue,\n PressableProps,\n StyleProp,\n TextStyle,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle } from 'react-native-reanimated'\n\nimport { createContext, use, useEffect } from 'react'\nimport { Text as NativeText, Pressable, View } from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\n\nimport type { IconStyle } from '../glyphs/icon-style'\nimport type { ResolvedTheme } from '../theme/scope'\n\nimport { BadgeInFlowContext } from '../badge'\nimport { Badge } from '../components/badge'\nimport { IconStyleContext } from '../glyphs/icon-style'\nimport { hitSlop, usePressFeedback } from '../press'\nimport { useLinkPress } from '../router'\nimport { withOpacity } from '../theme/color'\nimport { useTheme } from '../theme/scope'\nimport { composeStyles } from '../theme/styles'\nimport { useTypeRole } from '../typography/roles'\nimport { INDICATOR, PILL_HEIGHT, styles, stylesOf } from './styles'\n\n// The destination NavigationBar and NavigationRail both draw, in the four\n// forms their pages give it, as kanso-ui's src/navigation draws it. Apart\n// from either component, so the two cannot drift.\n//\n// A vertical destination puts its icon in the page's 56dp by 32dp active\n// indicator with the label 4dp under it, in label medium: the bar in a\n// compact window, sharing its width with the others, and the collapsed rail,\n// as wide as the rail. A horizontal one is a pill holding the icon and the\n// label side by side, 16dp in at either end: the bar from the medium window\n// size class at 40dp with 4dp between the two in label medium, and the\n// expanded rail at 56dp with 8dp between them in label large. Which form a\n// destination draws is its bar's or its rail's to say, through the context\n// it hands them.\n//\n// The current destination's indicator is the secondary container, with its\n// icon in on secondary container and, under the indicator, its label in\n// secondary; every other is on surface variant. A label set inside the pill,\n// as a horizontal destination sets it, takes on secondary container instead,\n// as on web: secondary over secondary container is not a pair a scheme is\n// held to, and on secondary container is.\n//\n// **The indicator grows** when its destination becomes current, and shrinks\n// back when another does: from 40% of its width to the whole of it from its\n// centre over `durationLong2` on the emphasized curve, fading in over the\n// first fifth of that, as Material's Android components draw it. Web draws it\n// at once. Under reduced motion it does here too.\n//\n// The state layer, the ripple and the focus ring are src/press's, in on\n// secondary container, drawn on the pill: the indicator in a vertical\n// destination, which its ripple grows from the centre of wherever it is\n// pressed, and the whole destination in a horizontal one. The bar's 40dp\n// pill's press reaches 4dp above and below it, to the 48dp target; a\n// vertical destination is the bar's full height already, and the other two\n// forms are 56dp and 64dp tall. A disabled one draws its icon\n// and label on surface at the disabled content opacity, with no layer.\n//\n// A destination is a `tab`, reporting whether it is the selected one, and is\n// named by its label, or by `aria-label` where that is given: the badge on\n// its icon is hidden from a screen reader, so what it says belongs there.\n//\n// **The label comes first in the tree and is drawn after the icon**, through\n// a reversed column or row, so the text inside a destination starts with its\n// name. A badge's count is text, hidden from a screen reader but still\n// written inside the destination under React Native Web, and first in the\n// tree it put the count ahead of the name: a destination named \"Second item,\n// 3 new\" read \"3 Second item\", which is not what a speech-input user would\n// say, and is what axe's label-in-name check fails. src/badge sets the count\n// apart from the label with a space for the same reason.\n\n/** What a bar hands each of its destinations. */\ntype NavigationContextValue = {\n readonly form: NavigationForm\n /**\n * Whether the destinations are being drawn off screen to measure the\n * horizontal form, which draws each one's content and nothing else.\n */\n readonly measuring: boolean\n /** The route of the current destination, matched against an `href`. */\n readonly selectedRoute?: string | undefined\n}\n\ntype NavigationDestinationProps = Omit<\n PressableProps,\n 'children' | 'disabled' | 'style'\n> & {\n /**\n * A badge on the icon: `true` for the badges page's small dot, a number\n * for the large badge holding it. The badge is hidden from a screen\n * reader, so say what it says in the destination's `aria-label` too:\n * \"First item, 3 new\".\n */\n readonly badge?: boolean | number | undefined\n /** The destination's name, drawn as its label. */\n readonly children?: ReactNode\n /**\n * The destination's icon, at the page's 24dp, which the destination hands\n * its colour and size through `useIconStyle()`.\n */\n readonly icon?: ReactNode\n /**\n * Draws the destination disabled, and it takes no press.\n * @default false\n */\n readonly isDisabled?: boolean\n readonly ref?: Ref<ComponentRef<typeof View>>\n readonly style?: StyleProp<ViewStyle>\n}\n\n/**\n * Which form a destination draws: the bar's `vertical` and `horizontal`,\n * and the rail's `collapsed` and `expanded`. The label is under the icon in\n * the first and the third, and beside it in the other two.\n */\ntype NavigationForm = 'collapsed' | 'expanded' | 'horizontal' | 'vertical'\n\ntype NavigationItemProps = NavigationDestinationProps & {\n /**\n * Where the destination goes, through the app's router, and what the\n * `selectedRoute` around it is matched against.\n */\n readonly href: string\n}\n\n// The indicator's width when it starts to grow, as a share of its whole\n// width, and the share of the move it fades in over.\nconst GROWN_FROM = 0.4\nconst FADE_SHARE = 0.2\n\nconst ICON_SIZE = 24\n\n// Whether a form sets the label beside the icon rather than under it.\nconst BESIDE: Readonly<Record<NavigationForm, boolean>> = {\n collapsed: false,\n expanded: true,\n horizontal: true,\n vertical: false,\n}\n\nconst NavigationContext = createContext<NavigationContextValue>({\n form: 'vertical',\n measuring: false,\n})\n\n/**\n * The active indicator's fill, which grows from its centre while its\n * destination is current and shrinks back once it is not.\n */\nfunction ActiveIndicator({ selected }: { readonly selected: boolean }) {\n const theme = useTheme()\n const { colors, motion } = theme\n const reduceMotion = useReducedMotion()\n const progress = useSharedValue(selected ? 1 : 0)\n\n useEffect(() => {\n const target = selected ? 1 : 0\n\n progress.set(\n reduceMotion\n ? target\n : withTiming(target, {\n duration: motion.durationLong2,\n easing: Easing.bezier(...motion.easingEmphasized),\n }),\n )\n }, [motion, progress, reduceMotion, selected])\n\n const motionStyle = useAnimatedStyle(() => {\n 'worklet'\n const grown = progress.get()\n\n return {\n opacity: Math.min(1, grown / FADE_SHARE),\n transform: [{ scaleX: GROWN_FROM + (1 - GROWN_FROM) * grown }],\n }\n })\n\n return (\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.fill,\n stylesOf(theme).pill,\n { backgroundColor: colors.secondaryContainer },\n motionStyle,\n )}\n />\n )\n}\n\n/**\n * What a destination draws over its indicator: the icon and its badge, and\n * where the label is beside the icon the label before them in the tree,\n * which the pill's reversed row draws after them.\n */\nfunction DestinationContent({\n badge,\n form,\n icon,\n isDisabled,\n label,\n selected,\n}: {\n readonly badge: boolean | number | undefined\n readonly form: NavigationForm\n readonly icon: ReactNode\n readonly isDisabled: boolean\n readonly label: ReactNode\n readonly selected: boolean\n}) {\n const theme = useTheme()\n const beside = BESIDE[form]\n\n return (\n <>\n {beside ? (\n <Label form={form} isDisabled={isDisabled} selected={selected}>\n {label}\n </Label>\n ) : null}\n <View style={styles.icon}>\n <IconStyleContext\n value={iconStyleOf(iconColorOf(theme, isDisabled, selected))}\n >\n {badge === undefined || badge === false ? (\n icon\n ) : (\n <BadgeInFlowContext value={beside}>\n <Badge count={badge === true ? undefined : badge}>{icon}</Badge>\n </BadgeInFlowContext>\n )}\n </IconStyleContext>\n </View>\n </>\n )\n}\n\n/** The colour a destination draws its icon in. */\nfunction iconColorOf(\n { colors, stateLayerOpacity }: ResolvedTheme,\n isDisabled: boolean,\n selected: boolean,\n): string {\n if (isDisabled) {\n return withOpacity(colors.onSurface, stateLayerOpacity.disabledContent)\n }\n return selected ? colors.onSecondaryContainer : colors.onSurfaceVariant\n}\n\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's jsx-no-new-object-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction iconStyleOf(color: ColorValue): IconStyle {\n return { color, size: ICON_SIZE }\n}\n\n/**\n * A destination's label, on one line: in label large in an expanded rail,\n * and in label medium everywhere else.\n */\nfunction Label({\n children,\n form,\n isDisabled,\n selected,\n}: {\n readonly children: ReactNode\n readonly form: NavigationForm\n readonly isDisabled: boolean\n readonly selected: boolean\n}) {\n const theme = useTheme()\n const role = useTypeRole(form === 'expanded' ? 'labelLarge' : 'labelMedium')\n\n return (\n <NativeText\n numberOfLines={1}\n style={composeStyles<TextStyle>(role, styles.label, {\n color: labelColorOf(theme, form, isDisabled, selected),\n })}\n >\n {children}\n </NativeText>\n )\n}\n\n/** The colour a destination draws its label in, which its form decides. */\nfunction labelColorOf(\n theme: ResolvedTheme,\n form: NavigationForm,\n isDisabled: boolean,\n selected: boolean,\n): string {\n return selected && !isDisabled && !BESIDE[form]\n ? theme.colors.secondary\n : iconColorOf(theme, isDisabled, selected)\n}\n\n// A label that is a string names its destination; anything else leaves the\n// name to `aria-label`.\nfunction nameOf(children: ReactNode): string | undefined {\n return typeof children === 'string' ? children : undefined\n}\n\n/**\n * One destination, in the form the bar around it asks for: an icon and a\n * label, and the active indicator behind the icon while it is current. A\n * `tab` reporting whether it is selected.\n */\nfunction NavigationDestination({\n 'aria-label': ariaLabel,\n badge,\n children,\n icon,\n isDisabled = false,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onPressIn,\n onPressOut,\n selected,\n style,\n ...props\n}: NavigationDestinationProps & { readonly selected: boolean }) {\n const theme = useTheme()\n const { form, measuring } = use(NavigationContext)\n const own = stylesOf(theme)\n const beside = BESIDE[form]\n const feedback = usePressFeedback({\n area: beside ? undefined : INDICATOR,\n color: theme.colors.onSecondaryContainer,\n corners: own.pill,\n disabled: isDisabled,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onPressIn,\n onPressOut,\n })\n const content = (\n <DestinationContent\n badge={badge}\n form={form}\n icon={icon}\n isDisabled={isDisabled}\n label={children}\n selected={selected}\n />\n )\n\n if (measuring) {\n return <View style={own.horizontal}>{content}</View>\n }\n\n if (beside) {\n return (\n <Pressable\n aria-label={ariaLabel ?? nameOf(children)}\n aria-selected={selected}\n hitSlop={form === 'horizontal' ? hitSlop(PILL_HEIGHT) : undefined}\n role=\"tab\"\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n style={composeStyles<ViewStyle>(own[form], feedback.ring, style)}\n >\n <ActiveIndicator selected={selected} />\n {feedback.layer}\n {content}\n </Pressable>\n )\n }\n\n return (\n <Pressable\n aria-label={ariaLabel ?? nameOf(children)}\n aria-selected={selected}\n role=\"tab\"\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n style={composeStyles<ViewStyle>(own[form], style)}\n >\n <Label form={form} isDisabled={isDisabled} selected={selected}>\n {children}\n </Label>\n <View style={composeStyles<ViewStyle>(own.indicator, feedback.ring)}>\n <ActiveIndicator selected={selected} />\n {feedback.layer}\n {content}\n </View>\n </Pressable>\n )\n}\n\n/**\n * A destination that goes to its `href` through the app's router, selected\n * while the `selectedRoute` around it is that `href`: the item of a bar and\n * of a rail alike.\n */\nfunction NavigationItem({ href, onPress, ...props }: NavigationItemProps) {\n const { selectedRoute } = use(NavigationContext)\n const press = useLinkPress(href, onPress)\n\n return (\n <NavigationDestination\n {...props}\n onPress={press}\n selected={selectedRoute !== undefined && href === selectedRoute}\n />\n )\n}\n\nexport type {\n NavigationContextValue,\n NavigationDestinationProps,\n NavigationForm,\n NavigationItemProps,\n}\n\nexport {\n iconColorOf,\n labelColorOf,\n NavigationContext,\n NavigationDestination,\n NavigationItem,\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
2
|
+
import { NumberFormatter } from "@internationalized/number";
|
|
3
|
+
//#region src/number/keyboard.ts
|
|
4
|
+
/**
|
|
5
|
+
* The keyboard for a number written in `locale` and `formatOptions`, from
|
|
6
|
+
* `minValue` up: one with a minus where the range reaches below zero, and a
|
|
7
|
+
* decimal separator where the format shows a fraction.
|
|
8
|
+
*/
|
|
9
|
+
function keyboardFor(locale, formatOptions, minValue) {
|
|
10
|
+
if (minValue === void 0 || Number.isNaN(minValue) || minValue < 0) return Platform.OS === "ios" ? "numbers-and-punctuation" : "numeric";
|
|
11
|
+
return (new NumberFormatter(locale, formatOptions).resolvedOptions().maximumFractionDigits ?? 0) > 0 ? "decimal-pad" : "number-pad";
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { keyboardFor };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=keyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.js","names":["NumberFormatOptions","KeyboardTypeOptions","NumberFormatter","Platform","keyboardFor","locale","formatOptions","minValue","hasNegative","undefined","Number","isNaN","OS","hasDecimals","resolvedOptions","maximumFractionDigits"],"sources":["../../src/number/keyboard.ts"],"sourcesContent":["import type { NumberFormatOptions } from '@internationalized/number'\nimport type { KeyboardTypeOptions } from 'react-native'\n\nimport { NumberFormatter } from '@internationalized/number'\nimport { Platform } from 'react-native'\n\n// The keyboard that types what a field holding a number takes, NumberField's\n// and a ColorField's holding a channel: React Aria's own choice of input\n// mode, in React Native's keyboards. A minus where the range reaches below\n// zero, and a decimal separator where the format shows a fraction. On iOS a\n// minus is on the numbers and punctuation keyboard alone, so a field that\n// takes one gets that.\n\n/**\n * The keyboard for a number written in `locale` and `formatOptions`, from\n * `minValue` up: one with a minus where the range reaches below zero, and a\n * decimal separator where the format shows a fraction.\n */\nfunction keyboardFor(\n locale: string,\n formatOptions: NumberFormatOptions | undefined,\n minValue: number | undefined,\n): KeyboardTypeOptions {\n const hasNegative =\n minValue === undefined || Number.isNaN(minValue) || minValue < 0\n\n if (hasNegative) {\n return Platform.OS === 'ios' ? 'numbers-and-punctuation' : 'numeric'\n }\n\n const hasDecimals =\n (new NumberFormatter(locale, formatOptions).resolvedOptions()\n .maximumFractionDigits ?? 0) > 0\n\n return hasDecimals ? 'decimal-pad' : 'number-pad'\n}\n\nexport { keyboardFor }\n"],"mappings":";;;;;;;;AAkBA,SAASI,YACPC,QACAC,eACAC,UACqB;CAIrB,IAFEA,aAAaE,KAAAA,KAAaC,OAAOC,MAAMJ,QAAQ,KAAKA,WAAW,GAG/D,OAAOJ,SAASS,OAAO,QAAQ,4BAA4B;CAO7D,QAHG,IAAIV,gBAAgBG,QAAQC,aAAa,CAAC,CAACQ,gBAAgB,CAAC,CAC1DC,yBAAyB,KAAK,IAEd,gBAAgB;AACvC"}
|
package/dist/overlay/anchored.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useTheme } from "../theme/scope.js";
|
|
2
2
|
import { OverlayHostContext } from "./host.js";
|
|
3
|
-
import {
|
|
3
|
+
import { useKeyboardTop, watchKeyboard } from "./keyboard.js";
|
|
4
|
+
import { aboveKeyboard, boundsOf, place } from "./placement.js";
|
|
4
5
|
import { c } from "react/compiler-runtime";
|
|
5
6
|
import { Dimensions, I18nManager, useWindowDimensions } from "react-native";
|
|
6
7
|
import { SafeAreaInsetsContext } from "react-native-safe-area-context";
|
|
@@ -24,14 +25,15 @@ const NO_INSETS = {
|
|
|
24
25
|
* web's anchored overlays are placed: on `side`, lined up by `align`, flipped
|
|
25
26
|
* to the opposite side at the edge of the window, and kept inside the safe
|
|
26
27
|
* area's insets with `spacing.md` to spare, the padding React Aria keeps from
|
|
27
|
-
* the edge of the viewport.
|
|
28
|
-
*
|
|
28
|
+
* the edge of the viewport. The software keyboard is an edge too while it is
|
|
29
|
+
* shown, so a list opened from a field being typed in stays above the keys.
|
|
30
|
+
* On `top` and `bottom`, `start` and `end` follow `I18nManager.isRTL`.
|
|
29
31
|
*
|
|
30
32
|
* The anchor is measured with `measureInWindow` whenever the surface reports
|
|
31
|
-
* a new size
|
|
33
|
+
* a new size, the window changes size or the keyboard moves.
|
|
32
34
|
*/
|
|
33
35
|
function useAnchoredPlacement(t0) {
|
|
34
|
-
const $ = c(
|
|
36
|
+
const $ = c(39);
|
|
35
37
|
const { align: t1, alignOffset: t2, anchor, side: t3, sideOffset } = t0;
|
|
36
38
|
const align = t1 === void 0 ? "center" : t1;
|
|
37
39
|
const alignOffset = t2 === void 0 ? 0 : t2;
|
|
@@ -40,6 +42,7 @@ function useAnchoredPlacement(t0) {
|
|
|
40
42
|
const { spacing } = useTheme();
|
|
41
43
|
const window = useWindowDimensions();
|
|
42
44
|
const insets = use(SafeAreaInsetsContext) ?? NO_INSETS;
|
|
45
|
+
const keyboardTop = useKeyboardTop();
|
|
43
46
|
const [measured, setMeasured] = useState(null);
|
|
44
47
|
const [surface, setSurface] = useState(null);
|
|
45
48
|
let t4;
|
|
@@ -68,8 +71,12 @@ function useAnchoredPlacement(t0) {
|
|
|
68
71
|
};
|
|
69
72
|
measure();
|
|
70
73
|
const subscription = Dimensions.addEventListener("change", measure);
|
|
74
|
+
const unwatch = watchKeyboard(() => {
|
|
75
|
+
measure();
|
|
76
|
+
});
|
|
71
77
|
return () => {
|
|
72
78
|
subscription.remove();
|
|
79
|
+
unwatch();
|
|
73
80
|
};
|
|
74
81
|
};
|
|
75
82
|
$[0] = anchor.current;
|
|
@@ -106,6 +113,8 @@ function useAnchoredPlacement(t0) {
|
|
|
106
113
|
let t7;
|
|
107
114
|
if ($[9] !== side) {
|
|
108
115
|
t7 = {
|
|
116
|
+
anchorFrame: void 0,
|
|
117
|
+
anchorWidth: void 0,
|
|
109
118
|
onLayout,
|
|
110
119
|
placed: false,
|
|
111
120
|
side,
|
|
@@ -117,12 +126,12 @@ function useAnchoredPlacement(t0) {
|
|
|
117
126
|
return t7;
|
|
118
127
|
}
|
|
119
128
|
let t7;
|
|
120
|
-
if ($[11] !== align || $[12] !== alignOffset || $[13] !== insets || $[14] !== measured.anchor || $[
|
|
129
|
+
if ($[11] !== align || $[12] !== alignOffset || $[13] !== insets || $[14] !== keyboardTop || $[15] !== measured.anchor || $[16] !== side || $[17] !== sideOffset || $[18] !== spacing.md || $[19] !== spacing.sm || $[20] !== surface || $[21] !== window) {
|
|
121
130
|
t7 = place({
|
|
122
131
|
align,
|
|
123
132
|
alignOffset,
|
|
124
133
|
anchor: measured.anchor,
|
|
125
|
-
bounds: boundsOf(window, insets, spacing.md),
|
|
134
|
+
bounds: aboveKeyboard(boundsOf(window, insets, spacing.md), keyboardTop, spacing.md),
|
|
126
135
|
rtl: I18nManager.isRTL,
|
|
127
136
|
side,
|
|
128
137
|
sideOffset: sideOffset ?? spacing.sm,
|
|
@@ -131,50 +140,71 @@ function useAnchoredPlacement(t0) {
|
|
|
131
140
|
$[11] = align;
|
|
132
141
|
$[12] = alignOffset;
|
|
133
142
|
$[13] = insets;
|
|
134
|
-
$[14] =
|
|
135
|
-
$[15] =
|
|
136
|
-
$[16] =
|
|
137
|
-
$[17] =
|
|
138
|
-
$[18] = spacing.
|
|
139
|
-
$[19] =
|
|
140
|
-
$[20] =
|
|
141
|
-
$[21] =
|
|
142
|
-
|
|
143
|
+
$[14] = keyboardTop;
|
|
144
|
+
$[15] = measured.anchor;
|
|
145
|
+
$[16] = side;
|
|
146
|
+
$[17] = sideOffset;
|
|
147
|
+
$[18] = spacing.md;
|
|
148
|
+
$[19] = spacing.sm;
|
|
149
|
+
$[20] = surface;
|
|
150
|
+
$[21] = window;
|
|
151
|
+
$[22] = t7;
|
|
152
|
+
} else t7 = $[22];
|
|
143
153
|
const placement = t7;
|
|
144
154
|
const x_0 = placement.x - measured.origin.x;
|
|
145
|
-
const t8 =
|
|
146
|
-
|
|
147
|
-
if ($[22] !== x_0) {
|
|
148
|
-
t9 = I18nManager.isRTL && I18nManager.doLeftAndRightSwapInRTL ? { right: x_0 } : { left: x_0 };
|
|
149
|
-
$[22] = x_0;
|
|
150
|
-
$[23] = t9;
|
|
151
|
-
} else t9 = $[23];
|
|
155
|
+
const t8 = measured.anchor.x - measured.origin.x;
|
|
156
|
+
const t9 = measured.anchor.y - measured.origin.y;
|
|
152
157
|
let t10;
|
|
153
|
-
if ($[24] !==
|
|
158
|
+
if ($[23] !== measured.anchor.height || $[24] !== measured.anchor.width || $[25] !== t8 || $[26] !== t9) {
|
|
154
159
|
t10 = {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
height: measured.anchor.height,
|
|
161
|
+
width: measured.anchor.width,
|
|
162
|
+
x: t8,
|
|
163
|
+
y: t9
|
|
159
164
|
};
|
|
160
|
-
$[
|
|
165
|
+
$[23] = measured.anchor.height;
|
|
166
|
+
$[24] = measured.anchor.width;
|
|
161
167
|
$[25] = t8;
|
|
162
168
|
$[26] = t9;
|
|
163
169
|
$[27] = t10;
|
|
164
170
|
} else t10 = $[27];
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
171
|
+
const t11 = placement.y - measured.origin.y;
|
|
172
|
+
let t12;
|
|
173
|
+
if ($[28] !== x_0) {
|
|
174
|
+
t12 = I18nManager.isRTL && I18nManager.doLeftAndRightSwapInRTL ? { right: x_0 } : { left: x_0 };
|
|
175
|
+
$[28] = x_0;
|
|
176
|
+
$[29] = t12;
|
|
177
|
+
} else t12 = $[29];
|
|
178
|
+
let t13;
|
|
179
|
+
if ($[30] !== placement.maxHeight || $[31] !== t11 || $[32] !== t12) {
|
|
180
|
+
t13 = {
|
|
181
|
+
maxHeight: placement.maxHeight,
|
|
182
|
+
position: "absolute",
|
|
183
|
+
top: t11,
|
|
184
|
+
...t12
|
|
185
|
+
};
|
|
186
|
+
$[30] = placement.maxHeight;
|
|
187
|
+
$[31] = t11;
|
|
188
|
+
$[32] = t12;
|
|
189
|
+
$[33] = t13;
|
|
190
|
+
} else t13 = $[33];
|
|
191
|
+
let t14;
|
|
192
|
+
if ($[34] !== measured.anchor.width || $[35] !== placement.side || $[36] !== t10 || $[37] !== t13) {
|
|
193
|
+
t14 = {
|
|
194
|
+
anchorFrame: t10,
|
|
195
|
+
anchorWidth: measured.anchor.width,
|
|
168
196
|
onLayout,
|
|
169
197
|
placed: true,
|
|
170
198
|
side: placement.side,
|
|
171
|
-
style:
|
|
199
|
+
style: t13
|
|
172
200
|
};
|
|
173
|
-
$[
|
|
174
|
-
$[
|
|
175
|
-
$[
|
|
176
|
-
|
|
177
|
-
|
|
201
|
+
$[34] = measured.anchor.width;
|
|
202
|
+
$[35] = placement.side;
|
|
203
|
+
$[36] = t10;
|
|
204
|
+
$[37] = t13;
|
|
205
|
+
$[38] = t14;
|
|
206
|
+
} else t14 = $[38];
|
|
207
|
+
return t14;
|
|
178
208
|
}
|
|
179
209
|
//#endregion
|
|
180
210
|
export { useAnchoredPlacement };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anchored.js","names":["RefObject","HostInstance","LayoutChangeEvent","ViewStyle","use","useEffect","useState","Dimensions","I18nManager","useWindowDimensions","SafeAreaInsetsContext","OverlayAlign","OverlaySide","Rect","Size","useTheme","OverlayHostContext","boundsOf","place","AnchoredPlacement","onLayout","event","placed","side","style","AnchoredPlacementOptions","align","alignOffset","anchor","Pick","sideOffset","Measured","origin","x","y","HIDDEN","left","opacity","pointerEvents","position","top","NO_INSETS","bottom","right","useAnchoredPlacement","t0","$","_c","t1","t2","t3","undefined","store","spacing","window","insets","measured","setMeasured","surface","setSurface","t4","current","measure","layer","target","measureInWindow","originX","originY","width","height","subscription","addEventListener","remove","t5","t6","Symbol","for","height_0","width_0","nativeEvent","layout","known","t7","md","sm","bounds","rtl","isRTL","placement","x_0","t8","t9","doLeftAndRightSwapInRTL","t10","maxHeight","t11","_c"],"sources":["../../src/overlay/anchored.ts"],"sourcesContent":["import type { RefObject } from 'react'\nimport type { HostInstance, LayoutChangeEvent, ViewStyle } from 'react-native'\n\nimport { use, useEffect, useState } from 'react'\nimport { Dimensions, I18nManager, useWindowDimensions } from 'react-native'\nimport { SafeAreaInsetsContext } from 'react-native-safe-area-context'\n\nimport type { OverlayAlign, OverlaySide, Rect, Size } from './placement'\n\nimport { useTheme } from '../theme/scope'\nimport { OverlayHostContext } from './host'\nimport { boundsOf, place } from './placement'\n\ntype AnchoredPlacement = {\n /**\n * Hand to the surface's own `onLayout`. The surface is placed once it has\n * reported its size, and placed again whenever that size changes.\n */\n readonly onLayout: (event: LayoutChangeEvent) => void\n /**\n * Whether the surface has been placed. Until it has, it is laid out out of\n * sight, and a screen reader cannot be sent to it.\n */\n readonly placed: boolean\n /** The side the surface opened on, which is the opposite one after a flip. */\n readonly side: OverlaySide\n /**\n * The surface's position in the overlay layer, and the height it may take.\n * Until it has been placed it is laid out out of sight, to be measured.\n */\n readonly style: ViewStyle\n}\n\ntype AnchoredPlacementOptions = {\n /**\n * Where the surface sits along the side it opens on.\n * @default 'center'\n */\n readonly align?: OverlayAlign | undefined\n /** Moves the surface along that side, in dp: right or down when positive. */\n readonly alignOffset?: number | undefined\n /** The view the surface opens beside. */\n readonly anchor: RefObject<null | Pick<HostInstance, 'measureInWindow'>>\n /**\n * Which side of the anchor the surface opens on. It flips to the opposite\n * side when there is no room.\n * @default 'bottom'\n */\n readonly side?: OverlaySide | undefined\n /**\n * The gap between the anchor and the surface, in dp.\n * @default spacing.sm\n */\n readonly sideOffset?: number | undefined\n}\n\ntype Measured = {\n readonly anchor: Rect\n /** Where the overlay layer starts in the window. */\n readonly origin: { readonly x: number; readonly y: number }\n}\n\nconst HIDDEN: ViewStyle = {\n left: 0,\n opacity: 0,\n pointerEvents: 'none',\n position: 'absolute',\n top: 0,\n}\n\n// Outside a SafeAreaProvider the insets are unknown, and the window's own edge\n// is the best bound there is.\nconst NO_INSETS = { bottom: 0, left: 0, right: 0, top: 0 }\n\n/**\n * Places a surface drawn in an `Overlay` beside the view that opened it, as\n * web's anchored overlays are placed: on `side`, lined up by `align`, flipped\n * to the opposite side at the edge of the window, and kept inside the safe\n * area's insets with `spacing.md` to spare, the padding React Aria keeps from\n * the edge of the viewport. On `top` and `bottom`, `start` and `end` follow\n * `I18nManager.isRTL`.\n *\n * The anchor is measured with `measureInWindow` whenever the surface reports\n * a new size or the window changes size.\n */\nfunction useAnchoredPlacement({\n align = 'center',\n alignOffset = 0,\n anchor,\n side = 'bottom',\n sideOffset,\n}: AnchoredPlacementOptions): AnchoredPlacement {\n const store = use(OverlayHostContext)\n const { spacing } = useTheme()\n const window = useWindowDimensions()\n const insets = use(SafeAreaInsetsContext) ?? NO_INSETS\n const [measured, setMeasured] = useState<Measured | null>(null)\n const [surface, setSurface] = useState<null | Size>(null)\n\n useEffect(() => {\n // The layer is measured as well as the anchor, since the host need not\n // start at the window's corner: the surface is placed in the layer, and\n // the anchor is measured in the window.\n const measure = () => {\n const layer = store?.layer() ?? null\n const target = anchor.current\n\n if (surface === null || layer === null || target === null) {\n return\n }\n\n layer.measureInWindow((originX, originY) => {\n target.measureInWindow((x, y, width, height) => {\n setMeasured({\n anchor: { height, width, x, y },\n origin: { x: originX, y: originY },\n })\n })\n })\n }\n\n measure()\n\n // A rotation or a resized window can move the anchor without the\n // surface changing size.\n const subscription = Dimensions.addEventListener('change', measure)\n\n return () => {\n subscription.remove()\n }\n }, [anchor, store, surface])\n\n const onLayout = (event: LayoutChangeEvent) => {\n const { height, width } = event.nativeEvent.layout\n\n setSurface((known) =>\n known?.height === height && known.width === width\n ? known\n : { height, width },\n )\n }\n\n if (measured === null || surface === null) {\n return { onLayout, placed: false, side, style: HIDDEN }\n }\n\n const placement = place({\n align,\n alignOffset,\n anchor: measured.anchor,\n bounds: boundsOf(window, insets, spacing.md),\n rtl: I18nManager.isRTL,\n side,\n sideOffset: sideOffset ?? spacing.sm,\n surface,\n })\n const x = placement.x - measured.origin.x\n\n return {\n onLayout,\n placed: true,\n side: placement.side,\n style: {\n maxHeight: placement.maxHeight,\n position: 'absolute',\n top: placement.y - measured.origin.y,\n // The placement is in physical coordinates, as `measureInWindow`\n // reports them. React Native swaps `left` and `right` in a right-to-left\n // layout unless an app turns that off, so there `right` is what puts\n // the surface's left edge where the placement says.\n ...(I18nManager.isRTL && I18nManager.doLeftAndRightSwapInRTL\n ? { right: x }\n : { left: x }),\n },\n }\n}\n\nexport type { AnchoredPlacement, AnchoredPlacementOptions }\n\nexport { useAnchoredPlacement }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"anchored.js","names":["RefObject","HostInstance","LayoutChangeEvent","ViewStyle","use","useEffect","useState","Dimensions","I18nManager","useWindowDimensions","SafeAreaInsetsContext","OverlayAlign","OverlaySide","Rect","Size","useTheme","OverlayHostContext","useKeyboardTop","watchKeyboard","aboveKeyboard","boundsOf","place","AnchoredPlacement","anchorFrame","anchorWidth","onLayout","event","placed","side","style","AnchoredPlacementOptions","align","alignOffset","anchor","Pick","sideOffset","Measured","origin","x","y","HIDDEN","left","opacity","pointerEvents","position","top","NO_INSETS","bottom","right","useAnchoredPlacement","t0","$","_c","t1","t2","t3","undefined","store","spacing","window","insets","keyboardTop","measured","setMeasured","surface","setSurface","t4","current","measure","layer","target","measureInWindow","originX","originY","width","height","subscription","addEventListener","unwatch","remove","t5","t6","Symbol","for","height_0","width_0","nativeEvent","layout","known","t7","md","sm","bounds","rtl","isRTL","placement","x_0","t8","t9","t10","t11","t12","doLeftAndRightSwapInRTL","t13","maxHeight","t14","_c"],"sources":["../../src/overlay/anchored.ts"],"sourcesContent":["import type { RefObject } from 'react'\nimport type { HostInstance, LayoutChangeEvent, ViewStyle } from 'react-native'\n\nimport { use, useEffect, useState } from 'react'\nimport { Dimensions, I18nManager, useWindowDimensions } from 'react-native'\nimport { SafeAreaInsetsContext } from 'react-native-safe-area-context'\n\nimport type { OverlayAlign, OverlaySide, Rect, Size } from './placement'\n\nimport { useTheme } from '../theme/scope'\nimport { OverlayHostContext } from './host'\nimport { useKeyboardTop, watchKeyboard } from './keyboard'\nimport { aboveKeyboard, boundsOf, place } from './placement'\n\ntype AnchoredPlacement = {\n /**\n * Where the anchor sits in the overlay layer, in physical coordinates, for\n * a layer drawn around it, and undefined until the surface has been\n * placed.\n */\n readonly anchorFrame: Rect | undefined\n /**\n * The anchor's width as it was measured, for a surface as wide as what\n * opened it, and undefined until the surface has been placed.\n */\n readonly anchorWidth: number | undefined\n /**\n * Hand to the surface's own `onLayout`. The surface is placed once it has\n * reported its size, and placed again whenever that size changes.\n */\n readonly onLayout: (event: LayoutChangeEvent) => void\n /**\n * Whether the surface has been placed. Until it has, it is laid out out of\n * sight, and a screen reader cannot be sent to it.\n */\n readonly placed: boolean\n /** The side the surface opened on, which is the opposite one after a flip. */\n readonly side: OverlaySide\n /**\n * The surface's position in the overlay layer, and the height it may take.\n * Until it has been placed it is laid out out of sight, to be measured.\n */\n readonly style: ViewStyle\n}\n\ntype AnchoredPlacementOptions = {\n /**\n * Where the surface sits along the side it opens on.\n * @default 'center'\n */\n readonly align?: OverlayAlign | undefined\n /** Moves the surface along that side, in dp: right or down when positive. */\n readonly alignOffset?: number | undefined\n /** The view the surface opens beside. */\n readonly anchor: RefObject<null | Pick<HostInstance, 'measureInWindow'>>\n /**\n * Which side of the anchor the surface opens on. It flips to the opposite\n * side when there is no room.\n * @default 'bottom'\n */\n readonly side?: OverlaySide | undefined\n /**\n * The gap between the anchor and the surface, in dp.\n * @default spacing.sm\n */\n readonly sideOffset?: number | undefined\n}\n\ntype Measured = {\n readonly anchor: Rect\n /** Where the overlay layer starts in the window. */\n readonly origin: { readonly x: number; readonly y: number }\n}\n\nconst HIDDEN: ViewStyle = {\n left: 0,\n opacity: 0,\n pointerEvents: 'none',\n position: 'absolute',\n top: 0,\n}\n\n// Outside a SafeAreaProvider the insets are unknown, and the window's own edge\n// is the best bound there is.\nconst NO_INSETS = { bottom: 0, left: 0, right: 0, top: 0 }\n\n/**\n * Places a surface drawn in an `Overlay` beside the view that opened it, as\n * web's anchored overlays are placed: on `side`, lined up by `align`, flipped\n * to the opposite side at the edge of the window, and kept inside the safe\n * area's insets with `spacing.md` to spare, the padding React Aria keeps from\n * the edge of the viewport. The software keyboard is an edge too while it is\n * shown, so a list opened from a field being typed in stays above the keys.\n * On `top` and `bottom`, `start` and `end` follow `I18nManager.isRTL`.\n *\n * The anchor is measured with `measureInWindow` whenever the surface reports\n * a new size, the window changes size or the keyboard moves.\n */\nfunction useAnchoredPlacement({\n align = 'center',\n alignOffset = 0,\n anchor,\n side = 'bottom',\n sideOffset,\n}: AnchoredPlacementOptions): AnchoredPlacement {\n const store = use(OverlayHostContext)\n const { spacing } = useTheme()\n const window = useWindowDimensions()\n const insets = use(SafeAreaInsetsContext) ?? NO_INSETS\n const keyboardTop = useKeyboardTop()\n const [measured, setMeasured] = useState<Measured | null>(null)\n const [surface, setSurface] = useState<null | Size>(null)\n\n useEffect(() => {\n // The layer is measured as well as the anchor, since the host need not\n // start at the window's corner: the surface is placed in the layer, and\n // the anchor is measured in the window.\n const measure = () => {\n const layer = store?.layer() ?? null\n const target = anchor.current\n\n if (surface === null || layer === null || target === null) {\n return\n }\n\n layer.measureInWindow((originX, originY) => {\n target.measureInWindow((x, y, width, height) => {\n setMeasured({\n anchor: { height, width, x, y },\n origin: { x: originX, y: originY },\n })\n })\n })\n }\n\n measure()\n\n // A rotation or a resized window can move the anchor without the\n // surface changing size, and so can a keyboard arriving, as a screen\n // makes room for the field being typed in.\n const subscription = Dimensions.addEventListener('change', measure)\n const unwatch = watchKeyboard(() => {\n measure()\n })\n\n return () => {\n subscription.remove()\n unwatch()\n }\n }, [anchor, store, surface])\n\n const onLayout = (event: LayoutChangeEvent) => {\n const { height, width } = event.nativeEvent.layout\n\n setSurface((known) =>\n known?.height === height && known.width === width\n ? known\n : { height, width },\n )\n }\n\n if (measured === null || surface === null) {\n return {\n anchorFrame: undefined,\n anchorWidth: undefined,\n onLayout,\n placed: false,\n side,\n style: HIDDEN,\n }\n }\n\n const placement = place({\n align,\n alignOffset,\n anchor: measured.anchor,\n bounds: aboveKeyboard(\n boundsOf(window, insets, spacing.md),\n keyboardTop,\n spacing.md,\n ),\n rtl: I18nManager.isRTL,\n side,\n sideOffset: sideOffset ?? spacing.sm,\n surface,\n })\n const x = placement.x - measured.origin.x\n\n return {\n anchorFrame: {\n height: measured.anchor.height,\n width: measured.anchor.width,\n x: measured.anchor.x - measured.origin.x,\n y: measured.anchor.y - measured.origin.y,\n },\n anchorWidth: measured.anchor.width,\n onLayout,\n placed: true,\n side: placement.side,\n style: {\n maxHeight: placement.maxHeight,\n position: 'absolute',\n top: placement.y - measured.origin.y,\n // The placement is in physical coordinates, as `measureInWindow`\n // reports them. React Native swaps `left` and `right` in a right-to-left\n // layout unless an app turns that off, so there `right` is what puts\n // the surface's left edge where the placement says.\n ...(I18nManager.isRTL && I18nManager.doLeftAndRightSwapInRTL\n ? { right: x }\n : { left: x }),\n },\n }\n}\n\nexport type { AnchoredPlacement, AnchoredPlacementOptions }\n\nexport { useAnchoredPlacement }\n"],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { c } from "react/compiler-runtime";
|
|
2
|
+
import { Keyboard, Platform } from "react-native";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
//#region src/overlay/keyboard.ts
|
|
5
|
+
function topOf(metrics) {
|
|
6
|
+
return metrics === void 0 || metrics === null || metrics.height === 0 ? null : metrics.screenY;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Where the software keyboard's top edge is in the window, in dp, or null
|
|
10
|
+
* while no keyboard is shown, for a surface that has to stay above it. A
|
|
11
|
+
* field's list opens while its keyboard is up, and the keyboard is drawn
|
|
12
|
+
* over the window rather than shrinking it, so the window's own edge would
|
|
13
|
+
* put the bottom of the list under the keys.
|
|
14
|
+
*/
|
|
15
|
+
function useKeyboardTop() {
|
|
16
|
+
const $ = c(2);
|
|
17
|
+
const [top, setTop] = useState(_temp);
|
|
18
|
+
let t0;
|
|
19
|
+
let t1;
|
|
20
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
21
|
+
t0 = () => watchKeyboard(setTop);
|
|
22
|
+
t1 = [];
|
|
23
|
+
$[0] = t0;
|
|
24
|
+
$[1] = t1;
|
|
25
|
+
} else {
|
|
26
|
+
t0 = $[0];
|
|
27
|
+
t1 = $[1];
|
|
28
|
+
}
|
|
29
|
+
useEffect(t0, t1);
|
|
30
|
+
return top;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Hands `listener` where the software keyboard's top edge is, or null, each
|
|
34
|
+
* time the keyboard moves, and returns what stops it. iOS reports a frame as
|
|
35
|
+
* the keyboard starts to move, and Android once it has arrived or gone,
|
|
36
|
+
* which is all either reports. React Native Web has no keyboard to report,
|
|
37
|
+
* and reports nothing.
|
|
38
|
+
*/
|
|
39
|
+
function _temp() {
|
|
40
|
+
return Platform.OS === "web" ? null : topOf(Keyboard.metrics());
|
|
41
|
+
}
|
|
42
|
+
function watchKeyboard(listener) {
|
|
43
|
+
const moved = (event) => {
|
|
44
|
+
listener(topOf(event.endCoordinates));
|
|
45
|
+
};
|
|
46
|
+
const hidden = () => {
|
|
47
|
+
listener(null);
|
|
48
|
+
};
|
|
49
|
+
const subscriptions = Platform.OS === "ios" ? [Keyboard.addListener("keyboardWillChangeFrame", moved), Keyboard.addListener("keyboardWillHide", hidden)] : [Keyboard.addListener("keyboardDidShow", moved), Keyboard.addListener("keyboardDidHide", hidden)];
|
|
50
|
+
return () => {
|
|
51
|
+
for (const subscription of subscriptions) subscription.remove();
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { useKeyboardTop, watchKeyboard };
|
|
56
|
+
|
|
57
|
+
//# sourceMappingURL=keyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.js","names":["KeyboardEvent","KeyboardMetrics","useEffect","useState","Keyboard","Platform","topOf","metrics","undefined","height","screenY","useKeyboardTop","$","_c","top","setTop","_temp","t0","t1","Symbol","for","watchKeyboard","OS","listener","moved","event","endCoordinates","hidden","subscriptions","addListener","subscription","remove","_c"],"sources":["../../src/overlay/keyboard.ts"],"sourcesContent":["import type { KeyboardEvent, KeyboardMetrics } from 'react-native'\n\nimport { useEffect, useState } from 'react'\nimport { Keyboard, Platform } from 'react-native'\n\n// A keyboard reported with no height covers nothing.\nfunction topOf(metrics: KeyboardMetrics | null | undefined): null | number {\n return metrics === undefined || metrics === null || metrics.height === 0\n ? null\n : metrics.screenY\n}\n\n/**\n * Where the software keyboard's top edge is in the window, in dp, or null\n * while no keyboard is shown, for a surface that has to stay above it. A\n * field's list opens while its keyboard is up, and the keyboard is drawn\n * over the window rather than shrinking it, so the window's own edge would\n * put the bottom of the list under the keys.\n */\nfunction useKeyboardTop(): null | number {\n const [top, setTop] = useState(() =>\n Platform.OS === 'web' ? null : topOf(Keyboard.metrics()),\n )\n\n useEffect(() => watchKeyboard(setTop), [])\n\n return top\n}\n\n/**\n * Hands `listener` where the software keyboard's top edge is, or null, each\n * time the keyboard moves, and returns what stops it. iOS reports a frame as\n * the keyboard starts to move, and Android once it has arrived or gone,\n * which is all either reports. React Native Web has no keyboard to report,\n * and reports nothing.\n */\nfunction watchKeyboard(listener: (top: null | number) => void): () => void {\n const moved = (event: KeyboardEvent) => {\n listener(topOf(event.endCoordinates))\n }\n const hidden = () => {\n listener(null)\n }\n const subscriptions =\n Platform.OS === 'ios'\n ? [\n Keyboard.addListener('keyboardWillChangeFrame', moved),\n Keyboard.addListener('keyboardWillHide', hidden),\n ]\n : [\n Keyboard.addListener('keyboardDidShow', moved),\n Keyboard.addListener('keyboardDidHide', hidden),\n ]\n\n return () => {\n for (const subscription of subscriptions) {\n subscription.remove()\n }\n }\n}\n\nexport { useKeyboardTop, watchKeyboard }\n"],"mappings":";;;;AAMA,SAASM,MAAMC,SAA4D;CACzE,OAAOA,YAAYC,KAAAA,KAAaD,YAAY,QAAQA,QAAQE,WAAW,IACnE,OACAF,QAAQG;AACd;;;;;;;;AASA,SAAAC,iBAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CACE,MAAA,CAAAC,KAAAC,UAAsBZ,SAASa,KAE/B;CAAC,IAAAC;CAAA,IAAAC;CAAA,IAAAN,EAAA,OAAAO,OAAAC,IAAA,2BAAA,GAAA;EAESH,WAAMI,cAAcN,MAAM;EAAGG,KAAA,CAAA;EAAEN,EAAA,KAAAK;EAAAL,EAAA,KAAAM;CAAA,OAAA;EAAAD,KAAAL,EAAA;EAAAM,KAAAN,EAAA;CAAA;CAAzCV,UAAUe,IAA6BC,EAAE;CAAC,OAEnCJ;AAAG;;;;;;;;AAPZ,SAAAE,QAAA;CAAA,OAEIX,SAAQiB,OAAQ,QAAhB,OAA+BhB,MAAMF,SAAQG,QAAS,CAAC;AAAC;AAe5D,SAASc,cAAcE,UAAoD;CACzE,MAAMC,SAASC,UAAyB;EACtCF,SAASjB,MAAMmB,MAAMC,cAAc,CAAC;CACtC;CACA,MAAMC,eAAe;EACnBJ,SAAS,IAAI;CACf;CACA,MAAMK,gBACJvB,SAASiB,OAAO,QACZ,CACElB,SAASyB,YAAY,2BAA2BL,KAAK,GACrDpB,SAASyB,YAAY,oBAAoBF,MAAM,CAAC,IAElD,CACEvB,SAASyB,YAAY,mBAAmBL,KAAK,GAC7CpB,SAASyB,YAAY,mBAAmBF,MAAM,CAAC;CAGvD,aAAa;EACX,KAAK,MAAMG,gBAAgBF,eACzBE,aAAaC,OAAO;CAExB;AACF"}
|