@colixsystems/widget-sdk 0.96.0 → 0.97.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/README.md +5 -0
- package/dist/contract.cjs +110 -1
- package/dist/contract.js +110 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,6 +66,11 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
|
|
|
66
66
|
|
|
67
67
|
`v0.91.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
|
|
68
68
|
|
|
69
|
+
### What's new in 0.97.0 (contract 1.69.0)
|
|
70
|
+
|
|
71
|
+
**`CONTRACT.themeComponents` gains five scopes: `accent`, `destructive`, `muted`, `popover`, `ring` (sc-5392).** The vocabulary shipped with exactly `button`/`card`/`text` (sc-1497), so a shadcn/Tailwind app import's `--accent`, `--destructive`, `--muted`, `--popover` and `--ring` custom properties had no `themeConfig` home and were reported "no theme home" on every import. Each new scope binds to real `styleSchema` fields on the built-ins that already had a matching surface — `accent` (a highlight/tag surface: `background`/`borderColor`/`radius`) to the Label widget's own fields, `destructive` (a themed danger/delete action: `background`/`textColor`/`borderColor`) to a new "Danger" Button variant, `muted` (a subtle/secondary surface: `background`/`textColor`/`borderColor`/`radius`) to Form Input's and Form Builder's pre-existing input fields, `popover` (a dropdown/menu surface: `background`/`textColor`/`borderColor`) to the same two widgets' choice-field option list, and `ring` (the app-wide focus-visible outline: `color`/`width`) to a new emphasis border on Button. **This is HOST-ONLY plumbing, exactly like the three scopes before it** — `useTheme()`'s documented `components` slice is unchanged, no widget-authoring hook or `propertySchema` type moved, and no scope declares `universalFields`, so a third-party or AI-generated widget's contract is unaffected; the Developer guide and `DEFAULT_SYSTEM_PROMPT` need no update because neither ever documented this internal vocabulary. Fully additive: a theme with no `components` key, or one using only `button`/`card`/`text`, resolves exactly as before.
|
|
72
|
+
- **`CONTRACT.version` → `1.69.0`** (additive: five new `themeComponents` scopes + their target-field bindings). No existing scope, token, or export changed shape.
|
|
73
|
+
|
|
69
74
|
### What's new in 0.96.0 (contract 1.68.0)
|
|
70
75
|
|
|
71
76
|
**A manifest action can declare `manual`, and every action script gains a `request` global (sc-5366).** The backend Action model grew three ways of *reaching* a script to sit beside the ones that *fire* it: `manual` (nothing starts it — the workspace runs it on demand), `app` (a published app's button `onPress`) and `http_post` (an inbound webhook at `POST /api/v1/action-hooks/:actionId`, authenticated with one of the workspace's integration API keys). The same change retired the separate `appInvokable` boolean, so one column now answers "what starts this action?".
|
package/dist/contract.cjs
CHANGED
|
@@ -211,6 +211,34 @@ const CARD_UNIVERSAL_FIELDS = Object.freeze({
|
|
|
211
211
|
gradient: "cardGradient",
|
|
212
212
|
});
|
|
213
213
|
|
|
214
|
+
// The Form widgets' text-entry surface, already read by both form widgets
|
|
215
|
+
// (REQ-THEME-13, predating this scope) -- a genuine subtle/secondary surface
|
|
216
|
+
// distinct from the card that hosts it.
|
|
217
|
+
const MUTED_INPUT_FIELDS = Object.freeze({
|
|
218
|
+
background: "inputBackground",
|
|
219
|
+
textColor: "inputTextColor",
|
|
220
|
+
borderColor: "inputBorderColor",
|
|
221
|
+
radius: "inputRadius",
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// The Form widgets' choice-field option list -- the closest thing this
|
|
225
|
+
// catalog has to a menu/dropdown surface (singleChoice/multiChoice render an
|
|
226
|
+
// inline list of options here).
|
|
227
|
+
const POPOVER_FIELDS = Object.freeze({
|
|
228
|
+
background: "popoverBackground",
|
|
229
|
+
textColor: "popoverTextColor",
|
|
230
|
+
borderColor: "popoverBorderColor",
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// The Button widget's danger-variant fields -- kept separate from its own
|
|
234
|
+
// `background`/`textColor`/`borderColor` (the `button` scope's fields above)
|
|
235
|
+
// so a themed destructive action never collides with the button's normal look.
|
|
236
|
+
const DANGER_BUTTON_FIELDS = Object.freeze({
|
|
237
|
+
background: "dangerBackground",
|
|
238
|
+
textColor: "dangerTextColor",
|
|
239
|
+
borderColor: "dangerBorderColor",
|
|
240
|
+
});
|
|
241
|
+
|
|
214
242
|
const THEME_COMPONENTS = Object.freeze({
|
|
215
243
|
button: Object.freeze({
|
|
216
244
|
label: "Buttons",
|
|
@@ -277,6 +305,82 @@ const THEME_COMPONENTS = Object.freeze({
|
|
|
277
305
|
"appstudio.data-value": TEXT_TYPOGRAPHY_FIELDS,
|
|
278
306
|
}),
|
|
279
307
|
}),
|
|
308
|
+
// sc-5392 -- a highlight/tag surface. Bound to Label's OWN background/
|
|
309
|
+
// borderColor/radius fields (REQ-THEME-13, predating this scope) rather
|
|
310
|
+
// than its `color` field, which the `text` scope already owns -- two
|
|
311
|
+
// scopes writing the same field on the same widget would race.
|
|
312
|
+
accent: Object.freeze({
|
|
313
|
+
label: "Accent",
|
|
314
|
+
tokens: Object.freeze({
|
|
315
|
+
background: Object.freeze({ type: "color", uiDefault: "colors.primarySoft" }),
|
|
316
|
+
borderColor: Object.freeze({ type: "color", uiDefault: "colors.primary" }),
|
|
317
|
+
radius: Object.freeze({ type: "size", min: 0, max: 48, uiDefault: "radii.pill" }),
|
|
318
|
+
}),
|
|
319
|
+
targets: Object.freeze({
|
|
320
|
+
"appstudio.label": Object.freeze({
|
|
321
|
+
background: "background",
|
|
322
|
+
borderColor: "borderColor",
|
|
323
|
+
radius: "radius",
|
|
324
|
+
}),
|
|
325
|
+
}),
|
|
326
|
+
}),
|
|
327
|
+
// sc-5392 -- the Button widget's danger/delete variant. Separate token set
|
|
328
|
+
// from `button` above so "make the buttons coral" never recolours Delete.
|
|
329
|
+
destructive: Object.freeze({
|
|
330
|
+
label: "Destructive",
|
|
331
|
+
tokens: Object.freeze({
|
|
332
|
+
background: Object.freeze({ type: "color", uiDefault: "colors.danger" }),
|
|
333
|
+
textColor: Object.freeze({ type: "color", uiDefault: "colors.onPrimary" }),
|
|
334
|
+
borderColor: Object.freeze({ type: "color", uiDefault: "colors.danger" }),
|
|
335
|
+
}),
|
|
336
|
+
targets: Object.freeze({
|
|
337
|
+
"appstudio.button": DANGER_BUTTON_FIELDS,
|
|
338
|
+
}),
|
|
339
|
+
}),
|
|
340
|
+
// sc-5392 -- a subtle/secondary surface, bound to the form widgets' own
|
|
341
|
+
// text-entry fields (already REQ-THEME-13 style fields, predating this
|
|
342
|
+
// scope) rather than to Text/Label/Data Value, whose `color` field the
|
|
343
|
+
// `text` scope already owns.
|
|
344
|
+
muted: Object.freeze({
|
|
345
|
+
label: "Muted",
|
|
346
|
+
tokens: Object.freeze({
|
|
347
|
+
background: Object.freeze({ type: "color", uiDefault: "colors.surfaceMuted" }),
|
|
348
|
+
textColor: Object.freeze({ type: "color", uiDefault: "colors.onSurfaceMuted" }),
|
|
349
|
+
borderColor: Object.freeze({ type: "color", uiDefault: "colors.border" }),
|
|
350
|
+
radius: Object.freeze({ type: "size", min: 0, max: 48, uiDefault: "radii.sm" }),
|
|
351
|
+
}),
|
|
352
|
+
targets: Object.freeze({
|
|
353
|
+
"appstudio.form-input": MUTED_INPUT_FIELDS,
|
|
354
|
+
"appstudio.form-builder": MUTED_INPUT_FIELDS,
|
|
355
|
+
}),
|
|
356
|
+
}),
|
|
357
|
+
// sc-5392 -- dropdown/menu surfaces. The form widgets' choice-field option
|
|
358
|
+
// list is the closest thing the built-in catalog has to a popover panel.
|
|
359
|
+
popover: Object.freeze({
|
|
360
|
+
label: "Popover",
|
|
361
|
+
tokens: Object.freeze({
|
|
362
|
+
background: Object.freeze({ type: "color", uiDefault: "colors.surface" }),
|
|
363
|
+
textColor: Object.freeze({ type: "color", uiDefault: "colors.onSurface" }),
|
|
364
|
+
borderColor: Object.freeze({ type: "color", uiDefault: "colors.border" }),
|
|
365
|
+
}),
|
|
366
|
+
targets: Object.freeze({
|
|
367
|
+
"appstudio.form-input": POPOVER_FIELDS,
|
|
368
|
+
"appstudio.form-builder": POPOVER_FIELDS,
|
|
369
|
+
}),
|
|
370
|
+
}),
|
|
371
|
+
// sc-5392 -- the app-wide focus-visible outline. A themed emphasis border
|
|
372
|
+
// on the Button widget, applied after its variant colours and beaten by the
|
|
373
|
+
// widget's own per-instance `borderColor` (REQ-THEME-13 stays final).
|
|
374
|
+
ring: Object.freeze({
|
|
375
|
+
label: "Focus ring",
|
|
376
|
+
tokens: Object.freeze({
|
|
377
|
+
color: Object.freeze({ type: "color", uiDefault: "colors.primary" }),
|
|
378
|
+
width: Object.freeze({ type: "size", min: 0, max: 8 }),
|
|
379
|
+
}),
|
|
380
|
+
targets: Object.freeze({
|
|
381
|
+
"appstudio.button": Object.freeze({ color: "ringColor", width: "ringWidth" }),
|
|
382
|
+
}),
|
|
383
|
+
}),
|
|
280
384
|
});
|
|
281
385
|
|
|
282
386
|
// sc-4505 — the value types a widget event payload field may declare. Narrower
|
|
@@ -2956,7 +3060,12 @@ const CONTRACT = deepFreeze({
|
|
|
2956
3060
|
// action script now sees a `request` global — `{ body }` on a run fired
|
|
2957
3061
|
// by the workspace-granted `http_post` webhook trigger, null otherwise.
|
|
2958
3062
|
// `app` and `http_post` stay operator-granted and are NOT declarable.
|
|
2959
|
-
|
|
3063
|
+
// 1.69.0: additive (sc-5392) — `themeComponents` gains five scopes:
|
|
3064
|
+
// `accent`, `destructive`, `muted`, `popover` and `ring`, so a
|
|
3065
|
+
// shadcn/Tailwind import's matching custom properties have a themeConfig
|
|
3066
|
+
// home instead of being reported lost. Host-only plumbing: no scope
|
|
3067
|
+
// declares `universalFields`, so a third-party manifest is unaffected.
|
|
3068
|
+
version: "1.69.0",
|
|
2960
3069
|
sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
|
|
2961
3070
|
hooks: HOOKS,
|
|
2962
3071
|
primitives: PRIMITIVES,
|
package/dist/contract.js
CHANGED
|
@@ -211,6 +211,34 @@ const CARD_UNIVERSAL_FIELDS = Object.freeze({
|
|
|
211
211
|
gradient: "cardGradient",
|
|
212
212
|
});
|
|
213
213
|
|
|
214
|
+
// The Form widgets' text-entry surface, already read by both form widgets
|
|
215
|
+
// (REQ-THEME-13, predating this scope) -- a genuine subtle/secondary surface
|
|
216
|
+
// distinct from the card that hosts it.
|
|
217
|
+
const MUTED_INPUT_FIELDS = Object.freeze({
|
|
218
|
+
background: "inputBackground",
|
|
219
|
+
textColor: "inputTextColor",
|
|
220
|
+
borderColor: "inputBorderColor",
|
|
221
|
+
radius: "inputRadius",
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// The Form widgets' choice-field option list -- the closest thing this
|
|
225
|
+
// catalog has to a menu/dropdown surface (singleChoice/multiChoice render an
|
|
226
|
+
// inline list of options here).
|
|
227
|
+
const POPOVER_FIELDS = Object.freeze({
|
|
228
|
+
background: "popoverBackground",
|
|
229
|
+
textColor: "popoverTextColor",
|
|
230
|
+
borderColor: "popoverBorderColor",
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// The Button widget's danger-variant fields -- kept separate from its own
|
|
234
|
+
// `background`/`textColor`/`borderColor` (the `button` scope's fields above)
|
|
235
|
+
// so a themed destructive action never collides with the button's normal look.
|
|
236
|
+
const DANGER_BUTTON_FIELDS = Object.freeze({
|
|
237
|
+
background: "dangerBackground",
|
|
238
|
+
textColor: "dangerTextColor",
|
|
239
|
+
borderColor: "dangerBorderColor",
|
|
240
|
+
});
|
|
241
|
+
|
|
214
242
|
const THEME_COMPONENTS = Object.freeze({
|
|
215
243
|
button: Object.freeze({
|
|
216
244
|
label: "Buttons",
|
|
@@ -277,6 +305,82 @@ const THEME_COMPONENTS = Object.freeze({
|
|
|
277
305
|
"appstudio.data-value": TEXT_TYPOGRAPHY_FIELDS,
|
|
278
306
|
}),
|
|
279
307
|
}),
|
|
308
|
+
// sc-5392 -- a highlight/tag surface. Bound to Label's OWN background/
|
|
309
|
+
// borderColor/radius fields (REQ-THEME-13, predating this scope) rather
|
|
310
|
+
// than its `color` field, which the `text` scope already owns -- two
|
|
311
|
+
// scopes writing the same field on the same widget would race.
|
|
312
|
+
accent: Object.freeze({
|
|
313
|
+
label: "Accent",
|
|
314
|
+
tokens: Object.freeze({
|
|
315
|
+
background: Object.freeze({ type: "color", uiDefault: "colors.primarySoft" }),
|
|
316
|
+
borderColor: Object.freeze({ type: "color", uiDefault: "colors.primary" }),
|
|
317
|
+
radius: Object.freeze({ type: "size", min: 0, max: 48, uiDefault: "radii.pill" }),
|
|
318
|
+
}),
|
|
319
|
+
targets: Object.freeze({
|
|
320
|
+
"appstudio.label": Object.freeze({
|
|
321
|
+
background: "background",
|
|
322
|
+
borderColor: "borderColor",
|
|
323
|
+
radius: "radius",
|
|
324
|
+
}),
|
|
325
|
+
}),
|
|
326
|
+
}),
|
|
327
|
+
// sc-5392 -- the Button widget's danger/delete variant. Separate token set
|
|
328
|
+
// from `button` above so "make the buttons coral" never recolours Delete.
|
|
329
|
+
destructive: Object.freeze({
|
|
330
|
+
label: "Destructive",
|
|
331
|
+
tokens: Object.freeze({
|
|
332
|
+
background: Object.freeze({ type: "color", uiDefault: "colors.danger" }),
|
|
333
|
+
textColor: Object.freeze({ type: "color", uiDefault: "colors.onPrimary" }),
|
|
334
|
+
borderColor: Object.freeze({ type: "color", uiDefault: "colors.danger" }),
|
|
335
|
+
}),
|
|
336
|
+
targets: Object.freeze({
|
|
337
|
+
"appstudio.button": DANGER_BUTTON_FIELDS,
|
|
338
|
+
}),
|
|
339
|
+
}),
|
|
340
|
+
// sc-5392 -- a subtle/secondary surface, bound to the form widgets' own
|
|
341
|
+
// text-entry fields (already REQ-THEME-13 style fields, predating this
|
|
342
|
+
// scope) rather than to Text/Label/Data Value, whose `color` field the
|
|
343
|
+
// `text` scope already owns.
|
|
344
|
+
muted: Object.freeze({
|
|
345
|
+
label: "Muted",
|
|
346
|
+
tokens: Object.freeze({
|
|
347
|
+
background: Object.freeze({ type: "color", uiDefault: "colors.surfaceMuted" }),
|
|
348
|
+
textColor: Object.freeze({ type: "color", uiDefault: "colors.onSurfaceMuted" }),
|
|
349
|
+
borderColor: Object.freeze({ type: "color", uiDefault: "colors.border" }),
|
|
350
|
+
radius: Object.freeze({ type: "size", min: 0, max: 48, uiDefault: "radii.sm" }),
|
|
351
|
+
}),
|
|
352
|
+
targets: Object.freeze({
|
|
353
|
+
"appstudio.form-input": MUTED_INPUT_FIELDS,
|
|
354
|
+
"appstudio.form-builder": MUTED_INPUT_FIELDS,
|
|
355
|
+
}),
|
|
356
|
+
}),
|
|
357
|
+
// sc-5392 -- dropdown/menu surfaces. The form widgets' choice-field option
|
|
358
|
+
// list is the closest thing the built-in catalog has to a popover panel.
|
|
359
|
+
popover: Object.freeze({
|
|
360
|
+
label: "Popover",
|
|
361
|
+
tokens: Object.freeze({
|
|
362
|
+
background: Object.freeze({ type: "color", uiDefault: "colors.surface" }),
|
|
363
|
+
textColor: Object.freeze({ type: "color", uiDefault: "colors.onSurface" }),
|
|
364
|
+
borderColor: Object.freeze({ type: "color", uiDefault: "colors.border" }),
|
|
365
|
+
}),
|
|
366
|
+
targets: Object.freeze({
|
|
367
|
+
"appstudio.form-input": POPOVER_FIELDS,
|
|
368
|
+
"appstudio.form-builder": POPOVER_FIELDS,
|
|
369
|
+
}),
|
|
370
|
+
}),
|
|
371
|
+
// sc-5392 -- the app-wide focus-visible outline. A themed emphasis border
|
|
372
|
+
// on the Button widget, applied after its variant colours and beaten by the
|
|
373
|
+
// widget's own per-instance `borderColor` (REQ-THEME-13 stays final).
|
|
374
|
+
ring: Object.freeze({
|
|
375
|
+
label: "Focus ring",
|
|
376
|
+
tokens: Object.freeze({
|
|
377
|
+
color: Object.freeze({ type: "color", uiDefault: "colors.primary" }),
|
|
378
|
+
width: Object.freeze({ type: "size", min: 0, max: 8 }),
|
|
379
|
+
}),
|
|
380
|
+
targets: Object.freeze({
|
|
381
|
+
"appstudio.button": Object.freeze({ color: "ringColor", width: "ringWidth" }),
|
|
382
|
+
}),
|
|
383
|
+
}),
|
|
280
384
|
});
|
|
281
385
|
|
|
282
386
|
// sc-4505 — the value types a widget event payload field may declare. Narrower
|
|
@@ -2956,7 +3060,12 @@ const CONTRACT = deepFreeze({
|
|
|
2956
3060
|
// action script now sees a `request` global — `{ body }` on a run fired
|
|
2957
3061
|
// by the workspace-granted `http_post` webhook trigger, null otherwise.
|
|
2958
3062
|
// `app` and `http_post` stay operator-granted and are NOT declarable.
|
|
2959
|
-
|
|
3063
|
+
// 1.69.0: additive (sc-5392) — `themeComponents` gains five scopes:
|
|
3064
|
+
// `accent`, `destructive`, `muted`, `popover` and `ring`, so a
|
|
3065
|
+
// shadcn/Tailwind import's matching custom properties have a themeConfig
|
|
3066
|
+
// home instead of being reported lost. Host-only plumbing: no scope
|
|
3067
|
+
// declares `universalFields`, so a third-party manifest is unaffected.
|
|
3068
|
+
version: "1.69.0",
|
|
2960
3069
|
sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
|
|
2961
3070
|
hooks: HOOKS,
|
|
2962
3071
|
primitives: PRIMITIVES,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colixsystems/widget-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.97.0",
|
|
4
4
|
"description": "Common widget interface for AppStudio. Implements WidgetManifest, WidgetContext, property schema, and helper hooks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|