kupos-ui-components-lib 10.4.69 → 10.4.70

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.
@@ -76,6 +76,9 @@ const OPERATOR_LOGO_LAYOUT = {
76
76
  };
77
77
  const MAX_VISIBLE_OPERATOR_LOGOS = 3;
78
78
  const FLAME_CENTER = { left: "76.8%", top: "56.4%" };
79
+ // Lifts operator logos off the green Remate art, where light logos otherwise blend in.
80
+ // drop-shadow follows the logo's shape rather than its box.
81
+ const REMATE_LOGO_SHADOW = "drop-shadow(0 0 1px rgba(0,0,0,0.45)) drop-shadow(0 1px 2px rgba(0,0,0,0.3))";
79
82
  const REMATE_KEY = "remate";
80
83
  function isRemateCard(card) {
81
84
  return card.isWowDeal || card.key === REMATE_KEY;
@@ -151,8 +154,10 @@ class DiscountBannersDesktop extends React.Component {
151
154
  const isActive = activeKey === card.key;
152
155
  const operatorLogos = (_a = card.operatorLogos) !== null && _a !== void 0 ? _a : [];
153
156
  const hasLogos = operatorLogos.length > 0;
154
- // Three logos fill the space beside the art, so a "+N" takes the third slot
155
- const visibleLogos = operatorLogos.length > MAX_VISIBLE_OPERATOR_LOGOS
157
+ // Remate lists every operator; other cards show three logos, with a "+N"
158
+ // taking the third slot when there are more
159
+ const visibleLogos = !isRemateCard(card) &&
160
+ operatorLogos.length > MAX_VISIBLE_OPERATOR_LOGOS
156
161
  ? operatorLogos.slice(0, MAX_VISIBLE_OPERATOR_LOGOS - 1)
157
162
  : operatorLogos;
158
163
  const isDimmed = activeKey != null && !isActive;
@@ -187,12 +192,16 @@ class DiscountBannersDesktop extends React.Component {
187
192
  React.createElement("span", { className: `bold-text ${sizeClasses.subtitle}`, style: Object.assign({ color: accentColor }, (hasLogos ? logoLayout.subtitle : undefined)) }, card.campaignTexts
188
193
  ? card.campaignTexts.text3
189
194
  : card.subtitle)),
190
- hasLogos && (React.createElement("span", { className: "bold-text flex items-center whitespace-nowrap text-[#464647]", style: logoLayout.row },
195
+ hasLogos && (React.createElement("span", { className: "bold-text flex items-center whitespace-nowrap text-[#464647]",
196
+ // Clip sideways only, so the Remate logo shadow isn't cut off above and below
197
+ style: Object.assign(Object.assign({}, logoLayout.row), { overflowX: "clip" }) },
191
198
  visibleLogos.map((logo) => {
192
199
  var _a;
193
- return (React.createElement("img", { key: logo.url, src: logo.url, alt: (_a = logo.name) !== null && _a !== void 0 ? _a : "", className: "block object-contain object-left", style: logoLayout.logo }));
200
+ return (React.createElement("img", { key: logo.url, src: logo.url, alt: (_a = logo.name) !== null && _a !== void 0 ? _a : "", className: "block object-contain object-left", style: Object.assign(Object.assign({}, logoLayout.logo), (isRemateCard(card)
201
+ ? { filter: REMATE_LOGO_SHADOW }
202
+ : undefined)) }));
194
203
  }),
195
- visibleLogos.length < operatorLogos.length && (React.createElement("span", null,
204
+ visibleLogos.length < operatorLogos.length && (React.createElement("span", { style: { flexShrink: 0 } },
196
205
  "+",
197
206
  operatorLogos.length - visibleLogos.length))))));
198
207
  })));
@@ -76,6 +76,9 @@ const OPERATOR_LOGO_LAYOUT = {
76
76
  };
77
77
  const MAX_VISIBLE_OPERATOR_LOGOS = 3;
78
78
  const FLAME_CENTER = { left: "76.8%", top: "56.4%" };
79
+ // Lifts operator logos off the green Remate art, where light logos otherwise blend in.
80
+ // drop-shadow follows the logo's shape rather than its box.
81
+ const REMATE_LOGO_SHADOW = "drop-shadow(0 0 1px rgba(0,0,0,0.45)) drop-shadow(0 1px 2px rgba(0,0,0,0.3))";
79
82
  const REMATE_KEY = "remate";
