@recipe-book/react 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -12,44 +12,111 @@ type NotAnImageComponent = 'Recipe.Image: as must be a component whose src and a
12
12
  /** `C` when its `src` and `alt` props take a string, else `NotAnImageComponent`. */
13
13
  type ImageComponent<C extends ElementType> = 'src' | 'alt' extends keyof ComponentPropsWithoutRef<C> ? ImageAttributes extends Pick<ComponentPropsWithoutRef<C>, 'src' | 'alt'> ? C : NotAnImageComponent : NotAnImageComponent;
14
14
  /**
15
- * The props of `as`, an `<img>` by default, with `src` and `alt` optional.
16
- * `RecipeImageProps<typeof NextImage>` types a wrapper around `next/image`.
15
+ * The props of `<Recipe.Image>`: those of `C` without its `ref`, with `src`
16
+ * and `alt` optional, plus `as`. `C` defaults to `'img'`. Use it to type a
17
+ * wrapper that takes what `<Recipe.Image as={C}>` takes.
18
+ *
19
+ * @example
20
+ * import NextImage from 'next/image'
21
+ *
22
+ * function Hero(props: Recipe.RecipeImageProps<typeof NextImage>) {
23
+ * return <Recipe.Image {...props} as={NextImage} className="hero" />
24
+ * }
25
+ *
26
+ * @see https://recipe-book.siraj.page/reference/react/image/#type-a-wrapper
17
27
  */
18
28
  type RecipeImageProps<C extends ElementType = 'img'> = {
19
29
  /**
20
- * The component to render instead of `<img>`, such as `next/image`. It gets
21
- * `src`, `alt`, `data-recipe-image` and the ref, and `Recipe.Image` takes
22
- * its props. Its `src` and `alt` must take strings, and its other required
23
- * props are required on `Recipe.Image`. From a Server Component, pass a
24
- * Client Component: one whose module starts with `'use client'`, as
30
+ * The component to render instead of `<img>`, such as `next/image`. It
31
+ * gets `src`, `alt`, `data-recipe-image` and the ref, and `Recipe.Image`
32
+ * takes its props. Its `src` and `alt` must take strings, and its other
33
+ * required props are required on `Recipe.Image`. From a Server Component,
34
+ * pass a Client Component: one whose module starts with `'use client'`, as
25
35
  * `next/image`'s does.
36
+ *
37
+ * @defaultValue `'img'`
38
+ *
39
+ * @see https://recipe-book.siraj.page/reference/react/image/#render-another-component
26
40
  */
27
41
  as?: ImageComponent<C> | undefined;
28
42
  } & Omit<ComponentPropsWithoutRef<C>, 'as' | 'src' | 'alt'> & {
29
- /** Replaces the recipe's `image`, such as with a CDN URL; nothing renders when the recipe has none. */
43
+ /**
44
+ * Replaces the recipe's `image`, such as with a CDN URL. Nothing renders
45
+ * when the recipe has no `image`, even with `src`. With `as`, it takes
46
+ * that component's `src` type, such as `string | StaticImport` for
47
+ * `next/image`.
48
+ *
49
+ * @defaultValue The recipe's `image`.
50
+ *
51
+ * @see https://recipe-book.siraj.page/reference/react/image/#image
52
+ */
30
53
  src?: (ComponentPropsWithoutRef<C> extends {
31
54
  src?: infer S;
32
55
  } ? S : never) | undefined;
33
- /** The alt text. Defaults to the recipe's `name`; pass `''` for a decorative image. */
56
+ /**
57
+ * The alt text. Pass `''` for a decorative image.
58
+ *
59
+ * @defaultValue The recipe's `name`.
60
+ *
61
+ * @see https://recipe-book.siraj.page/reference/react/image/#decorative-images
62
+ */
34
63
  alt?: string | undefined;
35
64
  };
36
65
  /**
37
66
  * The recipe's image, as an `<img>` or the component passed to `as`, or
38
67
  * nothing when the recipe has none. `src` defaults to the recipe's image and
39
- * `alt` to its name; pass `alt=""` when the image is decorative.
68
+ * `alt` to its name; pass `alt=""` when the image is decorative. Other props
69
+ * pass through, and it always sets `data-recipe-image`.
70
+ *
71
+ * `Recipe.Image` takes `as`, not `asChild`, so a component such as
72
+ * `next/image` gets `src` and `alt` from the recipe and still has its
73
+ * required props checked.
74
+ *
75
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
76
+ *
77
+ * @example
78
+ * import NextImage from 'next/image'
79
+ *
80
+ * function RecipeHero() {
81
+ * return <Recipe.Image as={NextImage} width={1200} height={800} />
82
+ * }
83
+ *
84
+ * @see https://recipe-book.siraj.page/reference/react/image/
40
85
  */
41
86
  declare const Image: <C extends ElementType = "img">(props: RecipeImageProps<C> & {
42
- /** Set to the `<img>`, or passed to the `as` component. Left unset when the recipe has no image. */
87
+ /**
88
+ * Set to the `<img>`, or passed to the `as` component. Left unset when the recipe has no image.
89
+ *
90
+ * @see https://recipe-book.siraj.page/reference/react/image/#image
91
+ */
43
92
  ref?: Ref<ComponentRef<C>> | undefined;
44
93
  }) => ReactNode;
45
94
 
46
- /** What `useRecipeState()` takes. The state props of `<Recipe.Root>` are the same. */
95
+ /**
96
+ * What `useRecipeState()` takes. The state props of `<Recipe.Root>` are the
97
+ * same.
98
+ *
99
+ * @see https://recipe-book.siraj.page/reference/react/hooks/#recipestateoptions
100
+ */
47
101
  type RecipeStateOptions = {
48
- /** A parsed recipe, as returned by `parseRecipe` in `@recipe-book/core`. */
102
+ /** A parsed recipe, as returned by `parseRecipe` in `@recipe-book/react/core`. */
49
103
  recipe: Recipe;
50
- /** The number of servings to show. Passing it makes servings controlled. */
104
+ /**
105
+ * The number of servings to show. Passing it makes servings controlled. A
106
+ * number outside the servings window shows `defaultServings` instead, with a
107
+ * warning in development.
108
+ *
109
+ * @see https://recipe-book.siraj.page/reference/react/root/#controlled-and-uncontrolled-state
110
+ */
51
111
  servings?: number | undefined;
52
- /** Starting servings when uncontrolled; defaults to the recipe's servings, then its yield, then 1. */
112
+ /**
113
+ * Starting servings when uncontrolled. A number outside the servings window
114
+ * falls back to the scaling base, with a warning in development.
115
+ *
116
+ * @defaultValue The recipe's scaling base: its servings, then its yield,
117
+ * then 1.
118
+ * @see https://recipe-book.siraj.page/reference/react/root/#scaling-base
119
+ */
53
120
  defaultServings?: number | undefined;
54
121
  /**
55
122
  * Called when `setServings` accepts a number other than the current one,
@@ -81,7 +148,12 @@ type StepItem = Step$1 & {
81
148
  /** The step's position, counted from 1 across sections. */
82
149
  number: number;
83
150
  };
