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

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,82 @@ function SaveToStudioButton({
2129
2129
  }, undefined, true, undefined, this);
2130
2130
  }
2131
2131
 
2132
+ // src/SpecDrivenTemplateShell.tsx
2133
+ import {
2134
+ BundleProvider,
2135
+ BundleRenderer
2136
+ } from "@contractspec/lib.surface-runtime/react";
2137
+ import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
2138
+ function SpecDrivenTemplateShell({
2139
+ plan,
2140
+ title,
2141
+ description,
2142
+ sidebar,
2143
+ actions,
2144
+ showSaveAction = true,
2145
+ saveProps,
2146
+ children
2147
+ }) {
2148
+ const headerContent = /* @__PURE__ */ jsxDEV8("header", {
2149
+ className: "border-border bg-card rounded-2xl border p-6 shadow-sm",
2150
+ children: [
2151
+ /* @__PURE__ */ jsxDEV8("div", {
2152
+ className: "flex flex-wrap items-center justify-between gap-4",
2153
+ children: [
2154
+ /* @__PURE__ */ jsxDEV8("div", {
2155
+ children: [
2156
+ /* @__PURE__ */ jsxDEV8("p", {
2157
+ className: "text-muted-foreground text-sm font-semibold tracking-wide uppercase",
2158
+ children: "ContractSpec Templates"
2159
+ }, undefined, false, undefined, this),
2160
+ /* @__PURE__ */ jsxDEV8("h1", {
2161
+ className: "text-3xl font-bold",
2162
+ children: title
2163
+ }, undefined, false, undefined, this),
2164
+ description ? /* @__PURE__ */ jsxDEV8("p", {
2165
+ className: "text-muted-foreground mt-2 max-w-2xl text-sm",
2166
+ children: description
2167
+ }, undefined, false, undefined, this) : null
2168
+ ]
2169
+ }, undefined, true, undefined, this),
2170
+ /* @__PURE__ */ jsxDEV8("div", {
2171
+ className: "flex flex-col items-end gap-2",
2172
+ children: [
2173
+ /* @__PURE__ */ jsxDEV8(LocalDataIndicator, {}, undefined, false, undefined, this),
2174
+ showSaveAction ? /* @__PURE__ */ jsxDEV8(SaveToStudioButton, {
2175
+ ...saveProps
2176
+ }, undefined, false, undefined, this) : null
2177
+ ]
2178
+ }, undefined, true, undefined, this)
2179
+ ]
2180
+ }, undefined, true, undefined, this),
2181
+ actions ? /* @__PURE__ */ jsxDEV8("div", {
2182
+ className: "mt-4",
2183
+ children: actions
2184
+ }, undefined, false, undefined, this) : null
2185
+ ]
2186
+ }, undefined, true, undefined, this);
2187
+ const slotContent = {
2188
+ header: headerContent,
2189
+ primary: /* @__PURE__ */ jsxDEV8("main", {
2190
+ className: "space-y-4 p-2",
2191
+ children
2192
+ }, undefined, false, undefined, this)
2193
+ };
2194
+ if (sidebar != null) {
2195
+ slotContent.sidebar = /* @__PURE__ */ jsxDEV8("aside", {
2196
+ className: "border-border bg-card rounded-2xl border p-4",
2197
+ children: sidebar
2198
+ }, undefined, false, undefined, this);
2199
+ }
2200
+ return /* @__PURE__ */ jsxDEV8(BundleProvider, {
2201
+ plan,
2202
+ children: /* @__PURE__ */ jsxDEV8(BundleRenderer, {
2203
+ slotContent
2204
+ }, undefined, false, undefined, this)
2205
+ }, undefined, false, undefined, this);
2206
+ }
2207
+
2132
2208
  // src/utils/generateSpecFromTemplate.ts
