authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-13 19:45:37-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-13 19:45:37-07:00
log564719165e9131ab2aa55e9c805b860a415690da
tree5bf3194ed5f24237c47b2c36170368b4662bd9f4
parent5e961d3d7fc07ff1ba998bfd20bb366c2ab8c9a9
signature Signed by PGP key B5690EEEBB952194

fix(mobile): keep usage widget rows consistently sized (#11669)


1 files changed, 29 insertions(+), 30 deletions(-)

apps/mobile/src/widgets/SubscriptionUsage.tsx+29-30
......@@ -2,12 +2,12 @@ import { HStack, ProgressView, Spacer, Text, VStack } from "@expo/ui/swift-ui";
22import {
33 accessibilityElement,
44 accessibilityLabel,
5 fixedSize,
56 font,
67 foregroundStyle,
78 frame,
89 layoutPriority,
910 lineLimit,
10 minimumScaleFactor,
1111 progressViewStyle,
1212 tint,
1313 widgetURL,
......@@ -33,6 +33,8 @@ function SubscriptionUsage(
3333 const accessory = family === "accessoryRectangular";
3434 const compact =
3535 family === "systemSmall" || accessory || environment.levelOfDetail === "simplified";
36 // Budget short cards for two quotas per provider, including their secondary text.
37 const dense = family === "systemSmall" || family === "systemMedium";
3638 const limit = family === "systemExtraLarge" ? 6 : family === "systemLarge" ? 4 : 2;
3739 const monochrome =
3840 environment.widgetRenderingMode !== "fullColor" || environment.isLuminanceReduced;
......@@ -77,6 +79,7 @@ function SubscriptionUsage(
7779 : provider.detail;
7880 const barModifiers = [
7981 progressViewStyle("linear"),
82 frame({ height: 4 }),
8083 ...(monochrome ? [] : [tint(provider.name === "Claude" ? "#d97757" : "#8e8e93")]),
8184 ];
8285 if (accessory) {
......@@ -99,7 +102,6 @@ function SubscriptionUsage(
99102 modifiers={[
100103 font({ textStyle: "caption", weight: "semibold" }),
101104 lineLimit(1),
102 minimumScaleFactor(0.75),
103105 foregroundStyle("primary"),
104106 ]}
105107 >
......@@ -132,35 +134,37 @@ function SubscriptionUsage(
132134 <VStack
133135 key={provider.name}
134136 alignment="leading"
135 spacing={compact ? 2 : 4}
136 modifiers={[frame({ maxWidth: Infinity, alignment: "leading" })]}
137 spacing={dense ? 1 : compact ? 2 : 4}
138 modifiers={[
139 frame({ maxWidth: Infinity, alignment: "leading" }),
140 fixedSize({ horizontal: false, vertical: true }),
141 ]}
137142 >
138143 <Text
139144 modifiers={[
140145 font({ textStyle: compact ? "caption" : "headline", weight: "bold" }),
141146 lineLimit(1),
142 minimumScaleFactor(0.75),
143147 foregroundStyle("primary"),
144148 ]}
145149 >
146150 {provider.name}
147151 </Text>
148 {(!compact || shown.length === 0) && detail !== "Subscription remaining" ? (
152 {!compact || shown.length === 0 ? (
149153 <Text
150154 modifiers={[
151155 font({ textStyle: "caption2" }),
152156 foregroundStyle("secondary"),
153 lineLimit(compact ? 1 : 2),
157 lineLimit(1),
154158 ]}
155159 >
156 {detail}
160 {detail === "Subscription remaining" ? " " : detail}
157161 </Text>
158162 ) : null}
159163 {shown.map((window) => (
160164 <VStack
161165 key={window.label}
162166 alignment="leading"
163 spacing={2}
167 spacing={dense ? 1 : 2}
164168 modifiers={[
165169 accessibilityElement("ignore"),
166170 accessibilityLabel(
......@@ -171,10 +175,9 @@ function SubscriptionUsage(
171175 <HStack spacing={4}>
172176 <Text
173177 modifiers={[
174 font({ textStyle: compact ? "caption2" : "caption" }),
178 font({ textStyle: compact || dense ? "caption2" : "caption" }),
175179 foregroundStyle("secondary"),
176180 lineLimit(1),
177 minimumScaleFactor(0.75),
178181 ]}
179182 >
180183 {window.label}
......@@ -182,9 +185,11 @@ function SubscriptionUsage(
182185 <Spacer />
183186 <Text
184187 modifiers={[
185 font({ textStyle: compact ? "caption2" : "caption", weight: "semibold" }),
188 font({
189 textStyle: compact || dense ? "caption2" : "caption",
190 weight: "semibold",
191 }),
186192 lineLimit(1),
187 minimumScaleFactor(0.75),
188193 layoutPriority(1),
189194 foregroundStyle(
190195 window.remaining <= 10 && !monochrome
......@@ -200,14 +205,7 @@ function SubscriptionUsage(
200205 </HStack>
201206 <ProgressView value={window.remaining / 100} modifiers={barModifiers} />
202207 {!compact ? (
203 <Text
204 modifiers={[
205 font({ textStyle: "caption2" }),
206 foregroundStyle("secondary"),
207 lineLimit(1),
208 minimumScaleFactor(0.75),
209 ]}
210 >
208 <Text modifiers={[font({ size: 10 }), foregroundStyle("secondary"), lineLimit(1)]}>
211209 {window.reset}
212210 </Text>
213211 ) : null}
......@@ -216,7 +214,13 @@ function SubscriptionUsage(
216214 {!compact &&
217215 !stale &&
218216 (period === "auto" ? (provider.totalWindows ?? windows.length) : windows.length) > limit ? (
219 <Text modifiers={[font({ textStyle: "caption2" }), foregroundStyle("secondary")]}>
217 <Text
218 modifiers={[
219 font({ textStyle: "caption2" }),
220 foregroundStyle("secondary"),
221 lineLimit(1),
222 ]}
223 >
220224 {(period === "auto" ? (provider.totalWindows ?? windows.length) : windows.length) -
221225 limit}{" "}
222226 more in T3
......@@ -228,11 +232,11 @@ function SubscriptionUsage(
228232 return (
229233 <VStack
230234 alignment="leading"
231 spacing={accessory ? 2 : 6}
235 spacing={accessory || dense ? 2 : 6}
232236 modifiers={props.url ? [widgetURL(props.url)] : []}
233237 >
234238 {compact ? (
235 <VStack alignment="leading" spacing={accessory ? 4 : 8}>
239 <VStack alignment="leading" spacing={accessory || dense ? 4 : 8}>
236240 {columns}
237241 </VStack>
238242 ) : (
......@@ -243,12 +247,7 @@ function SubscriptionUsage(
243247 {!accessory ? <Spacer /> : null}
244248 {!accessory ? (
245249 <Text
246 modifiers={[
247 font({ textStyle: "caption2" }),
248 foregroundStyle("secondary"),
249 lineLimit(1),
250 minimumScaleFactor(0.75),
251 ]}
250 modifiers={[font({ textStyle: "caption2" }), foregroundStyle("secondary"), lineLimit(1)]}
252251 >
253252 {props.checkedAt
254253 ? `As of ${new Date(props.checkedAt).toLocaleString(undefined, { hour: "numeric", minute: "2-digit", month: "short", day: "numeric" })}`