diff options
author | HiDeoo | 2024-08-16 19:03:05 +0200 |
---|---|---|
committer | GitHub | 2024-08-16 19:03:05 +0200 |
commit | 68f56a7ffd314b760443a057db9ed1a982dbe191 (patch) | |
tree | ca1b14dd6d645e923044b5d25aac7c519c5d0cf7 | |
parent | 9368494210dbcd80ada5b410340814fe36c4eb6c (diff) | |
download | IT.starlight-68f56a7ffd314b760443a057db9ed1a982dbe191.tar.gz IT.starlight-68f56a7ffd314b760443a057db9ed1a982dbe191.tar.bz2 IT.starlight-68f56a7ffd314b760443a057db9ed1a982dbe191.zip |
Add `<LinkButton>` component (#1784)
Co-authored-by: Chris Swithinbank <357379+delucis@users.noreply.github.com>
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
-rw-r--r-- | .changeset/chilled-pots-eat.md | 5 | ||||
-rw-r--r-- | .changeset/thirty-students-sit.md | 16 | ||||
-rw-r--r-- | docs/src/content/docs/guides/components.mdx | 32 | ||||
-rw-r--r-- | docs/src/content/docs/index.mdx | 5 | ||||
-rw-r--r-- | docs/src/content/docs/reference/frontmatter.md | 6 | ||||
-rw-r--r-- | packages/starlight/components.ts | 1 | ||||
-rw-r--r-- | packages/starlight/components/CallToAction.astro | 51 | ||||
-rw-r--r-- | packages/starlight/components/Hero.astro | 9 | ||||
-rw-r--r-- | packages/starlight/package.json | 4 | ||||
-rw-r--r-- | packages/starlight/schemas/hero.ts | 4 | ||||
-rw-r--r-- | packages/starlight/user-components/LinkButton.astro | 76 |
11 files changed, 144 insertions, 65 deletions
diff --git a/.changeset/chilled-pots-eat.md b/.changeset/chilled-pots-eat.md new file mode 100644 index 00000000..e5c56b35 --- /dev/null +++ b/.changeset/chilled-pots-eat.md @@ -0,0 +1,5 @@ +--- +'@astrojs/starlight': minor +--- + +Adds `<LinkButton>` component for visually distinct and emphasized call to action links diff --git a/.changeset/thirty-students-sit.md b/.changeset/thirty-students-sit.md new file mode 100644 index 00000000..1cfa90b6 --- /dev/null +++ b/.changeset/thirty-students-sit.md @@ -0,0 +1,16 @@ +--- +'@astrojs/starlight': minor +--- + +Changes the hero component action button default [variant](https://starlight.astro.build/reference/frontmatter/#heroconfig) from `minimal` to `primary`. + +If you want to preserve the previous behavior, hero component action buttons previously declared without a `variant` will need to be updated to include the `variant` property with the value `minimal`. + +```diff +hero: + actions: + - text: View on GitHub + link: https://github.com/astronaut/my-project + icon: external ++ variant: minimal +``` diff --git a/docs/src/content/docs/guides/components.mdx b/docs/src/content/docs/guides/components.mdx index 95a5e30f..4624a176 100644 --- a/docs/src/content/docs/guides/components.mdx +++ b/docs/src/content/docs/guides/components.mdx @@ -222,6 +222,38 @@ import { LinkCard } from '@astrojs/starlight/components'; <LinkCard title="Components" href="/guides/components/" /> </CardGrid> +### Link Buttons + +Use the `<LinkButton>` component for visually distinct call-to-action links. +A link button is useful for directing users to the most relevant or actionable content and often used on landing pages + +A `<LinkButton>` requires an [`href`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#href) attribute and optionally accepts other link attributes such as `target`. + +The `icon` attribute can optionally be set to the name of [one of Starlight's built-in icons](#all-icons) to include an icon next to the text. +The `iconPlacement` attribute can be used to place the icon before the text by setting it to `start` (defaults to `end`). + +Customize the appearance of the link button using the `variant` attribute, which can be set to `primary` (the default), `secondary`, or `minimal`. + +```mdx +# src/content/docs/example.mdx + +import { LinkButton } from '@astrojs/starlight/components'; + +<LinkButton href="/getting-started/">Get started</LinkButton> +<LinkButton href="https://docs.astro.build" variant="secondary" icon="external"> + Related: Astro +</LinkButton> +``` + +The above code generates the following on the page: + +import { LinkButton } from '@astrojs/starlight/components'; + +<LinkButton href="/getting-started/">Get started</LinkButton> +<LinkButton href="https://docs.astro.build" variant="secondary" icon="external"> + Related: Astro +</LinkButton> + ### Asides Asides (also known as “admonitions” or “callouts”) are useful for displaying secondary information alongside a page’s main content. diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx index 79c5ba60..d1dee8fe 100644 --- a/docs/src/content/docs/index.mdx +++ b/docs/src/content/docs/index.mdx @@ -15,10 +15,10 @@ hero: actions: - text: Get started icon: right-arrow - variant: primary link: /getting-started/ - text: View on GitHub icon: external + variant: minimal link: https://github.com/withastro/starlight --- @@ -69,8 +69,9 @@ import Testimonial from '~/components/testimonial.astro'; Starlight is our go-to example of a great DX: the speed, convenience, and attention to details is inspiring. It takes care of the tech and the looks, so you can focus on your content 👏 - + StackBlitz team absolutely loves it! + </Testimonial> <Testimonial name="Roberto" diff --git a/docs/src/content/docs/reference/frontmatter.md b/docs/src/content/docs/reference/frontmatter.md index 41fc4a5b..75b56444 100644 --- a/docs/src/content/docs/reference/frontmatter.md +++ b/docs/src/content/docs/reference/frontmatter.md @@ -115,10 +115,10 @@ hero: - text: Tell me more link: /getting-started/ icon: right-arrow - variant: primary - text: View on GitHub link: https://github.com/astronaut/my-project icon: external + variant: minimal attrs: rel: me --- @@ -166,8 +166,8 @@ interface HeroConfig { actions?: Array<{ text: string; link: string; - variant: 'primary' | 'secondary' | 'minimal'; - icon: string; + variant?: 'primary' | 'secondary' | 'minimal'; + icon?: string; attrs?: Record<string, string | number | boolean>; }>; } diff --git a/packages/starlight/components.ts b/packages/starlight/components.ts index 2935e9ff..67bf6b47 100644 --- a/packages/starlight/components.ts +++ b/packages/starlight/components.ts @@ -8,4 +8,5 @@ export { default as TabItem } from './user-components/TabItem.astro'; export { default as LinkCard } from './user-components/LinkCard.astro'; export { default as Steps } from './user-components/Steps.astro'; export { default as FileTree } from './user-components/FileTree.astro'; +export { default as LinkButton } from './user-components/LinkButton.astro'; export { Code } from 'astro-expressive-code/components'; diff --git a/packages/starlight/components/CallToAction.astro b/packages/starlight/components/CallToAction.astro deleted file mode 100644 index 551c64ea..00000000 --- a/packages/starlight/components/CallToAction.astro +++ /dev/null @@ -1,51 +0,0 @@ ---- -import type { HTMLAttributes } from 'astro/types'; -import Icon from '../user-components/Icon.astro'; -import type { Icons } from './Icons'; - -interface Props { - variant: 'primary' | 'secondary' | 'minimal'; - link: string; - icon?: undefined | { type: 'icon'; name: keyof typeof Icons } | { type: 'raw'; html: string }; - attrs?: Omit<HTMLAttributes<'a'>, 'href'> | undefined; -} - -const { link, variant, icon } = Astro.props; -const { class: customClass, ...attrs } = Astro.props.attrs || {}; ---- - -<a class:list={['sl-flex action', variant, customClass]} href={link} {...attrs}> - <slot /> - {icon?.type === 'icon' && <Icon name={icon.name} size="1.5rem" />} - {icon?.type === 'raw' && <Fragment set:html={icon.html} />} -</a> - -<style> - .action { - gap: 0.5em; - align-items: center; - border-radius: 999rem; - padding: 0.5rem 1.125rem; - color: var(--sl-color-white); - line-height: 1.1875; - text-decoration: none; - font-size: var(--sl-text-sm); - } - .action.primary { - background: var(--sl-color-text-accent); - color: var(--sl-color-black); - } - .action.secondary { - border: 1px solid; - } - .action.minimal { - padding-inline: 0; - } - - @media (min-width: 50rem) { - .action { - font-size: var(--sl-text-base); - padding: 1rem 1.25rem; - } - } -</style> diff --git a/packages/starlight/components/Hero.astro b/packages/starlight/components/Hero.astro index f763ce22..51be009a 100644 --- a/packages/starlight/components/Hero.astro +++ b/packages/starlight/components/Hero.astro @@ -2,7 +2,7 @@ import { Image } from 'astro:assets'; import { PAGE_TITLE_ID } from '../constants'; import type { Props } from '../props'; -import CallToAction from './CallToAction.astro'; +import LinkButton from '../user-components/LinkButton.astro'; const { data } = Astro.props.entry; const { title = data.title, tagline, image, actions = [] } = data.hero || {}; @@ -50,8 +50,11 @@ if (image) { { actions.length > 0 && ( <div class="sl-flex actions"> - {actions.map(({ text, ...attrs }) => ( - <CallToAction {...attrs} set:html={text} /> + {actions.map(({ attrs, icon, link: href, text, variant }) => ( + <LinkButton {href} {variant} icon={icon?.name} {...attrs}> + {text} + {icon?.html && <Fragment set:html={icon.html} />} + </LinkButton> ))} </div> ) diff --git a/packages/starlight/package.json b/packages/starlight/package.json index 1efba7a4..d331676a 100644 --- a/packages/starlight/package.json +++ b/packages/starlight/package.json @@ -47,10 +47,6 @@ "types": "./components/Sidebar.astro.tsx", "import": "./components/Sidebar.astro" }, - "./components/CallToAction.astro": { - "types": "./components/CallToAction.astro.tsx", - "import": "./components/CallToAction.astro" - }, "./components/MarkdownContent.astro": { "types": "./components/MarkdownContent.astro.tsx", "import": "./components/MarkdownContent.astro" diff --git a/packages/starlight/schemas/hero.ts b/packages/starlight/schemas/hero.ts index 0c335124..6ecc50df 100644 --- a/packages/starlight/schemas/hero.ts +++ b/packages/starlight/schemas/hero.ts @@ -49,8 +49,8 @@ export const HeroSchema = ({ image }: SchemaContext) => text: z.string(), /** Value for the link’s `href` attribute, e.g. `/page` or `https://mysite.com`. */ link: z.string(), - /** Button style to use. One of `primary`, `secondary`, or `minimal` (the default). */ - variant: z.enum(['primary', 'secondary', 'minimal']).default('minimal'), + /** Button style to use. One of `primary` (the default), `secondary`, or `minimal`. */ + variant: z.enum(['primary', 'secondary', 'minimal']).default('primary'), /** * An optional icon to display alongside the link text. * Can be an inline `<svg>` or the name of one of Starlight’s built-in icons. diff --git a/packages/starlight/user-components/LinkButton.astro b/packages/starlight/user-components/LinkButton.astro new file mode 100644 index 00000000..3bf68f07 --- /dev/null +++ b/packages/starlight/user-components/LinkButton.astro @@ -0,0 +1,76 @@ +--- +import type { HTMLAttributes } from 'astro/types'; +import { Icons } from '../components/Icons'; +import Icon from './Icon.astro'; + +interface Props extends Omit<HTMLAttributes<'a'>, 'href'> { + href: string | URL; + icon?: keyof typeof Icons | undefined; + iconPlacement?: 'start' | 'end' | undefined; + variant?: 'primary' | 'secondary' | 'minimal'; +} + +const { + class: className, + icon, + iconPlacement = 'end', + variant = 'primary', + ...attrs +} = Astro.props; +--- + +<a class:list={['sl-link-button not-content', variant, className]} {...attrs}> + {icon && iconPlacement === 'start' && <Icon name={icon} size="1.5rem" />} + <slot /> + {icon && iconPlacement === 'end' && <Icon name={icon} size="1.5rem" />} +</a> + +<style> + .sl-link-button { + align-items: center; + border: 1px solid transparent; + border-radius: 999rem; + display: inline-flex; + font-size: var(--sl-text-sm); + gap: 0.5em; + line-height: 1.1875; + outline-offset: 0.25rem; + padding: 0.4375rem 1.125rem; + text-decoration: none; + } + + .sl-link-button.primary { + background: var(--sl-color-text-accent); + border-color: var(--sl-color-text-accent); + color: var(--sl-color-black); + } + .sl-link-button.primary:hover { + color: var(--sl-color-black); + } + .sl-link-button.secondary { + border-color: inherit; + color: var(--sl-color-white); + } + .sl-link-button.minimal { + color: var(--sl-color-white); + padding-inline: 0; + } + + .sl-link-button :global(svg) { + flex-shrink: 0; + } + + @media (min-width: 50rem) { + .sl-link-button { + font-size: var(--sl-text-base); + padding: 0.9375rem 1.25rem; + } + } + + :global(.sl-markdown-content) .sl-link-button { + margin-inline-end: 1rem; + } + :global(.sl-markdown-content) .sl-link-button:not(:where(p *)) { + margin-block: 1rem; + } +</style> |