@colixsystems/widget-sdk 0.62.0 → 0.63.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
@@ -53,7 +53,11 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
53
53
 
54
54
  ## Status
55
55
 
56
- `v0.62.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**.
56
+ `v0.63.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**.
57
+
58
+ ### What's new in 0.63.0
59
+
60
+ **New optional manifest field `rendersOwnChrome` (sc-3331).** A boolean (default `false`) that declares whether your widget renders its OWN section header — a heading (and optional subtitle), plus any primary action for its section — making it a self-contained section. Set it `true` when your widget draws its own title (from a `title`/`subtitle` prop with a real default, so the author can still retitle it in the Properties Panel), and the AppStudio app-builder will place the widget as the WHOLE section: it will NOT add a standalone heading or a duplicate action button above it, so the section is never double-titled. Leave it `false`/omitted for a content-only widget whose heading the page supplies. `CONTRACT.version` → `1.42.0`. Additive — existing manifests omit it and read `false`, so no widget needs changing.
57
61
 
58
62
  ### What's new in 0.62.0
59
63
 
package/dist/contract.cjs CHANGED
@@ -971,6 +971,13 @@ const MANIFEST_SCHEMA = {
971
971
  "never auto-applies style — the widget owns placement.",
972
972
  default: {},
973
973
  },
