@lumiastream/ui 0.2.8-alpha.5 → 0.2.8-alpha.6

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/dist/index.d.ts CHANGED
@@ -498,6 +498,7 @@ type OverlayLayerBounds = {
498
498
  zIndex?: number;
499
499
  matrix?: string;
500
500
  clipPath?: string;
501
+ autoSize?: boolean;
501
502
  };
502
503
  type OverlayLayerState = {
503
504
  id: string;
@@ -606,6 +607,7 @@ interface SEText {
606
607
  scrolling?: {
607
608
  direction?: string;
608
609
  speed?: number;
610
+ enabled?: boolean;
609
611
  };
610
612
  css?: Record<string, unknown>;
611
613
  }
package/dist/index.js CHANGED
@@ -3237,11 +3237,21 @@ function listenerToLumiaVariable(listener) {
3237
3237
  return m[listener] ?? listener.replace(/-/g, "_");
3238
3238
  }
3239
3239
  function seCssToBounds(css, defaults = { width: 600, height: 200 }, canvas) {
3240
+ let widthIsAuto = false;
3241
+ let heightIsAuto = false;
3240
3242
  const toPx = (v, fallback, axis) => {
3241
- if (v == null) return fallback;
3243
+ if (v == null) {
3244
+ if (axis === "width") widthIsAuto = true;
3245
+ else if (axis === "height") heightIsAuto = true;
3246
+ return fallback;
3247
+ }
3242
3248
  if (typeof v === "number") return v;
3243
3249
  const s = v.trim();
3244
- if (s === "auto" || s === "") return fallback;
3250
+ if (s === "auto" || s === "") {
3251
+ if (axis === "width") widthIsAuto = true;
3252
+ else if (axis === "height") heightIsAuto = true;
3253
+ return fallback;
3254
+ }
3245
3255
  if (s.endsWith("%")) {
3246
3256
  const pct = parseFloat(s);
3247
3257
  if (canvas && axis && Number.isFinite(pct)) {
@@ -3255,6 +3265,7 @@ function seCssToBounds(css, defaults = { width: 600, height: 200 }, canvas) {
3255
3265
  };
3256
3266
  const width = toPx(css.width, defaults.width, "width");
3257
3267
  const height = toPx(css.height, defaults.height, "height");
3268
+ const autoSize = widthIsAuto || heightIsAuto;
3258
3269
  let x = toPx(css.left, 0, "width");
3259
3270
  let y = toPx(css.top, 0, "height");
3260
3271
  if (typeof css.transform === "string" && css.transform.includes("translate")) {
@@ -3280,7 +3291,8 @@ function seCssToBounds(css, defaults = { width: 600, height: 200 }, canvas) {
3280
3291
  width,
3281
3292
  height,
3282
3293
  opacity: css.opacity ?? 1,
3283
- zIndex: css["z-index"] ?? 0
3294
+ zIndex: css["z-index"] ?? 0,
3295
+ autoSize
3284
3296
  };
3285
3297
  }
3286
3298
  var LUMIA_DEFAULT_SIZES = {
@@ -3324,7 +3336,7 @@ function translateVariationCondition(seType, seCondition, requirement) {
3324
3336
  if (seCondition === "ATLEAST" && requirement != null) {
3325
3337
  return { conditionType: "GREATER_NUMBER", condition: requirement };
3326
3338
  }
3327
- return null;
3339
+ return { conditionType: "RANDOM", condition: 100 };
3328
3340
  }
3329
3341
  var LUMIA_LAYOUTS = /* @__PURE__ */ new Set(["column", "row", "onlyImage", "onlyText", "imageOver", "textOver"]);
3330
3342
  function translateLayout(seLayout) {
@@ -3352,7 +3364,11 @@ function buildUnit(widget, lumiaType, moduleExtras) {
3352
3364
  height: bounds.height,
3353
3365
  scale: [1, 1],
3354
3366
  opacity: bounds.opacity,
3355
- zIndex: bounds.zIndex
3367
+ zIndex: bounds.zIndex,
3368
+ // Carried over only when at least one axis was `auto` in the
3369
+ // source SE widget — text layers in particular want this so they
3370
+ // don't import as a 600x200 empty box.
3371
+ ...bounds.autoSize ? { autoSize: true } : {}
3356
3372
  }
3357
3373
  };
3358
3374
  const module = {
@@ -3374,6 +3390,19 @@ function buildUnit(widget, lumiaType, moduleExtras) {
3374
3390
  }
3375
3391
 
3376
3392
  // src/se-import/mappers/basic.ts
3393
+ function seExtraTextCss(seCss, scrolling) {
3394
+ const extra = {};
3395
+ if (typeof seCss["text-decoration"] === "string") extra.textDecoration = seCss["text-decoration"];
3396
+ if (typeof seCss["text-transform"] === "string") extra.textTransform = seCss["text-transform"];
3397
+ if (seCss["-webkit-text-stroke-color"]) extra["-webkit-text-stroke-color"] = seCss["-webkit-text-stroke-color"];
3398
+ if (seCss["-webkit-text-stroke-width"] != null) extra["-webkit-text-stroke-width"] = seCss["-webkit-text-stroke-width"];
3399
+ if (scrolling?.enabled) {
3400
+ extra.scroll = true;
3401
+ const speed = Number(scrolling.speed);
3402
+ if (Number.isFinite(speed) && speed > 0) extra.scrollSpeed = speed * 1e3;
3403
+ }
3404
+ return extra;
3405
+ }
3377
3406
  function mapText(widget) {
3378
3407
  const value = translateSeText(widget.text?.value ?? "");
3379
3408
  const seCss = widget.text?.css ?? {};
@@ -3390,7 +3419,8 @@ function mapText(widget) {
3390
3419
  color: seCss["color"] ?? "#ffffff",
3391
3420
  textShadow: seCss["text-shadow"] ?? "rgb(0, 0, 0) 1px 1px 1px",
3392
3421
  lineHeight: seCss["line-height"] ?? 1,
3393
- background: "transparent"
3422
+ background: "transparent",
3423
+ ...seExtraTextCss(seCss, widget.text?.scrolling)
3394
3424
  }
3395
3425
  });
3396
3426
  }
@@ -3443,7 +3473,8 @@ function mapReadout(widget, fallbackVar) {
3443
3473
  color: seCss["color"] ?? "#ffffff",
3444
3474
  textShadow: seCss["text-shadow"] ?? "rgb(0, 0, 0) 1px 1px 1px",
3445
3475
  lineHeight: seCss["line-height"] ?? 1,
3446
- background: "transparent"
3476
+ background: "transparent",
3477
+ ...seExtraTextCss(seCss, widget.text?.scrolling)
3447
3478
  }
3448
3479
  });
3449
3480
  }
@@ -3521,7 +3552,7 @@ function buildAlertEvent(seEvent, seEventType) {
3521
3552
  const textShadow = shadowEnabled ? importedTextShadow : "none";
3522
3553
  const marginTopRaw = Number(css["margin-top"]);
3523
3554
  const pushTextUp = Number.isFinite(marginTopRaw) ? -marginTopRaw : 0;
3524
- const variations = (seEvent.variations ?? []).map((variation) => buildAlertVariation(variation, seEventType)).filter((v) => v != null);
3555
+ const variations = (seEvent.variations ?? []).map((variation) => buildAlertVariation(variation, seEventType, seEvent)).filter((v) => v != null);
3525
3556
  const defaultDuration = (seEventType && SE_DEFAULT_DURATION_BY_EVENT[seEventType]) ?? 8;
3526
3557
  return {
3527
3558
  on: seEvent.enabled !== false,
@@ -3618,10 +3649,12 @@ function buildAlertEvent(seEvent, seEventType) {
3618
3649
  variations
3619
3650
  };
3620
3651
  }
3621
- function buildAlertVariation(v, seEventType) {
3652
+ function buildAlertVariation(v, seEventType, parentSettings) {
3622
3653
  const translated = translateVariationCondition(v.type ?? null, v.condition ?? null, v.requirement ?? null);
3623
3654
  if (!translated) return null;
3624
- const base = buildAlertEvent(v.settings, seEventType);
3655
+ const { variations: _parentVariations, ...parentInheritable } = parentSettings ?? {};
3656
+ const mergedSettings = deepMergeSeSettings(parentSettings ? parentInheritable : void 0, v.settings);
3657
+ const base = buildAlertEvent(mergedSettings, seEventType);
3625
3658
  return {
3626
3659
  name: v.name ?? "Variation",
3627
3660
  on: v.enabled !== false,
@@ -3632,6 +3665,22 @@ function buildAlertVariation(v, seEventType) {
3632
3665
  ...base
3633
3666
  };
3634
3667
  }
3668
+ function deepMergeSeSettings(parent, variation) {
3669
+ if (parent == null) return variation;
3670
+ if (variation == null) return parent;
3671
+ if (typeof parent !== "object" || typeof variation !== "object") return variation;
3672
+ if (Array.isArray(parent) || Array.isArray(variation)) return variation;
3673
+ const out = { ...parent };
3674
+ for (const [k, vv] of Object.entries(variation)) {
3675
+ if (vv === void 0) continue;
3676
+ if (vv && typeof vv === "object" && !Array.isArray(vv) && parent[k] && typeof parent[k] === "object" && !Array.isArray(parent[k])) {
3677
+ out[k] = deepMergeSeSettings(parent[k], vv);
3678
+ } else {
3679
+ out[k] = vv;
3680
+ }
3681
+ }
3682
+ return out;
3683
+ }
3635
3684
  function mapAlertBox(widget, opts = {}) {
3636
3685
  const v = widget.variables ?? {};
3637
3686
  const events = {};
@@ -3672,8 +3721,11 @@ function mapGoal(widget) {
3672
3721
  return buildUnit(widget, "goal", {
3673
3722
  content: {
3674
3723
  version: 1,
3675
- // Matches GoalTypes enum in components/Modules/Views/Goal/types.ts.
3676
- type: "bar",
3724
+ // `slim` reproduces SE's default goal look — label above a thin
3725
+ // track, with `0` / `goalAmount` anchoring the bar's edges and the
3726
+ // live `current` floating at the percentage position. See
3727
+ // components/Modules/Views/Goal/types.ts:GoalTypes.SLIM.
3728
+ type: "slim",
3677
3729
  label: translateSeText(v.title ?? "Goal"),
3678
3730
  subLabel: "",
3679
3731
  // The Goal module renders this template literal with {{current}} + {{goal}} substituted.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumiastream/ui",
3
- "version": "0.2.8-alpha.5",
3
+ "version": "0.2.8-alpha.6",
4
4
  "author": "Lumia Stream",
5
5
  "license": "ISC",
6
6
  "description": "Lumia UI Kit",