Repository: motion-canvas/motion-canvas
File: packages/2d/src/components/Layout.ts (TypeScript)

Code before:
  public declare readonly wrap: SimpleSignal<FlexWrap, this>;

  @initial('normal')
  @signal()
  public declare readonly justifyContent: SimpleSignal<FlexJustify, this>;
  @initial('normal')
  @signal()
  public declare readonly alignItems: SimpleSignal<FlexAlign, this>;
  @initial(null)
  @signal()
  public declare readonly gap: SimpleSignal<Length, this>;
  @initial(null)
  @signal()
  public declare readonly rowGap: SimpleSignal<Length, this>;
  @initial(null)
  @signal()
  public declare readonly columnGap: SimpleSignal<Length, this>;

  @initial(null)
  @signal()
  public declare readonly fontFamily: SimpleSignal<string | null, this>;
  @signal()
  public declare readonly fontSize: SimpleSignal<number, this>;

  protected computeFontSize(): number {
    this.requestLayoutUpdate();
    return Number(this.styles.getPropertyValue('font-size').slice(0, -2));
  }

  @initial(null)
  @signal()
  public declare readonly fontStyle: SimpleSignal<string | null, this>;
  @initial(null)
  @signal()
  public declare readonly fontWeight: SimpleSignal<number | null, this>;
  @signal()
  public declare readonly lineHeight: SimpleSignal<number, this>;

  protected computeLineHeight(): number {
    this.requestLayoutUpdate();
    const styleHeight = Number(
      this.styles.getPropertyValue('line-height').slice(0, -2),
    );
    const minHeight = this.fontSize() * 1.2;
    return styleHeight < minHeight ? minHeight : styleHeight;
  }

  @initial(null)
  @signal()
  public declare readonly letterSpacing: SimpleSignal<number | null, this>;
  @initial(null)

Review comment (performance):
This is a problem btw. I've noticed this when testing. Technically, `this.requestFontUpdate()` should be enough to update all important font values but for some reason it doesn't work. `this.requestLayoutUpdate()` is a bit more expensive so it would be nice to get the former to work.

Code after:
  @signal()
  public declare readonly wrap: SimpleSignal<FlexWrap, this>;

  @initial('normal')
  @signal()
  public declare readonly justifyContent: SimpleSignal<FlexJustify, this>;
  @initial('normal')
  @signal()
  public declare readonly alignItems: SimpleSignal<FlexAlign, this>;
  @initial(null)
  @signal()
  public declare readonly gap: SimpleSignal<Length, this>;
  @initial(null)
  @signal()
  public declare readonly rowGap: SimpleSignal<Length, this>;
  @initial(null)
  @signal()
  public declare readonly columnGap: SimpleSignal<Length, this>;

  @defaultStyle('font-family')
  @signal()
  public declare readonly fontFamily: SimpleSignal<string, this>;
  @defaultStyle('font-size', parseFloat)
  @signal()
  public declare readonly fontSize: SimpleSignal<number, this>;
  @defaultStyle('font-style')
  @signal()
  public declare readonly fontStyle: SimpleSignal<string, this>;
  @defaultStyle('font-weight', parseInt)
  @signal()
  public declare readonly fontWeight: SimpleSignal<number, this>;
  @initial('120%')
  @signal()
  public declare readonly lineHeight: SimpleSignal<Length, this>;
  @defaultStyle('letter-spacing', i => {
    if (i === 'normal') {
      return 'normal';
    }
    return parseFloat(i);
  })
  @signal()
  public declare readonly letterSpacing: SimpleSignal<LetterSpacing, this>;

  @defaultStyle('white-space', i => {
    return i === 'pre' ? 'pre' : i === 'normal';
  })
  @signal()
  public declare readonly textWrap: SimpleSignal<TextWrap, this>;

  @cloneable(false)
  @inspectable(false)