@oxyhq/bloom 0.12.0 → 0.13.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.
@@ -11,10 +11,13 @@ var _usePressAnimation = require("../hooks/usePressAnimation.js");
11
11
  var _useInteractionState = require("../hooks/useInteractionState.js");
12
12
  var _jsxRuntime = require("react/jsx-runtime");
13
13
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
+ // Material-style FAB scale. `small` (40px) keeps a full 24px icon box so the
15
+ // glyph reads clearly; `medium` (56px) is the canonical FAB; `large` (64px) is
16
+ // the high-prominence action.
14
17
  const SIZE_CONFIG = {
15
18
  small: {
16
19
  diameter: 40,
17
- iconBox: 20,
20
+ iconBox: 24,
18
21
  fontSize: 14
19
22
  },
20
23
  medium: {
@@ -28,6 +31,25 @@ const SIZE_CONFIG = {
28
31
  fontSize: 16
29
32
  }
30
33
  };
34
+ const MIN_NUMERIC_ICON_BOX = 22;
35
+
36
+ /**
37
+ * Resolve a `size` prop (preset name or raw pixel diameter) to concrete pixel
38
+ * geometry. A numeric size sets the diameter directly, derives the icon box as
39
+ * `round(size * 0.5)` (clamped to a sensible minimum) and lets the circle radius
40
+ * stay `size / 2` (the container uses a full pill radius, so any square stays a
41
+ * perfect circle).
42
+ */
43
+ function resolveSize(size) {
44
+ if (typeof size === 'number') {
45
+ return {
46
+ diameter: size,
47
+ iconBox: Math.max(MIN_NUMERIC_ICON_BOX, Math.round(size * 0.5)),
48
+ fontSize: Math.max(13, Math.round(size * 0.27))
49
+ };
50
+ }
51
+ return SIZE_CONFIG[size];
52
+ }
31
53
  const PILL_RADIUS = 999;
32
54
  const PRESS_SCALE = 0.94;
33
55
  const DEFAULT_OFFSET = 16;
@@ -81,7 +103,7 @@ const FabComponent = ({
81
103
  zIndex = DEFAULT_Z_INDEX
82
104
  }) => {
83
105
  const theme = (0, _useTheme.useTheme)();
84
- const sizeConfig = SIZE_CONFIG[size];
106
+ const sizeConfig = (0, _react.useMemo)(() => resolveSize(size), [size]);
85
107
  const isExtended = label != null && label.length > 0;
86
108
  const content = icon ?? children;
87
109
  const {
@@ -114,13 +136,13 @@ const FabComponent = ({
114
136
  elevation: 6
115
137
  };
116
138
  if (isExtended) {
117
- base.paddingHorizontal = size === 'small' ? 14 : 20;
139
+ base.paddingHorizontal = sizeConfig.diameter <= 44 ? 14 : 20;
118
140
  base.gap = 8;
119
141
  } else {
120
142
  base.width = sizeConfig.diameter;
121
143
  }
122
144
  return base;
123
- }, [resolvedColors.background, sizeConfig.diameter, theme.colors.shadow, isExtended, size]);
145
+ }, [resolvedColors.background, sizeConfig.diameter, theme.colors.shadow, isExtended]);
124
146
  const labelTextStyle = (0, _react.useMemo)(() => ({
125
147
  fontSize: sizeConfig.fontSize,
126
148
  fontWeight: '600',
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_useTheme","_usePressAnimation","_useInteractionState","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","SIZE_CONFIG","small","diameter","iconBox","fontSize","medium","large","PILL_RADIUS","PRESS_SCALE","DEFAULT_OFFSET","DEFAULT_Z_INDEX","HIT_SLOP","top","bottom","left","right","placementStyle","placement","offset","style","position","FabComponent","onPress","icon","children","label","variant","size","disabled","accessibilityLabel","accessibilityHint","labelStyle","className","testID","zIndex","theme","useTheme","sizeConfig","isExtended","length","content","scaleAnim","onPressIn","onPressOut","usePressAnimation","undefined","state","pressed","onIn","onPressedIn","onOut","onPressedOut","useInteractionState","resolvedColors","useMemo","resolveVariant","colors","containerStyle","base","alignItems","justifyContent","flexDirection","backgroundColor","background","borderRadius","height","shadowColor","shadow","shadowOffset","width","shadowOpacity","shadowRadius","elevation","paddingHorizontal","gap","labelTextStyle","fontWeight","color","foreground","handlePressIn","handlePressOut","jsx","Animated","View","transform","scale","jsxs","Pressable","opacity","hitSlop","accessibilityRole","accessibilityState","Text","numberOfLines","card","text","primary","primaryForeground","Fab","exports","memo","displayName"],"sourceRoot":"../../../src","sources":["fab/Fab.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_useTheme","_usePressAnimation","_useInteractionState","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","SIZE_CONFIG","small","diameter","iconBox","fontSize","medium","large","MIN_NUMERIC_ICON_BOX","resolveSize","size","Math","max","round","PILL_RADIUS","PRESS_SCALE","DEFAULT_OFFSET","DEFAULT_Z_INDEX","HIT_SLOP","top","bottom","left","right","placementStyle","placement","offset","style","position","FabComponent","onPress","icon","children","label","variant","disabled","accessibilityLabel","accessibilityHint","labelStyle","className","testID","zIndex","theme","useTheme","sizeConfig","useMemo","isExtended","length","content","scaleAnim","onPressIn","onPressOut","usePressAnimation","undefined","state","pressed","onIn","onPressedIn","onOut","onPressedOut","useInteractionState","resolvedColors","resolveVariant","colors","containerStyle","base","alignItems","justifyContent","flexDirection","backgroundColor","background","borderRadius","height","shadowColor","shadow","shadowOffset","width","shadowOpacity","shadowRadius","elevation","paddingHorizontal","gap","labelTextStyle","fontWeight","color","foreground","handlePressIn","handlePressOut","jsx","Animated","View","transform","scale","jsxs","Pressable","opacity","hitSlop","accessibilityRole","accessibilityState","Text","numberOfLines","card","text","primary","primaryForeground","Fab","exports","memo","displayName"],"sourceRoot":"../../../src","sources":["fab/Fab.tsx"],"mappings":"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","ignoreList":[]}
@@ -8,10 +8,13 @@ var _react = _interopRequireWildcard(require("react"));
8
8
  var _useTheme = require("../theme/use-theme.js");
9
9
  var _jsxRuntime = require("react/jsx-runtime");
10
10
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
11
+ // Material-style FAB scale. `small` (40px) keeps a full 24px icon box so the
12
+ // glyph reads clearly; `medium` (56px) is the canonical FAB; `large` (64px) is
13
+ // the high-prominence action.
11
14
  const SIZE_CONFIG = {
12
15
  small: {
13
16
  diameter: 40,
14
- iconBox: 20,
17
+ iconBox: 24,
15
18
  fontSize: 14
16
19
  },
17
20
  medium: {
@@ -25,6 +28,24 @@ const SIZE_CONFIG = {
25
28
  fontSize: 16
26
29
  }
27
30
  };
31
+ const MIN_NUMERIC_ICON_BOX = 22;
32
+
33
+ /**
34
+ * Resolve a `size` prop (preset name or raw pixel diameter) to concrete pixel
35
+ * geometry. Mirrors the native `resolveSize` exactly so a numeric size renders
36
+ * identically on both platforms. A numeric size sets the diameter directly and
37
+ * derives the icon box as `round(size * 0.5)` (clamped to a sensible minimum).
38
+ */
39
+ function resolveSize(size) {
40
+ if (typeof size === 'number') {
41
+ return {
42
+ diameter: size,
43
+ iconBox: Math.max(MIN_NUMERIC_ICON_BOX, Math.round(size * 0.5)),
44
+ fontSize: Math.max(13, Math.round(size * 0.27))
45
+ };
46
+ }
47
+ return SIZE_CONFIG[size];
48
+ }
28
49
  const PILL_RADIUS = 999;
29
50
  const PRESS_SCALE = 0.94;
30
51
  const DEFAULT_OFFSET = 16;
@@ -95,26 +116,37 @@ function useFabCss() {
95
116
  * CENTRAL CONTENT COLUMN as it scrolls and never escapes to the viewport edge /
96
117
  * over a side rail in a constrained multi-column app layout.
97
118
  *
98
- * To pin a sticky element to the BOTTOM of a column it must sit at the end of
99
- * the scroll content with `align-self: flex-end` (consumer column should be a
100
- * flex column) — documented in the component's usage story. We set `bottom`
101
- * and a self-alignment so the common case works with zero consumer CSS beyond a
102
- * `flex-col` column.
119
+ * Pinning a FAB to the BOTTOM of a column needs TWO mechanisms working together,
120
+ * because sticky alone is not enough:
121
+ *
122
+ * 1. `margin-top: auto` in a flex COLUMN this consumes all the free vertical
123
+ * space, pushing the FAB to the bottom of the container EVEN WHEN THE
124
+ * CONTENT IS SHORT (e.g. an empty feed / loading spinner). Without it, a
125
+ * short column leaves the FAB at its natural flow position (mid-column) —
126
+ * which is exactly the "floating in the middle / broken" bug.
127
+ * 2. `position: sticky; bottom` — when the content is TALL and the column
128
+ * scrolls, sticky keeps the FAB pinned to the bottom of the viewport as the
129
+ * user scrolls, instead of scrolling away with the content.
130
+ *
131
+ * Horizontal placement uses `align-self` (sticky elements can't be pushed by
132
+ * `left`/`right` the way absolute ones are) plus an inline-edge margin for the
133
+ * `offset`. The consumer column MUST be a flex column that fills the available
134
+ * height, and the FAB MUST be its last child — documented in the usage story.
103
135
  */
104
136
  function placementStyle(placement, offset) {
105
137
  if (placement === 'static') return {};
106
138
  const style = {
107
139
  position: 'sticky'
108
140
  };
109
- if (placement === 'bottom-right' || placement === 'bottom-left') {
141
+ const isBottom = placement === 'bottom-right' || placement === 'bottom-left';
142
+ if (isBottom) {
110
143
  style.bottom = offset;
144
+ // Push the FAB to the bottom of a (flex-column) container even when the
145
+ // content is too short to scroll, so it never floats mid-column.
146
+ style.marginTop = 'auto';
111
147
  } else {
112
148
  style.top = offset;
113
149
  }
114
- // Sticky elements can't be pushed horizontally by left/right the way absolute
115
- // ones are; we self-align within the (flex column) container instead, and add
116
- // a horizontal margin for the offset so the FAB sits `offset` px from the
117
- // column's inline edge.
118
150
  if (placement === 'bottom-right' || placement === 'top-right') {
119
151
  style.alignSelf = 'flex-end';
120
152
  style.marginRight = offset;
@@ -169,7 +201,7 @@ const FabWebComponent = ({
169
201
  const theme = (0, _useTheme.useTheme)();
170
202
  const reactId = (0, _react.useId)();
171
203
  const resolvedId = id ?? `bloom-fab-${reactId}`;
172
- const sizeConfig = SIZE_CONFIG[size];
204
+ const sizeConfig = (0, _react.useMemo)(() => resolveSize(size), [size]);
173
205
  const isExtended = label != null && label.length > 0;
174
206
  const content = icon ?? children;
175
207
  const variantColors = (0, _react.useMemo)(() => resolveVariant(variant, theme.colors), [variant, theme.colors]);
@@ -194,13 +226,14 @@ const FabWebComponent = ({
194
226
  ...placementStyle(placement, offset)
195
227
  };
196
228
  if (isExtended) {
197
- base.paddingLeft = size === 'small' ? 14 : 20;
198
- base.paddingRight = size === 'small' ? 14 : 20;
229
+ const pad = sizeConfig.diameter <= 44 ? 14 : 20;
230
+ base.paddingLeft = pad;
231
+ base.paddingRight = pad;
199
232
  } else {
200
233
  base.width = sizeConfig.diameter;
201
234
  }
202
235
  return base;
203
- }, [variantColors, sizeConfig.diameter, sizeConfig.fontSize, zIndex, restShadow, hoverShadow, placement, offset, isExtended, size]);
236
+ }, [variantColors, sizeConfig.diameter, sizeConfig.fontSize, zIndex, restShadow, hoverShadow, placement, offset, isExtended]);
204
237
  const handleClick = (0, _react.useCallback)(event => {
205
238
  if (disabled) {
206
239
  event.preventDefault();
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_useTheme","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","SIZE_CONFIG","small","diameter","iconBox","fontSize","medium","large","PILL_RADIUS","PRESS_SCALE","DEFAULT_OFFSET","DEFAULT_Z_INDEX","STYLE_ID","BLOOM_FAB_CSS","useFabCss","useEffect","document","getElementById","style","createElement","id","textContent","head","appendChild","placementStyle","placement","offset","position","bottom","top","alignSelf","marginRight","marginLeft","resolveVariant","variant","c","background","card","foreground","text","ring","primary","primaryForeground","FabWebComponent","onPress","onClick","icon","children","label","size","disabled","accessibilityLabel","ariaLabelProp","accessibilityHint","labelStyle","className","testID","zIndex","title","type","theme","useTheme","reactId","useId","resolvedId","sizeConfig","isExtended","length","content","variantColors","useMemo","colors","restShadow","shadow","hoverShadow","containerStyle","base","backgroundColor","color","borderRadius","height","boxShadow","fontWeight","paddingLeft","paddingRight","width","handleClick","useCallback","event","preventDefault","ariaLabel","composedClassName","concat","join","jsxs","undefined","jsx","display","alignItems","justifyContent","Fab","exports","memo","displayName"],"sourceRoot":"../../../src","sources":["fab/Fab.web.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_useTheme","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","SIZE_CONFIG","small","diameter","iconBox","fontSize","medium","large","MIN_NUMERIC_ICON_BOX","resolveSize","size","Math","max","round","PILL_RADIUS","PRESS_SCALE","DEFAULT_OFFSET","DEFAULT_Z_INDEX","STYLE_ID","BLOOM_FAB_CSS","useFabCss","useEffect","document","getElementById","style","createElement","id","textContent","head","appendChild","placementStyle","placement","offset","position","isBottom","bottom","marginTop","top","alignSelf","marginRight","marginLeft","resolveVariant","variant","c","background","card","foreground","text","ring","primary","primaryForeground","FabWebComponent","onPress","onClick","icon","children","label","disabled","accessibilityLabel","ariaLabelProp","accessibilityHint","labelStyle","className","testID","zIndex","title","type","theme","useTheme","reactId","useId","resolvedId","sizeConfig","useMemo","isExtended","length","content","variantColors","colors","restShadow","shadow","hoverShadow","containerStyle","base","backgroundColor","color","borderRadius","height","boxShadow","fontWeight","pad","paddingLeft","paddingRight","width","handleClick","useCallback","event","preventDefault","ariaLabel","composedClassName","concat","join","jsxs","undefined","jsx","display","alignItems","justifyContent","Fab","exports","memo","displayName"],"sourceRoot":"../../../src","sources":["fab/Fab.web.tsx"],"mappings":"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","ignoreList":[]}
@@ -6,10 +6,13 @@ import { useTheme } from "../theme/use-theme.js";
6
6
  import { usePressAnimation } from "../hooks/usePressAnimation.js";
7
7
  import { useInteractionState } from "../hooks/useInteractionState.js";
8
8
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
+ // Material-style FAB scale. `small` (40px) keeps a full 24px icon box so the
10
+ // glyph reads clearly; `medium` (56px) is the canonical FAB; `large` (64px) is
11
+ // the high-prominence action.
9
12
  const SIZE_CONFIG = {
10
13
  small: {
11
14
  diameter: 40,
12
- iconBox: 20,
15
+ iconBox: 24,
13
16
  fontSize: 14
14
17
  },
15
18
  medium: {
@@ -23,6 +26,25 @@ const SIZE_CONFIG = {
23
26
  fontSize: 16
24
27
  }
25
28
  };
29
+ const MIN_NUMERIC_ICON_BOX = 22;
30
+
31
+ /**
32
+ * Resolve a `size` prop (preset name or raw pixel diameter) to concrete pixel
33
+ * geometry. A numeric size sets the diameter directly, derives the icon box as
34
+ * `round(size * 0.5)` (clamped to a sensible minimum) and lets the circle radius
35
+ * stay `size / 2` (the container uses a full pill radius, so any square stays a
36
+ * perfect circle).
37
+ */
38
+ function resolveSize(size) {
39
+ if (typeof size === 'number') {
40
+ return {
41
+ diameter: size,
42
+ iconBox: Math.max(MIN_NUMERIC_ICON_BOX, Math.round(size * 0.5)),
43
+ fontSize: Math.max(13, Math.round(size * 0.27))
44
+ };
45
+ }
46
+ return SIZE_CONFIG[size];
47
+ }
26
48
  const PILL_RADIUS = 999;
27
49
  const PRESS_SCALE = 0.94;
28
50
  const DEFAULT_OFFSET = 16;
@@ -76,7 +98,7 @@ const FabComponent = ({
76
98
  zIndex = DEFAULT_Z_INDEX
77
99
  }) => {
78
100
  const theme = useTheme();
79
- const sizeConfig = SIZE_CONFIG[size];
101
+ const sizeConfig = useMemo(() => resolveSize(size), [size]);
80
102
  const isExtended = label != null && label.length > 0;
81
103
  const content = icon ?? children;
82
104
  const {
@@ -109,13 +131,13 @@ const FabComponent = ({
109
131
  elevation: 6
110
132
  };
111
133
  if (isExtended) {
112
- base.paddingHorizontal = size === 'small' ? 14 : 20;
134
+ base.paddingHorizontal = sizeConfig.diameter <= 44 ? 14 : 20;
113
135
  base.gap = 8;
114
136
  } else {
115
137
  base.width = sizeConfig.diameter;
116
138
  }
117
139
  return base;
118
- }, [resolvedColors.background, sizeConfig.diameter, theme.colors.shadow, isExtended, size]);
140
+ }, [resolvedColors.background, sizeConfig.diameter, theme.colors.shadow, isExtended]);
119
141
  const labelTextStyle = useMemo(() => ({
120
142
  fontSize: sizeConfig.fontSize,
121
143
  fontWeight: '600',
@@ -1 +1 @@
1
- {"version":3,"names":["React","memo","useMemo","Animated","Pressable","Text","View","useTheme","usePressAnimation","useInteractionState","jsx","_jsx","jsxs","_jsxs","SIZE_CONFIG","small","diameter","iconBox","fontSize","medium","large","PILL_RADIUS","PRESS_SCALE","DEFAULT_OFFSET","DEFAULT_Z_INDEX","HIT_SLOP","top","bottom","left","right","placementStyle","placement","offset","style","position","FabComponent","onPress","icon","children","label","variant","size","disabled","accessibilityLabel","accessibilityHint","labelStyle","className","testID","zIndex","theme","sizeConfig","isExtended","length","content","scaleAnim","onPressIn","onPressOut","undefined","state","pressed","onIn","onPressedIn","onOut","onPressedOut","resolvedColors","resolveVariant","colors","containerStyle","base","alignItems","justifyContent","flexDirection","backgroundColor","background","borderRadius","height","shadowColor","shadow","shadowOffset","width","shadowOpacity","shadowRadius","elevation","paddingHorizontal","gap","labelTextStyle","fontWeight","color","foreground","handlePressIn","handlePressOut","transform","scale","opacity","hitSlop","accessibilityRole","accessibilityState","numberOfLines","card","text","primary","primaryForeground","Fab","displayName"],"sourceRoot":"../../../src","sources":["fab/Fab.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","memo","useMemo","Animated","Pressable","Text","View","useTheme","usePressAnimation","useInteractionState","jsx","_jsx","jsxs","_jsxs","SIZE_CONFIG","small","diameter","iconBox","fontSize","medium","large","MIN_NUMERIC_ICON_BOX","resolveSize","size","Math","max","round","PILL_RADIUS","PRESS_SCALE","DEFAULT_OFFSET","DEFAULT_Z_INDEX","HIT_SLOP","top","bottom","left","right","placementStyle","placement","offset","style","position","FabComponent","onPress","icon","children","label","variant","disabled","accessibilityLabel","accessibilityHint","labelStyle","className","testID","zIndex","theme","sizeConfig","isExtended","length","content","scaleAnim","onPressIn","onPressOut","undefined","state","pressed","onIn","onPressedIn","onOut","onPressedOut","resolvedColors","resolveVariant","colors","containerStyle","base","alignItems","justifyContent","flexDirection","backgroundColor","background","borderRadius","height","shadowColor","shadow","shadowOffset","width","shadowOpacity","shadowRadius","elevation","paddingHorizontal","gap","labelTextStyle","fontWeight","color","foreground","handlePressIn","handlePressOut","transform","scale","opacity","hitSlop","accessibilityRole","accessibilityState","numberOfLines","card","text","primary","primaryForeground","Fab","displayName"],"sourceRoot":"../../../src","sources":["fab/Fab.tsx"],"mappings":"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","ignoreList":[]}
@@ -3,10 +3,13 @@
3
3
  import React, { memo, useCallback, useEffect, useId, useMemo } from 'react';
4
4
  import { useTheme } from "../theme/use-theme.js";
5
5
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
+ // Material-style FAB scale. `small` (40px) keeps a full 24px icon box so the
7
+ // glyph reads clearly; `medium` (56px) is the canonical FAB; `large` (64px) is
8
+ // the high-prominence action.
6
9
  const SIZE_CONFIG = {
7
10
  small: {
8
11
  diameter: 40,
9
- iconBox: 20,
12
+ iconBox: 24,
10
13
  fontSize: 14
11
14
  },
12
15
  medium: {
@@ -20,6 +23,24 @@ const SIZE_CONFIG = {
20
23
  fontSize: 16
21
24
  }
22
25
  };
26
+ const MIN_NUMERIC_ICON_BOX = 22;
27
+
28
+ /**
29
+ * Resolve a `size` prop (preset name or raw pixel diameter) to concrete pixel
30
+ * geometry. Mirrors the native `resolveSize` exactly so a numeric size renders
31
+ * identically on both platforms. A numeric size sets the diameter directly and
32
+ * derives the icon box as `round(size * 0.5)` (clamped to a sensible minimum).
33
+ */
34
+ function resolveSize(size) {
35
+ if (typeof size === 'number') {
36
+ return {
37
+ diameter: size,
38
+ iconBox: Math.max(MIN_NUMERIC_ICON_BOX, Math.round(size * 0.5)),
39
+ fontSize: Math.max(13, Math.round(size * 0.27))
40
+ };
41
+ }
42
+ return SIZE_CONFIG[size];
43
+ }
23
44
  const PILL_RADIUS = 999;
24
45
  const PRESS_SCALE = 0.94;
25
46
  const DEFAULT_OFFSET = 16;
@@ -90,26 +111,37 @@ function useFabCss() {
90
111
  * CENTRAL CONTENT COLUMN as it scrolls and never escapes to the viewport edge /
91
112
  * over a side rail in a constrained multi-column app layout.
92
113
  *
93
- * To pin a sticky element to the BOTTOM of a column it must sit at the end of
94
- * the scroll content with `align-self: flex-end` (consumer column should be a
95
- * flex column) — documented in the component's usage story. We set `bottom`
96
- * and a self-alignment so the common case works with zero consumer CSS beyond a
97
- * `flex-col` column.
114
+ * Pinning a FAB to the BOTTOM of a column needs TWO mechanisms working together,
115
+ * because sticky alone is not enough:
116
+ *
117
+ * 1. `margin-top: auto` in a flex COLUMN this consumes all the free vertical
118
+ * space, pushing the FAB to the bottom of the container EVEN WHEN THE
119
+ * CONTENT IS SHORT (e.g. an empty feed / loading spinner). Without it, a
120
+ * short column leaves the FAB at its natural flow position (mid-column) —
121
+ * which is exactly the "floating in the middle / broken" bug.
122
+ * 2. `position: sticky; bottom` — when the content is TALL and the column
123
+ * scrolls, sticky keeps the FAB pinned to the bottom of the viewport as the
124
+ * user scrolls, instead of scrolling away with the content.
125
+ *
126
+ * Horizontal placement uses `align-self` (sticky elements can't be pushed by
127
+ * `left`/`right` the way absolute ones are) plus an inline-edge margin for the
128
+ * `offset`. The consumer column MUST be a flex column that fills the available
129
+ * height, and the FAB MUST be its last child — documented in the usage story.
98
130
  */
99
131
  function placementStyle(placement, offset) {
100
132
  if (placement === 'static') return {};
101
133
  const style = {
102
134
  position: 'sticky'
103
135
  };
104
- if (placement === 'bottom-right' || placement === 'bottom-left') {
136
+ const isBottom = placement === 'bottom-right' || placement === 'bottom-left';
137
+ if (isBottom) {
105
138
  style.bottom = offset;
139
+ // Push the FAB to the bottom of a (flex-column) container even when the
140
+ // content is too short to scroll, so it never floats mid-column.
141
+ style.marginTop = 'auto';
106
142
  } else {
107
143
  style.top = offset;
108
144
  }
109
- // Sticky elements can't be pushed horizontally by left/right the way absolute
110
- // ones are; we self-align within the (flex column) container instead, and add
111
- // a horizontal margin for the offset so the FAB sits `offset` px from the
112
- // column's inline edge.
113
145
  if (placement === 'bottom-right' || placement === 'top-right') {
114
146
  style.alignSelf = 'flex-end';
115
147
  style.marginRight = offset;
@@ -164,7 +196,7 @@ const FabWebComponent = ({
164
196
  const theme = useTheme();
165
197
  const reactId = useId();
166
198
  const resolvedId = id ?? `bloom-fab-${reactId}`;
167
- const sizeConfig = SIZE_CONFIG[size];
199
+ const sizeConfig = useMemo(() => resolveSize(size), [size]);
168
200
  const isExtended = label != null && label.length > 0;
169
201
  const content = icon ?? children;
170
202
  const variantColors = useMemo(() => resolveVariant(variant, theme.colors), [variant, theme.colors]);
@@ -189,13 +221,14 @@ const FabWebComponent = ({
189
221
  ...placementStyle(placement, offset)
190
222
  };
191
223
  if (isExtended) {
192
- base.paddingLeft = size === 'small' ? 14 : 20;
193
- base.paddingRight = size === 'small' ? 14 : 20;
224
+ const pad = sizeConfig.diameter <= 44 ? 14 : 20;
225
+ base.paddingLeft = pad;
226
+ base.paddingRight = pad;
194
227
  } else {
195
228
  base.width = sizeConfig.diameter;
196
229
  }
197
230
  return base;
198
- }, [variantColors, sizeConfig.diameter, sizeConfig.fontSize, zIndex, restShadow, hoverShadow, placement, offset, isExtended, size]);
231
+ }, [variantColors, sizeConfig.diameter, sizeConfig.fontSize, zIndex, restShadow, hoverShadow, placement, offset, isExtended]);
199
232
  const handleClick = useCallback(event => {
200
233
  if (disabled) {
201
234
  event.preventDefault();
@@ -1 +1 @@
1
- {"version":3,"names":["React","memo","useCallback","useEffect","useId","useMemo","useTheme","jsx","_jsx","jsxs","_jsxs","SIZE_CONFIG","small","diameter","iconBox","fontSize","medium","large","PILL_RADIUS","PRESS_SCALE","DEFAULT_OFFSET","DEFAULT_Z_INDEX","STYLE_ID","BLOOM_FAB_CSS","useFabCss","document","getElementById","style","createElement","id","textContent","head","appendChild","placementStyle","placement","offset","position","bottom","top","alignSelf","marginRight","marginLeft","resolveVariant","variant","c","background","card","foreground","text","ring","primary","primaryForeground","FabWebComponent","onPress","onClick","icon","children","label","size","disabled","accessibilityLabel","ariaLabelProp","accessibilityHint","labelStyle","className","testID","zIndex","title","type","theme","reactId","resolvedId","sizeConfig","isExtended","length","content","variantColors","colors","restShadow","shadow","hoverShadow","containerStyle","base","backgroundColor","color","borderRadius","height","boxShadow","fontWeight","paddingLeft","paddingRight","width","handleClick","event","preventDefault","ariaLabel","composedClassName","concat","join","undefined","display","alignItems","justifyContent","Fab","displayName"],"sourceRoot":"../../../src","sources":["fab/Fab.web.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","memo","useCallback","useEffect","useId","useMemo","useTheme","jsx","_jsx","jsxs","_jsxs","SIZE_CONFIG","small","diameter","iconBox","fontSize","medium","large","MIN_NUMERIC_ICON_BOX","resolveSize","size","Math","max","round","PILL_RADIUS","PRESS_SCALE","DEFAULT_OFFSET","DEFAULT_Z_INDEX","STYLE_ID","BLOOM_FAB_CSS","useFabCss","document","getElementById","style","createElement","id","textContent","head","appendChild","placementStyle","placement","offset","position","isBottom","bottom","marginTop","top","alignSelf","marginRight","marginLeft","resolveVariant","variant","c","background","card","foreground","text","ring","primary","primaryForeground","FabWebComponent","onPress","onClick","icon","children","label","disabled","accessibilityLabel","ariaLabelProp","accessibilityHint","labelStyle","className","testID","zIndex","title","type","theme","reactId","resolvedId","sizeConfig","isExtended","length","content","variantColors","colors","restShadow","shadow","hoverShadow","containerStyle","base","backgroundColor","color","borderRadius","height","boxShadow","fontWeight","pad","paddingLeft","paddingRight","width","handleClick","event","preventDefault","ariaLabel","composedClassName","concat","join","undefined","display","alignItems","justifyContent","Fab","displayName"],"sourceRoot":"../../../src","sources":["fab/Fab.web.tsx"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"Fab.d.ts","sourceRoot":"","sources":["../../../../src/fab/Fab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAa7C,OAAO,KAAK,EAAgB,QAAQ,EAAuB,MAAM,SAAS,CAAC;AAE3E,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA4K3E,eAAO,MAAM,GAAG,sCAAqB,CAAC"}
1
+ {"version":3,"file":"Fab.d.ts","sourceRoot":"","sources":["../../../../src/fab/Fab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAa7C,OAAO,KAAK,EAAgB,QAAQ,EAAuB,MAAM,SAAS,CAAC;AAE3E,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAyM3E,eAAO,MAAM,GAAG,sCAAqB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Fab.web.d.ts","sourceRoot":"","sources":["../../../../src/fab/Fab.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAgB,QAAQ,EAAuB,MAAM,SAAS,CAAC;AAE3E,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAkP3E,eAAO,MAAM,GAAG,sCAAwB,CAAC"}
1
+ {"version":3,"file":"Fab.web.d.ts","sourceRoot":"","sources":["../../../../src/fab/Fab.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAgB,QAAQ,EAAuB,MAAM,SAAS,CAAC;AAE3E,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAyR3E,eAAO,MAAM,GAAG,sCAAwB,CAAC"}
@@ -10,24 +10,33 @@ import type { StyleProp, ViewStyle, TextStyle } from 'react-native';
10
10
  */
11
11
  export type FabVariant = 'primary' | 'secondary' | 'surface';
12
12
  /**
13
- * FAB sizes, matching Material-ish conventions but in Bloom's scale:
13
+ * FAB size presets, matching Material-ish conventions but in Bloom's scale:
14
14
  * - `small` — 40px (compact / dense layouts)
15
15
  * - `medium` — 56px (the canonical FAB; the default)
16
16
  * - `large` — 64px (high-prominence primary action)
17
17
  *
18
18
  * In the `extended` variant the height tracks the size but the FAB grows
19
19
  * horizontally to fit its icon + label as a pill.
20
+ *
21
+ * The `size` prop ALSO accepts a raw pixel `number` for an exact diameter
22
+ * between (or outside) the presets — e.g. `size={48}` for a FAB halfway between
23
+ * `small` and `medium`. A numeric size sets the diameter directly, derives the
24
+ * icon box as `round(size * 0.5)` (min 22px) and keeps the circle radius at
25
+ * `size / 2`.
20
26
  */
21
27
  export type FabSize = 'small' | 'medium' | 'large';
22
28
  /**
23
29
  * Where the FAB anchors itself.
24
30
  *
25
31
  * - `bottom-right` (default) / `bottom-left` / `top-right` / `top-left` —
26
- * the FAB pins itself to that corner of its CONTAINING block. On web this
27
- * uses `position: sticky` so it tracks the bottom of the scrolling column
28
- * (NOT the viewport edge), which is exactly what a constrained multi-column
29
- * app layout needs. On native it uses `position: absolute` within the
30
- * nearest positioned ancestor.
32
+ * the FAB pins itself to that corner of its CONTAINING block, never the
33
+ * viewport. On native it uses `position: absolute` within the nearest
34
+ * positioned ancestor. On web a `bottom-*` placement combines
35
+ * `margin-top: auto` (pins to the bottom of a flex COLUMN even when the
36
+ * content is short / not scrolling) with `position: sticky; bottom` (keeps
37
+ * it visible while a tall column scrolls). The consumer column MUST be a
38
+ * flex column that fills the available height and the FAB MUST be its last
39
+ * child.
31
40
  * - `static` — no positioning at all. The FAB is laid out inline and the
32
41
  * consumer is fully responsible for placement (e.g. wrapping it in their
33
42
  * own absolutely/sticky-positioned container). Use this when you need
@@ -35,7 +44,8 @@ export type FabSize = 'small' | 'medium' | 'large';
35
44
  *
36
45
  * CRITICAL: the positioned placements DO NOT use web `position: fixed` and are
37
46
  * never anchored to the viewport. They stay inside the containing column so the
38
- * FAB never escapes a constrained 3-column app layout and sits over a side rail.
47
+ * FAB never escapes a constrained 3-column app layout and sits over a side rail,
48
+ * and never float mid-column when the content is short.
39
49
  */
40
50
  export type FabPlacement = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'static';
41
51
  export interface FabProps {
@@ -57,7 +67,11 @@ export interface FabProps {
57
67
  */
58
68
  label?: string;
59
69
  variant?: FabVariant;
60
- size?: FabSize;
70
+ /**
71
+ * A preset (`'small' | 'medium' | 'large'`) or a raw pixel diameter
72
+ * (`number`). Defaults to `'medium'`. See {@link FabSize}.
73
+ */
74
+ size?: FabSize | number;
61
75
  /**
62
76
  * Corner of the containing block to anchor to. Defaults to `'bottom-right'`.
63
77
  * See {@link FabPlacement}. The DEFAULT never escapes the containing column
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/fab/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEpE;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAE7D;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,aAAa,GACb,WAAW,GACX,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,QAAQ;IACvB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;OAIG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,8CAA8C;IAC9C,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAUhB,wDAAwD;IACxD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAC/D,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;CACtC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/fab/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEpE;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAE7D;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,aAAa,GACb,WAAW,GACX,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,QAAQ;IACvB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAExB;;;;OAIG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,8CAA8C;IAC9C,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAUhB,wDAAwD;IACxD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAC/D,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;CACtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Fab.d.ts","sourceRoot":"","sources":["../../../../src/fab/Fab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAa7C,OAAO,KAAK,EAAgB,QAAQ,EAAuB,MAAM,SAAS,CAAC;AAE3E,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA4K3E,eAAO,MAAM,GAAG,sCAAqB,CAAC"}
1
+ {"version":3,"file":"Fab.d.ts","sourceRoot":"","sources":["../../../../src/fab/Fab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAa7C,OAAO,KAAK,EAAgB,QAAQ,EAAuB,MAAM,SAAS,CAAC;AAE3E,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAyM3E,eAAO,MAAM,GAAG,sCAAqB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Fab.web.d.ts","sourceRoot":"","sources":["../../../../src/fab/Fab.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAgB,QAAQ,EAAuB,MAAM,SAAS,CAAC;AAE3E,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAkP3E,eAAO,MAAM,GAAG,sCAAwB,CAAC"}
1
+ {"version":3,"file":"Fab.web.d.ts","sourceRoot":"","sources":["../../../../src/fab/Fab.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAgB,QAAQ,EAAuB,MAAM,SAAS,CAAC;AAE3E,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAyR3E,eAAO,MAAM,GAAG,sCAAwB,CAAC"}
@@ -10,24 +10,33 @@ import type { StyleProp, ViewStyle, TextStyle } from 'react-native';
10
10
  */
11
11
  export type FabVariant = 'primary' | 'secondary' | 'surface';
12
12
  /**
13
- * FAB sizes, matching Material-ish conventions but in Bloom's scale:
13
+ * FAB size presets, matching Material-ish conventions but in Bloom's scale:
14
14
  * - `small` — 40px (compact / dense layouts)
15
15
  * - `medium` — 56px (the canonical FAB; the default)
16
16
  * - `large` — 64px (high-prominence primary action)
17
17
  *
18
18
  * In the `extended` variant the height tracks the size but the FAB grows
19
19
  * horizontally to fit its icon + label as a pill.
20
+ *
21
+ * The `size` prop ALSO accepts a raw pixel `number` for an exact diameter
22
+ * between (or outside) the presets — e.g. `size={48}` for a FAB halfway between
23
+ * `small` and `medium`. A numeric size sets the diameter directly, derives the
24
+ * icon box as `round(size * 0.5)` (min 22px) and keeps the circle radius at
25
+ * `size / 2`.
20
26
  */
21
27
  export type FabSize = 'small' | 'medium' | 'large';
22
28
  /**
23
29
  * Where the FAB anchors itself.
24
30
  *
25
31
  * - `bottom-right` (default) / `bottom-left` / `top-right` / `top-left` —
26
- * the FAB pins itself to that corner of its CONTAINING block. On web this
27
- * uses `position: sticky` so it tracks the bottom of the scrolling column
28
- * (NOT the viewport edge), which is exactly what a constrained multi-column
29
- * app layout needs. On native it uses `position: absolute` within the
30
- * nearest positioned ancestor.
32
+ * the FAB pins itself to that corner of its CONTAINING block, never the
33
+ * viewport. On native it uses `position: absolute` within the nearest
34
+ * positioned ancestor. On web a `bottom-*` placement combines
35
+ * `margin-top: auto` (pins to the bottom of a flex COLUMN even when the
36
+ * content is short / not scrolling) with `position: sticky; bottom` (keeps
37
+ * it visible while a tall column scrolls). The consumer column MUST be a
38
+ * flex column that fills the available height and the FAB MUST be its last
39
+ * child.
31
40
  * - `static` — no positioning at all. The FAB is laid out inline and the
32
41
  * consumer is fully responsible for placement (e.g. wrapping it in their
33
42
  * own absolutely/sticky-positioned container). Use this when you need
@@ -35,7 +44,8 @@ export type FabSize = 'small' | 'medium' | 'large';
35
44
  *
36
45
  * CRITICAL: the positioned placements DO NOT use web `position: fixed` and are
37
46
  * never anchored to the viewport. They stay inside the containing column so the
38
- * FAB never escapes a constrained 3-column app layout and sits over a side rail.
47
+ * FAB never escapes a constrained 3-column app layout and sits over a side rail,
48
+ * and never float mid-column when the content is short.
39
49
  */
40
50
  export type FabPlacement = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'static';
41
51
  export interface FabProps {
@@ -57,7 +67,11 @@ export interface FabProps {
57
67
  */
58
68
  label?: string;
59
69
  variant?: FabVariant;
60
- size?: FabSize;
70
+ /**
71
+ * A preset (`'small' | 'medium' | 'large'`) or a raw pixel diameter
72
+ * (`number`). Defaults to `'medium'`. See {@link FabSize}.
73
+ */
74
+ size?: FabSize | number;
61
75
  /**
62
76
  * Corner of the containing block to anchor to. Defaults to `'bottom-right'`.
63
77
  * See {@link FabPlacement}. The DEFAULT never escapes the containing column
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/fab/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEpE;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAE7D;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,aAAa,GACb,WAAW,GACX,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,QAAQ;IACvB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;OAIG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,8CAA8C;IAC9C,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAUhB,wDAAwD;IACxD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAC/D,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;CACtC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/fab/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEpE;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAE7D;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,aAAa,GACb,WAAW,GACX,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,QAAQ;IACvB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAExB;;;;OAIG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,8CAA8C;IAC9C,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAUhB,wDAAwD;IACxD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAC/D,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;CACtC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/bloom",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -73,4 +73,21 @@ describe('Fab (native)', () => {
73
73
  );
74
74
  expect(getByText('★')).toBeTruthy();
75
75
  });
76
+
77
+ it('accepts a numeric size as a raw pixel diameter', () => {
78
+ const { getByTestId } = renderWithTheme(
79
+ <Fab testID="fab" size={48} accessibilityLabel="Add" icon={<Text>+</Text>} />,
80
+ );
81
+ // The Pressable's style is a flat-able array; the container object (first
82
+ // entry) carries the resolved geometry.
83
+ const style = getByTestId('fab').props.style as Array<
84
+ { width?: number; height?: number } | false
85
+ >;
86
+ const container = style.find(
87
+ (s): s is { width?: number; height?: number } =>
88
+ typeof s === 'object' && s !== null && 'width' in s,
89
+ );
90
+ expect(container?.width).toBe(48);
91
+ expect(container?.height).toBe(48);
92
+ });
76
93
  });
@@ -84,10 +84,23 @@ describe('Fab.web', () => {
84
84
  expect(fab.style.alignSelf).toBe('flex-end');
85
85
  });
86
86
 
87
+ it('sets margin-top: auto for bottom placements so a short column pins the FAB to the bottom', () => {
88
+ const c = mount(<Fab accessibilityLabel="Add" icon={<span>+</span>} />);
89
+ expect(getByRole(c, 'button').style.marginTop).toBe('auto');
90
+ });
91
+
92
+ it('does NOT set margin-top: auto for top placements', () => {
93
+ const c = mount(<Fab accessibilityLabel="Add" placement="top-right" icon={<span>+</span>} />);
94
+ const fab = getByRole(c, 'button');
95
+ expect(fab.style.marginTop).toBe('');
96
+ expect(fab.style.top).toBe('16px');
97
+ });
98
+
87
99
  it('applies no positioning for placement="static"', () => {
88
100
  const c = mount(<Fab accessibilityLabel="Add" placement="static" icon={<span>+</span>} />);
89
101
  const fab = getByRole(c, 'button');
90
102
  expect(fab.style.position).toBe('');
103
+ expect(fab.style.marginTop).toBe('');
91
104
  });
92
105
 
93
106
  it('renders an extended label', () => {
@@ -111,4 +124,18 @@ describe('Fab.web', () => {
111
124
  const c = mount(<Fab accessibilityLabel="Add" testID="my-fab" icon={<span>+</span>} />);
112
125
  expect(c.querySelector('[data-testid="my-fab"]')?.tagName).toBe('BUTTON');
113
126
  });
127
+
128
+ it('accepts a numeric size as a raw pixel diameter', () => {
129
+ const c = mount(<Fab accessibilityLabel="Add" size={48} icon={<span>+</span>} />);
130
+ const fab = getByRole(c, 'button');
131
+ expect(fab.style.width).toBe('48px');
132
+ expect(fab.style.height).toBe('48px');
133
+ });
134
+
135
+ it('keeps preset sizes working (medium = 56px diameter)', () => {
136
+ const c = mount(<Fab accessibilityLabel="Add" size="medium" icon={<span>+</span>} />);
137
+ const fab = getByRole(c, 'button');
138
+ expect(fab.style.width).toBe('56px');
139
+ expect(fab.style.height).toBe('56px');
140
+ });
114
141
  });
@@ -47,6 +47,15 @@ export const Extended: Story = {
47
47
  args: { label: 'Compose' },
48
48
  };
49
49
 
50
+ /**
51
+ * A raw pixel diameter via `size={number}` — here 48px, halfway between the
52
+ * `small` (40) and `medium` (56) presets. The icon box and font scale with the
53
+ * diameter automatically.
54
+ */
55
+ export const NumericSize: Story = {
56
+ args: { size: 48 },
57
+ };
58
+
50
59
  /**
51
60
  * The FAB anchored to the bottom-right of a CONSTRAINED column. On web the FAB
52
61
  * uses `position: sticky`, so it tracks the bottom of THIS column (not the
package/src/fab/Fab.tsx CHANGED
@@ -15,12 +15,41 @@ import type { FabPlacement, FabProps, FabSize, FabVariant } from './types';
15
15
 
16
16
  export type { FabProps, FabVariant, FabSize, FabPlacement } from './types';
17
17
 
18
- const SIZE_CONFIG: Record<FabSize, { diameter: number; iconBox: number; fontSize: number }> = {
19
- small: { diameter: 40, iconBox: 20, fontSize: 14 },
18
+ interface ResolvedSize {
19
+ diameter: number;
20
+ iconBox: number;
21
+ fontSize: number;
22
+ }
23
+
24
+ // Material-style FAB scale. `small` (40px) keeps a full 24px icon box so the
25
+ // glyph reads clearly; `medium` (56px) is the canonical FAB; `large` (64px) is
26
+ // the high-prominence action.
27
+ const SIZE_CONFIG: Record<FabSize, ResolvedSize> = {
28
+ small: { diameter: 40, iconBox: 24, fontSize: 14 },
20
29
  medium: { diameter: 56, iconBox: 24, fontSize: 15 },
21
30
  large: { diameter: 64, iconBox: 28, fontSize: 16 },
22
31
  };
23
32
 
33
+ const MIN_NUMERIC_ICON_BOX = 22;
34
+
35
+ /**
36
+ * Resolve a `size` prop (preset name or raw pixel diameter) to concrete pixel
37
+ * geometry. A numeric size sets the diameter directly, derives the icon box as
38
+ * `round(size * 0.5)` (clamped to a sensible minimum) and lets the circle radius
39
+ * stay `size / 2` (the container uses a full pill radius, so any square stays a
40
+ * perfect circle).
41
+ */
42
+ function resolveSize(size: FabSize | number): ResolvedSize {
43
+ if (typeof size === 'number') {
44
+ return {
45
+ diameter: size,
46
+ iconBox: Math.max(MIN_NUMERIC_ICON_BOX, Math.round(size * 0.5)),
47
+ fontSize: Math.max(13, Math.round(size * 0.27)),
48
+ };
49
+ }
50
+ return SIZE_CONFIG[size];
51
+ }
52
+
24
53
  const PILL_RADIUS = 999;
25
54
  const PRESS_SCALE = 0.94;
26
55
  const DEFAULT_OFFSET = 16;
@@ -68,7 +97,7 @@ const FabComponent: React.FC<FabProps> = ({
68
97
  zIndex = DEFAULT_Z_INDEX,
69
98
  }) => {
70
99
  const theme = useTheme();
71
- const sizeConfig = SIZE_CONFIG[size];
100
+ const sizeConfig = useMemo(() => resolveSize(size), [size]);
72
101
  const isExtended = label != null && label.length > 0;
73
102
  const content = icon ?? children;
74
103
 
@@ -96,13 +125,13 @@ const FabComponent: React.FC<FabProps> = ({
96
125
  elevation: 6,
97
126
  };
98
127
  if (isExtended) {
99
- base.paddingHorizontal = size === 'small' ? 14 : 20;
128
+ base.paddingHorizontal = sizeConfig.diameter <= 44 ? 14 : 20;
100
129
  base.gap = 8;
101
130
  } else {
102
131
  base.width = sizeConfig.diameter;
103
132
  }
104
133
  return base;
105
- }, [resolvedColors.background, sizeConfig.diameter, theme.colors.shadow, isExtended, size]);
134
+ }, [resolvedColors.background, sizeConfig.diameter, theme.colors.shadow, isExtended]);
106
135
 
107
136
  const labelTextStyle = useMemo((): TextStyle => ({
108
137
  fontSize: sizeConfig.fontSize,
@@ -14,12 +14,40 @@ import type { FabPlacement, FabProps, FabSize, FabVariant } from './types';
14
14
 
15
15
  export type { FabProps, FabVariant, FabSize, FabPlacement } from './types';
16
16
 
17
- const SIZE_CONFIG: Record<FabSize, { diameter: number; iconBox: number; fontSize: number }> = {
18
- small: { diameter: 40, iconBox: 20, fontSize: 14 },
17
+ interface ResolvedSize {
18
+ diameter: number;
19
+ iconBox: number;
20
+ fontSize: number;
21
+ }
22
+
23
+ // Material-style FAB scale. `small` (40px) keeps a full 24px icon box so the
24
+ // glyph reads clearly; `medium` (56px) is the canonical FAB; `large` (64px) is
25
+ // the high-prominence action.
26
+ const SIZE_CONFIG: Record<FabSize, ResolvedSize> = {
27
+ small: { diameter: 40, iconBox: 24, fontSize: 14 },
19
28
  medium: { diameter: 56, iconBox: 24, fontSize: 15 },
20
29
  large: { diameter: 64, iconBox: 28, fontSize: 16 },
21
30
  };
22
31
 
32
+ const MIN_NUMERIC_ICON_BOX = 22;
33
+
34
+ /**
35
+ * Resolve a `size` prop (preset name or raw pixel diameter) to concrete pixel
36
+ * geometry. Mirrors the native `resolveSize` exactly so a numeric size renders
37
+ * identically on both platforms. A numeric size sets the diameter directly and
38
+ * derives the icon box as `round(size * 0.5)` (clamped to a sensible minimum).
39
+ */
40
+ function resolveSize(size: FabSize | number): ResolvedSize {
41
+ if (typeof size === 'number') {
42
+ return {
43
+ diameter: size,
44
+ iconBox: Math.max(MIN_NUMERIC_ICON_BOX, Math.round(size * 0.5)),
45
+ fontSize: Math.max(13, Math.round(size * 0.27)),
46
+ };
47
+ }
48
+ return SIZE_CONFIG[size];
49
+ }
50
+
23
51
  const PILL_RADIUS = 999;
24
52
  const PRESS_SCALE = 0.94;
25
53
  const DEFAULT_OFFSET = 16;
@@ -92,24 +120,35 @@ function useFabCss(): void {
92
120
  * CENTRAL CONTENT COLUMN as it scrolls and never escapes to the viewport edge /
93
121
  * over a side rail in a constrained multi-column app layout.
94
122
  *
95
- * To pin a sticky element to the BOTTOM of a column it must sit at the end of
96
- * the scroll content with `align-self: flex-end` (consumer column should be a
97
- * flex column) — documented in the component's usage story. We set `bottom`
98
- * and a self-alignment so the common case works with zero consumer CSS beyond a
99
- * `flex-col` column.
123
+ * Pinning a FAB to the BOTTOM of a column needs TWO mechanisms working together,
124
+ * because sticky alone is not enough:
125
+ *
126
+ * 1. `margin-top: auto` in a flex COLUMN this consumes all the free vertical
127
+ * space, pushing the FAB to the bottom of the container EVEN WHEN THE
128
+ * CONTENT IS SHORT (e.g. an empty feed / loading spinner). Without it, a
129
+ * short column leaves the FAB at its natural flow position (mid-column) —
130
+ * which is exactly the "floating in the middle / broken" bug.
131
+ * 2. `position: sticky; bottom` — when the content is TALL and the column
132
+ * scrolls, sticky keeps the FAB pinned to the bottom of the viewport as the
133
+ * user scrolls, instead of scrolling away with the content.
134
+ *
135
+ * Horizontal placement uses `align-self` (sticky elements can't be pushed by
136
+ * `left`/`right` the way absolute ones are) plus an inline-edge margin for the
137
+ * `offset`. The consumer column MUST be a flex column that fills the available
138
+ * height, and the FAB MUST be its last child — documented in the usage story.
100
139
  */
101
140
  function placementStyle(placement: FabPlacement, offset: number): CSSProperties {
102
141
  if (placement === 'static') return {};
103
142
  const style: CSSProperties = { position: 'sticky' };
104
- if (placement === 'bottom-right' || placement === 'bottom-left') {
143
+ const isBottom = placement === 'bottom-right' || placement === 'bottom-left';
144
+ if (isBottom) {
105
145
  style.bottom = offset;
146
+ // Push the FAB to the bottom of a (flex-column) container even when the
147
+ // content is too short to scroll, so it never floats mid-column.
148
+ style.marginTop = 'auto';
106
149
  } else {
107
150
  style.top = offset;
108
151
  }
109
- // Sticky elements can't be pushed horizontally by left/right the way absolute
110
- // ones are; we self-align within the (flex column) container instead, and add
111
- // a horizontal margin for the offset so the FAB sits `offset` px from the
112
- // column's inline edge.
113
152
  if (placement === 'bottom-right' || placement === 'top-right') {
114
153
  style.alignSelf = 'flex-end';
115
154
  style.marginRight = offset;
@@ -162,7 +201,7 @@ const FabWebComponent: React.FC<FabProps> = ({
162
201
  const reactId = useId();
163
202
  const resolvedId = id ?? `bloom-fab-${reactId}`;
164
203
 
165
- const sizeConfig = SIZE_CONFIG[size];
204
+ const sizeConfig = useMemo(() => resolveSize(size), [size]);
166
205
  const isExtended = label != null && label.length > 0;
167
206
  const content = icon ?? children;
168
207
  const variantColors = useMemo(() => resolveVariant(variant, theme.colors), [variant, theme.colors]);
@@ -188,8 +227,9 @@ const FabWebComponent: React.FC<FabProps> = ({
188
227
  ...placementStyle(placement, offset),
189
228
  };
190
229
  if (isExtended) {
191
- base.paddingLeft = size === 'small' ? 14 : 20;
192
- base.paddingRight = size === 'small' ? 14 : 20;
230
+ const pad = sizeConfig.diameter <= 44 ? 14 : 20;
231
+ base.paddingLeft = pad;
232
+ base.paddingRight = pad;
193
233
  } else {
194
234
  base.width = sizeConfig.diameter;
195
235
  }
@@ -204,7 +244,6 @@ const FabWebComponent: React.FC<FabProps> = ({
204
244
  placement,
205
245
  offset,
206
246
  isExtended,
207
- size,
208
247
  ]);
209
248
 
210
249
  const handleClick = useCallback(
package/src/fab/types.ts CHANGED
@@ -12,13 +12,19 @@ import type { StyleProp, ViewStyle, TextStyle } from 'react-native';
12
12
  export type FabVariant = 'primary' | 'secondary' | 'surface';
13
13
 
14
14
  /**
15
- * FAB sizes, matching Material-ish conventions but in Bloom's scale:
15
+ * FAB size presets, matching Material-ish conventions but in Bloom's scale:
16
16
  * - `small` — 40px (compact / dense layouts)
17
17
  * - `medium` — 56px (the canonical FAB; the default)
18
18
  * - `large` — 64px (high-prominence primary action)
19
19
  *
20
20
  * In the `extended` variant the height tracks the size but the FAB grows
21
21
  * horizontally to fit its icon + label as a pill.
22
+ *
23
+ * The `size` prop ALSO accepts a raw pixel `number` for an exact diameter
24
+ * between (or outside) the presets — e.g. `size={48}` for a FAB halfway between
25
+ * `small` and `medium`. A numeric size sets the diameter directly, derives the
26
+ * icon box as `round(size * 0.5)` (min 22px) and keeps the circle radius at
27
+ * `size / 2`.
22
28
  */
23
29
  export type FabSize = 'small' | 'medium' | 'large';
24
30
 
@@ -26,11 +32,14 @@ export type FabSize = 'small' | 'medium' | 'large';
26
32
  * Where the FAB anchors itself.
27
33
  *
28
34
  * - `bottom-right` (default) / `bottom-left` / `top-right` / `top-left` —
29
- * the FAB pins itself to that corner of its CONTAINING block. On web this
30
- * uses `position: sticky` so it tracks the bottom of the scrolling column
31
- * (NOT the viewport edge), which is exactly what a constrained multi-column
32
- * app layout needs. On native it uses `position: absolute` within the
33
- * nearest positioned ancestor.
35
+ * the FAB pins itself to that corner of its CONTAINING block, never the
36
+ * viewport. On native it uses `position: absolute` within the nearest
37
+ * positioned ancestor. On web a `bottom-*` placement combines
38
+ * `margin-top: auto` (pins to the bottom of a flex COLUMN even when the
39
+ * content is short / not scrolling) with `position: sticky; bottom` (keeps
40
+ * it visible while a tall column scrolls). The consumer column MUST be a
41
+ * flex column that fills the available height and the FAB MUST be its last
42
+ * child.
34
43
  * - `static` — no positioning at all. The FAB is laid out inline and the
35
44
  * consumer is fully responsible for placement (e.g. wrapping it in their
36
45
  * own absolutely/sticky-positioned container). Use this when you need
@@ -38,7 +47,8 @@ export type FabSize = 'small' | 'medium' | 'large';
38
47
  *
39
48
  * CRITICAL: the positioned placements DO NOT use web `position: fixed` and are
40
49
  * never anchored to the viewport. They stay inside the containing column so the
41
- * FAB never escapes a constrained 3-column app layout and sits over a side rail.
50
+ * FAB never escapes a constrained 3-column app layout and sits over a side rail,
51
+ * and never float mid-column when the content is short.
42
52
  */
43
53
  export type FabPlacement =
44
54
  | 'bottom-right'
@@ -69,7 +79,11 @@ export interface FabProps {
69
79
  label?: string;
70
80
 
71
81
  variant?: FabVariant;
72
- size?: FabSize;
82
+ /**
83
+ * A preset (`'small' | 'medium' | 'large'`) or a raw pixel diameter
84
+ * (`number`). Defaults to `'medium'`. See {@link FabSize}.
85
+ */
86
+ size?: FabSize | number;
73
87
 
74
88
  /**
75
89
  * Corner of the containing block to anchor to. Defaults to `'bottom-right'`.