@oods/components-react 0.3.2 → 0.4.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.
@@ -3,7 +3,7 @@
3
3
  "mission": "s193-m05",
4
4
  "target": "react",
5
5
  "contractVersion": "1.1.0",
6
- "derivation": "Each emissionEligible value is asserted with @oods/component-contracts evaluateEmissionEligibility. Sprint 185 additions have built public declarations and passing shared scenarios, breadth, server-render and accessibility tests; prior nucleus row evidence is preserved. Sprint 186 wave 2 appends ClassificationPanel, FilterPanel, PriceSummary, AddressCollectionPanel, MembershipPanel, PreferencePanel, TagManager, AddressSummaryBadge, MessageStatusBadge, PreferenceSummaryBadge, RoleBadgeList, TagPills, AddressValidationTimeline, AuditEvent, MembershipAuditTimeline, MessageEventTimeline, PreferenceTimeline, AddressEditor, PreferenceEditor, RoleAssignmentForm, StatusSelector, TagInput and TemplatePicker root exports with the same six evidence classes; prior rows are preserved. Sprint 186 m06 folds the former eight ported families into the root contract, exports, declarations and shared scenarios. Historical readiness files remain as evidence; readiness-ported resolved to this root document from Sprint 186 m06 until Sprint 200 m04 retired that subpath, and this root document is now the only readiness export. Sprint 187 m02 adds five naming/classification families with the same six evidence classes. Native classification controls are presentational; no save or domain-change action is claimed. Sprint 187 m03 adds OwnerBadge, OwnershipSummary, OwnershipMeta and TagSummary with the same six reference classes and explicit scalar/trait-array semantics. No ownership transfer or tagging action is claimed. Sprint 192 m03 projects passing per-root axe and executable scenario results into accessibility and interaction evidence; native unwired controls are measured without claiming a domain action. Sprint 192 m04 projects per-root six-cell browser contrast/token checks and screenshot hashes into visualThemes. Sprint 192 m05 adds the three retained roots and derives all accessibility, interaction and theme claims from passing 75-root measurements. Sprint 193 m04 adds nine declared non-Viz recipes and derives all accessibility, interaction and theme claims from passing 84-root measurements. Sprint 193 m05 adds 25 typed Viz recipes and derives all accessibility, interaction and theme claims from passing 109-root measurements.",
6
+ "derivation": "Each emissionEligible value is asserted with @oods/component-contracts evaluateEmissionEligibility. Sprint 185 additions have built public declarations and passing shared scenarios, breadth, server-render and accessibility tests; prior nucleus row evidence is preserved. Sprint 186 wave 2 appends ClassificationPanel, FilterPanel, PriceSummary, AddressCollectionPanel, MembershipPanel, PreferencePanel, TagManager, AddressSummaryBadge, MessageStatusBadge, PreferenceSummaryBadge, RoleBadgeList, TagPills, AddressValidationTimeline, AuditEvent, MembershipAuditTimeline, MessageEventTimeline, PreferenceTimeline, AddressEditor, PreferenceEditor, RoleAssignmentForm, StatusSelector, TagInput and TemplatePicker root exports with the same six evidence classes; prior rows are preserved. Sprint 186 m06 folds the former eight ported families into the root contract, exports, declarations and shared scenarios. Historical readiness files remain as evidence; readiness-ported resolved to this root document from Sprint 186 m06 until Sprint 200 m04 retired that subpath, and this root document is now the only readiness export. Sprint 187 m02 adds five naming/classification families with the same six evidence classes. Native classification controls are presentational; no save or domain-change action is claimed. Sprint 187 m03 adds OwnerBadge, OwnershipSummary, OwnershipMeta and TagSummary with the same six reference classes and explicit scalar/trait-array semantics. No ownership transfer or tagging action is claimed. Sprint 192 m03 projects passing per-root axe and executable scenario results into accessibility and interaction evidence; native unwired controls are measured without claiming a domain action. Sprint 192 m04 projects per-root six-cell browser contrast/token checks and screenshot hashes into visualThemes. Sprint 192 m05 adds the three retained roots and derives all accessibility, interaction and theme claims from passing 75-root measurements. Sprint 193 m04 adds nine declared non-Viz recipes and derives all accessibility, interaction and theme claims from passing 84-root measurements. Sprint 193 m05 adds 25 typed Viz recipes and derives all accessibility, interaction and theme claims from passing 109-root measurements. Sprint 222 m02 adds Switch and Dialog with the same six evidence classes and derives their accessibility, interaction and theme claims from passing 112-root measurements.",
7
7
  "rows": [
8
8
  {
9
9
  "componentId": "AddressCollectionPanel",
@@ -2550,6 +2550,79 @@
2550
2550
  }
2551
2551
  }
