@gradial/aci 0.2.0-canary.730 → 0.2.0-canary.737
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/CHANGELOG.md +5 -0
- package/README.md +4 -4
- package/dist/react/index.d.ts +1 -295
- package/dist/react/index.js +0 -7
- package/dist/types/image.d.ts +4 -0
- package/dist/types/image.js +10 -2
- package/package.json +7 -7
- package/src/types/image.test.ts +63 -0
- package/src/types/image.ts +10 -2
- package/templates/astro/starter-content/src/cms/contracts/components/button.contract.ts +8 -8
- package/templates/astro/starter-content/src/cms/contracts/components/homeHero.contract.ts +10 -8
- package/templates/common/.agents/skills/authoring/SKILL.md +47 -10
- package/templates/common/starter-content/.content/patterns/components/button.json +13 -5
- package/templates/common/starter-content/.content/patterns/components/container.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/feature_card.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/feature_grid.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/home_hero.json +14 -8
- package/templates/common/starter-content/.content/patterns/components/personalization_choice.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/site-footer.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/site-navigation.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/stats_bar.json +2 -2
- package/templates/nextjs/starter-content/src/cms/contracts/components/button.contract.ts +8 -8
- package/templates/nextjs/starter-content/src/cms/contracts/components/homeHero.contract.ts +10 -8
package/CHANGELOG.md
CHANGED
|
@@ -188,6 +188,11 @@
|
|
|
188
188
|
|
|
189
189
|
### Changed
|
|
190
190
|
|
|
191
|
+
- Starter hero and button contracts describe component purpose and field meaning
|
|
192
|
+
in the component catalog. Authoring guidance uses those descriptions and
|
|
193
|
+
stable block IDs to identify the requested edit.
|
|
194
|
+
- The Next.js starter hero image is optional, matching Astro and the existing renderer.
|
|
195
|
+
|
|
191
196
|
- Next production builds and error-artifact preparation are content-independent
|
|
192
197
|
without `ACI_CODE_ARTIFACT_BUILD`. Local Next development still validates and
|
|
193
198
|
previews authored error seats; production authored error pages belong to
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agentic Content Infrastructure SDK
|
|
2
2
|
|
|
3
|
-
`@gradial/aci` `0.2.0-canary.
|
|
3
|
+
`@gradial/aci` `0.2.0-canary.737` is a pre-1.0 public-surface reset for the ACI
|
|
4
4
|
client SDK. Breaking changes from the old `0.1.x` accidental surface are
|
|
5
5
|
intentional: the root import is framework-neutral, framework runtime behavior is
|
|
6
6
|
behind explicit subpaths, and the first required customer path is React/Next.
|
|
@@ -8,7 +8,7 @@ behind explicit subpaths, and the first required customer path is React/Next.
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
npm install @gradial/aci@0.2.0-canary.
|
|
11
|
+
npm install @gradial/aci@0.2.0-canary.737 zod@^4
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
## Root Import
|
|
@@ -141,13 +141,13 @@ host bundles select and serve immutable release artifacts.
|
|
|
141
141
|
The first RC scaffold path is Next:
|
|
142
142
|
|
|
143
143
|
```bash
|
|
144
|
-
npx @gradial/aci@0.2.0-canary.
|
|
144
|
+
npx @gradial/aci@0.2.0-canary.737 init my-site --template next-starter
|
|
145
145
|
```
|
|
146
146
|
|
|
147
147
|
List available templates:
|
|
148
148
|
|
|
149
149
|
```bash
|
|
150
|
-
npx @gradial/aci@0.2.0-canary.
|
|
150
|
+
npx @gradial/aci@0.2.0-canary.737 init --list
|
|
151
151
|
```
|
|
152
152
|
|
|
153
153
|
## Personalization: The One-Tag Install
|
package/dist/react/index.d.ts
CHANGED
|
@@ -11,301 +11,7 @@ export interface ImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 's
|
|
|
11
11
|
image?: ImageData;
|
|
12
12
|
value?: ImageData;
|
|
13
13
|
}
|
|
14
|
-
export declare function Image({ image, value, ...attrs }: ImageProps): import("react").DetailedReactHTMLElement<import("../types/image.js").ImageAttrs, HTMLElement
|
|
15
|
-
id?: string | undefined | undefined;
|
|
16
|
-
title?: string | undefined | undefined;
|
|
17
|
-
role?: import("react").AriaRole | undefined;
|
|
18
|
-
prefix?: string | undefined | undefined;
|
|
19
|
-
width?: number | string | undefined | undefined;
|
|
20
|
-
height?: number | string | undefined | undefined;
|
|
21
|
-
sizes?: string | undefined | undefined;
|
|
22
|
-
srcSet?: string | undefined | undefined;
|
|
23
|
-
loading?: "eager" | "lazy" | undefined | undefined;
|
|
24
|
-
decoding?: "async" | "auto" | "sync" | undefined | undefined;
|
|
25
|
-
rel?: string | undefined | undefined;
|
|
26
|
-
content?: string | undefined | undefined;
|
|
27
|
-
referrerPolicy?: import("react").HTMLAttributeReferrerPolicy | undefined;
|
|
28
|
-
slot?: string | undefined | undefined;
|
|
29
|
-
style?: import("react").CSSProperties | undefined;
|
|
30
|
-
dir?: string | undefined | undefined;
|
|
31
|
-
hidden?: boolean | undefined | undefined;
|
|
32
|
-
children?: ReactNode;
|
|
33
|
-
dangerouslySetInnerHTML?: {
|
|
34
|
-
__html: string | TrustedHTML;
|
|
35
|
-
} | undefined | undefined;
|
|
36
|
-
className?: string | undefined | undefined;
|
|
37
|
-
crossOrigin?: "" | "anonymous" | "use-credentials" | undefined;
|
|
38
|
-
fetchPriority?: "high" | "low" | "auto" | undefined | undefined;
|
|
39
|
-
useMap?: string | undefined | undefined;
|
|
40
|
-
defaultChecked?: boolean | undefined | undefined;
|
|
41
|
-
defaultValue?: string | number | readonly string[] | undefined;
|
|
42
|
-
suppressContentEditableWarning?: boolean | undefined | undefined;
|
|
43
|
-
suppressHydrationWarning?: boolean | undefined | undefined;
|
|
44
|
-
accessKey?: string | undefined | undefined;
|
|
45
|
-
autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {}) | undefined;
|
|
46
|
-
autoFocus?: boolean | undefined | undefined;
|
|
47
|
-
contentEditable?: "inherit" | (boolean | "true" | "false") | "plaintext-only" | undefined;
|
|
48
|
-
contextMenu?: string | undefined | undefined;
|
|
49
|
-
draggable?: (boolean | "true" | "false") | undefined;
|
|
50
|
-
enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
|
|
51
|
-
lang?: string | undefined | undefined;
|
|
52
|
-
nonce?: string | undefined | undefined;
|
|
53
|
-
spellCheck?: (boolean | "true" | "false") | undefined;
|
|
54
|
-
tabIndex?: number | undefined | undefined;
|
|
55
|
-
translate?: "yes" | "no" | undefined | undefined;
|
|
56
|
-
radioGroup?: string | undefined | undefined;
|
|
57
|
-
about?: string | undefined | undefined;
|
|
58
|
-
datatype?: string | undefined | undefined;
|
|
59
|
-
inlist?: any;
|
|
60
|
-
property?: string | undefined | undefined;
|
|
61
|
-
resource?: string | undefined | undefined;
|
|
62
|
-
rev?: string | undefined | undefined;
|
|
63
|
-
typeof?: string | undefined | undefined;
|
|
64
|
-
vocab?: string | undefined | undefined;
|
|
65
|
-
autoCorrect?: string | undefined | undefined;
|
|
66
|
-
autoSave?: string | undefined | undefined;
|
|
67
|
-
color?: string | undefined | undefined;
|
|
68
|
-
itemProp?: string | undefined | undefined;
|
|
69
|
-
itemScope?: boolean | undefined | undefined;
|
|
70
|
-
itemType?: string | undefined | undefined;
|
|
71
|
-
itemID?: string | undefined | undefined;
|
|
72
|
-
itemRef?: string | undefined | undefined;
|
|
73
|
-
results?: number | undefined | undefined;
|
|
74
|
-
security?: string | undefined | undefined;
|
|
75
|
-
unselectable?: "on" | "off" | undefined | undefined;
|
|
76
|
-
popover?: "" | "auto" | "manual" | "hint" | undefined | undefined;
|
|
77
|
-
popoverTargetAction?: "toggle" | "show" | "hide" | undefined | undefined;
|
|
78
|
-
popoverTarget?: string | undefined | undefined;
|
|
79
|
-
inert?: boolean | undefined | undefined;
|
|
80
|
-
inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
|
|
81
|
-
is?: string | undefined | undefined;
|
|
82
|
-
exportparts?: string | undefined | undefined;
|
|
83
|
-
part?: string | undefined | undefined;
|
|
84
|
-
tw?: string | undefined;
|
|
85
|
-
"aria-activedescendant"?: string | undefined | undefined;
|
|
86
|
-
"aria-atomic"?: (boolean | "true" | "false") | undefined;
|
|
87
|
-
"aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
|
|
88
|
-
"aria-braillelabel"?: string | undefined | undefined;
|
|
89
|
-
"aria-brailleroledescription"?: string | undefined | undefined;
|
|
90
|
-
"aria-busy"?: (boolean | "true" | "false") | undefined;
|
|
91
|
-
"aria-checked"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
|
|
92
|
-
"aria-colcount"?: number | undefined | undefined;
|
|
93
|
-
"aria-colindex"?: number | undefined | undefined;
|
|
94
|
-
"aria-colindextext"?: string | undefined | undefined;
|
|
95
|
-
"aria-colspan"?: number | undefined | undefined;
|
|
96
|
-
"aria-controls"?: string | undefined | undefined;
|
|
97
|
-
"aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined | undefined;
|
|
98
|
-
"aria-describedby"?: string | undefined | undefined;
|
|
99
|
-
"aria-description"?: string | undefined | undefined;
|
|
100
|
-
"aria-details"?: string | undefined | undefined;
|
|
101
|
-
"aria-disabled"?: (boolean | "true" | "false") | undefined;
|
|
102
|
-
"aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined | undefined;
|
|
103
|
-
"aria-errormessage"?: string | undefined | undefined;
|
|
104
|
-
"aria-expanded"?: (boolean | "true" | "false") | undefined;
|
|
105
|
-
"aria-flowto"?: string | undefined | undefined;
|
|
106
|
-
"aria-grabbed"?: (boolean | "true" | "false") | undefined;
|
|
107
|
-
"aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined | undefined;
|
|
108
|
-
"aria-hidden"?: (boolean | "true" | "false") | undefined;
|
|
109
|
-
"aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined | undefined;
|
|
110
|
-
"aria-keyshortcuts"?: string | undefined | undefined;
|
|
111
|
-
"aria-label"?: string | undefined | undefined;
|
|
112
|
-
"aria-labelledby"?: string | undefined | undefined;
|
|
113
|
-
"aria-level"?: number | undefined | undefined;
|
|
114
|
-
"aria-live"?: "off" | "assertive" | "polite" | undefined | undefined;
|
|
115
|
-
"aria-modal"?: (boolean | "true" | "false") | undefined;
|
|
116
|
-
"aria-multiline"?: (boolean | "true" | "false") | undefined;
|
|
117
|
-
"aria-multiselectable"?: (boolean | "true" | "false") | undefined;
|
|
118
|
-
"aria-orientation"?: "horizontal" | "vertical" | undefined | undefined;
|
|
119
|
-
"aria-owns"?: string | undefined | undefined;
|
|
120
|
-
"aria-placeholder"?: string | undefined | undefined;
|
|
121
|
-
"aria-posinset"?: number | undefined | undefined;
|
|
122
|
-
"aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
|
|
123
|
-
"aria-readonly"?: (boolean | "true" | "false") | undefined;
|
|
124
|
-
"aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined | undefined;
|
|
125
|
-
"aria-required"?: (boolean | "true" | "false") | undefined;
|
|
126
|
-
"aria-roledescription"?: string | undefined | undefined;
|
|
127
|
-
"aria-rowcount"?: number | undefined | undefined;
|
|
128
|
-
"aria-rowindex"?: number | undefined | undefined;
|
|
129
|
-
"aria-rowindextext"?: string | undefined | undefined;
|
|
130
|
-
"aria-rowspan"?: number | undefined | undefined;
|
|
131
|
-
"aria-selected"?: (boolean | "true" | "false") | undefined;
|
|
132
|
-
"aria-setsize"?: number | undefined | undefined;
|
|
133
|
-
"aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined | undefined;
|
|
134
|
-
"aria-valuemax"?: number | undefined | undefined;
|
|
135
|
-
"aria-valuemin"?: number | undefined | undefined;
|
|
136
|
-
"aria-valuenow"?: number | undefined | undefined;
|
|
137
|
-
"aria-valuetext"?: string | undefined | undefined;
|
|
138
|
-
onCopy?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
|
|
139
|
-
onCopyCapture?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
|
|
140
|
-
onCut?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
|
|
141
|
-
onCutCapture?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
|
|
142
|
-
onPaste?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
|
|
143
|
-
onPasteCapture?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
|
|
144
|
-
onCompositionEnd?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
|
|
145
|
-
onCompositionEndCapture?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
|
|
146
|
-
onCompositionStart?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
|
|
147
|
-
onCompositionStartCapture?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
|
|
148
|
-
onCompositionUpdate?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
|
|
149
|
-
onCompositionUpdateCapture?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
|
|
150
|
-
onFocus?: import("react").FocusEventHandler<HTMLImageElement> | undefined;
|
|
151
|
-
onFocusCapture?: import("react").FocusEventHandler<HTMLImageElement> | undefined;
|
|
152
|
-
onBlur?: import("react").FocusEventHandler<HTMLImageElement> | undefined;
|
|
153
|
-
onBlurCapture?: import("react").FocusEventHandler<HTMLImageElement> | undefined;
|
|
154
|
-
onChange?: import("react").ChangeEventHandler<HTMLImageElement, Element> | undefined;
|
|
155
|
-
onChangeCapture?: import("react").ChangeEventHandler<HTMLImageElement, Element> | undefined;
|
|
156
|
-
onBeforeInput?: import("react").InputEventHandler<HTMLImageElement> | undefined;
|
|
157
|
-
onBeforeInputCapture?: import("react").InputEventHandler<HTMLImageElement> | undefined;
|
|
158
|
-
onInput?: import("react").InputEventHandler<HTMLImageElement> | undefined;
|
|
159
|
-
onInputCapture?: import("react").InputEventHandler<HTMLImageElement> | undefined;
|
|
160
|
-
onReset?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
161
|
-
onResetCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
162
|
-
onSubmit?: import("react").SubmitEventHandler<HTMLImageElement> | undefined;
|
|
163
|
-
onSubmitCapture?: import("react").SubmitEventHandler<HTMLImageElement> | undefined;
|
|
164
|
-
onInvalid?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
165
|
-
onInvalidCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
166
|
-
onLoad?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
167
|
-
onLoadCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
168
|
-
onError?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
169
|
-
onErrorCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
170
|
-
onKeyDown?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
|
|
171
|
-
onKeyDownCapture?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
|
|
172
|
-
onKeyPress?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
|
|
173
|
-
onKeyPressCapture?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
|
|
174
|
-
onKeyUp?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
|
|
175
|
-
onKeyUpCapture?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
|
|
176
|
-
onAbort?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
177
|
-
onAbortCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
178
|
-
onCanPlay?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
179
|
-
onCanPlayCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
180
|
-
onCanPlayThrough?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
181
|
-
onCanPlayThroughCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
182
|
-
onDurationChange?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
183
|
-
onDurationChangeCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
184
|
-
onEmptied?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
185
|
-
onEmptiedCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
186
|
-
onEncrypted?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
187
|
-
onEncryptedCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
188
|
-
onEnded?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
189
|
-
onEndedCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
190
|
-
onLoadedData?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
191
|
-
onLoadedDataCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
192
|
-
onLoadedMetadata?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
193
|
-
onLoadedMetadataCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
194
|
-
onLoadStart?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
195
|
-
onLoadStartCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
196
|
-
onPause?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
197
|
-
onPauseCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
198
|
-
onPlay?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
199
|
-
onPlayCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
200
|
-
onPlaying?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
201
|
-
onPlayingCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
202
|
-
onProgress?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
203
|
-
onProgressCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
204
|
-
onRateChange?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
205
|
-
onRateChangeCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
206
|
-
onSeeked?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
207
|
-
onSeekedCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
208
|
-
onSeeking?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
209
|
-
onSeekingCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
210
|
-
onStalled?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
211
|
-
onStalledCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
212
|
-
onSuspend?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
213
|
-
onSuspendCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
214
|
-
onTimeUpdate?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
215
|
-
onTimeUpdateCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
216
|
-
onVolumeChange?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
217
|
-
onVolumeChangeCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
218
|
-
onWaiting?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
219
|
-
onWaitingCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
220
|
-
onAuxClick?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
221
|
-
onAuxClickCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
222
|
-
onClick?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
223
|
-
onClickCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
224
|
-
onContextMenu?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
225
|
-
onContextMenuCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
226
|
-
onDoubleClick?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
227
|
-
onDoubleClickCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
228
|
-
onDrag?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
229
|
-
onDragCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
230
|
-
onDragEnd?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
231
|
-
onDragEndCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
232
|
-
onDragEnter?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
233
|
-
onDragEnterCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
234
|
-
onDragExit?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
235
|
-
onDragExitCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
236
|
-
onDragLeave?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
237
|
-
onDragLeaveCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
238
|
-
onDragOver?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
239
|
-
onDragOverCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
240
|
-
onDragStart?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
241
|
-
onDragStartCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
242
|
-
onDrop?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
243
|
-
onDropCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
|
|
244
|
-
onMouseDown?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
245
|
-
onMouseDownCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
246
|
-
onMouseEnter?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
247
|
-
onMouseLeave?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
248
|
-
onMouseMove?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
249
|
-
onMouseMoveCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
250
|
-
onMouseOut?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
251
|
-
onMouseOutCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
252
|
-
onMouseOver?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
253
|
-
onMouseOverCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
254
|
-
onMouseUp?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
255
|
-
onMouseUpCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
|
|
256
|
-
onSelect?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
257
|
-
onSelectCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
|
|
258
|
-
onTouchCancel?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
|
|
259
|
-
onTouchCancelCapture?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
|
|
260
|
-
onTouchEnd?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
|
|
261
|
-
onTouchEndCapture?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
|
|
262
|
-
onTouchMove?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
|
|
263
|
-
onTouchMoveCapture?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
|
|
264
|
-
onTouchStart?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
|
|
265
|
-
onTouchStartCapture?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
|
|
266
|
-
onPointerDown?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
267
|
-
onPointerDownCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
268
|
-
onPointerMove?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
269
|
-
onPointerMoveCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
270
|
-
onPointerUp?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
271
|
-
onPointerUpCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
272
|
-
onPointerCancel?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
273
|
-
onPointerCancelCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
274
|
-
onPointerEnter?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
275
|
-
onPointerLeave?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
276
|
-
onPointerOver?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
277
|
-
onPointerOverCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
278
|
-
onPointerOut?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
279
|
-
onPointerOutCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
280
|
-
onGotPointerCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
281
|
-
onGotPointerCaptureCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
282
|
-
onLostPointerCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
283
|
-
onLostPointerCaptureCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
|
|
284
|
-
onScroll?: import("react").UIEventHandler<HTMLImageElement> | undefined;
|
|
285
|
-
onScrollCapture?: import("react").UIEventHandler<HTMLImageElement> | undefined;
|
|
286
|
-
onScrollEnd?: import("react").UIEventHandler<HTMLImageElement> | undefined;
|
|
287
|
-
onScrollEndCapture?: import("react").UIEventHandler<HTMLImageElement> | undefined;
|
|
288
|
-
onWheel?: import("react").WheelEventHandler<HTMLImageElement> | undefined;
|
|
289
|
-
onWheelCapture?: import("react").WheelEventHandler<HTMLImageElement> | undefined;
|
|
290
|
-
onAnimationStart?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
|
|
291
|
-
onAnimationStartCapture?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
|
|
292
|
-
onAnimationEnd?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
|
|
293
|
-
onAnimationEndCapture?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
|
|
294
|
-
onAnimationIteration?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
|
|
295
|
-
onAnimationIterationCapture?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
|
|
296
|
-
onToggle?: import("react").ToggleEventHandler<HTMLImageElement> | undefined;
|
|
297
|
-
onBeforeToggle?: import("react").ToggleEventHandler<HTMLImageElement> | undefined;
|
|
298
|
-
onTransitionCancel?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
|
|
299
|
-
onTransitionCancelCapture?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
|
|
300
|
-
onTransitionEnd?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
|
|
301
|
-
onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
|
|
302
|
-
onTransitionRun?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
|
|
303
|
-
onTransitionRunCapture?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
|
|
304
|
-
onTransitionStart?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
|
|
305
|
-
onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
|
|
306
|
-
src: string;
|
|
307
|
-
alt: string;
|
|
308
|
-
}, HTMLElement>;
|
|
14
|
+
export declare function Image({ image, value, ...attrs }: ImageProps): import("react").DetailedReactHTMLElement<import("../types/image.js").ImageAttrs, HTMLElement>;
|
|
309
15
|
export interface LinkProps {
|
|
310
16
|
link: LinkData;
|
|
311
17
|
resolveLink?: (link: LinkData) => string | Promise<string>;
|
package/dist/react/index.js
CHANGED
|
@@ -14,13 +14,6 @@ export function Image({ image, value, ...attrs }) {
|
|
|
14
14
|
alt: '',
|
|
15
15
|
sources: [],
|
|
16
16
|
};
|
|
17
|
-
if (!resolved.sources[0]?.src) {
|
|
18
|
-
return createElement('img', {
|
|
19
|
-
src: '',
|
|
20
|
-
alt: resolved.alt,
|
|
21
|
-
...attrs,
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
17
|
return createElement('img', imageAttrs(resolved, attrs));
|
|
25
18
|
}
|
|
26
19
|
export function Link({ link, resolveLink, children }) {
|
package/dist/types/image.d.ts
CHANGED
|
@@ -74,5 +74,9 @@ export declare function primaryImageSource(image: Image): ImageSource;
|
|
|
74
74
|
* serialization. Media-scoped sources need a <picture> wrapper and are not
|
|
75
75
|
* representable as plain <img> attributes, so srcset/sizes are taken from the
|
|
76
76
|
* first unscoped source only.
|
|
77
|
+
*
|
|
78
|
+
* Runtime payloads with null, missing, or empty sources (malformed releases)
|
|
79
|
+
* render as a broken image that keeps its alt text instead of throwing and
|
|
80
|
+
* aborting SSR for the whole page.
|
|
77
81
|
*/
|
|
78
82
|
export declare function imageAttrs(image: Image, overrides?: ImageAttrs): ImageAttrs;
|
package/dist/types/image.js
CHANGED
|
@@ -32,10 +32,18 @@ export function primaryImageSource(image) {
|
|
|
32
32
|
* serialization. Media-scoped sources need a <picture> wrapper and are not
|
|
33
33
|
* representable as plain <img> attributes, so srcset/sizes are taken from the
|
|
34
34
|
* first unscoped source only.
|
|
35
|
+
*
|
|
36
|
+
* Runtime payloads with null, missing, or empty sources (malformed releases)
|
|
37
|
+
* render as a broken image that keeps its alt text instead of throwing and
|
|
38
|
+
* aborting SSR for the whole page.
|
|
35
39
|
*/
|
|
36
40
|
export function imageAttrs(image, overrides = {}) {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
41
|
+
const sources = Array.isArray(image.sources) ? image.sources : [];
|
|
42
|
+
const primary = sources[0];
|
|
43
|
+
if (!primary?.src) {
|
|
44
|
+
return { src: '', alt: image.alt, ...overrides };
|
|
45
|
+
}
|
|
46
|
+
const unscoped = sources.find((s) => !s.media) ?? primary;
|
|
39
47
|
return {
|
|
40
48
|
src: primary.src,
|
|
41
49
|
alt: image.alt,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradial/aci",
|
|
3
|
-
"version": "0.2.0-canary.
|
|
3
|
+
"version": "0.2.0-canary.737",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/gradial/bare-metal-go.git",
|
|
@@ -179,11 +179,11 @@
|
|
|
179
179
|
"astro": "^6.4.8"
|
|
180
180
|
},
|
|
181
181
|
"optionalDependencies": {
|
|
182
|
-
"@gradial/aci-cli-darwin-arm64": "0.2.0-canary.
|
|
183
|
-
"@gradial/aci-cli-darwin-x64": "0.2.0-canary.
|
|
184
|
-
"@gradial/aci-cli-linux-arm64": "0.2.0-canary.
|
|
185
|
-
"@gradial/aci-cli-linux-x64": "0.2.0-canary.
|
|
186
|
-
"@gradial/aci-cli-win32-arm64": "0.2.0-canary.
|
|
187
|
-
"@gradial/aci-cli-win32-x64": "0.2.0-canary.
|
|
182
|
+
"@gradial/aci-cli-darwin-arm64": "0.2.0-canary.737",
|
|
183
|
+
"@gradial/aci-cli-darwin-x64": "0.2.0-canary.737",
|
|
184
|
+
"@gradial/aci-cli-linux-arm64": "0.2.0-canary.737",
|
|
185
|
+
"@gradial/aci-cli-linux-x64": "0.2.0-canary.737",
|
|
186
|
+
"@gradial/aci-cli-win32-arm64": "0.2.0-canary.737",
|
|
187
|
+
"@gradial/aci-cli-win32-x64": "0.2.0-canary.737"
|
|
188
188
|
}
|
|
189
189
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { createElement } from 'react';
|
|
4
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
5
|
+
|
|
6
|
+
import { Image as ImageComponent, Picture } from '../react/index.js';
|
|
7
|
+
import { imageAttrs, type Image } from './image.js';
|
|
8
|
+
|
|
9
|
+
function image(sources: unknown): Image {
|
|
10
|
+
return {
|
|
11
|
+
$type: 'gradial.image',
|
|
12
|
+
assetId: 'ast_1',
|
|
13
|
+
versionId: 'v1',
|
|
14
|
+
alt: 'Hero',
|
|
15
|
+
sources,
|
|
16
|
+
} as Image;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
test('imageAttrs derives attributes from the primary source', () => {
|
|
20
|
+
const attrs = imageAttrs(
|
|
21
|
+
image([{ src: '/hero.webp', width: 1200, height: 800, type: 'image/webp' }]),
|
|
22
|
+
{ loading: 'eager' },
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
assert.deepEqual(attrs, {
|
|
26
|
+
src: '/hero.webp',
|
|
27
|
+
alt: 'Hero',
|
|
28
|
+
width: 1200,
|
|
29
|
+
height: 800,
|
|
30
|
+
srcSet: undefined,
|
|
31
|
+
sizes: undefined,
|
|
32
|
+
loading: 'eager',
|
|
33
|
+
decoding: 'async',
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
for (const [name, sources] of [
|
|
38
|
+
['null', null],
|
|
39
|
+
['missing', undefined],
|
|
40
|
+
['empty', []],
|
|
41
|
+
['srcless', [{ src: '' }]],
|
|
42
|
+
] as const) {
|
|
43
|
+
test(`imageAttrs falls back to a broken image when sources are ${name}`, () => {
|
|
44
|
+
assert.deepEqual(imageAttrs(image(sources), { className: 'hero' }), {
|
|
45
|
+
src: '',
|
|
46
|
+
alt: 'Hero',
|
|
47
|
+
className: 'hero',
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
test('React image components render alt text instead of aborting SSR on null sources', () => {
|
|
53
|
+
const html = renderToStaticMarkup(
|
|
54
|
+
createElement(
|
|
55
|
+
'main',
|
|
56
|
+
null,
|
|
57
|
+
createElement(Picture, { image: image(null) }),
|
|
58
|
+
createElement(ImageComponent, { image: image(null) }),
|
|
59
|
+
),
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
assert.equal(html, '<main><img alt="Hero"/><img alt="Hero"/></main>');
|
|
63
|
+
});
|
package/src/types/image.ts
CHANGED
|
@@ -104,10 +104,18 @@ export function primaryImageSource(image: Image): ImageSource {
|
|
|
104
104
|
* serialization. Media-scoped sources need a <picture> wrapper and are not
|
|
105
105
|
* representable as plain <img> attributes, so srcset/sizes are taken from the
|
|
106
106
|
* first unscoped source only.
|
|
107
|
+
*
|
|
108
|
+
* Runtime payloads with null, missing, or empty sources (malformed releases)
|
|
109
|
+
* render as a broken image that keeps its alt text instead of throwing and
|
|
110
|
+
* aborting SSR for the whole page.
|
|
107
111
|
*/
|
|
108
112
|
export function imageAttrs(image: Image, overrides: ImageAttrs = {}): ImageAttrs {
|
|
109
|
-
const
|
|
110
|
-
const
|
|
113
|
+
const sources: ImageSource[] = Array.isArray(image.sources) ? image.sources : [];
|
|
114
|
+
const primary = sources[0];
|
|
115
|
+
if (!primary?.src) {
|
|
116
|
+
return { src: '', alt: image.alt, ...overrides };
|
|
117
|
+
}
|
|
118
|
+
const unscoped = sources.find((s) => !s.media) ?? primary;
|
|
111
119
|
|
|
112
120
|
return {
|
|
113
121
|
src: primary.src,
|
|
@@ -2,14 +2,14 @@ import { defineComponentContract } from '@gradial/aci';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
export const schema = z.object({
|
|
5
|
-
label: z.string().min(1),
|
|
6
|
-
href: z.string().min(1),
|
|
7
|
-
variant: z.enum(['primary', 'secondary', 'outline', 'tertiary']).optional(),
|
|
8
|
-
newWindow: z.boolean().optional(),
|
|
9
|
-
icon: z.string().optional(),
|
|
10
|
-
iconPosition: z.enum(['before', 'after']).optional(),
|
|
11
|
-
className: z.string().optional(),
|
|
12
|
-
});
|
|
5
|
+
label: z.string().min(1).describe('Visible button text.'),
|
|
6
|
+
href: z.string().min(1).describe('Destination opened by the button.'),
|
|
7
|
+
variant: z.enum(['primary', 'secondary', 'outline', 'tertiary']).optional().describe('Visual emphasis of the button.'),
|
|
8
|
+
newWindow: z.boolean().optional().describe('Whether the destination opens in a new browser tab.'),
|
|
9
|
+
icon: z.string().optional().describe('Optional icon name displayed with the label.'),
|
|
10
|
+
iconPosition: z.enum(['before', 'after']).optional().describe('Place the icon before or after the visible label.'),
|
|
11
|
+
className: z.string().optional().describe('Additional presentation classes supplied by the site implementation.'),
|
|
12
|
+
}).describe('An inline call-to-action control for navigation or actions.');
|
|
13
13
|
|
|
14
14
|
export type ContentProps = z.infer<typeof schema>;
|
|
15
15
|
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { defineComponentContract, ImageSchema } from '@gradial/aci';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
|
-
export const schema = z
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
export const schema = z
|
|
5
|
+
.object({
|
|
6
|
+
eyebrow: z.string().optional().describe('Short context shown above the main headline.'),
|
|
7
|
+
headline: z.string().min(1).describe('The large headline for this hero.'),
|
|
8
|
+
description: z.string().optional().describe('Supporting copy below the hero headline.'),
|
|
9
|
+
ctaLabel: z.string().min(1).describe('Visible label for the hero call to action.'),
|
|
10
|
+
ctaHref: z.string().min(1).describe('Destination for the hero call to action.'),
|
|
11
|
+
image: ImageSchema.optional().describe('Primary visual displayed in the hero.'),
|
|
12
|
+
})
|
|
13
|
+
.describe('A large page-leading hero with a headline, supporting copy, call to action, and image.');
|
|
12
14
|
|
|
13
15
|
export type ContentProps = z.infer<typeof schema>;
|
|
14
16
|
|
|
@@ -314,6 +314,35 @@ template and republish.
|
|
|
314
314
|
- `props` must validate against the contract's Zod schema.
|
|
315
315
|
- `id` is unique within the page.
|
|
316
316
|
|
|
317
|
+
### Resolve the Target Before Editing
|
|
318
|
+
|
|
319
|
+
When a request uses a visual term such as "hero", "banner", or "top card",
|
|
320
|
+
do not select a component from its name alone. Read the page document first
|
|
321
|
+
and identify the block using all available evidence:
|
|
322
|
+
|
|
323
|
+
1. its order in the requested region (for example, the first block in `main`),
|
|
324
|
+
2. its current visible copy or asset,
|
|
325
|
+
3. its component description in the current site's schema, and
|
|
326
|
+
4. its stable block `id`.
|
|
327
|
+
|
|
328
|
+
Use the schema for the site you are editing. For local authoring, run
|
|
329
|
+
`aci schemas compile` after changing contracts and read
|
|
330
|
+
`.aci/schemas/<component-id>.schema.json`. For a remote branch, read
|
|
331
|
+
`/patterns/components/<component-id>.json` from that branch; its `schema`
|
|
332
|
+
comes from the linked code build. Seeded `.content/patterns` files are starter
|
|
333
|
+
examples and can differ from the local framework's contracts.
|
|
334
|
+
|
|
335
|
+
After selecting the block, read `properties.<field>.description` in that
|
|
336
|
+
schema to identify which property controls the requested content. Follow
|
|
337
|
+
`properties` and `items` for nested fields. Use the same current schema for
|
|
338
|
+
types, required fields, and allowed enum values; descriptions explain what
|
|
339
|
+
those fields mean.
|
|
340
|
+
|
|
341
|
+
If two blocks still match, ask which current copy the user means before
|
|
342
|
+
writing. After the write, verify the selected block's props and its rendered
|
|
343
|
+
region. A successful page render alone does not prove that the requested block
|
|
344
|
+
changed.
|
|
345
|
+
|
|
317
346
|
### Nested Blocks
|
|
318
347
|
|
|
319
348
|
Components that accept child blocks use `blockRef()` in their Zod schema
|
|
@@ -402,7 +431,7 @@ The `button` component is a common atomic block:
|
|
|
402
431
|
```
|
|
403
432
|
|
|
404
433
|
- `label` and `href` are required.
|
|
405
|
-
-
|
|
434
|
+
- Read the current site's schema for the supported optional properties and values.
|
|
406
435
|
- `icon`: a registered icon name.
|
|
407
436
|
- `iconPosition`: `before` | `after`
|
|
408
437
|
- `newWindow`: boolean for `target="_blank"`.
|
|
@@ -574,16 +603,16 @@ import { defineComponentContract, ImageSchema } from '@gradial/aci';
|
|
|
574
603
|
import { z } from 'zod';
|
|
575
604
|
|
|
576
605
|
export const schema = z.object({
|
|
577
|
-
headline: z.string().min(1),
|
|
578
|
-
description: z.string().optional(),
|
|
579
|
-
image: ImageSchema,
|
|
606
|
+
headline: z.string().min(1).describe('The prominent heading shown in this section.'),
|
|
607
|
+
description: z.string().optional().describe('Supporting copy below the heading.'),
|
|
608
|
+
image: ImageSchema.describe('Primary visual for the feature section.'),
|
|
580
609
|
features: z.array(z.object({
|
|
581
|
-
title: z.string().min(1),
|
|
582
|
-
description: z.string().min(1),
|
|
583
|
-
})).optional(),
|
|
584
|
-
ctaLabel: z.string().optional(),
|
|
585
|
-
ctaHref: z.string().optional(),
|
|
586
|
-
});
|
|
610
|
+
title: z.string().min(1).describe('Visible feature heading.'),
|
|
611
|
+
description: z.string().min(1).describe('Supporting copy for this feature.'),
|
|
612
|
+
})).optional().describe('Features in display order.'),
|
|
613
|
+
ctaLabel: z.string().optional().describe('Visible call-to-action text.'),
|
|
614
|
+
ctaHref: z.string().optional().describe('Call-to-action destination.'),
|
|
615
|
+
}).describe('A visual feature section with a heading, image, and optional call to action.');
|
|
587
616
|
|
|
588
617
|
export type ContentProps = z.infer<typeof schema>;
|
|
589
618
|
|
|
@@ -602,6 +631,14 @@ export const featureShowcaseContract = defineComponentContract({
|
|
|
602
631
|
});
|
|
603
632
|
```
|
|
604
633
|
|
|
634
|
+
Use `.describe()` on the root schema and authorable properties. Describe what
|
|
635
|
+
the component is for, not where one current page happens to place it. For enum
|
|
636
|
+
properties, explain the choices in the field's `.describe()` text just as
|
|
637
|
+
you describe a string or boolean field. Apply `.describe()` after wrappers
|
|
638
|
+
such as `.optional()`. The compiler preserves this text as the JSON Schema
|
|
639
|
+
`description` on that same node; there is no separate variant metadata
|
|
640
|
+
contract.
|
|
641
|
+
|
|
605
642
|
#### 2. Export from the barrel
|
|
606
643
|
|
|
607
644
|
```ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
|
|
4
|
+
"codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
|
|
5
5
|
"name": "button",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -10,13 +10,16 @@
|
|
|
10
10
|
"properties": {
|
|
11
11
|
"label": {
|
|
12
12
|
"type": "string",
|
|
13
|
-
"minLength": 1
|
|
13
|
+
"minLength": 1,
|
|
14
|
+
"description": "Visible button text."
|
|
14
15
|
},
|
|
15
16
|
"href": {
|
|
16
17
|
"type": "string",
|
|
17
|
-
"minLength": 1
|
|
18
|
+
"minLength": 1,
|
|
19
|
+
"description": "Destination opened by the button."
|
|
18
20
|
},
|
|
19
21
|
"variant": {
|
|
22
|
+
"description": "Visual emphasis of the button.",
|
|
20
23
|
"type": "string",
|
|
21
24
|
"enum": [
|
|
22
25
|
"primary",
|
|
@@ -27,12 +30,15 @@
|
|
|
27
30
|
]
|
|
28
31
|
},
|
|
29
32
|
"newWindow": {
|
|
33
|
+
"description": "Whether the destination opens in a new browser tab.",
|
|
30
34
|
"type": "boolean"
|
|
31
35
|
},
|
|
32
36
|
"icon": {
|
|
37
|
+
"description": "Optional icon name displayed with the label.",
|
|
33
38
|
"type": "string"
|
|
34
39
|
},
|
|
35
40
|
"iconPosition": {
|
|
41
|
+
"description": "Place the icon before or after the visible label.",
|
|
36
42
|
"type": "string",
|
|
37
43
|
"enum": [
|
|
38
44
|
"before",
|
|
@@ -40,6 +46,7 @@
|
|
|
40
46
|
]
|
|
41
47
|
},
|
|
42
48
|
"className": {
|
|
49
|
+
"description": "Additional presentation classes supplied by the site implementation.",
|
|
43
50
|
"type": "string"
|
|
44
51
|
}
|
|
45
52
|
},
|
|
@@ -47,7 +54,8 @@
|
|
|
47
54
|
"label",
|
|
48
55
|
"href"
|
|
49
56
|
],
|
|
50
|
-
"additionalProperties": false
|
|
57
|
+
"additionalProperties": false,
|
|
58
|
+
"description": "An inline call-to-action control for navigation or actions."
|
|
51
59
|
},
|
|
52
60
|
"imageSlots": {},
|
|
53
61
|
"notes": "",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
|
|
4
|
+
"codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
|
|
5
5
|
"name": "container",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
|
|
4
|
+
"codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
|
|
5
5
|
"name": "feature_card",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
|
|
4
|
+
"codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
|
|
5
5
|
"name": "feature_grid",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
|
|
4
|
+
"codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
|
|
5
5
|
"name": "home_hero",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -9,24 +9,30 @@
|
|
|
9
9
|
"type": "object",
|
|
10
10
|
"properties": {
|
|
11
11
|
"eyebrow": {
|
|
12
|
+
"description": "Short context shown above the main headline.",
|
|
12
13
|
"type": "string"
|
|
13
14
|
},
|
|
14
15
|
"headline": {
|
|
15
16
|
"type": "string",
|
|
16
|
-
"minLength": 1
|
|
17
|
+
"minLength": 1,
|
|
18
|
+
"description": "The large headline for this hero."
|
|
17
19
|
},
|
|
18
20
|
"description": {
|
|
21
|
+
"description": "Supporting copy below the hero headline.",
|
|
19
22
|
"type": "string"
|
|
20
23
|
},
|
|
21
24
|
"ctaLabel": {
|
|
22
25
|
"type": "string",
|
|
23
|
-
"minLength": 1
|
|
26
|
+
"minLength": 1,
|
|
27
|
+
"description": "Visible label for the hero call to action."
|
|
24
28
|
},
|
|
25
29
|
"ctaHref": {
|
|
26
30
|
"type": "string",
|
|
27
|
-
"minLength": 1
|
|
31
|
+
"minLength": 1,
|
|
32
|
+
"description": "Destination for the hero call to action."
|
|
28
33
|
},
|
|
29
34
|
"image": {
|
|
35
|
+
"description": "Primary visual displayed in the hero.",
|
|
30
36
|
"type": "object",
|
|
31
37
|
"properties": {
|
|
32
38
|
"$type": {
|
|
@@ -102,10 +108,10 @@
|
|
|
102
108
|
"required": [
|
|
103
109
|
"headline",
|
|
104
110
|
"ctaLabel",
|
|
105
|
-
"ctaHref"
|
|
106
|
-
"image"
|
|
111
|
+
"ctaHref"
|
|
107
112
|
],
|
|
108
|
-
"additionalProperties": false
|
|
113
|
+
"additionalProperties": false,
|
|
114
|
+
"description": "A large page-leading hero with a headline, supporting copy, call to action, and image."
|
|
109
115
|
},
|
|
110
116
|
"imageSlots": {
|
|
111
117
|
"image": {
|
package/templates/common/starter-content/.content/patterns/components/personalization_choice.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
|
|
4
|
+
"codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
|
|
5
5
|
"name": "personalization_choice",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
|
|
4
|
+
"codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
|
|
5
5
|
"name": "site-footer",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
|
|
4
|
+
"codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
|
|
5
5
|
"name": "site-navigation",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
|
|
4
|
+
"codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
|
|
5
5
|
"name": "stats_bar",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -2,14 +2,14 @@ import { defineComponentContract } from '@gradial/aci';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
export const schema = z.object({
|
|
5
|
-
label: z.string().min(1),
|
|
6
|
-
href: z.string().min(1),
|
|
7
|
-
variant: z.enum(['primary', 'secondary', 'tertiary', 'outline', 'ghost']).optional(),
|
|
8
|
-
newWindow: z.boolean().optional(),
|
|
9
|
-
icon: z.string().optional(),
|
|
10
|
-
iconPosition: z.enum(['before', 'after']).optional(),
|
|
11
|
-
className: z.string().optional(),
|
|
12
|
-
});
|
|
5
|
+
label: z.string().min(1).describe('Visible button text.'),
|
|
6
|
+
href: z.string().min(1).describe('Destination opened by the button.'),
|
|
7
|
+
variant: z.enum(['primary', 'secondary', 'tertiary', 'outline', 'ghost']).optional().describe('Visual emphasis of the button.'),
|
|
8
|
+
newWindow: z.boolean().optional().describe('Whether the destination opens in a new browser tab.'),
|
|
9
|
+
icon: z.string().optional().describe('Optional icon name displayed with the label.'),
|
|
10
|
+
iconPosition: z.enum(['before', 'after']).optional().describe('Place the icon before or after the visible label.'),
|
|
11
|
+
className: z.string().optional().describe('Additional presentation classes supplied by the site implementation.'),
|
|
12
|
+
}).describe('An inline call-to-action control for navigation or actions.');
|
|
13
13
|
|
|
14
14
|
export type ContentProps = z.infer<typeof schema>;
|
|
15
15
|
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { defineComponentContract, ImageSchema } from '@gradial/aci';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
|
-
export const schema = z
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
export const schema = z
|
|
5
|
+
.object({
|
|
6
|
+
eyebrow: z.string().optional().describe('Short context shown above the main headline.'),
|
|
7
|
+
headline: z.string().min(1).describe('The large headline for this hero.'),
|
|
8
|
+
description: z.string().optional().describe('Supporting copy below the hero headline.'),
|
|
9
|
+
ctaLabel: z.string().min(1).describe('Visible label for the hero call to action.'),
|
|
10
|
+
ctaHref: z.string().min(1).describe('Destination for the hero call to action.'),
|
|
11
|
+
image: ImageSchema.optional().describe('Primary visual displayed in the hero.'),
|
|
12
|
+
})
|
|
13
|
+
.describe('A large page-leading hero with a headline, supporting copy, call to action, and image.');
|
|
12
14
|
|
|
13
15
|
export type ContentProps = z.infer<typeof schema>;
|
|
14
16
|
|