1import { useState } from 'react'; 2 3import { Button } from '@proton/atoms/Button/Button'; 4import Href from '@proton/atoms/Href/Href'; 5import { ButtonGroup, Checkbox, Icon, RadioGroup } from '@proton/components/index'; 6 7import Banner, { BannerVariants } from './Banner'; 8import mdx from './Banner.mdx'; 9 10export default { 11 component: Banner, 12 title: 'components/Banner', 13 parameters: { docs: { page: mdx } }, 14}; 15 16export const Basic = () => ( 17 <Banner 18 action={<Button onClick={() => alert('Action clicked')}>Action</Button>} 19 link={<Href href="#">Learn more</Href>} 20 > 21 Text content 22 </Banner> 23); 24 25export const StoryWithCanvas = () => <div>I am a story with a canvas</div>; 26 27type BannerProps = React.ComponentProps<typeof Banner>; 28 29const variants: Required<BannerProps>['variant'][] = Object.values(BannerVariants); 30 31const toggles = ['dismissable', 'link', 'action'] as const; 32 33export const Sandbox = () => { 34 const [selectedVariant, setSelectedVariant] = useState<Required<BannerProps>['variant']>('norm'); 35 const [selectedToggles, setSelectedToggles] = useState(toggles.map(() => false)); 36 37 const banner = ( 38 <Banner 39 variant={selectedVariant} 40 onDismiss={selectedToggles[toggles.indexOf('dismissable')] ? () => alert('Dismissed') : undefined} 41 action={ 42 selectedToggles[toggles.indexOf('action')] ? ( 43 <Button onClick={() => alert('Action clicked')}>Action</Button> 44 ) : undefined 45 } 46 link={selectedToggles[toggles.indexOf('link')] ? <Href href="#">Learn more</Href> : undefined} 47 > 48 Something happened that you should know about. 49 </Banner> 50 ); 51 52 return ( 53 <div className="py-7"> 54 <div className="flex flex-row mb-4 gap-4"> 55 <div> 56 <strong className="block mb-4">Variant</strong> 57 <RadioGroup 58 name="selected-variant" 59 onChange={(v) => setSelectedVariant(v)} 60 value={selectedVariant} 61 options={variants.map((variant) => ({ value: variant, label: variant }))} 62 /> 63 </div> 64 <div> 65 <strong className="block mb-4">Toggles</strong> 66 {toggles.map((prop, i) => { 67 return ( 68 <div className="mb-2" key={i}> 69 <Checkbox 70 checked={selectedToggles[i]} 71 onChange={({ target: { checked } }) => { 72 setSelectedToggles( 73 selectedToggles.map((oldValue, otherIndex) => 74 otherIndex === i ? checked : oldValue 75 ) 76 ); 77 }} 78 > 79 {prop} 80 </Checkbox> 81 </div> 82 ); 83 })} 84 </div> 85 </div> 86 <div>{banner}</div> 87 </div> 88 ); 89}; 90 91const getRandomAction = () => 92 Math.random() > 0.2 ? <Button onClick={() => alert('Action clicked')}>Action</Button> : undefined; 93 94const getRandomLink = () => (Math.random() > 0.4 ? <Href href="#">Learn more</Href> : undefined); 95 96const getRandomText = () => { 97 const texts = [ 98 "Here's some important information.", 99 'Check out this feature to stay informed.', 100 'Be sure to follow the latest updates.', 101 "Don't miss out on these details.", 102 'Take action today to avoid issues.', 103 ]; 104 return texts[Math.floor(Math.random() * texts.length)]; 105}; 106 107const bannerConfigs = [ 108 { variant: BannerVariants.NORM, onDismiss: () => alert('Dismissed') }, 109 { variant: BannerVariants.INFO }, 110 { variant: BannerVariants.INFO_OUTLINE, onDismiss: () => alert('Dismissed') }, 111 { variant: BannerVariants.SUCCESS }, 112 { variant: BannerVariants.SUCCESS_OUTLINE, onDismiss: () => alert('Dismissed') }, 113 { variant: BannerVariants.WARNING }, 114 { variant: BannerVariants.WARNING_OUTLINE }, 115 { variant: BannerVariants.DANGER }, 116 { variant: BannerVariants.DANGER_OUTLINE, onDismiss: () => alert('Dismissed') }, 117]; 118 119export const All = () => ( 120 <div className="flex flex-column gap-4"> 121 {bannerConfigs.map((config, index) => ( 122 <Banner 123 key={index} 124 {...config} 125 action={Math.random() > 0.5 ? getRandomAction() : undefined} 126 link={Math.random() > 0.5 ? getRandomLink() : undefined} 127 children={getRandomText()} 128 /> 129 ))} 130 </div> 131); 132
133export const TextContent = () => ( 134 <Banner variant="danger-outline"> 135 <span className="color-danger text-bold">VPN Plus expires in 2 days.</span> Don't lose access to your premium 136 VPN features. Enable auto-renew today. 137 </Banner> 138);
139 140export const Icons = () => ( 141 <Banner variant="warning" icon={<Icon name="eye" />}> 142 Text content 143 </Banner> 144); 145 146export const Action = () => ( 147 <Banner action={<Button onClick={() => alert('Action clicked')}>Action</Button>}> 148 Something happened that you should know about. 149 </Banner> 150); 151 152export const DoubleAction = () => ( 153 <Banner 154 action={ 155 <ButtonGroup> 156 <Button onClick={() => alert('Action clicked')}>First Action</Button> 157 <Button onClick={() => alert('Action clicked')}>Second Action</Button> 158 </ButtonGroup> 159 } 160 > 161 Something happened that you should know about. 162 </Banner> 163); 164 165export const Link = () => ( 166 <Banner variant="warning" link={<Href href="#">Learn more</Href>}> 167 Something happened that you should know about. 168 </Banner> 169); 170 171export const Dismissable = () => ( 172 <Banner variant="danger-outline" onDismiss={() => alert('Dismissed')}> 173 Something happened that you should know about. 174 </Banner> 175);