@contractspec/bundle.library 3.9.7 → 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.
- package/.turbo/turbo-build.log +186 -174
- package/CHANGELOG.md +96 -0
- package/dist/components/docs/DocsIndexPage.js +2 -2
- package/dist/components/docs/docsManifest.js +1 -1
- package/dist/components/docs/getting-started/DataViewTutorialPage.js +117 -6
- package/dist/components/docs/getting-started/index.js +130 -19
- package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.d.ts +6 -0
- package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.js +176 -0
- package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.d.ts +1 -0
- package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.js +176 -0
- package/dist/components/docs/guides/GuidesIndexPage.js +2 -2
- package/dist/components/docs/guides/index.d.ts +1 -0
- package/dist/components/docs/guides/index.js +220 -46
- package/dist/components/docs/index.js +1195 -276
- package/dist/components/docs/libraries/LibrariesApplicationShellPage.content.d.ts +33 -0
- package/dist/components/docs/libraries/LibrariesApplicationShellPage.content.js +236 -0
- package/dist/components/docs/libraries/LibrariesApplicationShellPage.d.ts +1 -0
- package/dist/components/docs/libraries/LibrariesApplicationShellPage.js +236 -0
- package/dist/components/docs/libraries/LibrariesDataViewsPage.js +130 -6
- package/dist/components/docs/libraries/LibrariesDesignSystemPage.js +102 -3
- package/dist/components/docs/libraries/LibrariesOverviewPage.js +1 -1
- package/dist/components/docs/libraries/LibrariesPersonalizationPage.js +58 -4
- package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.content.d.ts +10 -0
- package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.content.js +43 -0
- package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.d.ts +1 -0
- package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.js +43 -0
- package/dist/components/docs/libraries/index.d.ts +2 -0
- package/dist/components/docs/libraries/index.js +616 -64
- package/dist/components/docs/specs/SpecsDataViewsPage.js +85 -3
- package/dist/components/docs/specs/index.js +96 -14
- package/dist/index.js +1206 -287
- package/dist/node/components/docs/DocsIndexPage.js +2 -2
- package/dist/node/components/docs/docsManifest.js +1 -1
- package/dist/node/components/docs/getting-started/DataViewTutorialPage.js +117 -6
- package/dist/node/components/docs/getting-started/index.js +130 -19
- package/dist/node/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.js +175 -0
- package/dist/node/components/docs/guides/GuideDataExchangeImportTemplatesPage.js +175 -0
- package/dist/node/components/docs/guides/GuidesIndexPage.js +2 -2
- package/dist/node/components/docs/guides/index.js +220 -46
- package/dist/node/components/docs/index.js +1195 -276
- package/dist/node/components/docs/libraries/LibrariesApplicationShellPage.content.js +235 -0
- package/dist/node/components/docs/libraries/LibrariesApplicationShellPage.js +235 -0
- package/dist/node/components/docs/libraries/LibrariesDataViewsPage.js +130 -6
- package/dist/node/components/docs/libraries/LibrariesDesignSystemPage.js +102 -3
- package/dist/node/components/docs/libraries/LibrariesOverviewPage.js +1 -1
- package/dist/node/components/docs/libraries/LibrariesPersonalizationPage.js +58 -4
- package/dist/node/components/docs/libraries/LibrariesTranslationRuntimePage.content.js +42 -0
- package/dist/node/components/docs/libraries/LibrariesTranslationRuntimePage.js +42 -0
- package/dist/node/components/docs/libraries/index.js +616 -64
- package/dist/node/components/docs/specs/SpecsDataViewsPage.js +85 -3
- package/dist/node/components/docs/specs/index.js +96 -14
- package/dist/node/index.js +1206 -287
- package/package.json +98 -26
- package/src/components/docs/docsManifest.test.ts +87 -0
- package/src/components/docs/docsManifest.ts +98 -1
- package/src/components/docs/generated/docs-index.notifications.json +7 -7
- package/src/components/docs/getting-started/DataViewTutorialPage.tsx +217 -47
- package/src/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.ts +185 -0
- package/src/components/docs/guides/GuideDataExchangeImportTemplatesPage.tsx +186 -0
- package/src/components/docs/guides/GuidesIndexPage.tsx +49 -42
- package/src/components/docs/guides/index.ts +1 -0
- package/src/components/docs/libraries/LibrariesApplicationShellPage.content.ts +283 -0
- package/src/components/docs/libraries/LibrariesApplicationShellPage.tsx +145 -0
- package/src/components/docs/libraries/LibrariesDataViewsPage.tsx +278 -54
- package/src/components/docs/libraries/LibrariesDesignSystemPage.tsx +244 -0
- package/src/components/docs/libraries/LibrariesOverviewPage.tsx +13 -1
- package/src/components/docs/libraries/LibrariesPersonalizationPage.tsx +141 -31
- package/src/components/docs/libraries/LibrariesTranslationRuntimePage.content.ts +78 -0
- package/src/components/docs/libraries/LibrariesTranslationRuntimePage.tsx +137 -0
- package/src/components/docs/libraries/index.ts +2 -0
- package/src/components/docs/specs/SpecsDataViewsPage.tsx +278 -116
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { CodeBlock, InstallCommand } from '@contractspec/lib.design-system';
|
|
2
|
+
import { Box, HStack, VStack } from '@contractspec/lib.design-system/layout';
|
|
3
|
+
import {
|
|
4
|
+
Code,
|
|
5
|
+
H1,
|
|
6
|
+
H2,
|
|
7
|
+
H3,
|
|
8
|
+
P,
|
|
9
|
+
Text,
|
|
10
|
+
} from '@contractspec/lib.design-system/typography';
|
|
11
|
+
import Link from '@contractspec/lib.ui-link';
|
|
12
|
+
import { ChevronRight } from 'lucide-react';
|
|
13
|
+
import {
|
|
14
|
+
notificationCenterExample,
|
|
15
|
+
notificationGuide,
|
|
16
|
+
refactorPrompt,
|
|
17
|
+
scratchPrompt,
|
|
18
|
+
shellParts,
|
|
19
|
+
shellUsageExample,
|
|
20
|
+
} from './LibrariesApplicationShellPage.content';
|
|
21
|
+
|
|
22
|
+
export function LibrariesApplicationShellPage() {
|
|
23
|
+
return (
|
|
24
|
+
<VStack className="space-y-8">
|
|
25
|
+
<VStack className="space-y-4">
|
|
26
|
+
<H1 className="font-bold text-4xl">Application shell</H1>
|
|
27
|
+
<P className="text-lg text-muted-foreground">
|
|
28
|
+
A reusable navigation system for product apps: desktop sidebar, topbar
|
|
29
|
+
breadcrumbs, command search, account actions, mobile adapters, and a
|
|
30
|
+
Notion-style <Code>PageOutline</Code> for page sections, with
|
|
31
|
+
prop-driven in-app notifications for web and native shells.
|
|
32
|
+
</P>
|
|
33
|
+
</VStack>
|
|
34
|
+
|
|
35
|
+
<VStack className="space-y-4">
|
|
36
|
+
<H2 className="font-bold text-2xl">Installation</H2>
|
|
37
|
+
<InstallCommand package="@contractspec/lib.design-system" />
|
|
38
|
+
</VStack>
|
|
39
|
+
|
|
40
|
+
<VStack className="space-y-4">
|
|
41
|
+
<H2 className="font-bold text-2xl">What It Standardizes</H2>
|
|
42
|
+
<Box className="grid gap-4 md:grid-cols-2">
|
|
43
|
+
{shellParts.map((part) => (
|
|
44
|
+
<Box key={part.title} className="card-subtle p-4">
|
|
45
|
+
<H3 className="font-semibold">{part.title}</H3>
|
|
46
|
+
<P className="mt-2 text-muted-foreground text-sm leading-7">
|
|
47
|
+
{part.body}
|
|
48
|
+
</P>
|
|
49
|
+
</Box>
|
|
50
|
+
))}
|
|
51
|
+
</Box>
|
|
52
|
+
</VStack>
|
|
53
|
+
|
|
54
|
+
<VStack className="space-y-4">
|
|
55
|
+
<H2 className="font-bold text-2xl">Import Surface</H2>
|
|
56
|
+
<P className="text-muted-foreground">
|
|
57
|
+
The shell is exposed as a focused design-system subpath so apps can
|
|
58
|
+
adopt navigation chrome without pulling unrelated documentation or
|
|
59
|
+
marketing helpers.
|
|
60
|
+
</P>
|
|
61
|
+
<CodeBlock
|
|
62
|
+
language="tsx"
|
|
63
|
+
filename="app-shell-example.tsx"
|
|
64
|
+
code={shellUsageExample}
|
|
65
|
+
/>
|
|
66
|
+
</VStack>
|
|
67
|
+
|
|
68
|
+
<VStack className="space-y-4">
|
|
69
|
+
<H2 className="font-bold text-2xl">Notification Center Boundary</H2>
|
|
70
|
+
<P className="text-muted-foreground">
|
|
71
|
+
Notifications are part of the shell experience, but the design system
|
|
72
|
+
only renders the affordance. Contracts, runtime helpers, persistence,
|
|
73
|
+
delivery, auth, and subscriptions stay outside the shell and feed a
|
|
74
|
+
render-ready <Code>ShellNotificationCenter</Code> into{' '}
|
|
75
|
+
<Code>AppShell</Code>.
|
|
76
|
+
</P>
|
|
77
|
+
<Box className="grid gap-4 md:grid-cols-2">
|
|
78
|
+
{notificationGuide.map((part) => (
|
|
79
|
+
<Box key={part.title} className="card-subtle p-4">
|
|
80
|
+
<H3 className="font-semibold">{part.title}</H3>
|
|
81
|
+
<P className="mt-2 text-muted-foreground text-sm leading-7">
|
|
82
|
+
{part.body}
|
|
83
|
+
</P>
|
|
84
|
+
</Box>
|
|
85
|
+
))}
|
|
86
|
+
</Box>
|
|
87
|
+
<CodeBlock
|
|
88
|
+
language="tsx"
|
|
89
|
+
filename="notification-center-boundary.ts"
|
|
90
|
+
code={notificationCenterExample}
|
|
91
|
+
/>
|
|
92
|
+
</VStack>
|
|
93
|
+
|
|
94
|
+
<VStack className="space-y-4">
|
|
95
|
+
<H2 className="font-bold text-2xl">AI Prompt: Build From Scratch</H2>
|
|
96
|
+
<P className="text-muted-foreground">
|
|
97
|
+
Use this prompt when the app does not already have a shell, command
|
|
98
|
+
surface, page outline, or in-app notification center.
|
|
99
|
+
</P>
|
|
100
|
+
<CodeBlock
|
|
101
|
+
language="markdown"
|
|
102
|
+
filename="implement-application-shell.md"
|
|
103
|
+
code={scratchPrompt}
|
|
104
|
+
/>
|
|
105
|
+
</VStack>
|
|
106
|
+
|
|
107
|
+
<VStack className="space-y-4">
|
|
108
|
+
<H2 className="font-bold text-2xl">AI Prompt: Refactor An App</H2>
|
|
109
|
+
<P className="text-muted-foreground">
|
|
110
|
+
Use this prompt when an app already has custom navigation chrome and
|
|
111
|
+
notification UI that need to migrate without breaking route behavior,
|
|
112
|
+
unread counts, or delivery semantics.
|
|
113
|
+
</P>
|
|
114
|
+
<CodeBlock
|
|
115
|
+
language="markdown"
|
|
116
|
+
filename="refactor-to-application-shell.md"
|
|
117
|
+
code={refactorPrompt}
|
|
118
|
+
/>
|
|
119
|
+
</VStack>
|
|
120
|
+
|
|
121
|
+
<VStack className="card-subtle space-y-3 p-6">
|
|
122
|
+
<H2 className="font-bold text-2xl">Naming</H2>
|
|
123
|
+
<P className="text-muted-foreground">
|
|
124
|
+
Use <Code>AppShell</Code> for the whole navigation frame and{' '}
|
|
125
|
+
<Code>PageOutline</Code> for the in-page navigation helper. The latter
|
|
126
|
+
is the product-app equivalent of a table of contents, but it is
|
|
127
|
+
intentionally named for live page sections rather than static
|
|
128
|
+
documentation. Use <Code>ShellNotifications</Code> for the
|
|
129
|
+
notification affordance when it is rendered directly, or pass the same
|
|
130
|
+
data contract through <Code>AppShell</Code> with the{' '}
|
|
131
|
+
<Code>notifications</Code> prop.
|
|
132
|
+
</P>
|
|
133
|
+
</VStack>
|
|
134
|
+
|
|
135
|
+
<HStack className="flex flex-wrap items-center gap-3 pt-2">
|
|
136
|
+
<Link href="/docs/libraries/cross-platform-ui" className="btn-ghost">
|
|
137
|
+
<Text>Cross-platform UI</Text>
|
|
138
|
+
</Link>
|
|
139
|
+
<Link href="/docs/libraries/design-system" className="btn-primary">
|
|
140
|
+
<Text>Design System</Text> <ChevronRight size={16} />
|
|
141
|
+
</Link>
|
|
142
|
+
</HStack>
|
|
143
|
+
</VStack>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
@@ -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
|
-
<
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
The <
|
|
12
|
-
<
|
|
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
|
-
</
|
|
16
|
-
</
|
|
148
|
+
</P>
|
|
149
|
+
</VStack>
|
|
17
150
|
|
|
18
|
-
<
|
|
19
|
-
<
|
|
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
|
-
</
|
|
159
|
+
</VStack>
|
|
27
160
|
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
<
|
|
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
|
-
</
|
|
167
|
+
</P>
|
|
35
168
|
|
|
36
169
|
<CodeBlock
|
|
37
170
|
language="tsx"
|
|
@@ -50,59 +183,150 @@ export function UserPage() {
|
|
|
50
183
|
}`}
|
|
51
184
|
/>
|
|
52
185
|
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
<
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
81
298
|
DataView parameters (filters, sorting, pagination) into query
|
|
82
299
|
arguments for your backend.
|
|
83
|
-
</
|
|
300
|
+
</P>
|
|
84
301
|
<CodeBlock
|
|
85
302
|
language="typescript"
|
|
86
303
|
code={`import { DataViewQueryGenerator } from '@contractspec/lib.contracts-spec/data-views/query-generator';
|
|
87
304
|
|
|
88
305
|
const generator = new DataViewQueryGenerator(MyUserList);
|
|
89
|
-
const
|
|
306
|
+
const params = {
|
|
90
307
|
pagination: { page: 1, pageSize: 20 },
|
|
91
|
-
filters: {
|
|
92
|
-
}
|
|
308
|
+
filters: {
|
|
309
|
+
role: { kind: 'single', value: 'admin' },
|
|
310
|
+
revenue: { kind: 'range', from: 1000, to: 5000 },
|
|
311
|
+
lastSeenAt: { kind: 'single', value: '2026-04-28T08:30:00Z' }
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const errors = generator.validateParams(params);
|
|
316
|
+
const query = generator.generate(params);
|
|
93
317
|
|
|
94
|
-
// query.input contains
|
|
318
|
+
// query.input contains skip/take plus the typed filter payloads.`}
|
|
95
319
|
/>
|
|
96
|
-
</
|
|
320
|
+
</VStack>
|
|
97
321
|
|
|
98
|
-
<
|
|
322
|
+
<HStack className="items-center gap-4 pt-4">
|
|
99
323
|
<Link href="/docs/libraries" className="btn-ghost">
|
|
100
|
-
Back to Libraries
|
|
324
|
+
<Text>Back to Libraries</Text>
|
|
101
325
|
</Link>
|
|
102
326
|
<Link href="/docs/libraries/data-backend" className="btn-primary">
|
|
103
|
-
Next: Data & Backend <ChevronRight size={16} />
|
|
327
|
+
<Text>Next: Data & Backend</Text> <ChevronRight size={16} />
|
|
104
328
|
</Link>
|
|
105
|
-
</
|
|
106
|
-
</
|
|
329
|
+
</HStack>
|
|
330
|
+
</VStack>
|
|
107
331
|
);
|
|
108
332
|
}
|