DSContextFooter.jsx (3940B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { cardContextTypes } from "../../Card/types.mjs"; 6 // eslint-disable-next-line no-shadow 7 import { CSSTransition, TransitionGroup } from "react-transition-group"; 8 import { FluentOrText } from "../../FluentOrText/FluentOrText.jsx"; 9 import React from "react"; 10 11 // Animation time is mirrored in DSContextFooter.scss 12 const ANIMATION_DURATION = 3000; 13 14 export const DSMessageLabel = props => { 15 const { context, context_type, mayHaveSectionsCards } = props; 16 const { icon, fluentID } = cardContextTypes[context_type] || {}; 17 18 if (!context && context_type && !mayHaveSectionsCards) { 19 return ( 20 <TransitionGroup component={null}> 21 <CSSTransition 22 key={fluentID} 23 timeout={ANIMATION_DURATION} 24 classNames="story-animate" 25 > 26 <StatusMessage icon={icon} fluentID={fluentID} /> 27 </CSSTransition> 28 </TransitionGroup> 29 ); 30 } 31 32 return null; 33 }; 34 35 export const StatusMessage = ({ icon, fluentID }) => ( 36 <div className="status-message"> 37 <span 38 aria-haspopup="true" 39 className={`story-badge-icon icon icon-${icon}`} 40 /> 41 <div className="story-context-label" data-l10n-id={fluentID} /> 42 </div> 43 ); 44 45 export const SponsorLabel = ({ 46 sponsored_by_override, 47 sponsor, 48 context, 49 newSponsoredLabel, 50 }) => { 51 const classList = `story-sponsored-label ${newSponsoredLabel || ""} clamp`; 52 // If override is not false or an empty string. 53 if (sponsored_by_override) { 54 return <p className={classList}>{sponsored_by_override}</p>; 55 } else if (sponsored_by_override === "") { 56 // We specifically want to display nothing if the server returns an empty string. 57 // So the server can turn off the label. 58 // This is to support the use cases where the sponsored context is displayed elsewhere. 59 return null; 60 } else if (sponsor) { 61 return ( 62 <p className={classList}> 63 <FluentOrText 64 message={{ 65 id: `newtab-label-sponsored-by`, 66 values: { sponsor }, 67 }} 68 /> 69 </p> 70 ); 71 } else if (context) { 72 return <p className={classList}>{context}</p>; 73 } 74 return null; 75 }; 76 77 export class DSContextFooter extends React.PureComponent { 78 render() { 79 const { 80 context, 81 context_type, 82 sponsor, 83 sponsored_by_override, 84 cta_button_variant, 85 source, 86 mayHaveSectionsCards, 87 } = this.props; 88 89 const sponsorLabel = SponsorLabel({ 90 sponsored_by_override, 91 sponsor, 92 context, 93 }); 94 const dsMessageLabel = DSMessageLabel({ 95 context, 96 context_type, 97 mayHaveSectionsCards, 98 }); 99 100 if (cta_button_variant === "variant-a") { 101 return ( 102 <div className="story-footer"> 103 {/* this button is decorative only */} 104 <button aria-hidden="true" className="story-cta-button"> 105 Shop Now 106 </button> 107 {sponsorLabel} 108 </div> 109 ); 110 } 111 112 if (cta_button_variant === "variant-b") { 113 return ( 114 <div className="story-footer"> 115 {sponsorLabel} 116 <span className="source clamp cta-footer-source">{source}</span> 117 </div> 118 ); 119 } 120 121 if (sponsorLabel || (dsMessageLabel && context_type !== "pocket")) { 122 return ( 123 <div className="story-footer"> 124 {sponsorLabel} 125 {dsMessageLabel} 126 </div> 127 ); 128 } 129 130 return null; 131 } 132 } 133 134 export const DSMessageFooter = props => { 135 const { context, context_type } = props; 136 137 const dsMessageLabel = DSMessageLabel({ 138 context, 139 context_type, 140 }); 141 142 // This case is specific and already displayed to the user elsewhere. 143 if (!dsMessageLabel) { 144 return null; 145 } 146 147 return <div className="story-footer">{dsMessageLabel}</div>; 148 };