@os-legal/ui 0.1.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 ADDED
@@ -0,0 +1,347 @@
1
+ # OpenContracts Component Library
2
+
3
+ A React component library implementing the OpenContracts design system — built around **transparent infrastructure**, **visible connections**, and **warm precision**.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install github:Open-Source-Legal/OS-Legal-Style
9
+ # or
10
+ yarn add github:Open-Source-Legal/OS-Legal-Style
11
+ ```
12
+
13
+ Or add to your `package.json`:
14
+
15
+ ```json
16
+ {
17
+ "dependencies": {
18
+ "@opencontracts/ui": "github:Open-Source-Legal/OS-Legal-Style"
19
+ }
20
+ }
21
+ ```
22
+
23
+ ## Setup
24
+
25
+ ### 1. Import Styles
26
+
27
+ Import the combined styles at your app's root:
28
+
29
+ ```tsx
30
+ // App.tsx or index.tsx
31
+ import { allStyles } from '@opencontracts/ui';
32
+
33
+ // Inject styles (or use your preferred method)
34
+ const styleEl = document.createElement('style');
35
+ styleEl.textContent = allStyles;
36
+ document.head.appendChild(styleEl);
37
+ ```
38
+
39
+ ### 2. Add Fonts
40
+
41
+ The design system uses Inter for UI and Georgia for headlines:
42
+
43
+ ```html
44
+ <link rel="preconnect" href="https://fonts.googleapis.com">
45
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
46
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ ```tsx
52
+ import { Button, Card, CardHeader, CardBody, SearchBox, StatBlock } from '@opencontracts/ui';
53
+
54
+ function App() {
55
+ return (
56
+ <Card>
57
+ <CardHeader
58
+ title="Contract Analysis"
59
+ subtitle="3 documents reviewed"
60
+ />
61
+ <CardBody>
62
+ <SearchBox
63
+ placeholder="Search contracts..."
64
+ onSubmit={(value) => console.log(value)}
65
+ />
66
+ <StatBlock value="142K" label="Annotations" sublabel="community contributed" />
67
+ </CardBody>
68
+ <div style={{ display: 'flex', gap: '8px', marginTop: '16px' }}>
69
+ <Button variant="primary">Accept All</Button>
70
+ <Button variant="secondary">Review</Button>
71
+ </div>
72
+ </Card>
73
+ );
74
+ }
75
+ ```
76
+
77
+ ## Components
78
+
79
+ ### Layout
80
+
81
+ | Component | Description |
82
+ |-----------|-------------|
83
+ | `AppShell` | Application shell with sidebar, header, and main content |
84
+ | `PageHeader` | Page title with breadcrumbs and actions |
85
+ | `SplitPane` | Resizable split panel layout |
86
+ | `Stack` / `HStack` / `VStack` | Flexbox layout utilities |
87
+ | `ScrollArea` | Custom scrollable container |
88
+ | `Card` | Container with Header, Body, Footer subcomponents |
89
+ | `Sidebar` | Dark navigation sidebar with sections |
90
+
91
+ ### Forms
92
+
93
+ | Component | Description |
94
+ |-----------|-------------|
95
+ | `Button` / `IconButton` | Primary, secondary, ghost, danger variants |
96
+ | `Input` | Text input with label, helper text, error states |
97
+ | `Textarea` | Multi-line input with auto-resize |
98
+ | `Select` | Native select with consistent styling |
99
+ | `Checkbox` / `CheckboxGroup` | Checkbox inputs with labels |
100
+ | `Radio` / `RadioGroup` | Radio button inputs |
101
+ | `Toggle` / `Switch` | Toggle switches |
102
+ | `FormField` | Form field wrapper with label and validation |
103
+ | `SearchBox` | Search input with icon and submit button |
104
+
105
+ ### Data Display
106
+
107
+ | Component | Description |
108
+ |-----------|-------------|
109
+ | `Avatar` / `AvatarGroup` | User avatars with status indicators |
110
+ | `Chip` / `ChipGroup` | Tags, labels, and filter chips |
111
+ | `StatBlock` / `StatGrid` | Large number stats with labels |
112
+ | `CollectionCard` | List cards with type icons and badges |
113
+ | `ActivityFeed` | Timeline with avatars and actions |
114
+ | `SourceCard` / `Citation` | Document source cards and citations |
115
+
116
+ ### Navigation
117
+
118
+ | Component | Description |
119
+ |-----------|-------------|
120
+ | `Tabs` | Tab navigation with panels |
121
+ | `FilterTabs` | Pill-style category filters with counts |
122
+ | `ActionList` | Clickable action items with icons |
123
+
124
+ ### Feedback
125
+
126
+ | Component | Description |
127
+ |-----------|-------------|
128
+ | `Toast` / `ToastProvider` | Toast notifications |
129
+ | `Alert` / `Banner` | Alert messages and banners |
130
+ | `Progress` / `ProgressCircle` | Progress indicators |
131
+ | `Spinner` | Loading spinner |
132
+ | `Skeleton` | Loading skeleton placeholders |
133
+ | `EmptyState` | Empty state illustrations |
134
+
135
+ ### Overlay
136
+
137
+ | Component | Description |
138
+ |-----------|-------------|
139
+ | `Modal` | Modal dialogs with Header, Body, Footer |
140
+ | `Tooltip` | Hover tooltips |
141
+ | `Popover` | Click-triggered popovers |
142
+
143
+ ### Chat & AI
144
+
145
+ | Component | Description |
146
+ |-----------|-------------|
147
+ | `ChatMessage` | Chat message bubbles |
148
+ | `ChatInput` | Chat text input with actions |
149
+ | `ChatContainer` | Chat layout container |
150
+ | `ThinkingBlock` | AI thinking/processing indicator |
151
+ | `TypingIndicator` | Typing animation |
152
+ | `TaskCard` | Task status cards |
153
+ | `ResearchCard` | AI research response cards |
154
+
155
+ ### Content
156
+
157
+ | Component | Description |
158
+ |-----------|-------------|
159
+ | `Hero` | Hero sections with search and actions |
160
+ | `SearchInput` | Search with suggestions |
161
+ | `ProjectPicker` | Project selection dropdown |
162
+ | `SourcesPanel` | Sources and files panel |
163
+
164
+ ## Component API Examples
165
+
166
+ ### SearchBox
167
+
168
+ ```tsx
169
+ <SearchBox
170
+ placeholder="Search across all legal knowledge..."
171
+ value={searchValue}
172
+ onChange={(e) => setSearchValue(e.target.value)}
173
+ onSubmit={(value) => handleSearch(value)}
174
+ buttonText="Search"
175
+ size="md" // sm | md | lg
176
+ />
177
+ ```
178
+
179
+ ### FilterTabs
180
+
181
+ ```tsx
182
+ <FilterTabs
183
+ items={[
184
+ { id: 'all', label: 'All' },
185
+ { id: 'legislation', label: 'Legislation', count: '2.4K' },
186
+ { id: 'contracts', label: 'Contracts', count: '12K' },
187
+ ]}
188
+ value={activeTab}
189
+ onChange={setActiveTab}
190
+ variant="pill" // pill | underline
191
+ />
192
+ ```
193
+
194
+ ### StatBlock & StatGrid
195
+
196
+ ```tsx
197
+ <StatGrid columns={2}>
198
+ <StatBlock value="23K+" label="Documents" sublabel="across all domains" />
199
+ <StatBlock value="142K" label="Annotations" sublabel="community contributed" />
200
+ </StatGrid>
201
+ ```
202
+
203
+ ### CollectionCard
204
+
205
+ ```tsx
206
+ <CollectionCard
207
+ type="legislation" // legislation | contracts | case-law | knowledge
208
+ badge="Legislation"
209
+ status="Active discussion"
210
+ title="US Federal Code - Annotated"
211
+ description="Complete USC with community annotations..."
212
+ stats={['54 titles', '34.2K annotations', '156 contributors']}
213
+ onClick={() => navigate('/collection/1')}
214
+ />
215
+ ```
216
+
217
+ ### ActivityFeed
218
+
219
+ ```tsx
220
+ <ActivityFeed
221
+ items={[
222
+ {
223
+ id: 1,
224
+ name: 'Sarah Chen',
225
+ initials: 'SC',
226
+ avatarColor: '#3B82F6',
227
+ action: 'annotated',
228
+ target: 'Liability Clause Analysis',
229
+ time: '12m ago',
230
+ },
231
+ ]}
232
+ viewAllUrl="/activity"
233
+ viewAllText="View all activity"
234
+ />
235
+ ```
236
+
237
+ ### ActionList
238
+
239
+ ```tsx
240
+ <ActionList
241
+ items={[
242
+ { id: 1, label: 'Upload document', icon: <UploadIcon /> },
243
+ { id: 2, label: 'Join project', icon: <JoinIcon /> },
244
+ ]}
245
+ variant="card" // default | card
246
+ onItemClick={(item) => console.log(item.label)}
247
+ />
248
+ ```
249
+
250
+ ### Button
251
+
252
+ ```tsx
253
+ <Button
254
+ variant="primary" // primary | secondary | ghost | danger
255
+ size="md" // sm | md | lg
256
+ loading={false}
257
+ fullWidth={false}
258
+ leftIcon={<Icon />}
259
+ disabled={false}
260
+ >
261
+ Label
262
+ </Button>
263
+ ```
264
+
265
+ ### Card
266
+
267
+ ```tsx
268
+ <Card variant="elevated" padding="md">
269
+ <CardHeader
270
+ title="Title"
271
+ subtitle="Subtitle"
272
+ action={<Button size="sm">Action</Button>}
273
+ />
274
+ <CardBody>Content here</CardBody>
275
+ <CardFooter>Footer actions</CardFooter>
276
+ </Card>
277
+ ```
278
+
279
+ ## Design Principles
280
+
281
+ 1. **Structure over decoration** — No heavy borders; shadows define boundaries
282
+ 2. **Connections matter** — Visual elements show relationships between documents
283
+ 3. **Light touch** — Subtle shadows (0.03-0.06 opacity), never harsh
284
+ 4. **Professional precision** — Deep teal accent (`#0F766E`) conveys trust and expertise
285
+
286
+ ## Color Palette
287
+
288
+ | Token | Value | Usage |
289
+ |-------|-------|-------|
290
+ | `--oc-accent` | `#0F766E` | Primary actions, active states, links |
291
+ | `--oc-accent-hover` | `#0D9488` | Hover state for accent elements |
292
+ | `--oc-fg-primary` | `#1E293B` | Primary text (slate-800) |
293
+ | `--oc-fg-secondary` | `#475569` | Secondary text (slate-600) |
294
+ | `--oc-fg-tertiary` | `#94A3B8` | Tertiary/muted text (slate-400) |
295
+ | `--oc-bg-canvas` | `#FAFAFA` | Page background |
296
+ | `--oc-bg-surface` | `#FFFFFF` | Card/surface backgrounds |
297
+ | `--oc-bg-sidebar` | `#0F172A` | Dark sidebar background |
298
+ | `--oc-border-default` | `#E2E8F0` | Default borders (slate-200) |
299
+ | `--oc-success` | `#059669` | Success states |
300
+ | `--oc-warning` | `#D97706` | Warning states |
301
+ | `--oc-error` | `#DC2626` | Error states |
302
+
303
+ ## Typography
304
+
305
+ - **UI Text**: Inter (400, 500, 600, 700)
306
+ - **Headlines**: Georgia (serif) for editorial feel
307
+ - **Font Sizes**: xs (11px), sm (13px), md (15px), lg (17px), xl (20px)
308
+
309
+ ## Spacing & Radius
310
+
311
+ | Token | Value |
312
+ |-------|-------|
313
+ | `--oc-spacing-xs` | 4px |
314
+ | `--oc-spacing-sm` | 8px |
315
+ | `--oc-spacing-md` | 16px |
316
+ | `--oc-spacing-lg` | 24px |
317
+ | `--oc-radius-sm` | 6px |
318
+ | `--oc-radius-md` | 8px |
319
+ | `--oc-radius-lg` | 12px |
320
+
321
+ ## TypeScript
322
+
323
+ All components are fully typed. Import types as needed:
324
+
325
+ ```tsx
326
+ import type {
327
+ ButtonProps,
328
+ CardProps,
329
+ SearchBoxProps,
330
+ FilterTabsProps,
331
+ CollectionCardProps,
332
+ } from '@opencontracts/ui';
333
+ ```
334
+
335
+ ## Development
336
+
337
+ ```bash
338
+ npm run dev # Watch mode
339
+ npm run build # Build library
340
+ npm run storybook # Start Storybook on port 6006
341
+ npm run lint # Run ESLint
342
+ npm run test # Run tests
343
+ ```
344
+
345
+ ## License
346
+
347
+ MIT © OpenContracts