@contractspec/lib.design-system 4.2.0 → 4.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.
Files changed (214) hide show
  1. package/README.md +128 -0
  2. package/dist/browser/components/data-view/DataViewGrid.js +1 -0
  3. package/dist/browser/components/data-view/DataViewList.js +1 -1
  4. package/dist/browser/components/data-view/DataViewRenderer.js +1 -1
  5. package/dist/browser/components/data-view/DataViewTable.js +1 -1
  6. package/dist/browser/components/data-view/collection.js +1 -0
  7. package/dist/browser/components/data-view/utils.js +1 -1
  8. package/dist/browser/components/forms/controls/Select.js +1 -1
  9. package/dist/browser/components/molecules/Tabs.js +1 -1
  10. package/dist/browser/components/object-reference/DefaultObjectReferenceDetail.js +1 -0
  11. package/dist/browser/components/object-reference/DefaultObjectReferenceParts.js +1 -0
  12. package/dist/browser/components/object-reference/DefaultObjectReferenceProperty.js +1 -0
  13. package/dist/browser/components/object-reference/ObjectReferenceHandler.js +1 -0
  14. package/dist/browser/components/object-reference/ObjectReferencePanel.js +1 -0
  15. package/dist/browser/components/object-reference/ReferenceIcon.js +1 -0
  16. package/dist/browser/components/object-reference/actions.js +1 -0
  17. package/dist/browser/components/object-reference/index.js +1 -0
  18. package/dist/browser/components/object-reference/maps.js +1 -0
  19. package/dist/browser/components/object-reference/runtime.js +1 -0
  20. package/dist/browser/components/object-reference/types.js +0 -0
  21. package/dist/browser/components/object-reference/url-safety.js +1 -0
  22. package/dist/browser/components/object-reference/useObjectReferenceController.js +1 -0
  23. package/dist/browser/components/organisms/Header.js +1 -1
  24. package/dist/browser/components/organisms/MarketingHeader.js +1 -1
  25. package/dist/browser/components/organisms/MarketingHeaderMobile.js +1 -1
  26. package/dist/browser/components/overlays/AdaptivePanel.js +1 -0
  27. package/dist/browser/components/overlays/index.js +1 -0
  28. package/dist/browser/components/shell/AppShell.js +1 -0
  29. package/dist/browser/components/shell/AppShell.types.js +0 -0
  30. package/dist/browser/components/shell/PageOutline.js +1 -0
  31. package/dist/browser/components/shell/ShellNotifications.js +1 -0
  32. package/dist/browser/components/shell/ShellSidebar.js +1 -0
  33. package/dist/browser/components/shell/index.js +1 -0
  34. package/dist/browser/components/shell/outline.js +1 -0
  35. package/dist/browser/components/shell/policy.js +1 -0
  36. package/dist/browser/components/shell/types.js +0 -0
  37. package/dist/browser/design-system.feature.js +1 -1
  38. package/dist/browser/i18n/translation.js +1 -1
  39. package/dist/browser/index.js +1 -1
  40. package/dist/browser/renderers/form-contract/phone-country-control.js +1 -0
  41. package/dist/browser/renderers/form-contract/phone-country-utils.js +1 -0
  42. package/dist/browser/renderers/form-contract/phone-field.js +1 -0
  43. package/dist/browser/renderers/form-contract/phone-utils.js +1 -0
  44. package/dist/browser/renderers/form-contract/renderer.js +1 -1
  45. package/dist/browser/renderers/form-contract/rich-fields.js +1 -1
  46. package/dist/browser/renderers/form-contract/shell.js +1 -1
  47. package/dist/browser/renderers/form-contract/values.js +1 -1
  48. package/dist/browser/shell.js +1 -0
  49. package/dist/components/data-view/DataViewGrid.d.ts +12 -0
  50. package/dist/components/data-view/DataViewGrid.js +1 -0
  51. package/dist/components/data-view/DataViewGrid.native.d.ts +12 -0
  52. package/dist/components/data-view/DataViewList.d.ts +3 -2
  53. package/dist/components/data-view/DataViewList.js +1 -1
  54. package/dist/components/data-view/DataViewList.native.d.ts +12 -0
  55. package/dist/components/data-view/DataViewRenderer.d.ts +11 -2
  56. package/dist/components/data-view/DataViewRenderer.js +1 -1
  57. package/dist/components/data-view/DataViewRenderer.native.d.ts +11 -2
  58. package/dist/components/data-view/DataViewTable.d.ts +4 -3
  59. package/dist/components/data-view/DataViewTable.js +1 -1
  60. package/dist/components/data-view/DataViewTable.native.d.ts +4 -3
  61. package/dist/components/data-view/collection.d.ts +24 -0
  62. package/dist/components/data-view/collection.js +1 -0
  63. package/dist/components/data-view/utils.js +1 -1
  64. package/dist/components/forms/controls/Select.d.ts +1 -1
  65. package/dist/components/forms/controls/Select.js +1 -1
  66. package/dist/components/legal/molecules/LegalTOC.d.ts +1 -1
  67. package/dist/components/marketing/MarketingCardsSection.d.ts +1 -1
  68. package/dist/components/molecules/StatusChip.d.ts +1 -1
  69. package/dist/components/molecules/Tabs.js +1 -1
  70. package/dist/components/object-reference/DefaultObjectReferenceDetail.d.ts +10 -0
  71. package/dist/components/object-reference/DefaultObjectReferenceDetail.js +1 -0
  72. package/dist/components/object-reference/DefaultObjectReferenceParts.d.ts +15 -0
  73. package/dist/components/object-reference/DefaultObjectReferenceParts.js +1 -0
  74. package/dist/components/object-reference/DefaultObjectReferenceParts.native.d.ts +16 -0
  75. package/dist/components/object-reference/DefaultObjectReferenceProperty.d.ts +13 -0
  76. package/dist/components/object-reference/DefaultObjectReferenceProperty.js +1 -0
  77. package/dist/components/object-reference/ObjectReferenceHandler.d.ts +2 -0
  78. package/dist/components/object-reference/ObjectReferenceHandler.js +1 -0
  79. package/dist/components/object-reference/ObjectReferenceHandler.native.d.ts +2 -0
  80. package/dist/components/object-reference/ObjectReferencePanel.d.ts +18 -0
  81. package/dist/components/object-reference/ObjectReferencePanel.js +1 -0
  82. package/dist/components/object-reference/ReferenceIcon.d.ts +7 -0
  83. package/dist/components/object-reference/ReferenceIcon.js +1 -0
  84. package/dist/components/object-reference/actions.d.ts +12 -0
  85. package/dist/components/object-reference/actions.js +1 -0
  86. package/dist/components/object-reference/index.d.ts +6 -0
  87. package/dist/components/object-reference/index.js +1 -0
  88. package/dist/components/object-reference/index.native.d.ts +4 -0
  89. package/dist/components/object-reference/maps.d.ts +8 -0
  90. package/dist/components/object-reference/maps.js +1 -0
  91. package/dist/components/object-reference/runtime.d.ts +13 -0
  92. package/dist/components/object-reference/runtime.js +1 -0
  93. package/dist/components/object-reference/types.d.ts +106 -0
  94. package/dist/components/object-reference/types.js +0 -0
  95. package/dist/components/object-reference/url-safety.d.ts +2 -0
  96. package/dist/components/object-reference/url-safety.js +1 -0
  97. package/dist/components/object-reference/useObjectReferenceController.d.ts +16 -0
  98. package/dist/components/object-reference/useObjectReferenceController.js +1 -0
  99. package/dist/components/organisms/Header.js +1 -1
  100. package/dist/components/organisms/MarketingHeader.js +1 -1
  101. package/dist/components/organisms/MarketingHeaderMobile.js +1 -1
  102. package/dist/components/overlays/AdaptivePanel.d.ts +26 -0
  103. package/dist/components/overlays/AdaptivePanel.js +1 -0
  104. package/dist/components/overlays/index.d.ts +1 -0
  105. package/dist/components/overlays/index.js +1 -0
  106. package/dist/components/shell/AppShell.d.ts +2 -0
  107. package/dist/components/shell/AppShell.js +1 -0
  108. package/dist/components/shell/AppShell.native.d.ts +2 -0
  109. package/dist/components/shell/AppShell.types.d.ts +22 -0
  110. package/dist/components/shell/AppShell.types.js +0 -0
  111. package/dist/components/shell/PageOutline.d.ts +12 -0
  112. package/dist/components/shell/PageOutline.js +1 -0
  113. package/dist/components/shell/PageOutline.native.d.ts +11 -0
  114. package/dist/components/shell/ShellNotifications.d.ts +5 -0
  115. package/dist/components/shell/ShellNotifications.js +1 -0
  116. package/dist/components/shell/ShellNotifications.native.d.ts +5 -0
  117. package/dist/components/shell/ShellSidebar.d.ts +11 -0
  118. package/dist/components/shell/ShellSidebar.js +1 -0
  119. package/dist/components/shell/index.d.ts +8 -0
  120. package/dist/components/shell/index.js +1 -0
  121. package/dist/components/shell/index.native.d.ts +5 -0
  122. package/dist/components/shell/outline.d.ts +5 -0
  123. package/dist/components/shell/outline.js +1 -0
  124. package/dist/components/shell/policy.d.ts +15 -0
  125. package/dist/components/shell/policy.js +1 -0
  126. package/dist/components/shell/types.d.ts +116 -0
  127. package/dist/components/shell/types.js +0 -0
  128. package/dist/design-system.feature.js +1 -1
  129. package/dist/i18n/translation.d.ts +6 -1
  130. package/dist/i18n/translation.js +1 -1
  131. package/dist/index.d.ts +5 -0
  132. package/dist/index.js +1 -1
  133. package/dist/native/components/data-view/DataViewGrid.js +1 -0
  134. package/dist/native/components/data-view/DataViewGrid.native.js +1 -0
  135. package/dist/native/components/data-view/DataViewList.js +1 -1
  136. package/dist/native/components/data-view/DataViewList.native.js +1 -0
  137. package/dist/native/components/data-view/DataViewRenderer.js +1 -1
  138. package/dist/native/components/data-view/DataViewRenderer.native.js +1 -1
  139. package/dist/native/components/data-view/DataViewTable.js +1 -1
  140. package/dist/native/components/data-view/DataViewTable.native.js +1 -1
  141. package/dist/native/components/data-view/collection.js +1 -0
  142. package/dist/native/components/data-view/utils.js +1 -1
  143. package/dist/native/components/forms/controls/Select.js +1 -1
  144. package/dist/native/components/molecules/Tabs.js +1 -1
  145. package/dist/native/components/molecules/Tabs.native.js +1 -1
  146. package/dist/native/components/object-reference/DefaultObjectReferenceDetail.js +1 -0
  147. package/dist/native/components/object-reference/DefaultObjectReferenceParts.js +1 -0
  148. package/dist/native/components/object-reference/DefaultObjectReferenceParts.native.js +1 -0
  149. package/dist/native/components/object-reference/DefaultObjectReferenceProperty.js +1 -0
  150. package/dist/native/components/object-reference/ObjectReferenceHandler.js +1 -0
  151. package/dist/native/components/object-reference/ObjectReferenceHandler.native.js +1 -0
  152. package/dist/native/components/object-reference/ObjectReferencePanel.js +1 -0
  153. package/dist/native/components/object-reference/ReferenceIcon.js +1 -0
  154. package/dist/native/components/object-reference/actions.js +1 -0
  155. package/dist/native/components/object-reference/index.js +1 -0
  156. package/dist/native/components/object-reference/index.native.js +1 -0
  157. package/dist/native/components/object-reference/maps.js +1 -0
  158. package/dist/native/components/object-reference/runtime.js +1 -0
  159. package/dist/native/components/object-reference/types.js +0 -0
  160. package/dist/native/components/object-reference/url-safety.js +1 -0
  161. package/dist/native/components/object-reference/useObjectReferenceController.js +1 -0
  162. package/dist/native/components/organisms/Header.js +1 -1
  163. package/dist/native/components/organisms/MarketingHeader.js +1 -1
  164. package/dist/native/components/organisms/MarketingHeaderMobile.js +1 -1
  165. package/dist/native/components/overlays/AdaptivePanel.js +1 -0
  166. package/dist/native/components/overlays/index.js +1 -0
  167. package/dist/native/components/shell/AppShell.js +1 -0
  168. package/dist/native/components/shell/AppShell.native.js +1 -0
  169. package/dist/native/components/shell/AppShell.types.js +0 -0
  170. package/dist/native/components/shell/PageOutline.js +1 -0
  171. package/dist/native/components/shell/PageOutline.native.js +1 -0
  172. package/dist/native/components/shell/ShellNotifications.js +1 -0
  173. package/dist/native/components/shell/ShellNotifications.native.js +1 -0
  174. package/dist/native/components/shell/ShellSidebar.js +1 -0
  175. package/dist/native/components/shell/index.js +1 -0
  176. package/dist/native/components/shell/index.native.js +1 -0
  177. package/dist/native/components/shell/outline.js +1 -0
  178. package/dist/native/components/shell/policy.js +1 -0
  179. package/dist/native/components/shell/types.js +0 -0
  180. package/dist/native/design-system.feature.js +1 -1
  181. package/dist/native/i18n/translation.js +1 -1
  182. package/dist/native/index.js +1 -1
  183. package/dist/native/renderers/form-contract/phone-country-control.js +1 -0
  184. package/dist/native/renderers/form-contract/phone-country-control.native.js +1 -0
  185. package/dist/native/renderers/form-contract/phone-country-utils.js +1 -0
  186. package/dist/native/renderers/form-contract/phone-field.js +1 -0
  187. package/dist/native/renderers/form-contract/phone-utils.js +1 -0
  188. package/dist/native/renderers/form-contract/renderer.js +1 -1
  189. package/dist/native/renderers/form-contract/rich-fields.js +1 -1
  190. package/dist/native/renderers/form-contract/shell.js +1 -1
  191. package/dist/native/renderers/form-contract/values.js +1 -1
  192. package/dist/native/shell.js +1 -0
  193. package/dist/native/shell.native.js +1 -0
  194. package/dist/renderers/form-contract/phone-country-control.d.ts +18 -0
  195. package/dist/renderers/form-contract/phone-country-control.js +1 -0
  196. package/dist/renderers/form-contract/phone-country-control.native.d.ts +18 -0
  197. package/dist/renderers/form-contract/phone-country-utils.d.ts +9 -0
  198. package/dist/renderers/form-contract/phone-country-utils.js +1 -0
  199. package/dist/renderers/form-contract/phone-field.d.ts +18 -0
  200. package/dist/renderers/form-contract/phone-field.js +1 -0
  201. package/dist/renderers/form-contract/phone-utils.d.ts +3 -0
  202. package/dist/renderers/form-contract/phone-utils.js +1 -0
  203. package/dist/renderers/form-contract/renderer.js +1 -1
  204. package/dist/renderers/form-contract/rich-fields.d.ts +2 -12
  205. package/dist/renderers/form-contract/rich-fields.js +1 -1
  206. package/dist/renderers/form-contract/shell.d.ts +9 -0
  207. package/dist/renderers/form-contract/shell.js +1 -1
  208. package/dist/renderers/form-contract/values.d.ts +1 -0
  209. package/dist/renderers/form-contract/values.js +1 -1
  210. package/dist/shell.d.ts +1 -0
  211. package/dist/shell.js +1 -0
  212. package/dist/shell.native.d.ts +1 -0
  213. package/dist/theme/variants.d.ts +1 -1
  214. package/package.json +523 -9