974
+ rendersOwnChrome: {
975
+ type: "boolean",
976
+ required: false,
977
+ description:
978
+ "Optional (default false). TRUE when the widget renders its OWN section header — a heading (and optional subtitle), plus any primary action for its section — making it a self-contained section. The AppStudio app-builder reads this when it places an already-installed widget: it lays the widget out as the WHOLE section and does NOT add a standalone heading or a duplicate action button above it, so the section is never double-titled. Set it to match what the component actually renders; leave it false (or omit) for a content-only widget whose heading the page supplies.",
979
+ default: false,
980
+ },
974
981
  events: {
975
982
  type: "object[]",
976
983
  required: true,
@@ -1908,7 +1915,11 @@ const CONTRACT = deepFreeze({
1908
1915
  // no in-code `|| "fallback"`. Backed by a host-only subpath export
1909
1916
  // (`@colixsystems/widget-sdk/host` -> resolveProps); the author-facing entry
1910
1917
  // is unchanged. No existing behaviour changes — minor bump.
1911
- version: "1.41.0",
1918
+ // 1.42.0 (sc-3331) — new OPTIONAL manifest field `rendersOwnChrome` (boolean,
1919
+ // default false): declares that the widget renders its own section header,
1920
+ // so the app-builder places it as a whole section without stacking a
1921
+ // heading above it. Additive — existing manifests omit it and read false.
1922
+ version: "1.42.0",
1912
1923
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
1913
1924
  hooks: HOOKS,
1914
1925
  primitives: PRIMITIVES,
package/dist/contract.js CHANGED
@@ -971,6 +971,13 @@ const MANIFEST_SCHEMA = {
971
971
  "never auto-applies style — the widget owns placement.",
972
972
  default: {},
973
973
  },
974
+ rendersOwnChrome: {
975
+ type: "boolean",
976
+ required: false,
977
+ description:
978
+ "Optional (default false). TRUE when the widget renders its OWN section header — a heading (and optional subtitle), plus any primary action for its section — making it a self-contained section. The AppStudio app-builder reads this when it places an already-installed widget: it lays the widget out as the WHOLE section and does NOT add a standalone heading or a duplicate action button above it, so the section is never double-titled. Set it to match what the component actually renders; leave it false (or omit) for a content-only widget whose heading the page supplies.",
979
+ default: false,
980
+ },
974
981
  events: {
975
982
  type: "object[]",
976
983
  required: true,
@@ -1908,7 +1915,11 @@ const CONTRACT = deepFreeze({
1908
1915
  // no in-code `|| "fallback"`. Backed by a host-only subpath export
1909
1916
  // (`@colixsystems/widget-sdk/host` -> resolveProps); the author-facing entry
1910
1917
  // is unchanged. No existing behaviour changes — minor bump.
1911
- version: "1.41.0",
1918
+ // 1.42.0 (sc-3331) — new OPTIONAL manifest field `rendersOwnChrome` (boolean,
1919
+ // default false): declares that the widget renders its own section header,
1920
+ // so the app-builder places it as a whole section without stacking a
1921
+ // heading above it. Additive — existing manifests omit it and read false.
1922
+ version: "1.42.0",
1912
1923
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
1913
1924
  hooks: HOOKS,
1914
1925
  primitives: PRIMITIVES,
package/dist/hooks.js CHANGED
@@ -2823,16 +2823,37 @@ function toPaymentError(err) {
2823
2823
  * anything yourself (no `Linking.openURL`, no `checkout_url` to
2824
2824
  * handle). The mock provider auto-confirms (`status: "PAID"`, no
2825
2825
  * redirect). Rejects with a `PaymentError`.
2826
- * getPayment(paymentId) → Promise<payment> — poll the terminal status.
2827
- *
2828
- * Because the web redirect reloads the app on return, confirm completion
2829
- * from server-authoritative state (the Mollie webhook flips the charge /
2830
- * your datastore record) re-read your bound record on mount, or poll
2831
- * `getPayment(id)` after the mock/native flow resolves. Requires the
2832
- * `payments.charge:appUser` scope in the manifest's `requestedScopes`. The
2833
- * charge settles to the workspace owner; the app user confirms the amount
2834
- * in hosted Checkout. No card data touches the widget — never collect card
2835
- * fields yourself.
2826
+ * getPayment(paymentId) → Promise<payment> — read the current status
2827
+ * (`PENDING` | `PAID` | `FAILED`), scoped server-side to the caller.
2828
+ *
2829
+ * THE PAYER IS ALWAYS A SIGNED-IN APP USER charging requires it, and a paid
2830
+ * widget lives on a page behind login. So read the buyer's identity from
2831
+ * `useUser()` (`{ id, email, displayName }`) and connect the record you write
2832
+ * to `user.id`. Do NOT re-collect the name / email `useUser()` already gives
2833
+ * you as required inputs; pre-filling an editable field from it, or asking for
2834
+ * genuinely new details (phone, address, notes), is fine.
2835
+ *
2836
+ * CONFIRM FROM SERVER STATE, NOT MEMORY — and handle success, failure, AND
2837
+ * cancel. On web `requestPayment` triggers a full-page redirect, so the app
2838
+ * reloads on return and any in-memory "done" flag is gone. One pattern works on
2839
+ * both platforms:
2840
+ * 1. On mount, read `useRouteParams()`. After the web redirect it carries
2841
+ * `payment` (`"success"` | `"cancel"`) and, on success, `payment_id`.
2842
+ * `"cancel"` → the user backed out: show a "payment cancelled" state, do
2843
+ * NOT treat it as paid. `"success"` + `payment_id` → poll `getPayment(id)`
2844
+ * until it leaves `PENDING`, then branch: `PAID` → confirm / write the
2845
+ * record; `FAILED` → show a failure state.
2846
+ * 2. Also poll the `id` that `requestPayment` RESOLVES with — the mock
2847
+ * provider and the native in-app-browser flow return here without a reload,
2848
+ * so route params are absent and this branch reconciles instead.
2849
+ * Poll a bounded number of times (e.g. every ~1.5s for up to ~30s) because the
2850
+ * Mollie webhook may land a moment after the redirect; if it is still `PENDING`
2851
+ * when you give up, show a "still processing" state rather than "paid".
2852
+ *
2853
+ * Requires the `payments.charge:appUser` scope in the manifest's
2854
+ * `requestedScopes`. The charge settles to the workspace owner; the app user
2855
+ * confirms the amount in hosted Checkout. No card data touches the widget —
2856
+ * never collect card fields yourself.
2836
2857
  */
2837
2858
  export function usePayments() {
2838
2859
  const ctx = useWidgetContextOrThrow("usePayments");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colixsystems/widget-sdk",
3
- "version": "0.62.0",
3
+ "version": "0.63.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",