@butternutbox/pawprint-native 1.2.0 → 1.3.1

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.
@@ -7,12 +7,12 @@
7
7
  CJS Build start
8
8
  ESM Build start
9
9
  DTS Build start
10
- CJS dist/index.cjs 563.58 KB
11
- CJS dist/index.cjs.map 1.10 MB
12
- CJS ⚡️ Build success in 6123ms
13
- ESM dist/index.js 532.63 KB
10
+ ESM dist/index.js 533.82 KB
14
11
  ESM dist/index.js.map 1.10 MB
15
- ESM ⚡️ Build success in 6123ms
16
- DTS ⚡️ Build success in 15381ms
17
- DTS dist/index.d.cts 108.40 KB
18
- DTS dist/index.d.ts 108.40 KB
12
+ ESM ⚡️ Build success in 8991ms
13
+ CJS dist/index.cjs 564.92 KB
14
+ CJS dist/index.cjs.map 1.10 MB
15
+ CJS ⚡️ Build success in 8993ms
16
+ DTS ⚡️ Build success in 22924ms
17
+ DTS dist/index.d.cts 111.87 KB
18
+ DTS dist/index.d.ts 111.87 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @butternutbox/pawprint-native
2
2
 
3
+ ## 1.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - fb1b99b: `SelectField`: stop a searchable field going dead before the user can type.
8
+
9
+ The Portal-cascade blur that follows the dropdown mounting can reach JS after both existing recoveries (the `keyboardDidShow` re-focus and the 100ms hardware-keyboard timer) have already run. React Native still counts the input as focused at that point, so the `keyboardDidShow` re-focus is a no-op, and once the blur lands nothing focuses it again: the soft keyboard hides and hardware key presses go nowhere. The search input now re-focuses itself when it blurs while the dropdown is still open.
10
+
11
+ ## 1.3.0
12
+
13
+ ### Minor Changes
14
+
15
+ - 9449ba4: Refactor Menu component to include anchor to the trigger, improve stylings and API
16
+
3
17
  ## 1.2.0
4
18
 
5
19
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -9159,6 +9159,16 @@ var SelectFieldRoot = React66__default.default.forwardRef(
9159
9159
  keyboardSub.remove();
9160
9160
  };
9161
9161
  }, [isOpen, searchable, isSearching, searchQuery]);
9162
+ const isOpenRef = React66__default.default.useRef(isOpen);
9163
+ React66__default.default.useEffect(() => {
9164
+ isOpenRef.current = isOpen;
9165
+ });
9166
+ const handleSearchBlur = () => {
9167
+ setTimeout(() => {
9168
+ var _a2;
9169
+ if (isOpenRef.current) (_a2 = searchInputRef.current) == null ? void 0 : _a2.focus();
9170
+ }, 50);
9171
+ };
9162
9172
  const isCompound = React66__default.default.Children.toArray(children).some(
9163
9173
  (child) => React66__default.default.isValidElement(child) && child.type === SelectFieldContent
9164
9174
  );