2133
2209
  function generateSpecFromTemplate(template) {
2134
2210
  const templateId = template?.id ?? "unknown";
@@ -2698,7 +2774,7 @@ function useSpecContent(templateId) {
2698
2774
  import { useCallback as useCallback8, useEffect as useEffect5 } from "react";
2699
2775
  import { Button as Button5, LoaderBlock as LoaderBlock3 } from "@contractspec/lib.design-system";
2700
2776
  import { Badge as Badge5 } from "@contractspec/lib.ui-kit-web/ui/badge";
2701
- import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
2777
+ import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
2702
2778
  "use client";
2703
2779
  function SpecEditorPanel({
2704
2780
  templateId,
@@ -2740,54 +2816,54 @@ function SpecEditorPanel({
2740
2816
  onLog?.("Spec reset to template defaults");
2741
2817
  }, [reset, onLog]);
2742
2818
  if (loading) {
2743
- return /* @__PURE__ */ jsxDEV8(LoaderBlock3, {
2819
+ return /* @__PURE__ */ jsxDEV9(LoaderBlock3, {
2744
2820
  label: "Loading spec..."
2745
2821
  }, undefined, false, undefined, this);
2746
2822
  }
2747
- return /* @__PURE__ */ jsxDEV8("div", {
2823
+ return /* @__PURE__ */ jsxDEV9("div", {
2748
2824
  className: "space-y-4",
2749
2825
  children: [
2750
- /* @__PURE__ */ jsxDEV8("div", {
2826
+ /* @__PURE__ */ jsxDEV9("div", {
2751
2827
  className: "flex items-center justify-between",
2752
2828
  children: [
2753
- /* @__PURE__ */ jsxDEV8("div", {
2829
+ /* @__PURE__ */ jsxDEV9("div", {
2754
2830
  className: "flex items-center gap-2",
2755
2831
  children: [
2756
- /* @__PURE__ */ jsxDEV8(Button5, {
2832
+ /* @__PURE__ */ jsxDEV9(Button5, {
2757
2833
  variant: "default",
2758
2834
  size: "sm",
2759
2835
  onClick: handleSave,
2760
2836
  children: "Save"
2761
2837
  }, undefined, false, undefined, this),
2762
- /* @__PURE__ */ jsxDEV8(Button5, {
2838
+ /* @__PURE__ */ jsxDEV9(Button5, {
2763
2839
  variant: "outline",
2764
2840
  size: "sm",
2765
2841
  onClick: handleValidate,
2766
2842
  children: "Validate"
2767
2843
  }, undefined, false, undefined, this),
2768
- isDirty && /* @__PURE__ */ jsxDEV8(Badge5, {
2844
+ isDirty && /* @__PURE__ */ jsxDEV9(Badge5, {
2769
2845
  variant: "secondary",
2770
2846
  className: "border-amber-500/30 bg-amber-500/20 text-amber-400",
2771
2847
  children: "Unsaved changes"
2772
2848
  }, undefined, false, undefined, this),
2773
- validation && /* @__PURE__ */ jsxDEV8(Badge5, {
2849
+ validation && /* @__PURE__ */ jsxDEV9(Badge5, {
2774
2850
  variant: validation.valid ? "default" : "destructive",
2775
2851
  className: validation.valid ? "border-green-500/30 bg-green-500/20 text-green-400" : "",
2776
2852
  children: validation.valid ? "Valid" : `${validation.errors.filter((e) => e.severity === "error").length} errors`
2777
2853
  }, undefined, false, undefined, this)
2778
2854
  ]
2779
2855
  }, undefined, true, undefined, this),
2780
- /* @__PURE__ */ jsxDEV8("div", {
2856
+ /* @__PURE__ */ jsxDEV9("div", {
2781
2857
  className: "flex items-center gap-2",
2782
2858
  children: [
2783
- lastSaved && /* @__PURE__ */ jsxDEV8("span", {
2859
+ lastSaved && /* @__PURE__ */ jsxDEV9("span", {
2784
2860
  className: "text-muted-foreground text-xs",
2785
2861
  children: [
2786
2862
  "Last saved: ",
2787
2863
  new Date(lastSaved).toLocaleTimeString()
2788
2864
  ]
2789
2865
  }, undefined, true, undefined, this),
2790
- /* @__PURE__ */ jsxDEV8(Button5, {
2866
+ /* @__PURE__ */ jsxDEV9(Button5, {
2791
2867
  variant: "ghost",
2792
2868
  size: "sm",
2793
2869
  onPress: handleReset,
@@ -2797,16 +2873,16 @@ function SpecEditorPanel({
2797
2873
  }, undefined, true, undefined, this)
2798
2874
  ]
2799
2875
  }, undefined, true, undefined, this),
2800
- validation && validation.errors.length > 0 && /* @__PURE__ */ jsxDEV8("div", {
2876
+ validation && validation.errors.length > 0 && /* @__PURE__ */ jsxDEV9("div", {
2801
2877
  className: "rounded-lg border border-amber-500/50 bg-amber-500/10 p-3",
2802
2878
  children: [
2803
- /* @__PURE__ */ jsxDEV8("p", {
2879
+ /* @__PURE__ */ jsxDEV9("p", {
2804
2880
  className: "mb-2 text-xs font-semibold text-amber-400 uppercase",
2805
2881
  children: "Validation Issues"
2806
2882
  }, undefined, false, undefined, this),
2807
- /* @__PURE__ */ jsxDEV8("ul", {
2883
+ /* @__PURE__ */ jsxDEV9("ul", {
2808
2884
  className: "space-y-1",
2809
- children: validation.errors.map((error, index) => /* @__PURE__ */ jsxDEV8("li", {
2885
+ children: validation.errors.map((error, index) => /* @__PURE__ */ jsxDEV9("li", {
2810
2886
  className: `text-xs ${error.severity === "error" ? "text-red-400" : "text-amber-400"}`,
2811
2887
  children: [
2812
2888
  "Line ",
@@ -2818,9 +2894,9 @@ function SpecEditorPanel({
2818
2894
  }, undefined, false, undefined, this)
2819
2895
  ]
2820
2896
  }, undefined, true, undefined, this),
2821
- /* @__PURE__ */ jsxDEV8("div", {
2897
+ /* @__PURE__ */ jsxDEV9("div", {
2822
2898
  className: "border-border bg-card rounded-2xl border p-4",
2823
- children: /* @__PURE__ */ jsxDEV8(SpecEditor, {
2899
+ children: /* @__PURE__ */ jsxDEV9(SpecEditor, {
2824
2900
  projectId: "sandbox",
2825
2901
  type: "CAPABILITY",
2826
2902
  content,
@@ -2835,7 +2911,7 @@ function SpecEditorPanel({
2835
2911
  }
2836
2912
 
2837
2913
  // src/TemplateShell.tsx
2838
- import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
2914
+ import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
2839
2915
  var TemplateShell = ({
2840
2916
  title,
2841
2917
  description,
@@ -2844,56 +2920,56 @@ var TemplateShell = ({
2844
2920
  showSaveAction = true,
2845
2921
  saveProps,
2846
2922
  children
2847
- }) => /* @__PURE__ */ jsxDEV9("div", {
2923
+ }) => /* @__PURE__ */ jsxDEV10("div", {
2848
2924
  className: "space-y-6",
2849
2925
  children: [
2850
- /* @__PURE__ */ jsxDEV9("header", {
2926
+ /* @__PURE__ */ jsxDEV10("header", {
2851
2927
  className: "border-border bg-card rounded-2xl border p-6 shadow-sm",
2852
2928
  children: [
2853
- /* @__PURE__ */ jsxDEV9("div", {
2929
+ /* @__PURE__ */ jsxDEV10("div", {
2854
2930
  className: "flex flex-wrap items-center justify-between gap-4",
2855
2931
  children: [
2856
- /* @__PURE__ */ jsxDEV9("div", {
2932
+ /* @__PURE__ */ jsxDEV10("div", {
2857
2933
  children: [
2858
- /* @__PURE__ */ jsxDEV9("p", {
2934
+ /* @__PURE__ */ jsxDEV10("p", {
2859
2935
  className: "text-muted-foreground text-sm font-semibold tracking-wide uppercase",
2860
2936
  children: "ContractSpec Templates"
2861
2937
  }, undefined, false, undefined, this),
2862
- /* @__PURE__ */ jsxDEV9("h1", {
2938
+ /* @__PURE__ */ jsxDEV10("h1", {
2863
2939
  className: "text-3xl font-bold",
2864
2940
  children: title
2865
2941
  }, undefined, false, undefined, this),
2866
- description ? /* @__PURE__ */ jsxDEV9("p", {
2942
+ description ? /* @__PURE__ */ jsxDEV10("p", {
2867
2943
  className: "text-muted-foreground mt-2 max-w-2xl text-sm",
2868
2944
  children: description
2869
2945
  }, undefined, false, undefined, this) : null
2870
2946
  ]
2871
2947
  }, undefined, true, undefined, this),
2872
- /* @__PURE__ */ jsxDEV9("div", {
2948
+ /* @__PURE__ */ jsxDEV10("div", {
2873
2949
  className: "flex flex-col items-end gap-2",
2874
2950
  children: [
2875
- /* @__PURE__ */ jsxDEV9(LocalDataIndicator, {}, undefined, false, undefined, this),
2876
- showSaveAction ? /* @__PURE__ */ jsxDEV9(SaveToStudioButton, {
2951
+ /* @__PURE__ */ jsxDEV10(LocalDataIndicator, {}, undefined, false, undefined, this),
2952
+ showSaveAction ? /* @__PURE__ */ jsxDEV10(SaveToStudioButton, {
2877
2953
  ...saveProps
2878
2954
  }, undefined, false, undefined, this) : null
2879
2955
  ]
2880
2956
  }, undefined, true, undefined, this)
2881
2957
  ]
2882
2958
  }, undefined, true, undefined, this),
2883
- actions ? /* @__PURE__ */ jsxDEV9("div", {
2959
+ actions ? /* @__PURE__ */ jsxDEV10("div", {
2884
2960
  className: "mt-4",
2885
2961
  children: actions
2886
2962
  }, undefined, false, undefined, this) : null
2887
2963
  ]
2888
2964
  }, undefined, true, undefined, this),
2889
- /* @__PURE__ */ jsxDEV9("div", {
2965
+ /* @__PURE__ */ jsxDEV10("div", {
2890
2966
  className: sidebar ? "grid gap-6 lg:grid-cols-[minmax(0,1fr)_320px]" : "w-full",
2891
2967
  children: [
2892
- /* @__PURE__ */ jsxDEV9("main", {
2968
+ /* @__PURE__ */ jsxDEV10("main", {
2893
2969
  className: "space-y-4 p-2",
2894
2970
  children
2895
2971
  }, undefined, false, undefined, this),
2896
- sidebar ? /* @__PURE__ */ jsxDEV9("aside", {
2972
+ sidebar ? /* @__PURE__ */ jsxDEV10("aside", {
2897
2973
  className: "border-border bg-card rounded-2xl border p-4",
2898
2974
  children: sidebar
2899
2975
  }, undefined, false, undefined, this) : null
@@ -3487,6 +3563,7 @@ export {
3487
3563
  TemplateRuntimeContext,
3488
3564
  TemplateComponentRegistry,
3489
3565
  SpecEditorPanel,
3566
+ SpecDrivenTemplateShell,
3490
3567
  SaveToStudioButton,
3491
3568
  PersonalizationInsights,
3492
3569
  OverlayContextProvider,
@@ -0,0 +1,197 @@
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 {
122
+ BundleProvider,
123
+ BundleRenderer
124
+ } from "@contractspec/lib.surface-runtime/react";
125
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
126
+ function SpecDrivenTemplateShell({
127
+ plan,
128
+ title,
129
+ description,
130
+ sidebar,
131
+ actions,
132
+ showSaveAction = true,
133
+ saveProps,
134
+ children
135
+ }) {
136
+ const headerContent = /* @__PURE__ */ jsxDEV3("header", {
137
+ className: "border-border bg-card rounded-2xl border p-6 shadow-sm",
138
+ children: [
139
+ /* @__PURE__ */ jsxDEV3("div", {
140
+ className: "flex flex-wrap items-center justify-between gap-4",
141
+ children: [
142
+ /* @__PURE__ */ jsxDEV3("div", {
143
+ children: [
144
+ /* @__PURE__ */ jsxDEV3("p", {
145
+ className: "text-muted-foreground text-sm font-semibold tracking-wide uppercase",
146
+ children: "ContractSpec Templates"
147
+ }, undefined, false, undefined, this),
148
+ /* @__PURE__ */ jsxDEV3("h1", {
149
+ className: "text-3xl font-bold",
150
+ children: title
151
+ }, undefined, false, undefined, this),
152
+ description ? /* @__PURE__ */ jsxDEV3("p", {
153
+ className: "text-muted-foreground mt-2 max-w-2xl text-sm",
154
+ children: description
155
+ }, undefined, false, undefined, this) : null
156
+ ]
157
+ }, undefined, true, undefined, this),
158
+ /* @__PURE__ */ jsxDEV3("div", {
159
+ className: "flex flex-col items-end gap-2",
160
+ children: [
161
+ /* @__PURE__ */ jsxDEV3(LocalDataIndicator, {}, undefined, false, undefined, this),
162
+ showSaveAction ? /* @__PURE__ */ jsxDEV3(SaveToStudioButton, {
163
+ ...saveProps
164
+ }, undefined, false, undefined, this) : null
165
+ ]
166
+ }, undefined, true, undefined, this)
167
+ ]
168
+ }, undefined, true, undefined, this),
169
+ actions ? /* @__PURE__ */ jsxDEV3("div", {
170
+ className: "mt-4",
171
+ children: actions
172
+ }, undefined, false, undefined, this) : null
173
+ ]
174
+ }, undefined, true, undefined, this);
175
+ const slotContent = {
176
+ header: headerContent,
177
+ primary: /* @__PURE__ */ jsxDEV3("main", {
178
+ className: "space-y-4 p-2",
179
+ children
180
+ }, undefined, false, undefined, this)
181
+ };
182
+ if (sidebar != null) {
183
+ slotContent.sidebar = /* @__PURE__ */ jsxDEV3("aside", {
184
+ className: "border-border bg-card rounded-2xl border p-4",
185
+ children: sidebar
186
+ }, undefined, false, undefined, this);
187
+ }
188
+ return /* @__PURE__ */ jsxDEV3(BundleProvider, {
189
+ plan,
190
+ children: /* @__PURE__ */ jsxDEV3(BundleRenderer, {
191
+ slotContent
192
+ }, undefined, false, undefined, this)
193
+ }, undefined, false, undefined, this);
194
+ }
195
+ export {
196
+ SpecDrivenTemplateShell
197
+ };
@@ -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
+ };