80
83
  function isRemateCard(card) {
81
84
  return card.isWowDeal || card.key === REMATE_KEY;
@@ -149,8 +152,10 @@ class DiscountBannersMobile extends React.Component {
149
152
  const isActive = activeKey === card.key;
150
153
  const operatorLogos = (_a = card.operatorLogos) !== null && _a !== void 0 ? _a : [];
151
154
  const hasLogos = operatorLogos.length > 0;
152
- // Three logos fill the space beside the art, so a "+N" takes the third slot
153
- const visibleLogos = operatorLogos.length > MAX_VISIBLE_OPERATOR_LOGOS
155
+ // Remate lists every operator; other cards show three logos, with a "+N"
156
+ // taking the third slot when there are more
157
+ const visibleLogos = !isRemateCard(card) &&
158
+ operatorLogos.length > MAX_VISIBLE_OPERATOR_LOGOS
154
159
  ? operatorLogos.slice(0, MAX_VISIBLE_OPERATOR_LOGOS - 1)
155
160
  : operatorLogos;
156
161
  const isDimmed = activeKey != null && !isActive;
@@ -185,12 +190,16 @@ class DiscountBannersMobile extends React.Component {
185
190
  React.createElement("span", { className: `bold-text ${sizeClasses.subtitle}`, style: Object.assign({ color: accentColor }, (hasLogos ? logoLayout.subtitle : undefined)) }, card.campaignTexts
186
191
  ? card.campaignTexts.text3
187
192
  : card.subtitle)),
188
- hasLogos && (React.createElement("span", { className: "bold-text flex items-center whitespace-nowrap text-[#464647]", style: logoLayout.row },
193
+ hasLogos && (React.createElement("span", { className: "bold-text flex items-center whitespace-nowrap text-[#464647]",
194
+ // Clip sideways only, so the Remate logo shadow isn't cut off above and below
195
+ style: Object.assign(Object.assign({}, logoLayout.row), { overflowX: "clip" }) },
189
196
  visibleLogos.map((logo) => {
190
197
  var _a;
191
- return (React.createElement("img", { key: logo.url, src: logo.url, alt: (_a = logo.name) !== null && _a !== void 0 ? _a : "", className: "block object-contain object-left", style: logoLayout.logo }));
198
+ return (React.createElement("img", { key: logo.url, src: logo.url, alt: (_a = logo.name) !== null && _a !== void 0 ? _a : "", className: "block object-contain object-left", style: Object.assign(Object.assign({}, logoLayout.logo), (isRemateCard(card)
199
+ ? { filter: REMATE_LOGO_SHADOW }
200
+ : undefined)) }));
192
201
  }),
193
- visibleLogos.length < operatorLogos.length && (React.createElement("span", null,
202
+ visibleLogos.length < operatorLogos.length && (React.createElement("span", { style: { flexShrink: 0 } },
194
203
  "+",
195
204
  operatorLogos.length - visibleLogos.length))))));
196
205
  })));
@@ -76,6 +76,9 @@ const OPERATOR_LOGO_LAYOUT = {
76
76
  };
77
77
  const MAX_VISIBLE_OPERATOR_LOGOS = 3;
78
78
  const FLAME_CENTER = { left: "76.8%", top: "56.4%" };
79
+ // Lifts operator logos off the green Remate art, where light logos otherwise blend in.
80
+ // drop-shadow follows the logo's shape rather than its box.
81
+ const REMATE_LOGO_SHADOW = "drop-shadow(0 0 1px rgba(0,0,0,0.45)) drop-shadow(0 1px 2px rgba(0,0,0,0.3))";
79
82
  const REMATE_KEY = "remate";