@@ -9249,6 +9259,7 @@ var SelectFieldRoot = React66__default.default.forwardRef(
9249
9259
  ref: searchInputRef,
9250
9260
  value: searchQuery,
9251
9261
  onChangeText: setSearchQuery,
9262
+ onBlur: handleSearchBlur,
9252
9263
  placeholder: searchPlaceholder != null ? searchPlaceholder : "Search...",
9253
9264
  returnKeyType: "search",
9254
9265
  clearButtonMode: "never",
@@ -10658,46 +10669,37 @@ var Tooltip = React66__default.default.forwardRef(
10658
10669
  );
10659
10670
  Tooltip.displayName = "Tooltip";
10660
10671
  var parseTokenValue53 = (value) => parseFloat(value);
10661
- var Row = styled51__default.default(reactNative.Pressable)(({ theme: theme2, divider }) => {
10672
+ var Row = styled51__default.default(reactNative.Pressable)(({ theme: theme2 }) => {
10662
10673
  const { spacing } = theme2.tokens.semantics.dimensions;
10663
- const { colour } = theme2.tokens.semantics;
10664
10674
  return {
10665
10675
  width: "100%",
10666
- alignItems: "center",
10676
+ alignItems: "flex-start",
10667
10677
  justifyContent: "center",
10668
10678
  paddingVertical: parseTokenValue53(spacing.md),
10669
- paddingHorizontal: parseTokenValue53(spacing.md),
10670
- borderBottomWidth: divider ? 1 : 0,
10671
- borderBottomColor: colour.border.divider
10679
+ paddingHorizontal: parseTokenValue53(spacing.md)
10672
10680
  };
10673
10681
  });
10674
10682
  var MenuItem = React66__default.default.forwardRef((_a, ref) => {
10675
10683
  var _b = _a, { variant = "action", onPress, children, divider = true } = _b, rest = __objRest(_b, ["variant", "onPress", "children", "divider"]);
10676
10684
  const theme2 = react.useTheme();
10677
10685
  const { colour, typography } = theme2.tokens.semantics;
10678
- const labelColour = variant === "destructive" ? colour.text.error : colour.text.action.default;
10686
+ const labelColour = variant === "destructive" ? colour.text.error : colour.text.link.default;
10679
10687
  const label = typeof children === "string" || typeof children === "number" ? String(children) : void 0;
10680
- return /* @__PURE__ */ jsxRuntime.jsx(
10681
- Row,
10682
- __spreadProps(__spreadValues({
10683
- ref,
10684
- divider,
10685
- onPress,
10686
- accessible: true,
10687
- accessibilityRole: "menuitem",
10688
- accessibilityLabel: label
10689
- }, rest), {
10690
- children: label !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
10691
- Typography,
10692
- {
10693
- token: typography.body.medium.md,
10694
- align: "center",
10695
- color: labelColour,
10696
- children: label
10697
- }
10698
- ) : children
10699
- })
10700
- );
10688
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10689
+ /* @__PURE__ */ jsxRuntime.jsx(
10690
+ Row,
10691
+ __spreadProps(__spreadValues({
10692
+ ref,
10693
+ onPress,
10694
+ accessible: true,
10695
+ accessibilityRole: "menuitem",
10696
+ accessibilityLabel: label
10697
+ }, rest), {
10698
+ children: label !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { token: typography.body.medium.md, color: labelColour, children: label }) : children
10699
+ })
10700
+ ),
10701
+ divider && /* @__PURE__ */ jsxRuntime.jsx(Divider, {})
10702
+ ] });
10701
10703
  });
10702
10704
  MenuItem.displayName = "Menu.Item";
10703
10705
  var parseTokenValue54 = (value) => parseFloat(value);
@@ -10708,18 +10710,14 @@ var DismissLayer = styled51__default.default(reactNative.Pressable)({
10708
10710
  right: 0,
10709
10711
  bottom: 0
10710
10712
  });
