@contractspec/lib.example-shared-ui 3.4.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2129,6 +2129,79 @@ function SaveToStudioButton({
2129
2129
  }, undefined, true, undefined, this);
2130
2130
  }
2131
2131
 
2132
+ // src/SpecDrivenTemplateShell.tsx
2133
+ import { BundleProvider, BundleRenderer } from "@contractspec/lib.surface-runtime/react";
2134
+ import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
2135
+ function SpecDrivenTemplateShell({
2136
+ plan,
2137
+ title,
2138
+ description,
2139
+ sidebar,
2140
+ actions,
2141
+ showSaveAction = true,
2142
+ saveProps,
2143
+ children
2144
+ }) {
2145
+ const headerContent = /* @__PURE__ */ jsxDEV8("header", {
2146
+ className: "border-border bg-card rounded-2xl border p-6 shadow-sm",
2147
+ children: [
2148
+ /* @__PURE__ */ jsxDEV8("div", {
2149
+ className: "flex flex-wrap items-center justify-between gap-4",
2150
+ children: [
2151
+ /* @__PURE__ */ jsxDEV8("div", {
2152
+ children: [
2153
+ /* @__PURE__ */ jsxDEV8("p", {
2154
+ className: "text-muted-foreground text-sm font-semibold tracking-wide uppercase",
2155
+ children: "ContractSpec Templates"
2156
+ }, undefined, false, undefined, this),
2157
+ /* @__PURE__ */ jsxDEV8("h1", {
2158
+ className: "text-3xl font-bold",
2159
+ children: title
2160
+ }, undefined, false, undefined, this),
2161
+ description ? /* @__PURE__ */ jsxDEV8("p", {
2162
+ className: "text-muted-foreground mt-2 max-w-2xl text-sm",
2163
+ children: description
2164
+ }, undefined, false, undefined, this) : null
2165
+ ]
2166
+ }, undefined, true, undefined, this),
2167
+ /* @__PURE__ */ jsxDEV8("div", {
2168
+ className: "flex flex-col items-end gap-2",
2169
+ children: [
2170
+ /* @__PURE__ */ jsxDEV8(LocalDataIndicator, {}, undefined, false, undefined, this),
2171
+ showSaveAction ? /* @__PURE__ */ jsxDEV8(SaveToStudioButton, {
2172
+ ...saveProps
2173
+ }, undefined, false, undefined, this) : null
2174
+ ]
2175
+ }, undefined, true, undefined, this)
2176
+ ]
2177
+ }, undefined, true, undefined, this),
2178
+ actions ? /* @__PURE__ */ jsxDEV8("div", {
2179
+ className: "mt-4",
2180
+ children: actions
2181
+ }, undefined, false, undefined, this) : null
2182
+ ]
2183
+ }, undefined, true, undefined, this);
2184
+ const slotContent = {
2185
+ header: headerContent,
2186
+ primary: /* @__PURE__ */ jsxDEV8("main", {
2187
+ className: "space-y-4 p-2",
2188
+ children
2189
+ }, undefined, false, undefined, this)
2190
+ };
2191
+ if (sidebar != null) {
2192
+ slotContent.sidebar = /* @__PURE__ */ jsxDEV8("aside", {
2193
+ className: "border-border bg-card rounded-2xl border p-4",
2194
+ children: sidebar
2195
+ }, undefined, false, undefined, this);
2196
+ }
2197
+ return /* @__PURE__ */ jsxDEV8(BundleProvider, {
2198
+ plan,
2199
+ children: /* @__PURE__ */ jsxDEV8(BundleRenderer, {
2200
+ slotContent
2201
+ }, undefined, false, undefined, this)
2202
+ }, undefined, false, undefined, this);
2203
+ }
2204
+
2132
2205
  // src/utils/generateSpecFromTemplate.ts
