@colixsystems/widget-sdk 0.129.0 → 0.131.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 CHANGED
@@ -70,7 +70,23 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
70
70
 
71
71
  ## Status
72
72
 
73
- `v0.129.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**.
73
+ `v0.131.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**.
74
+
75
+ ### What's new in 0.131.0 (contract 1.102.0)
76
+
77
+ **`styleGroup(name)` is deprecated and now inert (sc-7344).** The Widget Builder preview's click-to-select mode — the primitive's only reader — has been removed, so nothing maps a clicked element back to its style group any more. Style fields are edited through the whole-widget style editor the gear button opens.
78
+
79
+ - **No migration needed.** `styleGroup()` is still exported and still returns the same props, so existing `<View {...styleGroup("Card")}>` spreads keep building and rendering exactly as before — they are simply no-ops now. It was always a marker that changed nothing about how a widget renders.
80
+ - **Don't add it to new widgets.** The AI widget agent no longer emits it.
81
+
82
+ ### What's new in 0.130.0 (contract 1.101.0)
83
+
84
+ **~~New primitive `styleGroup(name)`~~ — superseded by 0.131.0, see above (sc-7282).** A widget's `styleSchema` already names the element each field belongs to via `ui.group` ("Card", "Title", "Value"), and the Studio renders those as labelled fieldsets. But a group name says which *fieldset* a control sits in, not which *element on screen* it moves — so clicking a button in the Widget Builder preview could only ever open the whole schema.
85
+
86
+ *(Historical — the guidance below no longer applies; see 0.131.0 above.)*
87
+
88
+ - **Spread it on the element each non-Basics group paints:** `<View {...styleGroup("Card")}>`. Pass the EXACT `ui.group` string; a mismatch marks an element no group owns. Mark each group ONCE, on the outermost element an author would point at — never the `"Basics"` group (it paints the whole widget) and never a child of an already-marked element. On a list that repeats a marked element per row, mark every row.
89
+ - **One module, both hosts.** It rides the existing `dataSet` prop: `react-native-web` maps it to a `data-*` attribute, and real react-native drops it, so the marker is inert on the device rather than a second implementation. It is a marker, not a style — it changes nothing about how a widget renders.
74
90
 
75
91
  ### What's new in 0.129.0 (contract 1.100.0)
76
92
 
package/dist/contract.cjs CHANGED
@@ -1878,6 +1878,17 @@ const PRIMITIVES = [
1878
1878
  rnComponent: null,
1879
1879
  docsUrl: null,
1880
1880
  },
1881
+ // sc-7282 — the element marker. sc-7344 removed its only reader (the Widget
1882
+ // Builder preview's click-to-select), so it is now DEPRECATED and inert on
1883
+ // both hosts. Kept exported because it is published API: dropping it would
1884
+ // break widgets already spreading it, and it is a no-op marker either way.
1885
+ {
1886
+ name: "styleGroup",
1887
+ description:
1888
+ "DEPRECATED (sc-7344) — do not add it to new widgets. It marked which rendered element a styleSchema `ui.group` painted, for a Widget Builder preview click-to-select that no longer exists. Nothing reads the marker now, so it has no effect on either host. It remains exported and safe: widgets that already spread it keep working — the call is a no-op now — so no migration is needed. Style fields are edited through the whole-widget style editor.",
1889
+ rnComponent: null,
1890
+ docsUrl: null,
1891
+ },
1881
1892
  // sc-6607 — the SCREEN-level overlay. Widgets could previously only paint an
1882
1893
  // overlay inside their own box, so a preview or dialog was clipped by the
1883
1894
  // layout container the widget sits in; this is the one primitive that leaves
