@eduardoalvarez/arrecife 0.6.0 → 0.7.0
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/CHANGELOG.md +69 -0
- package/README.md +185 -20
- package/dist/brand/index.js +3 -3
- package/dist/chart/index.js +3 -3
- package/dist/{chunk-XKYHTOUJ.js → chunk-2WPWEIMD.js} +1 -1
- package/dist/chunk-45HVCTB7.js +70 -0
- package/dist/{chunk-DKCN7BAL.js → chunk-727HCBD4.js} +1 -1
- package/dist/{chunk-25YNFCIF.js → chunk-E6KFUSKB.js} +6 -3
- package/dist/{chunk-6O3KWB6P.js → chunk-JN3IS5OS.js} +2 -2
- package/dist/{chunk-O4TAH7YJ.js → chunk-OMKSESQB.js} +27 -3
- package/dist/{chunk-PMN7NR3G.js → chunk-TA7TLWW4.js} +1 -1
- package/dist/{chunk-JMOOFZ3B.js → chunk-WGNIRIN7.js} +1 -1
- package/dist/doctor.mjs +166 -0
- package/dist/form/index.js +4 -4
- package/dist/icons/index.cjs +149 -0
- package/dist/icons/index.d.cts +94 -0
- package/dist/icons/index.d.ts +94 -0
- package/dist/icons/index.js +28 -0
- package/dist/index-DlAO2JZs.d.cts +47 -0
- package/dist/index-DlAO2JZs.d.ts +47 -0
- package/dist/index.cjs +279 -103
- package/dist/index.d.cts +186 -57
- package/dist/index.d.ts +186 -57
- package/dist/index.js +262 -179
- package/dist/og/index.cjs +3 -2
- package/dist/og/index.js +1 -1
- package/dist/shiki/index.js +1 -1
- package/dist/social/index.cjs +67 -0
- package/dist/social/index.d.cts +2 -0
- package/dist/social/index.d.ts +2 -0
- package/dist/social/index.js +2 -0
- package/dist/tokens/index.cjs +27 -3
- package/dist/tokens/index.d.cts +33 -6
- package/dist/tokens/index.d.ts +33 -6
- package/dist/tokens/index.js +2 -2
- package/dist/tokens/theme.css +33 -3
- package/dist/variants/index.cjs +6 -3
- package/dist/variants/index.d.cts +4 -1
- package/dist/variants/index.d.ts +4 -1
- package/dist/variants/index.js +1 -1
- package/llms.txt +363 -30
- package/package.json +24 -2
package/llms.txt
CHANGED
|
@@ -41,7 +41,7 @@ Radix, `clsx`, `tailwind-merge`, `class-variance-authority`, `date-fns` and
|
|
|
41
41
|
`react-day-picker` come as dependencies of the library. You do not need to
|
|
42
42
|
install or declare them.
|
|
43
43
|
|
|
44
|
-
**It ships no
|
|
44
|
+
**It ships no icon set.** The glyphs the components
|
|
45
45
|
need are inline, inherit `currentColor` and measure 1em.
|
|
46
46
|
|
|
47
47
|
## Tailwind configuration
|
|
@@ -116,6 +116,8 @@ that only whoever uses them installs.
|
|
|
116
116
|
| `@eduardoalvarez/arrecife/og` | **no** | — | The Open Graph templates for Satori |
|
|
117
117
|
| `@eduardoalvarez/arrecife/shiki` | **no** | — | The syntax highlighting theme |
|
|
118
118
|
| `@eduardoalvarez/arrecife/brand` | yes | — | Logo, isotype and mascot as components |
|
|
119
|
+
| `@eduardoalvarez/arrecife/social` | yes, on the server only | — | The nine social icons, loose. No `"use client"` |
|
|
120
|
+
| `@eduardoalvarez/arrecife/icons` | yes | `@phosphor-icons/react` | `Icon`, which draws a Phosphor icon at the system's size, and at the weight its role asks for |
|
|
119
121
|
| `@eduardoalvarez/arrecife/form` | yes | `react-hook-form` | The form layer: labels, errors and `aria-*` |
|
|
120
122
|
| `@eduardoalvarez/arrecife/chart` | yes | `recharts` | The chart chassis and the series palette |
|
|
121
123
|
| `@eduardoalvarez/arrecife/assets/*` | — | — | The brand PNGs |
|
|
@@ -124,15 +126,16 @@ Importing the root from a build script to get one token is the mistake the
|
|
|
124
126
|
subpaths exist to prevent: it drags all of React into a worker that never mounts
|
|
125
127
|
it.
|
|
126
128
|
|
|
127
|
-
`./form` and `./
|
|
128
|
-
hung off the main index, the projects that draw no charts
|
|
129
|
-
Form would have to install those dependencies anyway so
|
|
130
|
-
resolve an import they never execute.
|
|
129
|
+
`./form`, `./chart` and `./icons` sit outside the root for the symmetric reason:
|
|
130
|
+
if they hung off the main index, the projects that draw no charts, use no React
|
|
131
|
+
Hook Form and need no icons would have to install those dependencies anyway so
|
|
132
|
+
their bundler could resolve an import they never execute. Two of the five consume
|
|
133
|
+
zero icons.
|
|
131
134
|
|
|
132
135
|
### Next, Server Components and `"use client"`
|
|
133
136
|
|
|
134
137
|
The root, `./brand`, `./form` and `./chart` ship `"use client"` in the published
|
|
135
|
-
`dist
|
|
138
|
+
`dist/`, and they are the only four. They render React and their Radix primitives call `createContext` at
|
|
136
139
|
module scope, so without the directive a Next project with the App Router cannot
|
|
137
140
|
import them at all: it fails at build time with
|
|
138
141
|
`TypeError: (0 , r.createContext) is not a function`.
|
|
@@ -145,7 +148,11 @@ needed it.
|
|
|
145
148
|
|
|
146
149
|
The five portable subpaths do NOT carry the directive, and that is the half that
|
|
147
150
|
matters in a Server Component: `./tokens`, `./theme`, `./variants`, `./og` and
|
|
148
|
-
`./shiki` stay on the server.
|
|
151
|
+
`./shiki` stay on the server. Neither does `./social`, which is a third case: it
|
|
152
|
+
renders React — it is nine `<svg>` — so it can never be portable, but it holds no
|
|
153
|
+
state and nothing about it needs a client boundary. It is the only way to put a
|
|
154
|
+
social icon in a Server Component, and § «The social icons come from `./social`»
|
|
155
|
+
below says why the grouped form cannot do it. If all you need are classes — for a `<div>`, an
|
|
149
156
|
`<a>` or an Astro island you do not want to hydrate — import them from
|
|
150
157
|
`./variants` and nothing crosses to the client:
|
|
151
158
|
|
|
@@ -202,21 +209,256 @@ It has to go INLINE. A `<script src>`, even a synchronous one, gets downloaded,
|
|
|
202
209
|
and the flash comes back. The script re-attaches on `astro:after-swap` because
|
|
203
210
|
view transitions replace the whole `<html>`.
|
|
204
211
|
|
|
205
|
-
###
|
|
212
|
+
### `npx arrecife` — run it once after installing
|
|
213
|
+
|
|
214
|
+
Two things break with **no error at all**, and the command catches both.
|
|
215
|
+
|
|
216
|
+
**Tailwind purges everything the components emit** unless the stylesheet has
|
|
217
|
+
`@source "<path>/node_modules/@eduardoalvarez/arrecife/dist"`. It does not scan
|
|
218
|
+
`node_modules`. There is no console error and no undefined class: the card mounts
|
|
219
|
+
with no padding, no radius and no border. The path is relative to the SHEET, not
|
|
220
|
+
to the project root, and the command computes it.
|
|
221
|
+
|
|
222
|
+
**A `--color-*` of yours silently replaces ours.** A project coming from shadcn
|
|
223
|
+
has `@theme inline { --color-accent: var(--accent); }` — shadcn's `--accent` is
|
|
224
|
+
the hover surface, `#17303E`, and ours is the brand turquoise, `#35D6C0`. That
|
|
225
|
+
one line repainted 88 classes inside the library's own components grey. Five
|
|
226
|
+
names collide in total; four agree on the value and are harmless, and the command
|
|
227
|
+
tells them apart.
|
|
228
|
+
|
|
229
|
+
Do not silence it by removing the `@import`: the fix is the `@source` line, or
|
|
230
|
+
renaming your own token.
|
|
231
|
+
|
|
232
|
+
### `SidebarNav` groups, and the icon replaces the prompt
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
<SidebarNav aria-label="Administración" brand={<>…</>} version="v0.6.0" branch="main">
|
|
236
|
+
<SidebarItem href="/admin" icon={<Icon as={SquaresFour} />} active>Resumen</SidebarItem>
|
|
237
|
+
|
|
238
|
+
<SidebarGroup label="Ventas">
|
|
239
|
+
<SidebarItem href="/admin/ventas" icon={<Icon as={CreditCard} />}>Ventas</SidebarItem>
|
|
240
|
+
<SidebarItem href="/admin/cupones" icon={<Icon as={Ticket} />}>Cupones</SidebarItem>
|
|
241
|
+
</SidebarGroup>
|
|
242
|
+
</SidebarNav>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Past about eight items a flat sidebar stops being readable. Each `SidebarGroup`
|
|
246
|
+
is a nested list named by its label, so a screen reader says «lista Ventas, 3
|
|
247
|
+
elementos» instead of one list of eleven. The label is a paragraph and **not** a
|
|
248
|
+
heading on purpose: a sidebar is navigation, and a heading here would land in the
|
|
249
|
+
page's own outline.
|
|
250
|
+
|
|
251
|
+
**`icon` replaces the `▸`, it does not join it.** Do not pass a glyph and expect
|
|
252
|
+
the prompt as well. A sidebar with no icons keeps the prompt on every item, which
|
|
253
|
+
is what a four-section blog admin wants.
|
|
254
|
+
|
|
255
|
+
**`brand` does not replace `title`.** `title` is the eyebrow and also the `nav`'s
|
|
256
|
+
accessible name when it is a string; a logo is not an accessible name, so pass
|
|
257
|
+
`aria-label` when you use `brand`. See `docs/decisions.md` § 32.
|
|
258
|
+
|
|
259
|
+
**It collapses to a rail, and the toggle is CONTROLLED:**
|
|
260
|
+
|
|
261
|
+
```tsx
|
|
262
|
+
const [collapsed, setCollapsed] = useState(false);
|
|
263
|
+
|
|
264
|
+
<SidebarNav
|
|
265
|
+
collapsed={collapsed}
|
|
266
|
+
onCollapsedChange={setCollapsed}
|
|
267
|
+
brand={<Wordmark />}
|
|
268
|
+
mark={<Isotype className="h-6" />}
|
|
269
|
+
user={<Avatar … />}
|
|
270
|
+
>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
There is no uncontrolled mode: this state is almost always persisted, and an
|
|
274
|
+
internal one would fight the cookie you already keep. `onCollapsedChange` is also
|
|
275
|
+
what makes the toggle appear — `collapsed` on its own is a rail with no way out,
|
|
276
|
+
which is a layout and not an accident.
|
|
277
|
+
|
|
278
|
+
Collapsed, the widths become `w-sidebar-rail` (56) and `w-sidebar` (256), and the
|
|
279
|
+
component owns them only when it can collapse. It does **not** transition, on
|
|
280
|
+
purpose. `brand` is hidden and `mark` takes its place, because a wordmark does
|
|
281
|
+
not fit in a rail. Every label stays in the accessibility tree as `sr-only`, so
|
|
282
|
+
do not «simplify» by dropping the children of a collapsed item. See
|
|
283
|
+
`docs/decisions.md` § 34.
|
|
284
|
+
|
|
285
|
+
### `Nav` is two slots and one height
|
|
286
|
+
|
|
287
|
+
Almost everything an app shell wants from a site bar is already a slot:
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
<Nav
|
|
291
|
+
size="compact" // 56px, for a shell with a sidebar
|
|
292
|
+
brand={<a href="/"><Logo /><span><span className="text-accent">~/</span>cursos</span></a>}
|
|
293
|
+
actions={session ? <UserMenu /> : <Button size="sm" asChild><Link href="/login">Entrar</Link></Button>}
|
|
294
|
+
>
|
|
295
|
+
<NavItem href="/cursos" active>cursos</NavItem>
|
|
296
|
+
</Nav>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
`brand` and `actions` are `ReactNode`, so a wordmark, a user menu, a theme toggle
|
|
300
|
+
or a search box go in without the library knowing anything about sessions.
|
|
301
|
+
**Session state does not get a prop** — it is project infrastructure, and the
|
|
302
|
+
library takes none.
|
|
303
|
+
|
|
304
|
+
`size="compact"` is 56px instead of 64, for a bar that shares the screen with a
|
|
305
|
+
sidebar. It is a prop and not a class because the height lives on `Nav`'s inner
|
|
306
|
+
container: `className` reaches the `<header>` and stops there, so passing `h-14`
|
|
307
|
+
does nothing.
|
|
308
|
+
|
|
309
|
+
**One `Nav` per page.** It renders the site's `banner` landmark, and two banners
|
|
310
|
+
on one page is an accessibility failure — which is also why `PageHeader` goes
|
|
311
|
+
inside `<main>` and is not a landmark. See `docs/decisions.md` § 30.
|
|
312
|
+
|
|
313
|
+
### Icons are yours, the way they are drawn is not
|
|
314
|
+
|
|
315
|
+
The library ships no icon set and `lib/glyphs.tsx` is not exported: it is the
|
|
316
|
+
minimum set the primitives need and it does not grow. What the library does ship
|
|
317
|
+
is the drawing.
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
import { GraduationCap, Trash } from '@phosphor-icons/react';
|
|
321
|
+
import { Icon } from '@eduardoalvarez/arrecife/icons';
|
|
322
|
+
|
|
323
|
+
// 1em, and `tone="action"` by default — `regular`, the stroke the document names
|
|
324
|
+
<Icon as={GraduationCap} />
|
|
325
|
+
|
|
326
|
+
// Inside a control with no text, the name goes on the CONTROL
|
|
327
|
+
<Button size="icon-sm" variant="secondary" aria-label="Borrar la fila">
|
|
328
|
+
<Icon as={Trash} />
|
|
329
|
+
</Button>
|
|
330
|
+
|
|
331
|
+
// Alone and meaning something on its own, it gets a name
|
|
332
|
+
<Icon as={Trophy} label="Curso completado" />
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
**Do not size them by hand.** `size-4`, `size-3.5`, `size-6` scattered through a
|
|
336
|
+
codebase is what this replaces: at 1em the icon takes the size of the text it
|
|
337
|
+
sits in — 13px beside `text-label`, 15px beside `text-ui` — and nobody picks a
|
|
338
|
+
number.
|
|
339
|
+
|
|
340
|
+
**The weight is not yours to pick either, but it is not one value.** `tone` names
|
|
341
|
+
what the icon is doing and the weight follows from it. There are three and there
|
|
342
|
+
is no fourth:
|
|
343
|
+
|
|
344
|
+
| `tone` | Weight | What it is |
|
|
345
|
+
| --- | --- | --- |
|
|
346
|
+
| `action` · the default | `regular` | An icon that is a control or names one. It is the system's line: 16 on a 256 grid = 0.0625em, against the document's 1.6 on a 24 grid = 0.0667em. Six per cent apart, which is no pixel on any screen |
|
|
347
|
+
| `current` | `fill` | The one of a set you are on — the sidebar item carrying `aria-current` |
|
|
348
|
+
| `quiet` | `light` | Furniture: a marker in a metadata row, not a control and not a state |
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
<SidebarItem href="/cursos" active icon={<Icon as={GraduationCap} tone="current" />}>
|
|
352
|
+
cursos
|
|
353
|
+
</SidebarItem>
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
`current` is the one that earns the axis. An active item already paints itself
|
|
357
|
+
biolume, and colour on its own is the channel WCAG 1.4.1 says may not carry
|
|
358
|
+
meaning alone; the fill is the second channel, and it is the one that survives a
|
|
359
|
+
forced-colours mode. `weight` is deliberately **not** a prop: Phosphor ships six
|
|
360
|
+
and this system reads three, because `thin`, `bold` and `duotone` have no role
|
|
361
|
+
behind them here.
|
|
362
|
+
|
|
363
|
+
`@phosphor-icons/react` is an **optional** peer dependency. If your project uses
|
|
364
|
+
no icons you install nothing; two of the five do exactly that.
|
|
365
|
+
|
|
366
|
+
**An icon is not illustration, and the two never substitute for each other.**
|
|
367
|
+
Tiburoncín — the faces, the poses, the fin — is the mascot; it comes from
|
|
368
|
+
`./brand`, and the manual says where a face may appear: empty states,
|
|
369
|
+
confirmations, errors, course progress, celebration, and nowhere else. An icon is
|
|
370
|
+
functional vocabulary and goes wherever a control needs a label it cannot spell.
|
|
371
|
+
Do not put an icon where the system asks for a face, and do not put a face where
|
|
372
|
+
a control wants an icon.
|
|
373
|
+
|
|
374
|
+
**In Next, import from `@phosphor-icons/react/ssr` inside a Server Component.**
|
|
375
|
+
Phosphor's default build reads `IconContext` through `useContext`, and a hook in
|
|
376
|
+
a Server Component throws. It ships no `"use client"` to stop you, so the failure
|
|
377
|
+
arrives at render rather than at build. The `/ssr` entry is the same icons
|
|
378
|
+
without the context read, and `Icon` works with either.
|
|
379
|
+
|
|
380
|
+
See `docs/decisions.md` § 29 and § 35.
|
|
381
|
+
|
|
382
|
+
### `Stat`'s delta says direction, not judgement
|
|
383
|
+
|
|
384
|
+
```tsx
|
|
385
|
+
<Stat
|
|
386
|
+
label="alumnos"
|
|
387
|
+
value="1.284"
|
|
388
|
+
delta={{ value: '+12 esta semana', direction: 'up' }}
|
|
389
|
+
/>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
`direction` picks the arrow and **never the colour**. «+12 alumnos» and «+12
|
|
393
|
+
errores» point the same way and mean opposite things, so whether a number is good
|
|
394
|
+
news is `tone`'s job and yours: `neutral` for a datum, `alert` when the number IS
|
|
395
|
+
the problem, `achievement` when it is the reward. `alert` and `achievement` paint
|
|
396
|
+
the same sand on purpose — the API is the meaning, the colour is the
|
|
397
|
+
implementation. See `docs/decisions.md` § 28.
|
|
398
|
+
|
|
399
|
+
`delta.value` arrives already formatted, like `value`: the library imposes no
|
|
400
|
+
locale and computes no percentage. `spark` is a `ReactNode` and the library ships
|
|
401
|
+
no sparkline — pass your own, exactly like `icon`.
|
|
402
|
+
|
|
403
|
+
**Do not colour the number.** A neutral `Stat` renders its value in primary ink,
|
|
404
|
+
and biolume goes on the icon badge and the sparkline instead: three accents in
|
|
405
|
+
one card and the figure stops being the loudest thing in it. `alert` and
|
|
406
|
+
`achievement` DO paint the number sand, which is how «this number is not just a
|
|
407
|
+
number» is said. See `docs/decisions.md` § 31.
|
|
408
|
+
|
|
409
|
+
**`icon` is a badge in the corner opposite the title**, in a circle tinted at
|
|
410
|
+
10 % of the tone. You pass the glyph; the circle, the tint and the size are the
|
|
411
|
+
component's.
|
|
412
|
+
|
|
413
|
+
### The two shapes of `EmptyState`
|
|
206
414
|
|
|
207
415
|
```tsx
|
|
208
|
-
//
|
|
416
|
+
// The empty state IS the screen: a search with no results, a 404, a section
|
|
417
|
+
// with nothing in it yet. It carries the face, and `expression` is mandatory.
|
|
418
|
+
<EmptyState expression="waiting" title="Sin resultados" description="…" />
|
|
419
|
+
|
|
420
|
+
// The hole INSIDE something else: a table page, a dashboard widget. No face, no
|
|
421
|
+
// surface, no border — the table or the card already draws the region.
|
|
422
|
+
<EmptyState variant="inline" title="No hay lecciones en esta página" />
|
|
423
|
+
|
|
424
|
+
// ❌ does not compile: the props are a union, and `inline` has no face
|
|
425
|
+
<EmptyState variant="inline" expression="waiting" title="…" />
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
`inline` takes an optional `icon` — a `ReactNode` the project passes and sizes,
|
|
429
|
+
at 1em and in `currentColor`, like `Stat`'s. The library ships no icons.
|
|
430
|
+
|
|
431
|
+
Do not reach for `page` inside a table because the face is «nicer»: an admin
|
|
432
|
+
screen with a dozen empty regions gets a dozen mascots, which is what made every
|
|
433
|
+
consuming project write its own empty state instead of using this one.
|
|
434
|
+
|
|
435
|
+
### The social icons come from `./social`
|
|
436
|
+
|
|
437
|
+
```tsx
|
|
438
|
+
// ❌ does not exist: the root publishes them grouped, not loose
|
|
209
439
|
import { GitHub } from '@eduardoalvarez/arrecife';
|
|
210
440
|
|
|
211
|
-
// ✅
|
|
441
|
+
// ✅ the normal form
|
|
442
|
+
import { GitHub } from '@eduardoalvarez/arrecife/social';
|
|
443
|
+
|
|
444
|
+
// ✅ for iterating the catalogue
|
|
212
445
|
import { social } from '@eduardoalvarez/arrecife';
|
|
213
446
|
<social.GitHub />
|
|
214
447
|
```
|
|
215
448
|
|
|
216
449
|
All nine: `GitHub`, `LinkedIn`, `X`, `Instagram`, `Discord`, `YouTube`, `Rss`,
|
|
217
|
-
`Email`, `Newsletter`.
|
|
218
|
-
|
|
219
|
-
|
|
450
|
+
`Email`, `Newsletter`. `Newsletter` is the bell: a way to follow, like `Rss`,
|
|
451
|
+
named for what it means.
|
|
452
|
+
|
|
453
|
+
**In a Server Component the subpath is mandatory, not preferred.** The root
|
|
454
|
+
carries `"use client"`, and a client reference crosses the boundary per EXPORT —
|
|
455
|
+
the properties of a plain object are not exports, so `social.LinkedIn` is
|
|
456
|
+
`undefined` on the server and `undefined` as an element type kills the build at
|
|
457
|
+
prerender. `./social` carries no directive: it renders on the server and ships no
|
|
458
|
+
client JS. Use `social` only when mapping a list of names onto icons.
|
|
459
|
+
|
|
460
|
+
The root keeps the group because one of them is called `X`, and loose at the root
|
|
461
|
+
it collides. In the subpath, alias it: `import { X as XIcon }`.
|
|
220
462
|
|
|
221
463
|
The internal glyphs — `Close`, `ChevronDown`, `Sun` — are **not exported** and
|
|
222
464
|
are not going to be: they are the primitives' minimum set. A component that needs
|
|
@@ -240,7 +482,7 @@ same value is available in both places and they cannot disagree.
|
|
|
240
482
|
| `control.md` | `--spacing-control-md` | `px-control-md` |
|
|
241
483
|
| `control.icon` | `--spacing-control-icon` | `size-control-icon` (42×42) |
|
|
242
484
|
| `gradient[mode].hero` | `--gradient-hero` | `gradient-hero` |
|
|
243
|
-
| `size.nav` | `--spacing-nav` | `h-nav` |
|
|
485
|
+
| `size.nav` / `size.navCompact` | `--spacing-nav` / `--spacing-nav-compact` | `h-nav` / `h-nav-compact` |
|
|
244
486
|
| `size.content` / `size.wide` | `--container-content` / `--container-wide` | `max-w-content` / `max-w-wide` |
|
|
245
487
|
| `limits.measure` | `--container-measure` | `max-w-measure` |
|
|
246
488
|
| `shadow.standard` | `--shadow-standard` | `shadow-standard` |
|
|
@@ -288,6 +530,11 @@ compiles and looks wrong, or that fails the project's accessibility audit.
|
|
|
288
530
|
11. **The mascot's faces only appear** in empty states, confirmations, errors,
|
|
289
531
|
course progress and celebration. Never in a hero, pricing, services, contact
|
|
290
532
|
or the CV.
|
|
533
|
+
**And not in every empty state either**: `EmptyState variant="inline"` is the
|
|
534
|
+
hole inside a table page or a dashboard widget, and it carries no face — the
|
|
535
|
+
type does not accept one. `page`, the default, is the one that IS the screen,
|
|
536
|
+
and there `expression` stays mandatory. A dozen mascots on one admin screen is
|
|
537
|
+
not the humour contract. See `docs/decisions.md` § 27.
|
|
291
538
|
12. **The fin is not a free parameter**: `foam` on a dark background, `color` on a
|
|
292
539
|
light one. The components already choose it from the background.
|
|
293
540
|
|
|
@@ -968,7 +1215,7 @@ Source: `src/primitives/typography.tsx`
|
|
|
968
1215
|
|
|
969
1216
|
## Components
|
|
970
1217
|
|
|
971
|
-
Imported from `@eduardoalvarez/arrecife`.
|
|
1218
|
+
Imported from `@eduardoalvarez/arrecife`. 25 exports.
|
|
972
1219
|
|
|
973
1220
|
### ArticleCard
|
|
974
1221
|
|
|
@@ -1078,17 +1325,17 @@ Source: `src/components/course-card/index.tsx`
|
|
|
1078
1325
|
|
|
1079
1326
|
Source: `src/components/empty-state/index.tsx`
|
|
1080
1327
|
|
|
1081
|
-
The
|
|
1082
|
-
|
|
1083
|
-
- Extends: `Omit<ComponentPropsWithoutRef<'div'>, 'title'>`
|
|
1328
|
+
- Extends: `EmptyStateBase & ( \| { /** `page`, the default: the empty state IS the screen or the section, and it carries the face. */ variant?: 'page' \| undefined; /** * The face. Mandatory on `page` and impossible on `inline` — the props * are a union, so the generated table cannot show a per-variant «req.» * and the sentence has to carry it. Without it, `page` is a centred * paragraph. */ expression: Face; /** Where the brand PNGs are served from. */ basePath?: string \| undefined; icon?: never; } \| { /** `inline`: the hole inside a table or a widget. No face, and no way to pass one. */ variant: 'inline'; /** * A glyph above the line. It measures 1em and inherits `currentColor`, * like `Stat`'s: the project passes its own and sizes it, because the * system has no icon library and is not getting one. */ icon?: ReactNode; expression?: never; basePath?: never; } )`
|
|
1084
1329
|
|
|
1085
1330
|
| prop | type | req. | default | what it does |
|
|
1086
1331
|
| --- | --- | --- | --- | --- |
|
|
1087
1332
|
| `action` | `ReactNode` | | | The action that gets you out of the empty state. Usually a tertiary button. |
|
|
1088
1333
|
| `basePath` | `string` | | | Where the brand PNGs are served from. |
|
|
1089
1334
|
| `description` | `ReactNode` | | | One line explaining what is missing or what to do. |
|
|
1090
|
-
| `expression` | `"annoyed" \| "confused" \| "hearts" \| "laughing" \| "shades" \| "waiting" \| "wink"` |
|
|
1335
|
+
| `expression` | `"annoyed" \| "confused" \| "hearts" \| "laughing" \| "shades" \| "waiting" \| "wink"` | | | The face. Mandatory on `page` and impossible on `inline` — the props are a union, so the generated table cannot show a per-variant «req.» and the sentence has to carry it. Without it, `page` is a centred paragraph. |
|
|
1336
|
+
| `icon` | `ReactNode` | | | A glyph above the line. It measures 1em and inherits `currentColor`, like `Stat`'s: the project passes its own and sizes it, because the system has no icon library and is not getting one. |
|
|
1091
1337
|
| `title` | `ReactNode` | yes | | |
|
|
1338
|
+
| `variant` | `"inline" \| "page"` | | | `page`, the default: the empty state IS the screen or the section, and it carries the face. `inline`: the hole inside a table or a widget. No face, and no way to pass one. |
|
|
1092
1339
|
|
|
1093
1340
|
### EventCalendar
|
|
1094
1341
|
|
|
@@ -1167,7 +1414,7 @@ Migrated from `links/src/components/Card.astro`. The original scaled the card to
|
|
|
1167
1414
|
Source: `src/components/nav/index.tsx`
|
|
1168
1415
|
|
|
1169
1416
|
**Nav**
|
|
1170
|
-
The site bar: 64px, abyss at 86 % and a 14px blur behind it.
|
|
1417
|
+
The site bar: 64px, abyss at 86 % and a 14px blur behind it — 56 when it shares the screen with a sidebar.
|
|
1171
1418
|
|
|
1172
1419
|
- Extends: `ComponentPropsWithoutRef<'header'>`
|
|
1173
1420
|
|
|
@@ -1175,6 +1422,7 @@ The site bar: 64px, abyss at 86 % and a 14px blur behind it.
|
|
|
1175
1422
|
| --- | --- | --- | --- | --- |
|
|
1176
1423
|
| `actions` | `ReactNode` | | | Actions on the right: conversion, theme switch, search. |
|
|
1177
1424
|
| `brand` | `ReactNode` | | | The logo, on the left. |
|
|
1425
|
+
| `size` | `"compact" \| "default"` | | `default` | `compact` is 56px instead of 64, for a bar that shares the screen with a sidebar: at 64 the two compete for the same corner and together they eat the top of the content area. |
|
|
1178
1426
|
|
|
1179
1427
|
**NavItem**
|
|
1180
1428
|
The `./` is put there by the component, not by whoever uses it.
|
|
@@ -1198,10 +1446,10 @@ Source: `src/components/newsletter-form/index.tsx`
|
|
|
1198
1446
|
| `basePath` | `string` | | | |
|
|
1199
1447
|
| `description` | `ReactNode` | | | |
|
|
1200
1448
|
| `disclaimer` | `ReactNode` | | | The small print. It is the «sin spam», which is why it accepts a face. |
|
|
1201
|
-
| `errorMessage` | `ReactNode` | | `No se pudo suscribir ese
|
|
1449
|
+
| `errorMessage` | `ReactNode` | | `No se pudo suscribir ese correo. Revísalo y vuelve a intentar.` | |
|
|
1202
1450
|
| `expression` | `"annoyed" \| "confused" \| "hearts" \| "laughing" \| "shades" \| "waiting" \| "wink"` | | | |
|
|
1203
1451
|
| `fieldErrors` | `{ name?: ReactNode; email?: ReactNode; }` | | | A message under one specific field, instead of the single alert. |
|
|
1204
|
-
| `fieldLabel` | `string` | | `
|
|
1452
|
+
| `fieldLabel` | `string` | | `Correo electrónico` | |
|
|
1205
1453
|
| `nameField` | `boolean` | | `false` | Adds the name field ahead of the email one. |
|
|
1206
1454
|
| `nameInputProps` | `Omit<InputProps, "id" \| "disabled" \| "name">` | | | Whatever the project needs to hang off the name field: `minLength`, `maxLength`, `pattern`. The library imposes none of the three. |
|
|
1207
1455
|
| `nameLabel` | `string` | | `Nombre` | |
|
|
@@ -1212,7 +1460,7 @@ Source: `src/components/newsletter-form/index.tsx`
|
|
|
1212
1460
|
| `resetOnSuccess` | `boolean` | | `true` | Empties the fields after a successful subscription. On by default. |
|
|
1213
1461
|
| `state` | `"success" \| "error" \| "idle" \| "sending"` | | `idle` | |
|
|
1214
1462
|
| `submitLabel` | `string` | | `Suscribirme` | |
|
|
1215
|
-
| `successMessage` | `ReactNode` | | `Ya estás dentro. Te llega un
|
|
1463
|
+
| `successMessage` | `ReactNode` | | `Ya estás dentro. Te llega un correo cada dos semanas, y nada más.` | |
|
|
1216
1464
|
| `title` | `ReactNode` | yes | | |
|
|
1217
1465
|
|
|
1218
1466
|
### PageHeader
|
|
@@ -1246,7 +1494,7 @@ How much you have read. It is NOT `Progress` under another name.
|
|
|
1246
1494
|
| `target` | `RefObject<HTMLElement \| null>` | | | The element being measured. Without it, the whole document. |
|
|
1247
1495
|
| `tone` | `"accent" \| "warm"` | | `accent` | Sand instead of biolume, to match course progress. |
|
|
1248
1496
|
|
|
1249
|
-
### SidebarItem, SidebarNav
|
|
1497
|
+
### SidebarItem, SidebarGroup, SidebarNav
|
|
1250
1498
|
|
|
1251
1499
|
Source: `src/components/sidebar-nav/index.tsx`
|
|
1252
1500
|
|
|
@@ -1260,6 +1508,16 @@ The blog admin's sidebar.
|
|
|
1260
1508
|
| `active` | `boolean \| undefined` | | `false` | |
|
|
1261
1509
|
| `asChild` | `boolean \| undefined` | | `false` | |
|
|
1262
1510
|
| `badge` | `ReactNode` | | | Counter on the right: pending drafts, unused media. |
|
|
1511
|
+
| `icon` | `ReactNode` | | | The section's glyph, on the left. It REPLACES the `▸` rather than joining it, and it inherits `currentColor`, so it follows the item's state without being tinted separately. |
|
|
1512
|
+
|
|
1513
|
+
**SidebarGroup**
|
|
1514
|
+
A labelled block of items — «Contenido», «Alumnos», «Ventas».
|
|
1515
|
+
|
|
1516
|
+
- Extends: `Omit<ComponentPropsWithoutRef<'li'>, 'title'>`
|
|
1517
|
+
|
|
1518
|
+
| prop | type | req. | default | what it does |
|
|
1519
|
+
| --- | --- | --- | --- | --- |
|
|
1520
|
+
| `label` | `ReactNode` | yes | | The block's name. Sentence case, not a section title. |
|
|
1263
1521
|
|
|
1264
1522
|
**SidebarNav**
|
|
1265
1523
|
- Extends: `ComponentPropsWithoutRef<'nav'>`
|
|
@@ -1267,6 +1525,13 @@ The blog admin's sidebar.
|
|
|
1267
1525
|
| prop | type | req. | default | what it does |
|
|
1268
1526
|
| --- | --- | --- | --- | --- |
|
|
1269
1527
|
| `branch` | `ReactNode` | | | |
|
|
1528
|
+
| `brand` | `ReactNode` | | | The row at the top: isotype and wordmark, `cursos · admin`. It is a slot and not a `logo`/`name` pair because every panel spells its own name differently, and the part that IS the system — the rhythm, the hairline under it — is here. |
|
|
1529
|
+
| `collapsed` | `boolean \| undefined` | | `false` | Turns the sidebar into a rail: icons only, and the widths become the library's — `w-sidebar` and `w-sidebar-rail`. It is CONTROLLED and there is no uncontrolled mode, because this state is almost always persisted in a cookie or in `localStorage`, and an internal state would fight the one the project already keeps. |
|
|
1530
|
+
| `collapseLabel` | `string` | | `Plegar el panel` | The toggle's accessible name, in the two directions. |
|
|
1531
|
+
| `expandLabel` | `string` | | `Desplegar el panel` | |
|
|
1532
|
+
| `mark` | `ReactNode` | | | What `brand` becomes in the rail. Usually the isotype with no wordmark. |
|
|
1533
|
+
| `onCollapsedChange` | `(collapsed: boolean) => void` | | | Called with what the state should become. With it, the toggle appears; with `collapsed` alone the sidebar is a rail with no way out of it, which is a legitimate layout and not an accident. |
|
|
1534
|
+
| `user` | `ReactNode` | | | Who is signed in, at the bottom above the version. A slot, because an avatar needs a session and a sign-out route and the library takes no project infrastructure — the same reason `Nav`'s user menu goes in `actions`. |
|
|
1270
1535
|
| `version` | `ReactNode` | | | Version and branch, at the bottom. |
|
|
1271
1536
|
|
|
1272
1537
|
### Stat
|
|
@@ -1279,11 +1544,13 @@ A large metric: the number in the `stat` scale and its name underneath.
|
|
|
1279
1544
|
|
|
1280
1545
|
| prop | type | req. | default | what it does |
|
|
1281
1546
|
| --- | --- | --- | --- | --- |
|
|
1547
|
+
| `delta` | `StatDelta` | | | How the number moved since last time. |
|
|
1282
1548
|
| `description` | `ReactNode` | | | The standfirst: the nuance the number alone does not give. «12 aplicaciones» does not say whether that is a lot, and this is where that gets said. |
|
|
1283
|
-
| `icon` | `ReactNode` | | | Glyph
|
|
1549
|
+
| `icon` | `ReactNode` | | | Glyph in a tinted circle, in the corner opposite the title. At 1em, and it inherits `currentColor` from the badge, so it takes the tone without being tinted separately. |
|
|
1284
1550
|
| `label` | `ReactNode` | yes | | What is being counted. It goes in mono small caps. |
|
|
1285
1551
|
| `progress` | `number` | | | With `progress`, the metric reads as progress and adds the bar. |
|
|
1286
|
-
| `
|
|
1552
|
+
| `spark` | `ReactNode` | | | The number's shape over time, under it. A `ReactNode` and not a data prop: a sparkline needs a charting library, and this component lives in the barrel that four projects install. The one project that draws them passes its own, exactly like `icon`. |
|
|
1553
|
+
| `tone` | `"neutral" \| "alert" \| "achievement"` | | `neutral` | `alert` ONLY when the number is the problem, and `achievement` when it is the opposite — the diplomas issued, the modules finished. The two paint the same sand today and they are still two names: a system that names by meaning cannot make «this is bad» the only way to say «this stands out». See `docs/decisions.md` § 28. |
|
|
1287
1554
|
| `value` | `ReactNode` | yes | | The number, already formatted. The library imposes no locale. |
|
|
1288
1555
|
|
|
1289
1556
|
### TalkCard
|
|
@@ -1315,7 +1582,7 @@ The control that was missing. The library defined the whole theming system and e
|
|
|
1315
1582
|
|
|
1316
1583
|
| prop | type | req. | default | what it does |
|
|
1317
1584
|
| --- | --- | --- | --- | --- |
|
|
1318
|
-
| `label` | `string` | | `Cambiar de
|
|
1585
|
+
| `label` | `string` | | `Cambiar de tema` | Accessible name. The button has no visible text, so it is the only thing naming it. |
|
|
1319
1586
|
| `onThemeChange` | `(theme: Theme) => void` | | | Fires with whichever theme ended up set, in case the project wants to record it. |
|
|
1320
1587
|
| `size` | `"sm" \| "md" \| "lg" \| "icon" \| "icon-sm"` | | `icon` | |
|
|
1321
1588
|
| `variant` | `"primary" \| "conversion" \| "secondary" \| "tertiary" \| "destructive" \| "destructiveOutline"` | | `secondary` | |
|
|
@@ -1389,6 +1656,59 @@ Tiburoncín's head, with an expression.
|
|
|
1389
1656
|
| `basePath` | `string` | | `ASSETS_PATH` | |
|
|
1390
1657
|
| `expression` | `"annoyed" \| "confused" \| "hearts" \| "laughing" \| "shades" \| "waiting" \| "wink"` | yes | | |
|
|
1391
1658
|
|
|
1659
|
+
## Social icons
|
|
1660
|
+
|
|
1661
|
+
Imported from `@eduardoalvarez/arrecife/social` · or grouped as `social` from the root. 9 exports.
|
|
1662
|
+
|
|
1663
|
+
### GitHub, LinkedIn, X, Instagram, Discord, YouTube, Rss, Email, Newsletter
|
|
1664
|
+
|
|
1665
|
+
Source: `src/social/index.tsx`
|
|
1666
|
+
|
|
1667
|
+
**GitHub**
|
|
1668
|
+
- No own props: it passes through those of the element or primitive it wraps.
|
|
1669
|
+
|
|
1670
|
+
**LinkedIn**
|
|
1671
|
+
- No own props: it passes through those of the element or primitive it wraps.
|
|
1672
|
+
|
|
1673
|
+
**X**
|
|
1674
|
+
- No own props: it passes through those of the element or primitive it wraps.
|
|
1675
|
+
|
|
1676
|
+
**Instagram**
|
|
1677
|
+
- No own props: it passes through those of the element or primitive it wraps.
|
|
1678
|
+
|
|
1679
|
+
**Discord**
|
|
1680
|
+
- No own props: it passes through those of the element or primitive it wraps.
|
|
1681
|
+
|
|
1682
|
+
**YouTube**
|
|
1683
|
+
- No own props: it passes through those of the element or primitive it wraps.
|
|
1684
|
+
|
|
1685
|
+
**Rss**
|
|
1686
|
+
- No own props: it passes through those of the element or primitive it wraps.
|
|
1687
|
+
|
|
1688
|
+
**Email**
|
|
1689
|
+
- No own props: it passes through those of the element or primitive it wraps.
|
|
1690
|
+
|
|
1691
|
+
**Newsletter**
|
|
1692
|
+
The newsletter. It plays the same role as `Rss` — a way to follow, not a social network — which is why it belongs in this catalogue and does not open the door to an icon library.
|
|
1693
|
+
|
|
1694
|
+
- No own props: it passes through those of the element or primitive it wraps.
|
|
1695
|
+
|
|
1696
|
+
## Icons
|
|
1697
|
+
|
|
1698
|
+
Imported from `@eduardoalvarez/arrecife/icons` · requires `@phosphor-icons/react`. 1 exports.
|
|
1699
|
+
|
|
1700
|
+
### Icon
|
|
1701
|
+
|
|
1702
|
+
Source: `src/icons/index.tsx`
|
|
1703
|
+
|
|
1704
|
+
- Extends: `Omit<PhosphorIconProps, 'size' \| 'weight' \| 'ref'>`
|
|
1705
|
+
|
|
1706
|
+
| prop | type | req. | default | what it does |
|
|
1707
|
+
| --- | --- | --- | --- | --- |
|
|
1708
|
+
| `as` | `Icon` | yes | | The Phosphor icon itself, passed as a component: `<Icon as={Books} />`. |
|
|
1709
|
+
| `label` | `string` | | | The accessible name. WITHOUT it the icon is decorative and gets `aria-hidden`, which is the right default: most icons sit beside their own label and announcing them twice is noise. |
|
|
1710
|
+
| `tone` | `"action" \| "current" \| "quiet"` | | `action` | WHAT THE ICON IS DOING, which is what picks the weight. Three values, and there is no fourth: `action` is the default and the system's line, `current` is the one of a set you are on, `quiet` is furniture that is not a control. `weight` is deliberately not a prop — see `TONE_WEIGHT`. |
|
|
1711
|
+
|
|
1392
1712
|
## Forms
|
|
1393
1713
|
|
|
1394
1714
|
Imported from `@eduardoalvarez/arrecife/form` · requires `react-hook-form`. 7 exports.
|
|
@@ -1521,7 +1841,7 @@ it: if the code does not mount React, that subpath is the one to import.
|
|
|
1521
1841
|
| `radius` | `{ readonly chip: 6; readonly control: 10; readonly card: 14; readonly panel: 16; readonly pill: 999; }` | |
|
|
1522
1842
|
| `series` | `{ readonly dark: readonly ["#35D6C0", "#F2A65A", "#3E7CB1", "#71919C"]; readonly light: readonly ["#0D7C6F", "#A65B27", "#3E7CB1", "#626A75"]; }` | The chart series palette. FOUR, for the same reason as the syntax palette: the system communicates with color and border, not with chromatic noise. |
|
|
1523
1843
|
| `shadow` | `{ readonly standard: "0 1px 2px rgba(0, 0, 0, 0.35)"; }` | A single level. There is no elevation scale. |
|
|
1524
|
-
| `size` | `{ readonly nav: 64; readonly content: 760; readonly wide: 1180; }` | |
|
|
1844
|
+
| `size` | `{ readonly nav: 64; readonly navCompact: 56; readonly sidebar: 256; readonly sidebarRail: 56; readonly content: 760; readonly wide: 1180; }` | |
|
|
1525
1845
|
| `spacing` | `{ readonly stepXs: 8; readonly stepSm: 12; readonly stepMd: 16; readonly stepLg: 26; readonly stepXl: 40; readonly section: 96; }` | Page rhythm. All five steps carry `step` in the name, and that is not decoration: it is the fix for a bug that never surfaced anywhere. |
|
|
1526
1846
|
| `syntax` | `{ background, identifier, literal, keyword, comment, invalid }` | The syntax highlighting palette. |
|
|
1527
1847
|
| `tagline` | `{ long, short, en }` | |
|
|
@@ -1530,6 +1850,10 @@ it: if the code does not mount React, that subpath is the one to import.
|
|
|
1530
1850
|
|
|
1531
1851
|
Types (13): `BrandToken`, `ColorMode`, `ColorToken`, `ControlToken`, `FontToken`, `GradientToken`, `RadiusToken`, `SeriesToken`, `SizeToken`, `SpacingToken`, `SyntaxToken`, `Tokens`, `TypeScaleToken`.
|
|
1532
1852
|
|
|
1853
|
+
### `@eduardoalvarez/arrecife/social`
|
|
1854
|
+
|
|
1855
|
+
Types (1): `SocialIconProps`.
|
|
1856
|
+
|
|
1533
1857
|
### `@eduardoalvarez/arrecife/theme`
|
|
1534
1858
|
|
|
1535
1859
|
| export | type | what it is |
|
|
@@ -1561,6 +1885,15 @@ Types (2): `Theme`, `ThemeOptions`.
|
|
|
1561
1885
|
|
|
1562
1886
|
Types (8): `Background`, `Face`, `Fin`, `IsotypeProps`, `LogoProps`, `MascotFaceProps`, `MascotProps`, `Pose`.
|
|
1563
1887
|
|
|
1888
|
+
### `@eduardoalvarez/arrecife/icons`
|
|
1889
|
+
|
|
1890
|
+
| export | type | what it is |
|
|
1891
|
+
| --- | --- | --- |
|
|
1892
|
+
| `ICON_WEIGHT` | `"light" \| "fill" \| "thin" \| "regular" \| "bold" \| "duotone"` | Phosphor's own name for the system's line. It is what `tone="action"` resolves to. |
|
|
1893
|
+
| `TONE_WEIGHT` | `Record<IconTone, IconWeight>` | The three roles, and the weight each one is drawn at. This is the whole of the weight axis: Phosphor ships six and this system reads three, because the other three — `thin`, `bold`, `duotone` — have no role behind them here. |
|
|
1894
|
+
|
|
1895
|
+
Types (2): `IconProps`, `IconTone`.
|
|
1896
|
+
|
|
1564
1897
|
### `@eduardoalvarez/arrecife/shiki`
|
|
1565
1898
|
|
|
1566
1899
|
| export | type | what it is |
|
|
@@ -1602,11 +1935,11 @@ Types (6): `ArticleData`, `BaseData`, `CourseData`, `DefaultData`, `SatoriNode`,
|
|
|
1602
1935
|
| export | type | what it is |
|
|
1603
1936
|
| --- | --- | --- |
|
|
1604
1937
|
| `cn` | `(...inputs: ClassValue[]): string` | |
|
|
1605
|
-
| `social` | `typeof import("src/
|
|
1938
|
+
| `social` | `typeof import("src/social/index")` | |
|
|
1606
1939
|
| `toast` | `(message: ReactNode, options?: ToastOptions \| undefined): string` | Fires a notice. It returns its id, which is what you keep in order to close it by hand — the «guardando…» case that gets replaced when the request finishes. |
|
|
1607
1940
|
| `useTheme` | `(): Theme` | The theme set right now, for a project that needs to branch in React — a different logo per mode, an image with no light version. |
|
|
1608
1941
|
|
|
1609
|
-
Types (
|
|
1942
|
+
Types (62): `AccordionProps`, `AccordionTriggerProps`, `AlertProps`, `ArticleCardProps`, `AudioPlayerMode`, `AudioPlayerProps`, `AuthorCardProps`, `AvatarProps`, `AvatarUploadProps`, `BadgeProps`, `BlockquoteProps`, `BreadcrumbProps`, `ButtonProps`, `CalendarEvent`, `CalendarProps`, `CategoryBadgeProps`, `CheckboxProps`, `CodeBlockProps`, `CodeProps`, `CourseCardProps`, `Crumb`, `DateFieldProps`, `EmptyStateProps`, `EventCalendarProps`, `FooterLinkProps`, `FooterProps`, `HeroProps`, `InputProps`, `LabelProps`, `LinkRowProps`, `MetricBadgeProps`, `NavItemProps`, `NavProps`, `NewsletterFormProps`, `NewsletterState`, `PageHeaderProps`, `PaginationLinkProps`, `PopoverContentProps`, `ProgressProps`, `RadioGroupItemProps`, `RadioGroupProps`, `ScrollingProgressBarProps`, `SeparatorProps`, `SheetContentProps`, `SidebarGroupProps`, `SidebarItemProps`, `SidebarNavProps`, `SkeletonProps`, `SocialLink`, `StatDelta`, `StatProps`, `SwitchProps`, `TableOfContentsProps`, `TabsProps`, `TalkCardProps`, `TextProps`, `TextareaProps`, `ThemeToggleProps`, `ToastOptions`, `ToastVariant`, `ToasterProps`, `TocEntry`.
|
|
1610
1943
|
|
|
1611
1944
|
# Where to look if this is not enough
|
|
1612
1945
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eduardoalvarez/arrecife",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "The component library of Eduardo Álvarez’s visual identity",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Eduardo Esteban Álvarez Castañeda <soy@eduardoalvarez.dev>",
|
|
@@ -49,6 +49,16 @@
|
|
|
49
49
|
"import": "./dist/brand/index.js",
|
|
50
50
|
"require": "./dist/brand/index.cjs"
|
|
51
51
|
},
|
|
52
|
+
"./social": {
|
|
53
|
+
"types": "./dist/social/index.d.ts",
|
|
54
|
+
"import": "./dist/social/index.js",
|
|
55
|
+
"require": "./dist/social/index.cjs"
|
|
56
|
+
},
|
|
57
|
+
"./icons": {
|
|
58
|
+
"types": "./dist/icons/index.d.ts",
|
|
59
|
+
"import": "./dist/icons/index.js",
|
|
60
|
+
"require": "./dist/icons/index.cjs"
|
|
61
|
+
},
|
|
52
62
|
"./og": {
|
|
53
63
|
"types": "./dist/og/index.d.ts",
|
|
54
64
|
"import": "./dist/og/index.js",
|
|
@@ -73,16 +83,23 @@
|
|
|
73
83
|
"./assets/*": "./assets/*",
|
|
74
84
|
"./package.json": "./package.json"
|
|
75
85
|
},
|
|
86
|
+
"bin": {
|
|
87
|
+
"arrecife": "./dist/doctor.mjs"
|
|
88
|
+
},
|
|
76
89
|
"main": "./dist/index.cjs",
|
|
77
90
|
"module": "./dist/index.js",
|
|
78
91
|
"types": "./dist/index.d.ts",
|
|
79
92
|
"scripts": {
|
|
80
|
-
"build": "pnpm check:tokens && pnpm check:namespace && tsup && node scripts/add-use-client.mjs && pnpm build:tokens && pnpm build:llms",
|
|
93
|
+
"build": "pnpm check:tokens && pnpm check:namespace && tsup && node scripts/add-use-client.mjs && pnpm build:tokens && pnpm build:doctor && pnpm build:llms",
|
|
81
94
|
"build:tokens": "node scripts/build-tokens.mjs",
|
|
95
|
+
"build:doctor": "node scripts/build-doctor.mjs",
|
|
82
96
|
"build:llms": "node scripts/build-llms.mjs",
|
|
83
97
|
"check:tokens": "node scripts/check-tokens-purity.mjs",
|
|
84
98
|
"check:namespace": "node scripts/check-tokens-namespace.mjs",
|
|
85
99
|
"check:llms": "node scripts/build-llms.mjs --check",
|
|
100
|
+
"check:copy": "node scripts/check-copy-language.mjs",
|
|
101
|
+
"check:decisions": "node scripts/check-decisions.mjs",
|
|
102
|
+
"doctor": "node scripts/doctor.mjs",
|
|
86
103
|
"check:exports": "node scripts/check-package-exports.mjs",
|
|
87
104
|
"check:release": "node scripts/check-release-config.mjs",
|
|
88
105
|
"typecheck": "tsc --noEmit",
|
|
@@ -97,12 +114,16 @@
|
|
|
97
114
|
"test:light": "STORYBOOK_THEME=light vitest run --project storybook"
|
|
98
115
|
},
|
|
99
116
|
"peerDependencies": {
|
|
117
|
+
"@phosphor-icons/react": "^2.1.0",
|
|
100
118
|
"react": "^19.0.0",
|
|
101
119
|
"react-dom": "^19.0.0",
|
|
102
120
|
"react-hook-form": "^7.0.0",
|
|
103
121
|
"recharts": "^3.0.0"
|
|
104
122
|
},
|
|
105
123
|
"peerDependenciesMeta": {
|
|
124
|
+
"@phosphor-icons/react": {
|
|
125
|
+
"optional": true
|
|
126
|
+
},
|
|
106
127
|
"react-hook-form": {
|
|
107
128
|
"optional": true
|
|
108
129
|
},
|
|
@@ -112,6 +133,7 @@
|
|
|
112
133
|
},
|
|
113
134
|
"devDependencies": {
|
|
114
135
|
"@eslint/js": "^10.0.1",
|
|
136
|
+
"@phosphor-icons/react": "^2.1.10",
|
|
115
137
|
"@storybook/addon-a11y": "^10.5.10",
|
|
116
138
|
"@storybook/addon-docs": "^10.5.10",
|
|
117
139
|
"@storybook/addon-themes": "^10.5.10",
|