2133
2206
  function generateSpecFromTemplate(template) {
2134
2207
  const templateId = template?.id ?? "unknown";
@@ -2698,7 +2771,7 @@ function useSpecContent(templateId) {
2698
2771
  import { useCallback as useCallback8, useEffect as useEffect5 } from "react";
2699
2772
  import { Button as Button5, LoaderBlock as LoaderBlock3 } from "@contractspec/lib.design-system";
2700
2773
  import { Badge as Badge5 } from "@contractspec/lib.ui-kit-web/ui/badge";
2701
- import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
2774
+ import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
2702
2775
  "use client";
2703
2776
  function SpecEditorPanel({
2704
2777
  templateId,
@@ -2740,54 +2813,54 @@ function SpecEditorPanel({
2740
2813
  onLog?.("Spec reset to template defaults");
2741
2814
  }, [reset, onLog]);
2742
2815
  if (loading) {
2743
- return /* @__PURE__ */ jsxDEV8(LoaderBlock3, {
2816
+ return /* @__PURE__ */ jsxDEV9(LoaderBlock3, {
2744
2817
  label: "Loading spec..."
2745
2818
  }, undefined, false, undefined, this);
2746
2819
  }
2747
- return /* @__PURE__ */ jsxDEV8("div", {
2820
+ return /* @__PURE__ */ jsxDEV9("div", {
2748
2821
  className: "space-y-4",
2749
2822
  children: [
2750
- /* @__PURE__ */ jsxDEV8("div", {
2823
+ /* @__PURE__ */ jsxDEV9("div", {
2751
2824
  className: "flex items-center justify-between",
2752
2825
  children: [
2753
- /* @__PURE__ */ jsxDEV8("div", {
2826
+ /* @__PURE__ */ jsxDEV9("div", {
2754
2827
  className: "flex items-center gap-2",
2755
2828
  children: [
2756
- /* @__PURE__ */ jsxDEV8(Button5, {
2829
+ /* @__PURE__ */ jsxDEV9(Button5, {
2757
2830
  variant: "default",
2758
2831
  size: "sm",
2759
2832
  onClick: handleSave,
2760
2833
  children: "Save"
2761
2834
  }, undefined, false, undefined, this),
2762
- /* @__PURE__ */ jsxDEV8(Button5, {
2835
+ /* @__PURE__ */ jsxDEV9(Button5, {
2763
2836
  variant: "outline",
2764
2837
  size: "sm",
2765
2838
  onClick: handleValidate,
2766
2839
  children: "Validate"
2767
2840
  }, undefined, false, undefined, this),
2768
- isDirty && /* @__PURE__ */ jsxDEV8(Badge5, {
2841
+ isDirty && /* @__PURE__ */ jsxDEV9(Badge5, {
2769
2842
  variant: "secondary",
2770
2843
  className: "border-amber-500/30 bg-amber-500/20 text-amber-400",
2771
2844
  children: "Unsaved changes"
2772
2845
  }, undefined, false, undefined, this),
2773
- validation && /* @__PURE__ */ jsxDEV8(Badge5, {
2846
+ validation && /* @__PURE__ */ jsxDEV9(Badge5, {
2774
2847
  variant: validation.valid ? "default" : "destructive",
2775
2848
  className: validation.valid ? "border-green-500/30 bg-green-500/20 text-green-400" : "",
2776
2849
  children: validation.valid ? "Valid" : `${validation.errors.filter((e) => e.severity === "error").length} errors`
2777
2850
  }, undefined, false, undefined, this)
2778
2851
  ]
2779
2852
  }, undefined, true, undefined, this),
2780
- /* @__PURE__ */ jsxDEV8("div", {
2853
+ /* @__PURE__ */ jsxDEV9("div", {
2781
2854
  className: "flex items-center gap-2",
2782
2855
  children: [
2783
- lastSaved && /* @__PURE__ */ jsxDEV8("span", {
2856
+ lastSaved && /* @__PURE__ */ jsxDEV9("span", {
2784
2857
  className: "text-muted-foreground text-xs",
2785
2858
  children: [
2786
2859
  "Last saved: ",
2787
2860
  new Date(lastSaved).toLocaleTimeString()
2788
2861
  ]
2789
2862
  }, undefined, true, undefined, this),
2790
- /* @__PURE__ */ jsxDEV8(Button5, {
2863
+ /* @__PURE__ */ jsxDEV9(Button5, {
2791
2864
  variant: "ghost",
2792
2865
  size: "sm",
2793
2866
  onPress: handleReset,
@@ -2797,16 +2870,16 @@ function SpecEditorPanel({
2797
2870
  }, undefined, true, undefined, this)
2798
2871
  ]
2799
2872
  }, undefined, true, undefined, this),
2800
- validation && validation.errors.length > 0 && /* @__PURE__ */ jsxDEV8("div", {
2873
+ validation && validation.errors.length > 0 && /* @__PURE__ */ jsxDEV9("div", {
2801
2874
  className: "rounded-lg border border-amber-500/50 bg-amber-500/10 p-3",
2802
2875
  children: [
2803
- /* @__PURE__ */ jsxDEV8("p", {
2876
+ /* @__PURE__ */ jsxDEV9("p", {
2804
2877
  className: "mb-2 text-xs font-semibold text-amber-400 uppercase",
2805
2878
  children: "Validation Issues"
2806
2879
  }, undefined, false, undefined, this),
2807
- /* @__PURE__ */ jsxDEV8("ul", {
2880
+ /* @__PURE__ */ jsxDEV9("ul", {
2808
2881
  className: "space-y-1",
2809
- children: validation.errors.map((error, index) => /* @__PURE__ */ jsxDEV8("li", {
2882
+ children: validation.errors.map((error, index) => /* @__PURE__ */ jsxDEV9("li", {
2810
2883
  className: `text-xs ${error.severity === "error" ? "text-red-400" : "text-amber-400"}`,
2811
2884
  children: [
2812
2885
  "Line ",
@@ -2818,9 +2891,9 @@ function SpecEditorPanel({
2818
2891
  }, undefined, false, undefined, this)
2819
2892
  ]
2820
2893
  }, undefined, true, undefined, this),
2821
- /* @__PURE__ */ jsxDEV8("div", {
2894
+ /* @__PURE__ */ jsxDEV9("div", {
2822
2895
  className: "border-border bg-card rounded-2xl border p-4",
2823
- children: /* @__PURE__ */ jsxDEV8(SpecEditor, {
2896
+ children: /* @__PURE__ */ jsxDEV9(SpecEditor, {
2824
2897
  projectId: "sandbox",
2825
2898
  type: "CAPABILITY",
2826
2899
  content,
@@ -2835,7 +2908,7 @@ function SpecEditorPanel({
2835
2908
  }
2836
2909
 
2837
2910
  // src/TemplateShell.tsx
2838
- import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
2911
+ import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
2839
2912
  var TemplateShell = ({
2840
2913
  title,
2841
2914
  description,
@@ -2844,56 +2917,56 @@ var TemplateShell = ({
2844
2917
  showSaveAction = true,
2845
2918
  saveProps,
2846
2919
  children
2847
- }) => /* @__PURE__ */ jsxDEV9("div", {
2920
+ }) => /* @__PURE__ */ jsxDEV10("div", {
2848
2921
  className: "space-y-6",
2849
2922
  children: [
2850
- /* @__PURE__ */ jsxDEV9("header", {
2923
+ /* @__PURE__ */ jsxDEV10("header", {
2851
2924
  className: "border-border bg-card rounded-2xl border p-6 shadow-sm",
2852
2925
  children: [
2853
- /* @__PURE__ */ jsxDEV9("div", {
2926
+ /* @__PURE__ */ jsxDEV10("div", {
2854
2927
  className: "flex flex-wrap items-center justify-between gap-4",
2855
2928
  children: [
2856
- /* @__PURE__ */ jsxDEV9("div", {
2929
+ /* @__PURE__ */ jsxDEV10("div", {
2857
2930
  children: [
2858
- /* @__PURE__ */ jsxDEV9("p", {
2931
+ /* @__PURE__ */ jsxDEV10("p", {
2859
2932
  className: "text-muted-foreground text-sm font-semibold tracking-wide uppercase",
2860
2933
  children: "ContractSpec Templates"
2861
2934
  }, undefined, false, undefined, this),
2862
- /* @__PURE__ */ jsxDEV9("h1", {
2935
+ /* @__PURE__ */ jsxDEV10("h1", {
2863
2936
  className: "text-3xl font-bold",
2864
2937
  children: title
2865
2938
  }, undefined, false, undefined, this),
2866
- description ? /* @__PURE__ */ jsxDEV9("p", {
2939
+ description ? /* @__PURE__ */ jsxDEV10("p", {
2867
2940
  className: "text-muted-foreground mt-2 max-w-2xl text-sm",
2868
2941
  children: description
2869
2942
  }, undefined, false, undefined, this) : null
2870
2943
  ]
2871
2944
  }, undefined, true, undefined, this),
2872
- /* @__PURE__ */ jsxDEV9("div", {
2945
+ /* @__PURE__ */ jsxDEV10("div", {
2873
2946
  className: "flex flex-col items-end gap-2",
2874
2947
  children: [
2875
- /* @__PURE__ */ jsxDEV9(LocalDataIndicator, {}, undefined, false, undefined, this),
2876
- showSaveAction ? /* @__PURE__ */ jsxDEV9(SaveToStudioButton, {
2948
+ /* @__PURE__ */ jsxDEV10(LocalDataIndicator, {}, undefined, false, undefined, this),
2949
+ showSaveAction ? /* @__PURE__ */ jsxDEV10(SaveToStudioButton, {
2877
2950
  ...saveProps
2878
2951
  }, undefined, false, undefined, this) : null
2879
2952
  ]
2880
2953
  }, undefined, true, undefined, this)
2881
2954
  ]
2882
2955
  }, undefined, true, undefined, this),
2883
- actions ? /* @__PURE__ */ jsxDEV9("div", {
2956
+ actions ? /* @__PURE__ */ jsxDEV10("div", {
2884
2957
  className: "mt-4",
2885
2958
  children: actions
2886
2959
  }, undefined, false, undefined, this) : null
2887
2960
  ]
2888
2961
  }, undefined, true, undefined, this),
2889
- /* @__PURE__ */ jsxDEV9("div", {
2962
+ /* @__PURE__ */ jsxDEV10("div", {
2890
2963
  className: sidebar ? "grid gap-6 lg:grid-cols-[minmax(0,1fr)_320px]" : "w-full",
2891
2964
  children: [
2892
- /* @__PURE__ */ jsxDEV9("main", {
2965
+ /* @__PURE__ */ jsxDEV10("main", {
2893
2966
  className: "space-y-4 p-2",
2894
2967
  children
2895
2968
  }, undefined, false, undefined, this),
2896
- sidebar ? /* @__PURE__ */ jsxDEV9("aside", {
2969
+ sidebar ? /* @__PURE__ */ jsxDEV10("aside", {
2897
2970
  className: "border-border bg-card rounded-2xl border p-4",
2898
2971
  children: sidebar
2899
2972
  }, undefined, false, undefined, this) : null
@@ -3487,6 +3560,7 @@ export {
3487
3560
  TemplateRuntimeContext,
3488
3561
  TemplateComponentRegistry,
3489
3562
  SpecEditorPanel,
3563
+ SpecDrivenTemplateShell,
3490
3564
  SaveToStudioButton,
3491
3565
  PersonalizationInsights,
3492
3566
  OverlayContextProvider,
@@ -0,0 +1,194 @@
1
+ // src/lib/runtime-context.tsx
2
+ import { createContext, useContext } from "react";
3
+ "use client";
4
+ var TemplateRuntimeContext = createContext(null);
5
+ function useTemplateRuntime() {
6
+ const context = useContext(TemplateRuntimeContext);
7
+ if (!context) {
8
+ throw new Error("useTemplateRuntime must be used within a TemplateRuntimeProvider");
9
+ }
10
+ return context;
11
+ }
12
+
13
+ // src/LocalDataIndicator.tsx
14
+ import { RefreshCw, Shield } from "lucide-react";
15
+ import { useState } from "react";
16
+ import { jsxDEV } from "react/jsx-dev-runtime";
17
+ "use client";
18
+ function LocalDataIndicator() {
19
+ const { projectId, templateId, template, installer } = useTemplateRuntime();
20
+ const [isResetting, setIsResetting] = useState(false);
21
+ const handleReset = async () => {
22
+ setIsResetting(true);
23
+ try {
24
+ await installer.install(templateId, { projectId });
25
+ } finally {
26
+ setIsResetting(false);
27
+ }
28
+ };
29
+ return /* @__PURE__ */ jsxDEV("div", {
30
+ className: "border-border bg-muted/40 text-muted-foreground inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs",
31
+ children: [
32
+ /* @__PURE__ */ jsxDEV(Shield, {
33
+ className: "h-3.5 w-3.5 text-violet-400"
34
+ }, undefined, false, undefined, this),
35
+ /* @__PURE__ */ jsxDEV("span", {
36
+ children: [
37
+ "Local runtime ·",
38
+ " ",
39
+ /* @__PURE__ */ jsxDEV("span", {
40
+ className: "text-foreground font-semibold",
41
+ children: template.name
42
+ }, undefined, false, undefined, this)
43
+ ]
44
+ }, undefined, true, undefined, this),
45
+ /* @__PURE__ */ jsxDEV("button", {
46
+ type: "button",
47
+ className: "border-border text-muted-foreground hover:text-foreground inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[11px] font-semibold",
48
+ onClick: handleReset,
49
+ disabled: isResetting,
50
+ children: [
51
+ /* @__PURE__ */ jsxDEV(RefreshCw, {
52
+ className: "h-3 w-3"
53
+ }, undefined, false, undefined, this),
54
+ isResetting ? "Resetting…" : "Reset data"
55
+ ]
56
+ }, undefined, true, undefined, this)
57
+ ]
58
+ }, undefined, true, undefined, this);
59
+ }
60
+
61
+ // src/SaveToStudioButton.tsx
62
+ import { useState as useState2 } from "react";
63
+ import { Sparkles } from "lucide-react";
64
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
65
+ "use client";
66
+ function SaveToStudioButton({
67
+ organizationId = "demo-org",
68
+ projectName,
69
+ endpoint,
70
+ token
71
+ }) {
72
+ const { installer, templateId, template } = useTemplateRuntime();
73
+ const [status, setStatus] = useState2("idle");
74
+ const [error, setError] = useState2(null);
75
+ const handleSave = async () => {
76
+ setStatus("saving");
77
+ setError(null);
78
+ try {
79
+ await installer.saveToStudio({
80
+ templateId,
81
+ projectName: projectName ?? `${template.name} demo`,
82
+ organizationId,
83
+ endpoint,
84
+ token
85
+ });
86
+ setStatus("saved");
87
+ setTimeout(() => setStatus("idle"), 3000);
88
+ } catch (err) {
89
+ setStatus("error");
90
+ setError(err instanceof Error ? err.message : "Unknown error");
91
+ }
92
+ };
93
+ return /* @__PURE__ */ jsxDEV2("div", {
94
+ className: "flex flex-col items-end gap-1",
95
+ children: [
96
+ /* @__PURE__ */ jsxDEV2("button", {
97
+ type: "button",
98
+ className: "btn-primary inline-flex items-center gap-2 text-sm",
99
+ onClick: handleSave,
100
+ disabled: status === "saving",
101
+ children: [
102
+ /* @__PURE__ */ jsxDEV2(Sparkles, {
103
+ className: "h-4 w-4"
104
+ }, undefined, false, undefined, this),
105
+ status === "saving" ? "Publishing…" : "Save to Studio"
106
+ ]
107
+ }, undefined, true, undefined, this),
108
+ status === "error" && error ? /* @__PURE__ */ jsxDEV2("p", {
109
+ className: "text-destructive text-xs",
110
+ children: error
111
+ }, undefined, false, undefined, this) : null,
112
+ status === "saved" ? /* @__PURE__ */ jsxDEV2("p", {
113
+ className: "text-xs text-emerald-400",
114
+ children: "Template sent to Studio."
115
+ }, undefined, false, undefined, this) : null
116
+ ]
117
+ }, undefined, true, undefined, this);
118
+ }
119
+
120
+ // src/SpecDrivenTemplateShell.tsx
121
+ import { BundleProvider, BundleRenderer } from "@contractspec/lib.surface-runtime/react";
122
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
123
+ function SpecDrivenTemplateShell({
124
+ plan,
125
+ title,
126
+ description,
127
+ sidebar,
128
+ actions,
129
+ showSaveAction = true,
130
+ saveProps,
131
+ children
132
+ }) {
133
+ const headerContent = /* @__PURE__ */ jsxDEV3("header", {
134
+ className: "border-border bg-card rounded-2xl border p-6 shadow-sm",
135
+ children: [
136
+ /* @__PURE__ */ jsxDEV3("div", {
137
+ className: "flex flex-wrap items-center justify-between gap-4",
138
+ children: [
139
+ /* @__PURE__ */ jsxDEV3("div", {
140
+ children: [
141
+ /* @__PURE__ */ jsxDEV3("p", {
142
+ className: "text-muted-foreground text-sm font-semibold tracking-wide uppercase",
143
+ children: "ContractSpec Templates"
144
+ }, undefined, false, undefined, this),
145
+ /* @__PURE__ */ jsxDEV3("h1", {
146
+ className: "text-3xl font-bold",
147
+ children: title
148
+ }, undefined, false, undefined, this),
149
+ description ? /* @__PURE__ */ jsxDEV3("p", {
150
+ className: "text-muted-foreground mt-2 max-w-2xl text-sm",
151
+ children: description
152
+ }, undefined, false, undefined, this) : null
153
+ ]
154
+ }, undefined, true, undefined, this),
155
+ /* @__PURE__ */ jsxDEV3("div", {
156
+ className: "flex flex-col items-end gap-2",
157
+ children: [
158
+ /* @__PURE__ */ jsxDEV3(LocalDataIndicator, {}, undefined, false, undefined, this),
159
+ showSaveAction ? /* @__PURE__ */ jsxDEV3(SaveToStudioButton, {
160
+ ...saveProps
161
+ }, undefined, false, undefined, this) : null
162
+ ]
163
+ }, undefined, true, undefined, this)
164
+ ]
165
+ }, undefined, true, undefined, this),
166
+ actions ? /* @__PURE__ */ jsxDEV3("div", {
167
+ className: "mt-4",
168
+ children: actions
169
+ }, undefined, false, undefined, this) : null
170
+ ]
171
+ }, undefined, true, undefined, this);
172
+ const slotContent = {
173
+ header: headerContent,
174
+ primary: /* @__PURE__ */ jsxDEV3("main", {
175
+ className: "space-y-4 p-2",
176
+ children
177
+ }, undefined, false, undefined, this)
178
+ };
179
+ if (sidebar != null) {
180
+ slotContent.sidebar = /* @__PURE__ */ jsxDEV3("aside", {
181
+ className: "border-border bg-card rounded-2xl border p-4",
182
+ children: sidebar
183
+ }, undefined, false, undefined, this);
184
+ }
185
+ return /* @__PURE__ */ jsxDEV3(BundleProvider, {
186
+ plan,
187
+ children: /* @__PURE__ */ jsxDEV3(BundleRenderer, {
188
+ slotContent
189
+ }, undefined, false, undefined, this)
190
+ }, undefined, false, undefined, this);
191
+ }
192
+ export {
193
+ SpecDrivenTemplateShell
194
+ };
@@ -0,0 +1,85 @@
1
+ // src/bundles/ExampleTemplateBundle.ts
2
+ import { defineModuleBundle } from "@contractspec/lib.surface-runtime/spec";
3
+ var ExampleTemplateBundle = defineModuleBundle({
4
+ meta: {
5
+ key: "example.template",
6
+ version: "0.1.0",
7
+ title: "Example Template",
8
+ description: "Adaptive template shell for ContractSpec examples",
9
+ owners: ["team-platform"],
10
+ tags: ["example", "template"],
11
+ stability: "experimental"
12
+ },
13
+ routes: [
14
+ {
15
+ routeId: "template",
16
+ path: "/sandbox",
17
+ defaultSurface: "template-shell"
18
+ }
19
+ ],
20
+ surfaces: {
21
+ "template-shell": {
22
+ surfaceId: "template-shell",
23
+ kind: "workbench",
24
+ title: "Template Shell",
25
+ slots: [
26
+ {
27
+ slotId: "header",
28
+ role: "header",
29
+ accepts: ["action-bar"],
30
+ cardinality: "many"
31
+ },
32
+ {
33
+ slotId: "primary",
34
+ role: "primary",
35
+ accepts: ["entity-section", "rich-doc", "form", "custom-widget"],
36
+ cardinality: "many"
37
+ },
38
+ {
39
+ slotId: "sidebar",
40
+ role: "secondary",
41
+ accepts: ["entity-section", "custom-widget"],
42
+ cardinality: "one"
43
+ }
44
+ ],
45
+ layouts: [
46
+ {
47
+ layoutId: "main-with-sidebar",
48
+ title: "Main with sidebar",
49
+ root: {
50
+ type: "panel-group",
51
+ direction: "horizontal",
52
+ persistKey: "example.template.main-sidebar",
53
+ children: [
54
+ {
55
+ type: "panel-group",
56
+ direction: "vertical",
57
+ persistKey: "example.template.content",
58
+ children: [
59
+ { type: "slot", slotId: "header" },
60
+ { type: "slot", slotId: "primary" }
61
+ ]
62
+ },
63
+ { type: "slot", slotId: "sidebar" }
64
+ ]
65
+ }
66
+ }
67
+ ],
68
+ data: [],
69
+ verification: {
70
+ dimensions: {
71
+ guidance: "Can reveal hints and walkthrough notes.",
72
+ density: "Can select compact or balanced layouts.",
73
+ dataDepth: "Controls content depth and expansion.",
74
+ control: "Shows advanced options when allowed.",
75
+ media: "Supports text-first and hybrid modes.",
76
+ pace: "Maps to motion tokens and transitions.",
77
+ narrative: "Can order summary before or after detail."
78
+ }
79
+ }
80
+ }
81
+ }
82
+ });
83
+ export {
84
+ ExampleTemplateBundle
85
+ };
@@ -0,0 +1,85 @@
1
+ // src/bundles/ExampleTemplateBundle.ts
2
+ import { defineModuleBundle } from "@contractspec/lib.surface-runtime/spec";
3
+ var ExampleTemplateBundle = defineModuleBundle({
4
+ meta: {
5
+ key: "example.template",
6
+ version: "0.1.0",
7
+ title: "Example Template",
8
+ description: "Adaptive template shell for ContractSpec examples",
9
+ owners: ["team-platform"],
10
+ tags: ["example", "template"],
11
+ stability: "experimental"
12
+ },
13
+ routes: [
14
+ {
15
+ routeId: "template",
16
+ path: "/sandbox",
17
+ defaultSurface: "template-shell"
18
+ }
19
+ ],
20
+ surfaces: {
21
+ "template-shell": {
22
+ surfaceId: "template-shell",
23
+ kind: "workbench",
24
+ title: "Template Shell",
25
+ slots: [
26
+ {
27
+ slotId: "header",
28
+ role: "header",
29
+ accepts: ["action-bar"],
30
+ cardinality: "many"
31
+ },
32
+ {
33
+ slotId: "primary",
34
+ role: "primary",
35
+ accepts: ["entity-section", "rich-doc", "form", "custom-widget"],
36
+ cardinality: "many"
37
+ },
38
+ {
39
+ slotId: "sidebar",
40
+ role: "secondary",
41
+ accepts: ["entity-section", "custom-widget"],
42
+ cardinality: "one"
43
+ }
44
+ ],
45
+ layouts: [
46
+ {
47
+ layoutId: "main-with-sidebar",
48
+ title: "Main with sidebar",
49
+ root: {
50
+ type: "panel-group",
51
+ direction: "horizontal",
52
+ persistKey: "example.template.main-sidebar",
53
+ children: [
54
+ {
55
+ type: "panel-group",
56
+ direction: "vertical",
57
+ persistKey: "example.template.content",
58
+ children: [
59
+ { type: "slot", slotId: "header" },
60
+ { type: "slot", slotId: "primary" }
61
+ ]
62
+ },
63
+ { type: "slot", slotId: "sidebar" }
64
+ ]
65
+ }
66
+ }
67
+ ],
68
+ data: [],
69
+ verification: {
70
+ dimensions: {
71
+ guidance: "Can reveal hints and walkthrough notes.",
72
+ density: "Can select compact or balanced layouts.",
73
+ dataDepth: "Controls content depth and expansion.",
74
+ control: "Shows advanced options when allowed.",
75
+ media: "Supports text-first and hybrid modes.",
76
+ pace: "Maps to motion tokens and transitions.",
77
+ narrative: "Can order summary before or after detail."
78
+ }
79
+ }
80
+ }
81
+ }
82
+ });
83
+ export {
84
+ ExampleTemplateBundle
85
+ };