@@ -0,0 +1,4 @@
1
+ export { createCopyReferenceAction, createDefaultObjectReferenceActions, createEmailReferenceAction, createMapsProviderHref, createMapsReferenceActions, createOpenReferenceAction, createPhoneReferenceAction, getObjectReferenceDisplayValue, type ObjectReferenceMapsActionOptions, type ObjectReferenceMapsProvider, } from './actions';
2
+ export { ObjectReferenceHandler } from './ObjectReferenceHandler';
3
+ export { type ExecuteObjectReferenceActionOptions, executeObjectReferenceAction, } from './runtime';
4
+ export type { JsonPrimitive, JsonValue, ObjectReferenceActionDescriptor, ObjectReferenceActionEvent, ObjectReferenceActionHandler, ObjectReferenceActionRenderContext, ObjectReferenceActionVariant, ObjectReferenceCopyHandler, ObjectReferenceDescriptor, ObjectReferenceHandlerProps, ObjectReferenceIconRenderContext, ObjectReferenceInteractivityVisibility, ObjectReferenceKind, ObjectReferenceMetadata, ObjectReferenceOpenHrefHandler, ObjectReferenceOpenTarget, ObjectReferencePanelBreakpoint, ObjectReferencePanelMode, ObjectReferencePropertyRenderContext, ObjectReferenceRenderContext, ObjectReferenceSectionDescriptor, ObjectReferenceSectionRenderContext, } from './types';
@@ -0,0 +1,8 @@
1
+ import type { ObjectReferenceActionDescriptor, ObjectReferenceDescriptor } from './types';
2
+ export type ObjectReferenceMapsProvider = 'apple' | 'google' | 'waze' | 'geo';
3
+ export interface ObjectReferenceMapsActionOptions {
4
+ providers?: ObjectReferenceMapsProvider[];
5
+ labelPrefix?: string;
6
+ }
7
+ export declare function createMapsProviderHref(provider: ObjectReferenceMapsProvider, query: string): string;
8
+ export declare function createMapsReferenceActions(reference: ObjectReferenceDescriptor, options?: ObjectReferenceMapsActionOptions): ObjectReferenceActionDescriptor[];
@@ -0,0 +1 @@
1
+ export function createMapsProviderHref(e,t){const r=encodeURIComponent(a(t));switch(e){case"apple":return`https://maps.apple.com/?q=${r}`;case"google":return`https://www.google.com/maps/search/?api=1&query=${r}`;case"waze":return`https://waze.com/ul?q=${r}&navigate=yes`;case"geo":return`geo:0,0?q=${r}`}}export function createMapsReferenceActions(e,t={}){if(e.kind!=="address")return[];const r=e.value??e.label;if(!a(r))return[];const n=t.providers??["google","apple","waze"],o=t.labelPrefix??"Open in";return n.map((c)=>({id:`maps.${c}`,label:`${o} ${s(c)}`,description:"Open navigation for this address",href:createMapsProviderHref(c,r),iconKey:"map",metadata:{provider:c}}))}function a(e){return e.trim().replace(/\s+/g," ")}function s(e){switch(e){case"apple":return"Apple Maps";case"google":return"Google Maps";case"waze":return"Waze";case"geo":return"Maps"}}
@@ -0,0 +1,13 @@
1
+ import type { ObjectReferenceActionEvent, ObjectReferenceHandlerProps, ObjectReferenceOpenTarget } from './types';
2
+ export interface ExecuteObjectReferenceActionOptions {
3
+ actionHandlers?: ObjectReferenceHandlerProps['actionHandlers'];
4
+ copyText?: string;
5
+ copyHandler?: ObjectReferenceHandlerProps['copyHandler'];
6
+ openHref?: ObjectReferenceHandlerProps['openHref'];
7
+ onAction?: ObjectReferenceHandlerProps['onAction'];
8
+ onActionError?: ObjectReferenceHandlerProps['onActionError'];
9
+ defaultOpenTarget?: ObjectReferenceOpenTarget;
10
+ defaultCopy?: ObjectReferenceHandlerProps['copyHandler'];
11
+ defaultOpenHref?: ObjectReferenceHandlerProps['openHref'];
12
+ }
13
+ export declare function executeObjectReferenceAction(event: ObjectReferenceActionEvent, options: ExecuteObjectReferenceActionOptions): Promise<void>;
@@ -0,0 +1 @@
1
+ import{getObjectReferenceDisplayValue as A}from"./actions";import{normalizeSafeObjectReferenceHref as B}from"./url-safety";export async function executeObjectReferenceAction(k,q){try{const w=q.actionHandlers?.[k.action.id];if(w)await w(k);else if(k.action.id==="copy")await C(k,q);else if(k.action.href){const y=B(k.action.href);if(!y)throw Error("Unsafe object reference href.");await D(y,k,E(k,q),q)}await q.onAction?.(k)}catch(w){q.onActionError?.(w,k)}}function C(k,q){const w=q.copyText??F(k.action.metadata?.copyText)??A(k.reference);if(q.copyHandler)return q.copyHandler(w,k);if(q.defaultCopy)return q.defaultCopy(w,k);throw Error("Clipboard is not available.")}function D(k,q,w,y){if(y.openHref)return y.openHref(k,q,{target:w});return y.defaultOpenHref?.(k,q,{target:w})}function E(k,q){return k.action.openTarget??G(k.action.metadata?.openTarget)??k.reference.openTarget??q.defaultOpenTarget??"same-page"}function F(k){return typeof k==="string"?k:void 0}function G(k){return k==="same-page"||k==="new-page"?k:void 0}
@@ -0,0 +1,106 @@
1
+ import type * as React from 'react';
2
+ export type ObjectReferenceKind = 'address' | 'email' | 'phone' | 'user' | 'customer' | 'file' | 'url' | 'custom';
3
+ export type ObjectReferenceInteractivityVisibility = 'none' | 'underline' | 'icon';
4
+ export type ObjectReferenceActionVariant = 'default' | 'primary' | 'secondary' | 'danger';
5
+ export type ObjectReferenceOpenTarget = 'same-page' | 'new-page';
6
+ export type ObjectReferencePanelMode = import('../overlays').AdaptivePanelMode;
7
+ export type ObjectReferencePanelBreakpoint = import('../overlays').AdaptivePanelBreakpoint;
8
+ export type JsonPrimitive = string | number | boolean | null;
9
+ export type JsonValue = JsonPrimitive | JsonValue[] | {
10
+ readonly [key: string]: JsonValue;
11
+ };
12
+ export type ObjectReferenceMetadata = Record<string, JsonValue>;
13
+ export interface ObjectReferenceDescriptor {
14
+ id: string;
15
+ kind: ObjectReferenceKind;
16
+ label: string;
17
+ description?: string;
18
+ value?: string;
19
+ href?: string;
20
+ openTarget?: ObjectReferenceOpenTarget;
21
+ actions?: ObjectReferenceActionDescriptor[];
22
+ properties?: ObjectReferenceDescriptor[];
23
+ sections?: ObjectReferenceSectionDescriptor[];
24
+ metadata?: ObjectReferenceMetadata;
25
+ iconKey?: string;
26
+ ariaLabel?: string;
27
+ }
28
+ export interface ObjectReferenceSectionDescriptor {
29
+ id: string;
30
+ title?: string;
31
+ description?: string;
32
+ properties?: ObjectReferenceDescriptor[];
33
+ actions?: ObjectReferenceActionDescriptor[];
34
+ metadata?: ObjectReferenceMetadata;
35
+ }
36
+ export interface ObjectReferenceActionDescriptor {
37
+ id: string;
38
+ label: string;
39
+ description?: string;
40
+ href?: string;
41
+ openTarget?: ObjectReferenceOpenTarget;
42
+ disabled?: boolean;
43
+ variant?: ObjectReferenceActionVariant;
44
+ iconKey?: string;
45
+ metadata?: ObjectReferenceMetadata;
46
+ }
47
+ export interface ObjectReferenceActionEvent {
48
+ reference: ObjectReferenceDescriptor;
49
+ action: ObjectReferenceActionDescriptor;
50
+ source: 'action' | 'trigger';
51
+ }
52
+ export type ObjectReferenceActionHandler = (event: ObjectReferenceActionEvent) => void | Promise<void>;
53
+ export type ObjectReferenceCopyHandler = (text: string, event: ObjectReferenceActionEvent) => void | Promise<void>;
54
+ export type ObjectReferenceOpenHrefHandler = (href: string, event: ObjectReferenceActionEvent, options: {
55
+ target: ObjectReferenceOpenTarget;
56
+ }) => void | Promise<void>;
57
+ export interface ObjectReferenceRenderContext {
58
+ reference: ObjectReferenceDescriptor;
59
+ actions: ObjectReferenceActionDescriptor[];
60
+ open: boolean;
61
+ setOpen: (open: boolean) => void;
62
+ }
63
+ export interface ObjectReferenceActionRenderContext extends ObjectReferenceRenderContext {
64
+ action: ObjectReferenceActionDescriptor;
65
+ runAction: (action: ObjectReferenceActionDescriptor) => void;
66
+ }
67
+ export interface ObjectReferencePropertyRenderContext extends ObjectReferenceRenderContext {
68
+ property: ObjectReferenceDescriptor;
69
+ depth: number;
70
+ runPropertyAction: (property: ObjectReferenceDescriptor, action: ObjectReferenceActionDescriptor) => void;
71
+ }
72
+ export interface ObjectReferenceSectionRenderContext extends ObjectReferenceRenderContext {
73
+ section: ObjectReferenceSectionDescriptor;
74
+ }
75
+ export interface ObjectReferenceIconRenderContext {
76
+ iconKey: string;
77
+ reference: ObjectReferenceDescriptor;
78
+ action?: ObjectReferenceActionDescriptor;
79
+ }
80
+ export interface ObjectReferenceHandlerProps {
81
+ reference: ObjectReferenceDescriptor;
82
+ actions?: ObjectReferenceActionDescriptor[];
83
+ interactivityVisibility?: ObjectReferenceInteractivityVisibility;
84
+ openTarget?: ObjectReferenceOpenTarget;
85
+ panelMode?: ObjectReferencePanelMode;
86
+ mobilePanelMode?: Exclude<ObjectReferencePanelMode, 'responsive'>;
87
+ desktopPanelMode?: Exclude<ObjectReferencePanelMode, 'responsive'>;
88
+ responsiveBreakpoint?: ObjectReferencePanelBreakpoint;
89
+ defaultOpen?: boolean;
90
+ open?: boolean;
91
+ onOpenChange?: (open: boolean) => void;
92
+ actionHandlers?: Record<string, ObjectReferenceActionHandler>;
93
+ onAction?: ObjectReferenceActionHandler;
94
+ onActionError?: (error: unknown, event: ObjectReferenceActionEvent) => void;
95
+ copyText?: string;
96
+ copyHandler?: ObjectReferenceCopyHandler;
97
+ openHref?: ObjectReferenceOpenHrefHandler;
98
+ renderTrigger?: (context: ObjectReferenceRenderContext) => React.ReactNode;
99
+ renderDetail?: (context: ObjectReferenceRenderContext) => React.ReactNode;
100
+ renderAction?: (context: ObjectReferenceActionRenderContext) => React.ReactNode;
101
+ renderProperty?: (context: ObjectReferencePropertyRenderContext) => React.ReactNode;
102
+ renderSection?: (context: ObjectReferenceSectionRenderContext) => React.ReactNode;
103
+ iconRenderer?: (context: ObjectReferenceIconRenderContext) => React.ReactNode;
104
+ className?: string;
105
+ panelClassName?: string;
106
+ }
File without changes
@@ -0,0 +1,2 @@
1
+ export declare const SAFE_OBJECT_REFERENCE_PROTOCOLS: Set<string>;
2
+ export declare function normalizeSafeObjectReferenceHref(href: string | undefined): string | null;
@@ -0,0 +1 @@
1
+ export const SAFE_OBJECT_REFERENCE_PROTOCOLS=new Set(["http:","https:","mailto:","tel:","geo:"]);export function normalizeSafeObjectReferenceHref(e){const t=e?.trim();if(!t)return null;if(t.startsWith("/")&&!t.startsWith("//"))return t;if(t.startsWith("#"))return t;try{const r=new URL(t);return SAFE_OBJECT_REFERENCE_PROTOCOLS.has(r.protocol)?r.toString():null}catch{return null}}
@@ -0,0 +1,16 @@
1
+ import type { ObjectReferenceActionDescriptor, ObjectReferenceActionEvent, ObjectReferenceDescriptor, ObjectReferenceHandlerProps, ObjectReferenceOpenTarget, ObjectReferenceRenderContext } from './types';
2
+ interface ControllerOptions extends ObjectReferenceHandlerProps {
3
+ defaultCopy?: ObjectReferenceHandlerProps['copyHandler'];
4
+ defaultOpenTarget?: ObjectReferenceOpenTarget;
5
+ defaultOpenHref?: ObjectReferenceHandlerProps['openHref'];
6
+ }
7
+ export declare function useObjectReferenceController({ reference, actions, defaultOpen, open, onOpenChange, actionHandlers, onAction, onActionError, copyText, copyHandler, openHref, openTarget, defaultCopy, defaultOpenTarget, defaultOpenHref, }: ControllerOptions): {
8
+ context: ObjectReferenceRenderContext;
9
+ openDetail: () => void;
10
+ resolvedActions: ObjectReferenceActionDescriptor[];
11
+ resolvedOpen: boolean;
12
+ runAction: (action: ObjectReferenceActionDescriptor) => void;
13
+ runReferenceAction: (actionReference: ObjectReferenceDescriptor, action: ObjectReferenceActionDescriptor, source?: ObjectReferenceActionEvent["source"]) => void;
14
+ setOpen: (nextOpen: boolean) => void;
15
+ };
16
+ export {};
@@ -0,0 +1 @@
1
+ import*as q from"react";import{createDefaultObjectReferenceActions as v}from"./actions";import{executeObjectReferenceAction as x}from"./runtime";export function useObjectReferenceController({reference:k,actions:I,defaultOpen:$=!1,open:J,onOpenChange:K,actionHandlers:L,onAction:M,onActionError:N,copyText:P,copyHandler:Q,openHref:S,openTarget:B,defaultCopy:V,defaultOpenTarget:W,defaultOpenHref:X}){const[U,b]=q.useState($),Y=J!==void 0,F=J??U,G=q.useMemo(()=>I??k.actions??v(k),[I,k]),w=q.useCallback((m)=>{if(!Y)b(m);K?.(m)},[Y,K]),j=q.useMemo(()=>({reference:k,actions:G,open:F,setOpen:w}),[k,G,F,w]),z=q.useCallback((m,Z,E="action")=>{if(Z.disabled)return;x({reference:m,action:Z,source:E},{actionHandlers:L,copyText:P,copyHandler:Q,openHref:S,onAction:M,onActionError:N,defaultOpenTarget:_(B,m.openTarget,W),defaultCopy:V,defaultOpenHref:X})},[L,Q,P,V,W,X,M,N,B,S]),D=q.useCallback((m)=>{z(k,m)},[k,z]),h=q.useCallback(()=>{const m=_(B,k.openTarget);if(m==="new-page"&&k.href){z(k,{id:"open-detail",label:"Open details",href:k.href,openTarget:m,iconKey:"external-link"},"trigger");return}w(!0)},[B,k,z,w]);return{context:j,openDetail:h,resolvedActions:G,resolvedOpen:F,runAction:D,runReferenceAction:z,setOpen:w}}function _(...k){return k.find(Boolean)??"same-page"}
@@ -1 +1 @@
1
- import{jsx as z,jsxs as G,Fragment as U}from"react/jsx-runtime";import{Separator as X}from"@contractspec/lib.ui-kit-web/ui/separator";import{Sheet as Y,SheetContent as Z,SheetTitle as $,SheetTrigger as q}from"@contractspec/lib.ui-kit-web/ui/sheet";import{cn as P}from"@contractspec/lib.ui-kit-web/ui/utils";import{cva as Q}from"class-variance-authority";import{Menu as C}from"lucide-react";import{Button as D}from"../atoms/Button";import{ButtonLink as F}from"../atoms/ButtonLink";import{NavMain as A}from"../molecules/NavMain";import{NavUser as R}from"../molecules/NavUser";import{AppSidebar as L}from"./AppSidebar";const T=Q("hidden items-center justify-between gap-4 md:flex",{variants:{density:{compact:"px-3 py-1",comfortable:"px-4 py-2"}},defaultVariants:{density:"comfortable"}});const V=Q("flex items-center justify-between md:hidden",{variants:{density:{compact:"px-2 py-1",comfortable:"px-3 py-2"}},defaultVariants:{density:"comfortable"}});export function DesktopHeader({logo:I,nav:K,userMenu:E,cta:J,className:O,density:W}){return G("header",{className:P(T({density:W}),O),children:[G("div",{className:"flex items-center gap-4",children:[I,z(X,{orientation:"vertical",className:"h-6"}),z(A,{items:K})]}),G("div",{className:"flex items-center gap-2",children:[J&&z(F,{variant:J.variant,href:J.href,children:J.label}),E&&z(R,{...E})]})]})}export function MobileHeader({logo:I,userMenu:K,mobileSidebar:E,className:J,density:O}){return G("header",{className:P(V({density:O}),J),children:[G(Y,{children:[z(q,{asChild:!0,children:z(D,{variant:"ghost",size:"icon","aria-label":"Open menu",children:z(C,{className:"h-5 w-5"})})}),G(Z,{side:"left",className:"w-[300px] p-0",children:[z($,{className:"sr-only",children:"Menu"}),E?z(L,{sections:E.sections,top:E.top,bottom:E.bottom,className:"h-svh"}):z("div",{className:"p-4",children:"No sidebar configured"})]})]}),z("div",{className:"flex-1 px-2",children:I}),z("div",{className:"flex items-center gap-2",children:K&&z(R,{...K})})]})}export function Header(I){return G(U,{children:[z(MobileHeader,{...I}),z(DesktopHeader,{...I})]})}
1
+ import{jsx as z,jsxs as I,Fragment as A}from"react/jsx-runtime";import{Separator as Z}from"@contractspec/lib.ui-kit-web/ui/separator";import{cn as T}from"@contractspec/lib.ui-kit-web/ui/utils";import{cva as W}from"class-variance-authority";import{Menu as $}from"lucide-react";import*as q from"react";import{Button as D}from"../atoms/Button";import{ButtonLink as F}from"../atoms/ButtonLink";import{NavMain as O}from"../molecules/NavMain";import{NavUser as X}from"../molecules/NavUser";import{AdaptivePanel as P}from"../overlays";import{AppSidebar as R}from"./AppSidebar";const L=W("hidden items-center justify-between gap-4 md:flex",{variants:{density:{compact:"px-3 py-1",comfortable:"px-4 py-2"}},defaultVariants:{density:"comfortable"}});const V=W("flex items-center justify-between md:hidden",{variants:{density:{compact:"px-2 py-1",comfortable:"px-3 py-2"}},defaultVariants:{density:"comfortable"}});export function DesktopHeader({logo:E,nav:J,userMenu:C,cta:G,className:K,density:Q}){return I("header",{className:T(L({density:Q}),K),children:[I("div",{className:"flex items-center gap-4",children:[E,z(Z,{orientation:"vertical",className:"h-6"}),z(O,{items:J})]}),I("div",{className:"flex items-center gap-2",children:[G&&z(F,{variant:G.variant,href:G.href,children:G.label}),C&&z(X,{...C})]})]})}export function MobileHeader({logo:E,userMenu:J,mobileSidebar:C,className:G,density:K}){const[Q,Y]=q.useState(!1);return I("header",{className:T(V({density:K}),G),children:[z(P,{mode:"drawer",drawerDirection:"left",open:Q,onOpenChange:Y,trigger:z(D,{variant:"ghost",size:"icon","aria-label":"Open menu",children:z($,{className:"h-5 w-5"})}),title:"Menu",headerClassName:"sr-only",className:"w-[300px] p-0",children:C?z(R,{sections:C.sections,top:C.top,bottom:C.bottom,className:"h-svh"}):z("div",{className:"p-4",children:"No sidebar configured"})}),z("div",{className:"flex-1 px-2",children:E}),z("div",{className:"flex items-center gap-2",children:J&&z(X,{...J})})]})}export function Header(E){return I(A,{children:[z(MobileHeader,{...E}),z(DesktopHeader,{...E})]})}
@@ -1 +1 @@
1
- import{jsx as z,jsxs as J,Fragment as I}from"react/jsx-runtime";import{NavigationMenu as M,NavigationMenuContent as L,NavigationMenuItem as C,NavigationMenuLink as P,NavigationMenuList as k,NavigationMenuTrigger as N}from"@contractspec/lib.ui-kit-web/ui/navigation-menu";import{Separator as d}from"@contractspec/lib.ui-kit-web/ui/separator";import{Sheet as p,SheetContent as S,SheetHeader as v,SheetTrigger as h}from"@contractspec/lib.ui-kit-web/ui/sheet";import{Box as Y,HStack as W,VStack as b}from"@contractspec/lib.ui-kit-web/ui/stack";import{Text as q}from"@contractspec/lib.ui-kit-web/ui/text";import{cn as D}from"@contractspec/lib.ui-kit-web/ui/utils";import{cva as u}from"class-variance-authority";import{Menu as f}from"lucide-react";import*as g from"react";import{Button as y}from"../atoms/Button";import{ButtonLink as F}from"../atoms/ButtonLink";import{CommandSearchTrigger as U}from"../molecules/CommandSearchTrigger";import{LangSwitchDropdown as _}from"../molecules/LangSwitchDropdown";import{MobileNavMenu as l}from"../molecules/MobileNavMenu";import{NavItemCard as w}from"../molecules/NavItemCard";import{NavUser as j}from"../molecules/NavUser";const x=u("flex items-center justify-between gap-4",{variants:{density:{compact:"px-3 py-2",comfortable:"px-4 py-3"}},defaultVariants:{density:"comfortable"}});export function MarketingHeader({logo:V,nav:X=[],navLinkClassName:Z,userMenu:$,cta:A,className:H,density:B,right:O,commandPaletteGroups:K,langSwitchProps:Q}){const[T,G]=g.useState(!1);return z(W,{as:"header",className:D("sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60",H),children:J(W,{className:D("mx-auto w-full max-w-7xl items-center justify-center",x({density:B})),children:[z(b,{className:"flex items-center gap-2 md:hidden",children:J(p,{open:T,onOpenChange:G,children:[z(h,{asChild:!0,children:z(y,{variant:"ghost",size:"icon","aria-label":"Open menu",children:z(f,{className:"h-5 w-5"})})}),J(S,{side:"left",className:"w-[320px] p-4",children:[!!K?.length&&z(v,{children:z(U,{groups:K})}),A&&z(b,{className:"mb-3",children:z(F,{variant:A.variant,size:A.size,href:A.href,onClick:A.onClick,children:z(q,{children:A.label})})}),z(l,{items:X})]})]})}),V,z(W,{className:"hidden items-center gap-4 md:flex",children:X.length>0&&J(I,{children:[z(d,{orientation:"vertical",className:"h-6"}),z(M,{className:"hidden md:flex",children:z(k,{children:X.map((E)=>z(C,{children:E.items&&E.items.length>0?J(I,{children:[z(N,{className:Z,children:E.label}),z(L,{children:z("div",{className:"grid w-[760px] grid-cols-3 gap-3 p-3",children:E.items.map((R)=>z(w,{item:R},R.href))})})]}):z(P,{className:Z,href:E.href||"#",children:E.label})},String(E.key??E.href??E.label)))})})]})}),J(W,{className:"flex items-center gap-2",children:[!!K?.length&&z(Y,{className:"hidden items-center gap-2 md:flex",children:z(U,{groups:K})}),Q?.options?.length>1&&z(_,{value:Q.value,onChange:Q.onChange,options:Q.options}),O&&z(Y,{className:"hidden md:flex",children:O}),A&&z(Y,{className:"hidden md:flex",children:z(F,{variant:A.variant,size:A.size,href:A.href,onClick:A.onClick,children:z(q,{children:A.label})})}),$&&z(j,{...$})]})]})})}
1
+ import{jsx as z,jsxs as K,Fragment as I}from"react/jsx-runtime";import{NavigationMenu as M,NavigationMenuContent as C,NavigationMenuItem as L,NavigationMenuLink as k,NavigationMenuList as P,NavigationMenuTrigger as N}from"@contractspec/lib.ui-kit-web/ui/navigation-menu";import{Separator as d}from"@contractspec/lib.ui-kit-web/ui/separator";import{Box as Z,HStack as X,VStack as b}from"@contractspec/lib.ui-kit-web/ui/stack";import{Text as q}from"@contractspec/lib.ui-kit-web/ui/text";import{cn as D}from"@contractspec/lib.ui-kit-web/ui/utils";import{cva as S}from"class-variance-authority";import{Menu as p}from"lucide-react";import*as h from"react";import{Button as v}from"../atoms/Button";import{ButtonLink as F}from"../atoms/ButtonLink";import{CommandSearchTrigger as U}from"../molecules/CommandSearchTrigger";import{LangSwitchDropdown as g}from"../molecules/LangSwitchDropdown";import{MobileNavMenu as u}from"../molecules/MobileNavMenu";import{NavItemCard as f}from"../molecules/NavItemCard";import{NavUser as y}from"../molecules/NavUser";import{AdaptivePanel as _}from"../overlays";const j=S("flex items-center justify-between gap-4",{variants:{density:{compact:"px-3 py-2",comfortable:"px-4 py-3"}},defaultVariants:{density:"comfortable"}});export function MarketingHeader({logo:V,nav:Y=[],navLinkClassName:$,userMenu:A,cta:E,className:H,density:B,right:O,commandPaletteGroups:Q,langSwitchProps:W}){const[T,G]=h.useState(!1);return z(X,{as:"header",className:D("sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60",H),children:K(X,{className:D("mx-auto w-full max-w-7xl items-center justify-center",j({density:B})),children:[z(b,{className:"flex items-center gap-2 md:hidden",children:z(_,{mode:"drawer",drawerDirection:"left",open:T,onOpenChange:G,trigger:z(v,{variant:"ghost",size:"icon","aria-label":"Open menu",children:z(p,{className:"h-5 w-5"})}),title:"Menu",className:"w-[320px]",children:K("div",{className:"px-4 pb-4",children:[!!Q?.length&&z("div",{className:"mb-3",children:z(U,{groups:Q})}),E&&z(b,{className:"mb-3",children:z(F,{variant:E.variant,size:E.size,href:E.href,onClick:E.onClick,children:z(q,{children:E.label})})}),z(u,{items:Y})]})})}),V,z(X,{className:"hidden items-center gap-4 md:flex",children:Y.length>0&&K(I,{children:[z(d,{orientation:"vertical",className:"h-6"}),z(M,{className:"hidden md:flex",children:z(P,{children:Y.map((J)=>z(L,{children:J.items&&J.items.length>0?K(I,{children:[z(N,{className:$,children:J.label}),z(C,{children:z("div",{className:"grid w-[760px] grid-cols-3 gap-3 p-3",children:J.items.map((R)=>z(f,{item:R},R.href))})})]}):z(k,{className:$,href:J.href||"#",children:J.label})},String(J.key??J.href??J.label)))})})]})}),K(X,{className:"flex items-center gap-2",children:[!!Q?.length&&z(Z,{className:"hidden items-center gap-2 md:flex",children:z(U,{groups:Q})}),W?.options?.length>1&&z(g,{value:W.value,onChange:W.onChange,options:W.options}),O&&z(Z,{className:"hidden md:flex",children:O}),E&&z(Z,{className:"hidden md:flex",children:z(F,{variant:E.variant,size:E.size,href:E.href,onClick:E.onClick,children:z(q,{children:E.label})})}),A&&z(y,{...A})]})]})})}
@@ -1 +1 @@
1
- import{jsx as q,jsxs as z}from"react/jsx-runtime";import{Sheet as X,SheetContent as Y,SheetFooter as Z,SheetHeader as $,SheetTitle as k,SheetTrigger as B}from"@contractspec/lib.ui-kit-web/ui/sheet";import{VStack as F}from"@contractspec/lib.ui-kit-web/ui/stack";import{cn as H}from"@contractspec/lib.ui-kit-web/ui/utils";import{Menu as O}from"lucide-react";import*as R from"react";import{Button as V}from"../atoms/Button";import{CommandSearchTrigger as b}from"../molecules/CommandSearchTrigger";import{LangSwitchDropdown as D}from"../molecules/LangSwitchDropdown";import{MobileNavMenu as L}from"../molecules/MobileNavMenu";export function MarketingHeaderMobile({logo:I,nav:J=[],className:K,right:Q,commandPaletteGroups:E,langSwitchProps:A}){const[U,W]=R.useState(!1);return q("div",{className:H("w-full border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60 md:hidden",K),children:z("div",{className:"mx-auto flex w-full max-w-7xl items-center justify-between px-3 py-2",children:[z("div",{className:"flex items-center gap-2",children:[z(X,{open:U,onOpenChange:W,children:[q(B,{asChild:!0,children:q(V,{variant:"ghost",size:"icon","aria-label":"Open menu",children:q(O,{className:"h-5 w-5"})})}),z(Y,{side:"left",className:"w-[320px] p-4",children:[z($,{children:[q(k,{children:"Menu"}),!!E?.length&&q("div",{className:"mb-3",children:q(b,{groups:E,compact:!0})})]}),q(F,{children:q(L,{items:J})}),q(Z,{children:Q})]})]}),I]}),q("div",{className:"flex items-center gap-2",children:A?.options?.length>1&&q(D,{value:A.value,options:A.options,onChange:A.onChange})})]})})}
1
+ import{jsx as q,jsxs as E}from"react/jsx-runtime";import{VStack as W}from"@contractspec/lib.ui-kit-web/ui/stack";import{cn as X}from"@contractspec/lib.ui-kit-web/ui/utils";import{Menu as Y}from"lucide-react";import*as Z from"react";import{Button as $}from"../atoms/Button";import{CommandSearchTrigger as k}from"../molecules/CommandSearchTrigger";import{LangSwitchDropdown as A}from"../molecules/LangSwitchDropdown";import{MobileNavMenu as B}from"../molecules/MobileNavMenu";import{AdaptivePanel as O}from"../overlays";export function MarketingHeaderMobile({logo:I,nav:J=[],className:K,right:F,commandPaletteGroups:H,langSwitchProps:z}){const[Q,U]=Z.useState(!1);return q("div",{className:X("w-full border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60 md:hidden",K),children:E("div",{className:"mx-auto flex w-full max-w-7xl items-center justify-between px-3 py-2",children:[E("div",{className:"flex items-center gap-2",children:[q(O,{mode:"drawer",drawerDirection:"left",open:Q,onOpenChange:U,trigger:q($,{variant:"ghost",size:"icon","aria-label":"Open menu",children:q(Y,{className:"h-5 w-5"})}),title:"Menu",className:"w-[320px]",children:E("div",{className:"px-4 pb-4",children:[!!H?.length&&q("div",{className:"mb-3",children:q(k,{groups:H,compact:!0})}),q(W,{children:q(B,{items:J})}),F?q("div",{className:"mt-4",children:F}):null]})}),I]}),q("div",{className:"flex items-center gap-2",children:z?.options?.length>1&&q(A,{value:z.value,options:z.options,onChange:z.onChange})})]})})}
@@ -0,0 +1,26 @@
1
+ import type * as React from 'react';
2
+ export type AdaptivePanelMode = 'sheet' | 'drawer' | 'responsive';
3
+ export type AdaptivePanelBreakpoint = 'sm' | 'md' | 'lg' | number;
4
+ export type AdaptivePanelStaticMode = Exclude<AdaptivePanelMode, 'responsive'>;
5
+ export interface AdaptivePanelProps {
6
+ open: boolean;
7
+ onOpenChange: (open: boolean) => void;
8
+ trigger: React.ReactNode;
9
+ title: React.ReactNode;
10
+ description?: React.ReactNode;
11
+ mode?: AdaptivePanelMode;
12
+ mobileMode?: AdaptivePanelStaticMode;
13
+ desktopMode?: AdaptivePanelStaticMode;
14
+ breakpoint?: AdaptivePanelBreakpoint;
15
+ sheetSide?: 'top' | 'right' | 'bottom' | 'left';
16
+ drawerDirection?: 'top' | 'right' | 'bottom' | 'left';
17
+ className?: string;
18
+ headerClassName?: string;
19
+ titleClassName?: string;
20
+ descriptionClassName?: string;
21
+ sheetClassName?: string;
22
+ drawerClassName?: string;
23
+ children: React.ReactNode;
24
+ }
25
+ export declare function AdaptivePanel({ open, onOpenChange, trigger, title, description, mode, mobileMode, desktopMode, breakpoint, sheetSide, drawerDirection, className, headerClassName, titleClassName, descriptionClassName, sheetClassName, drawerClassName, children, }: AdaptivePanelProps): import("react/jsx-runtime").JSX.Element;
26
+ export declare function toAdaptivePanelBreakpointQuery(breakpoint: AdaptivePanelBreakpoint): string;
@@ -0,0 +1 @@
1
+ import{jsx as F,jsxs as G}from"react/jsx-runtime";import{Drawer as Q,DrawerContent as M,DrawerDescription as O,DrawerHeader as T,DrawerTitle as f,DrawerTrigger as S}from"@contractspec/lib.ui-kit-web/ui/drawer";import{Sheet as u,SheetContent as y,SheetDescription as D,SheetHeader as b,SheetTitle as k,SheetTrigger as x}from"@contractspec/lib.ui-kit-web/ui/sheet";import{useMediaQuery as _}from"@contractspec/lib.ui-kit-web/ui/use-media-query";import{cn as K}from"../../lib/utils";const g={sm:"(min-width: 640px)",md:"(min-width: 768px)",lg:"(min-width: 1024px)"};export function AdaptivePanel({open:z,onOpenChange:L,trigger:V,title:W,description:J,mode:X="responsive",mobileMode:U="drawer",desktopMode:Y="sheet",breakpoint:A="md",sheetSide:B="right",drawerDirection:E="bottom",className:Z,headerClassName:$,titleClassName:q,descriptionClassName:v,sheetClassName:H,drawerClassName:P,children:I}){const R=_(toAdaptivePanelBreakpointQuery(A));if((X==="responsive"?R?Y:U:X)==="drawer")return G(Q,{open:z,onOpenChange:L,direction:E,children:[F(S,{asChild:!0,children:V}),G(M,{className:K("max-h-[85vh]",Z,P),children:[G(T,{className:$,children:[F(f,{className:q,children:W}),J?F(O,{className:v,children:J}):null]}),I]})]});return G(u,{open:z,onOpenChange:L,children:[F(x,{asChild:!0,children:V}),G(y,{side:B,className:K("sm:max-w-md",Z,H),children:[G(b,{className:$,children:[F(k,{className:q,children:W}),J?F(D,{className:v,children:J}):null]}),I]})]})}export function toAdaptivePanelBreakpointQuery(z){return typeof z==="number"?`(min-width: ${z}px)`:g[z]}
@@ -0,0 +1 @@
1
+ export { AdaptivePanel, type AdaptivePanelBreakpoint, type AdaptivePanelMode, type AdaptivePanelProps, type AdaptivePanelStaticMode, toAdaptivePanelBreakpointQuery, } from './AdaptivePanel';
@@ -0,0 +1 @@
1
+ export{AdaptivePanel,toAdaptivePanelBreakpointQuery}from"./AdaptivePanel";
@@ -0,0 +1,2 @@
1
+ import type { AppShellProps } from './AppShell.types';
2
+ export declare function AppShell({ brand, logo, title, homeHref, navigation, commands, notifications, breadcrumbs, pageOutline, activeHref, activeOutlineId, userMenu, topbarStart, topbarEnd, children, className, contentClassName, onNavigate: _onNavigate, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ import{jsx as k,jsxs as F}from"react/jsx-runtime";import{Dialog as P,DialogContent as B,DialogHeader as T,DialogTitle as D}from"@contractspec/lib.ui-kit-web/ui/dialog";import{cn as U}from"@contractspec/lib.ui-kit-web/ui/utils";import{MenuIcon as w,PanelRightIcon as y}from"lucide-react";import*as I from"react";import{Button as C}from"../atoms/Button";import{NavBrand as u}from"../atoms/NavBrand";import{Breadcrumbs as _}from"../molecules/Breadcrumbs";import{CommandSearchTrigger as x}from"../molecules/CommandSearchTrigger";import{PageOutline as M}from"./PageOutline";import{ShellNotifications as j}from"./ShellNotifications";import{ShellSidebar as d}from"./ShellSidebar";function f({sections:q,activeHref:G}){return k("nav",{className:"flex flex-col gap-5","aria-label":"Application navigation",children:q.map((A,J)=>F("div",{className:"flex flex-col gap-2",children:[A.title&&k("div",{className:"font-medium text-muted-foreground text-xs uppercase tracking-wide",children:A.title}),k("div",{className:"flex flex-col gap-1",children:A.items.map((z)=>k(N,{item:z,activeHref:G},z.key??z.href??String(z.label)))})]},A.key??J))})}function N({item:q,activeHref:G,depth:A=0}){const J=q.active||Boolean(q.href)&&Boolean(G)&&(q.match==="startsWith"?G?.startsWith(q.href??""):G===q.href),z=F("span",{className:U("inline-flex min-w-0 items-center gap-2",A>0&&"pl-4"),children:[q.icon,k("span",{className:"truncate",children:q.label}),q.badge?k("span",{className:"ml-auto text-muted-foreground text-xs",children:q.badge}):null]}),Q=q.disabled||q.policyDecision?.effect==="deny";return F("div",{className:"flex flex-col gap-1",children:[q.href&&!Q?k("a",{href:q.href,target:q.target,"aria-current":J?"page":void 0,"aria-label":q.ariaLabel,onClick:()=>q.onSelect?.(),className:U("rounded-xs px-2 py-2 text-sm hover:bg-accent hover:text-accent-foreground",J&&"bg-accent font-medium text-accent-foreground"),children:z}):k("button",{type:"button","aria-disabled":Q||void 0,disabled:Q,"aria-label":q.ariaLabel,onClick:()=>q.onSelect?.(),className:U("rounded-xs px-2 py-2 text-left text-sm hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",J&&"bg-accent font-medium text-accent-foreground"),children:z}),q.children?.length?k("div",{className:"flex flex-col gap-1",children:q.children.map((K)=>k(N,{item:K,activeHref:G,depth:A+1},K.key??K.href??String(K.label)))}):null]})}export function AppShell({brand:q,logo:G,title:A,homeHref:J,navigation:z=[],commands:Q=[],notifications:K,breadcrumbs:Z=[],pageOutline:V=[],activeHref:$,activeOutlineId:E,userMenu:W,topbarStart:S,topbarEnd:H,children:b,className:p,contentClassName:O,onNavigate:l}){const[v,L]=I.useState(!1),[h,X]=I.useState(!1),R=q??k(u,{href:J,logo:G,title:A}),Y=(g=!1)=>Q.length?k(x,{groups:Q,placeholder:"Search or run action...",compact:g}):null;return F("div",{className:U("min-h-svh bg-background",p),children:[k("header",{className:"sticky top-0 z-30 border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60",children:F("div",{className:"flex h-14 items-center gap-3 px-3 md:px-4",children:[k(C,{variant:"ghost",size:"icon",className:"md:hidden","aria-label":"Open navigation",onPress:()=>L(!0),children:k(w,{className:"h-4 w-4"})}),k("div",{className:"min-w-0 md:hidden",children:R}),k("div",{className:"hidden min-w-0 md:block",children:S}),k("div",{className:"min-w-0 flex-1",children:Z.length?k(_,{items:Z}):null}),k("div",{className:"hidden shrink-0 md:block",children:Y()}),V.length?k(C,{variant:"ghost",size:"icon",className:"lg:hidden","aria-label":"Open page outline",onPress:()=>X(!0),children:k(y,{className:"h-4 w-4"})}):null,K?k(j,{notifications:K}):null,H,W]})}),F("div",{className:"grid min-h-[calc(100svh-3.5rem)] grid-cols-1 md:grid-cols-[280px_minmax(0,1fr)] lg:grid-cols-[280px_minmax(0,1fr)_240px]",children:[k("aside",{className:"hidden border-r md:block",children:k(d,{sections:z,brand:R,commandTrigger:Y(),footer:W,activeHref:$})}),k("main",{className:U("min-w-0 px-4 py-5 md:px-6",O),children:b}),V.length?k("aside",{className:"hidden px-4 py-5 lg:block",children:k(M,{items:V,activeId:E})}):null]}),k(P,{open:v,onOpenChange:L,children:F(B,{className:"max-h-[85svh] overflow-auto sm:max-w-sm",children:[k(T,{children:k(D,{children:"Menu"})}),F("div",{className:"flex flex-col gap-4",children:[Y(),k(f,{sections:z,activeHref:$}),W]})]})}),k(P,{open:h,onOpenChange:X,children:F(B,{className:"max-h-[85svh] overflow-auto sm:max-w-sm",children:[k(T,{children:k(D,{children:"On this page"})}),k(M,{items:V,activeId:E,variant:"compact",onNavigate:()=>X(!1)})]})})]})}
@@ -0,0 +1,2 @@
1
+ import type { AppShellProps } from './AppShell.types';
2
+ export declare function AppShell({ brand, logo, title, navigation, commands, notifications, breadcrumbs, pageOutline, activeHref, activeOutlineId, userMenu, topbarEnd, children, className, homeHref: _homeHref, topbarStart: _topbarStart, contentClassName, onNavigate, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,22 @@
1
+ import type * as React from 'react';
2
+ import type { PageOutlineItem, ShellBreadcrumbItem, ShellCommandGroup, ShellNavItem, ShellNavSection, ShellNotificationCenter } from './types';
3
+ export interface AppShellProps {
4
+ brand?: React.ReactNode;
5
+ logo?: React.ReactNode;
6
+ title?: React.ReactNode;
7
+ homeHref?: string;
8
+ navigation?: ShellNavSection[];
9
+ commands?: ShellCommandGroup[];
10
+ notifications?: ShellNotificationCenter;
11
+ breadcrumbs?: ShellBreadcrumbItem[];
12
+ pageOutline?: PageOutlineItem[];
13
+ activeHref?: string;
14
+ activeOutlineId?: string;
15
+ userMenu?: React.ReactNode;
16
+ topbarStart?: React.ReactNode;
17
+ topbarEnd?: React.ReactNode;
18
+ children: React.ReactNode;
19
+ className?: string;
20
+ contentClassName?: string;
21
+ onNavigate?: (item: ShellNavItem) => void;
22
+ }
File without changes
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ import type { PageOutlineItem, PageOutlineLevel } from './types';
3
+ export interface PageOutlineProps extends React.HTMLAttributes<HTMLElement> {
4
+ items: PageOutlineItem[];
5
+ activeId?: string;
6
+ onNavigate?: (item: PageOutlineItem) => void;
7
+ ariaLabel?: string;
8
+ variant?: 'rail' | 'compact';
9
+ maxLevel?: PageOutlineLevel;
10
+ }
11
+ export declare function PageOutline({ items, activeId, onNavigate, ariaLabel, variant, maxLevel, className, ...props }: PageOutlineProps): import("react/jsx-runtime").JSX.Element | null;
12
+ export declare function usePageOutlineActiveItem(ids: string[], options?: IntersectionObserverInit): string | undefined;
@@ -0,0 +1 @@
1
+ import{jsx as H}from"react/jsx-runtime";import{cn as S}from"@contractspec/lib.ui-kit-web/ui/utils";import*as M from"react";import{resolvePageOutlineItems as U}from"./outline";export function PageOutline({items:z,activeId:E,onNavigate:J,ariaLabel:K="On this page",variant:F="rail",maxLevel:C=3,className:B,...D}){const G=M.useMemo(()=>U(z,C),[z,C]);if(!G.length)return null;return H("nav",{"aria-label":K,className:S("text-muted-foreground text-sm",F==="rail"?"sticky top-20 max-h-[calc(100svh-6rem)] overflow-auto border-l pl-4":"rounded-md border p-3",B),...D,children:H("ol",{className:"m-0 list-none space-y-1 p-0",children:G.map((q)=>{const Q=E===q.id,T=q.href??`#${q.id}`;return H("li",{children:H("a",{href:T,"aria-current":Q?"location":void 0,onClick:()=>J?.(q),className:S("block rounded-xs px-2 py-1 transition-colors hover:bg-accent hover:text-accent-foreground",q.resolvedLevel===2&&"pl-5",q.resolvedLevel===3&&"pl-8 text-xs",Q&&"bg-accent font-medium text-accent-foreground"),children:q.label})},`${q.id}-${q.resolvedLevel}`)})})})}export function usePageOutlineActiveItem(z,E){const[J,K]=M.useState(z[0]);M.useEffect(()=>{if(!z.length||typeof IntersectionObserver>"u")return;const F=new IntersectionObserver((C)=>{const B=C.filter((D)=>D.isIntersecting).sort((D,G)=>G.intersectionRatio-D.intersectionRatio)[0];if(B?.target.id)K(B.target.id)},E??{rootMargin:"-20% 0px -65% 0px",threshold:[0,0.25,0.5,1]});for(const C of z){const B=document.getElementById(C);if(B)F.observe(B)}return()=>F.disconnect()},[z,E]);return J}
@@ -0,0 +1,11 @@
1
+ import type { PageOutlineItem, PageOutlineLevel } from './types';
2
+ export interface PageOutlineProps {
3
+ items: PageOutlineItem[];
4
+ activeId?: string;
5
+ onNavigate?: (item: PageOutlineItem) => void;
6
+ ariaLabel?: string;
7
+ maxLevel?: PageOutlineLevel;
8
+ className?: string;
9
+ }
10
+ export declare function PageOutline({ items, activeId, onNavigate, ariaLabel, maxLevel, className, }: PageOutlineProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export declare function usePageOutlineActiveItem(ids: string[]): string | undefined;
@@ -0,0 +1,5 @@
1
+ import type { ShellNotificationCenter } from './types';
2
+ export interface ShellNotificationsProps {
3
+ notifications: ShellNotificationCenter;
4
+ }
5
+ export declare function ShellNotifications({ notifications }: ShellNotificationsProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ import{jsx as D,jsxs as G,Fragment as S}from"react/jsx-runtime";import{cn as Z}from"@contractspec/lib.ui-kit-web/ui/utils";import{BellIcon as T,CheckIcon as $,XIcon as X}from"lucide-react";import*as q from"react";import{Button as V}from"../atoms/Button";function A(z){return z.status==="unread"||!z.status&&!z.readAt}function F(z){if(!z)return;return z instanceof Date?z.toLocaleString():z}export function ShellNotifications({notifications:z}){const[H,W]=q.useState(!1),E=z.items??[],J=z.unreadCount??E.filter((M)=>A(M)).length,K=z.label??"Notifications",P=z.emptyLabel??"No notifications",Q=z.markAllReadLabel??"Mark all notifications as read",Y=(M)=>{W(M);z.onOpenChange?.(M)};return G(S,{children:[G(V,{variant:"ghost",size:"icon",className:"relative",ariaLabelI18n:K,onPress:()=>Y(!0),children:[D(T,{className:"h-4 w-4"}),J>0?D("span",{"aria-label":`${J} unread notifications`,className:"absolute -top-1 -right-1 inline-flex min-h-4 min-w-4 items-center justify-center rounded-full bg-destructive px-1 font-medium text-[10px] text-destructive-foreground leading-none",children:J>99?"99+":J}):null]}),H?G("div",{"aria-label":K,"aria-modal":"true",className:"fixed top-16 right-4 z-50 max-h-[calc(100svh-5rem)] w-[min(24rem,calc(100vw-2rem))] overflow-auto rounded-md border bg-background p-4 shadow-lg",role:"dialog",children:[G("div",{className:"mb-3 flex items-center justify-between gap-3",children:[D("h2",{className:"font-semibold text-lg",children:K}),G("div",{className:"flex items-center gap-1",children:[E.length>0&&z.onMarkAllRead?G(V,{variant:"ghost",size:"sm",ariaLabelI18n:Q,onPress:z.onMarkAllRead,children:[D($,{className:"h-4 w-4"}),D("span",{children:"Mark all read"})]}):null,D(V,{variant:"ghost",size:"icon",ariaLabelI18n:"Close notifications",onPress:()=>Y(!1),children:D(X,{className:"h-4 w-4"})})]})]}),D("div",{className:"flex flex-col gap-2",children:z.loading?D("div",{"aria-live":"polite",className:"py-6 text-center text-muted-foreground text-sm",children:"Loading notifications..."}):E.length?E.map((M)=>D(U,{item:M,notifications:z,onClose:()=>Y(!1)},M.id)):D("div",{className:"py-6 text-center text-muted-foreground text-sm",children:P})})]}):null]})}function U({item:z,notifications:H,onClose:W}){const E=A(z),J=F(z.createdAt),K=()=>{H.onSelect?.(z);W()},P=()=>H.onMarkRead?.(z);if(H.renderItem)return D("div",{className:Z("rounded-xs border p-3",E&&"bg-muted/50"),children:H.renderItem(z,{unread:E,onSelect:K,onMarkRead:P})});const Q=D(S,{children:G("span",{className:"flex min-w-0 flex-1 flex-col gap-1 text-left",children:[G("span",{className:"flex items-center gap-2",children:[E?D("span",{className:"h-2 w-2 rounded-full bg-primary","aria-hidden":!0}):null,D("span",{className:"font-medium text-sm",children:z.title})]}),z.body?D("span",{className:"text-muted-foreground text-sm",children:z.body}):null,G("span",{className:"flex flex-wrap items-center gap-2 text-muted-foreground text-xs",children:[z.category?D("span",{children:z.category}):null,J?D("time",{children:J}):null]})]})});return G("div",{className:Z("flex items-start gap-2 rounded-xs border p-3",E&&"bg-muted/50"),children:[z.actionUrl?D("a",{href:z.actionUrl,className:"min-w-0 flex-1",onClick:K,children:Q}):D("button",{type:"button",className:"min-w-0 flex-1",onClick:K,children:Q}),E&&H.onMarkRead?D(V,{variant:"ghost",size:"icon",ariaLabelI18n:`Mark ${String(z.title)} as read`,onPress:P,children:D($,{className:"h-4 w-4"})}):null]})}
@@ -0,0 +1,5 @@
1
+ import type { ShellNotificationCenter } from './types';
2
+ export interface NativeShellNotificationsSectionProps {
3
+ notifications: ShellNotificationCenter;
4
+ }
5
+ export declare function NativeShellNotificationsSection({ notifications, }: NativeShellNotificationsSectionProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ import type { ShellNavSection } from './types';
3
+ export interface ShellSidebarProps {
4
+ sections: ShellNavSection[];
5
+ brand?: React.ReactNode;
6
+ commandTrigger?: React.ReactNode;
7
+ footer?: React.ReactNode;
8
+ activeHref?: string;
9
+ className?: string;
10
+ }
11
+ export declare function ShellSidebar({ sections, brand, commandTrigger, footer, activeHref, className, }: ShellSidebarProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ import{jsx as z,jsxs as Q}from"react/jsx-runtime";import{Sidebar as A,SidebarContent as F,SidebarFooter as L,SidebarGroup as P,SidebarGroupContent as R,SidebarGroupLabel as B,SidebarHeader as K,SidebarMenu as Y,SidebarMenuBadge as N,SidebarMenuButton as C,SidebarMenuItem as G,SidebarProvider as I,SidebarRail as T}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{cn as Z}from"@contractspec/lib.ui-kit-web/ui/utils";function M(q,D){if(q.active)return!0;if(!D||!q.href)return!1;return q.match==="startsWith"?D.startsWith(q.href):D===q.href}function $(q){return q.key??q.href??String(q.label)}function k({item:q,activeHref:D,depth:O=0}){const U=M(q,D),E=q.disabled||q.policyDecision?.effect==="deny",W=Boolean(q.children?.length),J=Q("span",{className:Z("inline-flex min-w-0 items-center gap-2",O>0&&"pl-4"),children:[q.icon,z("span",{className:"truncate",children:q.label})]});return Q(G,{children:[z(C,{asChild:!!q.href&&!E,isActive:U,"aria-disabled":E,"aria-label":q.href&&!E?void 0:q.ariaLabel,disabled:E,onClick:q.href||E?void 0:()=>q.onSelect?.(),children:q.href&&!E?z("a",{href:q.href,target:q.target,"aria-label":q.ariaLabel,onClick:()=>q.onSelect?.(),children:J}):J}),q.badge!=null&&z(N,{children:q.badge}),W&&z(Y,{className:"mt-1",children:q.children?.map((V)=>z(k,{item:V,activeHref:D,depth:O+1},$(V)))})]})}export function ShellSidebar({sections:q,brand:D,commandTrigger:O,footer:U,activeHref:E,className:W}){return z(I,{children:Q(A,{className:W,children:[z(T,{}),Q(K,{className:Z("gap-3",!D&&!O&&"hidden"),children:[D,O]}),z(F,{children:q.map((J,V)=>Q(P,{children:[J.title&&z(B,{children:J.title}),z(R,{children:z(Y,{children:J.items.map((X)=>z(k,{item:X,activeHref:E},$(X)))})})]},J.key??V))}),U&&z(L,{children:U})]})})}
@@ -0,0 +1,8 @@
1
+ export { AppShell } from './AppShell';
2
+ export type { AppShellProps } from './AppShell.types';
3
+ export { PageOutline, type PageOutlineProps, usePageOutlineActiveItem, } from './PageOutline';
4
+ export type { PolicyAwareShellCommandItem, PolicyAwareShellNavItem, ShellPolicyAnnotated, ShellPolicyBehavior, ShellPolicyDecisionProvider, } from './policy';
5
+ export { annotateShellCommandsDecisions, annotateShellNavigationDecisions, filterShellNavigationForPolicy, } from './policy';
6
+ export { ShellNotifications, type ShellNotificationsProps, } from './ShellNotifications';
7
+ export { ShellSidebar, type ShellSidebarProps } from './ShellSidebar';
8
+ export type { AppShellConfig, PageOutlineItem, PageOutlineLevel, ShellBreadcrumbItem, ShellCommandGroup, ShellCommandItem, ShellNavItem, ShellNavMatch, ShellNavSection, ShellNotificationCenter, ShellNotificationItem, ShellNotificationRenderContext, ShellNotificationStatus, ShellUserMenu, ShellUserMenuItem, } from './types';
@@ -0,0 +1 @@
1
+ export{AppShell}from"./AppShell";export{PageOutline,usePageOutlineActiveItem}from"./PageOutline";export{annotateShellCommandsDecisions,annotateShellNavigationDecisions,filterShellNavigationForPolicy}from"./policy";export{ShellNotifications}from"./ShellNotifications";export{ShellSidebar}from"./ShellSidebar";
@@ -0,0 +1,5 @@
1
+ export { AppShell } from './AppShell.native';
2
+ export type { AppShellProps } from './AppShell.types';
3
+ export { PageOutline, type PageOutlineProps, usePageOutlineActiveItem, } from './PageOutline.native';
4
+ export { NativeShellNotificationsSection, type NativeShellNotificationsSectionProps, } from './ShellNotifications.native';
5
+ export type { AppShellConfig, PageOutlineItem, PageOutlineLevel, ShellBreadcrumbItem, ShellCommandGroup, ShellCommandItem, ShellNavItem, ShellNavMatch, ShellNavSection, ShellNotificationCenter, ShellNotificationItem, ShellNotificationRenderContext, ShellNotificationStatus, ShellUserMenu, ShellUserMenuItem, } from './types';
@@ -0,0 +1,5 @@
1
+ import type { PageOutlineItem, PageOutlineLevel } from './types';
2
+ export type ResolvedPageOutlineItem = PageOutlineItem & {
3
+ resolvedLevel: PageOutlineLevel;
4
+ };
5
+ export declare function resolvePageOutlineItems(items: PageOutlineItem[], maxLevel: PageOutlineLevel, parentLevel?: number): ResolvedPageOutlineItem[];
@@ -0,0 +1 @@
1
+ export function resolvePageOutlineItems(n,t,r=1){return n.flatMap((e)=>{const l=Math.min(e.level??r,t),a={...e,resolvedLevel:l},i=e.children?.length?resolvePageOutlineItems(e.children,t,Math.min(l+1,t)):[];return[a,...i]})}
@@ -0,0 +1,15 @@
1
+ import type { PolicyDecision } from '@contractspec/lib.contracts-spec';
2
+ import type { PolicyRequirement } from '@contractspec/lib.contracts-spec/policy';
3
+ import type { ShellCommandGroup, ShellCommandItem, ShellNavItem, ShellNavSection } from './types';
4
+ export type ShellPolicyBehavior = 'hide' | 'disable' | 'show-with-lock';
5
+ export type ShellPolicyDecisionProvider<TItem> = (policy: PolicyRequirement, item: TItem) => PolicyDecision;
6
+ export interface ShellPolicyAnnotated {
7
+ policyDecision?: PolicyDecision;
8
+ disabled?: boolean;
9
+ locked?: boolean;
10
+ }
11
+ export type PolicyAwareShellNavItem = ShellNavItem & ShellPolicyAnnotated;
12
+ export type PolicyAwareShellCommandItem = ShellCommandItem & ShellPolicyAnnotated;
13
+ export declare function filterShellNavigationForPolicy(sections: ShellNavSection[], decisionProvider: ShellPolicyDecisionProvider<ShellNavItem | ShellNavSection>): ShellNavSection[];
14
+ export declare function annotateShellNavigationDecisions(sections: ShellNavSection[], decisionProvider: ShellPolicyDecisionProvider<ShellNavItem | ShellNavSection>): ShellNavSection[];
15
+ export declare function annotateShellCommandsDecisions(groups: ShellCommandGroup[], decisionProvider: ShellPolicyDecisionProvider<ShellCommandItem>): ShellCommandGroup[];
@@ -0,0 +1 @@
1
+ export function filterShellNavigationForPolicy(q,y){return annotateShellNavigationDecisions(q,y)}export function annotateShellNavigationDecisions(q,y){return q.flatMap((f)=>{const w=f.policy?y(f.policy,f):void 0,j=f.policyBehavior??"hide";if(w?.effect==="deny"&&j==="hide")return[];const k=f.items.flatMap((z)=>F(z,y));if(!k.length&&j==="hide")return[];if(!w&&k.length===f.items.length&&k.every((z,E)=>z===f.items[E]))return[f];return[{...f,items:k,policyDecision:w,disabled:w?.effect==="deny"&&j==="disable",locked:w?.effect==="deny"&&j==="show-with-lock"}]})}export function annotateShellCommandsDecisions(q,y){return q.flatMap((f)=>{const w=f.items.flatMap((j)=>{if(!j.policy)return[j];const k=y(j.policy,j);if(k.effect==="allow")return[{...j,policyDecision:k}];const A=j.policyBehavior??"disable";if(A==="hide")return[];return[{...j,policyDecision:k,disabled:A==="disable",locked:A==="show-with-lock"}]});return w.length?[{...f,items:w}]:[]})}function F(q,y){const f=q.policy?y(q.policy,q):void 0,w=q.policyBehavior??"hide";if(f?.effect==="deny"&&w==="hide")return[];const j=q.children,k=j?.flatMap((z)=>F(z,y));if(j?.length&&!k?.length&&!q.href&&w==="hide")return[];const A=!j&&!k||!!k&&k.length===j?.length&&k.every((z,E)=>z===j?.[E]);if(!f&&A)return[q];return[{...q,children:k,policyDecision:f,disabled:f?.effect==="deny"&&w==="disable",locked:f?.effect==="deny"&&w==="show-with-lock"}]}
@@ -0,0 +1,116 @@
1
+ import type { PolicyDecision } from '@contractspec/lib.contracts-spec';
2
+ import type { PolicyRequirement } from '@contractspec/lib.contracts-spec/policy';
3
+ import type * as React from 'react';
4
+ export type ShellNavMatch = 'exact' | 'startsWith';
5
+ export interface ShellNavItem {
6
+ policy?: PolicyRequirement;
7
+ policyBehavior?: 'hide' | 'disable' | 'show-with-lock';
8
+ policyDecision?: PolicyDecision;
9
+ disabled?: boolean;
10
+ locked?: boolean;
11
+ key?: string;
12
+ label: React.ReactNode;
13
+ href?: string;
14
+ icon?: React.ReactNode;
15
+ badge?: React.ReactNode;
16
+ description?: React.ReactNode;
17
+ children?: ShellNavItem[];
18
+ active?: boolean;
19
+ match?: ShellNavMatch;
20
+ priority?: number;
21
+ target?: '_self' | '_blank';
22
+ ariaLabel?: string;
23
+ onSelect?: () => void;
24
+ commandId?: string;
25
+ }
26
+ export interface ShellNavSection {
27
+ policy?: PolicyRequirement;
28
+ policyBehavior?: 'hide' | 'disable' | 'show-with-lock';
29
+ policyDecision?: PolicyDecision;
30
+ disabled?: boolean;
31
+ locked?: boolean;
32
+ key?: string;
33
+ title?: React.ReactNode;
34
+ items: ShellNavItem[];
35
+ }
36
+ export interface ShellCommandItem {
37
+ policy?: PolicyRequirement;
38
+ policyBehavior?: 'hide' | 'disable' | 'show-with-lock';
39
+ policyDecision?: PolicyDecision;
40
+ disabled?: boolean;
41
+ locked?: boolean;
42
+ id: string;
43
+ label: string;
44
+ shortcut?: string;
45
+ onSelect?: () => void;
46
+ }
47
+ export interface ShellCommandGroup {
48
+ heading?: string;
49
+ items: ShellCommandItem[];
50
+ }
51
+ export interface ShellBreadcrumbItem {
52
+ href?: string;
53
+ label: React.ReactNode;
54
+ }
55
+ export type ShellNotificationStatus = 'unread' | 'read' | 'archived' | string;
56
+ export interface ShellNotificationItem {
57
+ id: string;
58
+ title: React.ReactNode;
59
+ body?: React.ReactNode;
60
+ type?: string;
61
+ status?: ShellNotificationStatus;
62
+ readAt?: string | Date | null;
63
+ createdAt?: string | Date;
64
+ actionUrl?: string;
65
+ priority?: 'low' | 'normal' | 'high' | 'urgent' | string;
66
+ category?: string;
67
+ metadata?: Record<string, unknown>;
68
+ }
69
+ export interface ShellNotificationRenderContext {
70
+ unread: boolean;
71
+ onSelect: () => void;
72
+ onMarkRead: () => void;
73
+ }
74
+ export interface ShellNotificationCenter {
75
+ items?: ShellNotificationItem[];
76
+ unreadCount?: number;
77
+ loading?: boolean;
78
+ emptyLabel?: React.ReactNode;
79
+ label?: string;
80
+ markAllReadLabel?: string;
81
+ onOpenChange?: (open: boolean) => void;
82
+ onSelect?: (item: ShellNotificationItem) => void;
83
+ onMarkRead?: (item: ShellNotificationItem) => void;
84
+ onMarkAllRead?: () => void;
85
+ renderItem?: (item: ShellNotificationItem, context: ShellNotificationRenderContext) => React.ReactNode;
86
+ }
87
+ export interface ShellUserMenuItem {
88
+ label: React.ReactNode;
89
+ href?: string;
90
+ onSelect?: () => void;
91
+ icon?: React.ReactNode;
92
+ danger?: boolean;
93
+ }
94
+ export interface ShellUserMenu {
95
+ name?: string;
96
+ email?: string;
97
+ imageUrl?: string;
98
+ items: ShellUserMenuItem[];
99
+ }
100
+ export type PageOutlineLevel = 1 | 2 | 3;
101
+ export interface PageOutlineItem {
102
+ id: string;
103
+ label: React.ReactNode;
104
+ href?: string;
105
+ level?: PageOutlineLevel;
106
+ children?: PageOutlineItem[];
107
+ }
108
+ export interface AppShellConfig {
109
+ brand?: React.ReactNode;
110
+ navigation?: ShellNavSection[];
111
+ commands?: ShellCommandGroup[];
112
+ notifications?: ShellNotificationCenter;
113
+ breadcrumbs?: ShellBreadcrumbItem[];
114
+ userMenu?: React.ReactNode;
115
+ pageOutline?: PageOutlineItem[];
116
+ }
File without changes
@@ -1 +1 @@
1
- import{defineFeature as g}from"@contractspec/lib.contracts-spec/features";export const DesignSystemFeature=g({meta:{key:"libs.design-system",version:"1.0.0",title:"Design System",description:"Design tokens and theming primitives",domain:"design-system",owners:["@contractspec-core"],tags:["package","libs","design-system"],stability:"experimental"}});
1
+ import{defineFeature as g}from"@contractspec/lib.contracts-spec/features";export const DesignSystemFeature=g({meta:{key:"libs.design-system",version:"1.0.0",title:"Design System",description:"Design tokens, theming primitives, and composed product-surface components",domain:"design-system",owners:["@contractspec-core"],tags:["package","libs","design-system","components"],stability:"experimental"}});
@@ -1,6 +1,7 @@
1
1
  import type { TranslationRegistry } from '@contractspec/lib.contracts-spec/translations';
2
+ import type { RuntimeValues, TranslationRuntime } from '@contractspec/lib.translation-runtime';
2
3
  import * as React from 'react';
3
- export type DesignSystemTranslationResolver = (key: string) => string | undefined;
4
+ export type DesignSystemTranslationResolver = (key: string, values?: RuntimeValues) => string | undefined;
4
5
  export declare function DesignSystemTranslationProvider({ children, resolver, }: {
5
6
  children: React.ReactNode;
6
7
  resolver?: DesignSystemTranslationResolver;
@@ -14,3 +15,7 @@ export declare function createTranslationResolver({ registry, locale, fallbackLo
14
15
  fallbackLocale?: string;
15
16
  specKeys?: string[];
16
17
  }): DesignSystemTranslationResolver;
18
+ export declare function createRuntimeTranslationResolver({ runtime, onMissing, }: {
19
+ runtime: TranslationRuntime;
20
+ onMissing?: 'key' | 'empty' | 'throw';
21
+ }): DesignSystemTranslationResolver;