@contractspec/bundle.library 3.9.8 → 3.9.9

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.
Files changed (70) hide show
  1. package/.turbo/turbo-build.log +222 -214
  2. package/CHANGELOG.md +52 -0
  3. package/dist/components/docs/DocsIndexPage.js +2 -2
  4. package/dist/components/docs/docsManifest.js +1 -1
  5. package/dist/components/docs/getting-started/DataViewTutorialPage.js +81 -6
  6. package/dist/components/docs/getting-started/index.js +94 -19
  7. package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.d.ts +6 -0
  8. package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.js +176 -0
  9. package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.d.ts +1 -0
  10. package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.js +176 -0
  11. package/dist/components/docs/guides/GuidesIndexPage.js +2 -2
  12. package/dist/components/docs/guides/index.d.ts +1 -0
  13. package/dist/components/docs/guides/index.js +220 -46
  14. package/dist/components/docs/index.js +1003 -309
  15. package/dist/components/docs/libraries/LibrariesApplicationShellPage.content.d.ts +22 -5
  16. package/dist/components/docs/libraries/LibrariesApplicationShellPage.content.js +125 -37
  17. package/dist/components/docs/libraries/LibrariesApplicationShellPage.js +125 -37
  18. package/dist/components/docs/libraries/LibrariesDataViewsPage.js +120 -3
  19. package/dist/components/docs/libraries/LibrariesDesignSystemPage.js +101 -2
  20. package/dist/components/docs/libraries/LibrariesOverviewPage.js +1 -1
  21. package/dist/components/docs/libraries/LibrariesPersonalizationPage.js +58 -4
  22. package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.content.d.ts +10 -0
  23. package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.content.js +43 -0
  24. package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.d.ts +1 -0
  25. package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.js +43 -0
  26. package/dist/components/docs/libraries/index.d.ts +1 -0
  27. package/dist/components/docs/libraries/index.js +496 -97
  28. package/dist/components/docs/specs/SpecsDataViewsPage.js +49 -3
  29. package/dist/components/docs/specs/index.js +60 -14
  30. package/dist/index.js +1014 -320
  31. package/dist/node/components/docs/DocsIndexPage.js +2 -2
  32. package/dist/node/components/docs/docsManifest.js +1 -1
  33. package/dist/node/components/docs/getting-started/DataViewTutorialPage.js +81 -6
  34. package/dist/node/components/docs/getting-started/index.js +94 -19
  35. package/dist/node/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.js +175 -0
  36. package/dist/node/components/docs/guides/GuideDataExchangeImportTemplatesPage.js +175 -0
  37. package/dist/node/components/docs/guides/GuidesIndexPage.js +2 -2
  38. package/dist/node/components/docs/guides/index.js +220 -46
  39. package/dist/node/components/docs/index.js +1003 -309
  40. package/dist/node/components/docs/libraries/LibrariesApplicationShellPage.content.js +125 -37
  41. package/dist/node/components/docs/libraries/LibrariesApplicationShellPage.js +125 -37
  42. package/dist/node/components/docs/libraries/LibrariesDataViewsPage.js +120 -3
  43. package/dist/node/components/docs/libraries/LibrariesDesignSystemPage.js +101 -2
  44. package/dist/node/components/docs/libraries/LibrariesOverviewPage.js +1 -1
  45. package/dist/node/components/docs/libraries/LibrariesPersonalizationPage.js +58 -4
  46. package/dist/node/components/docs/libraries/LibrariesTranslationRuntimePage.content.js +42 -0
  47. package/dist/node/components/docs/libraries/LibrariesTranslationRuntimePage.js +42 -0
  48. package/dist/node/components/docs/libraries/index.js +496 -97
  49. package/dist/node/components/docs/specs/SpecsDataViewsPage.js +49 -3
  50. package/dist/node/components/docs/specs/index.js +60 -14
  51. package/dist/node/index.js +1014 -320
  52. package/package.json +74 -26
  53. package/src/components/docs/docsManifest.test.ts +87 -0
  54. package/src/components/docs/docsManifest.ts +90 -3
  55. package/src/components/docs/generated/docs-index.notifications.json +7 -7
  56. package/src/components/docs/getting-started/DataViewTutorialPage.tsx +181 -50
  57. package/src/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.ts +185 -0
  58. package/src/components/docs/guides/GuideDataExchangeImportTemplatesPage.tsx +186 -0
  59. package/src/components/docs/guides/GuidesIndexPage.tsx +49 -42
  60. package/src/components/docs/guides/index.ts +1 -0
  61. package/src/components/docs/libraries/LibrariesApplicationShellPage.content.ts +148 -35
  62. package/src/components/docs/libraries/LibrariesApplicationShellPage.tsx +38 -5
  63. package/src/components/docs/libraries/LibrariesDataViewsPage.tsx +267 -64
  64. package/src/components/docs/libraries/LibrariesDesignSystemPage.tsx +235 -0
  65. package/src/components/docs/libraries/LibrariesOverviewPage.tsx +8 -2
  66. package/src/components/docs/libraries/LibrariesPersonalizationPage.tsx +141 -31
  67. package/src/components/docs/libraries/LibrariesTranslationRuntimePage.content.ts +78 -0
  68. package/src/components/docs/libraries/LibrariesTranslationRuntimePage.tsx +137 -0
  69. package/src/components/docs/libraries/index.ts +1 -0
  70. package/src/components/docs/specs/SpecsDataViewsPage.tsx +239 -113
