@tbox.cn/app-module-promotion 0.9.3 → 0.9.4

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.
@@ -1,5 +1,5 @@
1
1
  // src/client/index.ts
2
- import "./promotion-CMKJ4DB3.css";
2
+ import "./promotion-6L7HLRC2.css";
3
3
 
4
4
  // src/client/cards/promotion-offer-list/index.tsx
5
5
  import { CalendarBlank, CalendarDots, CaretDown, Lightbulb, MapPin, Sparkle, Ticket } from "@phosphor-icons/react";
@@ -175,9 +175,6 @@ function CouponSheet(props) {
175
175
  );
176
176
  }
177
177
 
178
- // src/client/assets/promotion-coupon-header-pea-v1.jpg
179
- var promotion_coupon_header_pea_v1_default = "./promotion-coupon-header-pea-v1-4CCHFCCM.jpg";
180
-
181
178
  // src/client/cards/view.ts
182
179
  function offerTypeLabel(offerType) {
183
180
  switch (offerType) {
@@ -345,16 +342,13 @@ function PromotionOfferListCard(props) {
345
342
  ] })
346
343
  ] })
347
344
  ] }),
348
- coupon ? /* @__PURE__ */ jsxs2("header", { className: "promotion-activity__header promotion-activity__header--pea promotion-coupon__header", children: [
349
- /* @__PURE__ */ jsx3("img", { src: promotion_coupon_header_pea_v1_default, alt: "", "aria-hidden": "true", className: "promotion-activity__header-art" }),
350
- /* @__PURE__ */ jsxs2("div", { className: "promotion-activity__header-copy", children: [
351
- /* @__PURE__ */ jsxs2("div", { className: "promotion-activity__header-title-row", children: [
352
- /* @__PURE__ */ jsx3(Ticket, { weight: "fill" }),
353
- /* @__PURE__ */ jsx3("h3", { children: title })
354
- ] }),
355
- /* @__PURE__ */ jsx3("p", { children: eyebrow })
356
- ] })
357
- ] }) : /* @__PURE__ */ jsxs2("header", { className: "promotion-card__header", children: [
345
+ coupon ? /* @__PURE__ */ jsx3("header", { className: "promotion-activity__header promotion-activity__header--pea promotion-coupon__header", children: /* @__PURE__ */ jsxs2("div", { className: "promotion-activity__header-copy", children: [
346
+ /* @__PURE__ */ jsxs2("div", { className: "promotion-activity__header-title-row", children: [
347
+ /* @__PURE__ */ jsx3(Ticket, { weight: "fill" }),
348
+ /* @__PURE__ */ jsx3("h3", { children: title })
349
+ ] }),
350
+ /* @__PURE__ */ jsx3("p", { children: eyebrow })
351
+ ] }) }) : /* @__PURE__ */ jsxs2("header", { className: "promotion-card__header", children: [
358
352
  /* @__PURE__ */ jsx3("span", { className: "promotion-card__mark", children: promotion ? /* @__PURE__ */ jsx3(CalendarDots, { weight: "duotone" }) : /* @__PURE__ */ jsx3(Sparkle, { weight: "fill" }) }),
359
353
  /* @__PURE__ */ jsxs2("div", { children: [
360
354
  /* @__PURE__ */ jsx3("span", { className: "promotion-card__eyebrow", children: eyebrow }),
@@ -857,16 +851,13 @@ function PromotionEntitlementListCard(props) {
857
851
  }
858
852
  };
859
853
  return /* @__PURE__ */ jsxs4("section", { className: "promotion-card promotion-list--coupon promotion-entitlements", "aria-label": "\u6211\u7684\u4F18\u60E0\u6743\u76CA", children: [
860
- /* @__PURE__ */ jsxs4("header", { className: "promotion-activity__header promotion-activity__header--pea promotion-coupon__header", children: [
861
- /* @__PURE__ */ jsx6("img", { src: promotion_coupon_header_pea_v1_default, alt: "", "aria-hidden": "true", className: "promotion-activity__header-art" }),
862
- /* @__PURE__ */ jsxs4("div", { className: "promotion-activity__header-copy", children: [
863
- /* @__PURE__ */ jsxs4("div", { className: "promotion-activity__header-title-row", children: [
864
- /* @__PURE__ */ jsx6(Ticket3, { weight: "fill" }),
865
- /* @__PURE__ */ jsx6("h3", { children: "\u6211\u7684\u4F18\u60E0\u5238" })
866
- ] }),
867
- /* @__PURE__ */ jsx6("p", { children: "\u5F53\u524D\u8D26\u6237 \xB7 \u5238\u5305\u6743\u76CA" })
868
- ] })
869
- ] }),
854
+ /* @__PURE__ */ jsx6("header", { className: "promotion-activity__header promotion-activity__header--pea promotion-coupon__header", children: /* @__PURE__ */ jsxs4("div", { className: "promotion-activity__header-copy", children: [
855
+ /* @__PURE__ */ jsxs4("div", { className: "promotion-activity__header-title-row", children: [
856
+ /* @__PURE__ */ jsx6(Ticket3, { weight: "fill" }),
857
+ /* @__PURE__ */ jsx6("h3", { children: "\u6211\u7684\u4F18\u60E0\u5238" })
858
+ ] }),
859
+ /* @__PURE__ */ jsx6("p", { children: "\u5F53\u524D\u8D26\u6237 \xB7 \u5238\u5305\u6743\u76CA" })
860
+ ] }) }),
870
861
  !data.items.length ? /* @__PURE__ */ jsxs4("div", { className: "promotion-card__empty", children: [
871
862
  /* @__PURE__ */ jsx6(Ticket3, { size: 28, weight: "duotone" }),
872
863
  /* @__PURE__ */ jsx6("span", { children: data.noResultsReason ?? "\u5F53\u524D\u8D26\u6237\u6682\u65E0\u53EF\u7528\u6743\u76CA" })
@@ -988,26 +979,18 @@ var promotion_entitlement_list_default = PromotionEntitlementListCard;
988
979
  // src/client/cards/promotion-activity-list/index.tsx
989
980
  import { CalendarDots as CalendarDots2, Sparkle as Sparkle2, Ticket as Ticket4 } from "@phosphor-icons/react";
990
981
  import { sendCardAction as sendCardAction3 } from "@tbox.cn/app-sdk/client";
991
-
992
- // src/client/assets/promotion-activity-header-pea-v2.jpg
993
- var promotion_activity_header_pea_v2_default = "./promotion-activity-header-pea-v2-4CCHFCCM.jpg";
994
-
995
- // src/client/cards/promotion-activity-list/index.tsx
996
982
  import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
997
983
  var statusText2 = { AVAILABLE: "\u53EF\u62A5\u540D", FULL: "\u5DF2\u6EE1", ENDED: "\u5DF2\u7ED3\u675F", UPCOMING: "\u5373\u5C06\u5F00\u59CB", UNKNOWN: "\u5F85\u786E\u8BA4" };
998
984
  function PromotionActivityListCard(props) {
999
985
  const { data, cardId = "", isHistory = false } = props;
1000
986
  return /* @__PURE__ */ jsxs5("section", { className: "promotion-card promotion-activity promotion-activity--list", children: [
1001
- /* @__PURE__ */ jsxs5("header", { className: "promotion-activity__header promotion-activity__header--pea", children: [
1002
- /* @__PURE__ */ jsx7("img", { src: promotion_activity_header_pea_v2_default, alt: "", "aria-hidden": "true", className: "promotion-activity__header-art" }),
1003
- /* @__PURE__ */ jsxs5("div", { className: "promotion-activity__header-copy", children: [
1004
- /* @__PURE__ */ jsxs5("div", { className: "promotion-activity__header-title-row", children: [
1005
- /* @__PURE__ */ jsx7(Sparkle2, { weight: "fill" }),
1006
- /* @__PURE__ */ jsx7("h3", { children: "\u6D3B\u52A8\u4E2D\u5FC3" })
1007
- ] }),
1008
- /* @__PURE__ */ jsx7("p", { children: "\u53D1\u73B0\u5546\u573A\u8FD1\u671F\u7CBE\u5F69\u6D3B\u52A8" })
1009
- ] })
1010
- ] }),
987
+ /* @__PURE__ */ jsx7("header", { className: "promotion-activity__header promotion-activity__header--pea", children: /* @__PURE__ */ jsxs5("div", { className: "promotion-activity__header-copy", children: [
988
+ /* @__PURE__ */ jsxs5("div", { className: "promotion-activity__header-title-row", children: [
989
+ /* @__PURE__ */ jsx7(Sparkle2, { weight: "fill" }),
990
+ /* @__PURE__ */ jsx7("h3", { children: "\u6D3B\u52A8\u4E2D\u5FC3" })
991
+ ] }),
992
+ /* @__PURE__ */ jsx7("p", { children: "\u53D1\u73B0\u5546\u573A\u8FD1\u671F\u7CBE\u5F69\u6D3B\u52A8" })
993
+ ] }) }),
1011
994
  /* @__PURE__ */ jsx7("div", { className: "promotion-activity__list", children: data.items.map((item) => {
1012
995
  const status = item.availabilityStatus ?? (item.remainingQuota === 0 ? "FULL" : "UNKNOWN");
1013
996
  const action = item.itemActions?.find((candidate) => candidate.kind === "send" || candidate.kind === "link");
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  cards,
3
3
  clientModule
4
- } from "../chunk-P7IEEV37.js";
4
+ } from "../chunk-S7CVFCML.js";
5
5
  export {
6
6
  clientModule,
7
7
  cards as promotionClientCards
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  import {
12
12
  cards,
13
13
  clientModule
14
- } from "./chunk-P7IEEV37.js";
14
+ } from "./chunk-S7CVFCML.js";
15
15
  export {
16
16
  InMemoryPromotionService,
17
17
  clientModule,
@@ -1,10 +1,10 @@
1
1
  .promotion-card {
2
- /* 域色板(mall-vis 营销域):价格红/票根红/CTA 蓝与营销橙渐变/成功绿;对照 docs/mall/visual.md */
2
+ /* 域色板(mall-vis 营销域):价格红/票根红/CTA 蓝与营销橙渐变/成功绿;对照 docs/reference/templates.md(视觉体系与域色矩阵) */
3
3
  --promo-mint: #169e5a;
4
4
  --promo-mint-dark: #128356;
5
5
  --promo-mint-soft: #eaf8f1;
6
- --promo-coral: #e42f46;
7
- --promo-coral-soft: #fff1f3;
6
+ --promo-coral: var(--tbox-domain-promotion-accent, #e42f46);
7
+ --promo-coral-soft: var(--tbox-domain-promotion-surface, #fff1f3);
8
8
  --promo-cyan: #2368ec;
9
9
  --promo-cyan-soft: #eaf3ff;
10
10
  --promo-primary: #2368ec;
@@ -874,15 +874,15 @@
874
874
  }
875
875
  .promotion-activity__header--pea {
876
876
  background: #f9f1e2;
877
- }
878
- .promotion-activity__header-art {
879
- position: absolute;
880
- inset: 0;
881
- width: 100%;
882
- height: 100%;
883
- object-fit: cover;
884
- object-position: center;
885
- pointer-events: none;
877
+ /* 素材变量链(主题品牌资产轨 A1 级联修复):元素只消费不声明(声明截断主题覆写继承),
878
+ 兜底 = 中立渐变(零品牌资产——B2),主题包经 html[data-theme] 段覆写 --tbox-asset-promotion-activity-header */
879
+ background-image: var(--tbox-asset-promotion-activity-header, linear-gradient(135deg, #fff1f3, #ffe4e8));
880
+ background-size: cover;
881
+ background-position: center;
882
+ }
883
+ .promotion-coupon__header {
884
+ /* 券场景头图覆写(同一语义位族;消费形态同 A1 修复,兜底渐变同族) */
885
+ background-image: var(--tbox-asset-promotion-coupon-header, linear-gradient(135deg, #fff1f3, #ffe4e8));
886
886
  }
887
887
  .promotion-activity__header-copy {
888
888
  position: relative;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tbox.cn/app-module-promotion",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "type": "module",
5
5
  "description": "商圈营销模块:资格校验、推荐降级链、券卡(codegen 源)。",
6
6
  "exports": {
@@ -18,9 +18,9 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
- "@tbox.cn/app-contracts": "0.9.0",
22
- "@tbox.cn/app-contracts-mall": "0.9.0",
23
- "@tbox.cn/app-sdk": "0.17.0",
21
+ "@tbox.cn/app-contracts": "0.10.0",
22
+ "@tbox.cn/app-contracts-mall": "0.10.0",
23
+ "@tbox.cn/app-sdk": "0.19.0",
24
24
  "jsbarcode": "^3.12.3",
25
25
  "qrcode": "^1.5.4"
26
26
  },
@@ -2,7 +2,6 @@ import { CalendarDots, Sparkle, Ticket } from '@phosphor-icons/react';
2
2
  import { sendCardAction } from '@tbox.cn/app-sdk/client';
3
3
  import type { PromotionActivityListCardData } from '@tbox.cn/app-contracts-mall';
4
4
  import { ImageWithFallback } from '../../components/ImageWithFallback';
5
- import activityHeaderArtUrl from '../../assets/promotion-activity-header-pea-v2.jpg';
6
5
 
7
6
  const statusText: Record<string, string> = { AVAILABLE: '可报名', FULL: '已满', ENDED: '已结束', UPCOMING: '即将开始', UNKNOWN: '待确认' };
8
7
 
@@ -15,7 +14,6 @@ export function PromotionActivityListCard(props: {
15
14
  return (
16
15
  <section className="promotion-card promotion-activity promotion-activity--list">
17
16
  <header className="promotion-activity__header promotion-activity__header--pea">
18
- <img src={activityHeaderArtUrl} alt="" aria-hidden="true" className="promotion-activity__header-art" />
19
17
  <div className="promotion-activity__header-copy">
20
18
  <div className="promotion-activity__header-title-row">
21
19
  <Sparkle weight="fill" />
@@ -6,7 +6,6 @@ import { CouponSheet } from '../../components/CouponSheet';
6
6
  import { CouponBarcode, CouponQrCode } from '../../components/CouponQrCode';
7
7
  import type { SheetFact } from '../../components/CouponSheet';
8
8
  import { ImageWithFallback } from '../../components/ImageWithFallback';
9
- import couponHeaderArtUrl from '../../assets/promotion-coupon-header-pea-v1.jpg';
10
9
  import { sanitizeActivityHtml } from '../../utils/sanitize-activity-html';
11
10
  import { scrollCardBottom } from '../../utils/scroll-card-bottom';
12
11
  import { entitlementStatusLabel } from '../view';
@@ -75,7 +74,6 @@ export function PromotionEntitlementListCard(props: {
75
74
  return (
76
75
  <section className="promotion-card promotion-list--coupon promotion-entitlements" aria-label="我的优惠权益">
77
76
  <header className="promotion-activity__header promotion-activity__header--pea promotion-coupon__header">
78
- <img src={couponHeaderArtUrl} alt="" aria-hidden="true" className="promotion-activity__header-art" />
79
77
  <div className="promotion-activity__header-copy">
80
78
  <div className="promotion-activity__header-title-row">
81
79
  <Ticket weight="fill" />
@@ -5,7 +5,6 @@ import type { PromotionOfferListCardData } from '@tbox.cn/app-contracts-mall';
5
5
  import { CouponSheet } from '../../components/CouponSheet';
6
6
  import type { SheetFact } from '../../components/CouponSheet';
7
7
  import { ImageWithFallback } from '../../components/ImageWithFallback';
8
- import couponHeaderArtUrl from '../../assets/promotion-coupon-header-pea-v1.jpg';
9
8
  import { offerTypeLabel } from '../view';
10
9
  import { scrollCardBottom } from '../../utils/scroll-card-bottom';
11
10
 
@@ -109,7 +108,6 @@ export function PromotionOfferListCard(props: {
109
108
  {promotion && hero && <div className="promotion-list__hero"><ImageWithFallback src={hero.imageUrl} alt={title} className="promotion-list__hero-image" /><div className="promotion-list__glass"><span>刚刚更新</span><strong>{data.items.length} 个活动正在进行</strong></div></div>}
110
109
  {coupon ? (
111
110
  <header className="promotion-activity__header promotion-activity__header--pea promotion-coupon__header">
112
- <img src={couponHeaderArtUrl} alt="" aria-hidden="true" className="promotion-activity__header-art" />
113
111
  <div className="promotion-activity__header-copy">
114
112
  <div className="promotion-activity__header-title-row">
115
113
  <Ticket weight="fill" />
@@ -1,10 +1,10 @@
1
1
  .promotion-card {
2
- /* 域色板(mall-vis 营销域):价格红/票根红/CTA 蓝与营销橙渐变/成功绿;对照 docs/mall/visual.md */
2
+ /* 域色板(mall-vis 营销域):价格红/票根红/CTA 蓝与营销橙渐变/成功绿;对照 docs/reference/templates.md(视觉体系与域色矩阵) */
3
3
  --promo-mint: #169e5a;
4
4
  --promo-mint-dark: #128356;
5
5
  --promo-mint-soft: #eaf8f1;
6
- --promo-coral: #e42f46;
7
- --promo-coral-soft: #fff1f3;
6
+ --promo-coral: var(--tbox-domain-promotion-accent, #e42f46);
7
+ --promo-coral-soft: var(--tbox-domain-promotion-surface, #fff1f3);
8
8
  --promo-cyan: #2368ec;
9
9
  --promo-cyan-soft: #eaf3ff;
10
10
  --promo-primary: #2368ec;
@@ -874,15 +874,15 @@
874
874
  }
875
875
  .promotion-activity__header--pea {
876
876
  background: #f9f1e2;
877
- }
878
- .promotion-activity__header-art {
879
- position: absolute;
880
- inset: 0;
881
- width: 100%;
882
- height: 100%;
883
- object-fit: cover;
884
- object-position: center;
885
- pointer-events: none;
877
+ /* 素材变量链(主题品牌资产轨 A1 级联修复):元素只消费不声明(声明截断主题覆写继承),
878
+ 兜底 = 中立渐变(零品牌资产——B2),主题包经 html[data-theme] 段覆写 --tbox-asset-promotion-activity-header */
879
+ background-image: var(--tbox-asset-promotion-activity-header, linear-gradient(135deg, #fff1f3, #ffe4e8));
880
+ background-size: cover;
881
+ background-position: center;
882
+ }
883
+ .promotion-coupon__header {
884
+ /* 券场景头图覆写(同一语义位族;消费形态同 A1 修复,兜底渐变同族) */
885
+ background-image: var(--tbox-asset-promotion-coupon-header, linear-gradient(135deg, #fff1f3, #ffe4e8));
886
886
  }
887
887
  .promotion-activity__header-copy {
888
888
  position: relative;
@@ -112,9 +112,9 @@ describe('legacy 19 个营销展示语义', () => {
112
112
  expect(header?.textContent).toContain('商场神券');
113
113
  expect(header?.textContent).toContain('当前商场 · 优惠精选');
114
114
  expect(header?.classList.contains('promotion-activity__header--pea')).toBe(true);
115
- const headerArt = header?.querySelector('.promotion-activity__header-art');
116
- expect(headerArt?.getAttribute('aria-hidden')).toBe('true');
117
- expect(headerArt?.getAttribute('src')).toContain('promotion-coupon-header-pea-v1');
115
+ // 素材变量链(主题轨 T-2.3):coupon 头图经 CSS background + --tbox-asset-promotion-coupon-header;
116
+ // 资产值断言归构建链(css url 相对引用),渲染层断言 img 不再渲染(防回归)
117
+ expect(header?.querySelector('.promotion-activity__header-art')).toBeNull();
118
118
  });
119
119
 
120
120
  it('券列表默认最多展示 4 条,并支持查看更多/收起', () => {
@@ -192,7 +192,7 @@ describe('legacy 19 个营销展示语义', () => {
192
192
  expect(host.querySelector('.promotion-list--offers')).toBeNull();
193
193
  expect(host.querySelector('.promotion-coupon__header')?.textContent).toContain('我的优惠券');
194
194
  expect(host.querySelector('.promotion-coupon__header')?.textContent).toContain('当前账户 · 券包权益');
195
- expect(host.querySelector('.promotion-activity__header-art')?.getAttribute('src')).toContain('promotion-coupon-header-pea-v1');
195
+ expect(host.querySelector('.promotion-activity__header-art')).toBeNull(); // 素材变量链:头图 img 已转 CSS background
196
196
  // 券码不再摊在行上:一屏几张券,脱敏码谁也用不上,点开浮层才需要
197
197
  expect(host.querySelector('.promotion-coupon-row')?.textContent).not.toContain('****8888');
198
198
  expect(host.querySelector('.promotion-coupon-row')?.textContent).not.toContain('2026-12-31');
@@ -235,9 +235,9 @@ describe('legacy 19 个营销展示语义', () => {
235
235
  const host = render(<PromotionActivityListCard data={{ items: [{ ...activity, coverUrl: 'https://example.com/activity.png' }] } as never} cardId="c1" />);
236
236
  expect(host.querySelector('.promotion-activity__header')?.textContent).toContain('活动中心');
237
237
  expect(host.querySelector('.promotion-activity__header')?.textContent).toContain('发现商场近期精彩活动');
238
- const headerArt = host.querySelector('.promotion-activity__header-art');
239
- expect(headerArt?.getAttribute('aria-hidden')).toBe('true');
240
- expect(headerArt?.getAttribute('src')).not.toBe('https://example.com/activity.png');
238
+ // 素材变量链(主题轨 T-2.3):活动中心头图经 CSS background + --tbox-asset-promotion-activity-header;
239
+ // 业务封面仍只在条目缩略图(下方 thumb 断言),头图 img 不再渲染
240
+ expect(host.querySelector('.promotion-activity__header-art')).toBeNull();
241
241
  expect(host.querySelector('.promotion-activity__hero')).toBeNull();
242
242
  expect(host.textContent).not.toContain('MEMBER PICKS');
243
243
  expect(host.textContent).not.toContain('本周会员精选');
@@ -259,7 +259,7 @@ describe('legacy 19 个营销展示语义', () => {
259
259
  it('activity-list 空态仍展示同一活动中心标题', () => {
260
260
  const host = render(<PromotionActivityListCard data={{ items: [], noResultsReason: '近期暂无活动' }} />);
261
261
  expect(host.querySelector('.promotion-activity__header')?.textContent).toContain('活动中心');
262
- expect(host.querySelector('.promotion-activity__header-art')).not.toBeNull();
262
+ expect(host.querySelector('.promotion-activity__header--pea')).not.toBeNull(); // 空态仍保留品牌头容器(素材经 CSS background)
263
263
  expect(host.querySelector('.promotion-card__empty')?.textContent).toContain('近期暂无活动');
264
264
  });
265
265
 
@@ -1,5 +0,0 @@
1
- /** Static promotion image assets bundled by Vite/tsup. */
2
- declare module '*.jpg' {
3
- const url: string;
4
- export default url;
5
- }