mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 05:06:55 +04:00
Add docs and demo pages for Pricing and Shape
This commit is contained in:
1 parent
ef3abccfcf
commit
6056009b60
9 files changed
+546
-1
No files matched your search
@@ -3,9 +3,11 @@
|
||||
@use '../config' as *;
|
||||
|
||||
.shape {
|
||||
// scss-docs-start shape-css-vars
|
||||
--shape-size: #{$avatar-size};
|
||||
--shape-icon-size: #{$avatar-icon-size};
|
||||
--shape-border-radius: 35%;
|
||||
// scss-docs-end shape-css-vars
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
---
|
||||
title: Pricing
|
||||
summary: A row of plan cards with a price, a feature list and a button, where one card can be marked as featured.
|
||||
description: Show your plans side by side with the pricing component. Each card has a title, a price, a feature list and a button. Mark one card as featured to raise it above the others.
|
||||
related: [/ui/components/card, /ui/components/badge]
|
||||
source: core/scss/ui/_pricing.scss
|
||||
added-in: '1.7.0'
|
||||
classnames:
|
||||
component:
|
||||
- class: pricing
|
||||
desc: Container that lays the cards out in a column, and in a row from the md breakpoint up
|
||||
part:
|
||||
- class: pricing-card
|
||||
desc: One plan, with a border, a shadow and centered text
|
||||
- class: pricing-title
|
||||
desc: Plan name, sized like an h2
|
||||
- class: pricing-label
|
||||
desc: Label centered on the top edge of the card, for a badge such as "Popular"
|
||||
- class: pricing-price
|
||||
desc: Price row, large and bold
|
||||
- class: pricing-price-currency
|
||||
desc: Currency sign in front of the amount, smaller than the amount
|
||||
- class: pricing-price-description
|
||||
desc: Text next to the amount, such as the billing period
|
||||
- class: pricing-features
|
||||
desc: Plain list of features, aligned to the start
|
||||
- class: pricing-btn
|
||||
desc: Button wrapper, pushed to the bottom of the card
|
||||
modifier:
|
||||
- class: featured
|
||||
desc: Raises the card, adds a primary border and puts it first on small screens; set on pricing-card
|
||||
---
|
||||
import Example from '@components/Example.astro';
|
||||
import Icon from '@ui/Icon.astro';
|
||||
|
||||
## Default markup
|
||||
|
||||
Put the plans in a `.pricing` container, one `.pricing-card` per plan. Each card holds a `.pricing-title`, a `.pricing-price`, a `.pricing-features` list and a `.pricing-btn`. On small screens the cards stack. From the `md` breakpoint up they sit in a row and share their borders, so the group reads as one table.
|
||||
|
||||
Add `.featured` to the main plan. The card gets a primary border and a shadow, and on wide screens it is a bit taller than its neighbors, so it stands out. On small screens it moves to the top of the stack. A `.pricing-label` with a [badge](/ui/components/badge) sits on the top edge of the card.
|
||||
|
||||
<Example>
|
||||
<div class="pricing">
|
||||
<div class="pricing-card">
|
||||
<h3 class="pricing-title">Free</h3>
|
||||
<div class="pricing-price">
|
||||
<span class="pricing-price-currency">$</span>0
|
||||
<div class="pricing-price-description">
|
||||
<div>per user</div>
|
||||
<div>per month</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="pricing-features my-4">
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />Up to 3 users</li>
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />Basic components</li>
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />Community support</li>
|
||||
</ul>
|
||||
<div class="pricing-btn"><a href="#" class="btn w-100">Get started</a></div>
|
||||
</div>
|
||||
<div class="pricing-card featured">
|
||||
<div class="pricing-label"><span class="badge bg-primary text-primary-fg">Popular</span></div>
|
||||
<h3 class="pricing-title">Premium</h3>
|
||||
<div class="pricing-price">
|
||||
<span class="pricing-price-currency">$</span>49
|
||||
<div class="pricing-price-description">
|
||||
<div>per user</div>
|
||||
<div>per month</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="pricing-features my-4">
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />Up to 10 users</li>
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />All components</li>
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />Figma UI kit</li>
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />Priority support</li>
|
||||
</ul>
|
||||
<div class="pricing-btn"><a href="#" class="btn btn-primary w-100">Get started</a></div>
|
||||
</div>
|
||||
<div class="pricing-card">
|
||||
<h3 class="pricing-title">Enterprise</h3>
|
||||
<div class="pricing-price">
|
||||
<span class="pricing-price-currency">$</span>99
|
||||
<div class="pricing-price-description">
|
||||
<div>per user</div>
|
||||
<div>per month</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="pricing-features my-4">
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />Unlimited users</li>
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />All components</li>
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />Dedicated support</li>
|
||||
</ul>
|
||||
<div class="pricing-btn"><a href="#" class="btn w-100">Contact us</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
## Price
|
||||
|
||||
The `.pricing-price` row holds the amount. Put the currency sign in a `.pricing-price-currency` in front of it, and the billing period in a `.pricing-price-description` after it. The description is smaller and uses the secondary text color, so the amount stays the strongest part of the card.
|
||||
|
||||
<Example centered>
|
||||
<div class="pricing-price">
|
||||
<span class="pricing-price-currency">$</span>49
|
||||
<div class="pricing-price-description">
|
||||
<div>per user</div>
|
||||
<div>per month</div>
|
||||
</div>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
## Features
|
||||
|
||||
`.pricing-features` is a plain list with no bullets, aligned to the start of the card. Put an icon in front of each item to show what the plan includes. Use a margin utility such as `.my-4` to space the list from the price and the button.
|
||||
|
||||
<Example centered>
|
||||
<ul class="pricing-features">
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />Up to 10 users</li>
|
||||
<li><Icon name="check" color="green" class="icon-inline me-1" />All components</li>
|
||||
<li><Icon name="x" color="red" class="icon-inline me-1" />Dedicated support</li>
|
||||
</ul>
|
||||
</Example>
|
||||
|
||||
## Accessibility
|
||||
|
||||
- Use a heading for `.pricing-title`, with the level that fits the page, so users of a screen reader can jump between plans.
|
||||
- Say in the button text or in an `aria-label` which plan the button belongs to when several buttons share the same text.
|
||||
- Do not rely on the border color alone to mark the featured plan. The `.pricing-label` badge names it in text.
|
||||
@@ -0,0 +1,107 @@
|
||||
---
|
||||
title: Shape
|
||||
summary: A tinted, rounded square that holds one icon, for feature lists and other places where an icon needs a background.
|
||||
description: Put an icon on a soft, tinted background with the shape component. Pick a size and a color, or set the corner radius with a CSS variable.
|
||||
related: [/ui/components/avatar, /ui/components/icon]
|
||||
source: core/scss/ui/_shape.scss
|
||||
css-vars: shape
|
||||
added-in: '1.7.0'
|
||||
classnames:
|
||||
component:
|
||||
- class: shape
|
||||
desc: Container element, an inline rounded square in the primary color
|
||||
color:
|
||||
- class: shape-{color}
|
||||
desc: Any palette color, for example shape-red or shape-teal
|
||||
size:
|
||||
- class: shape-{size}
|
||||
desc: Avatar sizes from shape-xxs to shape-2xl
|
||||
---
|
||||
import Example from '@components/Example.astro';
|
||||
import Icon from '@ui/Icon.astro';
|
||||
|
||||
## Default markup
|
||||
|
||||
A shape is a `.shape` element with one icon inside. It is a square with soft corners, filled with a light tint of the primary color. The icon takes the stronger primary color. The square is the same size as an [avatar](/ui/components/avatar), so the two line up in a list.
|
||||
|
||||
<Example centered>
|
||||
<span class="shape"><Icon name="devices" /></span>
|
||||
</Example>
|
||||
|
||||
## Sizes
|
||||
|
||||
Add `.shape-{size}` to change the size. The sizes are the avatar sizes, from `xxs` to `2xl`. The icon grows with the square.
|
||||
|
||||
<Example centered>
|
||||
<div class="d-flex align-items-end gap-3">
|
||||
<span class="shape shape-xxs"><Icon name="star" /></span>
|
||||
<span class="shape shape-xs"><Icon name="star" /></span>
|
||||
<span class="shape shape-sm"><Icon name="star" /></span>
|
||||
<span class="shape shape-md"><Icon name="star" /></span>
|
||||
<span class="shape shape-lg"><Icon name="star" /></span>
|
||||
<span class="shape shape-xl"><Icon name="star" /></span>
|
||||
<span class="shape shape-2xl"><Icon name="star" /></span>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
## Colors
|
||||
|
||||
Add `.shape-{color}` to use another palette color. The square takes the light tint of the color and the icon takes the full color.
|
||||
|
||||
<Example centered>
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
<span class="shape shape-blue"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-azure"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-indigo"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-purple"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-pink"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-red"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-orange"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-yellow"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-lime"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-green"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-teal"><Icon name="brand-bootstrap" /></span>
|
||||
<span class="shape shape-cyan"><Icon name="brand-bootstrap" /></span>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
## Corner radius
|
||||
|
||||
The corners are rounded by `35%` of the size. Set `--tblr-shape-border-radius` on the shape to change this: `50%` makes a circle, `0` makes a sharp square.
|
||||
|
||||
<Example centered>
|
||||
<div class="d-flex gap-3">
|
||||
<span class="shape shape-md" style="--tblr-shape-border-radius: 0"><Icon name="palette" /></span>
|
||||
<span class="shape shape-md"><Icon name="palette" /></span>
|
||||
<span class="shape shape-md" style="--tblr-shape-border-radius: 50%"><Icon name="palette" /></span>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
## In a feature list
|
||||
|
||||
Shapes mark the items of a feature list. Put one above or next to each heading, with the same size and color on every item.
|
||||
|
||||
<Example>
|
||||
<div class="row g-4">
|
||||
<div class="col-md-4">
|
||||
<span class="shape shape-md mb-3"><Icon name="devices" /></span>
|
||||
<h3>Mobile-optimized</h3>
|
||||
<p class="text-secondary">Every page works on any screen size.</p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<span class="shape shape-md mb-3"><Icon name="mailbox" /></span>
|
||||
<h3>Tested email clients</h3>
|
||||
<p class="text-secondary">Checked in more than 90 email clients.</p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<span class="shape shape-md mb-3"><Icon name="palette" /></span>
|
||||
<h3>Minimal design</h3>
|
||||
<p class="text-secondary">Clean layouts based on Bootstrap.</p>
|
||||
</div>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
## Accessibility
|
||||
|
||||
- A shape is decoration. The icon inside renders with `aria-hidden="true"`, so the shape adds nothing to the accessibility tree.
|
||||
- Put the meaning in the text next to the shape, not in the icon or the color.
|
||||
@@ -1,10 +1,20 @@
|
||||
---
|
||||
import DefaultLayout from '@shared/layouts/DefaultLayout.astro'
|
||||
import DocsLink from '@ui/DocsLink.astro'
|
||||
import Icon from '@ui/Icon.astro'
|
||||
import PricingCard from '@shared/components/cards/PricingCard.astro'
|
||||
import PricingCardEnterprise from '@shared/components/cards/PricingCardEnterprise.astro'
|
||||
|
||||
const plans = [
|
||||
{ title: 'Free', price: '0', features: ['Up to 3 users', 'Basic components', 'Community support'], button: 'Get started', buttonClass: 'btn' },
|
||||
{ title: 'Premium', price: '49', featured: true, label: 'Popular', features: ['Up to 10 users', 'All components', 'Figma UI kit', 'Priority support'], button: 'Get started', buttonClass: 'btn btn-primary' },
|
||||
{ title: 'Enterprise', price: '99', features: ['Unlimited users', 'All components', 'Dedicated support'], button: 'Contact us', buttonClass: 'btn' },
|
||||
]
|
||||
---
|
||||
|
||||
<DefaultLayout title="Pricing cards" pageMenu="extra.pricing">
|
||||
<DefaultLayout title="Pricing cards" pageMenu="extra.pricing" description="Pricing cards show the plans side by side, with a price, a feature list and a button on each one.">
|
||||
<DocsLink slot="page-header-actions" path="/ui/components/pricing" />
|
||||
|
||||
<div class="row row-cards">
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<PricingCard price="0" users={3} category="Free" />
|
||||
@@ -21,5 +31,42 @@ import PricingCardEnterprise from '@shared/components/cards/PricingCardEnterpris
|
||||
<div class="col-12">
|
||||
<PricingCardEnterprise />
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="pricing">
|
||||
{
|
||||
plans.map((plan) => (
|
||||
<div class:list={['pricing-card', plan.featured && 'featured']}>
|
||||
{plan.label && (
|
||||
<div class="pricing-label">
|
||||
<span class="badge bg-primary text-primary-fg">{plan.label}</span>
|
||||
</div>
|
||||
)}
|
||||
<h2 class="pricing-title">{plan.title}</h2>
|
||||
<div class="pricing-price">
|
||||
<span class="pricing-price-currency">$</span>
|
||||
{plan.price}
|
||||
<div class="pricing-price-description">
|
||||
<div>per user</div>
|
||||
<div>per month</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="pricing-features my-4">
|
||||
{plan.features.map((feature) => (
|
||||
<li>
|
||||
<Icon name="check" color="green" class="icon-inline me-1" />
|
||||
{feature}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div class="pricing-btn">
|
||||
<a href="#" class:list={[plan.buttonClass, 'w-100']}>
|
||||
{plan.button}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DefaultLayout>
|
||||
@@ -0,0 +1,162 @@
|
||||
---
|
||||
import DefaultLayout from '@shared/layouts/DefaultLayout.astro'
|
||||
import Card from '@ui/Card.astro'
|
||||
import CardBody from '@ui/CardBody.astro'
|
||||
import CardTitle from '@ui/CardTitle.astro'
|
||||
import CardSubtitle from '@ui/CardSubtitle.astro'
|
||||
import DocsLink from '@ui/DocsLink.astro'
|
||||
import Icon from '@ui/Icon.astro'
|
||||
import { avatarSizes, extraColors } from '@shared/lib/tokens'
|
||||
|
||||
const icons = ['devices', 'mailbox', 'palette', 'tools', 'brand-bootstrap', 'paint', 'rocket', 'shield-check']
|
||||
|
||||
const radii = [
|
||||
{ label: 'Square', value: '0' },
|
||||
{ label: 'Default', value: undefined },
|
||||
{ label: 'Circle', value: '50%' },
|
||||
]
|
||||
|
||||
const features = [
|
||||
{ icon: 'devices', title: 'Mobile-optimized', text: 'Every page works on any screen size, from a phone to a wide monitor.' },
|
||||
{ icon: 'mailbox', title: 'Tested email clients', text: 'Checked in more than 90 email clients and devices.' },
|
||||
{ icon: 'palette', title: 'Minimal design', text: 'Clean layouts based on Bootstrap and Material Design principles.' },
|
||||
]
|
||||
|
||||
const featureList = [
|
||||
{ icon: 'tools', color: 'blue', title: 'Easy to customize', text: 'Change colors, fonts and spacing with Sass or CSS variables.' },
|
||||
{ icon: 'brand-bootstrap', color: 'purple', title: 'Built on Bootstrap', text: 'Every Bootstrap component works out of the box.' },
|
||||
{ icon: 'paint', color: 'green', title: 'Dark mode', text: 'One attribute switches the whole interface to a dark theme.' },
|
||||
]
|
||||
---
|
||||
|
||||
<DefaultLayout title="Shape" pageMenu="base.shape" description="Shapes put an icon on a soft, tinted square, for feature lists and other places where an icon needs a background.">
|
||||
<DocsLink slot="page-header-actions" path="/ui/components/shape" />
|
||||
|
||||
<div class="row row-cards">
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardTitle>Sizes</CardTitle>
|
||||
<CardSubtitle>Add <code>.shape-{size}</code>, from <code>xxs</code> to <code>2xl</code>, the same sizes as an avatar.</CardSubtitle>
|
||||
<div class="d-flex flex-wrap align-items-end gap-3">
|
||||
{
|
||||
avatarSizes.map((size) => (
|
||||
<span class:list={['shape', `shape-${size}`]}>
|
||||
<Icon name="star" />
|
||||
</span>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardTitle>Colors</CardTitle>
|
||||
<CardSubtitle>Add <code>.shape-{color}</code> to use another palette color.</CardSubtitle>
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
<span class="shape"><Icon name="brand-bootstrap" /></span>
|
||||
{
|
||||
extraColors.map((color) => (
|
||||
<span class:list={['shape', `shape-${color}`]}>
|
||||
<Icon name="brand-bootstrap" />
|
||||
</span>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardTitle>With icons</CardTitle>
|
||||
<CardSubtitle>Put one <code>.icon</code> inside the shape; it is sized with the square.</CardSubtitle>
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
{
|
||||
icons.map((icon) => (
|
||||
<span class="shape shape-md">
|
||||
<Icon name={icon} />
|
||||
</span>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardTitle>Corner radius</CardTitle>
|
||||
<CardSubtitle>Set <code>--tblr-shape-border-radius</code> to change the corners; the default is <code>35%</code>.</CardSubtitle>
|
||||
<div class="d-flex flex-wrap gap-4">
|
||||
{
|
||||
radii.map((item) => (
|
||||
<div class="text-center">
|
||||
<span class="shape shape-lg" style={item.value && `--tblr-shape-border-radius: ${item.value}`}>
|
||||
<Icon name="palette" />
|
||||
</span>
|
||||
<div class="text-secondary small mt-1">{item.label}</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-8">
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardTitle>Feature list</CardTitle>
|
||||
<CardSubtitle>A shape above each heading, with the same size and color on every item.</CardSubtitle>
|
||||
<div class="row g-4 text-center">
|
||||
{
|
||||
features.map((feature) => (
|
||||
<div class="col-md-4">
|
||||
<span class="shape shape-md mb-3">
|
||||
<Icon name={feature.icon} />
|
||||
</span>
|
||||
<h3 class="h3">{feature.title}</h3>
|
||||
<p class="text-secondary mb-0">{feature.text}</p>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardTitle>Feature list, inline</CardTitle>
|
||||
<CardSubtitle>A colored shape next to each heading, in a <code>.row</code> with an auto column.</CardSubtitle>
|
||||
<div class="row g-4">
|
||||
{
|
||||
featureList.map((feature) => (
|
||||
<div class="col-md-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-auto">
|
||||
<span class:list={['shape', 'shape-md', `shape-${feature.color}`]}>
|
||||
<Icon name={feature.icon} />
|
||||
</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3 class="h4 mb-1">{feature.title}</h3>
|
||||
<p class="text-secondary mb-0">{feature.text}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</DefaultLayout>
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
// Pricing component: three plan cards joined into one table, the middle one
|
||||
// featured with a primary border and a "Popular" badge on its top edge. Same
|
||||
// plans as the docs page, so the picture matches the example.
|
||||
import ScreenshotLayout from '../layouts/ScreenshotLayout.astro'
|
||||
import Icon from '@ui/Icon.astro'
|
||||
|
||||
const plans = [
|
||||
{ title: 'Free', price: '0', features: ['Up to 3 users', 'Basic components', 'Community support'], button: 'Get started', buttonClass: 'btn' },
|
||||
{ title: 'Premium', price: '49', featured: true, label: 'Popular', features: ['Up to 10 users', 'All components', 'Figma UI kit', 'Priority support'], button: 'Get started', buttonClass: 'btn btn-primary' },
|
||||
{ title: 'Enterprise', price: '99', features: ['Unlimited users', 'All components', 'Dedicated support'], button: 'Contact us', buttonClass: 'btn' },
|
||||
]
|
||||
---
|
||||
|
||||
<ScreenshotLayout title="Pricing" columns={3}>
|
||||
<div class="pricing">
|
||||
{
|
||||
plans.map((plan) => (
|
||||
<div class:list={['pricing-card', plan.featured && 'featured']}>
|
||||
{plan.label && (
|
||||
<div class="pricing-label">
|
||||
<span class="badge bg-primary text-primary-fg">{plan.label}</span>
|
||||
</div>
|
||||
)}
|
||||
<h2 class="pricing-title">{plan.title}</h2>
|
||||
<div class="pricing-price">
|
||||
<span class="pricing-price-currency">$</span>
|
||||
{plan.price}
|
||||
<div class="pricing-price-description">
|
||||
<div>per user</div>
|
||||
<div>per month</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="pricing-features my-4">
|
||||
{plan.features.map((feature) => (
|
||||
<li>
|
||||
<Icon name="check" color="green" class="icon-inline me-1" />
|
||||
{feature}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div class="pricing-btn">
|
||||
<a href="#" class:list={[plan.buttonClass, 'w-100']}>
|
||||
{plan.button}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</ScreenshotLayout>
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
// Shape component: a three-item feature list, each item with a colored shape
|
||||
// above its heading, the way the marketing pages use it. Three colors so the
|
||||
// tint and the icon color read as a pair; medium size so the icons are legible
|
||||
// at picture size.
|
||||
import ScreenshotLayout from '../layouts/ScreenshotLayout.astro'
|
||||
import Card from '@ui/Card.astro'
|
||||
import CardBody from '@ui/CardBody.astro'
|
||||
import Icon from '@ui/Icon.astro'
|
||||
|
||||
const features = [
|
||||
{ icon: 'devices', color: 'blue', title: 'Mobile-optimized', text: 'Every page works on any screen size, from a phone to a wide monitor.' },
|
||||
{ icon: 'mailbox', color: 'purple', title: 'Tested email clients', text: 'Checked in more than 90 email clients and devices.' },
|
||||
{ icon: 'palette', color: 'green', title: 'Minimal design', text: 'Clean layouts based on Bootstrap and Material Design principles.' },
|
||||
]
|
||||
---
|
||||
|
||||
<ScreenshotLayout title="Shape" columns={3}>
|
||||
<Card>
|
||||
<CardBody class="p-5">
|
||||
<div class="row g-5 text-center">
|
||||
{
|
||||
features.map((feature) => (
|
||||
<div class="col-4">
|
||||
<span class:list={['shape', 'shape-xl', `shape-${feature.color}`, 'mb-3']}>
|
||||
<Icon name={feature.icon} />
|
||||
</span>
|
||||
<h3 class="h3">{feature.title}</h3>
|
||||
<p class="text-secondary mb-0">{feature.text}</p>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</ScreenshotLayout>
|
||||
@@ -274,6 +274,10 @@
|
||||
"title": "Popover",
|
||||
"url": "/ui/components/popover"
|
||||
},
|
||||
{
|
||||
"title": "Pricing",
|
||||
"url": "/ui/components/pricing"
|
||||
},
|
||||
{
|
||||
"title": "Progress bar",
|
||||
"url": "/ui/components/progress"
|
||||
@@ -290,6 +294,10 @@
|
||||
"title": "Segmented control",
|
||||
"url": "/ui/components/segmented-control"
|
||||
},
|
||||
{
|
||||
"title": "Shape",
|
||||
"url": "/ui/components/shape"
|
||||
},
|
||||
{
|
||||
"title": "Signal",
|
||||
"url": "/ui/components/signal"
|
||||
|
||||
@@ -236,6 +236,11 @@
|
||||
"title": "Scroll spy",
|
||||
"url": "scroll-spy.html"
|
||||
},
|
||||
"shape": {
|
||||
"title": "Shape",
|
||||
"url": "shape.html",
|
||||
"badge": "New"
|
||||
},
|
||||
"signal": {
|
||||
"title": "Signal",
|
||||
"url": "signal.html"
|
||||
|
||||
Reference in new issue
Block a user