10711
- var Anchor = styled51__default.default(reactNative.View)(({ theme: theme2, align }) => {
10712
- const inset = parseTokenValue54(theme2.tokens.semantics.dimensions.spacing.md);
10713
- return __spreadValues({
10714
- position: "absolute"
10715
- }, align === "right" ? { right: inset } : { left: inset });
10713
+ var Anchor = styled51__default.default(reactNative.View)({
10714
+ position: "absolute"
10716
10715
  });
10717
10716
  var Card = styled51__default.default(reactNative.Pressable)(({ theme: theme2, width }) => {
10718
10717
  const { borderRadius } = theme2.tokens.semantics.dimensions;
10719
10718
  const { shadow, background } = theme2.tokens.semantics.colour;
10720
10719
  return {
10721
10720
  width,
10722
- maxWidth: "90%",
10723
10721
  borderRadius: parseTokenValue54(borderRadius.md),
10724
10722
  overflow: "hidden",
10725
10723
  backgroundColor: background.surface.default,
@@ -10737,12 +10735,25 @@ var Card = styled51__default.default(reactNative.Pressable)(({ theme: theme2, wi
10737
10735
  var MenuRoot = ({
10738
10736
  open,
10739
10737
  onClose,
10738
+ anchor,
10740
10739
  anchorOffset = 0,
10741
10740
  align = "right",
10742
- width = 360,
10741
+ width = 280,
10743
10742
  closeAccessibilityLabel = "Close menu",
10744
10743
  children
10745
10744
  }) => {
10745
+ const theme2 = react.useTheme();
10746
+ const { width: windowWidth } = reactNative.useWindowDimensions();
10747
+ const { spacing } = theme2.tokens.semantics.dimensions;
10748
+ const [lastAnchor, setLastAnchor] = React66.useState(anchor);
10749
+ if (anchor && anchor !== lastAnchor) setLastAnchor(anchor);
10750
+ const shownAnchor = anchor != null ? anchor : lastAnchor;
10751
+ const position = shownAnchor ? __spreadValues({
10752
+ top: shownAnchor.y + shownAnchor.height + parseTokenValue54(spacing.xs)
10753
+ }, align === "right" ? { right: windowWidth - (shownAnchor.x + shownAnchor.width) } : { left: shownAnchor.x }) : {
10754
+ top: anchorOffset,
10755
+ [align]: parseTokenValue54(spacing.md)
10756
+ };
10746
10757
  return /* @__PURE__ */ jsxRuntime.jsxs(
10747
10758
  reactNative.Modal,
10748
10759
  {
@@ -10760,10 +10771,10 @@ var MenuRoot = ({
10760
10771
  accessibilityLabel: closeAccessibilityLabel
10761
10772
  }
10762
10773
  ),
10763
- /* @__PURE__ */ jsxRuntime.jsx(Anchor, { align, style: { top: anchorOffset }, children: /* @__PURE__ */ jsxRuntime.jsx(
10774
+ /* @__PURE__ */ jsxRuntime.jsx(Anchor, { style: position, children: /* @__PURE__ */ jsxRuntime.jsx(
10764
10775
  Card,
10765
10776
  {
10766
- width,
10777
+ width: Math.min(width, windowWidth * 0.9),
10767
10778
  onPress: () => {
10768
10779
  },
10769
10780
  accessible: false,
@@ -10779,6 +10790,25 @@ MenuRoot.displayName = "Menu";
10779
10790
  var Menu2 = Object.assign(MenuRoot, {
10780
10791
  Item: MenuItem
10781
10792
  });
10793
+ var useMenuTrigger = () => {
10794
+ const triggerRef = React66.useRef(null);
10795
+ const [anchor, setAnchor] = React66.useState();
10796
+ const open = React66.useCallback(() => {
10797
+ var _a;
10798
+ (_a = triggerRef.current) == null ? void 0 : _a.measureInWindow(
10799
+ (x, y, width, height) => setAnchor({ x, y, width, height })
10800
+ );
10801
+ }, []);
10802
+ const close = React66.useCallback(() => setAnchor(void 0), []);
10803
+ const isOpen = anchor !== void 0;
10804
+ return {
10805
+ triggerRef,
10806
+ isOpen,
10807
+ open,
10808
+ close,
10809
+ menuProps: { open: isOpen, onClose: close, anchor }
10810
+ };
10811
+ };
10782
10812
  var parseTokenValue55 = (value) => parseFloat(value);
10783
10813
  var StyledInsightRoot = styled51__default.default(reactNative.View)(
10784
10814
  ({
@@ -12926,6 +12956,7 @@ exports.slideOutAnimation = slideOutAnimation;
12926
12956
  exports.theme = theme;
12927
12957
  exports.useCopyField = useCopyField;
12928
12958
  exports.useDrawerKeyboardAvoidance = useDrawerKeyboardAvoidance;
12959
+ exports.useMenuTrigger = useMenuTrigger;
12929
12960
  exports.usePasswordField = usePasswordField;
12930
12961
  exports.usePawprint = usePawprint;
12931
12962
  exports.useSearchField = useSearchField;