mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-31 08:25:35 +00:00
fix(payment): keep subscription plan titles readable
This commit is contained in:
@@ -14,12 +14,12 @@
|
||||
<!-- Header: name + badge + price -->
|
||||
<div class="mb-3 flex items-start justify-between gap-2">
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="truncate text-base font-bold text-gray-900 dark:text-white">{{ plan.name }}</h3>
|
||||
<span :class="['shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium', badgeLightClass]">
|
||||
{{ pLabel }}
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
:title="plan.name"
|
||||
class="h-12 min-w-0 break-words [overflow-wrap:anywhere] text-base font-bold leading-6 text-gray-900 dark:text-white line-clamp-2"
|
||||
>
|
||||
{{ plan.name }}
|
||||
</h3>
|
||||
<p v-if="plan.description" class="mt-0.5 text-xs leading-relaxed text-gray-500 dark:text-dark-400 line-clamp-2">
|
||||
{{ plan.description }}
|
||||
</p>
|
||||
@@ -30,7 +30,12 @@
|
||||
<span :class="['text-2xl font-extrabold tracking-tight', textClass]">{{ plan.price }}</span>
|
||||
<span v-if="plan.currency" class="text-xs font-medium text-gray-400 dark:text-dark-500">{{ plan.currency }}</span>
|
||||
</div>
|
||||
<span class="text-[11px] text-gray-400 dark:text-dark-500">/ {{ validitySuffix }}</span>
|
||||
<div class="flex items-center justify-end gap-1">
|
||||
<span :class="['inline-flex shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium', badgeLightClass]">
|
||||
{{ pLabel }}
|
||||
</span>
|
||||
<span class="text-[11px] text-gray-400 dark:text-dark-500">/ {{ validitySuffix }}</span>
|
||||
</div>
|
||||
<div v-if="plan.original_price" class="mt-0.5 flex items-center justify-end gap-1.5">
|
||||
<span class="text-xs text-gray-400 line-through dark:text-dark-500">{{ planCurrencySymbol }}{{ plan.original_price }}<template v-if="plan.currency"> {{ plan.currency }}</template></span>
|
||||
<span :class="['rounded px-1 py-0.5 text-[10px] font-semibold', discountClass]">{{ discountText }}</span>
|
||||
|
||||
@@ -86,4 +86,66 @@ describe("SubscriptionPlanCard", () => {
|
||||
expect(mountPlanCard("openai", { currency: "USD" }).text()).toContain("$10USD");
|
||||
expect(mountPlanCard("openai", { currency: "" }).text()).toContain("$10");
|
||||
});
|
||||
|
||||
it.each([
|
||||
["long Chinese", "企业全球加速专业订阅套餐(含高级模型与优先支持)"],
|
||||
["long English", "Enterprise Global Acceleration Subscription with Priority Support"],
|
||||
["unbroken token", "EnterpriseGlobalAccelerationSubscriptionWithPrioritySupport1234567890"],
|
||||
])("keeps the full %s plan title accessible in a bounded two-line area", (_label, name) => {
|
||||
const wrapper = mountPlanCard("openai", { name });
|
||||
const title = wrapper.get("h3");
|
||||
|
||||
expect(title.text()).toBe(name);
|
||||
expect(title.attributes("title")).toBe(name);
|
||||
expect(title.classes()).toEqual(expect.arrayContaining([
|
||||
"min-w-0",
|
||||
"h-12",
|
||||
"break-words",
|
||||
"line-clamp-2",
|
||||
"[overflow-wrap:anywhere]",
|
||||
]));
|
||||
expect(title.classes()).not.toContain("truncate");
|
||||
});
|
||||
|
||||
it("keeps title, badge, price, description, and purchase action in separate bounded regions", () => {
|
||||
const wrapper = mountPlanCard("openai", {
|
||||
name: "Enterprise Global Acceleration Subscription with Priority Support",
|
||||
price: 123.45,
|
||||
currency: "USD",
|
||||
description: "Includes advanced models and priority support.",
|
||||
});
|
||||
const title = wrapper.get("h3");
|
||||
const badge = wrapper.findAll("span").find((node) => node.text() === "OpenAI");
|
||||
const price = wrapper.findAll("span").find((node) => node.text() === "123.45");
|
||||
|
||||
expect(title.element.parentElement?.classList).toContain("min-w-0");
|
||||
expect(title.element.parentElement?.classList).toContain("flex-1");
|
||||
expect(badge?.classes()).toContain("shrink-0");
|
||||
expect([...(badge?.element.parentElement?.classList ?? [])]).toEqual(expect.arrayContaining([
|
||||
"flex",
|
||||
"items-center",
|
||||
"justify-end",
|
||||
]));
|
||||
expect(badge?.element.parentElement?.textContent).toContain("/ 30payment.days");
|
||||
expect(badge?.element.parentElement?.parentElement?.classList).toContain("shrink-0");
|
||||
expect(price?.element.parentElement?.parentElement?.classList).toContain("shrink-0");
|
||||
expect(wrapper.get("p").text()).toBe("Includes advanced models and priority support.");
|
||||
expect(wrapper.get("button").text()).toBe("payment.subscribeNow");
|
||||
});
|
||||
|
||||
it("keeps short plan titles compact and aligned", () => {
|
||||
const wrapper = mountPlanCard("openai", { name: "Pro", description: "" });
|
||||
const title = wrapper.get("h3");
|
||||
const badge = wrapper.findAll("span").find((node) => node.text() === "OpenAI");
|
||||
|
||||
expect(title.text()).toBe("Pro");
|
||||
expect(title.attributes("title")).toBe("Pro");
|
||||
expect(title.classes()).toEqual(expect.arrayContaining(["text-base", "font-bold", "h-12"]));
|
||||
expect([...(badge?.element.parentElement?.classList ?? [])]).toEqual(expect.arrayContaining([
|
||||
"flex",
|
||||
"items-center",
|
||||
"justify-end",
|
||||
]));
|
||||
expect(badge?.element.parentElement?.textContent).toContain("/ 30payment.days");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user