@@ -3820,7 +3831,27 @@ const CONTRACT = deepFreeze({
3820
3831
  // preview useCamera already owns, so this is full parity wherever the
3821
3832
  // browser ships the API and a declared `supported:false` where it does not
3822
3833
  // (Safari, Firefox) — a genuine browser gap per CLAUDE.md §8.
3823
- version: "1.100.0",
3834
+ // 1.101.0: additive (sc-7282) — a new `styleGroup(name)` primitive marking
3835
+ // WHICH rendered element a styleSchema `ui.group` paints, so the Widget
3836
+ // Builder preview can map a clicked node back to its group and show only
3837
+ // that group's style fields instead of the whole schema. It returns props
3838
+ // to spread (`<View {...styleGroup("Card")}>`) and rides the existing
3839
+ // `dataSet` prop: react-native-web maps it to `data-*`, real react-native
3840
+ // drops it, so ONE module serves both hosts and the marker is inert on the
3841
+ // device — no §8 native-only case and no paired implementation. Purely a
3842
+ // marker: it changes nothing about how a widget renders. Minor bump on the
3843
+ // pre-1.0 channel.
3844
+ // 1.102.0: deprecation (sc-7344) — `styleGroup(name)` is now inert. Its only
3845
+ // reader, the Widget Builder preview's click-to-select mode (sc-7209) and
3846
+ // the per-element style narrowing it fed (sc-7282), is removed: two
3847
+ // controls opened one drawer, and arming the overlay stopped the author
3848
+ // exercising the widget they were previewing. The primitive stays
3849
+ // EXPORTED and unchanged — it is published API and a pure no-op marker, so
3850
+ // widgets already spreading it keep building with no migration (CLAUDE.md
3851
+ // §7: a breaking change to a shipped package needs a reason, and there is
3852
+ // none here). Only the MANDATE to emit it is gone, from the AI widget
3853
+ // agent prompt and the designer skill. Minor bump: nothing removed.
3854
+ version: "1.102.0",
3824
3855
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
3825
3856
  hooks: HOOKS,
3826
3857
  primitives: PRIMITIVES,
package/dist/contract.js CHANGED
@@ -1878,6 +1878,17 @@ const PRIMITIVES = [
1878
1878
  rnComponent: null,
1879
1879
  docsUrl: null,
1880
1880
  },
1881
+ // sc-7282 — the element marker. sc-7344 removed its only reader (the Widget
1882
+ // Builder preview's click-to-select), so it is now DEPRECATED and inert on
1883
+ // both hosts. Kept exported because it is published API: dropping it would
1884
+ // break widgets already spreading it, and it is a no-op marker either way.
1885
+ {
1886
+ name: "styleGroup",
1887
+ description:
1888
+ "DEPRECATED (sc-7344) — do not add it to new widgets. It marked which rendered element a styleSchema `ui.group` painted, for a Widget Builder preview click-to-select that no longer exists. Nothing reads the marker now, so it has no effect on either host. It remains exported and safe: widgets that already spread it keep working — the call is a no-op now — so no migration is needed. Style fields are edited through the whole-widget style editor.",
1889
+ rnComponent: null,
1890
+ docsUrl: null,
1891
+ },
1881
1892
  // sc-6607 — the SCREEN-level overlay. Widgets could previously only paint an
1882
1893
  // overlay inside their own box, so a preview or dialog was clipped by the
1883
1894
  // layout container the widget sits in; this is the one primitive that leaves
@@ -3820,7 +3831,27 @@ const CONTRACT = deepFreeze({
3820
3831
  // preview useCamera already owns, so this is full parity wherever the
3821
3832
  // browser ships the API and a declared `supported:false` where it does not
3822
3833
  // (Safari, Firefox) — a genuine browser gap per CLAUDE.md §8.
3823
- version: "1.100.0",
3834
+ // 1.101.0: additive (sc-7282) — a new `styleGroup(name)` primitive marking
3835
+ // WHICH rendered element a styleSchema `ui.group` paints, so the Widget
3836
+ // Builder preview can map a clicked node back to its group and show only
3837
+ // that group's style fields instead of the whole schema. It returns props
3838
+ // to spread (`<View {...styleGroup("Card")}>`) and rides the existing
3839
+ // `dataSet` prop: react-native-web maps it to `data-*`, real react-native
3840
+ // drops it, so ONE module serves both hosts and the marker is inert on the
3841
+ // device — no §8 native-only case and no paired implementation. Purely a
3842
+ // marker: it changes nothing about how a widget renders. Minor bump on the
3843
+ // pre-1.0 channel.
3844
+ // 1.102.0: deprecation (sc-7344) — `styleGroup(name)` is now inert. Its only
3845
+ // reader, the Widget Builder preview's click-to-select mode (sc-7209) and
3846
+ // the per-element style narrowing it fed (sc-7282), is removed: two
3847
+ // controls opened one drawer, and arming the overlay stopped the author
3848
+ // exercising the widget they were previewing. The primitive stays
3849
+ // EXPORTED and unchanged — it is published API and a pure no-op marker, so
3850
+ // widgets already spreading it keep building with no migration (CLAUDE.md
3851
+ // §7: a breaking change to a shipped package needs a reason, and there is
3852
+ // none here). Only the MANDATE to emit it is gone, from the AI widget
3853
+ // agent prompt and the designer skill. Minor bump: nothing removed.
3854
+ version: "1.102.0",
3824
3855
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
3825
3856
  hooks: HOOKS,
3826
3857
  primitives: PRIMITIVES,
package/dist/index.d.ts CHANGED
@@ -2679,3 +2679,15 @@ export function pressableLift(state?: {
2679
2679
  hovered?: boolean;
2680
2680
  pressed?: boolean;
2681
2681
  }): Array<Record<string, unknown> | null>;
2682
+
2683
+ /**
2684
+ * @deprecated (sc-7344) — inert; nothing reads the marker. It marked which
2685
+ * rendered element a styleSchema `ui.group` painted, for a Widget Builder
2686
+ * preview click-to-select that no longer exists. Still exported and safe:
2687
+ * existing spreads keep working as no-ops, so no migration is needed.
2688
+ *
2689
+ * A missing or blank name returns `undefined`, so spreading is always safe.
2690
+ */
2691
+ export function styleGroup(
2692
+ name: string,
2693
+ ): { dataSet: Record<string, string> } | undefined;
package/dist/index.js CHANGED
@@ -155,3 +155,4 @@ export {
155
155
  } from "./contract.js";
156
156
  export { normalizeLucideIconName } from "./lucideIconName.js";
157
157
  export { pressableLift } from "./interaction.js";
158
+ export { styleGroup } from "./style-group.js";
@@ -149,3 +149,4 @@ export {
149
149
  } from "./contract.js";
150
150
  export { normalizeLucideIconName } from "./lucideIconName.js";
151
151
  export { pressableLift } from "./interaction.native.js";
152
+ export { styleGroup } from "./style-group.js";
@@ -0,0 +1,35 @@
1
+ // sc-7282 — marked WHICH rendered element a styleSchema `ui.group` paints.
2
+ //
3
+ // DEPRECATED (sc-7344): its only reader, the Widget Builder preview's
4
+ // click-to-select, is gone, so the marker is now inert. Kept exported because
5
+ // it is published API and a no-op — widgets already spreading it need no
6
+ // migration (CLAUDE.md §7). Do not add it to new widgets.
7
+ //
8
+ // ONE file, no `.native.js` twin: `react-native-web` maps `dataSet` to `data-*`
9
+ // attributes while real react-native drops the prop, so the marker is inert on
10
+ // the device rather than a second implementation (CLAUDE.md §3). The paired
11
+ // modules in this package (interaction.js, overlay.js) exist because their
12
+ // behaviour genuinely differs per host; this one's does not.
13
+ //
14
+ // Not a primitive wrapper either — primitives.js re-exports react-native-web
15
+ // directly, and its header records that the hand-written paired wrappers were
16
+ // removed on purpose.
17
+
18
+ /** The `dataSet` key, surfacing in the DOM as `data-style-group`. */
19
+ export const STYLE_GROUP_DATA_KEY = "styleGroup";
20
+
21
+ /**
22
+ * @deprecated (sc-7344) — inert; nothing reads the marker.
23
+ *
24
+ * Props marking the element a style group paints. Still returns the same shape,
25
+ * so existing spreads keep working as no-ops.
26
+ *
27
+ * Returns `undefined` for a missing or blank name so `{...styleGroup(x)}` stays
28
+ * safe when `x` is absent: spreading `undefined` is a no-op in JSX.
29
+ */
30
+ export function styleGroup(name) {
31
+ if (typeof name !== "string") return undefined;
32
+ const trimmed = name.trim();
33
+ if (!trimmed) return undefined;
34
+ return { dataSet: { [STYLE_GROUP_DATA_KEY]: trimmed } };
35
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colixsystems/widget-sdk",
3
- "version": "0.129.0",
3
+ "version": "0.131.0",
4
4
  "description": "Common widget interface for AppStudio. Implements WidgetManifest, WidgetContext, property schema, and helper hooks.",
5
5
  "homepage": "https://github.com/Colix-AB/AppStudio",
6
6
  "type": "module",
@@ -49,7 +49,7 @@
49
49
  ],
50
50
  "scripts": {
51
51
  "build": "node scripts/build.js",
52
- "test": "node --test src/__tests__/contract.test.js src/__tests__/vetted-imports-audit.test.js src/__tests__/hooks-users.test.js src/__tests__/hooks-groups.test.js src/__tests__/hooks-invites.test.js src/__tests__/hooks-schema.test.js src/__tests__/hooks-assets-by-tag.test.js src/__tests__/hooks-filestore-upload.test.js src/__tests__/hooks-filestore-file.test.js src/__tests__/hooks-mutation.test.js src/__tests__/hooks-payments.test.js src/__tests__/hooks-record-permissions.test.js src/__tests__/hooks-geolocation.test.js src/__tests__/hooks-section-empty.test.js src/__tests__/hooks-widget-event.test.js src/__tests__/hooks-widget-input.test.js src/__tests__/hooks-identification.test.js src/__tests__/hooks-subscription.test.js src/__tests__/hooks-volatile-query-key.test.js src/__tests__/linter-users-scope.test.js src/__tests__/linter-comments.test.js src/__tests__/linter-translation-api.test.js src/__tests__/linter-page-url.test.js src/__tests__/linter-image-height.test.js src/__tests__/linter-flex-basis-percent.test.js src/__tests__/linter-hardcoded-design.test.js src/__tests__/linter-measured-padding.test.js src/__tests__/linter-payment-error.test.js src/__tests__/linter-platform.test.js src/__tests__/linter-react-import.test.js src/__tests__/lucide-icon-names.test.js src/__tests__/lucideIconName.test.js src/__tests__/manifest-actions.test.js src/__tests__/widget-translations.test.js src/__tests__/hooks-translate.test.js src/__tests__/devserver.test.js src/__tests__/flatten-entry.test.js src/__tests__/host-externals.test.js src/__tests__/datetimepicker.test.js src/__tests__/property-schema-resolve.test.js src/__tests__/corner-radius.test.js src/__tests__/theme-components-parity.test.js src/__tests__/navigation-parity.test.js src/__tests__/theme-depth-tokens.test.js src/__tests__/interaction-lift.test.js src/__tests__/toast-host.test.js src/__tests__/overlay-tokens.test.js src/__tests__/hooks-domain-error-mapping.test.js src/__tests__/linter-datastore-error.test.js src/__tests__/linter-write-gating.test.js src/__tests__/hooks-speech-to-text.test.js src/__tests__/hooks-camera.test.js src/__tests__/hooks-barcode.test.js src/__tests__/hooks-image-editor.test.js src/__tests__/hooks-bound-columns.test.js src/__tests__/hooks-stable-query.test.js src/__tests__/hooks-can-write.test.js src/__tests__/widget-route.test.js src/__tests__/linter-html-in-content.test.js src/__tests__/markdown.test.js src/__tests__/markdown-edit.test.js src/__tests__/richtext-tokens.test.js"
52
+ "test": "node --test src/__tests__/contract.test.js src/__tests__/vetted-imports-audit.test.js src/__tests__/hooks-users.test.js src/__tests__/hooks-groups.test.js src/__tests__/hooks-invites.test.js src/__tests__/hooks-schema.test.js src/__tests__/hooks-assets-by-tag.test.js src/__tests__/hooks-filestore-upload.test.js src/__tests__/hooks-filestore-file.test.js src/__tests__/hooks-mutation.test.js src/__tests__/hooks-payments.test.js src/__tests__/hooks-record-permissions.test.js src/__tests__/hooks-geolocation.test.js src/__tests__/hooks-section-empty.test.js src/__tests__/hooks-widget-event.test.js src/__tests__/hooks-widget-input.test.js src/__tests__/hooks-identification.test.js src/__tests__/hooks-subscription.test.js src/__tests__/hooks-volatile-query-key.test.js src/__tests__/linter-users-scope.test.js src/__tests__/linter-comments.test.js src/__tests__/linter-translation-api.test.js src/__tests__/linter-page-url.test.js src/__tests__/linter-image-height.test.js src/__tests__/linter-flex-basis-percent.test.js src/__tests__/linter-hardcoded-design.test.js src/__tests__/linter-measured-padding.test.js src/__tests__/linter-payment-error.test.js src/__tests__/linter-platform.test.js src/__tests__/linter-react-import.test.js src/__tests__/lucide-icon-names.test.js src/__tests__/lucideIconName.test.js src/__tests__/manifest-actions.test.js src/__tests__/widget-translations.test.js src/__tests__/hooks-translate.test.js src/__tests__/devserver.test.js src/__tests__/flatten-entry.test.js src/__tests__/host-externals.test.js src/__tests__/datetimepicker.test.js src/__tests__/property-schema-resolve.test.js src/__tests__/corner-radius.test.js src/__tests__/theme-components-parity.test.js src/__tests__/navigation-parity.test.js src/__tests__/theme-depth-tokens.test.js src/__tests__/interaction-lift.test.js src/__tests__/toast-host.test.js src/__tests__/overlay-tokens.test.js src/__tests__/hooks-domain-error-mapping.test.js src/__tests__/linter-datastore-error.test.js src/__tests__/linter-write-gating.test.js src/__tests__/hooks-speech-to-text.test.js src/__tests__/hooks-camera.test.js src/__tests__/hooks-barcode.test.js src/__tests__/hooks-image-editor.test.js src/__tests__/hooks-bound-columns.test.js src/__tests__/hooks-stable-query.test.js src/__tests__/hooks-can-write.test.js src/__tests__/widget-route.test.js src/__tests__/linter-html-in-content.test.js src/__tests__/markdown.test.js src/__tests__/markdown-edit.test.js src/__tests__/richtext-tokens.test.js src/__tests__/style-group.test.js"
53
53
  },
54
54
  "engines": {
55
55
  "node": ">=18"