create-ailk 0.20.0 → 0.21.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/README.md +21 -1
- package/component-catalog.json +184 -6
- package/component-catalog.md +20 -9
- package/dist/apply-design.d.ts +9 -0
- package/dist/apply-design.js +78 -31
- package/dist/design-home.d.ts +54 -11
- package/dist/design-home.js +160 -22
- package/dist/lib/design-checks.d.ts +6 -1
- package/dist/lib/design-checks.js +23 -2
- package/dist/programmatic.js +44 -20
- package/dist/site-roster.d.ts +4 -2
- package/dist/site-roster.js +7 -5
- package/dist/starter-grid.js +16 -0
- package/dist/surfaces.js +11 -0
- package/dist/sync-routes.d.ts +28 -0
- package/dist/sync-routes.js +123 -1
- package/dist/update.d.ts +6 -1
- package/dist/update.js +120 -18
- package/package.json +3 -3
- package/site-templates/_base/ailk-template.json +2 -2
- package/site-templates/_base/content/en/WorkingAgreementPage/working-agreement.mdx +78 -0
- package/site-templates/designs/minimalism/DESIGN.md +1 -1
- package/site-templates/designs/minimalism/contact/local-business-service.mdx +23 -0
- package/site-templates/designs/minimalism/contact/organization-product.mdx +23 -0
- package/site-templates/designs/minimalism/contact/organization-service.mdx +23 -0
- package/site-templates/designs/minimalism/contact/person-service.mdx +23 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +11 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +34 -23
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +33 -23
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +33 -23
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +31 -21
- package/templates/README.md +26 -25
- package/templates/apps/api/CLAUDE.md +7 -3
- package/templates/apps/api/jest.config.cjs +1 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +26 -0
- package/templates/apps/api/src/services/project-listings.ts +6 -1
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +69 -61
- package/templates/apps/mcp/jest.config.cjs +1 -0
- package/templates/apps/web/CLAUDE.md +26 -1
- package/templates/apps/web/app/[locale]/about/[slug]/page.tsx +46 -0
- package/templates/apps/web/app/[locale]/about/__tests__/about-routes.test.tsx +350 -0
- package/templates/apps/web/app/[locale]/about/page.tsx +83 -1
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +7 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-magnet.test.ts +138 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-text.test.ts +17 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-magnet-page.test.tsx +347 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +73 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +5 -3
- package/templates/apps/web/app/[locale]/contact/contact-form-magnet.ts +77 -0
- package/templates/apps/web/app/[locale]/contact/contact-form-text.ts +2 -0
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +35 -3
- package/templates/apps/web/app/[locale]/contact/page.tsx +81 -9
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/layout.tsx +23 -2
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/working-agreement/__tests__/page.test.tsx +63 -0
- package/templates/apps/web/app/[locale]/working-agreement/page.tsx +41 -0
- package/templates/apps/web/jest.config.cjs +1 -0
- package/templates/apps/web/lib/__tests__/deck-page.test.ts +244 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +4 -2
- package/templates/apps/web/lib/deck-page.ts +186 -0
- package/templates/apps/web/messages/en.json +16 -5
- package/templates/database/CHANGELOG.md +9 -0
- package/templates/database/__tests__/seed.test.ts +39 -2
- package/templates/database/jest.config.cjs +1 -0
- package/templates/database/package.json +1 -1
- package/templates/database/seed.ts +29 -0
- package/templates/tools/jest/pin-timezone.cjs +34 -0
- package/versions.json +34 -34
package/README.md
CHANGED
|
@@ -250,6 +250,14 @@ hand-authored translations, so `sync-routes` reports a missing namespace
|
|
|
250
250
|
rather than attempting to merge JSON keys into it. Adding it is a manual
|
|
251
251
|
step, same as reading any other reported gap.
|
|
252
252
|
|
|
253
|
+
The site's structured-data test (`apps/web/lib/__tests__/structured-data.test.tsx`)
|
|
254
|
+
fails any route that neither renders through `renderPage` nor is listed in its
|
|
255
|
+
`NO_STRUCTURED_DATA_ROUTES`. When `--apply` adds a route the template exempts
|
|
256
|
+
there and the site has edited that test (its bytes differ from the hash in
|
|
257
|
+
`.ailk-template-files.json`), the report prints the exact template entry to
|
|
258
|
+
add for each added route, under `Also required`. The test itself is never
|
|
259
|
+
written; an untouched copy is `create-ailk update`'s to bring forward.
|
|
260
|
+
|
|
253
261
|
**The manifest.** `ROUTE_SINCE` in `src/surfaces.ts` maps every template route
|
|
254
262
|
directory (relative to `apps/web/app/[locale]`) to the `@working-theory/*`
|
|
255
263
|
fixed-group release line that first shipped it — the version a site pins, so
|
|
@@ -289,7 +297,7 @@ merge-file` against the recorded version's own copy as the base. A clean
|
|
|
289
297
|
merge keeps your edit AND the fix, and is reported as **Merged**. A
|
|
290
298
|
conflict leaves the file exactly as it was — never written with conflict
|
|
291
299
|
markers — and is reported under **Needs review** with both versions
|
|
292
|
-
named
|
|
300
|
+
named.
|
|
293
301
|
- A recordable file the running version adds that the site lacks is
|
|
294
302
|
**Added**, unless it sits under a route or directory the site deliberately
|
|
295
303
|
does not carry (a gated-off surface, a spoke exclusion, or a directory you
|
|
@@ -301,6 +309,18 @@ recorded (a module bundle's own file, say) when its bytes differ from the
|
|
|
301
309
|
running copy. Nothing the base scaffold did not write is ever touched. No
|
|
302
310
|
template change at all means `Already up to date` and zero files written.
|
|
303
311
|
|
|
312
|
+
**Tests are held back with the file they test.** When a file is left under
|
|
313
|
+
**Needs review** or **Skipped**, every template test file that imports it by a
|
|
314
|
+
relative import (`relay.test.ts` importing `../relay`, say) stays exactly as
|
|
315
|
+
the site has it, and its record entry keeps its old hash and version — so a
|
|
316
|
+
run never leaves a test from the new version exercising code from the old
|
|
317
|
+
one. Each is reported under a **Held back with `<file>`** heading. Reconcile
|
|
318
|
+
the file, then run `update` again to bring its tests forward; every other
|
|
319
|
+
file in the run still updates. A held test-support file (`__tests__/fixtures.ts`,
|
|
320
|
+
say) holds the tests importing it in turn. A file skipped because you deleted
|
|
321
|
+
it keeps its tests held on every run: delete those tests too, or restore the
|
|
322
|
+
file.
|
|
323
|
+
|
|
304
324
|
**A site scaffolded before this record existed** gets one built on its first
|
|
305
325
|
`update` run, from the `patternVersion` `.ailk-site-manifest.json` already
|
|
306
326
|
records — no separate command, no per-site setup. If that version predates
|
package/component-catalog.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"importPath": "@working-theory/ui/sections",
|
|
10
10
|
"rootBarrel": "@working-theory/ui",
|
|
11
11
|
"sourceRoot": "packages/ui/src/sections",
|
|
12
|
-
"count":
|
|
12
|
+
"count": 56
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"name": "blocks",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"importPath": "@working-theory/ui/blocks",
|
|
18
18
|
"rootBarrel": "@working-theory/ui",
|
|
19
19
|
"sourceRoot": "packages/ui/src/blocks",
|
|
20
|
-
"count":
|
|
20
|
+
"count": 106
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"name": "chrome",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"importPath": "@working-theory/ui/chrome",
|
|
26
26
|
"rootBarrel": "@working-theory/ui",
|
|
27
27
|
"sourceRoot": "packages/ui/src/chrome",
|
|
28
|
-
"count":
|
|
28
|
+
"count": 19
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"name": "primitives",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"importPath": "@working-theory/ui-scheduling",
|
|
90
90
|
"rootBarrel": "@working-theory/ui-scheduling",
|
|
91
91
|
"sourceRoot": "packages-paid/ui-scheduling/src/blocks",
|
|
92
|
-
"count":
|
|
92
|
+
"count": 6
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
95
|
"name": "signal-collectors-sections",
|
|
@@ -485,6 +485,17 @@
|
|
|
485
485
|
"descriptionGrade": "strong",
|
|
486
486
|
"sectionType": "items"
|
|
487
487
|
},
|
|
488
|
+
{
|
|
489
|
+
"name": "ItemsTileLinkIsland",
|
|
490
|
+
"tier": "sections",
|
|
491
|
+
"sourcePath": "packages/ui/src/sections/ItemsTileLinkIsland.tsx",
|
|
492
|
+
"importPath": "@working-theory/ui/sections",
|
|
493
|
+
"exported": false,
|
|
494
|
+
"description": "Makes a whole linked tile card its link's click target.",
|
|
495
|
+
"descriptionSource": "doc-comment",
|
|
496
|
+
"descriptionGrade": "strong",
|
|
497
|
+
"sectionType": null
|
|
498
|
+
},
|
|
488
499
|
{
|
|
489
500
|
"name": "LogoCloud",
|
|
490
501
|
"tier": "sections",
|
|
@@ -892,6 +903,17 @@
|
|
|
892
903
|
"descriptionGrade": "strong",
|
|
893
904
|
"sectionType": null
|
|
894
905
|
},
|
|
906
|
+
{
|
|
907
|
+
"name": "BlogSidebarBox",
|
|
908
|
+
"tier": "blocks",
|
|
909
|
+
"sourcePath": "packages/ui/src/blocks/BlogSidebarBox.tsx",
|
|
910
|
+
"importPath": "@working-theory/ui/blocks",
|
|
911
|
+
"exported": true,
|
|
912
|
+
"description": "Heading + text + one outlined button, authored on the blog index page's own content. Content is set on the blog index page's own frontmatter, never hard-coded.",
|
|
913
|
+
"descriptionSource": "barrel",
|
|
914
|
+
"descriptionGrade": "strong",
|
|
915
|
+
"sectionType": null
|
|
916
|
+
},
|
|
895
917
|
{
|
|
896
918
|
"name": "BrandLogo",
|
|
897
919
|
"tier": "blocks",
|
|
@@ -1453,6 +1475,17 @@
|
|
|
1453
1475
|
"descriptionGrade": "strong",
|
|
1454
1476
|
"sectionType": null
|
|
1455
1477
|
},
|
|
1478
|
+
{
|
|
1479
|
+
"name": "PostArchiveRow",
|
|
1480
|
+
"tier": "blocks",
|
|
1481
|
+
"sourcePath": "packages/ui/src/blocks/PostArchiveRow.tsx",
|
|
1482
|
+
"importPath": "@working-theory/ui/blocks",
|
|
1483
|
+
"exported": true,
|
|
1484
|
+
"description": "One \"Previous posts\" row: title link + meta, host-placed `Separator` between rows. Draws no divider of its own (border convention — the host places `Separator` between rows, as BlogList already does for PostRow).",
|
|
1485
|
+
"descriptionSource": "barrel",
|
|
1486
|
+
"descriptionGrade": "strong",
|
|
1487
|
+
"sectionType": null
|
|
1488
|
+
},
|
|
1456
1489
|
{
|
|
1457
1490
|
"name": "PostCard",
|
|
1458
1491
|
"tier": "blocks",
|
|
@@ -1464,6 +1497,17 @@
|
|
|
1464
1497
|
"descriptionGrade": "weak",
|
|
1465
1498
|
"sectionType": null
|
|
1466
1499
|
},
|
|
1500
|
+
{
|
|
1501
|
+
"name": "PostMetaLine",
|
|
1502
|
+
"tier": "blocks",
|
|
1503
|
+
"sourcePath": "packages/ui/src/blocks/PostMetaLine.tsx",
|
|
1504
|
+
"importPath": "@working-theory/ui/blocks",
|
|
1505
|
+
"exported": true,
|
|
1506
|
+
"description": "`<tag> · <date>` meta line, either half optional (C4). Shows the tag alone, the date alone, or both joined by a middot; renders nothing with neither.",
|
|
1507
|
+
"descriptionSource": "barrel",
|
|
1508
|
+
"descriptionGrade": "strong",
|
|
1509
|
+
"sectionType": null
|
|
1510
|
+
},
|
|
1467
1511
|
{
|
|
1468
1512
|
"name": "PostRow",
|
|
1469
1513
|
"tier": "blocks",
|
|
@@ -1475,6 +1519,17 @@
|
|
|
1475
1519
|
"descriptionGrade": "strong",
|
|
1476
1520
|
"sectionType": null
|
|
1477
1521
|
},
|
|
1522
|
+
{
|
|
1523
|
+
"name": "PostTeaser",
|
|
1524
|
+
"tier": "blocks",
|
|
1525
|
+
"sourcePath": "packages/ui/src/blocks/PostTeaser.tsx",
|
|
1526
|
+
"importPath": "@working-theory/ui/blocks",
|
|
1527
|
+
"exported": true,
|
|
1528
|
+
"description": "The featured post (`size=\"lg\"`) and \"Latest posts\" grid card (`size=\"md\"`); no cover renders no placeholder. Composes MediaFigure + PostMetaLine + primitives. No author byline (C7). RSC: no hooks or browser APIs.",
|
|
1529
|
+
"descriptionSource": "barrel",
|
|
1530
|
+
"descriptionGrade": "weak",
|
|
1531
|
+
"sectionType": null
|
|
1532
|
+
},
|
|
1478
1533
|
{
|
|
1479
1534
|
"name": "PricingExtraTierRow",
|
|
1480
1535
|
"tier": "blocks",
|
|
@@ -1750,6 +1805,17 @@
|
|
|
1750
1805
|
"descriptionGrade": "strong",
|
|
1751
1806
|
"sectionType": null
|
|
1752
1807
|
},
|
|
1808
|
+
{
|
|
1809
|
+
"name": "TopicChips",
|
|
1810
|
+
"tier": "blocks",
|
|
1811
|
+
"sourcePath": "packages/ui/src/blocks/TopicChips.tsx",
|
|
1812
|
+
"importPath": "@working-theory/ui/blocks",
|
|
1813
|
+
"exported": true,
|
|
1814
|
+
"description": "\"All\" plus one chip per tag, each a real server-rendered link — never a client-side filter — with the current page's chip marked `aria-current=\"page\"` / `data-current=\"true\"` in the served HTML. Composes Button (asChild) + Link; RSC, no client state.",
|
|
1815
|
+
"descriptionSource": "doc-comment",
|
|
1816
|
+
"descriptionGrade": "weak",
|
|
1817
|
+
"sectionType": null
|
|
1818
|
+
},
|
|
1753
1819
|
{
|
|
1754
1820
|
"name": "UpgradeDialog",
|
|
1755
1821
|
"tier": "blocks",
|
|
@@ -1959,6 +2025,17 @@
|
|
|
1959
2025
|
"descriptionGrade": "strong",
|
|
1960
2026
|
"sectionType": null
|
|
1961
2027
|
},
|
|
2028
|
+
{
|
|
2029
|
+
"name": "NavBackLink",
|
|
2030
|
+
"tier": "chrome",
|
|
2031
|
+
"sourcePath": "packages/ui/src/chrome/NavBackLink.tsx",
|
|
2032
|
+
"importPath": "@working-theory/ui/chrome",
|
|
2033
|
+
"exported": true,
|
|
2034
|
+
"description": "The bare header's back arrow, deck-return-aware.",
|
|
2035
|
+
"descriptionSource": "doc-comment",
|
|
2036
|
+
"descriptionGrade": "weak",
|
|
2037
|
+
"sectionType": null
|
|
2038
|
+
},
|
|
1962
2039
|
{
|
|
1963
2040
|
"name": "NavMobileMenu",
|
|
1964
2041
|
"tier": "chrome",
|
|
@@ -3235,6 +3312,17 @@
|
|
|
3235
3312
|
"descriptionGrade": "strong",
|
|
3236
3313
|
"sectionType": null
|
|
3237
3314
|
},
|
|
3315
|
+
{
|
|
3316
|
+
"name": "BookingProfileHeader",
|
|
3317
|
+
"tier": "scheduling-blocks",
|
|
3318
|
+
"sourcePath": "packages-paid/ui-scheduling/src/blocks/BookingProfileHeader.tsx",
|
|
3319
|
+
"importPath": "@working-theory/ui-scheduling",
|
|
3320
|
+
"exported": true,
|
|
3321
|
+
"description": "The /meet hub's opening header. The Cal.com / Calendly profile shape: whose calendar this is, then one line saying what to do here. A centered portrait over a single h1, and nothing beneath it — the booker cards below carry each event's own title, so a subtitle here would only repeat them.",
|
|
3322
|
+
"descriptionSource": "doc-comment",
|
|
3323
|
+
"descriptionGrade": "strong",
|
|
3324
|
+
"sectionType": null
|
|
3325
|
+
},
|
|
3238
3326
|
{
|
|
3239
3327
|
"name": "FlowStepper",
|
|
3240
3328
|
"tier": "signal-collectors-sections",
|
|
@@ -5109,6 +5197,10 @@
|
|
|
5109
5197
|
},
|
|
5110
5198
|
"columns": {
|
|
5111
5199
|
"anyOf": [
|
|
5200
|
+
{
|
|
5201
|
+
"type": "number",
|
|
5202
|
+
"const": 1
|
|
5203
|
+
},
|
|
5112
5204
|
{
|
|
5113
5205
|
"type": "number",
|
|
5114
5206
|
"const": 2
|
|
@@ -6660,6 +6752,20 @@
|
|
|
6660
6752
|
},
|
|
6661
6753
|
"annualBadge": {
|
|
6662
6754
|
"type": "string"
|
|
6755
|
+
},
|
|
6756
|
+
"priceSubheadAccent": {
|
|
6757
|
+
"type": "string"
|
|
6758
|
+
},
|
|
6759
|
+
"priceSubheadAccentTone": {
|
|
6760
|
+
"type": "string",
|
|
6761
|
+
"enum": [
|
|
6762
|
+
"default",
|
|
6763
|
+
"muted",
|
|
6764
|
+
"brand",
|
|
6765
|
+
"success",
|
|
6766
|
+
"danger",
|
|
6767
|
+
"warning"
|
|
6768
|
+
]
|
|
6663
6769
|
}
|
|
6664
6770
|
},
|
|
6665
6771
|
"required": [
|
|
@@ -6878,6 +6984,20 @@
|
|
|
6878
6984
|
},
|
|
6879
6985
|
"annualBadge": {
|
|
6880
6986
|
"type": "string"
|
|
6987
|
+
},
|
|
6988
|
+
"priceSubheadAccent": {
|
|
6989
|
+
"type": "string"
|
|
6990
|
+
},
|
|
6991
|
+
"priceSubheadAccentTone": {
|
|
6992
|
+
"type": "string",
|
|
6993
|
+
"enum": [
|
|
6994
|
+
"default",
|
|
6995
|
+
"muted",
|
|
6996
|
+
"brand",
|
|
6997
|
+
"success",
|
|
6998
|
+
"danger",
|
|
6999
|
+
"warning"
|
|
7000
|
+
]
|
|
6881
7001
|
}
|
|
6882
7002
|
},
|
|
6883
7003
|
"required": [
|
|
@@ -9045,7 +9165,8 @@
|
|
|
9045
9165
|
"enum": [
|
|
9046
9166
|
"with-testimonial",
|
|
9047
9167
|
"split-with-pattern",
|
|
9048
|
-
"card"
|
|
9168
|
+
"card",
|
|
9169
|
+
"column"
|
|
9049
9170
|
]
|
|
9050
9171
|
},
|
|
9051
9172
|
"pattern": {
|
|
@@ -9733,11 +9854,68 @@
|
|
|
9733
9854
|
"baseUrl"
|
|
9734
9855
|
]
|
|
9735
9856
|
},
|
|
9857
|
+
"topics": {
|
|
9858
|
+
"type": "array",
|
|
9859
|
+
"items": {
|
|
9860
|
+
"type": "object",
|
|
9861
|
+
"properties": {
|
|
9862
|
+
"label": {
|
|
9863
|
+
"type": "string"
|
|
9864
|
+
},
|
|
9865
|
+
"href": {
|
|
9866
|
+
"type": "string"
|
|
9867
|
+
},
|
|
9868
|
+
"current": {
|
|
9869
|
+
"type": "boolean"
|
|
9870
|
+
}
|
|
9871
|
+
},
|
|
9872
|
+
"required": [
|
|
9873
|
+
"label",
|
|
9874
|
+
"href"
|
|
9875
|
+
]
|
|
9876
|
+
}
|
|
9877
|
+
},
|
|
9878
|
+
"sidebar": {
|
|
9879
|
+
"maxItems": 3,
|
|
9880
|
+
"type": "array",
|
|
9881
|
+
"items": {
|
|
9882
|
+
"type": "object",
|
|
9883
|
+
"properties": {
|
|
9884
|
+
"heading": {
|
|
9885
|
+
"type": "string"
|
|
9886
|
+
},
|
|
9887
|
+
"text": {
|
|
9888
|
+
"type": "string"
|
|
9889
|
+
},
|
|
9890
|
+
"cta": {
|
|
9891
|
+
"type": "object",
|
|
9892
|
+
"properties": {
|
|
9893
|
+
"label": {
|
|
9894
|
+
"type": "string"
|
|
9895
|
+
},
|
|
9896
|
+
"href": {
|
|
9897
|
+
"type": "string"
|
|
9898
|
+
}
|
|
9899
|
+
},
|
|
9900
|
+
"required": [
|
|
9901
|
+
"label",
|
|
9902
|
+
"href"
|
|
9903
|
+
]
|
|
9904
|
+
}
|
|
9905
|
+
},
|
|
9906
|
+
"required": [
|
|
9907
|
+
"heading",
|
|
9908
|
+
"text",
|
|
9909
|
+
"cta"
|
|
9910
|
+
]
|
|
9911
|
+
}
|
|
9912
|
+
},
|
|
9736
9913
|
"variant": {
|
|
9737
9914
|
"type": "string",
|
|
9738
9915
|
"enum": [
|
|
9739
9916
|
"list",
|
|
9740
|
-
"grid"
|
|
9917
|
+
"grid",
|
|
9918
|
+
"index"
|
|
9741
9919
|
]
|
|
9742
9920
|
}
|
|
9743
9921
|
},
|
package/component-catalog.md
CHANGED
|
@@ -15,13 +15,13 @@ The component inventory of `@working-theory/ui` and the shells of `@working-theo
|
|
|
15
15
|
3. Check the Primitives, Panels and Shells tables too — a low-level control, a collapsible layout container, or a route-level frame lives there, not under Sections or Blocks.
|
|
16
16
|
4. Only then build. If you do build, you are declaring the capability is genuinely absent.
|
|
17
17
|
|
|
18
|
-
Inventory: **
|
|
18
|
+
Inventory: **319 component files** across 16 tiers — 56 sections, 106 blocks, 19 chrome, 79 primitives, 6 panels, 8 shells, 5 docs-blog-blocks, 1 docs-blog-chrome, 2 docs-blog-shells, 2 scheduling-sections, 6 scheduling-blocks, 5 signal-collectors-sections, 9 signal-collectors-blocks, 2 commerce-sections, 12 commerce-blocks, 1 commerce-panels. 316 distinct names: `SchedulerEmbed`, `Separator`, `Tabs` exist in more than one tier as genuinely different components, listed once per tier with its own source path.
|
|
19
19
|
|
|
20
|
-
Description coverage: **
|
|
20
|
+
Description coverage: **315/319** components carry a capability description derived from source — 44 from the section registry's hand-authored when-to-use text, 236 from the component's own doc-comment header, 35 from its tier barrel's roster line. **4** have none; they are listed under [Undescribed components](#undescribed-components) rather than given a sentence invented from their name.
|
|
21
21
|
|
|
22
|
-
Of those, **
|
|
22
|
+
Of those, **281** are *strong* — a capability sentence you could match a requirement against — and **34** are *weak*: either one short clause, or a long one that spends itself on wiring (client boundaries, class names, which primitives it composes) instead of on what the thing is for. Weak rows are marked `(weak)` and listed in full under [Weak descriptions](#weak-descriptions). Coverage is 99%, but **findable-without-luck coverage is 88%**.
|
|
23
23
|
|
|
24
|
-
Per tier, strong out of total: **Sections**
|
|
24
|
+
Per tier, strong out of total: **Sections** 55/56 · **Blocks** 98/106 · **Chrome** 10/19 · **Primitives** 64/79 (4 undescribed) · **Panels** 5/6 · **Shells** 7/8 · **Docs + Blog Blocks** 5/5 · **Docs + Blog Chrome** 1/1 · **Docs + Blog Shells** 0/2 · **Scheduling Sections** 2/2 · **Scheduling Blocks** 6/6 · **Signal-Collectors Sections** 5/5 · **Signal-Collectors Blocks** 8/9 · **Commerce Sections** 2/2 · **Commerce Blocks** 12/12 · **Commerce Panels** 1/1. A tier low on this line is a tier where a capability search is most likely to come up empty on something that exists.
|
|
25
25
|
|
|
26
26
|
That grade is **mechanical**. It counts what it can measure — how much a description adds beyond the component's own name, how much of it is spent on wiring, whether the extraction came out damaged — and it cannot tell a fluent paragraph about the wrong subject from a useful one. A person reading these tables will find more rows unusable than the weak count admits. Treat it as a floor on the problem, not a measurement of it, and read the source before concluding a capability is absent.
|
|
27
27
|
|
|
@@ -53,7 +53,7 @@ The left column is search vocabulary — how a person phrases the need. It is ha
|
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
|
-
## Sections (
|
|
56
|
+
## Sections (56)
|
|
57
57
|
|
|
58
58
|
Page-level content bands. Most are MDX-driven (authored by `type` in page frontmatter and dispatched by `SectionRenderer`); a few are composed directly in a route.
|
|
59
59
|
|
|
@@ -93,6 +93,7 @@ Import: `import { X } from "@working-theory/ui/sections";` (or from the `@workin
|
|
|
93
93
|
| `HeroPromptCapture` | The Hero `promptCapture` opt-in's wiring. Composes the two new blocks — `PromptCaptureCard` (the chat-style card) and `SuggestionChipCarousel` (the one-expanded-slot chip row) — and owns the ONE piece of state they share: the typed text. A chip click writes into it; the card renders and edits it; submit carries it onward. | `import { HeroPromptCapture } from "@working-theory/ui/sections"` |
|
|
94
94
|
| `HeroQuickSearch` | Surfaces the existing ⌘K quick-search as an inline trigger inside the hero CTA cluster (Chassis 2). It does NOT re-roll a search input: it composes the SearchInputTrigger primitive (an input-style control at CTA height) plus the Command palette primitive, so there is ONE search mechanism. The nav's compact 24px ⌘K pill stays as-is — the hero reads as a search INPUT, matching the 44px "Get Started" CTA. | internal — compose from `packages/ui/src/sections/HeroQuickSearch.tsx` |
|
|
95
95
|
| `Items` | A general-purpose card/items grid — use for services, use cases, or any homogeneous list of cards. | MDX `type: items` · `import { Items } from "@working-theory/ui/sections"` |
|
|
96
|
+
| `ItemsTileLinkIsland` | Makes a whole linked tile card its link's click target. | internal — compose from `packages/ui/src/sections/ItemsTileLinkIsland.tsx` |
|
|
96
97
|
| `LogoCloud` | A customer/partner logo wall — use for trust-by-association social proof. | MDX `type: logoCloud` · `import { LogoCloud } from "@working-theory/ui/sections"` |
|
|
97
98
|
| `MDXContent` | The keystone the docs route and blog both render their compiled MDX through. | `import { MDXContent } from "@working-theory/ui/sections"` |
|
|
98
99
|
| `MediaBand` | A single full-width image band — use for the 1-up visual moment Gallery's 2-column minimum can't express (e.g. between pricing plan columns); renders a labeled placeholder until a real image is supplied. | MDX `type: media-band` · `import { MediaBand } from "@working-theory/ui/sections"` |
|
|
@@ -119,7 +120,7 @@ Import: `import { X } from "@working-theory/ui/sections";` (or from the `@workin
|
|
|
119
120
|
|
|
120
121
|
---
|
|
121
122
|
|
|
122
|
-
## Blocks (
|
|
123
|
+
## Blocks (106)
|
|
123
124
|
|
|
124
125
|
Intermediate composition tiles — the pieces sections are built from. Compose primitives and panels; never import a section.
|
|
125
126
|
|
|
@@ -141,6 +142,7 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
141
142
|
| `BadgeRow` | Horizontal cluster of static badge labels used by Hero and Feature section families for `data.badge` and tag-list patterns. | `import { BadgeRow } from "@working-theory/ui/blocks"` |
|
|
142
143
|
| `BillingToggle` | Monthly / Annual billing period toggle for the Pricing section. Purely presentational — click handlers come from the parent (Pricing section). No "use client" needed at the block level; the parent Pricing section is "use client" and passes the callbacks down. | `import { BillingToggle } from "@working-theory/ui/blocks"` |
|
|
143
144
|
| `BlogPostHeader` | Layout: the better-auth sticky left rail — eyebrow ← back-link · decorative title · author byline · date/reading-time meta · tags. Per the title here is DECORATIVE (aria-hidden): the semantic `<h1>` is rendered atop the right content column by `BlogPost` (bodyOnly), so the page keeps exactly one heading. | `import { BlogPostHeader } from "@working-theory/ui/blocks"` |
|
|
145
|
+
| `BlogSidebarBox` | Heading + text + one outlined button, authored on the blog index page's own content. Content is set on the blog index page's own frontmatter, never hard-coded. | `import { BlogSidebarBox } from "@working-theory/ui/blocks"` |
|
|
144
146
|
| `BrandLogo` | Brand identity lockup (mark + wordmark + badge slot) as a home link. Brand identity lockup for Nav, Footer, and other surfaces. | `import { BrandLogo } from "@working-theory/ui/blocks"` |
|
|
145
147
|
| `Card` | The base surface-chrome block the section tier composes instead of hand-rolling `rounded + hairline border + surface + p-card` (7× duplicated at time). A block owns its visual identity: it looks the same everywhere it is composed, and a higher tier SELECTS a look via `variant` — it never patches via className. | `import { Card } from "@working-theory/ui/blocks"` |
|
|
146
148
|
| `ChoiceCard` | Onboarding "Is this you?" disambiguation card — reimplements the ploy.ai persona-disambiguation capture: a researched candidate option vs a "none of these are me" option, confirmed by the user ("a human-input seam the user answers to orient the agent"). Purely presentational and props-driven: renders options + an optional "none of these" option + a confirm action, disabled until a selection is made. | `import { ChoiceCard } from "@working-theory/ui/blocks"` |
|
|
@@ -193,8 +195,11 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
193
195
|
| `PageHeaderSwitcher` | Header-owned context-switcher island (DropdownMenu-backed). Header-owned segment switcher rendered inside PageHeader's `switcher` slot. Composes DropdownMenu (Radix-backed — positioning, click-outside, Escape, focus management, and roving keyboard nav all come for free). | `import { PageHeaderSwitcher } from "@working-theory/ui/blocks"` |
|
|
194
196
|
| `PairingCard` | Quiet card naming a matched WaitlistRecommendation pairing: both resolved offer names + the resolved reason, joined against a caller-supplied offers[] by key. | `import { PairingCard } from "@working-theory/ui/blocks"` |
|
|
195
197
|
| `PhoneNumberField` | Single-box combo phone input for the "tel" field kind (supersedes the two-segment country-Select + number-Input layout). | `import { PhoneNumberField } from "@working-theory/ui/blocks"` |
|
|
198
|
+
| `PostArchiveRow` | One "Previous posts" row: title link + meta, host-placed `Separator` between rows. Draws no divider of its own (border convention — the host places `Separator` between rows, as BlogList already does for PostRow). | `import { PostArchiveRow } from "@working-theory/ui/blocks"` |
|
|
196
199
|
| `PostCard` | Same props as PostRow, a vertical arrangement. A single linked blog-index card (cover · date · reading time · title · excerpt · "Read more"). Tier 3 block; composes MediaFigure + primitives. RSC default. *(weak)* | `import { PostCard } from "@working-theory/ui/blocks"` |
|
|
200
|
+
| `PostMetaLine` | `<tag> · <date>` meta line, either half optional (C4). Shows the tag alone, the date alone, or both joined by a middot; renders nothing with neither. | `import { PostMetaLine } from "@working-theory/ui/blocks"` |
|
|
197
201
|
| `PostRow` | A single horizontal row in the two-column blog index: a landscape cover thumbnail (left) followed by the post's title · excerpt · author+date meta · tag list. The WHOLE row is one link (aria-labelled by the title, so screen readers announce the post title rather than the concatenated row content). | `import { PostRow } from "@working-theory/ui/blocks"` |
|
|
202
|
+
| `PostTeaser` | The featured post (`size="lg"`) and "Latest posts" grid card (`size="md"`); no cover renders no placeholder. Composes MediaFigure + PostMetaLine + primitives. No author byline (C7). RSC: no hooks or browser APIs. *(weak)* | `import { PostTeaser } from "@working-theory/ui/blocks"` |
|
|
198
203
|
| `PricingExtraTierRow` | Compact horizontal extra-tier row for the Pricing 'two-tiers-with-extra-tier' variant. Renders plan name + description on the left and a CTA on the right. Structurally different from PricingTierCard (no price display in this variant). | `import { PricingExtraTierRow } from "@working-theory/ui/blocks"` |
|
|
199
204
|
| `PricingTierCard` | Single pricing tier card (all 4 Pricing variants). Renders a single pricing tier: plan name + optional badge, description, price display, CTA button, and feature checklist. | `import { PricingTierCard } from "@working-theory/ui/blocks"` |
|
|
200
205
|
| `PricingTierCardFeaturesDisclosure` | Phone-breakpoint (<md, 768px — the same phone/tablet step CardGrid's own mobile-stacking ramp uses) presentation of a tier card's feature list: collapsed behind a disclosure button so price + CTA (which render ABOVE this row, see PricingTierCard's row-slot ordering) fit the first card view on a phone — the wisprflow.ai/pricing pattern. `md` and up renders the SAME feature list, always expanded, in a second, non-interactive tree — desktop/tablet is unaffected by the collapse. | `import { PricingTierCardFeaturesDisclosure } from "@working-theory/ui/blocks"` |
|
|
@@ -220,6 +225,7 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
220
225
|
| `TableOfContents` | The shared "On this page" rail consumed by the docs shell and the blog post layout (do not couple it to docs-only context). Renders a flat list of heading anchors and scroll-spies the heading currently in view, highlighting the matching item. | `import { TableOfContents } from "@working-theory/ui/blocks"` |
|
|
221
226
|
| `TeamMemberCard` | Renders one team member in either of two layout modes: 'inline' — small circular avatar left + name/role right (with-small-images variant) 'stacked' — large circular avatar top + name/role/social-links below (with-large-images variant). | `import { TeamMemberCard } from "@working-theory/ui/blocks"` |
|
|
222
227
|
| `TestimonialAside` | For ContactForm 'with-testimonial' variant. Rating (optional 0–5): rendered via Rating primitive with accessible label. avatar (optional): composed via Avatar + AvatarFallback + AvatarImage (initials fallback). | `import { TestimonialAside } from "@working-theory/ui/blocks"` |
|
|
228
|
+
| `TopicChips` | "All" plus one chip per tag, each a real server-rendered link — never a client-side filter — with the current page's chip marked `aria-current="page"` / `data-current="true"` in the served HTML. Composes Button (asChild) + Link; RSC, no client state. *(weak)* | `import { TopicChips } from "@working-theory/ui/blocks"` |
|
|
223
229
|
| `UpgradeDialog` | A plan-comparison dialog a consumer opens when an entitlement gates an action — controlled by default (open/onOpenChange are the primary interface; `trigger` is optional, since both known consumers open it from a menu row rather than an inline trigger). | `import { UpgradeDialog } from "@working-theory/ui/blocks"` |
|
|
224
230
|
| `UserBlock` | Position-agnostic identity/account trigger block: avatar + primary label + optional secondary line, with density/affordance/collapsed/truncation variants. A single focusable button-rooted element that forwardRef's + spreads props so DropdownMenuTrigger asChild (AccountMenu) can clone it as its trigger anchor. | `import { UserBlock } from "@working-theory/ui/blocks"` |
|
|
225
231
|
| `VerifyCodeField` | Presentational code-entry unit for StepFlow's `verify` step type: a status line ("We sent a code to…"), a 6-digit numeric code Field, and a resend link. Composes existing Field/Input/Button/Text primitives — no bespoke markup, no new primitive. | `import { VerifyCodeField } from "@working-theory/ui/blocks"` |
|
|
@@ -231,7 +237,7 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
231
237
|
|
|
232
238
|
---
|
|
233
239
|
|
|
234
|
-
## Chrome (
|
|
240
|
+
## Chrome (19)
|
|
235
241
|
|
|
236
242
|
Persistent framing UI that wraps page content — navigation, footers, sidebars, banners. Not MDX-driven.
|
|
237
243
|
|
|
@@ -249,6 +255,7 @@ Import: `import { X } from "@working-theory/ui/chrome";` (or from the `@working-
|
|
|
249
255
|
| `FloatingCta` | Persistent fixed corner action pill. *(weak)* | `import { FloatingCta } from "@working-theory/ui/chrome"` |
|
|
250
256
|
| `Footer` | Site footer server component with secondary nav links. Label resolution order for navItems labels. Resolved labels are passed into FooterNav as pre-resolved strings — no duplicated resolution logic across variants. | `import { Footer } from "@working-theory/ui/chrome"` |
|
|
251
257
|
| `Nav` | Primary navigation server component with locale-aware links. Three layout variants supported via `navAlignment`. Flyout (mega-menu) items: the desktop link list is ALWAYS a single SectionNav render path — there is no Path A/B fork. | `import { Nav } from "@working-theory/ui/chrome"` |
|
|
258
|
+
| `NavBackLink` | The bare header's back arrow, deck-return-aware. *(weak)* | `import { NavBackLink } from "@working-theory/ui/chrome"` |
|
|
252
259
|
| `NavMobileMenu` | Client subcomponent for mobile hamburger state. Isolates "use client" to this narrow component so Nav (Server Component) stays clean. Renders a hamburger button + collapsible link list. Closes the menu automatically when the pathname changes (route navigation). *(weak)* | internal — compose from `packages/ui/src/chrome/NavMobileMenu.tsx` |
|
|
253
260
|
| `NavOverflowMenu` | The Nav row's per-breakpoint link-overflow disclosure. The desktop link row never wraps: a fixed per-breakpoint inline-link budget (4 at md, 6 at lg+) is enforced by the caller (Nav), which splits `navItems` into an inline slice and an overflow slice. This component renders ONLY the overflow slice, behind a disclosure trigger, in source order — it never computes the budget itself. | internal — compose from `packages/ui/src/chrome/NavOverflowMenu.tsx` |
|
|
254
261
|
| `NotificationsMenu` | Bell trigger + notifications popover chrome (ploy-capture app-frame). Presentational, props-driven. The unread count and row list arrive entirely via props — this component carries NO fetch/polling logic of its own. Rows are pre-formatted at the call site (relative time, heading, empty copy) per the AILK i18n/formatting convention (design-system-rules Rule 10). | `import { NotificationsMenu } from "@working-theory/ui/chrome"` |
|
|
@@ -440,7 +447,7 @@ Import: `import { X } from "@working-theory/ui-scheduling";` (or from the `@work
|
|
|
440
447
|
|
|
441
448
|
---
|
|
442
449
|
|
|
443
|
-
## Scheduling Blocks (
|
|
450
|
+
## Scheduling Blocks (6)
|
|
444
451
|
|
|
445
452
|
Paid — delivered by the `scheduling` module bundle, not present in a Free scaffold. The pieces the booker section is built from — slot pickers, timezone and confirmation furniture.
|
|
446
453
|
|
|
@@ -453,6 +460,7 @@ Import: `import { X } from "@working-theory/ui-scheduling";` (or from the `@work
|
|
|
453
460
|
| `BookerEventHeader` | TWO KINDS OF TEXT, AND THE DIFFERENCE MATTERS. `eyebrow` and `headline` are AUTHORED: the operator's words about why someone would book. Everything in the meta row — duration, meeting type, timezone — is DERIVED from the calendar on the availability read, which is why the section schema has no field for any of it. | internal — compose from `packages-paid/ui-scheduling/src/blocks/BookerEventHeader.tsx` |
|
|
454
461
|
| `BookerPanel` | The booking card, fully controlled. One chassis, five views, ONE FOOTER. | internal — compose from `packages-paid/ui-scheduling/src/blocks/BookerPanel.tsx` |
|
|
455
462
|
| `BookerSlotGrid` | The selected day's open times. Two columns at 48px on mobile — the measured pixel target — widening to three at `lg` so the desktop variant shows more of the day without scrolling. Two columns is not an arbitrary density: at 390px it is the widest grid where a time still reads at a glance, and it puts eight times (a full working day's openings) inside one thumb-reachable block. | internal — compose from `packages-paid/ui-scheduling/src/blocks/BookerSlotGrid.tsx` |
|
|
463
|
+
| `BookingProfileHeader` | The /meet hub's opening header. The Cal.com / Calendly profile shape: whose calendar this is, then one line saying what to do here. A centered portrait over a single h1, and nothing beneath it — the booker cards below carry each event's own title, so a subtitle here would only repeat them. | `import { BookingProfileHeader } from "@working-theory/ui-scheduling"` |
|
|
456
464
|
|
|
457
465
|
---
|
|
458
466
|
|
|
@@ -542,7 +550,7 @@ Import: `import { X } from "@working-theory/ui-commerce";` (or from the `@workin
|
|
|
542
550
|
|
|
543
551
|
## Weak descriptions
|
|
544
552
|
|
|
545
|
-
These
|
|
553
|
+
These 34 components have a description that is accurate but does not do the job well: too short to match against, or long but spent on implementation. A capability search reaches them only if the searcher's word happens to be in it, so they are the most likely place for this catalog to repeat the failure it was built to fix. Read the source before concluding the capability is absent — and if you own one of these components, its header is the fix.
|
|
546
554
|
|
|
547
555
|
| Component | Tier | What the source gives us |
|
|
548
556
|
| --- | --- | --- |
|
|
@@ -550,14 +558,17 @@ These 31 components have a description that is accurate but does not do the job
|
|
|
550
558
|
| `AgentContextCard` | blocks | Capability-bearing block that renders agent provenance. RSC note: no hooks or browser APIs — server-renderable by default. |
|
|
551
559
|
| `PageHeader` | blocks | RSC. Page-level header composing the Breadcrumb primitive for the left-side wayfinding trail, a generic right-side `actions` slot, and an optional `switcher` slot for header-owned segment switching. Fills AppShell's `header` slot (AdminShell and similar). No accent bar. No tab API. No named action props — the caller assembles whatever button/menu nodes it needs and passes them as `actions`. |
|
|
552
560
|
| `PostCard` | blocks | Same props as PostRow, a vertical arrangement. A single linked blog-index card (cover · date · reading time · title · excerpt · "Read more"). Tier 3 block; composes MediaFigure + primitives. RSC default. |
|
|
561
|
+
| `PostTeaser` | blocks | The featured post (`size="lg"`) and "Latest posts" grid card (`size="md"`); no cover renders no placeholder. Composes MediaFigure + PostMetaLine + primitives. No author byline (C7). RSC: no hooks or browser APIs. |
|
|
553
562
|
| `PricingTierCardSeatControl` | blocks | Seat-count range picker for the Team tier card. Renders a Select primitive that lets the user choose an "Up to N seats" option from a caller-supplied list of numbers. The parent PricingTierCard stays a pure RSC; only this tiny island is hydrated. Pattern mirrors PageHeaderSwitcher.tsx: small "use client" island imported by an otherwise-server-rendered parent, keeping the client bundle minimal. |
|
|
554
563
|
| `SinglePriceCard` | blocks | 2-column split card for the Pricing 'single-price-with-details' variant. |
|
|
555
564
|
| `SocialIcons` | blocks | Horizontal row of social icon links. Renders brand icons (via Icon primitive + simple-icons paths) inside accessible Link primitives. Each platform link gets an aria-label. Shared by company-mission, simple-centered, and newsletter-below footer variants, and composed by TeamMemberCard for member social links. |
|
|
565
|
+
| `TopicChips` | blocks | "All" plus one chip per tag, each a real server-rendered link — never a client-side filter — with the current page's chip marked `aria-current="page"` / `data-current="true"` in the served HTML. Composes Button (asChild) + Link; RSC, no client state. |
|
|
556
566
|
| `Banner` | chrome | Site-wide announcement and consent banner chrome. |
|
|
557
567
|
| `BannerConsentIsland` | chrome | Accept / Reject action cluster for the consent Banner. Isolated to "use client" so Banner stays RSC. The onAccept / onReject callbacks must be Server Actions when used inside an RSC tree; they may be regular functions in client contexts (Storybook, testing). |
|
|
558
568
|
| `BannerDismissIsland` | chrome | Isolated to "use client" so Banner (Server Component) stays RSC. Mirrors the Nav / NavMobileMenu split: interactivity is contained here. Rendering: wraps its children in a relative-positioned div and absolutely places the × dismiss button at the end (RTL-safe: `end-4`) of the bar. |
|
|
559
569
|
| `BottomTabBar` | chrome | Fixed, safe-area-aware phone bottom tab bar chrome. Server Component (RSC) — presentational, no interaction state of its own; the leading avatar/account trigger is supplied as a node by the consumer (AppFrame composes AccountMenu around it). |
|
|
560
570
|
| `FloatingCta` | chrome | Persistent fixed corner action pill. |
|
|
571
|
+
| `NavBackLink` | chrome | The bare header's back arrow, deck-return-aware. |
|
|
561
572
|
| `NavMobileMenu` | chrome | Client subcomponent for mobile hamburger state. Isolates "use client" to this narrow component so Nav (Server Component) stays clean. Renders a hamburger button + collapsible link list. Closes the menu automatically when the pathname changes (route navigation). |
|
|
562
573
|
| `SidebarNav` | chrome | Application sidebar rail (nav + teams + user) for dashboard shells. Server Component (RSC). Renders the vertical sidebar rail for application-shell layouts. Used as the `sidebar` prop of AdminShell. Wrap in a FixedPanel (panels tier) to get the expanded ↔ rail ↔ hidden state machinery. Independently reusable in future shells (settings, analytics, etc.). |
|
|
563
574
|
| `SidebarNavRailItems` | chrome | Client boundary for the collapsed rail tooltip affordance. Isolated "use client" boundary so SidebarNav itself stays a Server Component. Renders icon-only nav links with Tooltip labels when the rail is collapsed. |
|
package/dist/apply-design.d.ts
CHANGED
|
@@ -42,6 +42,11 @@ export type ApplyDesignChange = {
|
|
|
42
42
|
kind: "home";
|
|
43
43
|
action: "seeded" | "restored";
|
|
44
44
|
fields: string[];
|
|
45
|
+
} | {
|
|
46
|
+
path: string;
|
|
47
|
+
kind: "contact";
|
|
48
|
+
action: "seeded" | "restored";
|
|
49
|
+
fields: string[];
|
|
45
50
|
} | {
|
|
46
51
|
path: string;
|
|
47
52
|
kind: "manifest";
|
|
@@ -57,6 +62,10 @@ export interface ApplyDesignResult {
|
|
|
57
62
|
home: HomeSeedOutcome;
|
|
58
63
|
/** #7743 D7 — the design ships a home arc for this site, so a home it leaves alone is reported. */
|
|
59
64
|
homeArc?: true;
|
|
65
|
+
/** #8661 D11 — what the design did to the contact page's sections and title. */
|
|
66
|
+
contact: HomeSeedOutcome;
|
|
67
|
+
/** #8661 D11 — the design ships a contact page for this site, so a contact page it leaves alone is reported. */
|
|
68
|
+
contactSeed?: true;
|
|
60
69
|
/** The site-relative roster file, when there is one. */
|
|
61
70
|
rosterPath?: string;
|
|
62
71
|
/** #7720 D4.2 — the distinct families written to site-fonts.ts, display first; set only when faces are written. */
|