84
- /** A section of a recipe's ingredients or steps. Untitled sections have no `title`. */
151
+ /**
152
+ * A section of a recipe's ingredients or steps. Untitled sections have no
153
+ * `title`.
154
+ *
155
+ * @see https://recipe-book.siraj.page/reference/react/hooks/#recipesection
156
+ */
85
157
  type RecipeSection<T> = {
86
158
  /** The section's id from the recipe. */
87
159
  id: string;
@@ -90,7 +162,11 @@ type RecipeSection<T> = {
90
162
  /** The ingredients or steps in the section. */
91
163
  items: T[];
92
164
  };
93
- /** What `useRecipe()` and `useRecipeState()` return. */
165
+ /**
166
+ * What `useRecipe()` and `useRecipeState()` return.
167
+ *
168
+ * @see https://recipe-book.siraj.page/reference/react/hooks/#recipestate
169
+ */
94
170
  type RecipeState = {
95
171
  /** The parsed recipe. */
96
172
  recipe: Recipe;
@@ -98,9 +174,13 @@ type RecipeState = {
98
174
  servings: number;
99
175
  /**
100
176
  * Calls `onServingsChange` with a number other than the current one, and
101
- * changes the servings unless controlled; ignores one outside a millionth to
102
- * a million times the scaling base. While a controlled `servings` is outside
103
- * that range, passing the number shown calls `onServingsChange` too.
177
+ * changes the servings unless controlled. Ignores a number outside the
178
+ * servings window, from a millionth to a million times the scaling base
179
+ * including both ends, and warns about it in development. While a
180
+ * controlled `servings` is outside that window, passing the number shown
181
+ * calls `onServingsChange` too.
182
+ *
183
+ * @see https://recipe-book.siraj.page/reference/react/root/#servings-window
104
184
  */
105
185
  setServings: (servings: number) => void;
106
186
  /** From `resolveRecipe`: `servings` divided by the recipe's servings amount, else its yield amount, else 1. */
@@ -136,23 +216,61 @@ type RecipeState = {
136
216
  *
137
217
  * @throws {RecipeBookError} `invalid_argument` in development when `recipe`
138
218
  * isn't a parsed recipe.
219
+ *
220
+ * @param options - The recipe and its state.
221
+ * @returns The recipe, its servings and display system with their setters,
222
+ * its ingredients at those settings, and its numbered steps.
223
+ *
224
+ * @example
225
+ * import type { Recipe as ParsedRecipe } from '@recipe-book/react/core'
226
+ * import * as Recipe from '@recipe-book/react'
227
+ *
228
+ * function ServingsSummary({ recipe }: { recipe: ParsedRecipe }) {
229
+ * const { servings, scale } = Recipe.useRecipeState({
230
+ * recipe,
231
+ * defaultServings: 8,
232
+ * })
233
+ * return <p>{`Serves ${servings}, scaled ×${scale}`}</p>
234
+ * }
235
+ *
236
+ * @see https://recipe-book.siraj.page/reference/react/hooks/#userecipestate
139
237
  */
140
238
  declare function useRecipeState(options: RecipeStateOptions): RecipeState;
141
239
 
142
- /** Levels a section heading can take; level 1 belongs to the page. */
240
+ /**
241
+ * The heading levels `<Recipe.Ingredients>` and `<Recipe.Steps>` take as
242
+ * `headingLevel` for section titles; level 1 belongs to the page's title.
243
+ * Both default to 3, for sections under an `<h2>` such as "Ingredients". Pass
244
+ * the level below your own heading to keep the outline in order.
245
+ *
246
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#recipeheadinglevel
247
+ */
143
248
  type RecipeHeadingLevel = 2 | 3 | 4 | 5 | 6;
144
249
 
145
- /** Attributes for the wrapping `<div>`, plus `headingLevel`; `children` renders each section. */
146
- type RecipeIngredientsProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'> & {
250
+ /**
251
+ * Attributes for the wrapping `<div>` other than `dangerouslySetInnerHTML`,
252
+ * plus `headingLevel`; `children` renders each section.
253
+ *
254
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredients
255
+ */
256
+ type RecipeIngredientsProps = Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'dangerouslySetInnerHTML'> & {
147
257
  /**
148
258
  * Heading level of section titles in the default rendering. Defaults to 3,
149
259
  * for ingredients under an `<h2>` such as "Ingredients".
260
+ *
261
+ * @defaultValue `3`
262
+ * @see https://recipe-book.siraj.page/guides/make-a-recipe-accessible/#set-heading-levels
150
263
  */
151
264
  headingLevel?: RecipeHeadingLevel | undefined;
152
265
  /**
153
266
  * Renders each section instead of the default. Each result is keyed for
154
267
  * you, so return one element or a fragment; an array's items need their own
155
268
  * keys, as anywhere in React.
269
+ *
270
+ * @defaultValue A `<section>` named by the section's heading, or a `<div>`
271
+ * for an untitled section, around a `<Recipe.IngredientList>` of its
272
+ * ingredients.
273
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#render-your-own-sections
156
274
  */
157
275
  children?: ((section: RecipeSection<IngredientItem>) => ReactNode) | undefined;
158
276
  };
@@ -160,23 +278,68 @@ type RecipeIngredientsProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'>
160
278
  * The recipe's ingredients at the current servings and display system, one
161
279
  * block per section. A titled section renders as a `<section>` named by its
162
280
  * heading, then a `<Recipe.IngredientList>`.
281
+ *
282
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
283
+ * @throws {RecipeBookError} `invalid_argument` from the `<Recipe.Ingredient>`
284
+ * it renders for each item by default, when Root's `locale` isn't a language
285
+ * tag that `Intl` accepts, such as `'en_US'`.
286
+ *
287
+ * @example
288
+ * <Recipe.Root recipe={recipe}>
289
+ * <h2>Ingredients</h2>
290
+ * <Recipe.Ingredients />
291
+ * </Recipe.Root>
292
+ *
293
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredients
163
294
  */
164
295
  declare const Ingredients: ForwardRefExoticComponent<RecipeIngredientsProps & RefAttributes<HTMLDivElement>>;
165
- /** Attributes for the `<ul>`, plus the `section` to list; `children` renders each ingredient. */
166
- type RecipeIngredientListProps = Omit<ComponentPropsWithoutRef<'ul'>, 'children'> & {
296
+ /**
297
+ * Attributes for the `<ul>` other than `dangerouslySetInnerHTML`, plus the
298
+ * `section` to list; `children` renders each ingredient.
299
+ *
300
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredientlist
301
+ */
302
+ type RecipeIngredientListProps = Omit<ComponentPropsWithoutRef<'ul'>, 'children' | 'dangerouslySetInnerHTML'> & {
167
303
  /** The section to list. Defaults to every ingredient in the recipe. */
168
304
  section?: RecipeSection<IngredientItem> | undefined;
169
305
  /**
170
306
  * Renders each ingredient instead of `<Recipe.Ingredient>`. Each result is
171
307
  * keyed for you, so return one element or a fragment; an array's items need
172
308
  * their own keys, as anywhere in React.
309
+ *
310
+ * @defaultValue `(item) => <Recipe.Ingredient item={item} />`
311
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#render-your-own-ingredients
173
312
  */
174
313
  children?: ((item: IngredientItem) => ReactNode) | undefined;
175
314
  };
176
- /** An unordered list of ingredients. */
315
+ /**
316
+ * An unordered list of ingredients, one `<Recipe.Ingredient>` each unless
317
+ * `children` renders them.
318
+ *
319
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
320
+ * @throws {RecipeBookError} `invalid_argument` from the `<Recipe.Ingredient>`
321
+ * it renders for each item by default, when Root's `locale` isn't a language
322
+ * tag that `Intl` accepts, such as `'en_US'`.
323
+ *
324
+ * @example
325
+ * <Recipe.IngredientList>
326
+ * {(item) => (
327
+ * <Recipe.Ingredient item={item}>
328
+ * <Recipe.IngredientName /> <Recipe.IngredientQuantity />
329
+ * </Recipe.Ingredient>
330
+ * )}
331
+ * </Recipe.IngredientList>
332
+ *
333
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredientlist
334
+ */
177
335
  declare const IngredientList: ForwardRefExoticComponent<RecipeIngredientListProps & RefAttributes<HTMLUListElement>>;
178
- /** Attributes for the `<li>`, plus the `item` to render and `asChild`. */
179
- type RecipeIngredientProps = ComponentPropsWithoutRef<'li'> & {
336
+ /**
337
+ * Attributes for the `<li>` other than `dangerouslySetInnerHTML`, plus the
338
+ * `item` to render and `asChild`.
339
+ *
340
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredient
341
+ */
342
+ type RecipeIngredientProps = Omit<ComponentPropsWithoutRef<'li'>, 'dangerouslySetInnerHTML'> & {
180
343
  /** The ingredient to render, such as one that `<Recipe.IngredientList>` passes to its `children`. */
181
344
  item: IngredientItem;
182
345
  /**
@@ -187,6 +350,9 @@ type RecipeIngredientProps = ComponentPropsWithoutRef<'li'> & {
187
350
  * are set. The child's own children replace the line's, so an empty child
188
351
  * gets the default line. With anything but one element child, it renders
189
352
  * its own `<li>`, with a warning in development.
353
+ *
354
+ * @defaultValue `false`
355
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#render-your-own-element
190
356
  */
191
357
  asChild?: boolean | undefined;
192
358
  };
@@ -202,16 +368,27 @@ type RecipeIngredientProps = ComponentPropsWithoutRef<'li'> & {
202
368
  * or `converted` into the display system. Unquantified lines have
203
369
  * `data-unquantified` instead. Optional ingredients have `data-optional`.
204
370
  *
371
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
372
+ * @throws {RecipeBookError} `invalid_argument` when Root's `locale` isn't a
373
+ * language tag that `Intl` accepts, such as `'en_US'`; when `item` isn't
374
+ * `{ ingredient, quantity? }`, such as an authored ingredient; or when an
375
+ * `item` you build has an amount that isn't a finite number greater than 0
376
+ * or a range of them, or a range whose `min` isn't less than its `max`.
377
+ * @throws {RecipeBookError} `unknown_unit` when the item's unit isn't a unit
378
+ * ID.
379
+ *
205
380
  * @example
206
381
  * <Recipe.Ingredient item={item} className="flex gap-2">
207
382
  * <Recipe.IngredientQuantity className="w-24 tabular-nums" />
208
383
  * <Recipe.IngredientName />
209
384
  * <Recipe.IngredientNote className="text-stone-500" />
210
385
  * </Recipe.Ingredient>
386
+ *
387
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredient
211
388
  */
212
389
  declare const Ingredient: ForwardRefExoticComponent<RecipeIngredientProps & RefAttributes<HTMLLIElement>>;
213
390
  /** Attributes for an ingredient sub-part's `<span>`, plus `asChild`; `children` go before its text. */
214
- type IngredientTextProps = ComponentPropsWithoutRef<'span'> & {
391
+ type IngredientTextProps = Omit<ComponentPropsWithoutRef<'span'>, 'dangerouslySetInnerHTML'> & {
215
392
  /**
216
393
  * Renders as its one element child, such as `<a href={url} />`, instead of a
217
394
  * `<span>`, with the text after the child's own children. A prop on the
@@ -233,6 +410,10 @@ type RecipeIngredientQuantityProps = IngredientTextProps;
233
410
  * <Recipe.IngredientQuantity>
234
411
  * {item.origin === 'converted' && '≈ '}
235
412
  * </Recipe.IngredientQuantity>
413
+ *
414
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Ingredient>`.
415
+ *
416
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredientquantity
236
417
  */
237
418
  declare const IngredientQuantity: ForwardRefExoticComponent<RecipeIngredientQuantityProps & RefAttributes<HTMLSpanElement>>;
238
419
  /** Attributes for the `<span>`, plus `asChild`; `children` go before the name. */
@@ -246,6 +427,10 @@ type RecipeIngredientNameProps = IngredientTextProps;
246
427
  * <Recipe.IngredientName asChild>
247
428
  * <a href={`/glossary/${item.id}`} />
248
429
  * </Recipe.IngredientName>
430
+ *
431
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Ingredient>`.
432
+ *
433
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredientname
249
434
  */
250
435
  declare const IngredientName: ForwardRefExoticComponent<RecipeIngredientNameProps & RefAttributes<HTMLSpanElement>>;
251
436
  /** Attributes for the `<span>`, plus `asChild`; `children` go before the note. */
@@ -256,6 +441,10 @@ type RecipeIngredientNoteProps = IngredientTextProps;
256
441
  *
257
442
  * @example
258
443
  * <Recipe.IngredientNote className="text-stone-500" />
444
+ *
445
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Ingredient>`.
446
+ *
447
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredientnote
259
448
  */
260
449
  declare const IngredientNote: ForwardRefExoticComponent<RecipeIngredientNoteProps & RefAttributes<HTMLSpanElement>>;
261
450
  /** Attributes for the `<span>`, plus `asChild`; `children` go before the label. */
@@ -267,28 +456,95 @@ type RecipeIngredientOptionalProps = IngredientTextProps;
267
456
  *
268
457
  * @example
269
458
  * <Recipe.IngredientOptional className="text-stone-500" />
459
+ *
460
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Ingredient>`.
461
+ *
462
+ * @see https://recipe-book.siraj.page/reference/react/ingredients/#ingredientoptional
270
463
  */
271
464
  declare const IngredientOptional: ForwardRefExoticComponent<RecipeIngredientOptionalProps & RefAttributes<HTMLSpanElement>>;
272
465
 
273
- /** Attributes for the `<script>` but `type`, `src` and content, plus `toJsonLd`'s options. */
274
- type RecipeJsonLdProps = Pick<ToJsonLdOptions, 'servings' | 'system' | 'url' | 'extra'> & Omit<ComponentPropsWithoutRef<'script'>, 'type' | 'children' | 'dangerouslySetInnerHTML' | 'src'>;
466
+ /**
467
+ * The props of `<Recipe.JsonLd>`: `toJsonLd`'s `servings`, `system`, `url`
468
+ * and `extra`, passed to it as they are, plus the `<script>`'s attributes but
469
+ * `type`, `src` and its content, which `<Recipe.JsonLd>` sets.
470
+ *
471
+ * @see https://recipe-book.siraj.page/reference/react/json-ld/#jsonld
472
+ */
473
+ type RecipeJsonLdProps = {
474
+ /**
475
+ * Writes the recipe at this many servings, as `resolveRecipe` scales it.
476
+ * The Root's servings don't change it.
477
+ *
478
+ * @defaultValue The recipe's own servings, unscaled.
479
+ *
480
+ * @see https://recipe-book.siraj.page/reference/react/json-ld/#jsonld
481
+ */
482
+ servings?: ToJsonLdOptions['servings'];
483
+ /**
484
+ * Writes quantities in this measurement system. The Root's system doesn't
485
+ * change it.
486
+ *
487
+ * @defaultValue `recipe.system`, then `'metric'`.
488
+ *
489
+ * @see https://recipe-book.siraj.page/reference/react/json-ld/#jsonld
490
+ */
491
+ system?: ToJsonLdOptions['system'];
492
+ /**
493
+ * The recipe page's URL. Each step gets it as `url`, with the step's id,
494
+ * percent-encoded, as the fragment; without it, steps have no `url`.
495
+ * `<Recipe.Step>` renders no `id`, so pass it the step's `id` for the
496
+ * fragment to point at it.
497
+ *
498
+ * @see https://recipe-book.siraj.page/reference/react/json-ld/#step-ids
499
+ */
500
+ url?: ToJsonLdOptions['url'];
501
+ /**
502
+ * schema.org fields the recipe doesn't model, such as `author`,
503
+ * `datePublished`, or `keywords`, written as you pass them. A field
504
+ * `toJsonLd` writes from the recipe wins; `@context` and `@type` are always
505
+ * its own. A field that is `undefined` is left out, so
506
+ * `{ image: maybeImage }` adds an image only when there is one, and an
507
+ * `image` here stops the missing-image warning. A field `toJsonLd` writes
508
+ * from a recipe takes the type `SchemaOrgRecipe` gives it here too, so an
509
+ * `image` is a URL. Pass the `extra` that `fromJsonLd` returned to write them
510
+ * back.
511
+ *
512
+ * @example
513
+ * <Recipe.JsonLd
514
+ * url="https://example.com/pancakes"
515
+ * extra={{ author: { '@type': 'Person', name: 'Ada Lovelace' } }}
516
+ * />
517
+ *
518
+ * @see https://recipe-book.siraj.page/reference/react/json-ld/#jsonld
519
+ */
520
+ extra?: ToJsonLdOptions['extra'];
521
+ } & Omit<ComponentPropsWithoutRef<'script'>, 'type' | 'children' | 'dangerouslySetInnerHTML' | 'src'>;
275
522
  /**
276
523
  * The recipe as schema.org Recipe JSON-LD, for search engines' recipe results,
277
524
  * in a `<script type="application/ld+json">` with `<` escaped as `\u003c`.
278
525
  * Writes the recipe as authored: at its own servings and in `recipe.system`,
279
526
  * else metric, unless `servings` or `system` say otherwise. Root's current
280
- * servings and system don't change it. The text is in English.
527
+ * servings and system don't change it. The text is in English. Other props
528
+ * pass to the `<script>`, and it always sets `data-recipe-json-ld`.
281
529
  *
282
530
  * In development, logs to the browser console the warnings that `toJsonLd`
283
531
  * returns, such as for a missing `image`, unless the previous render had the
284
- * same ones in the same order.
532
+ * same ones in the same order. Nothing logs where it renders only on the
533
+ * server, such as in an Astro page without a `client:` directive.
285
534
  *
286
535
  * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
287
536
  *
288
537
  * @example
289
- * <Recipe.Root recipe={recipe}>
290
- * <Recipe.JsonLd url="https://example.com/pancakes" />
291
- * </Recipe.Root>
538
+ * // app/pancakes/page.tsx, a Server Component: no 'use client' needed
539
+ * export default function Page() {
540
+ * return (
541
+ * <Recipe.Root recipe={recipe}>
542
+ * <Recipe.JsonLd url="https://example.com/pancakes" />
543
+ * </Recipe.Root>
544
+ * )
545
+ * }
546
+ *
547
+ * @see https://recipe-book.siraj.page/reference/react/json-ld/
292
548
  */
293
549
  declare const JsonLd: ForwardRefExoticComponent<RecipeJsonLdProps & RefAttributes<HTMLScriptElement>>;
294
550
 
@@ -299,80 +555,229 @@ declare const JsonLd: ForwardRefExoticComponent<RecipeJsonLdProps & RefAttribute
299
555
  * A new key is additive: labels that leave it out keep its English default,
300
556
  * and a label pack checked with `satisfies RecipeLabels` gets a compile error
301
557
  * naming the new key.
558
+ *
559
+ * @example
560
+ * const spanish = {
561
+ * servings: 'Raciones',
562
+ * servingUnit: { one: 'ración', other: 'raciones' },
563
+ * system: 'Sistema de medida',
564
+ * metric: 'Métrico',
565
+ * us: 'EE. UU.',
566
+ * fan: 'con ventilador',
567
+ * optional: '(opcional)',
568
+ * to: 'a',
569
+ * } satisfies Recipe.RecipeLabels
570
+ *
571
+ * <Recipe.RecipeBookProvider locale="es-ES" labels={spanish}>
572
+ * {children}
573
+ * </Recipe.RecipeBookProvider>
574
+ *
575
+ * @see https://recipe-book.siraj.page/reference/react/provider/
302
576
  */
303
577
  type RecipeLabels = {
304
- /** Accessible name of the servings controls. */
578
+ /**
579
+ * Accessible name of `<Recipe.ServingsSelect>` and `<Recipe.ServingsInput>`,
580
+ * unless they get an `aria-label` or `aria-labelledby`. Defaults to
581
+ * `'Servings'`.
582
+ *
583
+ * @see https://recipe-book.siraj.page/reference/react/provider/
584
+ */
305
585
  servings: string;
306
- /** Unit for the servings count: "1 serving", "4 servings". */
586
+ /**
587
+ * Unit for the servings count: "1 serving", "4 servings".
588
+ * `<Recipe.ServingsSelect>` words each option with it, for a recipe with
589
+ * `servings`. Defaults to `{ one: 'serving', other: 'servings' }`.
590
+ *
591
+ * @see https://recipe-book.siraj.page/reference/react/provider/
592
+ */
307
593
  servingUnit: {
308
594
  /** Follows 1 and a fraction below 1: "1 serving", "½ serving". */
309
595
  one: string;
310
596
  /** Follows decimals and any other number: "0.3 servings", "4 servings". */
311
597
  other: string;
312
598
  };
313
- /** Accessible name of the system toggle. */
599
+ /**
600
+ * Accessible name of `<Recipe.SystemToggle>`, unless it gets an
601
+ * `aria-label` or `aria-labelledby`. Defaults to `'Measurement system'`.
602
+ *
603
+ * @see https://recipe-book.siraj.page/reference/react/provider/
604
+ */
314
605
  system: string;
315
- /** Name of the metric system. */
606
+ /**
607
+ * Name of the metric system, shown by a `<Recipe.SystemOption>` for
608
+ * `'metric'` that has no children, or an empty `asChild` child. Defaults to
609
+ * `'Metric'`.
610
+ *
611
+ * @see https://recipe-book.siraj.page/reference/react/provider/
612
+ */
316
613
  metric: string;
317
- /** Name of the US system. */
614
+ /**
615
+ * Name of the US system, shown by a `<Recipe.SystemOption>` for `'us'` that
616
+ * has no children, or an empty `asChild` child. Defaults to `'US'`.
617
+ *
618
+ * @see https://recipe-book.siraj.page/reference/react/provider/
619
+ */
318
620
  us: string;
319
- /** Marker after a fan-oven temperature in step text: "160 °C fan". */
621
+ /**
622
+ * Marker after a fan-oven temperature in `<Recipe.StepText>`: "160 °C fan".
623
+ * An empty string leaves it out. Defaults to `'fan'`.
624
+ *
625
+ * @see https://recipe-book.siraj.page/reference/react/provider/
626
+ */
320
627
  fan: string;
321
- /** Marker after an optional ingredient, shown as is, punctuation included. */
628
+ /**
629
+ * Marker after an optional ingredient, shown as is, punctuation included.
630
+ * `<Recipe.IngredientOptional>` renders it, and the function from
631
+ * `useFormatIngredient()` returns it as `optional`. Defaults to
632
+ * `'(optional)'`.
633
+ *
634
+ * @see https://recipe-book.siraj.page/reference/react/provider/
635
+ */
322
636
  optional: string;
323
- /** Spoken between the ends of a range, "2 to 3 tbsp". Screen readers only. */
637
+ /**
638
+ * Spoken between the ends of a range, "2 to 3 tbsp". Screen readers only:
639
+ * `<Recipe.IngredientQuantity>` keeps the visible dash, "2–3 tbsp".
640
+ * Defaults to `'to'`.
641
+ *
642
+ * @see https://recipe-book.siraj.page/reference/react/provider/
643
+ */
324
644
  to: string;
325
645
  };
326
646
 
327
647
  /** The locale, labels, and starting system that `RecipeBookProvider` and `<Recipe.Root>` take. */
328
648
  type RecipeBookConfig = {
329
- /** BCP 47 locale for formatting numbers. Defaults to the outer provider's, then `'en-US'`. */
649
+ /**
650
+ * A language tag that `Intl` accepts, such as `'de-DE'`, for formatting
651
+ * numbers. With a tag it rejects, such as `'en_US'`, formatting a number
652
+ * throws `invalid_argument`.
653
+ *
654
+ * @defaultValue The outer provider's `locale`, then `'en-US'`.
655
+ *
656
+ * @see https://recipe-book.siraj.page/reference/react/provider/#recipebookprovider
657
+ * @see https://recipe-book.siraj.page/reference/react/root/#root
658
+ */
330
659
  locale?: string | undefined;
331
- /** Overrides for built-in text. Unset keys keep the outer value. */
660
+ /**
661
+ * Built-in text to override. A key you leave out keeps the outer provider's
662
+ * value, then its English default. Pass an object that keeps its identity
663
+ * between renders: an equal but new one re-renders most parts.
664
+ *
665
+ * @see https://recipe-book.siraj.page/reference/react/provider/
666
+ * @see https://recipe-book.siraj.page/reference/react/root/
667
+ */
332
668
  labels?: RecipeLabelOverrides | undefined;
333
- /** Initial display system. Defaults to the outer provider's, then the system each recipe was written in, then `'metric'`. */
669
+ /**
670
+ * The measurement system a Root starts in, unless its `system` is
671
+ * controlled. Defaults to the outer provider's, then the system its recipe
672
+ * was written in, then `'metric'`. A value other than `'metric'` or `'us'`
673
+ * counts as missing.
674
+ *
675
+ * @see https://recipe-book.siraj.page/reference/react/provider/#recipebookprovider
676
+ * @see https://recipe-book.siraj.page/reference/react/root/#root
677
+ */
334
678
  defaultSystem?: System | undefined;
335
679
  };
336
680
  /**
681
+ * Built-in text to override, for the `labels` prop of `RecipeBookProvider` and
682
+ * `<Recipe.Root>`.
683
+ *
337
684
  * Any keys of `RecipeLabels`. A value replaces the whole key, so `servingUnit`
338
685
  * needs both `one` and `other`.
686
+ *
687
+ * @example
688
+ * // At module scope, so it keeps its identity between renders.
689
+ * const labels = {
690
+ * servings: 'Portions',
691
+ * servingUnit: { one: 'portion', other: 'portions' },
692
+ * } satisfies Recipe.RecipeLabelOverrides
693
+ *
694
+ * <Recipe.Root recipe={recipe} labels={labels}>
695
+ * <Recipe.ServingsSelect />
696
+ * </Recipe.Root>
697
+ *
698
+ * @see https://recipe-book.siraj.page/reference/react/provider/#recipelabeloverrides
339
699
  */
340
700
  type RecipeLabelOverrides = {
341
701
  [Key in keyof RecipeLabels]?: RecipeLabels[Key] | undefined;
342
702
  };
343
- /** Defaults for every Root below it, plus `children`. */
703
+ /**
704
+ * Props of `RecipeBookProvider`: defaults for every Root below it, plus
705
+ * `children`.
706
+ *
707
+ * @example
708
+ * export function AppProvider(props: Recipe.RecipeBookProviderProps) {
709
+ * return <Recipe.RecipeBookProvider locale="en-GB" {...props} />
710
+ * }
711
+ *
712
+ * @see https://recipe-book.siraj.page/reference/react/provider/#recipebookprovider
713
+ */
344
714
  type RecipeBookProviderProps = RecipeBookConfig & {
345
- /** The part of the app that uses these defaults. */
715
+ /**
716
+ * The part of the app that uses these defaults.
717
+ *
718
+ * @see https://recipe-book.siraj.page/reference/react/provider/#recipebookprovider
719
+ */
346
720
  children?: ReactNode;
347
721
  };
348
722
  /**
349
723
  * App-wide defaults for every `<Recipe.Root>` below it. Takes only data, so it
350
724
  * can wrap a layout rendered as a Server Component. Nested providers override
351
725
  * the outer one key by key.
726
+ *
727
+ * @example
728
+ * // app/layout.tsx
729
+ * <Recipe.RecipeBookProvider defaultSystem="metric">
730
+ * {children}
731
+ * </Recipe.RecipeBookProvider>
732
+ *
733
+ * @see https://recipe-book.siraj.page/reference/react/provider/#recipebookprovider
352
734
  */
353
735
  declare function RecipeBookProvider({ children, ...config }: RecipeBookProviderProps): JSX.Element;
354
736
  /**
355
- * The state of the nearest `<Recipe.Root>`: the recipe, servings, and display
356
- * system, with their setters.
737
+ * The state of the nearest `<Recipe.Root>`: the recipe, servings, and
738
+ * measurement system, with their setters.
739
+ *
740
+ * @returns The Root's `RecipeState`: `recipe`, `servings`, `scale`, `system`,
741
+ * `canConvert`, `ingredients` and `steps` as the Root shows them, and the
742
+ * `setServings` and `setSystem` that change them.
357
743
  *
358
744
  * @throws {RecipeBookError} `missing_parent` outside a Root.
745
+ *
746
+ * @example
747
+ * function SystemSwitch() {
748
+ * const { system, setSystem, canConvert } = Recipe.useRecipe()
749
+ * if (!canConvert) return null
750
+ * return (
751
+ * <button onClick={() => setSystem(system === 'us' ? 'metric' : 'us')}>
752
+ * {system === 'us' ? 'Show metric' : 'Show US'}
753
+ * </button>
754
+ * )
755
+ * }
756
+ *
757
+ * @see https://recipe-book.siraj.page/reference/react/hooks/#userecipe
359
758
  */
360
759
  declare function useRecipe(): RecipeState;
361
760
 
362
761
  /**
363
- * A union: a parsed `recipe`, or raw data with `parse`. To wrap `Root`,
364
- * intersect (`RecipeRootProps & { … }`) or destructure it, rather than
365
- * `Omit<RecipeRootProps, …>`, which doesn't type-check against a union.
762
+ * The props of `<Recipe.Root>`, a union: a parsed `recipe`, or raw data with
763
+ * `parse`. To wrap `Root`, intersect (`RecipeRootProps & { … }`) or
764
+ * destructure it, rather than `Omit<RecipeRootProps, …>`, which doesn't
765
+ * type-check against a union.
766
+ *
767
+ * @see https://recipe-book.siraj.page/reference/react/root/#root
768
+ * @see https://recipe-book.siraj.page/reference/react/root/#wrap-root
366
769
  */
367
770
  type RecipeRootProps = RecipeBookConfig & Omit<RecipeStateOptions, 'recipe' | 'defaultSystem'> & {
368
771
  /** The parts and components that read the recipe's state. */
369
772
  children?: ReactNode;
370
773
  } & ({
371
774
  /**
372
- * A parsed recipe. Call `parseRecipe` from `@recipe-book/core` on the
373
- * server, in a loader, or at build time, and pass `result.data`.
775
+ * A parsed recipe. Call `parseRecipe` from `@recipe-book/react/core`
776
+ * on the server, in a loader, or at build time, and pass
777
+ * `result.data`.
374
778
  */
375
779
  recipe: Recipe;
780
+ /** Only with recipe data to parse. A parsed recipe takes no `parse`. */
376
781
  parse?: undefined;
377
782
  /** Only with `parse`. A parsed recipe always renders. */
378
783
  fallback?: undefined;
@@ -381,14 +786,19 @@ type RecipeRootProps = RecipeBookConfig & Omit<RecipeStateOptions, 'recipe' | 'd
381
786
  recipe: unknown;
382
787
  /**
383
788
  * Parses `recipe` in the browser. Pass `parseRecipe` from
384
- * `@recipe-book/core`; only apps that do download the parser.
789
+ * `@recipe-book/react/core`; only apps that do download the parser.
385
790
  *
386
791
  * A function, so it can only be passed from a Client Component. Pass a
387
792
  * stable function such as `parseRecipe` itself: an inline arrow
388
793
  * parses again on every render.
389
794
  */
390
795
  parse: (input: unknown) => ParseResult<Recipe>;
391
- /** Rendered instead of `children` when `parse` rejects `recipe`. */
796
+ /**
797
+ * Rendered instead of `children` when `parse` rejects `recipe`.
798
+ *
799
+ * @defaultValue `null`
800
+ * @see https://recipe-book.siraj.page/reference/react/root/#parse-in-the-browser
801
+ */
392
802
  fallback?: ReactNode;
393
803
  });
394
804
  /**
@@ -402,16 +812,37 @@ type RecipeRootProps = RecipeBookConfig & Omit<RecipeStateOptions, 'recipe' | 'd
402
812
  *
403
813
  * @throws {RecipeBookError} `invalid_argument` when `recipe` isn't a parsed
404
814
  * recipe and there is no `parse`.
815
+ *
816
+ * @example
817
+ * <Recipe.Root recipe={recipe} defaultServings={8}>
818
+ * <Recipe.Image />
819
+ * <Recipe.Ingredients />
820
+ * <Recipe.Steps />
821
+ * </Recipe.Root>
822
+ *
823
+ * @see https://recipe-book.siraj.page/reference/react/root/
405
824
  */
406
825
  declare function Root({ recipe, parse, fallback, children, ...options }: RecipeRootProps): JSX.Element;
407
826
 
408
- /** Attributes for the `<select>`, plus the `options` to offer. */
409
- type RecipeServingsSelectProps = Omit<ComponentPropsWithoutRef<'select'>, 'value' | 'defaultValue' | 'multiple' | 'children'> & {
827
+ /**
828
+ * The props of `<Recipe.ServingsSelect>`: the `<select>`'s attributes, plus
829
+ * the `options` to offer. It sets the value and the options itself, so it
830
+ * doesn't take `value`, `defaultValue`, `multiple`, `children` or
831
+ * `dangerouslySetInnerHTML`.
832
+ *
833
+ * @see https://recipe-book.siraj.page/reference/react/servings/#servingsselect
834
+ */
835
+ type RecipeServingsSelectProps = Omit<ComponentPropsWithoutRef<'select'>, 'value' | 'defaultValue' | 'multiple' | 'children' | 'dangerouslySetInnerHTML'> & {
410
836
  /**
411
- * Servings to offer, shown in ascending order. Defaults to ½×, 1×, 2×, and
412
- * 3× the servings the recipe scales from (its servings amount, else its
413
- * yield amount, else 1), each rounded to a whole number of at least 1.
414
- * Values the recipe can't be scaled to are left out.
837
+ * Servings to offer, shown in ascending order. A number outside the
838
+ * servings window is left out.
839
+ *
840
+ * @defaultValue ½×, 1×, 2×, and 3× the recipe's scaling base (its servings
841
+ * amount, else its yield amount, else 1), each rounded to a whole number of
842
+ * at least 1.
843
+ *
844
+ * @see https://recipe-book.siraj.page/reference/react/servings/#servingsselect
845
+ * @see https://recipe-book.siraj.page/reference/react/root/#servings-window
415
846
  */
416
847
  options?: readonly number[] | undefined;
417
848
  };
@@ -428,18 +859,55 @@ type RecipeServingsSelectProps = Omit<ComponentPropsWithoutRef<'select'>, 'value
428
859
  * It sets `autoComplete="off"`, so when going back reloads the page, the
429
860
  * browser doesn't restore an earlier choice over the Root's servings. An
430
861
  * `autoComplete` you pass wins.
862
+ *
863
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`, and
864
+ * `invalid_argument` when the Root's `locale` isn't a language tag that
865
+ * `Intl` accepts, such as `'en_US'`.
866
+ *
867
+ * @example
868
+ * <Recipe.Root recipe={recipe}>
869
+ * <Recipe.ServingsSelect options={[2, 4, 6, 8]} />
870
+ * </Recipe.Root>
871
+ *
872
+ * @see https://recipe-book.siraj.page/reference/react/servings/#servingsselect
431
873
  */
432
874
  declare const ServingsSelect: ForwardRefExoticComponent<RecipeServingsSelectProps & RefAttributes<HTMLSelectElement>>;
433
- /** Attributes for the `<input type="number">`, except its value, which follows the Root's servings. */
875
+ /**
876
+ * The props of `<Recipe.ServingsInput>`: the `<input type="number">`'s
877
+ * attributes, with `min`, `max` and `step` as numbers. It sets the type and
878
+ * the value, which follows the Root's servings, so it doesn't take `type`,
879
+ * `value` or `defaultValue`.
880
+ *
881
+ * @see https://recipe-book.siraj.page/reference/react/servings/#servingsinput
882
+ */
434
883
  type RecipeServingsInputProps = Omit<ComponentPropsWithoutRef<'input'>, 'type' | 'value' | 'defaultValue' | 'min' | 'max' | 'step'> & {
435
- /** The fewest servings that can be entered. Defaults to 1. */
884
+ /**
885
+ * The fewest servings that can be entered, set as the `min` attribute. The
886
+ * `step` grid counts from it.
887
+ *
888
+ * @defaultValue `1`
889
+ *
890
+ * @see https://recipe-book.siraj.page/reference/react/servings/#servingsinput
891
+ */
436
892
  min?: number | undefined;
437
- /** The most servings that can be entered. */
893
+ /**
894
+ * The most servings that can be entered, set as the `max` attribute.
895
+ * Without it, there's no `max` attribute, and the input accepts numbers up
896
+ * to the top of the servings window.
897
+ *
898
+ * @see https://recipe-book.siraj.page/reference/react/servings/#servingsinput
899
+ * @see https://recipe-book.siraj.page/reference/react/root/#servings-window
900
+ */
438
901
  max?: number | undefined;
439
902
  /**
440
903
  * How far the arrows move the value, and the grid, counted from `min`, that
441
- * an entered value must be on. Defaults to 1. `'any'` allows any value. A
442
- * `step` that isn't a number above 0 counts as 1, as in the browser.
904
+ * an entered value must be on. `'any'` allows any value. A `step` that
905
+ * isn't a number above 0 counts as 1, as in the browser.
906
+ *
907
+ * @defaultValue `1`, the browser's step for an input without a `step`
908
+ * attribute
909
+ *
910
+ * @see https://recipe-book.siraj.page/reference/react/servings/#the-step-grid
443
911
  */
444
912
  step?: number | 'any' | undefined;
445
913
  };
@@ -451,12 +919,28 @@ type RecipeServingsInputProps = Omit<ComponentPropsWithoutRef<'input'>, 'type' |
451
919
  * range, so typing them logs no warning.
452
920
  *
453
921
  * Its accessible name and `autoComplete` follow the same rules as
454
- * `<Recipe.ServingsSelect>`.
922
+ * `<Recipe.ServingsSelect>`. `inputMode` defaults to `'numeric'` when `min`
923
+ * and the step are whole numbers, as with the defaults of 1, and to
924
+ * `'decimal'` otherwise, including with `step="any"`.
925
+ *
926
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
927
+ *
928
+ * @example
929
+ * <Recipe.Root recipe={recipe}>
930
+ * <Recipe.ServingsInput max={48} />
931
+ * </Recipe.Root>
932
+ *
933
+ * @see https://recipe-book.siraj.page/reference/react/servings/#servingsinput
455
934
  */
456
935
  declare const ServingsInput: ForwardRefExoticComponent<RecipeServingsInputProps & RefAttributes<HTMLInputElement>>;
457
936
 
458
- /** Attributes for the `<span>`; it renders the step's text, so no `children`. */
459
- type RecipeStepTextProps = Omit<ComponentPropsWithoutRef<'span'>, 'children'>;
937
+ /**
938
+ * Attributes for the `<span>`; it renders the step's text, so no `children` or
939
+ * `dangerouslySetInnerHTML`.
940
+ *
941
+ * @see https://recipe-book.siraj.page/reference/react/steps/#steptext
942
+ */
943
+ type RecipeStepTextProps = Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'dangerouslySetInnerHTML'>;
460
944
  /**
461
945
  * The nearest `<Recipe.Step>`'s text, with each temperature shown in Root's
462
946
  * display system: °C for metric, °F for US. A reading the author wrote in that
@@ -467,54 +951,110 @@ type RecipeStepTextProps = Omit<ComponentPropsWithoutRef<'span'>, 'children'>;
467
951
  * mark that follows a temperature as another way to give the same setting, as
468
952
  * in `190C/170C fan/gas 5` or `200°C (gas mark 6)`, is left out. Everything
469
953
  * else, including a gas mark on its own or before a temperature, is shown as
470
- * authored. Each temperature is a `<span data-recipe-temperature>`.
954
+ * authored. Each temperature is a `<span data-recipe-temperature>`. When
955
+ * `segmentStepText` pairs a conventional setting with a fan one, the
956
+ * conventional one shows first and the fan one after a slash, as in
957
+ * `200 °C / 180 °C fan`.
471
958
  *
472
959
  * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Step>`.
960
+ * @throws {RecipeBookError} `invalid_argument` for a step with a temperature
961
+ * when Root's `locale` isn't a language tag that `Intl` accepts, such as
962
+ * `'en_US'`.
473
963
  *
474
964
  * @example
475
965
  * <Recipe.Step item={step}>
476
966
  * <Recipe.StepName /> <Recipe.StepText />
477
967
  * </Recipe.Step>
968
+ *
969
+ * @see https://recipe-book.siraj.page/reference/react/steps/#steptext
478
970
  */
479
971
  declare const StepText: ForwardRefExoticComponent<RecipeStepTextProps & RefAttributes<HTMLSpanElement>>;
480
972
 
481
- /** Attributes for the wrapping `<div>`, plus `headingLevel`; `children` renders each section. */
482
- type RecipeStepsProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'> & {
973
+ /**
974
+ * Attributes for the wrapping `<div>` other than `dangerouslySetInnerHTML`,
975
+ * plus `headingLevel`; `children` renders each section.
976
+ *
977
+ * @see https://recipe-book.siraj.page/reference/react/steps/#steps
978
+ */
979
+ type RecipeStepsProps = Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'dangerouslySetInnerHTML'> & {
483
980
  /**
484
981
  * Heading level of section titles in the default rendering. Defaults to 3,
485
982
  * for steps under an `<h2>` such as "Method".
983
+ *
984
+ * @defaultValue `3`
985
+ * @see https://recipe-book.siraj.page/guides/make-a-recipe-accessible/#set-heading-levels
486
986
  */
487
987
  headingLevel?: RecipeHeadingLevel | undefined;
488
988
  /**
489
989
  * Renders each section instead of the default. Each result is keyed for
490
990
  * you, so return one element or a fragment; an array's items need their own
491
991
  * keys, as anywhere in React.
992
+ *
993
+ * @defaultValue A `<section>` named by the section's heading, or a `<div>`
994
+ * for an untitled section, around a `<Recipe.StepList>` of its steps.
995
+ * @see https://recipe-book.siraj.page/reference/react/steps/#render-your-own-sections
492
996
  */
493
997
  children?: ((section: RecipeSection<StepItem>) => ReactNode) | undefined;
494
998
  };
495
999
  /**
496
1000
  * The recipe's steps, one block per section. A titled section renders as a
497
1001
  * `<section>` named by its heading, then a `<Recipe.StepList>`.
1002
+ *
1003
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
1004
+ *
1005
+ * @example
1006
+ * <Recipe.Root recipe={recipe}>
1007
+ * <h2>Method</h2>
1008
+ * <Recipe.Steps />
1009
+ * </Recipe.Root>
1010
+ *
1011
+ * @see https://recipe-book.siraj.page/reference/react/steps/#steps
498
1012
  */
499
1013
  declare const Steps: ForwardRefExoticComponent<RecipeStepsProps & RefAttributes<HTMLDivElement>>;
500
- /** Attributes for the `<ol>`, plus the `section` to list; `children` renders each step. */
501
- type RecipeStepListProps = Omit<ComponentPropsWithoutRef<'ol'>, 'children'> & {
1014
+ /**
1015
+ * Attributes for the `<ol>` other than `dangerouslySetInnerHTML`, plus the
1016
+ * `section` to list; `children` renders each step.
1017
+ *
1018
+ * @see https://recipe-book.siraj.page/reference/react/steps/#steplist
1019
+ */
1020
+ type RecipeStepListProps = Omit<ComponentPropsWithoutRef<'ol'>, 'children' | 'dangerouslySetInnerHTML'> & {
502
1021
  /** The section to list. Defaults to every step in the recipe. */
503
1022
  section?: RecipeSection<StepItem> | undefined;
504
1023
  /**
505
1024
  * Renders each step instead of `<Recipe.Step>`. Each result is keyed for
506
1025
  * you, so return one element or a fragment; an array's items need their own
507
1026
  * keys, as anywhere in React.
1027
+ *
1028
+ * @defaultValue `(step) => <Recipe.Step item={step} />`
1029
+ * @see https://recipe-book.siraj.page/reference/react/steps/#render-your-own-steps
508
1030
  */
509
1031
  children?: ((step: StepItem) => ReactNode) | undefined;
510
1032
  };
511
1033
  /**
512
1034
  * An ordered list of steps. `start` defaults to the first step's number, so
513
1035
  * numbering continues across sections.
1036
+ *
1037
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
1038
+ *
1039
+ * @example
1040
+ * <Recipe.StepList>
1041
+ * {(step) => (
1042
+ * <Recipe.Step item={step}>
1043
+ * <Recipe.StepName /> <Recipe.StepText />
1044
+ * </Recipe.Step>
1045
+ * )}
1046
+ * </Recipe.StepList>
1047
+ *
1048
+ * @see https://recipe-book.siraj.page/reference/react/steps/#steplist
514
1049
  */
515
1050
  declare const StepList: ForwardRefExoticComponent<RecipeStepListProps & RefAttributes<HTMLOListElement>>;
516
- /** Attributes for the `<li>`, plus the `item` to render and `asChild`. */
517
- type RecipeStepProps = ComponentPropsWithoutRef<'li'> & {
1051
+ /**
1052
+ * Attributes for the `<li>` other than `dangerouslySetInnerHTML`, plus the
1053
+ * `item` to render and `asChild`.
1054
+ *
1055
+ * @see https://recipe-book.siraj.page/reference/react/steps/#step
1056
+ */
1057
+ type RecipeStepProps = Omit<ComponentPropsWithoutRef<'li'>, 'dangerouslySetInnerHTML'> & {
518
1058
  /** The step to render, with its number. */
519
1059
  item: StepItem;
520
1060
  /**
@@ -525,6 +1065,9 @@ type RecipeStepProps = ComponentPropsWithoutRef<'li'> & {
525
1065
  * are set. The child's own children replace the step's, so an empty child
526
1066
  * gets the name and text. With anything but one element child, it renders
527
1067
  * its own `<li>`, with a warning in development.
1068
+ *
1069
+ * @defaultValue `false`
1070
+ * @see https://recipe-book.siraj.page/reference/react/steps/#render-your-own-element
528
1071
  */
529
1072
  asChild?: boolean | undefined;
530
1073
  };
@@ -538,24 +1081,42 @@ type RecipeStepProps = ComponentPropsWithoutRef<'li'> & {
538
1081
  * <Recipe.Step item={step}>
539
1082
  * <Recipe.StepName /> <Recipe.StepText />
540
1083
  * </Recipe.Step>
1084
+ *
1085
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
1086
+ *
1087
+ * @see https://recipe-book.siraj.page/reference/react/steps/#step
541
1088
  */
542
1089
  declare const Step: ForwardRefExoticComponent<RecipeStepProps & RefAttributes<HTMLLIElement>>;
543
- /** Attributes for the `<b>`; it renders the step's name, so no `children`. */
544
- type RecipeStepNameProps = Omit<ComponentPropsWithoutRef<'b'>, 'children'>;
1090
+ /**
1091
+ * Attributes for the `<b>`; it renders the step's name, so no `children` or
1092
+ * `dangerouslySetInnerHTML`.
1093
+ *
1094
+ * @see https://recipe-book.siraj.page/reference/react/steps/#stepname
1095
+ */
1096
+ type RecipeStepNameProps = Omit<ComponentPropsWithoutRef<'b'>, 'children' | 'dangerouslySetInnerHTML'>;
545
1097
  /**
546
1098
  * The nearest `<Recipe.Step>`'s name in a `<b data-recipe-name>`, or nothing
547
1099
  * when the step has none.
548
1100
  *
549
1101
  * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Step>`.
1102
+ *
1103
+ * @see https://recipe-book.siraj.page/reference/react/steps/#stepname
550
1104
  */
551
1105
  declare const StepName: ForwardRefExoticComponent<RecipeStepNameProps & RefAttributes<HTMLElement>>;
552
1106
 
553
1107
  /**
554
- * Attributes for the radio group's `<div>`, except the `role` it sets, plus
555
- * `asChild`.
556
- * The group sets `aria-disabled` itself.
1108
+ * The props of `<Recipe.SystemToggle>`: the radio group's `<div>` attributes,
1109
+ * plus `asChild`. It sets `role` and renders its own content, so it doesn't
1110
+ * take `role` or `dangerouslySetInnerHTML`.
1111
+ *
1112
+ * The group sets `aria-disabled` and its data attributes at runtime, over any
1113
+ * you pass, so `aria-disabled` is there only while the toggle is disabled. An
1114
+ * `asChild` child's own `role`, `aria-disabled` and data attributes still
1115
+ * win.
1116
+ *
1117
+ * @see https://recipe-book.siraj.page/reference/react/system-toggle/#systemtoggle
557
1118
  */
558
- type RecipeSystemToggleProps = Omit<ComponentPropsWithoutRef<'div'>, 'role'> & {
1119
+ type RecipeSystemToggleProps = Omit<ComponentPropsWithoutRef<'div'>, 'role' | 'dangerouslySetInnerHTML'> & {
559
1120
  /**
560
1121
  * Renders the radio group as its one element child, such as
561
1122
  * `<motion.div layout />`, instead of a `<div>`. A prop on the child wins,
@@ -565,26 +1126,63 @@ type RecipeSystemToggleProps = Omit<ComponentPropsWithoutRef<'div'>, 'role'> & {
565
1126
  * group's, so an empty child gets the metric and US options. With anything
566
1127
  * but one element child, it renders its own `<div>`, with a warning in
567
1128
  * development.
1129
+ *
1130
+ * @defaultValue `false`
1131
+ *
1132
+ * @see https://recipe-book.siraj.page/reference/react/system-toggle/#render-your-own-elements
568
1133
  */
569
1134
  asChild?: boolean | undefined;
570
1135
  };
571
1136
  /**
572
- * Switches the display system. A radio group whose default options are
573
- * metric and US. Disabled when there's nothing to convert: no ingredient has a
574
- * unit that belongs to only one system, and no `Recipe.StepText` in the Root
575
- * shows a temperature. A `StepText` counts once it mounts, so for a recipe
576
- * whose only temperatures are in its steps, the toggle enables after
1137
+ * Switches the Root's measurement system. A radio group whose default options
1138
+ * are metric and US. Disabled when there's nothing to convert: no ingredient
1139
+ * has a unit that belongs to only one system, and no `Recipe.StepText` in the
1140
+ * Root shows a temperature. A `StepText` counts once it mounts, so for a
1141
+ * recipe whose only temperatures are in its steps, the toggle enables after
577
1142
  * hydration.
1143
+ *
1144
+ * Its accessible name defaults to the `system` label, unless you pass
1145
+ * `aria-label` or `aria-labelledby`.
1146
+ *
1147
+ * @throws {RecipeBookError} `missing_parent` outside a `<Recipe.Root>`.
1148
+ *
1149
+ * @example
1150
+ * <Recipe.Root recipe={recipe}>
1151
+ * <Recipe.SystemToggle className="units" />
1152
+ * </Recipe.Root>
1153
+ *
1154
+ * @see https://recipe-book.siraj.page/reference/react/system-toggle/#systemtoggle
578
1155
  */
579
1156
  declare const SystemToggle: ForwardRefExoticComponent<RecipeSystemToggleProps & RefAttributes<HTMLDivElement>>;
580
1157
  /**
581
- * Attributes for the radio's `<button>`, except the `role` and `tabIndex` it
582
- * sets, with `value` the system it selects, plus `asChild`.
583
- * The option sets `aria-checked` itself.
1158
+ * The props of `<Recipe.SystemOption>`: the radio's `<button>` attributes,
1159
+ * with `value` the system it selects, plus `asChild`. It sets `role` and
1160
+ * `tabIndex` and renders its own content, so it doesn't take them or
1161
+ * `dangerouslySetInnerHTML`.
1162
+ *
1163
+ * The option sets `aria-checked` and its data attributes at runtime, over any
1164
+ * you pass. An `asChild` child's own `role`, `aria-checked` and data
1165
+ * attributes still win.
1166
+ *
1167
+ * @see https://recipe-book.siraj.page/reference/react/system-toggle/#systemoption
584
1168
  */
585
- type RecipeSystemOptionProps = Omit<ComponentPropsWithoutRef<'button'>, 'value' | 'role' | 'tabIndex'> & {
586
- /** The system this option selects. */
1169
+ type RecipeSystemOptionProps = Omit<ComponentPropsWithoutRef<'button'>, 'value' | 'role' | 'tabIndex' | 'dangerouslySetInnerHTML'> & {
1170
+ /**
1171
+ * The system this option selects: `'metric'` or `'us'`.
1172
+ *
1173
+ * @see https://recipe-book.siraj.page/reference/react/system-toggle/#systemoption
1174
+ */
587
1175
  value: System;
1176
+ /**
1177
+ * The button's `autocomplete` attribute. Off by default, so when going back
1178
+ * reloads the page, Firefox doesn't re-enable an option that the server
1179
+ * rendered disabled and the page enabled later.
1180
+ *
1181
+ * @defaultValue `'off'`
1182
+ *
1183
+ * @see https://recipe-book.siraj.page/reference/react/system-toggle/#systemoption
1184
+ */
1185
+ autoComplete?: string | undefined;
588
1186
  /**
589
1187
  * Renders the radio as its one element child, such as
590
1188
  * `<motion.button layout />`, instead of a `<button>`. A prop on the child
@@ -596,12 +1194,36 @@ type RecipeSystemOptionProps = Omit<ComponentPropsWithoutRef<'button'>, 'value'
596
1194
  * the option's, so an empty child gets the system's label. With anything but
597
1195
  * one element child, it renders its own `<button>`, with a warning in
598
1196
  * development.
1197
+ *
1198
+ * @defaultValue `false`
1199
+ *
1200
+ * @see https://recipe-book.siraj.page/reference/react/system-toggle/#render-your-own-elements
599
1201
  */
600
1202
  asChild?: boolean | undefined;
601
1203
  };
602
1204
  /**
603
- * One option of a `<Recipe.SystemToggle>`. Children default to the system's
604
- * label.
1205
+ * One option of a `<Recipe.SystemToggle>`. Checked when its `value` is the
1206
+ * Root's system; a click sets the Root's system to `value`. Children default
1207
+ * to the system's label. Its `type` defaults to `'button'`, so it doesn't
1208
+ * submit a form. It's disabled while the toggle is, even with
1209
+ * `disabled={false}`.
1210
+ *
1211
+ * It sets `autoComplete="off"`, so when going back reloads the page, Firefox
1212
+ * doesn't re-enable an option that the server rendered disabled and the page
1213
+ * enabled later. An `autoComplete` you pass wins.
1214
+ *
1215
+ * @throws {RecipeBookError} `missing_parent` outside a
1216
+ * `<Recipe.SystemToggle>`.
1217
+ *
1218
+ * @example
1219
+ * <Recipe.SystemToggle>
1220
+ * <Recipe.SystemOption value="us">Cups and spoons</Recipe.SystemOption>
1221
+ * <Recipe.SystemOption value="metric">
1222
+ * Grams and milliliters
1223
+ * </Recipe.SystemOption>
1224
+ * </Recipe.SystemToggle>
1225
+ *
1226
+ * @see https://recipe-book.siraj.page/reference/react/system-toggle/#systemoption
605
1227
  */
606
1228
  declare const SystemOption: ForwardRefExoticComponent<RecipeSystemOptionProps & RefAttributes<HTMLButtonElement>>;
607
1229
 
@@ -618,10 +1240,17 @@ type FormattedIngredientItem = FormattedIngredient & {
618
1240
  * renderers without a DOM. Returns the same function until the locale or
619
1241
  * `labels.optional` changes.
620
1242
  *
621
- * Without a Root, call `formatIngredient` from `@recipe-book/core`.
1243
+ * Without a Root, call `formatIngredient` from `@recipe-book/react/core`.
622
1244
  *
623
1245
  * @throws {RecipeBookError} `missing_parent` outside a Root.
624
1246
  *
1247
+ * @returns A function that formats one of the state's ingredient items into
1248
+ * the pieces `<Recipe.Ingredient>` renders. It throws `invalid_argument`
1249
+ * when Root's `locale` isn't a language tag that `Intl` accepts, such as
1250
+ * `'en_US'`, the item isn't `{ ingredient, quantity? }`, or it has an amount
1251
+ * that `formatQuantity` rejects, and `unknown_unit` when the item's unit
1252
+ * isn't a unit ID.
1253
+ *
625
1254
  * @example
626
1255
  * function CopyIngredients() {
627
1256
  * const { ingredients } = Recipe.useRecipe()
@@ -638,6 +1267,8 @@ type FormattedIngredientItem = FormattedIngredient & {
638
1267
  * </button>
639
1268
  * )
640
1269
  * }
1270
+ *
1271
+ * @see https://recipe-book.siraj.page/reference/react/hooks/#useformatingredient
641
1272
  */
642
1273
  declare function useFormatIngredient(): (item: IngredientItem) => FormattedIngredientItem;
643
1274