Skip to content

fix: inline style override for padding/margin properties#4

Merged
hyochan merged 2 commits into
mainfrom
fix/inline-style-override
Nov 15, 2025
Merged

fix: inline style override for padding/margin properties#4
hyochan merged 2 commits into
mainfrom
fix/inline-style-override

Conversation

@hyochan
Copy link
Copy Markdown
Member

@hyochan hyochan commented Nov 15, 2025

  • Reverse style array order in Babel plugin optimization ([__ks.base, props.style])
  • Expand shorthand properties (padding, margin) to longhand for proper override
  • Add tests for expandShorthandProperties function

Summary by CodeRabbit

  • Bug Fixes

    • Ensure base styles are applied before external styles so external styles reliably override base styles
    • Expand padding/margin shorthands into explicit per-side longhand properties for more consistent React Native styling
  • Tests

    • Added comprehensive tests covering shorthand expansion, mixed cases, and edge inputs

- Reverse style array order in Babel plugin optimization ([__ks.base, props.style])
- Expand shorthand properties (padding, margin) to longhand for proper override
- Add tests for expandShorthandProperties function
@hyochan hyochan added the 🛠 bugfix All kinds of bug fixes label Nov 15, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 15, 2025

Walkthrough

Refactored padding/margin shorthand expansion to emit explicit longhand (top/right/bottom/left) in plugin and runtime; added a runtime utility to expand external styles; and reordered style source application to apply base styles before external styles to allow external overrides.

Changes

Cohort / File(s) Summary
Babel plugin: shorthand parsing
packages/babel-plugin-kstyled/src/css-parser.ts
Updated expandShorthand to return explicit longhand mappings for 1-, 2-, and 3-value padding/margin inputs (paddingTop/Right/Bottom/Left and margin equivalents) instead of vertical/horizontal shorthand forms.
Plugin entry: style order
packages/babel-plugin-kstyled/src/index.ts
Swapped style source order from [props.style, __ks.base] to [__ks.base, props.style] so base styles are applied first and external styles may override.
Runtime: shorthand handling
packages/kstyled/src/css.tsx
Changed padding/margin shorthand handling to emit explicit longhand per-side properties for 1/2/3-value shorthand cases; preserved 4-value behavior.
Runtime: style merging & utility
packages/kstyled/src/utils/style-merger.ts
Added exported expandShorthandProperties(styleObj: any): any to expand padding/margin shorthand into longhand and integrated expansion for externalStyle inputs before pushing into buildStyleArray.
Tests: style-merger
packages/kstyled/src/utils/__tests__/style-merger.test.ts
Added tests validating shorthand expansion to longhand, preservation of unrelated props, handling of mixed shorthand, and edge cases (null/undefined/empty).
Styled runtime: merged metadata
packages/kstyled/src/styled.tsx
Switched inputs to buildStyleArray to use mergedCompiledStyles/mergedStyleKeys (merged metadata) instead of component-local compiledStyles/styleKeys.
Babel tests
packages/babel-plugin-kstyled/src/__tests__/transform.test.ts
Updated expectations to assert longhand padding/margin outputs (paddingTop/Right/Bottom/Left, marginTop/Right/Bottom/Left) instead of vertical/horizontal shorthand.
Dev dependency
packages/kstyled/package.json
Added @types/jest to devDependencies.

Sequence Diagram(s)

sequenceDiagram
    participant Component
    participant Plugin/Runtime as Processor
    participant expandShorthand as Expander
    participant buildStyleArray as Builder
    participant Merger

    Component->>Processor: request render (has __ks.base, props.style)
    Note over Processor: NEW order: apply __ks.base first, then props.style
    Processor->>Builder: buildStyleArray([__ks.base, props.style])
    Builder->>expandShorthand: expand external style objects (padding/margin)
    alt shorthand present
        expandShorthand-->>Builder: explicit longhand props (paddingTop/Right/Bottom/Left...)
    else no shorthand
        expandShorthand-->>Builder: unchanged props
    end
    Builder->>Merger: merge base longhand + expanded external longhand
    Merger-->>Component: final style (external overrides base)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay extra attention to:
    • Correct mapping for 2- and 3-value shorthand (vertical/horizontal semantics).
    • Consistency of expansion logic between css-parser.ts, css.tsx, and style-merger.ts.
    • Effects of reordering sources (__ks.base vs props.style) across both plugin and runtime paths.
    • Updated tests in plugin and new tests for style-merger.