80
83
  function isRemateCard(card) {
81
84
  return card.isWowDeal || card.key === REMATE_KEY;
@@ -132,8 +135,10 @@ const DiscountBanners = ({ services = [], wowDealData, backgroundImages = [], ar
132
135
  const isActive = activeKey === card.key;
133
136
  const operatorLogos = (_a = card.operatorLogos) !== null && _a !== void 0 ? _a : [];
134
137
  const hasLogos = operatorLogos.length > 0;
135
- // Three logos fill the space beside the art, so a "+N" takes the third slot
136
- const visibleLogos = operatorLogos.length > MAX_VISIBLE_OPERATOR_LOGOS
138
+ // Remate lists every operator; other cards show three logos, with a "+N"
139
+ // taking the third slot when there are more
140
+ const visibleLogos = !isRemateCard(card) &&
141
+ operatorLogos.length > MAX_VISIBLE_OPERATOR_LOGOS
137
142
  ? operatorLogos.slice(0, MAX_VISIBLE_OPERATOR_LOGOS - 1)
138
143
  : operatorLogos;
139
144
  const isDimmed = activeKey != null && !isActive;
@@ -164,12 +169,16 @@ const DiscountBanners = ({ services = [], wowDealData, backgroundImages = [], ar
164
169
  React.createElement("span", { className: `flex flex-col ${sizeClasses.column}` },
165
170
  React.createElement("span", { className: `bold-text text-[#464647] ${sizeClasses.discount}`, style: hasLogos ? logoLayout.discount : undefined }, card.discountLabel),
166
171
  React.createElement("span", { className: `bold-text ${sizeClasses.subtitle}`, style: Object.assign({ color: accentColor }, (hasLogos ? logoLayout.subtitle : undefined)) }, card.subtitle)),
167
- hasLogos && (React.createElement("span", { className: "bold-text flex items-center whitespace-nowrap text-[#464647]", style: logoLayout.row },
172
+ hasLogos && (React.createElement("span", { className: "bold-text flex items-center whitespace-nowrap text-[#464647]",
173
+ // Clip sideways only, so the Remate logo shadow isn't cut off above and below
174
+ style: Object.assign(Object.assign({}, logoLayout.row), { overflowX: "clip" }) },
168
175
  visibleLogos.map((logo) => {
169
176
  var _a;
170
- return (React.createElement("img", { key: logo.url, src: logo.url, alt: (_a = logo.name) !== null && _a !== void 0 ? _a : "", className: "block object-contain object-left", style: logoLayout.logo }));
177
+ return (React.createElement("img", { key: logo.url, src: logo.url, alt: (_a = logo.name) !== null && _a !== void 0 ? _a : "", className: "block object-contain object-left", style: Object.assign(Object.assign({}, logoLayout.logo), (isRemateCard(card)
178
+ ? { filter: REMATE_LOGO_SHADOW }
179
+ : undefined)) }));
171
180
  }),
172
- visibleLogos.length < operatorLogos.length && (React.createElement("span", null,
181
+ visibleLogos.length < operatorLogos.length && (React.createElement("span", { style: { flexShrink: 0 } },
173
182
  "+",
174
183
  operatorLogos.length - visibleLogos.length))))));
175
184
  })));
@@ -115,7 +115,7 @@ function toDiscountLabel(discount, currencySign) {
115
115
  }
116
116
  // Groups services into one card per discount category. Remate/wow-deal is always the first card.
117
117
  export function deriveDiscountCards(services = [], wowDealData, currencySign = "$") {
118
- var _a, _b, _c, _d;
118
+ var _a, _b, _c, _d, _e;
119
119
  const cards = new Map();
120
120
  const wowServices = wowDealData === null || wowDealData === void 0 ? void 0 : wowDealData.services;
121
121
  const hasWowDeal = !!wowDealData &&
@@ -207,5 +207,15 @@ export function deriveDiscountCards(services = [], wowDealData, currencySign = "
207
207
  if (showsLogo)
208
208
  addOperatorLogo(cards.get(key), service);
209
209
  }
210
+ // Operators sharing a discount are listed alphabetically; logos without a name go last.
211
+ for (const card of cards.values()) {
212
+ (_e = card.operatorLogos) === null || _e === void 0 ? void 0 : _e.sort((a, b) => {
213
+ if (!a.name)
214
+ return b.name ? 1 : 0;
215
+ if (!b.name)
216
+ return -1;
217
+ return a.name.localeCompare(b.name, "es", { sensitivity: "base" });
218
+ });
219
+ }
210
220
  return Array.from(cards.values());
211
221
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kupos-ui-components-lib",
3
- "version": "10.4.69",
3
+ "version": "10.4.70",
4
4
  "description": "A reusable UI components package",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -89,6 +89,11 @@ const MAX_VISIBLE_OPERATOR_LOGOS = 3;
89
89
 
90
90
  const FLAME_CENTER = { left: "76.8%", top: "56.4%" };
91
91
 
92
+ // Lifts operator logos off the green Remate art, where light logos otherwise blend in.
93
+ // drop-shadow follows the logo's shape rather than its box.
94
+ const REMATE_LOGO_SHADOW =
95
+ "drop-shadow(0 0 1px rgba(0,0,0,0.45)) drop-shadow(0 1px 2px rgba(0,0,0,0.3))";
96
+
92
97
  const REMATE_KEY = "remate";
93
98
 
94
99
  function isRemateCard(card: DiscountBannerCard): boolean {
@@ -207,8 +212,10 @@ class DiscountBannersDesktop extends React.Component<
207
212
  const isActive = activeKey === card.key;
208
213
  const operatorLogos = card.operatorLogos ?? [];
209
214
  const hasLogos = operatorLogos.length > 0;
210
- // Three logos fill the space beside the art, so a "+N" takes the third slot
215
+ // Remate lists every operator; other cards show three logos, with a "+N"
216
+ // taking the third slot when there are more
211
217
  const visibleLogos =
218
+ !isRemateCard(card) &&
212
219
  operatorLogos.length > MAX_VISIBLE_OPERATOR_LOGOS
213
220
  ? operatorLogos.slice(0, MAX_VISIBLE_OPERATOR_LOGOS - 1)
214
221
  : operatorLogos;
@@ -307,7 +314,8 @@ class DiscountBannersDesktop extends React.Component<
307
314
  {hasLogos && (
308
315
  <span
309
316
  className="bold-text flex items-center whitespace-nowrap text-[#464647]"
310
- style={logoLayout.row}
317
+ // Clip sideways only, so the Remate logo shadow isn't cut off above and below
318
+ style={{ ...logoLayout.row, overflowX: "clip" }}
311
319
  >
312
320
  {visibleLogos.map((logo) => (
313
321
  <img
@@ -315,11 +323,18 @@ class DiscountBannersDesktop extends React.Component<
315
323
  src={logo.url}
316
324
  alt={logo.name ?? ""}
317
325
  className="block object-contain object-left"
318
- style={logoLayout.logo}
326
+ style={{
327
+ ...logoLayout.logo,
328
+ ...(isRemateCard(card)
329
+ ? { filter: REMATE_LOGO_SHADOW }
330
+ : undefined),
331
+ }}
319
332
  />
320
333
  ))}
321
334
  {visibleLogos.length < operatorLogos.length && (
322
- <span>+{operatorLogos.length - visibleLogos.length}</span>
335
+ <span style={{ flexShrink: 0 }}>
336
+ +{operatorLogos.length - visibleLogos.length}
337
+ </span>
323
338
  )}
324
339
  </span>
325
340
  )}
@@ -89,6 +89,11 @@ const MAX_VISIBLE_OPERATOR_LOGOS = 3;
89
89
 
90
90
  const FLAME_CENTER = { left: "76.8%", top: "56.4%" };
91
91
 
92
+ // Lifts operator logos off the green Remate art, where light logos otherwise blend in.
93
+ // drop-shadow follows the logo's shape rather than its box.
94
+ const REMATE_LOGO_SHADOW =
95
+ "drop-shadow(0 0 1px rgba(0,0,0,0.45)) drop-shadow(0 1px 2px rgba(0,0,0,0.3))";
96
+
92
97
  const REMATE_KEY = "remate";
93
98
 
94
99
  function isRemateCard(card: DiscountBannerCard): boolean {
@@ -200,8 +205,10 @@ class DiscountBannersMobile extends React.Component<
200
205
  const isActive = activeKey === card.key;
201
206
  const operatorLogos = card.operatorLogos ?? [];
202
207
  const hasLogos = operatorLogos.length > 0;
203
- // Three logos fill the space beside the art, so a "+N" takes the third slot
208
+ // Remate lists every operator; other cards show three logos, with a "+N"
209
+ // taking the third slot when there are more
204
210
  const visibleLogos =
211
+ !isRemateCard(card) &&
205
212
  operatorLogos.length > MAX_VISIBLE_OPERATOR_LOGOS
206
213
  ? operatorLogos.slice(0, MAX_VISIBLE_OPERATOR_LOGOS - 1)
207
214
  : operatorLogos;
@@ -300,7 +307,8 @@ class DiscountBannersMobile extends React.Component<
300
307
  {hasLogos && (
301
308
  <span
302
309
  className="bold-text flex items-center whitespace-nowrap text-[#464647]"
303
- style={logoLayout.row}
310
+ // Clip sideways only, so the Remate logo shadow isn't cut off above and below
311
+ style={{ ...logoLayout.row, overflowX: "clip" }}
304
312
  >
305
313
  {visibleLogos.map((logo) => (
306
314
  <img
@@ -308,11 +316,18 @@ class DiscountBannersMobile extends React.Component<
308
316
  src={logo.url}
309
317
  alt={logo.name ?? ""}
310
318
  className="block object-contain object-left"
311
- style={logoLayout.logo}
319
+ style={{
320
+ ...logoLayout.logo,
321
+ ...(isRemateCard(card)
322
+ ? { filter: REMATE_LOGO_SHADOW }
323
+ : undefined),
324
+ }}
312
325
  />
313
326
  ))}
314
327
  {visibleLogos.length < operatorLogos.length && (
315
- <span>+{operatorLogos.length - visibleLogos.length}</span>
328
+ <span style={{ flexShrink: 0 }}>
329
+ +{operatorLogos.length - visibleLogos.length}
330
+ </span>
316
331
  )}
317
332
  </span>
318
333
  )}
@@ -88,6 +88,11 @@ const MAX_VISIBLE_OPERATOR_LOGOS = 3;
88
88
 
89
89
  const FLAME_CENTER = { left: "76.8%", top: "56.4%" };
90
90
 
91
+ // Lifts operator logos off the green Remate art, where light logos otherwise blend in.
92
+ // drop-shadow follows the logo's shape rather than its box.
93
+ const REMATE_LOGO_SHADOW =
94
+ "drop-shadow(0 0 1px rgba(0,0,0,0.45)) drop-shadow(0 1px 2px rgba(0,0,0,0.3))";
95
+
91
96
  const REMATE_KEY = "remate";
92
97
 
93
98
  function isRemateCard(card: DiscountBannerCard): boolean {
@@ -182,8 +187,10 @@ const DiscountBanners: React.FC<DiscountBannersProps> = ({
182
187
  const isActive = activeKey === card.key;
183
188
  const operatorLogos = card.operatorLogos ?? [];
184
189
  const hasLogos = operatorLogos.length > 0;
185
- // Three logos fill the space beside the art, so a "+N" takes the third slot
190
+ // Remate lists every operator; other cards show three logos, with a "+N"
191
+ // taking the third slot when there are more
186
192
  const visibleLogos =
193
+ !isRemateCard(card) &&
187
194
  operatorLogos.length > MAX_VISIBLE_OPERATOR_LOGOS
188
195
  ? operatorLogos.slice(0, MAX_VISIBLE_OPERATOR_LOGOS - 1)
189
196
  : operatorLogos;
@@ -278,7 +285,8 @@ const DiscountBanners: React.FC<DiscountBannersProps> = ({
278
285
  {hasLogos && (
279
286
  <span
280
287
  className="bold-text flex items-center whitespace-nowrap text-[#464647]"
281
- style={logoLayout.row}
288
+ // Clip sideways only, so the Remate logo shadow isn't cut off above and below
289
+ style={{ ...logoLayout.row, overflowX: "clip" }}
282
290
  >
283
291
  {visibleLogos.map((logo) => (
284
292
  <img
@@ -286,11 +294,18 @@ const DiscountBanners: React.FC<DiscountBannersProps> = ({
286
294
  src={logo.url}
287
295
  alt={logo.name ?? ""}
288
296
  className="block object-contain object-left"
289
- style={logoLayout.logo}
297
+ style={{
298
+ ...logoLayout.logo,
299
+ ...(isRemateCard(card)
300
+ ? { filter: REMATE_LOGO_SHADOW }
301
+ : undefined),
302
+ }}
290
303
  />
291
304
  ))}
292
305
  {visibleLogos.length < operatorLogos.length && (
293
- <span>+{operatorLogos.length - visibleLogos.length}</span>
306
+ <span style={{ flexShrink: 0 }}>
307
+ +{operatorLogos.length - visibleLogos.length}
308
+ </span>
294
309
  )}
295
310
  </span>
296
311
  )}
@@ -267,5 +267,14 @@ export function deriveDiscountCards(
267
267
  if (showsLogo) addOperatorLogo(cards.get(key)!, service);
268
268
  }
269
269
 
270
+ // Operators sharing a discount are listed alphabetically; logos without a name go last.
271
+ for (const card of cards.values()) {
272
+ card.operatorLogos?.sort((a, b) => {
273
+ if (!a.name) return b.name ? 1 : 0;
274
+ if (!b.name) return -1;
275
+ return a.name.localeCompare(b.name, "es", { sensitivity: "base" });
276
+ });
277
+ }
278
+
270
279
  return Array.from(cards.values());
271
280
  }