@@ -1,37 +1,170 @@
1
1
  import { CodeBlock, InstallCommand } from '@contractspec/lib.design-system';
2
+ import { HStack, VStack } from '@contractspec/lib.design-system/layout';
3
+ import { List, ListItem } from '@contractspec/lib.design-system/list';
4
+ import {
5
+ Code,
6
+ H1,
7
+ H2,
8
+ H3,
9
+ P,
10
+ Text,
11
+ } from '@contractspec/lib.design-system/typography';
2
12
  import Link from '@contractspec/lib.ui-link';
3
13
  import { ChevronRight } from 'lucide-react';
4
14
 
15
+ const COLLECTION_DATAVIEW_EXAMPLE = `import { defineDataView } from '@contractspec/lib.contracts-spec/data-views';
16
+
17
+ export const AccountsDataView = defineDataView({
18
+ meta: {
19
+ key: 'crm.accounts',
20
+ version: '1.0.0',
21
+ title: 'Accounts',
22
+ description: 'Customer account workspace',
23
+ domain: 'crm',
24
+ entity: 'account',
25
+ owners: ['@crm'],
26
+ tags: ['crm', 'accounts'],
27
+ stability: 'stable',
28
+ },
29
+ source: {
30
+ primary: { key: 'crm.accounts.list', version: '1.0.0' },
31
+ },
32
+ view: {
33
+ kind: 'table',
34
+ fields: [
35
+ { key: 'name', label: 'Name', dataPath: 'name', sortable: true },
36
+ { key: 'owner', label: 'Owner', dataPath: 'owner' },
37
+ { key: 'arr', label: 'ARR', dataPath: 'arr', format: { type: 'currency', currency: 'EUR' } },
38
+ {
39
+ key: 'internalNotes',
40
+ label: 'Internal notes',
41
+ dataPath: 'internalNotes',
42
+ visibility: { minDataDepth: 'detailed' },
43
+ },
44
+ ],
45
+ columns: [
46
+ { field: 'name' },
47
+ { field: 'owner' },
48
+ { field: 'arr' },
49
+ { field: 'internalNotes' },
50
+ ],
51
+ collection: {
52
+ viewModes: {
53
+ defaultMode: 'table',
54
+ allowedModes: ['list', 'grid', 'table'],
55
+ },
56
+ pagination: {
57
+ pageSize: 25,
58
+ pageSizeOptions: [10, 25, 50],
59
+ },
60
+ toolbar: {
61
+ search: true,
62
+ viewMode: true,
63
+ filters: true,
64
+ density: true,
65
+ dataDepth: true,
66
+ },
67
+ density: 'comfortable',
68
+ dataDepth: 'standard',
69
+ personalization: {
70
+ enabled: true,
71
+ persist: {
72
+ viewMode: true,
73
+ density: true,
74
+ dataDepth: true,
75
+ pageSize: true,
76
+ },
77
+ },
78
+ },
79
+ },
80
+ });`;
81
+
82
+ const PERSONALIZED_RENDERER_EXAMPLE = `import { DataViewRenderer } from '@contractspec/lib.design-system';
83
+ import { resolveDataViewPreferences } from '@contractspec/lib.personalization/data-view-preferences';
84
+
85
+ const resolved = resolveDataViewPreferences({
86
+ spec: AccountsDataView,
87
+ preferences: profile.canonical,
88
+ insights,
89
+ record: savedDataViewPreference,
90
+ });
91
+
92
+ <DataViewRenderer
93
+ spec={AccountsDataView}
94
+ items={accounts}
95
+ defaultViewMode={resolved.viewMode}
96
+ defaultDensity={resolved.density}
97
+ defaultDataDepth={resolved.dataDepth}
98
+ pagination={{
99
+ page,
100
+ pageSize: resolved.pageSize ?? 25,
101
+ total,
102
+ }}
103
+ onViewModeChange={(viewMode) => {
104
+ tracker.trackDataViewInteraction({
105
+ dataViewKey: AccountsDataView.meta.key,
106
+ dataViewVersion: AccountsDataView.meta.version,
107
+ action: 'view_mode_changed',
108
+ viewMode,
109
+ });
110
+ }}
111
+ onDensityChange={(density) => {
112
+ tracker.trackDataViewInteraction({
113
+ dataViewKey: AccountsDataView.meta.key,
114
+ action: 'density_changed',
115
+ density,
116
+ });
117
+ }}
118
+ onDataDepthChange={(dataDepth) => {
119
+ tracker.trackDataViewInteraction({
120
+ dataViewKey: AccountsDataView.meta.key,
121
+ action: 'data_depth_changed',
122
+ dataDepth,
123
+ });
124
+ }}
125
+ />;
126
+ `;
127
+
128
+ const DATAVIEW_AGENT_PROMPT = `Implement a production DataView for <entity>.
129
+
130
+ Requirements:
131
+ - Define one canonical DataViewSpec with kind 'table', collection viewModes for list/grid/table, pagination defaults, toolbar search/filter/view mode/density/dataDepth controls, and personalization persist hints.
132
+ - Mark fields that should only appear in richer experiences with visibility.minDataDepth.
133
+ - Render it with DataViewRenderer using plain props from resolveDataViewPreferences.
134
+ - Track user interactions with trackDataViewInteraction for view mode, density, data depth, search, filters, sorting, and pagination.
135
+ - Keep @contractspec/lib.design-system independent from @contractspec/lib.personalization.
136
+ - Add focused tests for default resolution, invalid-mode fallback, data-depth projection, and behavior-derived preferred view mode.`;
137
+
5
138
  export function LibrariesDataViewsPage() {
6
139
  return (
7
- <div className="space-y-8">
8
- <div className="space-y-4">
9
- <h1 className="font-bold text-4xl">DataViews Runtime Library</h1>
10
- <p className="text-lg text-muted-foreground">
11
- The <code>@contractspec/lib.contracts-spec/data-views</code> and{' '}
12
- <code>@contractspec/lib.design-system</code> libraries provide the
140
+ <VStack className="space-y-8">
141
+ <VStack className="space-y-4">
142
+ <H1 className="font-bold text-4xl">DataViews Runtime Library</H1>
143
+ <P className="text-lg text-muted-foreground">
144
+ The <Code>@contractspec/lib.contracts-spec/data-views</Code> and{' '}
145
+ <Code>@contractspec/lib.design-system</Code> libraries provide the
13
146
  runtime logic and UI components to render DataViews in your
14
147
  application.
15
- </p>
16
- </div>
148
+ </P>
149
+ </VStack>
17
150
 
18
- <div className="space-y-4">
19
- <h2 className="font-bold text-2xl">Installation</h2>
151
+ <VStack className="space-y-4">
152
+ <H2 className="font-bold text-2xl">Installation</H2>
20
153
  <InstallCommand
21
154
  package={[
22
155
  '@contractspec/lib.contracts-spec',
23
156
  '@contractspec/lib.design-system',
24
157
  ]}
25
158
  />
26
- </div>
159
+ </VStack>
27
160
 
28
- <div className="space-y-4">
29
- <h2 className="font-bold text-2xl">DataViewRenderer</h2>
30
- <p className="text-muted-foreground">
161
+ <VStack className="space-y-4">
162
+ <H2 className="font-bold text-2xl">DataViewRenderer</H2>
163
+ <P className="text-muted-foreground">
31
164
  The primary component for rendering any DataView. It automatically
32
165
  selects the correct layout (List, Table, Grid, Detail) based on the
33
166
  spec.
34
- </p>
167
+ </P>
35
168
 
36
169
  <CodeBlock
37
170
  language="tsx"
@@ -50,51 +183,121 @@ export function UserPage() {
50
183
  }`}
51
184
  />
52
185
 
53
- <h3 className="font-semibold text-xl">Props</h3>
54
- <ul className="list-disc space-y-2 pl-6 text-muted-foreground">
55
- <li>
56
- <code>spec</code>: The DataViewSpec definition.
57
- </li>
58
- <li>
59
- <code>items</code>: Array of data items to render.
60
- </li>
61
- <li>
62
- <code>filters</code>: Current filter state object.
63
- </li>
64
- <li>
65
- <code>onFilterChange</code>: Callback when typed filters change.
66
- Renderers emit <code>DataViewFilterValue</code> objects for numeric,
67
- percent, currency, temporal, duration, and boolean filters.
68
- </li>
69
- <li>
70
- <code>pagination</code>: Object with <code>page</code>,{' '}
71
- <code>pageSize</code>, <code>total</code>.
72
- </li>
73
- <li>
74
- <code>onPageChange</code>: Callback when page changes.
75
- </li>
76
- <li>
77
- <code>viewMode</code> / <code>defaultViewMode</code>: Controlled
78
- or initial collection mode for specs that allow <code>list</code>,{' '}
79
- <code>grid</code>, or <code>table</code> projections through{' '}
80
- <code>view.collection.viewModes</code>.
81
- </li>
82
- <li>
83
- <code>density</code> / <code>defaultDensity</code>: Controlled or
84
- initial density for collection renderers, seeded by{' '}
85
- <code>view.collection.density</code> and table{' '}
86
- <code>view.density</code>.
87
- </li>
88
- </ul>
89
- </div>
90
-
91
- <div className="space-y-4">
92
- <h2 className="font-bold text-2xl">Query Generation</h2>
93
- <p className="text-muted-foreground">
94
- The <code>DataViewQueryGenerator</code> utility helps translate
186
+ <H3 className="font-semibold text-xl">Props</H3>
187
+ <List className="list-disc space-y-2 pl-6 text-muted-foreground">
188
+ <ListItem>
189
+ <Text>
190
+ <Code>spec</Code>: The DataViewSpec definition.
191
+ </Text>
192
+ </ListItem>
193
+ <ListItem>
194
+ <Text>
195
+ <Code>items</Code>: Array of data items to render.
196
+ </Text>
197
+ </ListItem>
198
+ <ListItem>
199
+ <Text>
200
+ <Code>filters</Code>: Current filter state object.
201
+ </Text>
202
+ </ListItem>
203
+ <ListItem>
204
+ <Text>
205
+ <Code>onFilterChange</Code>: Callback when typed filters change.
206
+ Renderers emit <Code>DataViewFilterValue</Code> objects for
207
+ numeric, percent, currency, temporal, duration, and boolean
208
+ filters.
209
+ </Text>
210
+ </ListItem>
211
+ <ListItem>
212
+ <Text>
213
+ <Code>pagination</Code>: Object with <Code>page</Code>,{' '}
214
+ <Code>pageSize</Code>, <Code>total</Code>.
215
+ </Text>
216
+ </ListItem>
217
+ <ListItem>
218
+ <Text>
219
+ <Code>onPageChange</Code>: Callback when page changes.
220
+ </Text>
221
+ </ListItem>
222
+ <ListItem>
223
+ <Text>
224
+ <Code>viewMode</Code> / <Code>defaultViewMode</Code>: Controlled
225
+ or initial collection mode for specs that allow <Code>list</Code>,{' '}
226
+ <Code>grid</Code>, or <Code>table</Code> projections through{' '}
227
+ <Code>view.collection.viewModes</Code>.
228
+ </Text>
229
+ </ListItem>
230
+ <ListItem>
231
+ <Text>
232
+ <Code>density</Code> / <Code>defaultDensity</Code>: Controlled or
233
+ initial density for collection renderers. Host apps can seed this
234
+ from <Code>@contractspec/lib.personalization</Code> while specs
235
+ can declare <Code>view.collection.density</Code> and table{' '}
236
+ <Code>view.density</Code> defaults.
237
+ </Text>
238
+ </ListItem>
239
+ <ListItem>
240
+ <Text>
241
+ <Code>dataDepth</Code> / <Code>defaultDataDepth</Code>: Controlled
242
+ or initial summary/standard/detailed/exhaustive projection. Fields
243
+ can declare <Code>visibility.minDataDepth</Code>, and collection
244
+ specs can opt into <Code>view.collection.personalization</Code>{' '}
245
+ persistence hints.
246
+ </Text>
247
+ </ListItem>
248
+ </List>
249
+ </VStack>
250
+
251
+ <VStack className="space-y-4">
252
+ <H2 className="font-bold text-2xl">
253
+ Collection Defaults And Data Depth
254
+ </H2>
255
+ <P className="text-muted-foreground">
256
+ Use one authored <Code>DataViewSpec</Code> for list, grid, and table
257
+ experiences. <Code>view.collection</Code> declares allowed modes,
258
+ toolbar controls, pagination defaults, density, data depth, and
259
+ persistence hints. <Code>visibility.minDataDepth</Code> lets a field
260
+ appear only when the renderer is in a detailed or exhaustive mode.
261
+ </P>
262
+ <CodeBlock language="typescript" code={COLLECTION_DATAVIEW_EXAMPLE} />
263
+ </VStack>
264
+
265
+ <VStack className="space-y-4">
266
+ <H2 className="font-bold text-2xl">Personalization Bridge</H2>
267
+ <P className="text-muted-foreground">
268
+ Resolve user preferences in the host app, then pass ordinary renderer
269
+ props into <Code>DataViewRenderer</Code>. The bridge helper lives in{' '}
270
+ <Code>@contractspec/lib.personalization</Code>, so the design-system
271
+ renderer stays portable for apps that do not use personalization. See
272
+ the{' '}
273
+ <Link
274
+ href="/docs/libraries/personalization"
275
+ className="text-[color:var(--rust)] underline underline-offset-4"
276
+ >
277
+ <Text>personalization library guide</Text>
278
+ </Link>{' '}
279
+ for the behavior tracker, analyzer, and DataView preference resolver.
280
+ </P>
281
+ <CodeBlock language="tsx" code={PERSONALIZED_RENDERER_EXAMPLE} />
282
+ </VStack>
283
+
284
+ <VStack className="space-y-4">
285
+ <H2 className="font-bold text-2xl">Agent Prompt</H2>
286
+ <P className="text-muted-foreground">
287
+ Use this prompt when asking an implementation agent to add a
288
+ preference-aware collection DataView without breaking package
289
+ boundaries.
290
+ </P>
291
+ <CodeBlock language="markdown" code={DATAVIEW_AGENT_PROMPT} />
292
+ </VStack>
293
+
294
+ <VStack className="space-y-4">
295
+ <H2 className="font-bold text-2xl">Query Generation</H2>
296
+ <P className="text-muted-foreground">
297
+ The <Code>DataViewQueryGenerator</Code> utility helps translate
95
298
  DataView parameters (filters, sorting, pagination) into query
96
299
  arguments for your backend.
97
- </p>
300
+ </P>
98
301
  <CodeBlock
99
302
  language="typescript"
100
303
  code={`import { DataViewQueryGenerator } from '@contractspec/lib.contracts-spec/data-views/query-generator';
@@ -114,16 +317,16 @@ const query = generator.generate(params);
114
317
 
115
318
  // query.input contains skip/take plus the typed filter payloads.`}
116
319
  />
117
- </div>
320
+ </VStack>
118
321
 
119
- <div className="flex items-center gap-4 pt-4">
322
+ <HStack className="items-center gap-4 pt-4">
120
323
  <Link href="/docs/libraries" className="btn-ghost">
121
- Back to Libraries
324
+ <Text>Back to Libraries</Text>
122
325
  </Link>
123
326
  <Link href="/docs/libraries/data-backend" className="btn-primary">
124
- Next: Data & Backend <ChevronRight size={16} />
327
+ <Text>Next: Data & Backend</Text> <ChevronRight size={16} />
125
328
  </Link>
126
- </div>
127
- </div>
329
+ </HStack>
330
+ </VStack>
128
331
  );
129
332
  }