Poem

🐰 I hopped through shorthand, longhand in paw,
Top, right, bottom, left — precise like law.
Base lays the ground, external takes flight,
Styles dance together, everything's right. ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: fixing inline style override behavior for padding/margin properties by expanding shorthands to longhand equivalents.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/inline-style-override

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 451236d and 7e5f8bf.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • packages/babel-plugin-kstyled/src/__tests__/transform.test.ts (7 hunks)
  • packages/kstyled/package.json (1 hunks)
🔇 Additional comments (7)
packages/kstyled/package.json (1)

49-49: LGTM!

The addition of @types/jest is appropriate for TypeScript type support in Jest test files, and the version is compatible with the existing jest@29.7.0 dependency.

packages/babel-plugin-kstyled/src/__tests__/transform.test.ts (6)

28-34: LGTM!

Test expectations correctly verify that 2-value padding shorthands expand to explicit longhand properties (paddingTop, paddingRight, paddingBottom, paddingLeft) rather than React Native-specific shorthands. This ensures proper style override behavior when external styles are applied.


124-140: LGTM!

This test correctly verifies that single-value padding shorthands are preserved as-is without expansion. Only multi-value shorthands need to be expanded to longhand properties for proper override behavior.


159-166: LGTM!

Test expectations correctly verify that static padding shorthands are expanded to longhand properties even when combined with dynamic styles. The comment accurately describes the expected behavior.


229-237: LGTM!

Test expectations correctly verify that padding shorthand expansion works properly with the .attrs() pattern, ensuring the feature integrates well across different styled component patterns.


283-297: LGTM!

The test correctly verifies the complex real-world scenario where padding shorthand is expanded to longhand properties while preserving other static styles and dynamic backgroundColor handling. This ensures the refactor handles mixed style scenarios properly.


705-716: LGTM!

Test expectations correctly verify that shorthand expansion to longhand properties works properly with mixed unit values (px and unitless). This edge case is important for ensuring consistent behavior across different value formats.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/kstyled/src/utils/style-merger.ts (1)

94-111: Consider memoizing expanded external styles for performance.

The expandShorthandProperties function is called on every render when external styles are present. For components that re-render frequently or have complex external styles, consider memoizing the expansion result to avoid redundant object iterations.

This is likely not a bottleneck in most cases given the function's simplicity, but could be considered if profiling reveals performance issues.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12902ef and 451236d.

📒 Files selected for processing (6)
  • packages/babel-plugin-kstyled/src/css-parser.ts (2 hunks)
  • packages/babel-plugin-kstyled/src/index.ts (1 hunks)
  • packages/kstyled/src/css.tsx (1 hunks)
  • packages/kstyled/src/styled.tsx (1 hunks)
  • packages/kstyled/src/utils/__tests__/style-merger.test.ts (1 hunks)
  • packages/kstyled/src/utils/style-merger.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/kstyled/src/styled.tsx (1)
packages/kstyled/src/utils/style-merger.ts (1)
  • buildStyleArray (73-115)
packages/kstyled/src/utils/__tests__/style-merger.test.ts (1)
packages/kstyled/src/utils/style-merger.ts (1)
  • expandShorthandProperties (11-65)
🪛 GitHub Actions: Tests
packages/babel-plugin-kstyled/src/index.ts

[error] 1-1: Command 'pnpm --filter babel-plugin-kstyled --filter kstyled test' failed with exit code 1 (jest); ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL

packages/babel-plugin-kstyled/src/css-parser.ts

[error] 1-1: Command 'pnpm --filter babel-plugin-kstyled --filter kstyled test' failed with exit code 1 (jest); ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL

🔇 Additional comments (9)
packages/babel-plugin-kstyled/src/index.ts (2)

