From a136c85e6b2b0445e48184595b2696994621c8f1 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 24 Jun 2021 17:48:24 -0500 Subject: [PATCH] New Props API (#515) * wip: update props api * feat(#139, #309): enable new props api * chore: migrate examples to new props API * docs: update syntax guide for new props API * chore: update examples to new props API * chore: update docs to new Props API * fix: hide __astroInternal from `Astro.props` consumers * chore: remove scratchpad file * chore: fix script error * test: fix failing collection tests * fix: set __astroInternal to `enumerable: false` * chore: add changeset * feat: warn users using old props api --- .changeset/rich-starfishes-begin.md | 63 +++++++++++++++++++ docs-www/src/components/Note.astro | 7 ++- docs-www/src/layouts/Main.astro | 2 +- docs/api.md | 2 +- docs/collections.md | 10 +-- docs/markdown.md | 2 +- docs/styling.md | 2 +- docs/syntax.md | 23 +++++-- .../astro-markdown/src/layouts/main.astro | 1 - examples/blog/src/components/MainHead.astro | 19 +++--- examples/blog/src/components/Nav.astro | 7 ++- examples/blog/src/components/Pagination.astro | 8 ++- .../blog/src/components/PostPreview.astro | 7 ++- examples/blog/src/layouts/post.astro | 5 +- examples/blog/src/pages/$author.astro | 3 +- examples/blog/src/pages/$posts.astro | 2 +- examples/docs/src/components/Note.astro | 7 ++- examples/docs/src/layouts/Main.astro | 2 +- .../portfolio/src/components/MainHead.astro | 2 +- examples/portfolio/src/layouts/project.astro | 2 +- examples/portfolio/src/pages/$projects.astro | 2 +- .../snowpack/src/components/BaseHead.astro | 9 ++- examples/snowpack/src/components/Button.astro | 2 +- examples/snowpack/src/components/Nav.astro | 5 +- .../src/components/PokemonLookup.astro | 5 +- examples/snowpack/src/components/Subnav.astro | 9 ++- .../src/layouts/content-with-cover.astro | 2 +- examples/snowpack/src/layouts/content.astro | 2 +- examples/snowpack/src/layouts/post.astro | 2 +- packages/astro/components/Markdown.astro | 3 +- packages/astro/components/Prism.astro | 5 +- packages/astro/src/@types/astro.ts | 1 + packages/astro/src/compiler/codegen/index.ts | 56 +++++++++-------- packages/astro/src/compiler/index.ts | 24 ++++--- packages/astro/src/runtime.ts | 2 +- .../astro-basic/src/layouts/base.astro | 4 +- .../astro-collection/src/pages/$grouped.astro | 4 +- .../src/pages/$individual.astro | 4 +- .../astro-collection/src/pages/$nested.astro | 2 +- .../src/pages/$paginated.astro | 2 +- .../astro-collection/src/pages/$remote.astro | 2 +- .../astro-collection/src/pages/$shallow.astro | 2 +- .../astro-global/src/layouts/post.astro | 2 +- .../astro-global/src/pages/$posts.astro | 2 +- .../astro-markdown/src/pages/code.astro | 4 +- .../astro-markdown/src/pages/complex.astro | 4 +- .../astro-markdown/src/pages/deep.astro | 4 +- .../astro-markdown/src/pages/post.astro | 4 +- .../astro-rss/src/pages/$episodes.astro | 2 +- www/src/components/Author.astro | 6 +- www/src/components/BaseHead.astro | 9 ++- www/src/components/BlockQuote.astro | 9 ++- www/src/components/BlogPost.astro | 12 ++-- www/src/components/BlogPostPreview.astro | 10 ++- www/src/components/Note.astro | 7 ++- www/src/components/Shell.astro | 5 +- www/src/layouts/Blog.astro | 2 +- 57 files changed, 275 insertions(+), 132 deletions(-) create mode 100644 .changeset/rich-starfishes-begin.md diff --git a/.changeset/rich-starfishes-begin.md b/.changeset/rich-starfishes-begin.md new file mode 100644 index 000000000..ad9edb09a --- /dev/null +++ b/.changeset/rich-starfishes-begin.md @@ -0,0 +1,63 @@ +--- +'astro': minor +--- + +**This is a breaking change!** + +Astro props are now accessed from the `Astro.props` global. This change is meant to make prop definitions more ergonomic, leaning into JavaScript patterns you already know (destructuring and defaults). Astro components previously used a prop syntax borrowed from [Svelte](https://svelte.dev/docs#1_export_creates_a_component_prop), but it became clear that this was pretty confusing for most users. + + +```diff + --- ++ const { text = 'Hello world!' } = Astro.props; +- export let text = 'Hello world!'; + --- + +
{text}
+``` + +[Read more about the `.astro` syntax](https://github.com/snowpackjs/astro/blob/main/docs/syntax.md#data-and-props) + +--- + +### How do I define what props my component accepts? + +Astro frontmatter scripts are TypeScript! Because of this, we can leverage TypeScript types to define the shape of your props. + +```ts +--- +export interface Props { + text?: string; +} +const { text = 'Hello world!' } = Astro.props as Props; +--- +``` + +> **Note** Casting `Astro.props as Props` is a temporary workaround. We expect our Language Server to handle this automatically soon! + +### How do I access props I haven't explicitly defined? + +One of the great things about this change is that it's straight-forward to access _any_ props. Just use `...props`! + +```ts +--- +export interface Props { + text?: string; + [attr: string]: unknown; +} +const { text = 'Hello world!', ...props } = Astro.props as Props; +--- +``` + +### What about prop validation? + +We considered building prop validation into Astro, but decided to leave that implementation up to you! This way, you can use any set of tools you like. + +```ts +--- +const { text = 'Hello world!' } = Astro.props; + +if (typeof text !== 'string') throw new Error(`Expected "text" to be of type "string" but recieved "${typeof string}"!`); +--- +``` + diff --git a/docs-www/src/components/Note.astro b/docs-www/src/components/Note.astro index 46940ddf8..c57ede3a0 100644 --- a/docs-www/src/components/Note.astro +++ b/docs-www/src/components/Note.astro @@ -1,6 +1,9 @@ --- -export let type = "tip"; -export let title; +export interface Props { + title: string; + type?: 'tip' | 'warning' | 'error' +} +const { type = 'tip', title } = Astro.props; ---