hero.tsx (6147B)
1 import * as React from "react"; 2 import { Actions } from "../util/actions"; 3 import { Container } from "../util/container"; 4 import { Section } from "../util/section"; 5 import { useTheme } from "../layout"; 6 import { TinaMarkdown } from "tinacms/dist/rich-text"; 7 import type { TinaTemplate } from "tinacms"; 8 import { PageBlocksHero } from "../../tina/__generated__/types"; 9 import { tinaField } from "tinacms/dist/react"; 10 import Image from "next/image"; 11 12 export const Hero = ({ data }: { data: PageBlocksHero }) => { 13 const theme = useTheme(); 14 const headlineColorClasses = { 15 blue: "from-blue-400 to-blue-600", 16 teal: "from-teal-400 to-teal-600", 17 green: "from-green-400 to-green-600", 18 red: "from-red-400 to-red-600", 19 pink: "from-pink-400 to-pink-600", 20 purple: "from-purple-400 to-purple-600", 21 orange: "from-orange-300 to-orange-600", 22 yellow: "from-yellow-400 to-yellow-600", 23 }; 24 25 return ( 26 <Section color={data.color}> 27 <Container 28 size="large" 29 className="grid grid-cols-1 md:grid-cols-5 gap-14 items-start justify-center" 30 > 31 <div className="row-start-2 md:row-start-1 md:col-span-5 text-center md:text-left"> 32 {data.tagline && ( 33 <h2 34 data-tina-field={tinaField(data, "tagline")} 35 className="relative inline-block px-3 py-1 mb-8 text-md font-bold tracking-wide title-font z-20" 36 > 37 {data.tagline} 38 <span className="absolute w-full h-full left-0 top-0 rounded-full -z-1 bg-current opacity-7"></span> 39 </h2> 40 )} 41 {data.headline && ( 42 <h3 43 data-tina-field={tinaField(data, "headline")} 44 className={`w-full relative mb-10 text-5xl font-extrabold tracking-normal leading-tight title-font`} 45 > 46 <span 47 className={`bg-clip-text text-transparent bg-gradient-to-r ${ 48 data.color === "primary" 49 ? `from-white to-gray-100` 50 : headlineColorClasses[theme.color] 51 }`} 52 > 53 {data.headline} 54 </span> 55 </h3> 56 )} 57 <div className="flex flex-col md:flex-row gap-6"> 58 <div className="flex flex-col md:w-3/5"> 59 {data.text && ( 60 <div 61 data-tina-field={tinaField(data, "text")} 62 className={`prose prose-lg mx-auto md:mx-0 mb-10 ${ 63 data.color === "primary" 64 ? `prose-primary` 65 : `dark:prose-dark` 66 }`} 67 > 68 <TinaMarkdown content={data.text} /> 69 </div> 70 )} 71 </div> 72 {data.image && ( 73 <div 74 data-tina-field={tinaField(data.image, "src")} 75 className="relative flex-shrink-0 md:w-2/5 flex justify-center" 76 > 77 <Image 78 className="w-full h-auto max-w-full rounded-lg" 79 style={{ objectFit: "cover" }} 80 alt={data.image.alt} 81 src={data.image.src} 82 width={500} 83 height={500} 84 /> 85 </div> 86 )} 87 </div> 88 {data.text2 && ( 89 <div 90 data-tina-field={tinaField(data, "text2")} 91 className={`prose prose-lg mx-auto md:mx-0 mb-10 ${ 92 data.color === "primary" ? `prose-primary` : `dark:prose-dark` 93 }`} 94 > 95 <TinaMarkdown content={data.text2} /> 96 </div> 97 )} 98 {data.actions && ( 99 <div className="mt-10"> 100 <Actions 101 className="justify-center md:justify-start py-2" 102 parentColor={data.color} 103 actions={data.actions} 104 /> 105 </div> 106 )} 107 </div> 108 </Container> 109 </Section> 110 ); 111 }; 112 113 export const heroBlockSchema: TinaTemplate = { 114 name: "hero", 115 label: "Hero", 116 ui: { 117 previewSrc: "/blocks/hero.png", 118 defaultItem: { 119 tagline: "Here's some text above the other text", 120 headline: "This Big Text is Totally Awesome", 121 text: "Phasellus scelerisque, libero eu finibus rutrum, risus risus accumsan libero, nec molestie urna dui a leo.", 122 }, 123 }, 124 fields: [ 125 { 126 type: "string", 127 label: "Tagline", 128 name: "tagline", 129 }, 130 { 131 type: "string", 132 label: "Headline", 133 name: "headline", 134 }, 135 { 136 label: "Text-1", 137 name: "text", 138 type: "rich-text", 139 }, 140 { 141 type: "rich-text", 142 label: "Text-2", 143 name: "text2", 144 }, 145 { 146 label: "Actions", 147 name: "actions", 148 type: "object", 149 list: true, 150 ui: { 151 defaultItem: { 152 label: "Action Label", 153 type: "button", 154 icon: true, 155 link: "/", 156 }, 157 itemProps: (item) => ({ label: item.label }), 158 }, 159 fields: [ 160 { 161 label: "Label", 162 name: "label", 163 type: "string", 164 }, 165 { 166 label: "Type", 167 name: "type", 168 type: "string", 169 options: [ 170 { label: "Button", value: "button" }, 171 { label: "Link", value: "link" }, 172 ], 173 }, 174 { 175 label: "Icon", 176 name: "icon", 177 type: "boolean", 178 }, 179 { 180 label: "Link", 181 name: "link", 182 type: "string", 183 }, 184 ], 185 }, 186 { 187 type: "object", 188 label: "Image", 189 name: "image", 190 fields: [ 191 { 192 name: "src", 193 label: "Image Source", 194 type: "image", 195 }, 196 { 197 name: "alt", 198 label: "Alt Text", 199 type: "string", 200 }, 201 ], 202 }, 203 { 204 type: "string", 205 label: "Color", 206 name: "color", 207 options: [ 208 { label: "Default", value: "default" }, 209 { label: "Tint", value: "tint" }, 210 { label: "Primary", value: "primary" }, 211 ], 212 }, 213 ], 214 };