summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiDeoo2024-08-16 19:03:05 +0200
committerGitHub2024-08-16 19:03:05 +0200
commit68f56a7ffd314b760443a057db9ed1a982dbe191 (patch)
treeca1b14dd6d645e923044b5d25aac7c519c5d0cf7
parent9368494210dbcd80ada5b410340814fe36c4eb6c (diff)
downloadIT.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.md5
-rw-r--r--.changeset/thirty-students-sit.md16
-rw-r--r--docs/src/content/docs/guides/components.mdx32
-rw-r--r--docs/src/content/docs/index.mdx5
-rw-r--r--docs/src/content/docs/reference/frontmatter.md6
-rw-r--r--packages/starlight/components.ts1
-rw-r--r--packages/starlight/components/CallToAction.astro51
-rw-r--r--packages/starlight/components/Hero.astro9
-rw-r--r--packages/starlight/package.json4
-rw-r--r--packages/starlight/schemas/hero.ts4
-rw-r--r--packages/starlight/user-components/LinkButton.astro76
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>