@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 +9 -1
- package/dist/contract.cjs +6 -1
- package/dist/contract.js +6 -1
- package/dist/host.d.ts +10 -3
- package/dist/navigation.cjs +27 -5
- package/dist/navigation.js +27 -5
- package/package.json +1 -1
- package/src/contract.js +6 -1
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
package/dist/navigation.cjs
CHANGED
|
@@ -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`,
|
|
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
|
|
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
|
|
137
|
-
//
|
|
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 -
|
|
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);
|
package/dist/navigation.js
CHANGED
|
@@ -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`,
|
|
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
|
|
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
|
|
128
|
-
//
|
|
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 -
|
|
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.
|
|
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
|
-
|
|
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,
|