@windstream/react-shared-components 0.2.93 → 0.2.94

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/dist/core.d.ts CHANGED
@@ -68,15 +68,15 @@ type InputFieldProps = Omit<InputHTMLAttributes<HTMLInputElement>, "size"> & {
68
68
 
69
69
  declare const InputField: ForwardRefRenderFunction<HTMLInputElement, InputFieldProps>;
70
70
  declare const Input: React$1.ForwardRefExoticComponent<Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "size"> & {
71
- state?: "default" | "focus" | "active" | "hover" | "filled" | "error" | undefined;
72
- size?: "slim" | "medium" | "large" | undefined;
71
+ state?: "error" | "default" | "filled" | "active" | "focus" | "hover" | undefined;
72
+ size?: "medium" | "large" | "slim" | undefined;
73
73
  label?: string | undefined;
74
74
  errorText?: string | undefined;
75
- prefixIconName?: "location_on" | "search" | undefined;
75
+ prefixIconName?: "search" | "location_on" | undefined;
76
76
  prefixIconSize?: 20 | 24 | 40 | 48 | undefined;
77
77
  prefixIconFill?: boolean | undefined;
78
78
  suffixIconFill?: boolean | undefined;
79
- suffixIconName?: "visibility" | "visibility_off" | "lock" | undefined;
79
+ suffixIconName?: "visibility" | "lock" | "visibility_off" | undefined;
80
80
  suffixIconSize?: 20 | 24 | 40 | 48 | undefined;
81
81
  containerClassName?: string | undefined;
82
82
  prefixIconClassName?: string | undefined;
package/dist/index.d.ts CHANGED
@@ -68,11 +68,11 @@ type InputFieldProps = Omit<InputHTMLAttributes<HTMLInputElement>, "size"> & {
68
68
 
69
69
  declare const InputField: ForwardRefRenderFunction<HTMLInputElement, InputFieldProps>;
70
70
  declare const Input: React$1.ForwardRefExoticComponent<Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "size"> & {
71
- state?: "default" | "focus" | "active" | "hover" | "filled" | "error" | undefined;
72
- size?: "slim" | "medium" | "large" | undefined;
71
+ state?: "error" | "default" | "focus" | "active" | "hover" | "filled" | undefined;
72
+ size?: "medium" | "slim" | "large" | undefined;
73
73
  label?: string | undefined;
74
74
  errorText?: string | undefined;
75
- prefixIconName?: "location_on" | "search" | undefined;
75
+ prefixIconName?: "search" | "location_on" | undefined;
76
76
  prefixIconSize?: 20 | 24 | 40 | 48 | undefined;
77
77
  prefixIconFill?: boolean | undefined;
78
78
  suffixIconFill?: boolean | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windstream/react-shared-components",
3
- "version": "0.2.93",
3
+ "version": "0.2.94",
4
4
  "type": "module",
5
5
  "description": "Shared React components for Kinetic applications",
6
6
  "main": "dist/index.js",
@@ -65,6 +65,41 @@ describe("AnchoredBottomBanner", () => {
65
65
  );
66
66
  });
67
67
 
68
+ it("tags the default banner entry, icon, timer, and linked button label", () => {
69
+ render(
70
+ <AnchoredBottomBanner
71
+ enableCountdownTimer={true}
72
+ countdownEndDateTime="2026-05-19T13:00:00Z"
73
+ iconName="local_offer"
74
+ ctaButtonLabel="Shop now"
75
+ fieldProps={{
76
+ entry: { "data-contentful-entry-id": "banner-entry" },
77
+ iconName: { "data-contentful-field-id": "iconName" },
78
+ countdownEndDateTime: {
79
+ "data-contentful-field-id": "countdownEndDateTime",
80
+ },
81
+ buttonLabel: { "data-contentful-field-id": "buttonLabel" },
82
+ }}
83
+ />
84
+ );
85
+
86
+ expect(screen.getByText("Shop now")).toHaveAttribute(
87
+ "data-contentful-field-id",
88
+ "buttonLabel"
89
+ );
90
+ expect(screen.getByText("local_offer").parentElement).toHaveAttribute(
91
+ "data-contentful-field-id",
92
+ "iconName"
93
+ );
94
+ expect(screen.getByText(/01H : 00M : 00/)).toHaveAttribute(
95
+ "data-contentful-field-id",
96
+ "countdownEndDateTime"
97
+ );
98
+ expect(
99
+ document.querySelector('[data-contentful-entry-id="banner-entry"]')
100
+ ).toBeInTheDocument();
101
+ });
102
+
68
103
  it("uses active scheduled-message fieldProps for its CTA content", () => {
69
104
  render(
70
105
  <AnchoredBottomBanner
@@ -387,6 +422,62 @@ describe("AnchoredBottomBanner scheduledMessages", () => {
387
422
  expect(screen.getByText(/01H : 00M : 00/)).toBeInTheDocument();
388
423
  });
389
424
 
425
+ it("uses the active scheduled-message entry tags for banner content", () => {
426
+ render(
427
+ <AnchoredBottomBanner
428
+ enableCountdownTimer={true}
429
+ countdownEndDateTime="2026-05-19T14:00:00Z"
430
+ iconName="local_offer"
431
+ ctaButtonLabel="Default label"
432
+ fieldProps={{
433
+ entry: { "data-contentful-entry-id": "default-entry" },
434
+ iconName: { "data-contentful-field-id": "default-icon" },
435
+ countdownEndDateTime: {
436
+ "data-contentful-field-id": "default-countdown",
437
+ },
438
+ buttonLabel: { "data-contentful-field-id": "default-label" },
439
+ }}
440
+ scheduledMessages={[
441
+ {
442
+ scheduledStart: "2026-05-18",
443
+ scheduleEnd: "2026-05-20",
444
+ enableCountdownTimer: true,
445
+ countdownEndDateTime: "2026-05-19T13:00:00Z",
446
+ iconName: "bolt",
447
+ ctaButtonLabel: "Flash sale",
448
+ fieldProps: {
449
+ entry: { "data-contentful-entry-id": "scheduled-entry" },
450
+ iconName: { "data-contentful-field-id": "scheduled-icon" },
451
+ countdownEndDateTime: {
452
+ "data-contentful-field-id": "scheduled-countdown",
453
+ },
454
+ buttonLabel: { "data-contentful-field-id": "scheduled-label" },
455
+ },
456
+ },
457
+ ]}
458
+ />
459
+ );
460
+
461
+ expect(screen.getByText("Flash sale")).toHaveAttribute(
462
+ "data-contentful-field-id",
463
+ "scheduled-label"
464
+ );
465
+ expect(screen.getByText("bolt").parentElement).toHaveAttribute(
466
+ "data-contentful-field-id",
467
+ "scheduled-icon"
468
+ );
469
+ expect(screen.getByText(/01H : 00M : 00/)).toHaveAttribute(
470
+ "data-contentful-field-id",
471
+ "scheduled-countdown"
472
+ );
473
+ expect(
474
+ document.querySelector('[data-contentful-entry-id="scheduled-entry"]')
475
+ ).toBeInTheDocument();
476
+ expect(
477
+ document.querySelector('[data-contentful-entry-id="default-entry"]')
478
+ ).not.toBeInTheDocument();
479
+ });
480
+
390
481
  it("treats scheduleEnd as inclusive of the whole end day", () => {
391
482
  render(
392
483
  <AnchoredBottomBanner
@@ -343,6 +343,7 @@ export const AnchoredBottomBanner: React.FC<AnchoredBottomBannerProps> = ({
343
343
  className={`fixed bottom-0 left-0 right-0 z-[30] flex w-full items-center justify-center px-4 py-3 transition-all duration-300 ${bgClass} ${
344
344
  boxShadow ? boxShadow : "shadow-[0_-4px_10px_rgba(0,0,0,0.1)]"
345
345
  }`}
346
+ {...effectiveFieldProps?.entry}
346
347
  >
347
348
  <Link
348
349
  href={effectiveCtaButtonLink || "#"}
@@ -354,28 +355,34 @@ export const AnchoredBottomBanner: React.FC<AnchoredBottomBannerProps> = ({
354
355
  className={`${textColorClass} break-words text-body1 font-black leading-snug md:text-[18px]`}
355
356
  >
356
357
  {effectiveIconName && (
357
- <MaterialIcon
358
- name={
359
- effectiveIconName as React.ComponentProps<
360
- typeof MaterialIcon
361
- >["name"]
362
- }
363
- size={24}
364
- fill={1}
365
- className={`${textColorClass} align-text-bottom`}
366
- />
358
+ <span {...effectiveFieldProps?.iconName}>
359
+ <MaterialIcon
360
+ name={
361
+ effectiveIconName as React.ComponentProps<
362
+ typeof MaterialIcon
363
+ >["name"]
364
+ }
365
+ size={24}
366
+ fill={1}
367
+ className={`${textColorClass} align-text-bottom`}
368
+ />
369
+ </span>
367
370
  )}
368
371
  {countdown.shouldShow && (
369
372
  <span
370
373
  className="inline-block whitespace-nowrap rounded-lg bg-white px-1 tabular-nums text-text"
371
374
  suppressHydrationWarning={true}
375
+ {...effectiveFieldProps?.countdownEndDateTime}
372
376
  >
373
377
  {countdown.text}
374
378
  </span>
375
379
  )}
376
380
  {countdown.shouldShow ? " " : null}
377
381
  {effectiveCtaButtonLabel && (
378
- <span {...effectiveFieldProps?.ctaButtonLabel}>
382
+ <span
383
+ {...(effectiveFieldProps?.buttonLabel ??
384
+ effectiveFieldProps?.ctaButtonLabel)}
385
+ >
379
386
  {effectiveCtaButtonLabel}
380
387
  </span>
381
388
  )}{" "}
@@ -51,7 +51,14 @@ export interface ScheduledMessage {
51
51
  ctaSuffixText?: string;
52
52
  ctaButtonLink?: string;
53
53
  ctaButtonTarget?: string;
54
- fieldProps?: FieldProps<"ctaButtonLabel" | "ctaSuffixText">;
54
+ fieldProps?: FieldProps<
55
+ | "entry"
56
+ | "iconName"
57
+ | "countdownEndDateTime"
58
+ | "buttonLabel"
59
+ | "ctaButtonLabel"
60
+ | "ctaSuffixText"
61
+ >;
55
62
  }
56
63
 
57
64
  export interface AnchoredBottomBannerProps {
@@ -80,6 +87,13 @@ export interface AnchoredBottomBannerProps {
80
87
  activeMessage?: ScheduledMessage;
81
88
  applicableWeekday: string;
82
89
  }) => void;
83
- /** DOM attributes for the rendered CTA label and suffix fields. */
84
- fieldProps?: FieldProps<"ctaButtonLabel" | "ctaSuffixText">;
90
+ /** DOM attributes for the banner entry and rendered content fields. */
91
+ fieldProps?: FieldProps<
92
+ | "entry"
93
+ | "iconName"
94
+ | "countdownEndDateTime"
95
+ | "buttonLabel"
96
+ | "ctaButtonLabel"
97
+ | "ctaSuffixText"
98
+ >;
85
99
  }
@@ -4,7 +4,6 @@ import type { FieldProps } from "@shared/types/field-props";
4
4
 
5
5
  export interface DynamicTabT {
6
6
  tabName: string;
7
- fieldProps?: { tabName?: Record<string, unknown> };
8
7
  anchorId: string;
9
8
  tabContent: ReactNode;
10
9
  /** Inspector attributes for this tab's name and content. */
@@ -7,7 +7,7 @@ import {
7
7
  UTILITY_LINKS,
8
8
  ACCOUNT_LINKS,
9
9
  SUPPORT_LINKS,
10
- } from "./Navigation.stories.mocks";
10
+ } from "./navigation.stories.mocks";
11
11
 
12
12
  const searchFormStyle = `
13
13
  form[name="searchForm"] {