| 1 |
import { PageCanvas } from '@auto-launch/templates/PageCanvas'; |
| 2 |
import { CARD } from '@auto-launch/templates/surface'; |
| 3 |
import { arrowRight, Icon } from '@wordpress/icons'; |
| 4 |
import classNames from 'classnames'; |
| 5 |
|
| 6 |
// Makes room for the highlighted box's negative top margin. |
| 7 |
const GRID = [ |
| 8 |
'relative z-10 grid w-full sm:mx-auto sm:grid-cols-2 sm:pt-7', |
| 9 |
'[gap:var(--ext-tpl-choice-gap,24px)]', |
| 10 |
].join(' '); |
| 11 |
|
| 12 |
const WIDE = [ |
| 13 |
'sm:[max-width:var(--ext-tpl-choice-width,672px)]', |
| 14 |
'sm:[align-items:var(--ext-tpl-choice-align,stretch)]', |
| 15 |
].join(' '); |
| 16 |
|
| 17 |
const BOX = [ |
| 18 |
CARD, |
| 19 |
'flex flex-col overflow-hidden text-left text-ui-ink', |
| 20 |
'[gap:var(--ext-tpl-choice-box-gap,0px)]', |
| 21 |
].join(' '); |
| 22 |
|
| 23 |
const HIGHLIGHT = [ |
| 24 |
'[border-width:var(--ext-tpl-choice-highlight-border,3px)]', |
| 25 |
'border-ui-action sm:-mt-7', |
| 26 |
].join(' '); |
| 27 |
|
| 28 |
const BADGE = [ |
| 29 |
'flex items-center justify-center bg-ui-action', |
| 30 |
'[height:var(--ext-tpl-choice-badge-height,28px)]', |
| 31 |
'text-ui-status font-ui-status text-ui-action-text', |
| 32 |
].join(' '); |
| 33 |
|
| 34 |
const ICON_STRIP = [ |
| 35 |
'flex items-center justify-center text-ui-ink', |
| 36 |
'[padding-block:var(--ext-tpl-choice-icon-pad,40px)]', |
| 37 |
].join(' '); |
| 38 |
|
| 39 |
const BODY = 'flex flex-1 flex-col justify-between gap-ui p-ui'; |
| 40 |
|
| 41 |
const COPY = 'flex flex-col [gap:var(--ext-tpl-choice-copy-gap,8px)]'; |
| 42 |
|
| 43 |
const BUTTON = [ |
| 44 |
'inline-flex w-full items-center justify-between gap-2 rounded-ui-button', |
| 45 |
'[padding:var(--ext-tpl-choice-button-pad,10px)_var(--ext-tpl-choice-button-pad-x,20px)]', |
| 46 |
'text-ui-body font-ui-body transition focus:outline-none', |
| 47 |
'focus-visible:ring-1 focus-visible:ring-ui-line', |
| 48 |
].join(' '); |
| 49 |
|
| 50 |
const Box = ({ |
| 51 |
icon, |
| 52 |
badgeLabel, |
| 53 |
heading, |
| 54 |
description, |
| 55 |
buttonLabel, |
| 56 |
buttonIcon = arrowRight, |
| 57 |
highlight, |
| 58 |
onClick, |
| 59 |
}) => ( |
| 60 |
<div className={classNames(BOX, highlight ? HIGHLIGHT : 'border-ui')}> |
| 61 |
{highlight && badgeLabel && <span className={BADGE}>{badgeLabel}</span>} |
| 62 |
<span className={ICON_STRIP}> |
| 63 |
<Icon fill="currentColor" icon={icon} size={40} /> |
| 64 |
</span> |
| 65 |
<span className={BODY}> |
| 66 |
<span className={COPY}> |
| 67 |
{heading && ( |
| 68 |
<span className="text-ui-body font-ui-heading font-ui-strong"> |
| 69 |
{heading} |
| 70 |
</span> |
| 71 |
)} |
| 72 |
<span className="text-ui-body opacity-70">{description}</span> |
| 73 |
</span> |
| 74 |
<button |
| 75 |
type="button" |
| 76 |
onClick={onClick} |
| 77 |
className={classNames( |
| 78 |
BUTTON, |
| 79 |
highlight |
| 80 |
? 'border-ui border-ui-action bg-ui-action text-ui-action-text hover:opacity-90' |
| 81 |
: 'border-ui border-ui-line bg-ui-secondary-fill text-ui-secondary-text', |
| 82 |
)} |
| 83 |
> |
| 84 |
{buttonLabel} |
| 85 |
<Icon fill="currentColor" icon={buttonIcon} size={20} /> |
| 86 |
</button> |
| 87 |
</span> |
| 88 |
</div> |
| 89 |
); |
| 90 |
|
| 91 |
export const Page = ({ parts, has }) => ( |
| 92 |
<PageCanvas> |
| 93 |
<div className="w-full flex flex-col items-center gap-ui md:gap-ui-lg m-auto"> |
| 94 |
<div className="mb-ui-block">{parts.logo}</div> |
| 95 |
{has.heading && parts.heading} |
| 96 |
<div className={classNames(GRID, WIDE)}> |
| 97 |
{(parts.options ?? []).map(({ key, ...option }) => ( |
| 98 |
<Box key={key} {...option} /> |
| 99 |
))} |
| 100 |
</div> |
| 101 |
</div> |
| 102 |
{has.footer && <div className="w-full pt-8 shrink-0">{parts.footer}</div>} |
| 103 |
</PageCanvas> |
| 104 |
); |
| 105 |
|