Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
danielguillan committed Feb 15, 2024
1 parent 3c123dc commit 5edd985
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 21 deletions.
30 changes: 18 additions & 12 deletions packages/react/src/PricingCards/PricingCards.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,21 @@ export const OneItem: StoryFn<typeof PricingCards> = () => {
return (
<PricingCards>
<PricingCards.Item>
<PricingCards.Label>Recommended</PricingCards.Label>
<PricingCards.Heading>Copilot</PricingCards.Heading>
<PricingCards.Description>Copilot in the coding environment.</PricingCards.Description>
<PricingCards.Price trailingText="per user / month">Included</PricingCards.Price>
<PricingCards.FeatureList>
<PricingCards.Heading>Copilot Individual</PricingCards.Heading>
<PricingCards.Description>
Code completions, Chat, and more for indie developers and freelancers.
</PricingCards.Description>
<PricingCards.Price currencySymbol="$" trailingText="per month / $100 per year">
10
</PricingCards.Price>
{/* <PricingCards.FeatureList>
<PricingCards.FeatureListItem variant="highlight">
Everything in Copilot Business plus:
</PricingCards.FeatureListItem>
<PricingCards.FeatureListItem>Chat in IDE and Mobile</PricingCards.FeatureListItem>
<PricingCards.FeatureListItem>CLI assistance</PricingCards.FeatureListItem>
<PricingCards.FeatureListItem>Code completions</PricingCards.FeatureListItem>
</PricingCards.FeatureList>
</PricingCards.FeatureList> */}
<PricingCards.PrimaryAction href="/buy">Buy now</PricingCards.PrimaryAction>
<PricingCards.SecondaryAction href="/contact">Contact sales</PricingCards.SecondaryAction>
</PricingCards.Item>
Expand Down Expand Up @@ -118,10 +121,14 @@ export const ThreeItems: StoryFn<typeof PricingCards> = () => {
<PricingCards.FeatureListItem>Security vulnerability filter</PricingCards.FeatureListItem>
</PricingCards.FeatureList>

<PricingCards.PrimaryAction href="/buy">Buy now</PricingCards.PrimaryAction>
<PricingCards.SecondaryAction href="/contact">Contact sales</PricingCards.SecondaryAction>
<PricingCards.FootNote>
Free for verified students, teachers, and maintainers of popular open source projects.
</PricingCards.FootNote>

<PricingCards.PrimaryAction href="/buy">Start a free trial</PricingCards.PrimaryAction>
</PricingCards.Item>
<PricingCards.Item>

<PricingCards.Item featured>
<PricingCards.Label>Recommended</PricingCards.Label>
<PricingCards.Heading>Copilot Business</PricingCards.Heading>
<PricingCards.Description>Copilot personalized to your organization.</PricingCards.Description>
Expand All @@ -142,8 +149,8 @@ export const ThreeItems: StoryFn<typeof PricingCards> = () => {
Enterprise-grade security, safety, and privacy
</PricingCards.FeatureListItem>{' '}
</PricingCards.FeatureList>
<PricingCards.PrimaryAction href="/buy">Buy now</PricingCards.PrimaryAction>
<PricingCards.SecondaryAction href="/contact">Contact sales</PricingCards.SecondaryAction>
<PricingCards.PrimaryAction href="/buy">Buy now</PricingCards.PrimaryAction>
</PricingCards.Item>
<PricingCards.Item>
<PricingCards.Label>Available Feb 2024</PricingCards.Label>
Expand All @@ -163,8 +170,7 @@ export const ThreeItems: StoryFn<typeof PricingCards> = () => {
<PricingCards.FeatureListItem>CLI assistance</PricingCards.FeatureListItem>
<PricingCards.FeatureListItem>Code completions</PricingCards.FeatureListItem>
</PricingCards.FeatureList>
<PricingCards.PrimaryAction href="/buy">Buy now</PricingCards.PrimaryAction>
<PricingCards.SecondaryAction href="/contact">Contact sales</PricingCards.SecondaryAction>
<PricingCards.PrimaryAction href="/waitlist">Join waitlist</PricingCards.PrimaryAction>
</PricingCards.Item>
</PricingCards>
)
Expand Down
37 changes: 32 additions & 5 deletions packages/react/src/PricingCards/PricingCards.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,17 @@
/* ---------------------------------------------------------- */

.PricingCards--items-1 {
padding-block: var(--base-size-40);
padding-inline: var(--base-size-32);
border-radius: var(--brand-borderRadius-xlarge);
border: solid 1px var(--brand-color-border-default);
background-color: var(--brand-color-canvas-default);
}

.PricingCards--items-1,
.PricingCards--items-1 .PricingCards__item {
display: flex;
flex-direction: column;
}

/* ---------------------------------------------------------- */
Expand Down Expand Up @@ -52,7 +62,7 @@
}

/* ---------------------------------------------------------- */
/* 4. Two item layout */
/* 4. Two items */
/* ---------------------------------------------------------- */

.PricingCards--items-2 {
Expand Down Expand Up @@ -96,7 +106,7 @@
}

/* ---------------------------------------------------------- */
/* 5. Three item layout */
/* 5. Three items */
/* ---------------------------------------------------------- */

.PricingCards--items-3 {
Expand Down Expand Up @@ -125,7 +135,7 @@
@media (min-width: 63.28rem) {
.PricingCards__item {
display: grid;
grid-row: label / actions;
grid-row: label / footer;
grid-template-rows: subgrid;
}
}
Expand All @@ -145,10 +155,16 @@
'description'
'price'
'feature-list'
'actions';
'footer';
}
}

.PricingCards__item.PricingCards__item--featured {
border-width: 1px;
border-style: solid;
border-color: var(--brand-color-accent-primary);
}

/* ---------------------------------------------------------- */
/* 7. Content */
/* ---------------------------------------------------------- */
Expand Down Expand Up @@ -195,8 +211,15 @@
fill: var(--brand-color-accent-primary);
}

.PricingCards__footer {
grid-row: footer;
display: flex;
flex-direction: column;
justify-content: flex-end;
gap: var(--base-size-24);
}

.PricingCards__actions {
grid-row: actions;
display: flex;
flex-direction: column;
gap: var(--base-size-8);
Expand Down Expand Up @@ -245,3 +268,7 @@
.PricingCards__price-trailing-text {
align-self: center;
}

.PricingCards__footNode {
white-space: break-spaces;
}
5 changes: 4 additions & 1 deletion packages/react/src/PricingCards/PricingCards.module.css.d.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
declare const styles: {
readonly "PricingCards": string;
readonly "PricingCards--items-1": string;
readonly "PricingCards__item": string;
readonly "PricingCards--items-2": string;
readonly "PricingCards--items-3": string;
readonly "PricingCards__item": string;
readonly "PricingCards__item--featured": string;
readonly "PricingCards__label": string;
readonly "PricingCards__heading": string;
readonly "PricingCards__description": string;
readonly "PricingCards__price": string;
readonly "PricingCards__feature-list": string;
readonly "PricingCards__feature-list-item": string;
readonly "PricingCards__footer": string;
readonly "PricingCards__actions": string;
readonly "PricingCards__primary-action": string;
readonly "PricingCards__secondary-action": string;
readonly "PricingCards__price-currency-symbol": string;
readonly "PricingCards__price-value": string;
readonly "PricingCards__price-trailing-text": string;
readonly "PricingCards__footNode": string;
};
export = styles;

53 changes: 50 additions & 3 deletions packages/react/src/PricingCards/PricingCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,20 @@ export type PricingCardsItem<C extends keyof JSX.IntrinsicElements = 'article'>
* The HTML element used to render individual PricingCards items.
*/
as?: C | 'article' | 'div'
featured?: boolean
} & (C extends 'article' ? PropsWithChildren<BaseProps<HTMLElement>> : PropsWithChildren<BaseProps<HTMLDivElement>>)

const PricingCardsItem = forwardRef(
(
{children, className, animate, as = 'article', style, ...rest}: PropsWithChildren<PricingCardsItem>,
{
children,
className,
animate,
as = 'article',
featured = false,
style,
...rest
}: PropsWithChildren<PricingCardsItem>,
ref: Ref<HTMLDivElement>,
) => {
const {classes: animationClasses, styles: animationInlineStyles} = useAnimation(animate)
Expand Down Expand Up @@ -101,19 +110,36 @@ const PricingCardsItem = forwardRef(
return false
})

const footNotes = React.Children.toArray(children).filter(child => {
if (React.isValidElement(child) && typeof child.type !== 'string') {
if (child.type === PricingCardsFootNote) {
return true
}
}
return false
})

const validElements = ['div', 'article']
const Component = validElements.includes(as) ? as : 'div'

return (
<Component
className={clsx(styles.PricingCards__item, animationClasses, className)}
className={clsx(
styles.PricingCards__item,
{[styles[`PricingCards__item--featured`]]: featured},
animationClasses,
className,
)}
ref={ref}
{...(rest as HTMLAttributes<HTMLElement>)}
style={{...animationInlineStyles, ...style}}
>
{filteredChildren}

<footer className={styles.PricingCards__actions}>{filteredActions}</footer>
<footer className={styles.PricingCards__footer}>
{footNotes}
<div className={styles.PricingCards__actions}>{filteredActions}</div>
</footer>
</Component>
)
},
Expand Down Expand Up @@ -288,6 +314,26 @@ const PricingCardsSecondaryAction = forwardRef<
)
})

type PricingCardsFootNoteProps = BaseProps<HTMLParagraphElement>

const PricingCardsFootNote = forwardRef<HTMLParagraphElement, PricingCardsFootNoteProps>(
({children, className, ...rest}, ref) => {
return (
<Text
as="p"
ref={ref}
size="100"
weight="light"
variant="muted"
className={clsx(styles['PricingCards__footnote'], className)}
{...rest}
>
{children}
</Text>
)
},
)

/**
* Pricing card component:
* {@link https://primer.style/brand/components/PricingCards/ See usage examples}.
Expand All @@ -302,4 +348,5 @@ export const PricingCards = Object.assign(PricingCardsRoot, {
FeatureListItem: PricingCardsFeatureListItem,
PrimaryAction: PricingCardsPrimaryAction,
SecondaryAction: PricingCardsSecondaryAction,
FootNote: PricingCardsFootNote,
})

0 comments on commit 5edd985

Please sign in to comment.