@@ -88,10 +88,115 @@ const FOCUSED_SUBPATHS_EXAMPLE = `import { themeSpecToTailwindPreset } from '@co
88
88
  import { Select } from '@contractspec/lib.design-system/controls';
89
89
  import { FormDialog } from '@contractspec/lib.design-system/forms';
90
90
  import { HStack } from '@contractspec/lib.design-system/layout';
91
+ import { AdaptivePanel } from '@contractspec/lib.design-system/components/overlays';
92
+ import { ObjectReferenceHandler } from '@contractspec/lib.design-system/components/object-reference';
91
93
 
92
94
  // Root imports remain supported:
93
95
  import { Button, DataTable } from '@contractspec/lib.design-system';`;
94
96
 
97
+ const OBJECT_REFERENCE_EXAMPLE = `import {
98
+ ObjectReferenceHandler,
99
+ createDefaultObjectReferenceActions,
100
+ createMapsReferenceActions,
101
+ type ObjectReferenceDescriptor,
102
+ type ObjectReferenceOpenHrefHandler,
103
+ } from '@contractspec/lib.design-system';
104
+
105
+ const customerContact: ObjectReferenceDescriptor = {
106
+ id: 'user.amina',
107
+ kind: 'user',
108
+ label: 'Amina Laurent',
109
+ description: 'Customer success owner',
110
+ href: '/customers/acme/users/amina',
111
+ properties: [
112
+ {
113
+ id: 'user.amina.email',
114
+ kind: 'email',
115
+ label: 'Email',
116
+ value: 'amina@example.com',
117
+ },
118
+ {
119
+ id: 'user.amina.phone',
120
+ kind: 'phone',
121
+ label: 'Phone',
122
+ value: '+33 1 23 45 67 89',
123
+ },
124
+ ],
125
+ sections: [
126
+ {
127
+ id: 'customer-site',
128
+ title: 'Primary site',
129
+ properties: [
130
+ {
131
+ id: 'customer-site.address',
132
+ kind: 'address',
133
+ label: 'Paris office',
134
+ value: '10 rue de Rivoli, 75001 Paris',
135
+ actions: createMapsReferenceActions({
136
+ id: 'customer-site.address',
137
+ kind: 'address',
138
+ label: 'Paris office',
139
+ value: '10 rue de Rivoli, 75001 Paris',
140
+ }),
141
+ },
142
+ ],
143
+ },
144
+ ],
145
+ };
146
+
147
+ const openHref: ObjectReferenceOpenHrefHandler = (href, _event, options) => {
148
+ if (options.target === 'new-page') {
149
+ window.open(href, '_blank', 'noopener,noreferrer');
150
+ return;
151
+ }
152
+
153
+ window.location.assign(href);
154
+ };
155
+
156
+ <ObjectReferenceHandler
157
+ reference={customerContact}
158
+ actions={createDefaultObjectReferenceActions(customerContact)}
159
+ interactivityVisibility="icon"
160
+ openTarget="same-page"
161
+ panelMode="responsive"
162
+ mobilePanelMode="drawer"
163
+ desktopPanelMode="sheet"
164
+ responsiveBreakpoint="md"
165
+ openHref={openHref}
166
+ />;`;
167
+
168
+ const ADAPTIVE_PANEL_EXAMPLE = `import { AdaptivePanel } from '@contractspec/lib.design-system/components/overlays';
169
+
170
+ <AdaptivePanel
171
+ open={open}
172
+ onOpenChange={setOpen}
173
+ trigger={<button type="button">Edit</button>}
174
+ title="Edit customer"
175
+ description="Update contact and site details."
176
+ mode="responsive"
177
+ mobileMode="drawer"
178
+ desktopMode="sheet"
179
+ breakpoint="md"
180
+ sheetSide="right"
181
+ drawerDirection="bottom"
182
+ >
183
+ {content}
184
+ </AdaptivePanel>;`;
185
+
186
+ const OBJECT_REFERENCE_PROMPT = `Find every user-facing address, phone number, email, user, customer, file, URL, and tenant-specific object reference currently rendered as inert text.
187
+
188
+ Replace each one with ObjectReferenceHandler from @contractspec/lib.design-system. Keep descriptors data-only: id, kind, label, value, href, openTarget, properties, sections, metadata, iconKey, and ariaLabel are allowed; React callbacks belong in handler props only.
189
+
190
+ Use properties and sections for rich references. For example, a user reference can expose email, phone, address, files, and customer links in one panel instead of rendering separate disconnected strings.
191
+
192
+ Use panelMode="responsive" by default. Let desktop render a sheet and small screens render a bottom drawer through AdaptivePanel. Do not call Sheet or Drawer directly for this interaction unless a lower-level primitive is being implemented.
193
+
194
+ Use openTarget="same-page" unless product requirements explicitly require a new page. Put custom copy, navigation, analytics, permissions, or tenant-specific actions in copyHandler, openHref, actionHandlers, onAction, and onActionError.
195
+
196
+ For addresses, use createMapsReferenceActions so users can choose Google Maps, Apple Maps, or Waze. For email and phone references, prefer createDefaultObjectReferenceActions unless a product-specific action set is required.
197
+
198
+ After replacing references, verify keyboard access, visible affordance choice (none, underline, or icon), safe href behavior, mobile drawer layout, and desktop sheet layout.`;
199
+
95
200
  export function LibrariesDesignSystemPage() {
96
201
  return (
97
202
  <div className="space-y-8">
@@ -134,6 +239,15 @@ export function LibrariesDesignSystemPage() {
134
239
  <strong>Platform Utilities</strong>: Hooks for responsive and
135
240
  adaptive design
136
241
  </li>
242
+ <li>
243
+ <strong>Object References</strong>: Clickable references for
244
+ addresses, phone numbers, users, customers, files, URLs, and custom
245
+ objects
246
+ </li>
247
+ <li>
248
+ <strong>Adaptive Panels</strong>: One panel API that resolves to a
249
+ desktop sheet or mobile drawer
250
+ </li>
137
251
  <li>
138
252
  <strong>Theme Bridge</strong>: ThemeSpec to Tailwind variables,
139
253
  presets, CSS text, and runtime light/dark mode
@@ -165,6 +279,118 @@ export function LibrariesDesignSystemPage() {
165
279
  <CodeBlock language="tsx" code={FOCUSED_SUBPATHS_EXAMPLE} />
166
280
  </div>
167
281
 
282
+ <div className="space-y-4">
283
+ <h2 className="font-bold text-2xl">Actionable object references</h2>
284
+ <p className="text-muted-foreground">
285
+ Use <code>ObjectReferenceHandler</code> whenever a product surface
286
+ renders an object that may need quick interaction: addresses, phone
287
+ numbers, emails, users, customers, files, URLs, and tenant-specific
288
+ objects. The goal is to avoid inert references while keeping the
289
+ descriptor contract declarative enough for OSS consumers and future
290
+ contract-generated surfaces.
291
+ </p>
292
+ <div className="grid gap-4 md:grid-cols-2">
293
+ <div className="card-subtle p-4">
294
+ <h3 className="mb-2 font-semibold">Descriptor model</h3>
295
+ <ul className="list-inside list-disc space-y-1 text-muted-foreground text-sm">
296
+ <li>
297
+ References use data-only descriptors: <code>id</code>,{' '}
298
+ <code>kind</code>, <code>label</code>, <code>value</code>,{' '}
299
+ <code>href</code>, <code>openTarget</code>,{' '}
300
+ <code>metadata</code>, <code>iconKey</code>, and{' '}
301
+ <code>ariaLabel</code>.
302
+ </li>
303
+ <li>
304
+ Rich references use nested <code>properties</code> and{' '}
305
+ <code>sections</code>, so one user or customer can expose email,
306
+ phone, address, files, and links inside the same panel.
307
+ </li>
308
+ <li>
309
+ Reference kinds are <code>address</code>, <code>email</code>,{' '}
310
+ <code>phone</code>, <code>user</code>, <code>customer</code>,{' '}
311
+ <code>file</code>, <code>url</code>, and <code>custom</code>.
312
+ </li>
313
+ </ul>
314
+ </div>
315
+ <div className="card-subtle p-4">
316
+ <h3 className="mb-2 font-semibold">Runtime behavior</h3>
317
+ <ul className="list-inside list-disc space-y-1 text-muted-foreground text-sm">
318
+ <li>
319
+ Choose visibility with <code>interactivityVisibility</code>:
320
+ <code>none</code>, <code>underline</code>, or <code>icon</code>.
321
+ </li>
322
+ <li>
323
+ Detail navigation defaults to <code>same-page</code>; set{' '}
324
+ <code>openTarget="new-page"</code> on the handler, reference, or
325
+ action when a new page is required.
326
+ </li>
327
+ <li>
328
+ Host apps provide behavior through <code>copyHandler</code>,{' '}
329
+ <code>openHref</code>, <code>actionHandlers</code>,{' '}
330
+ <code>onAction</code>, and <code>onActionError</code>.
331
+ </li>
332
+ </ul>
333
+ </div>
334
+ <div className="card-subtle p-4">
335
+ <h3 className="mb-2 font-semibold">Default actions</h3>
336
+ <ul className="list-inside list-disc space-y-1 text-muted-foreground text-sm">
337
+ <li>
338
+ <code>createDefaultObjectReferenceActions</code> adds copy,
339
+ open, email, phone, and map actions when the descriptor supports
340
+ them.
341
+ </li>
342
+ <li>
343
+ <code>createMapsReferenceActions</code> creates Google Maps,
344
+ Apple Maps, Waze, or geo actions for address references.
345
+ </li>
346
+ <li>
347
+ Safe href handling allows expected app, web, email, phone, and
348
+ map URLs while rejecting unsafe schemes.
349
+ </li>
350
+ </ul>
351
+ </div>
352
+ <div className="card-subtle p-4">
353
+ <h3 className="mb-2 font-semibold">Extension points</h3>
354
+ <ul className="list-inside list-disc space-y-1 text-muted-foreground text-sm">
355
+ <li>
356
+ Use <code>renderTrigger</code>, <code>renderDetail</code>,{' '}
357
+ <code>renderAction</code>, <code>renderProperty</code>,{' '}
358
+ <code>renderSection</code>, and <code>iconRenderer</code> to
359
+ wrap or overload presentation.
360
+ </li>
361
+ <li>
362
+ Keep tenant-specific permissions, analytics, and integration
363
+ side effects at the host boundary through runtime handlers.
364
+ </li>
365
+ </ul>
366
+ </div>
367
+ </div>
368
+ <CodeBlock language="tsx" code={OBJECT_REFERENCE_EXAMPLE} />
369
+ </div>
370
+
371
+ <div className="space-y-4">
372
+ <h2 className="font-bold text-2xl">Adaptive panels</h2>
373
+ <p className="text-muted-foreground">
374
+ <code>AdaptivePanel</code> is the shared overlay decision for surfaces
375
+ that should feel native on both desktop and small screens. Its default
376
+ responsive mode renders a sheet at the configured desktop breakpoint
377
+ and a drawer below it. <code>ObjectReferenceHandler</code> uses this
378
+ panel contract through <code>panelMode</code>,{' '}
379
+ <code>mobilePanelMode</code>, <code>desktopPanelMode</code>, and{' '}
380
+ <code>responsiveBreakpoint</code>.
381
+ </p>
382
+ <CodeBlock language="tsx" code={ADAPTIVE_PANEL_EXAMPLE} />
383
+ </div>
384
+
385
+ <div className="space-y-4">
386
+ <h2 className="font-bold text-2xl">Prompt for adoption work</h2>
387
+ <p className="text-muted-foreground">
388
+ Use this prompt when asking an agent or downstream OSS consumer to
389
+ replace inert references across an application.
390
+ </p>
391
+ <CodeBlock language="text" code={OBJECT_REFERENCE_PROMPT} />
392
+ </div>
393
+
168
394
  <div className="space-y-4">
169
395
  <h2 className="font-bold text-2xl">Data table example</h2>
170
396
  <p className="text-muted-foreground">
@@ -218,6 +444,15 @@ export function LibrariesDesignSystemPage() {
218
444
  <li>PackageManagerProvider</li>
219
445
  </ul>
220
446
  </div>
447
+ <div className="card-subtle p-4">
448
+ <h3 className="mb-2 font-semibold">References & Overlays</h3>
449
+ <ul className="space-y-1 text-muted-foreground text-sm">
450
+ <li>ObjectReferenceHandler</li>
451
+ <li>createDefaultObjectReferenceActions</li>
452
+ <li>createMapsReferenceActions</li>
453
+ <li>AdaptivePanel</li>
454
+ </ul>
455
+ </div>
221
456
  </div>
222
457
  </div>
223
458
 
@@ -30,6 +30,12 @@ const libraryGroups = [
30
30
  'Run typed capability surfaces, execute policies, and connect runtime adapters.',
31
31
  href: '/docs/libraries/runtime',
32
32
  },
33
+ {
34
+ title: '@contractspec/lib.translation-runtime',
35
+ description:
36
+ 'Resolve ContractSpec TranslationSpec catalogs with ICU formatting, SSR snapshots, BCP 47 locales, overrides, and optional i18next projection.',
37
+ href: '/docs/libraries/translation-runtime',
38
+ },
33
39
  {
34
40
  title: '@contractspec/lib.ui-kit',
35
41
  description:
@@ -45,13 +51,13 @@ const libraryGroups = [
45
51
  {
46
52
  title: '@contractspec/lib.design-system',
47
53
  description:
48
- 'Build higher-level product surfaces and documented marketing/docs primitives on top of the web and native UI packages.',
54
+ 'Build higher-level product surfaces, actionable object references, adaptive panels, and documented marketing/docs primitives on top of the web and native UI packages.',
49
55
  href: '/docs/libraries/design-system',
50
56
  },
51
57
  {
52
58
  title: 'Application shell',
53
59
  description:
54
- 'Adopt the shared sidebar, topbar, command search, mobile navigation, and PageOutline patterns for product apps.',
60
+ 'Adopt the shared sidebar, topbar, command search, notifications, mobile navigation, and PageOutline patterns for product apps.',
55
61
  href: '/docs/libraries/application-shell',
56
62
  },
57
63
  {