@colixsystems/widget-sdk 0.232.0 → 0.234.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
@@ -84,7 +84,15 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
84
84
 
85
85
  ## Status
86
86
 
87
- `v0.232.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**.
87
+ `v0.234.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**.
88
+
89
+ ### What's new in 0.234.0 (contract 1.189.0)
90
+
91
+ **The space around a bottom bar's tabs is the author's (host side only).** `resolveFooterTokens` from `@colixsystems/widget-sdk/host` now also resolves `padding`, 0–12px with a default of 4: the bar is its 40px tabs plus that space above and below, so 48px by default (it was a fixed 56) and 40px at zero. A floating bar's `itemRadius` follows the curve one padding in. `FOOTER_SIZES.padding` carries the bound. Nothing a widget imports changes.
92
+
93
+ ### What's new in 0.233.0 (contract 1.188.0)
94
+
95
+ **A floating bottom navigation bar is frosted glass by default (host side only).** `resolveFooterTokens` from `@colixsystems/widget-sdk/host` now also resolves `glass`, true for a floating bar unless the theme's `footer.glass` is `false` (a docked bar is never frosted, as nothing scrolls behind it), and `glassTint`, the 8-digit hex surface laid over the blur: the bar's `backgroundColor` at 72%, or its own alpha when it already has one. Nothing a widget imports changes.
88
96
 
89
97
  ### What's new in 0.232.0 (contract 1.187.0)
90
98
 