2552
2552
  },
2553
+ {
2554
+ "componentId": "Dialog",
2555
+ "state": "implemented-evidence-complete",
2556
+ "emissionEligible": true,
2557
+ "evidence": {
2558
+ "versionedContract": {
2559
+ "status": "passed",
2560
+ "refs": [
2561
+ "packages/component-contracts/src/contracts.ts#Dialog"
2562
+ ]
2563
+ },
2564
+ "targetImplementation": {
2565
+ "status": "passed",
2566
+ "refs": [
2567
+ "packages/components-react/src/presentational.tsx#Dialog"
2568
+ ]
2569
+ },
2570
+ "packageExport": {
2571
+ "status": "passed",
2572
+ "refs": [
2573
+ "packages/components-react/src/index.ts#Dialog"
2574
+ ]
2575
+ },
2576
+ "publicDeclaration": {
2577
+ "status": "passed",
2578
+ "refs": [
2579
+ "packages/components-react/dist/index.d.ts#Dialog"
2580
+ ]
2581
+ },
2582
+ "dependencyClosure": {
2583
+ "status": "passed",
2584
+ "refs": [
2585
+ "packages/components-react/test/package-contract.spec.ts#dependency-closure"
2586
+ ]
2587
+ },
2588
+ "frameworkScenario": {
2589
+ "status": "passed",
2590
+ "refs": [
2591
+ "packages/components-react/test/scenarios.spec.tsx#dialog-confirm"
2592
+ ]
2593
+ },
2594
+ "accessibility": {
2595
+ "status": "passed",
2596
+ "classification": "verified",
2597
+ "refs": [
2598
+ "artifacts/product-reality/sprint-222/m02/switch-dialog/react-measured.json#Dialog"
2599
+ ]
2600
+ },
2601
+ "interaction": {
2602
+ "status": "passed",
2603
+ "classification": "verified",
2604
+ "refs": [
2605
+ "artifacts/product-reality/sprint-222/m02/switch-dialog/react-measured.json#Dialog"
2606
+ ]
2607
+ },
2608
+ "visualThemes": {
2609
+ "status": "passed",
2610
+ "classification": "verified",
2611
+ "cells": [
2612
+ "A-light",
2613
+ "A-dark",
2614
+ "A-hc",
2615
+ "B-light",
2616
+ "B-dark",
2617
+ "B-hc"
2618
+ ],
2619
+ "refs": [
2620
+ "artifacts/product-reality/sprint-222/m02/switch-dialog/react-theme/report.json#Dialog"
2621
+ ]
2622
+ }
2623
+ },
2624
+ "measurementRoot": "artifacts/product-reality/sprint-222/m02/switch-dialog"
2625
+ },
2553
2626
  {
2554
2627
  "componentId": "FilterPanel",
2555
2628
  "state": "implemented-evidence-complete",
@@ -5314,6 +5387,79 @@
5314
5387
  }
5315
5388
  }
5316
5389
  },
