Skip to content

Commit

Permalink
✨ Text under image and CTA #2610
Browse files Browse the repository at this point in the history
  • Loading branch information
millianapia committed Jan 22, 2025
1 parent acc8276 commit 9652402
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 74 deletions.
2 changes: 2 additions & 0 deletions sanityv3/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import fullWidthVideo from './objects/fullWidthVideo'
import iframe from './objects/iframe'
import imageWithAlt from './objects/imageWithAlt'
import imageWithAltAndCaption from './objects/imageWithAltAndCaption'
import carouselImage from './objects/carouselImage'
import largeTable from './objects/largeTable'
import linkSelector from './objects/linkSelector'
import menuGroup from './objects/menuGroup'
Expand Down Expand Up @@ -139,6 +140,7 @@ const RemainingSchemas = [
internalServerError,
imageWithAlt,
imageWithAltAndCaption,
carouselImage,
pullQuote,
factbox,
relatedLinks,
Expand Down
66 changes: 66 additions & 0 deletions sanityv3/schemas/objects/carouselImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { ImageWithAlt } from './imageWithAlt'
import type { Reference } from 'sanity'
import { Rule } from 'sanity'


export type CarouselImage = {
_type: 'carouselImage'
image: ImageWithAlt
captionPositionUnderImage?: boolean
action?: Reference[]
}

export default {
name: 'carouselImage',
title: 'Image with options',
type: 'object',
options: {
collapsed: false,
},
fields: [
{
name: 'image',
title: 'Image with alt',
type: 'imageWithAlt',
},
{
name: 'caption',
title: 'Image caption',
type: 'string',
},
{
name: 'attribution',
title: 'Credit',
type: 'string',
},
{
type: 'boolean',
name: 'captionPositionUnderImage',
title: 'Position caption and credit under image',
description: 'Toggle to display caption and credit under the image.',
initialValue: false,
},
{
name: 'action',
title: 'Link',
type: 'array',
of: [{ type: 'linkSelector', title: 'Link' }],
description: 'Optional link associated with the image.',
validation: (Rule: Rule) => Rule.max(1).error('Only one action is permitted'),
},
],
preview: {
select: {
imageUrl: 'image.asset.url',
alt: 'image.alt',
caption: 'caption',
},
prepare({ imageUrl, caption, alt }: { imageUrl: string; alt: string; caption: string }) {
return {
title: alt || 'No alt text',
subtitle: caption || 'No caption',
media: <img src={imageUrl} alt={alt} style={{ height: '100%' }} />,
}
},
},
}
3 changes: 2 additions & 1 deletion sanityv3/schemas/objects/imageCarousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ export default {
name: 'items',
description: 'Add images for the carousel',
title: 'Carousel items',
of: [{ type: 'imageWithAltAndCaption' }],
of: [{ type: 'imageWithAltAndCaption' },
{ type: 'carouselImage' }],
validation: (Rule: Rule) => Rule.required().min(2),
},
{
Expand Down
5 changes: 3 additions & 2 deletions web/core/Carousel/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ export const Carousel = forwardRef<HTMLElement, CarouselProps>(function Carousel
mx-auto
${
variant === 'image' && displayMode === 'single'
? 'overflow-hidden grid grid-flow-row'
? 'grid grid-flow-row'
: 'px-6 lg:px-layout-sm flex flex-col-reverse max-w-viewport'
}
Expand All @@ -353,7 +353,8 @@ export const Carousel = forwardRef<HTMLElement, CarouselProps>(function Carousel
<div
role="group"
aria-labelledby={controlsId}
className={`${
className={`
${
variant === 'image' && displayMode === 'single'
? 'w-[var(--image-carousel-card-w-sm)] md:w-[var(--image-carousel-card-w-md)] lg:w-[var(--image-carousel-card-w-lg)] mx-auto col-start-1 col-end-1 row-start-2 row-end-2'
: ''
Expand Down
16 changes: 12 additions & 4 deletions web/core/Carousel/CarouselImageItem.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import envisTwMerge from '../../twMerge'
import Image from '../../pageComponents/shared/SanityImage'
import { ImageWithAlt, ImageWithCaptionData } from '../../types/index'
import { ImageWithAlt, ImageWithCaptionData, LinkData } from '../../types/index'
import { DisplayModes } from './Carousel'
import { forwardRef, HTMLAttributes } from 'react'
import GridLinkArrow from '@sections/Grid/GridLinkArrow'

type CarouselImageItemProps = {
image?: ImageWithAlt | ImageWithCaptionData
Expand All @@ -12,10 +13,12 @@ type CarouselImageItemProps = {
caption?: string
attribution?: string
active?: boolean
captionPositionUnderImage?: boolean
action?: LinkData
} & HTMLAttributes<HTMLLIElement>

export const CarouselImageItem = forwardRef<HTMLLIElement, CarouselImageItemProps>(function CarouselImageItem(
{ active = false, image, caption, attribution, displayMode = 'single', className = '', ...rest },
{ active = false, image, caption, attribution, displayMode = 'single', className = '', action, captionPositionUnderImage, ...rest },
ref,
) {
return (
Expand Down Expand Up @@ -52,13 +55,15 @@ export const CarouselImageItem = forwardRef<HTMLLIElement, CarouselImageItemProp
{caption || attribution ? (
<figure className="relative w-full h-full">
<Image maxWidth={1420} image={image as ImageWithAlt} fill className="rounded-md" />
<GridLinkArrow action={action} variant="circle" />
<figcaption
className={`${
active ? 'block' : 'hidden'
} absolute bottom-0 left-4 right-4 lg:left-8 lg:right-8 mb-4 lg:mb-8`}
} absolute -bottom-[158px] min-w-[40%] max-w-[60%] left-4 right-4 lg:left-16 lg:right-8 mb-4 lg:mb-8
`}
>
<div
className={`bg-spruce-wood-70/75 text-slate-80 px-8 pt-6 w-fit flex flex-col max-w-text ${
className={`w-full text-slate-80 pl-2 pr-8 flex flex-col max-w-text ${
attribution ? 'pb-4' : 'pb-6'
}`}
>
Expand All @@ -68,7 +73,10 @@ export const CarouselImageItem = forwardRef<HTMLLIElement, CarouselImageItemProp
</figcaption>
</figure>
) : (
<div>
<Image maxWidth={1420} image={image as ImageWithAlt} fill className="rounded-md" />
<GridLinkArrow action={action} variant="circle" />
</div>
)}
</li>
)
Expand Down
11 changes: 8 additions & 3 deletions web/lib/queries/common/imageCarouselFields.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import linkSelectorFields from './actions/linkSelectorFields'
import background from './background'

export const imageCarouselFields = /* groq */ `
Expand All @@ -6,15 +7,19 @@ export const imageCarouselFields = /* groq */ `
title,
ingress,
hideTitle,
items[] {
items[]{
...,
"id": _key,
...
action[0]{
${linkSelectorFields},
}
},
"options": {
autoplay,
delay
},
"designOptions": {
captionPositionUnderImage,
"designOptions": {
${background}
},
`
28 changes: 0 additions & 28 deletions web/pageComponents/shared/search/pagination/PaginationItem.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,8 @@
import { Button } from '@core/Button'
import { usePagination } from 'react-instantsearch'
import styled from 'styled-components'

// Based on: https://github.com/algolia/react-instantsearch/blob/master/examples/hooks/components/Pagination.tsx

const StyledListItem = styled.li`
display: inline-block;
`

const PaginationLink = styled(Button)<{ isCurrent?: boolean }>`
width: 44px;
height: 44px;
color: var(--pagination-btn-text-color);
${({ isCurrent }) =>
isCurrent && {
background: 'var(--pagination-btn-background-active)',
color: 'var(--pagination-btn-text-color-active)',
}}
:hover {
color: var(--pagination-btn-text-color-active);
:disabled {
color: var(--pagination-btn-disabled);
}
}
:disabled {
cursor: auto;
color: var(--pagination-btn-disabled);
}
`

export function isModifierClick(event: React.MouseEvent) {
const isMiddleClick = event.button === 1
return Boolean(isMiddleClick || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import { EventCardData } from '../../../../types/index'
import { forwardRef, HTMLAttributes } from 'react'
import { twMerge } from 'tailwind-merge'
import { getEventDates } from '../../../../common/helpers/dateUtilities'
import { toPlainText } from '@portabletext/react'
import { PortableTextBlock } from '@portabletext/types'
import { FormattedDateParts, useIntl } from 'react-intl'
import { FormattedDateParts } from 'react-intl'
import { BaseLink } from '@core/Link'
import { Icon } from '@equinor/eds-core-react'
import { world } from '@equinor/eds-icons'
Expand All @@ -19,12 +17,8 @@ const PastEventsListItem = forwardRef<HTMLAnchorElement, PastEventsListItemProps
{ event, className = '', hasSectionTitle = true, ...rest },
ref,
) {
const intl = useIntl()
const details = intl.formatMessage({ id: 'details', defaultMessage: 'Details' })

const { title, eventDate, location, slug } = event
const { start } = getEventDates(eventDate)
const plainTitle = title ? toPlainText(title as PortableTextBlock[]) : ''

return (
<BaseLink
Expand Down
70 changes: 41 additions & 29 deletions web/sections/Grid/GridLinkArrow.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,49 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { twMerge } from 'tailwind-merge'
import { getUrlFromAction } from '../../common/helpers'
import { BaseLink } from '@core/Link'
import { getLocaleFromName } from '../../lib/localization'
import { ArrowRight } from '../../icons'
import { LinkData } from '../../types/index'
import { forwardRef } from 'react'
import { twMerge } from 'tailwind-merge';
import { getUrlFromAction } from '../../common/helpers';
import { BaseLink } from '@core/Link';
import { getLocaleFromName } from '../../lib/localization';
import { ArrowRight } from '../../icons';
import { LinkData } from '../../types/index';
import { forwardRef } from 'react';

type GridLinkArrowProps = {
action?: LinkData
className?: string
bgColor?: string
}
action?: LinkData;
className?: string;
bgColor?: string;
variant?: "square" | "circle" ;
};

const GridLinkArrow = forwardRef<HTMLDivElement, GridLinkArrowProps>(function GridLinkArrow(
{ action, className = '', bgColor },
{ action, className = '', bgColor, variant = 'square' },
ref,
) {
const url = action && getUrlFromAction(action)
const url = action && getUrlFromAction(action);

const variantClassName = () => {
const bgClassName = () => {
switch (bgColor) {
case 'bg-yellow-50':
case 'bg-green-50':
case 'bg-orange-50':
case 'bg-mist-blue-100':
case 'bg-moss-green-50':
case 'bg-spruce-wood-90':
return `text-slate-80 hover:bg-slate-80 hover:text-white-100 focus-visible:bg-slate-80 focus-visible:text-white-100`
return `text-slate-80 hover:bg-slate-80 hover:text-white-100 focus-visible:bg-slate-80 focus-visible:text-white-100`;
case 'bg-white-100':
return `text-slate-80 hover:bg-grey-50 hover:text-white-100 focus-visible:bg-grey-50 focus-visible:text-white-100`
return `text-slate-80 hover:bg-grey-50 hover:text-white-100 focus-visible:bg-grey-50 focus-visible:text-white-100`;
case 'bg-blue-50':
case 'bg-slate-80':
default:
return `text-white-100 hover:bg-white-100 hover:text-slate-80 focus-visible:bg-white-100 focus-visible:text-slate-80`
return `text-white-100 hover:bg-white-100 hover:text-slate-80 focus-visible:bg-white-100 focus-visible:text-slate-80`;
}
};

const variantClassName = () => {
switch (variant) {
case 'circle':
return `m-1 p-2 hover:rounded-full`;
default:
return ``;
}
}

Expand All @@ -51,24 +61,26 @@ const GridLinkArrow = forwardRef<HTMLDivElement, GridLinkArrowProps>(function Gr
href={url as string}
{...(action.link?.lang && { locale: getLocaleFromName(action.link?.lang) })}
type={action.type}
className={`group
py-2
px-4
focus:outline-none
${variantClassName()}
focus-visible:envis-outline
dark:focus-visible:envis-outline
`}
className={twMerge(
`group
py-2
px-4
focus:outline-none
${bgClassName()}
${variantClassName()}
focus-visible:envis-outline
dark:focus-visible:envis-outline`,
)}
>
<span className="sr-only">{`${action.label} ${
action.extension ? `(${action.extension.toUpperCase()})` : ''
}`}</span>
<ArrowRight className={`size-10`} />
<ArrowRight className={variant === 'circle' ? 'size-7' :`size-10`} />
</BaseLink>
</div>
)}
</>
)
})
);
});

export default GridLinkArrow
export default GridLinkArrow;
2 changes: 2 additions & 0 deletions web/types/imageTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,6 @@ export type ImageCarouselData = {

export type ImageCarouselItem = {
id: string
captionPositionUnderImage?: boolean
action?: any
} & ImageWithCaptionData

0 comments on commit 9652402

Please sign in to comment.