package/dist/contract.cjs CHANGED
@@ -6044,7 +6044,12 @@ const CONTRACT = deepFreeze({
6044
6044
  // bar's `shape` (unset floats), `radius`, `itemRadius`, `sideMargin` and
6045
6045
  // `bottomSpacing`; host exports `FOOTER_SIZES`, `clampFooterSize` and
6046
6046
  // `FOOTER_HOME_LINE_CLEARANCE_PX`. No widget-facing surface changes.
6047
- version: "1.187.0",
6047
+ // 1.188.0: additive (sc-11692) — `resolveFooterTokens` gains `glass` (a
6048
+ // floating bar is frosted unless `footer.glass` is false) and `glassTint`.
6049
+ // 1.189.0: additive (sc-11703) — `resolveFooterTokens` gains `padding`,
6050
+ // the space around a bottom bar's tabs (0–12, default 4); `FOOTER_SIZES`
6051
+ // gains its bound.
6052
+ version: "1.189.0",
6048
6053
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
6049
6054
  hooks: HOOKS,
6050
6055
  primitives: PRIMITIVES,
package/dist/contract.js CHANGED
@@ -6040,7 +6040,12 @@ const CONTRACT = deepFreeze({
6040
6040
  // bar's `shape` (unset floats), `radius`, `itemRadius`, `sideMargin` and
6041
6041
  // `bottomSpacing`; host exports `FOOTER_SIZES`, `clampFooterSize` and
6042
6042
  // `FOOTER_HOME_LINE_CLEARANCE_PX`. No widget-facing surface changes.
6043
- version: "1.187.0",
6043
+ // 1.188.0: additive (sc-11692) — `resolveFooterTokens` gains `glass` (a
6044
+ // floating bar is frosted unless `footer.glass` is false) and `glassTint`.
6045
+ // 1.189.0: additive (sc-11703) — `resolveFooterTokens` gains `padding`,
6046
+ // the space around a bottom bar's tabs (0–12, default 4); `FOOTER_SIZES`
6047
+ // gains its bound.
6048
+ version: "1.189.0",
6044
6049
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
6045
6050
  hooks: HOOKS,
6046
6051
  primitives: PRIMITIVES,
package/dist/host.d.ts CHANGED
@@ -265,14 +265,21 @@ export interface FooterTokens {
265
265
  /** The active tab's surface, or `null` for none — which is what "accent"
266
266
  * resolves to unless the author names one. */
267
267
  activeSurface: string | null;
268
+ /** sc-11692: a floating bar's frosted glass, on unless `glass: false`. */
269
+ glass: boolean;
270
+ /** The see-through surface laid over the blur (8-digit hex), or `null`
271
+ * when the bar is not frosted. */
272
+ glassTint: string | null;
268
273
  /** sc-11678: a rounded bar inset from the screen's sides, the page showing
269
274
  * around and beneath it, or the edge-to-edge strip. Unset is "floating". */
270
275
  shape: "floating" | "docked";
271
276
  /** A floating bar's corner radius, px (0–40). */
272
277
  radius: number;
273
- /** A tab's corner radius, px: a floating bar's curve one row inset in
278
+ /** A tab's corner radius, px: a floating bar's curve one padding in
274
279
  * (min 6) for a filled tab; 6 for an accent tab or a docked bar. */
275
280
  itemRadius: number;
281
+ /** sc-11703: the space around the tabs, px (0–12, default 4). */
282
+ padding: number;
276
283
  /** A floating bar's distance from the screen's sides, px (0–48). */
277
284
  sideMargin: number;
278
285
  /** Space below the tabs, px (0–32), on top of the system's clearance. */
@@ -281,14 +288,14 @@ export interface FooterTokens {
281
288
 
282
289
  /** sc-11678: each bar measurement's upper bound and default, px (min 0). */
283
290
  export const FOOTER_SIZES: Readonly<
284
- Record<"radius" | "sideMargin" | "bottomSpacing", Readonly<{ max: number; fallback: number }>>
291
+ Record<"radius" | "sideMargin" | "bottomSpacing" | "padding", Readonly<{ max: number; fallback: number }>>
285
292
  >;
286
293
 
287
294
  /** sc-11678: one bar measurement clamped onto its `FOOTER_SIZES` range, or
288
295
  * `undefined` when the value is not a finite number. */
289
296
  export function clampFooterSize(
290
297
  value: unknown,
291
- key: "radius" | "sideMargin" | "bottomSpacing",
298
+ key: "radius" | "sideMargin" | "bottomSpacing" | "padding",
292
299
  ): number | undefined;
293
300
 
294
301
  /** sc-11678: the part of the iOS bottom inset a bar keeps clear (the home
@@ -86,7 +86,8 @@ function menuItemCap(menuType) {
86
86
  // The authorable keys are the controls the Design panel offers, one for one:
87
87
  // `backgroundColor`, `textColor`, `tabActiveBackgroundColor`,
88
88
  // `tabActiveTextColor`, `borderColor`, `borderWidth`, `activeStyle`,
89
- // `tabLayout`, and (sc-11678) `shape`, `radius`, `sideMargin`, `bottomSpacing`.
89
+ // `tabLayout`, (sc-11678) `shape`, `radius`, `sideMargin`, `bottomSpacing`
90
+ // (sc-11692) `glass` and (sc-11703) `padding`.
90
91
  function resolveFooterTokens(theme) {
91
92
  const config = isPlainObject(theme) ? theme : {};
92
93
  const footer = isPlainObject(config.footer) ? config.footer : {};
@@ -105,8 +106,16 @@ function resolveFooterTokens(theme) {
105
106
  const divider = borderWidth > 0;
106
107
  const floats = footer.shape !== "docked";
107
108
  const radius = footerSizeOr(footer, "radius");
109
+ const padding = footerSizeOr(footer, "padding");
110
+ const backgroundColor = hexOr(footer.backgroundColor, DEFAULT_FOOTER_SURFACE);
111
+ // sc-11692: frosted unless switched off; only a floating bar has a page
112
+ // behind it to frost.
113
+ const glass = floats && footer.glass !== false;
108
114
  return {
109
- backgroundColor: hexOr(footer.backgroundColor, DEFAULT_FOOTER_SURFACE),
115
+ backgroundColor,
116
+ glass,
117
+ // The surface over the blur: the bar's colour, see-through.
118
+ glassTint: glass ? translucentHex(backgroundColor) : null,
110
119
  textColor: hexOr(footer.textColor, DEFAULT_CHROME_TEXT),
111
120
  borderColor: divider ? borderColor : null,
112
121
  borderWidth: divider ? borderWidth : null,
@@ -133,11 +142,12 @@ function resolveFooterTokens(theme) {
133
142
  // sc-11678: unset floats, so every app gets the rounded, inset bar.
134
143
  shape: floats ? "floating" : "docked",
135
144
  radius,
136
- // A filled tab follows a floating bar's curve one row inset (8px) in,
137
- // never sharper than the docked 6px chip. An accent tab paints no surface,
145
+ // A filled tab follows a floating bar's curve one padding in, never
146
+ // sharper than the docked 6px chip. An accent tab paints no surface,
138
147
  // and a curved top edge would bend its marker into an arc.
139
148
  itemRadius:
140
- floats && !accent ? Math.max(DOCKED_TAB_RADIUS, radius - 8) : DOCKED_TAB_RADIUS,
149
+ floats && !accent ? Math.max(DOCKED_TAB_RADIUS, radius - padding) : DOCKED_TAB_RADIUS,
150
+ padding,
141
151
  sideMargin: footerSizeOr(footer, "sideMargin"),
142
152
  bottomSpacing: footerSizeOr(footer, "bottomSpacing"),
143
153
  };
@@ -149,8 +159,20 @@ const FOOTER_SIZES = Object.freeze({
149
159
  radius: Object.freeze({ max: 40, fallback: 28 }),
150
160
  sideMargin: Object.freeze({ max: 48, fallback: 12 }),
151
161
  bottomSpacing: Object.freeze({ max: 32, fallback: 8 }),
162
+ // sc-11703: the space around the tabs; 4 makes a 48pt bar (40pt tabs).
163
+ padding: Object.freeze({ max: 12, fallback: 4 }),
152
164
  });
153
165
  const DOCKED_TAB_RADIUS = 6;
166
+
167
+ // sc-11692: a colour that already carries its own alpha keeps it; an opaque
168
+ // one is laid over the blur at 72%.
169
+ const GLASS_TINT_ALPHA = "b8";
170
+ function translucentHex(hex) {
171
+ const digits = hex.slice(1);
172
+ if (digits.length === 8) return hex;
173
+ const six = digits.length === 3 ? digits.replace(/./g, (d) => d + d) : digits;
174
+ return `#${six}${GLASS_TINT_ALPHA}`;
175
+ }
154
176
  function clampFooterSize(value, key) {
155
177
  if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
156
178
  return Math.min(Math.max(Math.round(value), 0), FOOTER_SIZES[key].max);
@@ -77,7 +77,8 @@ export function menuItemCap(menuType) {
77
77
  // The authorable keys are the controls the Design panel offers, one for one:
78
78
  // `backgroundColor`, `textColor`, `tabActiveBackgroundColor`,
79
79
  // `tabActiveTextColor`, `borderColor`, `borderWidth`, `activeStyle`,
80
- // `tabLayout`, and (sc-11678) `shape`, `radius`, `sideMargin`, `bottomSpacing`.
80
+ // `tabLayout`, (sc-11678) `shape`, `radius`, `sideMargin`, `bottomSpacing`
81
+ // (sc-11692) `glass` and (sc-11703) `padding`.
81
82
  export function resolveFooterTokens(theme) {
82
83
  const config = isPlainObject(theme) ? theme : {};
83
84
  const footer = isPlainObject(config.footer) ? config.footer : {};
@@ -96,8 +97,16 @@ export function resolveFooterTokens(theme) {
96
97
  const divider = borderWidth > 0;
97
98
  const floats = footer.shape !== "docked";
98
99
  const radius = footerSizeOr(footer, "radius");
100
+ const padding = footerSizeOr(footer, "padding");
101
+ const backgroundColor = hexOr(footer.backgroundColor, DEFAULT_FOOTER_SURFACE);
102
+ // sc-11692: frosted unless switched off; only a floating bar has a page
103
+ // behind it to frost.
104
+ const glass = floats && footer.glass !== false;
99
105
  return {
100
- backgroundColor: hexOr(footer.backgroundColor, DEFAULT_FOOTER_SURFACE),
106
+ backgroundColor,
107
+ glass,
108
+ // The surface over the blur: the bar's colour, see-through.
109
+ glassTint: glass ? translucentHex(backgroundColor) : null,
101
110
  textColor: hexOr(footer.textColor, DEFAULT_CHROME_TEXT),
102
111
  borderColor: divider ? borderColor : null,
103
112
  borderWidth: divider ? borderWidth : null,
@@ -124,11 +133,12 @@ export function resolveFooterTokens(theme) {
124
133
  // sc-11678: unset floats, so every app gets the rounded, inset bar.
125
134
  shape: floats ? "floating" : "docked",
126
135
  radius,
127
- // A filled tab follows a floating bar's curve one row inset (8px) in,
128
- // never sharper than the docked 6px chip. An accent tab paints no surface,
136
+ // A filled tab follows a floating bar's curve one padding in, never
137
+ // sharper than the docked 6px chip. An accent tab paints no surface,
129
138
  // and a curved top edge would bend its marker into an arc.
130
139
  itemRadius:
131
- floats && !accent ? Math.max(DOCKED_TAB_RADIUS, radius - 8) : DOCKED_TAB_RADIUS,
140
+ floats && !accent ? Math.max(DOCKED_TAB_RADIUS, radius - padding) : DOCKED_TAB_RADIUS,
141
+ padding,
132
142
  sideMargin: footerSizeOr(footer, "sideMargin"),
133
143
  bottomSpacing: footerSizeOr(footer, "bottomSpacing"),
134
144
  };
@@ -140,8 +150,20 @@ export const FOOTER_SIZES = Object.freeze({
140
150
  radius: Object.freeze({ max: 40, fallback: 28 }),
141
151
  sideMargin: Object.freeze({ max: 48, fallback: 12 }),
142
152
  bottomSpacing: Object.freeze({ max: 32, fallback: 8 }),
153
+ // sc-11703: the space around the tabs; 4 makes a 48pt bar (40pt tabs).
154
+ padding: Object.freeze({ max: 12, fallback: 4 }),
143
155
  });
144
156
  const DOCKED_TAB_RADIUS = 6;
157
+
158
+ // sc-11692: a colour that already carries its own alpha keeps it; an opaque
159
+ // one is laid over the blur at 72%.
160
+ const GLASS_TINT_ALPHA = "b8";
161
+ function translucentHex(hex) {
162
+ const digits = hex.slice(1);
163
+ if (digits.length === 8) return hex;
164
+ const six = digits.length === 3 ? digits.replace(/./g, (d) => d + d) : digits;
165
+ return `#${six}${GLASS_TINT_ALPHA}`;
166
+ }
145
167
  export function clampFooterSize(value, key) {
146
168
  if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
147
169
  return Math.min(Math.max(Math.round(value), 0), FOOTER_SIZES[key].max);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colixsystems/widget-sdk",
3
- "version": "0.232.0",
3
+ "version": "0.234.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",
package/src/contract.js CHANGED
@@ -6040,7 +6040,12 @@ const CONTRACT = deepFreeze({
6040
6040
  // bar's `shape` (unset floats), `radius`, `itemRadius`, `sideMargin` and
6041
6041
  // `bottomSpacing`; host exports `FOOTER_SIZES`, `clampFooterSize` and
6042
6042
  // `FOOTER_HOME_LINE_CLEARANCE_PX`. No widget-facing surface changes.
6043
- version: "1.187.0",
6043
+ // 1.188.0: additive (sc-11692) — `resolveFooterTokens` gains `glass` (a
6044
+ // floating bar is frosted unless `footer.glass` is false) and `glassTint`.
6045
+ // 1.189.0: additive (sc-11703) — `resolveFooterTokens` gains `padding`,
6046
+ // the space around a bottom bar's tabs (0–12, default 4); `FOOTER_SIZES`
6047
+ // gains its bound.
6048
+ version: "1.189.0",
6044
6049
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
6045
6050
  hooks: HOOKS,
6046
6051
  primitives: PRIMITIVES,