5390
+ {
5391
+ "componentId": "Switch",
5392
+ "state": "implemented-evidence-complete",
5393
+ "emissionEligible": true,
5394
+ "evidence": {
5395
+ "versionedContract": {
5396
+ "status": "passed",
5397
+ "refs": [
5398
+ "packages/component-contracts/src/contracts.ts#Switch"
5399
+ ]
5400
+ },
5401
+ "targetImplementation": {
5402
+ "status": "passed",
5403
+ "refs": [
5404
+ "packages/components-react/src/fields.tsx#Switch"
5405
+ ]
5406
+ },
5407
+ "packageExport": {
5408
+ "status": "passed",
5409
+ "refs": [
5410
+ "packages/components-react/src/index.ts#Switch"
5411
+ ]
5412
+ },
5413
+ "publicDeclaration": {
5414
+ "status": "passed",
5415
+ "refs": [
5416
+ "packages/components-react/dist/index.d.ts#Switch"
5417
+ ]
5418
+ },
5419
+ "dependencyClosure": {
5420
+ "status": "passed",
5421
+ "refs": [
5422
+ "packages/components-react/test/package-contract.spec.ts#dependency-closure"
5423
+ ]
5424
+ },
5425
+ "frameworkScenario": {
5426
+ "status": "passed",
5427
+ "refs": [
5428
+ "packages/components-react/test/scenarios.spec.tsx#switch-controlled"
5429
+ ]
5430
+ },
5431
+ "accessibility": {
5432
+ "status": "passed",
5433
+ "classification": "verified",
5434
+ "refs": [
5435
+ "artifacts/product-reality/sprint-222/m02/switch-dialog/react-measured.json#Switch"
5436
+ ]
5437
+ },
5438
+ "interaction": {
5439
+ "status": "passed",
5440
+ "classification": "verified",
5441
+ "refs": [
5442
+ "artifacts/product-reality/sprint-222/m02/switch-dialog/react-measured.json#Switch"
5443
+ ]
5444
+ },
5445
+ "visualThemes": {
5446
+ "status": "passed",
5447
+ "classification": "verified",
5448
+ "cells": [
5449
+ "A-light",
5450
+ "A-dark",
5451
+ "A-hc",
5452
+ "B-light",
5453
+ "B-dark",
5454
+ "B-hc"
5455
+ ],
5456
+ "refs": [
5457
+ "artifacts/product-reality/sprint-222/m02/switch-dialog/react-theme/report.json#Switch"
5458
+ ]
5459
+ }
5460
+ },
5461
+ "measurementRoot": "artifacts/product-reality/sprint-222/m02/switch-dialog"
5462
+ },
5317
5463
  {
5318
5464
  "componentId": "Table",
5319
5465
  "state": "implemented-evidence-complete",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oods/components-react",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "React components for OODS Foundry: the controls, layouts and domain views its generated screens use.",
5
5
  "homepage": "https://oods-foundry.com/",
6
6
  "bugs": {
@@ -64,8 +64,8 @@
64
64
  ],
65
65
  "dependencies": {
66
66
  "@radix-ui/react-slot": "^1.1.2",
67
- "@oods/component-contracts": "0.3.2",
68
- "@oods/component-styles": "0.3.2"
67
+ "@oods/component-contracts": "0.4.0",
68
+ "@oods/component-styles": "0.4.0"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "react": ">=18 <20",
@@ -1,338 +0,0 @@
1
- // src/status-map.json
2
- var status_map_default = {
3
- domains: {
4
- subscription: {
5
- future: {
6
- description: "Subscription is scheduled but not yet active.",
7
- chip: {
8
- foreground: "color.text.info",
9
- background: "color.background.info.subtle",
10
- border: "color.border.info",
11
- icon: "icon.status.scheduled"
12
- },
13
- banner: {
14
- foreground: "color.text.info",
15
- background: "color.background.surface.default",
16
- border: "color.border.info",
17
- icon: "icon.status.scheduled"
18
- }
19
- },
20
- trialing: {
21
- description: "Subscription is in a trial period before billing begins.",
22
- chip: {
23
- foreground: "color.text.accent",
24
- background: "color.background.accent.subtle",
25
- border: "color.border.accent",
26
- icon: "icon.status.trial"
27
- },
28
- banner: {
29
- foreground: "color.text.accent",
30
- background: "color.background.surface.default",
31
- border: "color.border.accent",
32
- icon: "icon.status.trial"
33
- }
34
- },
35
- active: {
36
- description: "Subscription is paid and service is provisioned.",
37
- chip: {
38
- foreground: "color.text.positive",
39
- background: "color.background.positive.subtle",
40
- border: "color.border.positive",
41
- icon: "icon.status.success"
42
- },
43
- banner: {
44
- foreground: "color.text.positive",
45
- background: "color.background.surface.default",
46
- border: "color.border.positive",
47
- icon: "icon.status.success"
48
- }
49
- },
50
- paused: {
51
- description: "Billing paused temporarily by finance or customer request.",
52
- chip: {
53
- foreground: "color.text.neutral",
54
- background: "color.background.neutral.subtle",
55
- border: "color.border.neutral",
56
- icon: "icon.status.paused"
57
- },
58
- banner: {
59
- foreground: "color.text.neutral",
60
- background: "color.background.surface.muted",
61
- border: "color.border.neutral",
62
- icon: "icon.status.paused"
63
- }
64
- },
65
- pending_cancellation: {
66
- description: "Subscription will cancel at period end but remains active now.",
67
- chip: {
68
- foreground: "color.text.info",
69
- background: "color.background.info.subtle",
70
- border: "color.border.info",
71
- icon: "icon.status.pending"
72
- },
73
- banner: {
74
- foreground: "color.text.info",
75
- background: "color.background.surface.default",
76
- border: "color.border.info",
77
- icon: "icon.status.pending"
78
- }
79
- },
80
- past_due: {
81
- description: "Renewal payment failed; smart retries ongoing and access retained during the grace window.",
82
- chip: {
83
- foreground: "color.text.danger",
84
- background: "color.background.danger.subtle",
85
- border: "color.border.danger",
86
- icon: "icon.status.warning"
87
- },
88
- banner: {
89
- foreground: "color.text.onbold",
90
- background: "color.background.danger.bold",
91
- border: "color.border.danger",
92
- icon: "icon.status.warning"
93
- }
94
- },
95
- unpaid: {
96
- description: "Payment retries exhausted; service access revoked.",
97
- chip: {
98
- foreground: "color.text.danger",
99
- background: "color.background.danger.subtle",
100
- border: "color.border.danger",
101
- icon: "icon.status.error"
102
- },
103
- banner: {
104
- foreground: "color.text.onbold",
105
- background: "color.background.danger.bold",
106
- border: "color.border.danger",
107
- icon: "icon.status.error"
108
- }
109
- },
110
- terminated: {
111
- description: "Subscription ended; service access revoked and billing stopped.",
112
- chip: {
113
- foreground: "color.text.disabled",
114
- background: "color.background.disabled",
115
- border: "color.border.disabled",
116
- icon: "icon.status.canceled"
117
- },
118
- banner: {
119
- foreground: "color.text.neutral",
120
- background: "color.background.neutral.subtle",
121
- border: "color.border.neutral",
122
- icon: "icon.status.canceled"
123
- }
124
- }
125
- },
126
- invoice: {
127
- draft: {
128
- description: "Invoice is editable and not yet finalized.",
129
- chip: {
130
- foreground: "color.text.neutral",
131
- background: "color.background.neutral.subtle",
132
- border: "color.border.neutral",
133
- icon: "icon.status.draft"
134
- },
135
- banner: {
136
- foreground: "color.text.neutral",
137
- background: "color.background.surface.muted",
138
- border: "color.border.neutral",
139
- icon: "icon.status.draft"
140
- }
141
- },
142
- posted: {
143
- description: "Invoice finalized with terms before collection.",
144
- chip: {
145
- foreground: "color.text.info",
146
- background: "color.background.info.subtle",
147
- border: "color.border.info",
148
- icon: "icon.status.pending"
149
- },
150
- banner: {
151
- foreground: "color.text.info",
152
- background: "color.background.surface.default",
153
- border: "color.border.info",
154
- icon: "icon.status.pending"
155
- }
156
- },
157
- paid: {
158
- description: "Invoice collected successfully in full.",
159
- chip: {
160
- foreground: "color.text.positive",
161
- background: "color.background.positive.subtle",
162
- border: "color.border.positive",
163
- icon: "icon.status.success"
164
- },
165
- banner: {
166
- foreground: "color.text.positive",
167
- background: "color.background.surface.default",
168
- border: "color.border.positive",
169
- icon: "icon.status.success"
170
- }
171
- },
172
- past_due: {
173
- description: "Invoice is unpaid past its due date.",
174
- chip: {
175
- foreground: "color.text.danger",
176
- background: "color.background.danger.subtle",
177
- border: "color.border.danger",
178
- icon: "icon.status.error"
179
- },
180
- banner: {
181
- foreground: "color.text.onbold",
182
- background: "color.background.danger.bold",
183
- border: "color.border.danger",
184
- icon: "icon.status.error"
185
- }
186
- },
187
- void: {
188
- description: "Invoice canceled and no longer payable.",
189
- chip: {
190
- foreground: "color.text.disabled",
191
- background: "color.background.disabled",
192
- border: "color.border.disabled",
193
- icon: "icon.status.void"
194
- },
195
- banner: {
196
- foreground: "color.text.neutral",
197
- background: "color.background.neutral.subtle",
198
- border: "color.border.neutral",
199
- icon: "icon.status.void"
200
- }
201
- }
202
- }
203
- }
204
- };
205
-
206
- // src/status.ts
207
- var TONE_ALIASES = {
208
- info: "info",
209
- informational: "info",
210
- accent: "accent",
211
- highlight: "accent",
212
- positive: "success",
213
- success: "success",
214
- ok: "success",
215
- warning: "warning",
216
- caution: "warning",
217
- danger: "critical",
218
- critical: "critical",
219
- error: "critical",
220
- negative: "critical",
221
- neutral: "neutral",
222
- pending: "info"
223
- };
224
- var toLabel = (status) => status.split(/[_-]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
225
- var inferTone = (entry) => {
226
- if (!entry) return "neutral";
227
- for (const reference of [entry.foreground, entry.background, entry.border]) {
228
- const segments = reference.replace(/^\{|\}$/g, "").split(/[\s./_-]+/).reverse();
229
- for (const segment of segments) {
230
- const tone = TONE_ALIASES[segment.toLowerCase()];
231
- if (tone) return tone;
232
- }
233
- }
234
- return "neutral";
235
- };
236
- var componentTokenSet = (tone) => {
237
- const normalized = tone === "positive" ? "success" : tone === "danger" ? "critical" : tone;
238
- return {
239
- background: `var(--sys-status-${normalized}-surface)`,
240
- border: `var(--sys-status-${normalized}-border)`,
241
- foreground: `var(--sys-status-${normalized}-text)`
242
- };
243
- };
244
- var rawTokenSet = (entry) => {
245
- const tone = inferTone(entry);
246
- return componentTokenSet(tone);
247
- };
248
- var bannerFallback = (tone) => tone === "neutral" ? {
249
- background: "var(--cmp-banner-background)",
250
- border: "var(--cmp-banner-border)",
251
- foreground: "var(--cmp-banner-text)"
252
- } : componentTokenSet(tone);
253
- var fallback = (domain, status, tone = "neutral") => ({
254
- domain,
255
- status,
256
- label: toLabel(status || "Unknown"),
257
- description: "Status not found in registry; falling back to the requested token set.",
258
- tone,
259
- badge: { subtle: componentTokenSet(tone), solid: componentTokenSet(tone) },
260
- banner: { subtle: bannerFallback(tone), solid: componentTokenSet(tone) }
261
- });
262
- var registry = /* @__PURE__ */ new Map();
263
- for (const [domain, entries] of Object.entries(status_map_default.domains)) {
264
- const domainEntries = /* @__PURE__ */ new Map();
265
- for (const [status, entry] of Object.entries(entries)) {
266
- const tone = inferTone(entry.chip);
267
- domainEntries.set(status.toLowerCase(), {
268
- domain,
269
- status,
270
- label: toLabel(status),
271
- description: entry.description,
272
- tone,
273
- iconName: entry.chip.icon ?? entry.banner?.icon,
274
- badge: { subtle: rawTokenSet(entry.chip), solid: componentTokenSet(tone) },
275
- banner: {
276
- subtle: entry.banner ? rawTokenSet(entry.banner) : bannerFallback(tone),
277
- solid: componentTokenSet(tone)
278
- }
279
- });
280
- }
281
- registry.set(domain, domainEntries);
282
- }
283
- var LEGACY_STATUS_ALIASES = {
284
- subscription: { delinquent: "unpaid" }
285
- };
286
- var STATUS_DOMAINS = Object.freeze([...registry.keys()]);
287
- function getStatusPresentation(domain, status) {
288
- const entries = registry.get(domain);
289
- if (!entries) return fallback(domain, status);
290
- const normalized = status.toLowerCase();
291
- const direct = entries.get(normalized);
292
- if (direct) return direct;
293
- const alias = LEGACY_STATUS_ALIASES[domain]?.[normalized];
294
- const aliased = alias ? entries.get(alias) : void 0;
295
- return aliased ? { ...aliased, status, label: toLabel(status) } : fallback(domain, status);
296
- }
297
- function listStatuses(domain) {
298
- return [...registry.get(domain)?.values() ?? []];
299
- }
300
- function getToneTokenSet(tone) {
301
- return componentTokenSet(tone);
302
- }
303
- function getBannerToneTokenSet(tone) {
304
- return bannerFallback(tone);
305
- }
306
- var ICON_GLYPHS = {
307
- success: "\u2714\uFE0E",
308
- warning: "\u26A0\uFE0E",
309
- critical: "\u2A2F",
310
- danger: "\u2A2F",
311
- error: "\u2A2F",
312
- negative: "\u2A2F",
313
- pending: "\u2026",
314
- processing: "\u27F3",
315
- paused: "\u23F8",
316
- canceled: "\u2205",
317
- cancelled: "\u2205",
318
- draft: "\u270E",
319
- void: "\u2205",
320
- paid: "\u2714\uFE0E",
321
- info: "\u2139\uFE0E",
322
- trial: "\u2605",
323
- future: "\u23F2",
324
- scheduled: "\u23F2",
325
- refunded: "\u21BA",
326
- locked: "\u{1F512}",
327
- unlocked: "\u{1F513}",
328
- default: "\u2022"
329
- };
330
- function resolveStatusGlyph(iconName) {
331
- const segment = iconName?.split(".").pop()?.toLowerCase();
332
- return segment ? ICON_GLYPHS[segment] ?? ICON_GLYPHS.default : void 0;
333
- }
334
- function defaultStatusGlyph() {
335
- return ICON_GLYPHS.default;
336
- }
337
-
338
- export { STATUS_DOMAINS, defaultStatusGlyph, getBannerToneTokenSet, getStatusPresentation, getToneTokenSet, listStatuses, resolveStatusGlyph };