598-607: LGTM! Style precedence order correctly implements override semantics.

The reordering ensures external styles (props.style) override base styles (__ks.base) as intended. In React Native, styles are merged left-to-right in arrays, so placing base styles first and external styles last gives external styles the highest priority.


1-1: Provide specific pipeline failure details to verify the actual issue.

The original review claims test failures without providing evidence. I've inspected the codebase and found:

  • All source files (index.ts, css-parser.ts, types.ts, transform.ts) are syntactically valid
  • Jest configuration is properly set up
  • Test file exists with structured test cases
  • All imports resolve correctly

To verify the claimed pipeline failures, please share:

  • The actual error messages or logs from the failing tests
  • The specific test names that are failing
  • The full CI/CD pipeline output

Without concrete failure details, I cannot determine if issues exist or what specifically needs to be fixed.

packages/babel-plugin-kstyled/src/css-parser.ts (2)

212-228: LGTM! Shorthand expansion correctly implements longhand properties for proper override behavior.

The logic correctly expands CSS shorthand values to explicit longhand properties:

  • 2 values (vertical horizontal): top/bottom get parts[0], right/left get parts[1]
  • 3 values (top horizontal bottom): top=parts[0], right/left=parts[1], bottom=parts[2]

This ensures external styles can override individual sides when base styles use longhand properties, preventing React Native's inconsistent behavior with mixed shorthand/longhand properties.


239-256: LGTM! Margin expansion logic is consistent with padding.

The margin shorthand expansion follows the same correct pattern as padding, ensuring consistent override semantics across both properties.

packages/kstyled/src/utils/__tests__/style-merger.test.ts (1)

1-147: LGTM! Comprehensive test coverage for expandShorthandProperties.

The test suite thoroughly validates:

  • All shorthand expansions (padding, margin, horizontal, vertical variants)
  • Preservation of non-shorthand properties
  • Mixed shorthand scenarios
  • Edge cases (null, undefined, empty objects)

Well-structured and provides confidence in the utility function's correctness.

packages/kstyled/src/css.tsx (1)

140-163: LGTM! Runtime parser correctly mirrors build-time shorthand expansion.

The runtime CSS parsing logic for padding/margin shorthands is consistent with the build-time parser (css-parser.ts), ensuring uniform behavior regardless of whether styles are processed at build time or runtime. All shorthand cases (1-4 values) correctly expand to longhand properties.

packages/kstyled/src/styled.tsx (1)

123-132: LGTM! Correctly uses merged metadata for style inheritance.

Using mergedCompiledStyles and mergedStyleKeys instead of the component's own compiledStyles/styleKeys ensures that inherited base styles are properly included in the style array. This aligns with the broader changes in the PR to ensure correct style precedence and override behavior.

packages/kstyled/src/utils/style-merger.ts (2)

5-65: LGTM! Utility function correctly expands all padding/margin shorthands to longhand.

The implementation correctly handles all React Native padding/margin shorthand properties and expands them to explicit longhand properties (top/right/bottom/left). The function also properly:

  • Handles null/undefined/non-object inputs
  • Preserves non-shorthand properties
  • Uses Object.prototype.hasOwnProperty.call for safe iteration

Note on property ordering edge case: If an external style object contains both a shorthand property and its corresponding longhand property (e.g., { padding: 10, paddingTop: 20 }), the final result depends on object property iteration order. Since modern JavaScript maintains insertion order, the last defined property wins. This is consistent with CSS/React Native semantics where later declarations override earlier ones.


94-111: LGTM! External style expansion ensures consistent override semantics.

Expanding external styles to longhand properties before adding them to the style array ensures they can properly override base longhand properties. This addresses React Native's inconsistent handling of mixed shorthand/longhand properties across different style objects in an array.

The implementation correctly handles both array and non-array external styles.

@hyochan hyochan merged commit 6130dc6 into main Nov 15, 2025
5 checks passed
@hyochan hyochan deleted the fix/inline-style-override branch November 15, 2025 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠 bugfix All kinds of bug fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant