@colixsystems/widget-sdk 0.156.0 → 0.158.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 +10 -2
- package/dist/host.d.ts +5 -1
- package/dist/navigation.cjs +54 -21
- package/dist/navigation.js +54 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,7 +73,15 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
|
|
|
73
73
|
|
|
74
74
|
## Status
|
|
75
75
|
|
|
76
|
-
`v0.
|
|
76
|
+
`v0.157.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**.
|
|
77
|
+
|
|
78
|
+
### What's new in 0.157.0 (contract 1.122.0 — unchanged)
|
|
79
|
+
|
|
80
|
+
**The app header's row has its own text colour (sc-8518).** `resolveTopStripeLayout(theme)` now returns **`tintColor`** and **`titleColor`** beside the resolved `backgroundColor`, each reading `theme.sidebar.stripe.textColor` and falling back through `resolveTopBarTokens` when it is unset — exactly as the surface already falls back. One authored colour drives both, as the bar's own does; unset they part, the icons taking slate and the app name the brand.
|
|
81
|
+
|
|
82
|
+
Before this the row's ink lived on `topBar.textColor`, which also paints the tab row every top navigation bar draws — so recolouring the app header moved every one of those tab rows with it. What the two colours reach is what `slots` describes: the phone header, the desktop strip, the full-width bar, and the export's screen header. The drawer's own account rows, the sign-in control, the notification bell and the site-mode sheet are not that row and keep reading the bar.
|
|
83
|
+
|
|
84
|
+
Additive — nothing in the existing `./host` surface changed, an unset value resolves to what it resolved to before, and the contract is untouched.
|
|
77
85
|
|
|
78
86
|
### What's new in 0.156.0 (contract 1.122.0)
|
|
79
87
|
|
|
@@ -111,7 +119,7 @@ Behaviour: a bare date given to a `mode="datetime"` picker now shows local midni
|
|
|
111
119
|
|
|
112
120
|
**The app header's row is arrangeable, and `./host` publishes the resolver both hosts read (sc-8023).** The row runs across the top of the content outside the side panel, and is drawn three times — as the phone header where the panel is a drawer, as the desktop strip, and as the full-width bar when one is switched on. Each surface hard-coded its own copy of it, so an author could colour the row but never move anything in it.
|
|
113
121
|
|
|
114
|
-
- **`resolveTopStripeLayout(theme)`** reads `theme.sidebar.stripe` and returns the arrangement fully resolved: `slots` (already filtered and sequenced, so no host re-derives it), `order`, the box (`height`, `paddingX`, `contentOffsetY`), the resolved `backgroundColor
|
|
122
|
+
- **`resolveTopStripeLayout(theme)`** reads `theme.sidebar.stripe` and returns the arrangement fully resolved: `slots` (already filtered and sequenced, so no host re-derives it), `order`, the box (`height`, `paddingX`, `contentOffsetY`, and `barHeight` — the height once the nudge is held, since pushing the contents down grows the bar rather than letting them fall out of it), the resolved `backgroundColor` (joined in 0.155.0 by `tintColor` and `titleColor`), and `menuSide` — which edge the drawer must arrive from, since the brand grows and a burger ordered after it sits at the trailing edge. The web Player picks the drawer's side with it; the export makes it `drawerPosition`.
|
|
115
123
|
- **`TOP_STRIPE_SLOTS`** is the vocabulary (`back`, `menu`, `brand`, `notifications`) and **`TOP_STRIPE_ALWAYS_SHOWN_SLOTS`** the slots that move but never hide. The burger is the only member: it is drawn only where the panel is a drawer, and there it is the sole route into the menu, so hiding it would strand the visitor. It keeps its place in `order` regardless.
|
|
116
124
|
- **`topStripeShowKey(slot)`** derives the `theme_config` key that shows or hides one slot, in one place, so a control, the write path and the resolver cannot spell it differently.
|
|
117
125
|
- **The bounds travel with the resolver** — `MIN`/`MAX_TOP_STRIPE_HEIGHT_PX`, `MIN`/`MAX_TOP_STRIPE_PADDING_X_PX`, `MAX_TOP_STRIPE_OFFSET_Y_PX` — so a control offers exactly the range the resolver clamps to. `DEFAULT_TOP_STRIPE_HEIGHT_PX` / `DEFAULT_TOP_STRIPE_PADDING_X_PX` are what the DESKTOP row measures with nothing stored, published so a control can show the number an author is departing from; the resolver still answers `null`, because each surface keeps its own box until one is named.
|
package/dist/host.d.ts
CHANGED
|
@@ -332,8 +332,12 @@ export interface TopStripeLayout {
|
|
|
332
332
|
* bar's 64px, the phone header's content-sized row. */
|
|
333
333
|
height: number | null;
|
|
334
334
|
paddingX: number | null;
|
|
335
|
-
/** How far the row
|
|
335
|
+
/** How far the row's contents are pushed down, 0-60px. */
|
|
336
336
|
contentOffsetY: number;
|
|
337
|
+
/** The bar's total height once the nudge is held — its box plus
|
|
338
|
+
* `contentOffsetY`, so contents never fall out of the bottom. Null only
|
|
339
|
+
* while both are unset, where each surface keeps its own box. */
|
|
340
|
+
barHeight: number | null;
|
|
337
341
|
/** Every slot in the author's sequence, hidden ones included. */
|
|
338
342
|
order: TopStripeSlot[];
|
|
339
343
|
/** What the bar actually SHOWS, already filtered and sequenced. A surface
|
package/dist/navigation.cjs
CHANGED
|
@@ -403,15 +403,18 @@ function topStripeOrder(value) {
|
|
|
403
403
|
* bar left holding nothing is not drawn at all.
|
|
404
404
|
*
|
|
405
405
|
* @param {unknown} theme — the whole `theme_config`.
|
|
406
|
-
* @returns {{ backgroundColor: string,
|
|
407
|
-
*
|
|
408
|
-
*
|
|
406
|
+
* @returns {{ backgroundColor: string, tintColor: string, titleColor: string,
|
|
407
|
+
* height: number|null, paddingX: number|null, contentOffsetY: number,
|
|
408
|
+
* barHeight: number|null,
|
|
409
|
+
* order: string[], slots: string[], menuSide: "start"|"end" }}
|
|
409
410
|
*/
|
|
410
411
|
function resolveTopStripeLayout(theme) {
|
|
411
412
|
const config = isPlainObject(theme) ? theme : {};
|
|
412
413
|
const sidebar = isPlainObject(config.sidebar) ? config.sidebar : {};
|
|
413
414
|
const stripe = isPlainObject(sidebar.stripe) ? sidebar.stripe : {};
|
|
414
415
|
const order = topStripeOrder(stripe.order);
|
|
416
|
+
// Resolved once: the row's colours all fall back through the app-header bar.
|
|
417
|
+
const barTokens = resolveTopBarTokens(theme);
|
|
415
418
|
const shown = (slot) => {
|
|
416
419
|
if (TOP_STRIPE_ALWAYS_SHOWN_SLOTS.includes(slot)) return true;
|
|
417
420
|
const value = stripe[topStripeShowKey(slot)];
|
|
@@ -420,39 +423,69 @@ function resolveTopStripeLayout(theme) {
|
|
|
420
423
|
: TOP_STRIPE_SLOT_SHOWN_BY_DEFAULT[slot];
|
|
421
424
|
};
|
|
422
425
|
const slots = order.filter(shown);
|
|
426
|
+
// Unset defers to each surface's own box — the desktop bar's fixed 64px, the
|
|
427
|
+
// phone header's content-sized row.
|
|
428
|
+
const height = topStripeClampedOr(
|
|
429
|
+
stripe.height,
|
|
430
|
+
MIN_TOP_STRIPE_HEIGHT_PX,
|
|
431
|
+
MAX_TOP_STRIPE_HEIGHT_PX,
|
|
432
|
+
null,
|
|
433
|
+
);
|
|
434
|
+
const contentOffsetY = topStripeClampedOr(
|
|
435
|
+
stripe.contentOffsetY,
|
|
436
|
+
0,
|
|
437
|
+
MAX_TOP_STRIPE_OFFSET_Y_PX,
|
|
438
|
+
0,
|
|
439
|
+
);
|
|
423
440
|
return {
|
|
424
441
|
// There is no alignment to resolve: the brand slot GROWS, so the row has no
|
|
425
442
|
// free space for `justify-content` to distribute and every value looked
|
|
426
443
|
// identical. The row spreads because the brand takes the slack.
|
|
427
|
-
|
|
428
|
-
// the phone header's content-sized row.
|
|
429
|
-
height: topStripeClampedOr(
|
|
430
|
-
stripe.height,
|
|
431
|
-
MIN_TOP_STRIPE_HEIGHT_PX,
|
|
432
|
-
MAX_TOP_STRIPE_HEIGHT_PX,
|
|
433
|
-
null,
|
|
434
|
-
),
|
|
444
|
+
height,
|
|
435
445
|
paddingX: topStripeClampedOr(
|
|
436
446
|
stripe.paddingX,
|
|
437
447
|
MIN_TOP_STRIPE_PADDING_X_PX,
|
|
438
448
|
MAX_TOP_STRIPE_PADDING_X_PX,
|
|
439
449
|
null,
|
|
440
450
|
),
|
|
441
|
-
contentOffsetY
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
451
|
+
contentOffsetY,
|
|
452
|
+
// sc-8552: the bar GROWS by the nudge rather than letting its contents fall
|
|
453
|
+
// out of the bottom — the box the author sized, plus what they pushed into
|
|
454
|
+
// it. For a surface that must state a height (the desktop bar, the native
|
|
455
|
+
// header); the phone row is content-sized and grows on its padding alone.
|
|
456
|
+
barHeight:
|
|
457
|
+
height === null && contentOffsetY === 0
|
|
458
|
+
? null
|
|
459
|
+
: (height ?? DEFAULT_TOP_STRIPE_HEIGHT_PX) + contentOffsetY,
|
|
447
460
|
// sc-8023: the stripe's OWN surface, inheriting the app-header colour when
|
|
448
461
|
// unset — so an untouched app is unmoved, and an author who dresses a
|
|
449
462
|
// page's top navigation bar no longer repaints the stripe above the panel by
|
|
450
463
|
// accident. Fully resolved here, not raw-or-null, for the reason sc-8033
|
|
451
464
|
// resolved the footer's: a default that lives in each host drifts.
|
|
452
|
-
backgroundColor: hexOr(
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
465
|
+
backgroundColor: hexOr(stripe.backgroundColor, barTokens.backgroundColor),
|
|
466
|
+
// sc-8518: the row's OWN text, the half sc-8023 left on the bar. An author
|
|
467
|
+
// recolouring the app header used to move every top navigation bar's tab
|
|
468
|
+
// labels with it, because both read `topBar.textColor` — and had to open a
|
|
469
|
+
// panel named after the other part to do it.
|
|
470
|
+
//
|
|
471
|
+
// One authored colour drives BOTH slots, exactly as the bar's own does:
|
|
472
|
+
// unset they part (icons take slate, the app name takes the brand), and
|
|
473
|
+
// naming one is a decision about the whole row. Unset inherits the bar,
|
|
474
|
+
// so an app that never opens this field is unmoved.
|
|
475
|
+
//
|
|
476
|
+
// The row is what `slots` above describes — the desktop bar, the phone
|
|
477
|
+
// header, and native's screen header. The drawer's own account rows, the
|
|
478
|
+
// sign-in control and the site-mode sheet are NOT this row and keep
|
|
479
|
+
// reading the bar; so does the SITE header, which is shown instead of this
|
|
480
|
+
// row rather than beside it.
|
|
481
|
+
//
|
|
482
|
+
// The notification bell is the one member of `slots` this does not reach.
|
|
483
|
+
// It keeps its own resting colour on both hosts — web reads the authored
|
|
484
|
+
// `topBar.textColor` and the export tints it not at all — and moving it
|
|
485
|
+
// here would widen that difference rather than close it. Whoever closes it
|
|
486
|
+
// should move both hosts at once.
|
|
487
|
+
tintColor: hexOr(stripe.textColor, barTokens.tintColor),
|
|
488
|
+
titleColor: hexOr(stripe.textColor, barTokens.titleColor),
|
|
456
489
|
order,
|
|
457
490
|
slots,
|
|
458
491
|
// sc-8023: which edge the panel the burger opens should come in from. The
|
package/dist/navigation.js
CHANGED
|
@@ -394,15 +394,18 @@ function topStripeOrder(value) {
|
|
|
394
394
|
* bar left holding nothing is not drawn at all.
|
|
395
395
|
*
|
|
396
396
|
* @param {unknown} theme — the whole `theme_config`.
|
|
397
|
-
* @returns {{ backgroundColor: string,
|
|
398
|
-
*
|
|
399
|
-
*
|
|
397
|
+
* @returns {{ backgroundColor: string, tintColor: string, titleColor: string,
|
|
398
|
+
* height: number|null, paddingX: number|null, contentOffsetY: number,
|
|
399
|
+
* barHeight: number|null,
|
|
400
|
+
* order: string[], slots: string[], menuSide: "start"|"end" }}
|
|
400
401
|
*/
|
|
401
402
|
export function resolveTopStripeLayout(theme) {
|
|
402
403
|
const config = isPlainObject(theme) ? theme : {};
|
|
403
404
|
const sidebar = isPlainObject(config.sidebar) ? config.sidebar : {};
|
|
404
405
|
const stripe = isPlainObject(sidebar.stripe) ? sidebar.stripe : {};
|
|
405
406
|
const order = topStripeOrder(stripe.order);
|
|
407
|
+
// Resolved once: the row's colours all fall back through the app-header bar.
|
|
408
|
+
const barTokens = resolveTopBarTokens(theme);
|
|
406
409
|
const shown = (slot) => {
|
|
407
410
|
if (TOP_STRIPE_ALWAYS_SHOWN_SLOTS.includes(slot)) return true;
|
|
408
411
|
const value = stripe[topStripeShowKey(slot)];
|
|
@@ -411,39 +414,69 @@ export function resolveTopStripeLayout(theme) {
|
|
|
411
414
|
: TOP_STRIPE_SLOT_SHOWN_BY_DEFAULT[slot];
|
|
412
415
|
};
|
|
413
416
|
const slots = order.filter(shown);
|
|
417
|
+
// Unset defers to each surface's own box — the desktop bar's fixed 64px, the
|
|
418
|
+
// phone header's content-sized row.
|
|
419
|
+
const height = topStripeClampedOr(
|
|
420
|
+
stripe.height,
|
|
421
|
+
MIN_TOP_STRIPE_HEIGHT_PX,
|
|
422
|
+
MAX_TOP_STRIPE_HEIGHT_PX,
|
|
423
|
+
null,
|
|
424
|
+
);
|
|
425
|
+
const contentOffsetY = topStripeClampedOr(
|
|
426
|
+
stripe.contentOffsetY,
|
|
427
|
+
0,
|
|
428
|
+
MAX_TOP_STRIPE_OFFSET_Y_PX,
|
|
429
|
+
0,
|
|
430
|
+
);
|
|
414
431
|
return {
|
|
415
432
|
// There is no alignment to resolve: the brand slot GROWS, so the row has no
|
|
416
433
|
// free space for `justify-content` to distribute and every value looked
|
|
417
434
|
// identical. The row spreads because the brand takes the slack.
|
|
418
|
-
|
|
419
|
-
// the phone header's content-sized row.
|
|
420
|
-
height: topStripeClampedOr(
|
|
421
|
-
stripe.height,
|
|
422
|
-
MIN_TOP_STRIPE_HEIGHT_PX,
|
|
423
|
-
MAX_TOP_STRIPE_HEIGHT_PX,
|
|
424
|
-
null,
|
|
425
|
-
),
|
|
435
|
+
height,
|
|
426
436
|
paddingX: topStripeClampedOr(
|
|
427
437
|
stripe.paddingX,
|
|
428
438
|
MIN_TOP_STRIPE_PADDING_X_PX,
|
|
429
439
|
MAX_TOP_STRIPE_PADDING_X_PX,
|
|
430
440
|
null,
|
|
431
441
|
),
|
|
432
|
-
contentOffsetY
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
442
|
+
contentOffsetY,
|
|
443
|
+
// sc-8552: the bar GROWS by the nudge rather than letting its contents fall
|
|
444
|
+
// out of the bottom — the box the author sized, plus what they pushed into
|
|
445
|
+
// it. For a surface that must state a height (the desktop bar, the native
|
|
446
|
+
// header); the phone row is content-sized and grows on its padding alone.
|
|
447
|
+
barHeight:
|
|
448
|
+
height === null && contentOffsetY === 0
|
|
449
|
+
? null
|
|
450
|
+
: (height ?? DEFAULT_TOP_STRIPE_HEIGHT_PX) + contentOffsetY,
|
|
438
451
|
// sc-8023: the stripe's OWN surface, inheriting the app-header colour when
|
|
439
452
|
// unset — so an untouched app is unmoved, and an author who dresses a
|
|
440
453
|
// page's top navigation bar no longer repaints the stripe above the panel by
|
|
441
454
|
// accident. Fully resolved here, not raw-or-null, for the reason sc-8033
|
|
442
455
|
// resolved the footer's: a default that lives in each host drifts.
|
|
443
|
-
backgroundColor: hexOr(
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
456
|
+
backgroundColor: hexOr(stripe.backgroundColor, barTokens.backgroundColor),
|
|
457
|
+
// sc-8518: the row's OWN text, the half sc-8023 left on the bar. An author
|
|
458
|
+
// recolouring the app header used to move every top navigation bar's tab
|
|
459
|
+
// labels with it, because both read `topBar.textColor` — and had to open a
|
|
460
|
+
// panel named after the other part to do it.
|
|
461
|
+
//
|
|
462
|
+
// One authored colour drives BOTH slots, exactly as the bar's own does:
|
|
463
|
+
// unset they part (icons take slate, the app name takes the brand), and
|
|
464
|
+
// naming one is a decision about the whole row. Unset inherits the bar,
|
|
465
|
+
// so an app that never opens this field is unmoved.
|
|
466
|
+
//
|
|
467
|
+
// The row is what `slots` above describes — the desktop bar, the phone
|
|
468
|
+
// header, and native's screen header. The drawer's own account rows, the
|
|
469
|
+
// sign-in control and the site-mode sheet are NOT this row and keep
|
|
470
|
+
// reading the bar; so does the SITE header, which is shown instead of this
|
|
471
|
+
// row rather than beside it.
|
|
472
|
+
//
|
|
473
|
+
// The notification bell is the one member of `slots` this does not reach.
|
|
474
|
+
// It keeps its own resting colour on both hosts — web reads the authored
|
|
475
|
+
// `topBar.textColor` and the export tints it not at all — and moving it
|
|
476
|
+
// here would widen that difference rather than close it. Whoever closes it
|
|
477
|
+
// should move both hosts at once.
|
|
478
|
+
tintColor: hexOr(stripe.textColor, barTokens.tintColor),
|
|
479
|
+
titleColor: hexOr(stripe.textColor, barTokens.titleColor),
|
|
447
480
|
order,
|
|
448
481
|
slots,
|
|
449
482
|
// sc-8023: which edge the panel the burger opens should come in from. The
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colixsystems/widget-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.158.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",
|