react-native-terra-ui 0.11.1 → 0.11.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.11.2](https://github.com/earthlin9/react-native-terra-ui/compare/v0.11.1...v0.11.2) (2026-09-12)
4
+
5
+ ### Features
6
+
7
+ * **ui:** [badge] add offset prop and enlarge the indicator ([da293fa](https://github.com/earthlin9/react-native-terra-ui/commit/da293fa887d81cfeaf45f19067734e05ac4c6320))
8
+
3
9
  ## [0.11.1](https://github.com/earthlin9/react-native-terra-ui/compare/v0.11.0...v0.11.1) (2026-09-12)
4
10
 
5
11
  ### Features
@@ -4,7 +4,8 @@ import { View } from "react-native-unistyles/components/native/View";
4
4
  import { forwardRef } from "react";
5
5
  import { StyleSheet } from "react-native-unistyles";
6
6
  import { BadgeIndicator } from "./parts/BadgeIndicator.js";
7
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
+ import { getAnchorPosition } from "./utils.js";
8
+
8
9
  /**
9
10
  * Overlays a count or status indicator on one corner of the element it wraps.
10
11
  *
@@ -15,14 +16,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
16
  * ```
16
17
  *
17
18
  * The child renders untouched — `Badge` contributes the positioning context and
18
- * the overlay, nothing else.
19
+ * the overlay, nothing else. A round child usually wants a negative `offset`,
20
+ * since the corner being anchored to is the bounding box's, not the circle's.
19
21
  */
22
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
23
  const Badge = /*#__PURE__*/forwardRef(function Badge({
21
24
  children,
22
25
  placement = "top-right",
23
26
  label,
24
27
  color = "danger",
25
28
  size = "md",
29
+ offset = 0,
26
30
  isVisible = true,
27
31
  fullWidth = false,
28
32
  accessibilityLabel,
@@ -32,8 +36,6 @@ const Badge = /*#__PURE__*/forwardRef(function Badge({
32
36
  const _styles = styles;
33
37
  {
34
38
  const styles = _styles.useVariants({
35
- placement,
36
- size,
37
39
  fullWidth
38
40
  });
39
41
  return (
@@ -45,7 +47,7 @@ const Badge = /*#__PURE__*/forwardRef(function Badge({
45
47
  ...rest,
46
48
  children: [children, isVisible ? /*#__PURE__*/_jsx(View, {
47
49
  pointerEvents: "box-none",
48
- style: styles.anchor,
50
+ style: [styles.anchor, getAnchorPosition(placement, size, offset)],
49
51
  children: /*#__PURE__*/_jsx(BadgeIndicator, {
50
52
  label: label,
51
53
  color: color,
@@ -61,14 +63,10 @@ export { Badge };
61
63
 
62
64
  // ─── Styles ───────────────────────────────────────────────────────────────────
63
65
  //
64
- // The indicator is positioned by absolute insets picked from `size`, never by
65
- // measuring the child its overhang is a function of its own size, not the
66
- // child's. Which edges those insets land on is `placement`, and the magnitude
67
- // is `size`, so the two interact and the offsets are compound variants.
68
- //
69
- // The inset equals the dot's radius, which puts a dot's centre exactly on the
70
- // child's corner. A pill keeps the same anchored edges and grows inward from
71
- // them, so a longer label extends across the child rather than away from it.
66
+ // The indicator's insets are computed in `getAnchorPosition`, not declared here:
67
+ // `offset` is an open-ended number, so it could never be a variant condition,
68
+ // and the position involves no theme tokens at all. That leaves this stylesheet
69
+ // with only what genuinely varies declaratively.
72
70
  const styles = StyleSheet.create(() => ({
73
71
  wrapper: {
74
72
  position: "relative",
@@ -83,92 +81,12 @@ const styles = StyleSheet.create(() => ({
83
81
  false: {
84
82
  alignSelf: "flex-start"
85
83
  }
86
- },
87
- placement: {
88
- "top-right": {},
89
- "top-left": {},
90
- "bottom-right": {},
91
- "bottom-left": {}
92
- },
93
- size: {
94
- sm: {},
95
- md: {}
96
84
  }
97
85
  },
98
86
  uni__dependencies: [4]
99
87
  },
100
88
  anchor: {
101
- position: "absolute",
102
- variants: {
103
- placement: {
104
- "top-right": {},
105
- "top-left": {},
106
- "bottom-right": {},
107
- "bottom-left": {}
108
- },
109
- size: {
110
- sm: {},
111
- md: {}
112
- }
113
- },
114
- compoundVariants: [{
115
- placement: "top-right",
116
- size: "sm",
117
- styles: {
118
- top: -5,
119
- right: -5
120
- }
121
- }, {
122
- placement: "top-right",
123
- size: "md",
124
- styles: {
125
- top: -6,
126
- right: -6
127
- }
128
- }, {
129
- placement: "top-left",
130
- size: "sm",
131
- styles: {
132
- top: -5,
133
- left: -5
134
- }
135
- }, {
136
- placement: "top-left",
137
- size: "md",
138
- styles: {
139
- top: -6,
140
- left: -6
141
- }
142
- }, {
143
- placement: "bottom-right",
144
- size: "sm",
145
- styles: {
146
- bottom: -5,
147
- right: -5
148
- }
149
- }, {
150
- placement: "bottom-right",
151
- size: "md",
152
- styles: {
153
- bottom: -6,
154
- right: -6
155
- }
156
- }, {
157
- placement: "bottom-left",
158
- size: "sm",
159
- styles: {
160
- bottom: -5,
161
- left: -5
162
- }
163
- }, {
164
- placement: "bottom-left",
165
- size: "md",
166
- styles: {
167
- bottom: -6,
168
- left: -6
169
- }
170
- }],
171
- uni__dependencies: [4]
89
+ position: "absolute"
172
90
  }
173
91
  }));
174
92
  //# sourceMappingURL=Badge.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","StyleSheet","BadgeIndicator","jsx","_jsx","jsxs","_jsxs","Badge","children","placement","label","color","size","isVisible","fullWidth","accessibilityLabel","style","rest","ref","_styles","styles","useVariants","View","wrapper","pointerEvents","anchor","create","position","variants","true","alignSelf","false","sm","md","uni__dependencies","compoundVariants","top","right","left","bottom"],"sourceRoot":"../../../../src","sources":["components/badge/Badge.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["forwardRef","StyleSheet","BadgeIndicator","getAnchorPosition","jsx","_jsx","jsxs","_jsxs","Badge","children","placement","label","color","size","offset","isVisible","fullWidth","accessibilityLabel","style","rest","ref","_styles","styles","useVariants","View","wrapper","pointerEvents","anchor","create","position","variants","true","alignSelf","false","uni__dependencies"],"sourceRoot":"../../../../src","sources":["components/badge/Badge.tsx"],"mappings":";;;AAAA,SAA4BA,UAAU,QAAQ,OAAO;AAGrD,SAASC,UAAU,QAAQ,wBAAwB;AAEnD,SAASC,cAAc;AAEvB,SAASC,iBAAiB;;AAE1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAZA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAaA,MAAMC,KAAK,gBAAGR,UAAU,CAAwC,SAASQ,KAAKA,CAC5E;EACEC,QAAQ;EACRC,SAAS,GAAG,WAAW;EACvBC,KAAK;EACLC,KAAK,GAAG,QAAQ;EAChBC,IAAI,GAAG,IAAI;EACXC,MAAM,GAAG,CAAC;EACVC,SAAS,GAAG,IAAI;EAChBC,SAAS,GAAG,KAAK;EACjBC,kBAAkB;EAClBC,KAAK;EACL,GAAGC;AACL,CAAC,EACDC,GAAG,EACH;EAAA,MAAAC,OAAA,GAAAC,MAAA;EAAA;IAAA,MAAAA,MAAA,GAAAD,OAAA,CAAAE,WAAA,CACmB;MAAEP;IAAU,CAAC;IAEhC;MAAA;MACE;MACAT,KAAA,CAACiB,IAAI;QAACJ,GAAG,EAAEA,GAAI;QAACF,KAAK,EAAE,CAACI,MAAM,CAACG,OAAO,EAAEP,KAAK,CAAE;QAAA,GAAKC,IAAI;QAAAV,QAAA,GACrDA,QAAQ,EACRM,SAAS,gBACRV,IAAA,CAACmB,IAAI;UAACE,aAAa,EAAC,UAAU;UAACR,KAAK,EAAE,CAACI,MAAM,CAACK,MAAM,EAAExB,iBAAiB,CAACO,SAAS,EAAEG,IAAI,EAAEC,MAAM,CAAC,CAAE;UAAAL,QAAA,eAChGJ,IAAA,CAACH,cAAc;YAACS,KAAK,EAAEA,KAAM;YAACC,KAAK,EAAEA,KAAM;YAACC,IAAI,EAAEA,IAAK;YAACI,kBAAkB,EAAEA;UAAmB,CAAE;QAAC,CAC9F,CAAC,GACL,IAAI;MAAA,CACJ;IAAC;EACP;AACJ,CAAC,CAAC;AAEF,SAAST,KAAK;;AAEd;AACA;AACA;AACA;AACA;AACA;AACA,MAAMc,MAAM,GAAGrB,UAAU,CAAC2B,MAAM,CAAC,OAAO;EACtCH,OAAO,EAAE;IACPI,QAAQ,EAAE,UAAU;IACpBC,QAAQ,EAAE;MACR;MACA;MACA;MACAd,SAAS,EAAE;QACTe,IAAI,EAAE;UAAEC,SAAS,EAAE;QAAU,CAAC;QAC9BC,KAAK,EAAE;UAAED,SAAS,EAAE;QAAa;MACnC;IACF,CAAC;IAAAE,iBAAA;EACH,CAAC;EACDP,MAAM,EAAE;IACNE,QAAQ,EAAE;EACZ;AACF,CAAC,CAAC,CAAC","ignoreList":[]}
@@ -18,7 +18,8 @@ const FG_TOKEN = {
18
18
  };
19
19
  const LABEL_VARIANT = {
20
20
  sm: "label-sm",
21
- md: "label-md"
21
+ md: "label-md",
22
+ lg: "label-lg"
22
23
  };
23
24
  /**
24
25
  * The overlay itself: a dot, or a pill carrying the label. Owns the paint, the
@@ -109,6 +110,9 @@ const styles = StyleSheet.create(theme => {
109
110
  },
110
111
  md: {
111
112
  borderWidth: 2
113
+ },
114
+ lg: {
115
+ borderWidth: 2
112
116
  }
113
117
  },
114
118
  color: {
@@ -131,16 +135,23 @@ const styles = StyleSheet.create(theme => {
131
135
  },
132
136
  uni__dependencies: [0, 4]
133
137
  },
138
+ // These diameters are mirrored by `DOT_SIZE` in `../utils.ts`, which the
139
+ // anchor arithmetic reads. The Babel plugin needs them literal here, so a
140
+ // test asserts the two stay equal.
134
141
  dot: {
135
142
  variants: {
136
143
  size: {
137
144
  sm: {
138
- width: 10,
139
- height: 10
140
- },
141
- md: {
142
145
  width: 12,
143
146
  height: 12
147
+ },
148
+ md: {
149
+ width: 16,
150
+ height: 16
151
+ },
152
+ lg: {
153
+ width: 20,
154
+ height: 20
144
155
  }
145
156
  }
146
157
  },
@@ -150,14 +161,19 @@ const styles = StyleSheet.create(theme => {
150
161
  variants: {
151
162
  size: {
152
163
  sm: {
153
- height: 16,
154
- minWidth: 16,
155
- paddingHorizontal: 4
164
+ height: 18,
165
+ minWidth: 18,
166
+ paddingHorizontal: 5
156
167
  },
157
168
  md: {
158
- height: 20,
159
- minWidth: 20,
169
+ height: 22,
170
+ minWidth: 22,
160
171
  paddingHorizontal: 6
172
+ },
173
+ lg: {
174
+ height: 26,
175
+ minWidth: 26,
176
+ paddingHorizontal: 8
161
177
  }
162
178
  }
163
179
  },
@@ -181,6 +197,11 @@ const styles = StyleSheet.create(theme => {
181
197
  fontSize: theme.typography.variants["label-md"].fontSize,
182
198
  lineHeight: theme.typography.variants["label-md"].lineHeight,
183
199
  letterSpacing: theme.typography.variants["label-md"].letterSpacing
200
+ },
201
+ lg: {
202
+ fontSize: theme.typography.variants["label-lg"].fontSize,
203
+ lineHeight: theme.typography.variants["label-lg"].lineHeight,
204
+ letterSpacing: theme.typography.variants["label-lg"].letterSpacing
184
205
  }
185
206
  }
186
207
  },
@@ -1 +1 @@
1
- {"version":3,"names":["StyleSheet","useUnistyles","resolveThemeColor","FONT_WEIGHT_VALUE","SYSTEM_FONT","getCustomBadgeColors","hasLabel","jsx","_jsx","SCHEME_NAMES","Set","FG_TOKEN","primary","secondary","success","warning","danger","LABEL_VARIANT","sm","md","BadgeIndicator","label","color","size","accessibilityLabel","theme","_styles","styles","useVariants","custom","has","labelled","foreground","fg","announced","String","undefined","accessibility","accessible","accessibilityElementsHidden","importantForAccessibility","View","style","indicator","pill","dot","backgroundColor","bg","children","RNText","maxFontSizeMultiplier","typography","variants","numberOfLines","create","c","labelFont","fonts","semibold","isSystemLabelFont","alignItems","justifyContent","borderRadius","radius","full","borderColor","borderWidth","uni__dependencies","width","height","minWidth","paddingHorizontal","textAlign","fontFamily","fontWeight","fontSize","lineHeight","letterSpacing"],"sourceRoot":"../../../../../src","sources":["components/badge/parts/BadgeIndicator.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["StyleSheet","useUnistyles","resolveThemeColor","FONT_WEIGHT_VALUE","SYSTEM_FONT","getCustomBadgeColors","hasLabel","jsx","_jsx","SCHEME_NAMES","Set","FG_TOKEN","primary","secondary","success","warning","danger","LABEL_VARIANT","sm","md","lg","BadgeIndicator","label","color","size","accessibilityLabel","theme","_styles","styles","useVariants","custom","has","labelled","foreground","fg","announced","String","undefined","accessibility","accessible","accessibilityElementsHidden","importantForAccessibility","View","style","indicator","pill","dot","backgroundColor","bg","children","RNText","maxFontSizeMultiplier","typography","variants","numberOfLines","create","c","labelFont","fonts","semibold","isSystemLabelFont","alignItems","justifyContent","borderRadius","radius","full","borderColor","borderWidth","uni__dependencies","width","height","minWidth","paddingHorizontal","textAlign","fontFamily","fontWeight","fontSize","lineHeight","letterSpacing"],"sourceRoot":"../../../../../src","sources":["components/badge/parts/BadgeIndicator.tsx"],"mappings":"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","ignoreList":[]}
@@ -22,4 +22,62 @@ export function getCustomBadgeColors(literal) {
22
22
  export function hasLabel(label) {
23
23
  return label !== undefined && label !== "";
24
24
  }
25
+
26
+ /**
27
+ * Outer diameter of the dot per size. The indicator's own stylesheet repeats
28
+ * these as literals — the unistyles Babel plugin reads that object statically,
29
+ * so it cannot reference this table — and `anchorOffsetsMatchDotRadius` in the
30
+ * test suite is what keeps the two in step.
31
+ */
32
+ export const DOT_SIZE = {
33
+ sm: 12,
34
+ md: 16,
35
+ lg: 20
36
+ };
37
+ /**
38
+ * Absolute insets for the indicator, in pure arithmetic rather than one
39
+ * compound variant per (placement, size) cell: `offset` is an open-ended number
40
+ * and could never be a variant condition, and nothing here touches the theme.
41
+ *
42
+ * The base inset is the dot's radius, which puts a dot's centre exactly on the
43
+ * child's bounding-box corner. `offset` moves it from there — positive away
44
+ * from the child's centre, negative toward it.
45
+ */
46
+ export function getAnchorPosition(placement, size, offset = 0) {
47
+ const base = DOT_SIZE[size] / 2;
48
+ const {
49
+ x,
50
+ y
51
+ } = typeof offset === "number" ? {
52
+ x: offset,
53
+ y: offset
54
+ } : {
55
+ x: offset.x ?? 0,
56
+ y: offset.y ?? 0
57
+ };
58
+ const insetX = -(base + x);
59
+ const insetY = -(base + y);
60
+ switch (placement) {
61
+ case "top-left":
62
+ return {
63
+ top: insetY,
64
+ left: insetX
65
+ };
66
+ case "bottom-right":
67
+ return {
68
+ bottom: insetY,
69
+ right: insetX
70
+ };
71
+ case "bottom-left":
72
+ return {
73
+ bottom: insetY,
74
+ left: insetX
75
+ };
76
+ default:
77
+ return {
78
+ top: insetY,
79
+ right: insetX
80
+ };
81
+ }
82
+ }
25
83
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["readableOn","getCustomBadgeColors","literal","bg","fg","hasLabel","label","undefined"],"sourceRoot":"../../../../src","sources":["components/badge/utils.ts"],"mappings":";;AAAA,SAASA,UAAU;;AAEnB;AACA;AACA;;AAOA;AACA,OAAO,SAASC,oBAAoBA,CAACC,OAAe,EAAqB;EACvE,OAAO;IAAEC,EAAE,EAAED,OAAO;IAAEE,EAAE,EAAEJ,UAAU,CAACE,OAAO;EAAE,CAAC;AACjD;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,QAAQA,CAACC,KAAkC,EAA4B;EACrF,OAAOA,KAAK,KAAKC,SAAS,IAAID,KAAK,KAAK,EAAE;AAC5C","ignoreList":[]}
1
+ {"version":3,"names":["readableOn","getCustomBadgeColors","literal","bg","fg","hasLabel","label","undefined","DOT_SIZE","sm","md","lg","getAnchorPosition","placement","size","offset","base","x","y","insetX","insetY","top","left","bottom","right"],"sourceRoot":"../../../../src","sources":["components/badge/utils.ts"],"mappings":";;AAAA,SAASA,UAAU;;AAGnB;AACA;AACA;;AAOA;AACA,OAAO,SAASC,oBAAoBA,CAACC,OAAe,EAAqB;EACvE,OAAO;IAAEC,EAAE,EAAED,OAAO;IAAEE,EAAE,EAAEJ,UAAU,CAACE,OAAO;EAAE,CAAC;AACjD;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,QAAQA,CAACC,KAAkC,EAA4B;EACrF,OAAOA,KAAK,KAAKC,SAAS,IAAID,KAAK,KAAK,EAAE;AAC5C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAME,QAAmC,GAAG;EACjDC,EAAE,EAAE,EAAE;EACNC,EAAE,EAAE,EAAE;EACNC,EAAE,EAAE;AACN,CAAC;AASD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAC/BC,SAAyB,EACzBC,IAAe,EACfC,MAA2C,GAAG,CAAC,EAC/B;EAChB,MAAMC,IAAI,GAAGR,QAAQ,CAACM,IAAI,CAAC,GAAG,CAAC;EAC/B,MAAM;IAAEG,CAAC;IAAEC;EAAE,CAAC,GACZ,OAAOH,MAAM,KAAK,QAAQ,GAAG;IAAEE,CAAC,EAAEF,MAAM;IAAEG,CAAC,EAAEH;EAAO,CAAC,GAAG;IAAEE,CAAC,EAAEF,MAAM,CAACE,CAAC,IAAI,CAAC;IAAEC,CAAC,EAAEH,MAAM,CAACG,CAAC,IAAI;EAAE,CAAC;EAEhG,MAAMC,MAAM,GAAG,EAAEH,IAAI,GAAGC,CAAC,CAAC;EAC1B,MAAMG,MAAM,GAAG,EAAEJ,IAAI,GAAGE,CAAC,CAAC;EAE1B,QAAQL,SAAS;IACf,KAAK,UAAU;MACb,OAAO;QAAEQ,GAAG,EAAED,MAAM;QAAEE,IAAI,EAAEH;MAAO,CAAC;IACtC,KAAK,cAAc;MACjB,OAAO;QAAEI,MAAM,EAAEH,MAAM;QAAEI,KAAK,EAAEL;MAAO,CAAC;IAC1C,KAAK,aAAa;MAChB,OAAO;QAAEI,MAAM,EAAEH,MAAM;QAAEE,IAAI,EAAEH;MAAO,CAAC;IACzC;MACE,OAAO;QAAEE,GAAG,EAAED,MAAM;QAAEI,KAAK,EAAEL;MAAO,CAAC;EACzC;AACF","ignoreList":[]}
@@ -9,7 +9,8 @@ import type { BadgeProps } from "./types.js";
9
9
  * ```
10
10
  *
11
11
  * The child renders untouched — `Badge` contributes the positioning context and
12
- * the overlay, nothing else.
12
+ * the overlay, nothing else. A round child usually wants a negative `offset`,
13
+ * since the corner being anchored to is the bounding box's, not the circle's.
13
14
  */
14
15
  declare const Badge: import("react").ForwardRefExoticComponent<BadgeProps & import("react").RefAttributes<import("react-native/types_generated/src/private/webapis/dom/nodes/ReactNativeElement").default>>;
15
16
  export { Badge };
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../../../src/components/badge/Badge.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAS,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,KAAK,wLA4BT,CAAC;AAEH,OAAO,EAAE,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../../../src/components/badge/Badge.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAS,CAAC;AAG1C;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,KAAK,wLA6BT,CAAC;AAEH,OAAO,EAAE,KAAK,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"BadgeIndicator.d.ts","sourceRoot":"","sources":["../../../../../../src/components/badge/parts/BadgeIndicator.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAU,CAAC;AAqBtD,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,4CAA4C,mBAAmB,gCA0C7F,CAAC"}
1
+ {"version":3,"file":"BadgeIndicator.d.ts","sourceRoot":"","sources":["../../../../../../src/components/badge/parts/BadgeIndicator.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAU,CAAC;AAsBtD,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,4CAA4C,mBAAmB,gCA0C7F,CAAC"}
@@ -3,7 +3,7 @@ import type { ViewProps } from "react-native";
3
3
  /** Corner of the wrapped child the indicator is anchored to. */
4
4
  export type BadgePlacement = "top-right" | "top-left" | "bottom-right" | "bottom-left";
5
5
  /** Scale of the dot, pill, and label. */
6
- export type BadgeSize = "sm" | "md";
6
+ export type BadgeSize = "sm" | "md" | "lg";
7
7
  /**
8
8
  * Semantic color scheme, or a raw CSS color literal (`#fff`, `rgb(...)`, `hsl(...)`).
9
9
  * A literal paints the indicator with that exact value and derives a readable
@@ -30,6 +30,19 @@ export interface BadgeProps extends ViewProps {
30
30
  color?: BadgeColor;
31
31
  /** Scale of the indicator. Defaults to `'md'`. */
32
32
  size?: BadgeSize;
33
+ /**
34
+ * Nudges the indicator along both axes from the corner `placement` picked.
35
+ * Positive moves it away from the child's centre, negative pulls it in.
36
+ * A number applies to both axes; `{ x, y }` sets them separately.
37
+ *
38
+ * The corner it anchors to is the child's **bounding box**, so a round child
39
+ * needs a negative offset to bring the indicator onto the visible edge — a
40
+ * circle only meets its box at 45°, about `0.21 × width` away. Defaults to `0`.
41
+ */
42
+ offset?: number | {
43
+ x?: number;
44
+ y?: number;
45
+ };
33
46
  /** Renders the indicator. The child renders either way. Defaults to `true`. */
34
47
  isVisible?: boolean;
35
48
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/components/badge/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,aAAa,CAAC;AAEvF,yCAAyC;AACzC,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpC;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,WAAW,GACX,SAAS,GACT,SAAS,GACT,QAAQ,GAER,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,mFAAmF;IACnF,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,oEAAoE;IACpE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,kDAAkD;IAClD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/components/badge/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,aAAa,CAAC;AAEvF,yCAAyC;AACzC,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,WAAW,GACX,SAAS,GACT,SAAS,GACT,QAAQ,GAER,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,mFAAmF;IACnF,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,oEAAoE;IACpE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,kDAAkD;IAClD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B"}
@@ -1,3 +1,4 @@
1
+ import type { BadgePlacement, BadgeSize } from "./types.js";
1
2
  export interface CustomBadgeColors {
2
3
  bg: string;
3
4
  fg: string;
@@ -10,4 +11,30 @@ export declare function getCustomBadgeColors(literal: string): CustomBadgeColors
10
11
  * `isVisible` rather than relying on falsiness.
11
12
  */
12
13
  export declare function hasLabel(label: string | number | undefined): label is string | number;
14
+ /**
15
+ * Outer diameter of the dot per size. The indicator's own stylesheet repeats
16
+ * these as literals — the unistyles Babel plugin reads that object statically,
17
+ * so it cannot reference this table — and `anchorOffsetsMatchDotRadius` in the
18
+ * test suite is what keeps the two in step.
19
+ */
20
+ export declare const DOT_SIZE: Record<BadgeSize, number>;
21
+ export interface AnchorPosition {
22
+ top?: number;
23
+ right?: number;
24
+ bottom?: number;
25
+ left?: number;
26
+ }
27
+ /**
28
+ * Absolute insets for the indicator, in pure arithmetic rather than one
29
+ * compound variant per (placement, size) cell: `offset` is an open-ended number
30
+ * and could never be a variant condition, and nothing here touches the theme.
31
+ *
32
+ * The base inset is the dot's radius, which puts a dot's centre exactly on the
33
+ * child's bounding-box corner. `offset` moves it from there — positive away
34
+ * from the child's centre, negative toward it.
35
+ */
36
+ export declare function getAnchorPosition(placement: BadgePlacement, size: BadgeSize, offset?: number | {
37
+ x?: number;
38
+ y?: number;
39
+ }): AnchorPosition;
13
40
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/components/badge/utils.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,0FAA0F;AAC1F,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,MAAM,GAAG,MAAM,CAErF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/components/badge/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAS,CAAC;AAMzD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,0FAA0F;AAC1F,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,MAAM,GAAG,MAAM,CAErF;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAI9C,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE,SAAS,EACf,MAAM,GAAE,MAAM,GAAG;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAM,GAC9C,cAAc,CAkBhB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-terra-ui",
3
- "version": "0.11.1",
3
+ "version": "0.11.2",
4
4
  "description": "Themeable React Native UI components built on react-native-unistyles",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -5,6 +5,7 @@ import { StyleSheet } from "react-native-unistyles";
5
5
 
6
6
  import { BadgeIndicator } from "./parts/BadgeIndicator";
7
7
  import type { BadgeProps } from "./types";
8
+ import { getAnchorPosition } from "./utils";
8
9
 
9
10
  /**
10
11
  * Overlays a count or status indicator on one corner of the element it wraps.
@@ -16,7 +17,8 @@ import type { BadgeProps } from "./types";
16
17
  * ```
17
18
  *
18
19
  * The child renders untouched — `Badge` contributes the positioning context and
19
- * the overlay, nothing else.
20
+ * the overlay, nothing else. A round child usually wants a negative `offset`,
21
+ * since the corner being anchored to is the bounding box's, not the circle's.
20
22
  */
21
23
  const Badge = forwardRef<ComponentRef<typeof View>, BadgeProps>(function Badge(
22
24
  {
@@ -25,6 +27,7 @@ const Badge = forwardRef<ComponentRef<typeof View>, BadgeProps>(function Badge(
25
27
  label,
26
28
  color = "danger",
27
29
  size = "md",
30
+ offset = 0,
28
31
  isVisible = true,
29
32
  fullWidth = false,
30
33
  accessibilityLabel,
@@ -33,14 +36,14 @@ const Badge = forwardRef<ComponentRef<typeof View>, BadgeProps>(function Badge(
33
36
  },
34
37
  ref
35
38
  ) {
36
- styles.useVariants({ placement, size, fullWidth });
39
+ styles.useVariants({ fullWidth });
37
40
 
38
41
  return (
39
42
  // `style` last so an explicit `alignSelf` beats `fullWidth`.
40
43
  <View ref={ref} style={[styles.wrapper, style]} {...rest}>
41
44
  {children}
42
45
  {isVisible ? (
43
- <View pointerEvents="box-none" style={styles.anchor}>
46
+ <View pointerEvents="box-none" style={[styles.anchor, getAnchorPosition(placement, size, offset)]}>
44
47
  <BadgeIndicator label={label} color={color} size={size} accessibilityLabel={accessibilityLabel} />
45
48
  </View>
46
49
  ) : null}
@@ -52,14 +55,10 @@ export { Badge };
52
55
 
53
56
  // ─── Styles ───────────────────────────────────────────────────────────────────
54
57
  //
55
- // The indicator is positioned by absolute insets picked from `size`, never by
56
- // measuring the child its overhang is a function of its own size, not the
57
- // child's. Which edges those insets land on is `placement`, and the magnitude
58
- // is `size`, so the two interact and the offsets are compound variants.
59
- //
60
- // The inset equals the dot's radius, which puts a dot's centre exactly on the
61
- // child's corner. A pill keeps the same anchored edges and grows inward from
62
- // them, so a longer label extends across the child rather than away from it.
58
+ // The indicator's insets are computed in `getAnchorPosition`, not declared here:
59
+ // `offset` is an open-ended number, so it could never be a variant condition,
60
+ // and the position involves no theme tokens at all. That leaves this stylesheet
61
+ // with only what genuinely varies declaratively.
63
62
  const styles = StyleSheet.create(() => ({
64
63
  wrapper: {
65
64
  position: "relative",
@@ -71,41 +70,9 @@ const styles = StyleSheet.create(() => ({
71
70
  true: { alignSelf: "stretch" },
72
71
  false: { alignSelf: "flex-start" },
73
72
  },
74
- placement: {
75
- "top-right": {},
76
- "top-left": {},
77
- "bottom-right": {},
78
- "bottom-left": {},
79
- },
80
- size: {
81
- sm: {},
82
- md: {},
83
- },
84
73
  },
85
74
  },
86
75
  anchor: {
87
76
  position: "absolute",
88
- variants: {
89
- placement: {
90
- "top-right": {},
91
- "top-left": {},
92
- "bottom-right": {},
93
- "bottom-left": {},
94
- },
95
- size: {
96
- sm: {},
97
- md: {},
98
- },
99
- },
100
- compoundVariants: [
101
- { placement: "top-right", size: "sm", styles: { top: -5, right: -5 } },
102
- { placement: "top-right", size: "md", styles: { top: -6, right: -6 } },
103
- { placement: "top-left", size: "sm", styles: { top: -5, left: -5 } },
104
- { placement: "top-left", size: "md", styles: { top: -6, left: -6 } },
105
- { placement: "bottom-right", size: "sm", styles: { bottom: -5, right: -5 } },
106
- { placement: "bottom-right", size: "md", styles: { bottom: -6, right: -6 } },
107
- { placement: "bottom-left", size: "sm", styles: { bottom: -5, left: -5 } },
108
- { placement: "bottom-left", size: "md", styles: { bottom: -6, left: -6 } },
109
- ],
110
77
  },
111
78
  }));
@@ -24,6 +24,7 @@ const FG_TOKEN: Record<BadgeScheme, ColorToken> = {
24
24
  const LABEL_VARIANT: Record<BadgeSize, RoleTextVariant> = {
25
25
  sm: "label-sm",
26
26
  md: "label-md",
27
+ lg: "label-lg",
27
28
  };
28
29
 
29
30
  export interface BadgeIndicatorProps {
@@ -114,6 +115,7 @@ const styles = StyleSheet.create((theme) => {
114
115
  size: {
115
116
  sm: { borderWidth: 1.5 },
116
117
  md: { borderWidth: 2 },
118
+ lg: { borderWidth: 2 },
117
119
  },
118
120
  color: {
119
121
  primary: { backgroundColor: c["accent.solid.bg"] },
@@ -124,19 +126,24 @@ const styles = StyleSheet.create((theme) => {
124
126
  },
125
127
  },
126
128
  },
129
+ // These diameters are mirrored by `DOT_SIZE` in `../utils.ts`, which the
130
+ // anchor arithmetic reads. The Babel plugin needs them literal here, so a
131
+ // test asserts the two stay equal.
127
132
  dot: {
128
133
  variants: {
129
134
  size: {
130
- sm: { width: 10, height: 10 },
131
- md: { width: 12, height: 12 },
135
+ sm: { width: 12, height: 12 },
136
+ md: { width: 16, height: 16 },
137
+ lg: { width: 20, height: 20 },
132
138
  },
133
139
  },
134
140
  },
135
141
  pill: {
136
142
  variants: {
137
143
  size: {
138
- sm: { height: 16, minWidth: 16, paddingHorizontal: 4 },
139
- md: { height: 20, minWidth: 20, paddingHorizontal: 6 },
144
+ sm: { height: 18, minWidth: 18, paddingHorizontal: 5 },
145
+ md: { height: 22, minWidth: 22, paddingHorizontal: 6 },
146
+ lg: { height: 26, minWidth: 26, paddingHorizontal: 8 },
140
147
  },
141
148
  },
142
149
  },
@@ -159,6 +166,11 @@ const styles = StyleSheet.create((theme) => {
159
166
  lineHeight: theme.typography.variants["label-md"].lineHeight,
160
167
  letterSpacing: theme.typography.variants["label-md"].letterSpacing,
161
168
  },
169
+ lg: {
170
+ fontSize: theme.typography.variants["label-lg"].fontSize,
171
+ lineHeight: theme.typography.variants["label-lg"].lineHeight,
172
+ letterSpacing: theme.typography.variants["label-lg"].letterSpacing,
173
+ },
162
174
  },
163
175
  },
164
176
  },
@@ -5,7 +5,7 @@ import type { ViewProps } from "react-native";
5
5
  export type BadgePlacement = "top-right" | "top-left" | "bottom-right" | "bottom-left";
6
6
 
7
7
  /** Scale of the dot, pill, and label. */
8
- export type BadgeSize = "sm" | "md";
8
+ export type BadgeSize = "sm" | "md" | "lg";
9
9
 
10
10
  /**
11
11
  * Semantic color scheme, or a raw CSS color literal (`#fff`, `rgb(...)`, `hsl(...)`).
@@ -41,6 +41,16 @@ export interface BadgeProps extends ViewProps {
41
41
  color?: BadgeColor;
42
42
  /** Scale of the indicator. Defaults to `'md'`. */
43
43
  size?: BadgeSize;
44
+ /**
45
+ * Nudges the indicator along both axes from the corner `placement` picked.
46
+ * Positive moves it away from the child's centre, negative pulls it in.
47
+ * A number applies to both axes; `{ x, y }` sets them separately.
48
+ *
49
+ * The corner it anchors to is the child's **bounding box**, so a round child
50
+ * needs a negative offset to bring the indicator onto the visible edge — a
51
+ * circle only meets its box at 45°, about `0.21 × width` away. Defaults to `0`.
52
+ */
53
+ offset?: number | { x?: number; y?: number };
44
54
  /** Renders the indicator. The child renders either way. Defaults to `true`. */
45
55
  isVisible?: boolean;
46
56
  /**
@@ -1,4 +1,5 @@
1
1
  import { readableOn } from "#utils/color-utils";
2
+ import type { BadgePlacement, BadgeSize } from "./types";
2
3
 
3
4
  // A custom color literal (hex/rgb/hsl) isn't a bounded set of options, so it
4
5
  // can't be a unistyles variant condition — it's derived here instead, the same
@@ -22,3 +23,55 @@ export function getCustomBadgeColors(literal: string): CustomBadgeColors {
22
23
  export function hasLabel(label: string | number | undefined): label is string | number {
23
24
  return label !== undefined && label !== "";
24
25
  }
26
+
27
+ /**
28
+ * Outer diameter of the dot per size. The indicator's own stylesheet repeats
29
+ * these as literals — the unistyles Babel plugin reads that object statically,
30
+ * so it cannot reference this table — and `anchorOffsetsMatchDotRadius` in the
31
+ * test suite is what keeps the two in step.
32
+ */
33
+ export const DOT_SIZE: Record<BadgeSize, number> = {
34
+ sm: 12,
35
+ md: 16,
36
+ lg: 20,
37
+ };
38
+
39
+ export interface AnchorPosition {
40
+ top?: number;
41
+ right?: number;
42
+ bottom?: number;
43
+ left?: number;
44
+ }
45
+
46
+ /**
47
+ * Absolute insets for the indicator, in pure arithmetic rather than one
48
+ * compound variant per (placement, size) cell: `offset` is an open-ended number
49
+ * and could never be a variant condition, and nothing here touches the theme.
50
+ *
51
+ * The base inset is the dot's radius, which puts a dot's centre exactly on the
52
+ * child's bounding-box corner. `offset` moves it from there — positive away
53
+ * from the child's centre, negative toward it.
54
+ */
55
+ export function getAnchorPosition(
56
+ placement: BadgePlacement,
57
+ size: BadgeSize,
58
+ offset: number | { x?: number; y?: number } = 0
59
+ ): AnchorPosition {
60
+ const base = DOT_SIZE[size] / 2;
61
+ const { x, y } =
62
+ typeof offset === "number" ? { x: offset, y: offset } : { x: offset.x ?? 0, y: offset.y ?? 0 };
63
+
64
+ const insetX = -(base + x);
65
+ const insetY = -(base + y);
66
+
67
+ switch (placement) {
68
+ case "top-left":
69
+ return { top: insetY, left: insetX };
70
+ case "bottom-right":
71
+ return { bottom: insetY, right: insetX };
72
+ case "bottom-left":
73
+ return { bottom: insetY, left: insetX };
74
+ default:
75
+ return { top: insetY, right: insetX };
76
+ }
77
+ }