@windstream/react-shared-components 0.2.64 → 0.2.65
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/contentful/index.esm.js +2 -2
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +1 -1
- package/dist/contentful/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/contentful/blocks/anchored-bottom-banner/index.tsx +14 -5
- package/src/contentful/blocks/footer/index.test.tsx +17 -0
- package/src/contentful/blocks/footer/index.tsx +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ declare const Input: React$1.ForwardRefExoticComponent<Omit<React$1.InputHTMLAtt
|
|
|
70
70
|
size?: "slim" | "medium" | "large" | undefined;
|
|
71
71
|
label?: string | undefined;
|
|
72
72
|
errorText?: string | undefined;
|
|
73
|
-
prefixIconName?: "
|
|
73
|
+
prefixIconName?: "search" | "location_on" | undefined;
|
|
74
74
|
prefixIconSize?: 20 | 24 | 40 | 48 | undefined;
|
|
75
75
|
prefixIconFill?: boolean | undefined;
|
|
76
76
|
suffixIconFill?: boolean | undefined;
|
package/package.json
CHANGED
|
@@ -178,18 +178,27 @@ export const AnchoredBottomBanner: React.FC<AnchoredBottomBannerProps> = ({
|
|
|
178
178
|
const [nowMs, setNowMs] = useState(() => Date.now());
|
|
179
179
|
const intervalRef = useRef<number | null>(null);
|
|
180
180
|
|
|
181
|
+
const [hasMounted, setHasMounted] = useState(false);
|
|
182
|
+
useEffect(() => setHasMounted(true), []);
|
|
183
|
+
|
|
181
184
|
// The message active for "now" (display window + daysToShow) wins.
|
|
182
185
|
const activeMessage = useMemo(
|
|
183
|
-
() =>
|
|
184
|
-
|
|
186
|
+
() =>
|
|
187
|
+
hasMounted
|
|
188
|
+
? scheduledMessages?.find(message => isMessageActive(message, nowMs))
|
|
189
|
+
: undefined,
|
|
190
|
+
[scheduledMessages, nowMs, hasMounted]
|
|
185
191
|
);
|
|
186
192
|
const hasActiveMessage = activeMessage !== undefined;
|
|
187
193
|
|
|
188
194
|
// Expose the resolved result so consumers (analytics) can read what showed.
|
|
189
195
|
const applicableWeekday = schedulingZoneWeekday(nowMs);
|
|
190
196
|
useEffect(() => {
|
|
197
|
+
// Only report after client-side schedule resolution so analytics never
|
|
198
|
+
// records the pre-mount hasActiveMessage:false fallback.
|
|
199
|
+
if (!hasMounted) return;
|
|
191
200
|
onResolved?.({ hasActiveMessage, activeMessage, applicableWeekday });
|
|
192
|
-
}, [hasActiveMessage, activeMessage, applicableWeekday, onResolved]);
|
|
201
|
+
}, [hasMounted, hasActiveMessage, activeMessage, applicableWeekday, onResolved]);
|
|
193
202
|
|
|
194
203
|
// Latest display-window end, so we keep ticking to let messages activate/expire.
|
|
195
204
|
const scheduleMaxEndMs = useMemo(() => {
|
|
@@ -328,12 +337,12 @@ export const AnchoredBottomBanner: React.FC<AnchoredBottomBannerProps> = ({
|
|
|
328
337
|
className={`${textColorClass} align-text-bottom`}
|
|
329
338
|
/>
|
|
330
339
|
)}
|
|
331
|
-
{countdown.shouldShow && (
|
|
340
|
+
{hasMounted && countdown.shouldShow && (
|
|
332
341
|
<span className="inline-block whitespace-nowrap rounded-lg bg-white px-1 tabular-nums text-text">
|
|
333
342
|
{countdown.text}
|
|
334
343
|
</span>
|
|
335
344
|
)}
|
|
336
|
-
{countdown.shouldShow ? " " : null}
|
|
345
|
+
{hasMounted && countdown.shouldShow ? " " : null}
|
|
337
346
|
{effectiveCtaButtonLabel && effectiveCtaButtonLabel}{" "}
|
|
338
347
|
{effectiveCtaSuffixText && (
|
|
339
348
|
<span className="ml-0.5">{effectiveCtaSuffixText}</span>
|
|
@@ -205,6 +205,23 @@ describe("Footer", () => {
|
|
|
205
205
|
});
|
|
206
206
|
|
|
207
207
|
describe("Copyright and terms", () => {
|
|
208
|
+
it("wraps copyrights in a <div> (not a <p>) so block-level rich text is valid", () => {
|
|
209
|
+
render(<Footer {...defaultProps} />);
|
|
210
|
+
const copyEl = screen.getByText("All rights reserved.");
|
|
211
|
+
expect(copyEl.tagName).toBe("DIV");
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it("renders block-level rich text in copyrights without invalid <div>-in-<p> nesting", () => {
|
|
215
|
+
render(
|
|
216
|
+
<Footer
|
|
217
|
+
{...defaultProps}
|
|
218
|
+
copyrights={<div data-testid="rich-copyright">© 2026 Windstream</div>}
|
|
219
|
+
/>
|
|
220
|
+
);
|
|
221
|
+
// the rich-text <div> must NOT be nested inside a <p>
|
|
222
|
+
expect(screen.getByTestId("rich-copyright").closest("p")).toBeNull();
|
|
223
|
+
});
|
|
224
|
+
|
|
208
225
|
it("renders copyright year with current year", () => {
|
|
209
226
|
render(<Footer {...defaultProps} />);
|
|
210
227
|
const currentYear = new Date().getFullYear().toString();
|
|
@@ -64,7 +64,7 @@ export const Footer: React.FC<FooterProps> = ({
|
|
|
64
64
|
<p className="terms-text footnote text-white">
|
|
65
65
|
© {new Date().getFullYear()} {terms}
|
|
66
66
|
</p>
|
|
67
|
-
<
|
|
67
|
+
<div className="copy-rights whitespace-pre-line">{copyrights}</div>
|
|
68
68
|
<nav aria-label="Footer legal">
|
|
69
69
|
<ul className="bottom-links list-none">
|
|
70
70
|
{bottomLinks?.map((link: any, index: number) => (
|