Skip to content

Conversation

@Dugyu
Copy link
Collaborator

@Dugyu Dugyu commented Jul 21, 2025

In standard CSS and Web rendering environments, when a transition-property specifies multiple properties (e.g., opacity, transform), the corresponding transition timing values (transition-duration, transition-timing-function and transition-delay) values are automatically expanded (repeated) to match the number of transitioned properties. For example:

transition-property: opacity, transform;
transition-duration: 200ms;
/* becomes: 200ms, 200ms automatically */

Tailwind transition plugins rely on this implicit expansion:

.transition {
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); /* set default ease*/
  transition-duration: 150ms; /* set default duration*/
}
.delay-1000 {
  transition-delay: 1000ms; /* implicitly expand to match the number of transition properties*/
}
.duration-1000 {
  transition-duration: 1000ms; /* Override the default duration*/
}

However, Lynx currently does not support automatic value expansion when transition-property contains multiple properties (e.g., 'opacity, transform'). As a result, transition timing values like transition-duration must be manually repeated to match the number of properties in transition-property, otherwise, only the first property will animate and the others will be ignored.

To work around this, this PR introduces scoped transition timing utilities, generate correctly repeated timing values for each grouped transition-property, automatically matching the transitionProperty modifiers defined in config['theme'], such as:

  • duration-colors-* ease-colors-* delay-colors-* (for transitionProperty.colors)
  • duration-n-* ease-n-* delay-n-* (for transitionProperty.DEFAULT)
  • etc.

How it works

  • Scoped utilities like duration-colors-*, ease-colors-*, and delay-colors-* are generated when theme.transitionProperty.colors contains multiple properties (e.g., 'color', 'background-color', 'border-color').

  • Scoped utilities like duration-n-*, ease-n-*, and delay-n-* correspond to the theme.transitionProperty.DEFAULT group when it contains multiple properties.

  • When transitionProperty resolves to a single property (e.g., 'opacity', 'transform'), no scoped timing utilities are generated. You should continue using Tailwind's standard duration-*, ease-*, and delay-*.

These utilities internally calculate the correct repetition count based on the associated property group and generate comma-separated values for transition-duration, transition-timing-function, or transition-delay accordingly.
This ensures smoother DX parity with Tailwind's expected behavior while remaining compatible with Lynx's CSS runtime constraints.

Example Usage

<view
  className={clsx(
    'bg-blue-400 transition duration-n-1000',
    transitioned && 'bg-rose-400',
  )}
/>

<text
  className={clsx(
    'text-white bg-blue-400 transition-colors duration-colors-500 delay-colors-700',
    transitioned && 'text-yellow-300 bg-rose-400',
  )}
>
  Hello ReactLynx
</text>

Generated css

.transition {
  transition-property: background-color, opacity, transform, border-color, color;
  transition-duration: 150ms, 150ms, 150ms, 150ms, 150ms;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1), cubic-bezier(0.4, 0, 0.2, 1), cubic-bezier(0.4, 0, 0.2, 1), cubic-bezier(0.4, 0, 0.2, 1), cubic-bezier(0.4, 0, 0.2, 1);
}
.transition-colors {
  transition-property: background-color, border-color, color;
  transition-duration: 150ms, 150ms, 150ms;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1), cubic-bezier(0.4, 0, 0.2, 1), cubic-bezier(0.4, 0, 0.2, 1);
}
.delay-colors-700 {
  transition-delay: 700ms, 700ms, 700ms;
}
.duration-colors-500 {
  transition-duration: 500ms, 500ms, 500ms;
}
.duration-n-1000 {
  transition-duration: 1000ms, 1000ms, 1000ms, 1000ms, 1000ms;
}

Corresponding Lynx theme config:

transitionProperty: {
    // fill, stroke, backdrop-filter, box-shadow, text-decoration-color cannot be animated in Lynx
    none: 'none',
    all: 'all',
    DEFAULT: 'background-color, opacity, transform, border-color, color',
    colors: 'background-color, border-color, color',
    opacity: 'opacity',
    transform: 'transform',
    color: 'color',
    filter: 'filter',
    'background-color': 'background-color',
    'border-color': 'border-color',
 }

Summary by CodeRabbit

  • New Features
    • Introduced advanced transition utilities with scoped timing classes for properties, durations, delays, and timing functions, supporting grouped and repeated CSS values.
    • Added new theme sections defining detailed transition property groups, customizable durations, and timing functions.
    • Added new utility functions to generate repeated CSS property values and identify plain identifier lists.
    • Introduced plugins for transition-delay, transition-duration, transition-property, and transition-timing-function with dynamic utility generation.
    • Implemented a plugin registry enforcing ordered plugin loading for consistent CSS output.
  • Bug Fixes
    • Improved handling of grouped transition properties to ensure accurate CSS output for multi-property transitions.
  • Tests
    • Added comprehensive test suites for transition utilities, repeater utilities, and plugin behavior to ensure correctness and reliability.
  • Documentation
    • Enhanced type exports and theme type definitions for improved developer experience and type safety.

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).

@changeset-bot
Copy link

changeset-bot bot commented Jul 21, 2025

🦋 Changeset detected

Latest commit: 8ff850b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@lynx-js/tailwind-preset Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 21, 2025

📝 Walkthrough

Walkthrough

This change introduces new utility functions and plugins for handling scoped and repeated transition timing utilities in the Tailwind preset for Lynx. It adds new plugins for transition properties, durations, delays, and timing functions, updates the theme configuration, and implements comprehensive tests. Supporting utility functions for repeated CSS values and type definitions are also included.

Changes

Files/Group Change Summary
src/plugins/lynx/transitionProperty.ts, transitionDuration.ts, transitionDelay.ts, transitionTimingFunction.ts Added new Tailwind plugins for transition property, duration, delay, and timing function, each using shared utility logic.
src/plugins/lynx/index.ts Exported the new transition plugins.
src/plugin-utils/create-repeater-utility.ts, get-modifier-repeater-map.ts, is-plain-ident-list.ts, create-transition-timing-plugin.ts Added new utility functions for repeating CSS values, mapping modifiers, checking identifier lists, and creating transition timing plugins.
src/plugin-utils/index.ts Exported new utility functions.
src/__tests__/plugin-utils/create-repeater-utility.test.ts, get-modifier-repeater-map.test.ts Added tests for the new repeater and modifier mapping utilities.
src/__tests__/plugins/transitionProperty.test.ts, transitionDuration.test.ts, transitionDelay.test.ts, transitionTimingFunction.test.ts Added tests for the new transition plugins.
src/__tests__/utils/mock-api.ts, run-plugin.ts Updated plugin API mocks to support new theme value lookups and removed redundant theme logic.
src/core.ts Commented out core transition plugins, now handled via new plugin mechanism.
src/theme.ts Updated theme type and redefined transition-related theme values, adding more detailed transition property, duration, and timing function sections.
src/types/theme-types.ts Introduced new Lynx-specific theme type definitions.
src/types/index.d.ts Re-exported new theme types.
src/types/tailwind-types.ts Removed obsolete StrictThemeConfig type.
src/plugin-utils/create-function-call-utility.ts Updated import source for type only.
src/lynx.ts Changed plugin iteration to use ordered plugin list for deterministic plugin loading.
src/plugins/lynx/plugin-registry.ts Added centralized plugin registry with ordered plugin entries and mappings.
src/plugins/lynx/plugin-types.ts Added type alias for Lynx plugin names derived from plugin modules.

Estimated code review effort

4 (~75–90 minutes)

Suggested reviewers

  • colinaaa
  • gaoachao

Poem

🐇
In the garden of code, transitions bloom anew,
With durations and delays, in colors and hues.
Utilities repeat, like carrots in a row,
Timing functions hop, where breezy breezes blow.
Tests abound, themes refined,
Lynx-tailwind magic, perfectly aligned!
🌱✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

 ERROR  Cannot resolve version $@rspack/core in overrides. The direct dependencies don't have dependency "@rspack/core".
For help, run: pnpm help install


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f285ee and 8ff850b.

📒 Files selected for processing (5)
  • packages/third-party/tailwind-preset/src/__tests__/plugin-registry.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/core.ts (4 hunks)
  • packages/third-party/tailwind-preset/src/lynx.ts (2 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/plugin-types.ts (1 hunks)
🧠 Learnings (2)
📓 Common learnings
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.
packages/third-party/tailwind-preset/src/__tests__/plugin-registry.test.ts (1)

Learnt from: colinaaa
PR: #1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:26:16.722Z
Learning: In the lynx-family/lynx-stack repository, CI checks require changesets when files matching the pattern "src/**" are modified (as configured in .changeset/config.json). For internal changes that don't need meaningful changesets, an empty changeset file is used to satisfy the CI requirement while not generating any release notes.

✅ Files skipped from review due to trivial changes (1)
  • packages/third-party/tailwind-preset/src/plugins/lynx/plugin-types.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/third-party/tailwind-preset/src/lynx.ts
  • packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts
  • packages/third-party/tailwind-preset/src/core.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.
packages/third-party/tailwind-preset/src/__tests__/plugin-registry.test.ts (1)

Learnt from: colinaaa
PR: #1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:26:16.722Z
Learning: In the lynx-family/lynx-stack repository, CI checks require changesets when files matching the pattern "src/**" are modified (as configured in .changeset/config.json). For internal changes that don't need meaningful changesets, an empty changeset file is used to satisfy the CI requirement while not generating any release notes.

🔇 Additional comments (5)
packages/third-party/tailwind-preset/src/__tests__/plugin-registry.test.ts (5)

4-12: LGTM! Well-organized imports.

The import statements are comprehensive and properly structured, including all necessary testing utilities, types, and registry objects for the test suite.


16-24: Excellent test coverage for plugin registry mapping.

This test effectively validates both the existence of plugin exports and their correct reference mapping, which is crucial for catching configuration errors. The two-step validation approach with clear comments makes the test intent obvious.


26-35: Solid validation of plugin map consistency.

The test properly validates that LYNX_PLUGIN_MAP values reference the correct plugin implementations. The type assertion for Object.entries maintains type safety while enabling dynamic iteration.


38-41: Clean and effective duplicate detection.

The test uses a standard Set-based approach to detect duplicate plugin names, which is both efficient and readable. This validation is essential for registry integrity.


44-46: Valuable compile-time type validation.

The type-level assertion ensures that LYNX_PLUGIN_MAP maintains complete coverage of all LynxPluginName values at compile time, complementing the runtime tests with static type safety guarantees.

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Dugyu Dugyu requested review from gaoachao and upupming July 21, 2025 12:40
Copy link
Contributor

@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 (5)
packages/third-party/tailwind-preset/src/__tests__/plugins/tranitionDelay.test.ts (1)

1-1: Fix filename typo

The filename contains a typo: tranitionDelay.test.ts should be transitionDelay.test.ts (missing 's' in "transition").

packages/third-party/tailwind-preset/src/plugins/lynx/transitionProperty.ts (1)

10-14: Consider improving comment formatting.

The comment explaining the Lynx vs Web default timing function difference is valuable but could be formatted better for readability.

-    const defaultTimingFunction = theme(
-      'transitionTimingFunction.DEFAULT',
-      'ease', // Lynx default transition-timing-function is 'linear' (Web is 'ease'), we use 'ease' for similar DX experience with Web
-    );
+    const defaultTimingFunction = theme(
+      'transitionTimingFunction.DEFAULT',
+      // Lynx default is 'linear' (Web is 'ease'), we use 'ease' for similar DX experience
+      'ease',
+    );
packages/third-party/tailwind-preset/src/__tests__/plugin-utils/create-repeater-utility.test.ts (1)

73-80: Consider adding a comment to clarify the test behavior.

This test case demonstrates an important behavior where complex CSS values (containing commas) are treated as a single item rather than being split. A brief comment would make this behavior more explicit.

  it('treats complex matchValue as single item', () => {
+    // CSS variables with commas should not be split - treated as single value
    const fn = createRepeaterUtility('transition-delay', {
      matchValue: 'x, var(--a, y), z',
    });
    expect(fn('300ms')).toEqual({
      'transition-delay': '300ms',
    });
  });
packages/third-party/tailwind-preset/src/plugin-utils/create-repeater-utility.ts (2)

44-46: Minor spelling correction in parameter names.

The parameter names use "Deliminator" instead of the correct spelling "Delimiter". Consider updating for consistency with standard terminology.

-    splitDeliminator = ',',
-    fillDeliminator = ', ',
+    splitDelimiter = ',',
+    fillDelimiter = ', ',

And update the interface accordingly:

-  splitDeliminator?: string;
-  fillDeliminator?: string;
+  splitDelimiter?: string;
+  fillDelimiter?: string;

Also applies to: 95-101


104-106: Consider expanding CSS function detection.

The isPlainIdentList function only checks for var() and calc() functions. While this covers the most common cases for transition properties, there are other CSS functions that could appear in property lists.

Consider a more comprehensive check:

function isPlainIdentList(value: string): boolean {
-  return !value.includes('var(') && !value.includes('calc(');
+  // Check for common CSS functions that would make this not a plain list
+  return !/(?:var|calc|attr|url)\s*\(/i.test(value);
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a2a57d and 7df256c.

📒 Files selected for processing (20)
  • .changeset/rich-eels-cheat.md (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugin-utils/create-repeater-utility.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugins/tranitionDelay.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDuration.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugins/transitionProperty.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugins/transitionTimingFunction.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/utils/mock-api.ts (2 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/utils/run-plugin.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/core.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/create-repeater-utility.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/index.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/index.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDelay.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDuration.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionProperty.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionTimingFunction.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/theme.ts (2 hunks)
  • packages/third-party/tailwind-preset/src/types/index.d.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/types/tailwind-types.ts (0 hunks)
  • packages/third-party/tailwind-preset/src/types/theme-types.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/third-party/tailwind-preset/src/types/tailwind-types.ts
🧰 Additional context used
🧠 Learnings (2)
.changeset/rich-eels-cheat.md (1)

Learnt from: PupilTong
PR: #1029
File: packages/web-platform/web-core/src/uiThread/createRenderAllOnUI.ts:95-99
Timestamp: 2025-07-16T06:28:26.421Z
Learning: In the lynx-stack codebase, CSS selectors in SSR hydration are generated by their own packages, ensuring a predictable format that makes simple string manipulation safe and preferable over regex for performance reasons.

packages/third-party/tailwind-preset/src/theme.ts (2)

Learnt from: PupilTong
PR: #1029
File: packages/web-platform/web-core/src/uiThread/createRenderAllOnUI.ts:95-99
Timestamp: 2025-07-16T06:28:26.421Z
Learning: In the lynx-stack codebase, CSS selectors in SSR hydration are generated by their own packages, ensuring a predictable format that makes simple string manipulation safe and preferable over regex for performance reasons.

Learnt from: PupilTong
PR: #1029
File: packages/web-platform/web-mainthread-apis/src/createMainThreadGlobalThis.ts:214-217
Timestamp: 2025-07-16T06:25:41.024Z
Learning: In the lynx-stack codebase, CSS strings produced by genCssContent are considered trusted developer input, so additional sanitization/escaping is not required.

🧬 Code Graph Analysis (3)
packages/third-party/tailwind-preset/src/__tests__/plugins/transitionTimingFunction.test.ts (2)
packages/third-party/tailwind-preset/src/__tests__/utils/run-plugin.ts (1)
  • runPlugin (28-62)
packages/third-party/tailwind-preset/src/plugins/lynx/transitionTimingFunction.ts (1)
  • transitionTimingFunction (8-39)
packages/third-party/tailwind-preset/src/types/theme-types.ts (1)
packages/third-party/tailwind-preset/src/types/tailwind-types.ts (3)
  • ThemeConfig (28-28)
  • ResolvableTo (29-29)
  • KeyValuePair (27-27)
packages/third-party/tailwind-preset/src/theme.ts (1)
packages/third-party/tailwind-preset/src/types/theme-types.ts (1)
  • LynxThemeConfig (38-38)
🔇 Additional comments (23)
packages/third-party/tailwind-preset/src/plugin-utils/index.ts (1)

5-5: LGTM! Clean export addition.

The new export follows the existing pattern and integrates well with the module structure to support the transition plugins functionality.

packages/third-party/tailwind-preset/src/types/index.d.ts (1)

6-6: LGTM! Consistent type export addition.

The new export follows the established pattern and properly integrates the theme types into the public API alongside existing type exports.

packages/third-party/tailwind-preset/src/plugins/lynx/index.ts (1)

32-35: LGTM! Well-organized transition plugin exports.

The new transition plugin exports follow the established pattern and logically group related functionality. These additions align with the PR objective to address Lynx's transition timing value expansion limitations.

.changeset/rich-eels-cheat.md (1)

1-8: LGTM! Clear and comprehensive changeset documentation.

The changeset accurately describes the new scoped timing utilities and provides helpful examples. The patch version bump is appropriate for this additive change.

packages/third-party/tailwind-preset/src/core.ts (1)

95-98: LGTM! Proper core plugin deactivation.

Commenting out the default core transition plugins prevents conflicts with the new enhanced transition plugins while maintaining clear documentation of what was changed. This ensures the custom plugins with grouped property support take precedence.

packages/third-party/tailwind-preset/src/__tests__/utils/run-plugin.ts (1)

55-55: LGTM - Good refactoring to centralize theme handling

This change simplifies the API construction by delegating theme value lookup to the enhanced mockPluginAPI function, reducing code duplication and improving maintainability.

packages/third-party/tailwind-preset/src/__tests__/plugins/transitionTimingFunction.test.ts (1)

1-71: LGTM - Comprehensive test coverage for transition timing function plugin

The test structure is well-designed with:

  • Proper theme configuration setup
  • Comprehensive coverage of all utility variants
  • Validation of both invalid and valid inputs
  • Correct assertion of grouped timing function repetition

The test effectively validates the plugin's behavior for scoped transition timing utilities.

packages/third-party/tailwind-preset/src/__tests__/plugins/tranitionDelay.test.ts (1)

9-70: LGTM - Well-structured test for transition delay plugin

The test provides comprehensive coverage of the transitionDelay plugin functionality:

  • Validates invalid input handling
  • Tests single delay values
  • Verifies grouped delay repetition based on property counts
  • Follows consistent testing patterns with other transition plugins

The test logic correctly validates the plugin's behavior for scoped transition delay utilities.

packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDuration.test.ts (1)

1-72: LGTM - Comprehensive test coverage for transition duration plugin

The test provides excellent coverage of the transitionDuration plugin:

  • Validates invalid input handling returning null
  • Tests single duration values
  • Verifies grouped duration repetition based on property counts
  • Tests fallback behavior for duration-repeat utility
  • Maintains consistency with other transition plugin test patterns

The test effectively validates all branches of the plugin's functionality.

packages/third-party/tailwind-preset/src/__tests__/utils/mock-api.ts (2)

34-34: LGTM - Good addition of optional theme values parameter

Adding the optional themeVals parameter with a sensible default enables theme-based testing while maintaining backward compatibility.


46-62: LGTM - Excellent implementation of deep theme value lookup

The enhanced theme method implementation provides:

  • Dot-notation path navigation (e.g., "transitionProperty.colors")
  • Robust null/undefined checking during traversal
  • Proper fallback to default values
  • Type safety with generics

This enhancement enables realistic theme-based testing for the new transition plugins while maintaining the existing API contract.

packages/third-party/tailwind-preset/src/plugins/lynx/transitionTimingFunction.ts (1)

1-39: LGTM! Well-structured transition timing function plugin.

The plugin implementation correctly follows the established pattern for transition utilities. The use of createRepeaterUtility with appropriate matchValue configurations for different property groups (colors, visual, effects) aligns well with the PR objective of providing scoped timing utilities. The filtering of the DEFAULT key from theme values is also handled properly.

packages/third-party/tailwind-preset/src/plugins/lynx/transitionProperty.ts (1)

16-42: LGTM! Solid transition property utility implementation.

The utility correctly validates inputs, handles the coordination between transition-property, transition-duration, and transition-timing-function, and uses the createRepeaterUtility appropriately to match timing values with property groups. The error handling by returning null for invalid inputs is appropriate.

packages/third-party/tailwind-preset/src/plugins/lynx/transitionDuration.ts (1)

1-37: LGTM! Consistent implementation following established pattern.

The plugin implementation maintains excellent consistency with the other transition plugins. The utility naming (duration, duration-colors, etc.) clearly indicates their purpose, and the use of createRepeaterUtility with appropriate matchValue configurations correctly handles grouped transition properties.

packages/third-party/tailwind-preset/src/__tests__/plugin-utils/create-repeater-utility.test.ts (1)

1-92: LGTM! Comprehensive test coverage for the utility function.

The test suite provides excellent coverage of the createRepeaterUtility function, including edge cases, error conditions, and custom delimiter support. The tests clearly verify the expected behavior for both count-based and matchValue-based repetition, as well as proper error handling for invalid inputs.

packages/third-party/tailwind-preset/src/plugins/lynx/transitionDelay.ts (1)

1-37: LGTM! Completes the transition plugin set with consistent implementation.

This plugin maintains perfect consistency with the other transition plugins (duration, timing function, property), using the same patterns for utility creation and theme value handling. The complete set of delay, delay-colors, delay-visual, and delay-effects utilities provides the necessary scoped timing controls mentioned in the PR objectives.

packages/third-party/tailwind-preset/src/__tests__/plugins/transitionProperty.test.ts (1)

9-93: Excellent comprehensive test coverage.

The test suite thoroughly covers all expected behaviors of the transitionProperty plugin, including edge cases like CSS variables, complex nested values, and invalid inputs. The test structure is well-organized and validates the core functionality of automatic value repetition for transition properties.

packages/third-party/tailwind-preset/src/types/theme-types.ts (2)

10-22: Well-structured theme type overrides.

The LynxThemeOverrides type cleanly picks specific theme keys that need Lynx-specific behavior, particularly the transition-related properties that align with this PR's objectives for scoped transition utilities.


24-35: Excellent extensibility design.

The extension mechanism through LynxTailwindEarlyAdoption and LynxCustomFields provides a clean way to add new theme properties while maintaining type safety. The intersection type properly combines all theme components.

packages/third-party/tailwind-preset/src/plugin-utils/create-repeater-utility.ts (1)

58-68: Fix inconsistent count validation logic.

There's an inconsistency in the count validation: line 59 allows count >= 1 but line 65 rejects repeatCount < 1. Since a count of 1 is valid (single property), the validation should be consistent.

Apply this fix:

  const repeatCount =
    typeof count === 'number' && Number.isFinite(count) && count >= 1
      ? count
      : valuesFromMatchValue?.length ?? null;

  if (
-    !property || typeof property !== 'string' || typeof repeatCount !== 'number'
-    || repeatCount < 1
+    !property || typeof property !== 'string' || typeof repeatCount !== 'number'
+    || repeatCount < 1
  ) {

Wait, actually the logic is correct. The issue is that if repeatCount < 1 (which can happen when valuesFromMatchValue?.length is 0), we should return the null function. Let me reconsider...

Actually, the logic is fine. If count >= 1, it's valid. If we fall back to valuesFromMatchValue?.length and that's 0 or undefined, repeatCount becomes 0 or null, and repeatCount < 1 correctly catches this.

Likely an incorrect or invalid review comment.

packages/third-party/tailwind-preset/src/theme.ts (3)

4-6: Proper type migration to Lynx-specific theme config.

The import and type annotation changes correctly migrate from the generic StrictThemeConfig to the Lynx-specific LynxThemeConfig, which provides better type safety for Lynx-specific theme properties.


92-106: Well-designed transition property groups.

The transitionProperty configuration effectively groups related properties (colors, visual, effects) while excluding Lynx-unsupported properties like box-shadow and text-decoration-color. The property groups align perfectly with the PR's goal of providing scoped transition utilities.


107-125: Comprehensive transition timing configurations.

The new transitionDuration and transitionTimingFunction sections provide excellent coverage of timing options, from quick 75ms animations to longer 1000ms transitions, plus standard easing curves with proper cubic-bezier definitions.

Copy link
Contributor

@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: 1

🧹 Nitpick comments (1)
packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts (1)

27-40: Consider extracting utility extraction logic into a test helper.

The utility extraction logic from mocked matchUtilities calls is complex and could be reused across other transition plugin tests. This pattern would benefit from being extracted into a reusable test utility function.

Consider creating a helper function:

// In test utils
function extractUtilitiesFromMockCalls(matchUtilities: any): Record<string, UtilityFn> {
  return matchUtilities.mock.calls.reduce<Record<string, UtilityFn>>(
    (acc, call) => {
      const group = call[0] as Record<string, UtilityFn>;
      for (const key in group) {
        acc[key] = group[key]!;
      }
      return acc;
    },
    {},
  );
}

Then use it in the test:

-    const utils = matchUtilities.mock.calls.reduce<Record<string, UtilityFn>>(
-      (acc, call) => {
-        const group = call[0] as Record<string, UtilityFn>;
-        for (const key in group) {
-          acc[key] = group[key]!;
-        }
-        return acc;
-      },
-      {},
-    );
+    const utils = extractUtilitiesFromMockCalls(matchUtilities);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7df256c and 6241e25.

📒 Files selected for processing (1)
  • packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts (1 hunks)
🔇 Additional comments (5)
packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts (5)

1-8: LGTM! Clean imports and proper test setup.

The imports are well-structured with proper separation between third-party testing utilities and local modules.


42-46: Good coverage of invalid input scenarios.

The test properly validates that invalid inputs (null, false, number) return null, which is important for robust error handling.


47-50: LGTM! Basic delay utility test is correct.

The basic delay utility test correctly validates that a single delay value is applied without repetition.


52-63: No changes needed: transition delay repetitions are correct.

Manual count of properties confirms 2 colors (color, background-color), 3 visual (opacity, visibility, transform), and 2 effects (box-shadow, filter), matching the test expectations.


11-25: No action required: test’s custom theme values are intentional
The test deliberately stubs transitionProperty with its own placeholder values to verify that the plugin correctly reads whatever is passed in via theme(). It isn’t meant to mirror the real defaults in theme.ts, so there’s no need to sync those values.

Likely an incorrect or invalid review comment.

@codspeed-hq
Copy link

codspeed-hq bot commented Jul 21, 2025

CodSpeed Performance Report

Merging #1324 will not alter performance

Comparing Dugyu:feat/transition-property-expansion (8ff850b) with main (629d422)

Summary

✅ 10 untouched benchmarks

@relativeci
Copy link

relativeci bot commented Jul 21, 2025

Web Explorer

#3262 Bundle Size — 304.52KiB (0%).

8ff850b(current) vs 629d422 main#3248(baseline)

Bundle metrics  Change 2 changes
                 Current
#3262
     Baseline
#3248
No change  Initial JS 140.65KiB 140.65KiB
No change  Initial CSS 31.83KiB 31.83KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 4 4
No change  Assets 5 5
Change  Modules 204(-0.49%) 205
No change  Duplicate Modules 17 17
Change  Duplicate Code 4.23%(+0.24%) 4.22%
No change  Packages 3 3
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#3262
     Baseline
#3248
No change  JS 221.88KiB 221.88KiB
No change  Other 50.82KiB 50.82KiB
No change  CSS 31.83KiB 31.83KiB

Bundle analysis reportBranch Dugyu:feat/transition-property-e...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link

relativeci bot commented Jul 21, 2025

React Example

#3272 Bundle Size — 234.97KiB (0%).

8ff850b(current) vs 629d422 main#3258(baseline)

Bundle metrics  no changes
                 Current
#3272
     Baseline
#3258
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 0% 37.9%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 156 156
No change  Duplicate Modules 63 63
No change  Duplicate Code 45.95% 45.95%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#3272
     Baseline
#3258
No change  IMG 145.76KiB 145.76KiB
No change  Other 89.22KiB 89.22KiB

Bundle analysis reportBranch Dugyu:feat/transition-property-e...Project dashboard


Generated by RelativeCIDocumentationReport issue

@codecov
Copy link

codecov bot commented Jul 22, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Copy link
Contributor

@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/third-party/tailwind-preset/src/plugin-utils/is-plain-indent-list.ts (1)

1-52: LGTM! Well-implemented utility with excellent documentation.

The function logic is sound and the comprehensive JSDoc documentation with examples makes the intent and usage clear. The regex pattern appropriately validates simple CSS identifiers while avoiding complex cases like functions or custom properties.

Minor: Filename inconsistency

The filename uses is-plain-indent-list.ts but the function is isPlainIdentList - there's a typo in the filename (indent vs ident). Consider renaming the file to is-plain-ident-list.ts for consistency.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f72a668 and fafab9e.

📒 Files selected for processing (13)
  • .changeset/rich-eels-cheat.md (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugin-utils/create-repeater-utility.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugin-utils/get-modifier-repeater-map.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/create-function-call-utility.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/create-repeater-utility.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/create-transition-timing-plugin.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/get-modifier-repeater-map.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/index.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/is-plain-indent-list.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDelay.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDuration.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionProperty.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionTimingFunction.ts (1 hunks)
🧠 Learnings (4)
📓 Common learnings
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.
Learnt from: PupilTong
PR: lynx-family/lynx-stack#1029
File: packages/web-platform/web-core/src/uiThread/createRenderAllOnUI.ts:95-99
Timestamp: 2025-07-16T06:28:26.421Z
Learning: In the lynx-stack codebase, CSS selectors in SSR hydration are generated by their own packages, ensuring a predictable format that makes simple string manipulation safe and preferable over regex for performance reasons.
packages/third-party/tailwind-preset/src/__tests__/plugin-utils/get-modifier-repeater-map.test.ts (1)

Learnt from: Dugyu
PR: #1324
File: packages/third-party/tailwind-preset/src/tests/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.

packages/third-party/tailwind-preset/src/plugin-utils/create-transition-timing-plugin.ts (2)

Learnt from: Dugyu
PR: #1324
File: packages/third-party/tailwind-preset/src/tests/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.

Learnt from: Dugyu
PR: #1324
File: packages/third-party/tailwind-preset/src/tests/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.

packages/third-party/tailwind-preset/src/plugin-utils/get-modifier-repeater-map.ts (1)

Learnt from: Dugyu
PR: #1324
File: packages/third-party/tailwind-preset/src/tests/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.

🧬 Code Graph Analysis (1)
packages/third-party/tailwind-preset/src/plugin-utils/is-plain-indent-list.ts (1)
packages/third-party/tailwind-preset/src/plugin-utils/index.ts (1)
  • isPlainIdentList (7-7)
✅ Files skipped from review due to trivial changes (2)
  • packages/third-party/tailwind-preset/src/plugin-utils/create-function-call-utility.ts
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDuration.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionTimingFunction.ts
  • .changeset/rich-eels-cheat.md
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDelay.ts
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionProperty.ts
  • packages/third-party/tailwind-preset/src/tests/plugin-utils/create-repeater-utility.test.ts
  • packages/third-party/tailwind-preset/src/plugin-utils/create-repeater-utility.ts
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.
Learnt from: PupilTong
PR: lynx-family/lynx-stack#1029
File: packages/web-platform/web-core/src/uiThread/createRenderAllOnUI.ts:95-99
Timestamp: 2025-07-16T06:28:26.421Z
Learning: In the lynx-stack codebase, CSS selectors in SSR hydration are generated by their own packages, ensuring a predictable format that makes simple string manipulation safe and preferable over regex for performance reasons.
packages/third-party/tailwind-preset/src/__tests__/plugin-utils/get-modifier-repeater-map.test.ts (1)

Learnt from: Dugyu
PR: #1324
File: packages/third-party/tailwind-preset/src/tests/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.

packages/third-party/tailwind-preset/src/plugin-utils/create-transition-timing-plugin.ts (2)

Learnt from: Dugyu
PR: #1324
File: packages/third-party/tailwind-preset/src/tests/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.

Learnt from: Dugyu
PR: #1324
File: packages/third-party/tailwind-preset/src/tests/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.

packages/third-party/tailwind-preset/src/plugin-utils/get-modifier-repeater-map.ts (1)

Learnt from: Dugyu
PR: #1324
File: packages/third-party/tailwind-preset/src/tests/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.374Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.

🧬 Code Graph Analysis (1)
packages/third-party/tailwind-preset/src/plugin-utils/is-plain-indent-list.ts (1)
packages/third-party/tailwind-preset/src/plugin-utils/index.ts (1)
  • isPlainIdentList (7-7)
🔇 Additional comments (4)
packages/third-party/tailwind-preset/src/plugin-utils/index.ts (1)

5-7: LGTM! Clean addition of new utility exports.

The new exports follow established naming conventions and integrate well with the existing module structure. These utilities support the transition timing functionality described in the PR objectives.

packages/third-party/tailwind-preset/src/plugin-utils/create-transition-timing-plugin.ts (1)

8-33: LGTM! Well-structured plugin factory function.

The implementation correctly:

  • Uses the established plugin creation pattern
  • Retrieves theme values appropriately
  • Leverages the getModifierRepeaterMap utility with sensible options
  • Filters out the 'DEFAULT' modifier from timing values, which is appropriate since timing values typically don't need a default modifier

The skipIfSingleProperty: true option aligns well with the retrieved learning that DEFAULT typically contains the maximum number of properties.

packages/third-party/tailwind-preset/src/__tests__/plugin-utils/get-modifier-repeater-map.test.ts (1)

8-80: Excellent comprehensive test coverage!

The test suite thoroughly covers all key scenarios:

  • Base utility generation
  • Repeated modifier behavior (when provided/omitted)
  • Named modifier utilities for multi-property groups
  • skipIfSingleProperty option behavior
  • Custom delimiter support

The test data is well-designed, including edge cases like empty strings and single properties. The DEFAULT configuration with 5 properties aligns with the retrieved learning about it typically containing the maximum number of properties.

packages/third-party/tailwind-preset/src/plugin-utils/get-modifier-repeater-map.ts (1)

10-72: LGTM! Well-architected utility function with excellent documentation.

The implementation demonstrates good design principles:

  • Clear separation of DEFAULT vs named modifiers
  • Proper conditional logic for optional repeated modifier
  • Consistent use of the createRepeaterUtility abstraction
  • Appropriate null-checking for utility creation
  • Comprehensive JSDoc documentation

The function correctly handles all the requirements for generating scoped transition timing utilities as described in the PR objectives.

…ransition property matching from theme values
@Dugyu Dugyu force-pushed the feat/transition-property-expansion branch from fafab9e to 73b1a03 Compare July 23, 2025 05:35
Copy link
Contributor

@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/third-party/tailwind-preset/src/plugin-utils/is-plain-ident-list.ts (1)

45-45: Consider CSS identifier compliance for hyphen prefix.

The regex pattern allows identifiers to start with a hyphen (-), which violates standard CSS identifier rules. CSS identifiers typically cannot start with a single hyphen unless it's part of a vendor prefix (like -webkit-) or custom property.

However, given the documented trade-off for "simplicity and predictability in the context of Tailwind-style theming," this may be acceptable if the theme configuration is controlled and doesn't include such edge cases.

If stricter CSS compliance is desired, consider:

-  const identPattern = /^[a-z_-][\w-]*$/i;
+  const identPattern = /^[a-z_][\w-]*$/i;
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fafab9e and 73b1a03.

📒 Files selected for processing (14)
  • .changeset/rich-eels-cheat.md (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugin-utils/create-repeater-utility.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugin-utils/get-modifier-repeater-map.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/__tests__/plugins/transitionProperty.test.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/create-function-call-utility.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/create-repeater-utility.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/create-transition-timing-plugin.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/get-modifier-repeater-map.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/index.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugin-utils/is-plain-ident-list.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDelay.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDuration.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionProperty.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionTimingFunction.ts (1 hunks)
🧠 Learnings (1)
📓 Common learnings
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.
🧬 Code Graph Analysis (1)
packages/third-party/tailwind-preset/src/plugin-utils/is-plain-ident-list.ts (1)
packages/third-party/tailwind-preset/src/plugin-utils/index.ts (1)
  • isPlainIdentList (7-7)
✅ Files skipped from review due to trivial changes (2)
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDuration.ts
  • packages/third-party/tailwind-preset/src/plugin-utils/create-transition-timing-plugin.ts
🚧 Files skipped from review as they are similar to previous changes (11)
  • packages/third-party/tailwind-preset/src/plugin-utils/create-function-call-utility.ts
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionDelay.ts
  • packages/third-party/tailwind-preset/src/tests/plugin-utils/get-modifier-repeater-map.test.ts
  • packages/third-party/tailwind-preset/src/tests/plugin-utils/create-repeater-utility.test.ts
  • packages/third-party/tailwind-preset/src/tests/plugins/transitionProperty.test.ts
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionTimingFunction.ts
  • packages/third-party/tailwind-preset/src/plugin-utils/get-modifier-repeater-map.ts
  • packages/third-party/tailwind-preset/src/plugins/lynx/transitionProperty.ts
  • packages/third-party/tailwind-preset/src/plugin-utils/create-repeater-utility.ts
  • packages/third-party/tailwind-preset/src/plugin-utils/index.ts
  • .changeset/rich-eels-cheat.md
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.
🧬 Code Graph Analysis (1)
packages/third-party/tailwind-preset/src/plugin-utils/is-plain-ident-list.ts (1)
packages/third-party/tailwind-preset/src/plugin-utils/index.ts (1)
  • isPlainIdentList (7-7)
🔇 Additional comments (4)
packages/third-party/tailwind-preset/src/plugin-utils/is-plain-ident-list.ts (4)

1-4: LGTM!

Standard copyright header follows the expected format.


5-39: Excellent documentation!

The JSDoc is comprehensive and clearly explains the function's purpose, limitations, and trade-offs. The examples are particularly helpful for understanding the expected behavior.


41-44: Clean function signature!

The parameter names are descriptive, and the default delimiter value is appropriate for the use case.


47-52: Solid implementation with good edge case handling!

The function correctly handles whitespace trimming, empty segments, and validates each identifier. The functional programming approach with method chaining makes the logic clear and readable.

@Dugyu
Copy link
Collaborator Author

Dugyu commented Jul 23, 2025

Actionable comments posted: 0

🧹 Nitpick comments (1)

packages/third-party/tailwind-preset/src/plugin-utils/is-plain-ident-list.ts (1)> 45-45: Consider CSS identifier compliance for hyphen prefix.

The regex pattern allows identifiers to start with a hyphen (-), which violates standard CSS identifier rules. CSS identifiers typically cannot start with a single hyphen unless it's part of a vendor prefix (like -webkit-) or custom property.
However, given the documented trade-off for "simplicity and predictability in the context of Tailwind-style theming," this may be acceptable if the theme configuration is controlled and doesn't include such edge cases.
If stricter CSS compliance is desired, consider:

-  const identPattern = /^[a-z_-][\w-]*$/i;
+  const identPattern = /^[a-z_][\w-]*$/i;

📜 Review details

We're intentionally using a more permissive pattern to support Tailwind-style theming and platform-specific properties on Lynx such as -x-handle-color.

Copy link
Contributor

@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: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73b1a03 and 4159f51.

📒 Files selected for processing (4)
  • packages/third-party/tailwind-preset/src/core.ts (4 hunks)
  • packages/third-party/tailwind-preset/src/lynx.ts (2 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts (1 hunks)
  • packages/third-party/tailwind-preset/src/plugins/lynx/plugin-types.ts (1 hunks)
🧠 Learnings (3)
📓 Common learnings
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.
packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts (2)

Learnt from: PupilTong
PR: #1029
File: packages/web-platform/web-core/src/uiThread/createRenderAllOnUI.ts:95-99
Timestamp: 2025-07-16T06:28:26.463Z
Learning: In the lynx-stack codebase, CSS selectors in SSR hydration are generated by their own packages, ensuring a predictable format that makes simple string manipulation safe and preferable over regex for performance reasons.

Learnt from: colinaaa
PR: #1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:23:07.797Z
Learning: In the lynx-family/lynx-stack repository, changesets are only required for meaningful changes to end-users such as bugfixes and features. Internal/development changes like chores, refactoring, or removing debug info do not need changeset entries.

packages/third-party/tailwind-preset/src/lynx.ts (3)

Learnt from: PupilTong
PR: #1029
File: packages/web-platform/web-core/src/uiThread/createRenderAllOnUI.ts:95-99
Timestamp: 2025-07-16T06:28:26.463Z
Learning: In the lynx-stack codebase, CSS selectors in SSR hydration are generated by their own packages, ensuring a predictable format that makes simple string manipulation safe and preferable over regex for performance reasons.

Learnt from: colinaaa
PR: #1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:23:07.797Z
Learning: In the lynx-family/lynx-stack repository, changesets are only required for meaningful changes to end-users such as bugfixes and features. Internal/development changes like chores, refactoring, or removing debug info do not need changeset entries.

Learnt from: colinaaa
PR: #1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:26:16.722Z
Learning: In the lynx-family/lynx-stack repository, CI checks require changesets when files matching the pattern "src/**" are modified (as configured in .changeset/config.json). For internal changes that don't need meaningful changesets, an empty changeset file is used to satisfy the CI requirement while not generating any release notes.

🧬 Code Graph Analysis (2)
packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts (4)
packages/third-party/tailwind-preset/src/plugins/lynx/plugin-types.ts (1)
  • LynxPluginName (6-6)
packages/third-party/tailwind-preset/src/lynx.ts (1)
  • LynxPluginName (58-58)
packages/third-party/tailwind-preset/src/core.ts (3)
  • LynxPluginName (183-183)
  • LYNX_PLUGIN_MAP (185-185)
  • ORDERED_LYNX_PLUGIN_NAMES (185-185)
packages/react/transform/src/swc_plugin_css_scope/mod.rs (1)
  • n (152-164)
packages/third-party/tailwind-preset/src/lynx.ts (1)
packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts (2)
  • ORDERED_LYNX_PLUGIN_NAMES (72-73)
  • LYNX_PLUGIN_MAP (69-70)
✅ Files skipped from review due to trivial changes (1)
  • packages/third-party/tailwind-preset/src/plugins/lynx/plugin-types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/third-party/tailwind-preset/src/core.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: In Lynx tailwind preset transition utilities, transitionProperty.DEFAULT is typically the group that contains the maximum number of transition properties, making utilities like delay-repeat, duration-repeat, and ease-repeat repeat values for the most comprehensive set of properties.
Learnt from: Dugyu
PR: lynx-family/lynx-stack#1324
File: packages/third-party/tailwind-preset/src/__tests__/plugins/transitionDelay.test.ts:65-67
Timestamp: 2025-07-21T13:03:54.408Z
Learning: Tailwind's default transitionProperty.DEFAULT configuration includes: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter - not 'all'.
packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts (2)

Learnt from: PupilTong
PR: #1029
File: packages/web-platform/web-core/src/uiThread/createRenderAllOnUI.ts:95-99
Timestamp: 2025-07-16T06:28:26.463Z
Learning: In the lynx-stack codebase, CSS selectors in SSR hydration are generated by their own packages, ensuring a predictable format that makes simple string manipulation safe and preferable over regex for performance reasons.

Learnt from: colinaaa
PR: #1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:23:07.797Z
Learning: In the lynx-family/lynx-stack repository, changesets are only required for meaningful changes to end-users such as bugfixes and features. Internal/development changes like chores, refactoring, or removing debug info do not need changeset entries.

packages/third-party/tailwind-preset/src/lynx.ts (3)

Learnt from: PupilTong
PR: #1029
File: packages/web-platform/web-core/src/uiThread/createRenderAllOnUI.ts:95-99
Timestamp: 2025-07-16T06:28:26.463Z
Learning: In the lynx-stack codebase, CSS selectors in SSR hydration are generated by their own packages, ensuring a predictable format that makes simple string manipulation safe and preferable over regex for performance reasons.

Learnt from: colinaaa
PR: #1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:23:07.797Z
Learning: In the lynx-family/lynx-stack repository, changesets are only required for meaningful changes to end-users such as bugfixes and features. Internal/development changes like chores, refactoring, or removing debug info do not need changeset entries.

Learnt from: colinaaa
PR: #1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:26:16.722Z
Learning: In the lynx-family/lynx-stack repository, CI checks require changesets when files matching the pattern "src/**" are modified (as configured in .changeset/config.json). For internal changes that don't need meaningful changesets, an empty changeset file is used to satisfy the CI requirement while not generating any release notes.

🧬 Code Graph Analysis (2)
packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts (4)
packages/third-party/tailwind-preset/src/plugins/lynx/plugin-types.ts (1)
  • LynxPluginName (6-6)
packages/third-party/tailwind-preset/src/lynx.ts (1)
  • LynxPluginName (58-58)
packages/third-party/tailwind-preset/src/core.ts (3)
  • LynxPluginName (183-183)
  • LYNX_PLUGIN_MAP (185-185)
  • ORDERED_LYNX_PLUGIN_NAMES (185-185)
packages/react/transform/src/swc_plugin_css_scope/mod.rs (1)
  • n (152-164)
packages/third-party/tailwind-preset/src/lynx.ts (1)
packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts (2)
  • ORDERED_LYNX_PLUGIN_NAMES (72-73)
  • LYNX_PLUGIN_MAP (69-70)
🔇 Additional comments (5)
packages/third-party/tailwind-preset/src/lynx.ts (2)

6-11: LGTM! Clean import refactoring to support centralized plugin management.

The imports are well-organized and properly align with the new plugin registry system being introduced.


35-41: Excellent improvement to ensure deterministic plugin ordering.

The change from iterating over an unordered set to the ordered ORDERED_LYNX_PLUGIN_NAMES array is crucial for consistent CSS output and proper dependency resolution between plugins. The explicit skip of the 'defaults' plugin is correct since it's already added initially at line 33.

This change directly addresses the transition plugin dependencies mentioned in the plugin registry, where timing utilities depend on property utilities being registered first.

packages/third-party/tailwind-preset/src/plugins/lynx/plugin-registry.ts (3)

9-23: Excellent documentation explaining the plugin ordering rationale.

The comprehensive comments clearly explain why plugin execution order matters, specifically highlighting the transition plugin dependencies that are central to this PR. The documentation covers all key benefits: deterministic CSS output, maintainability, and user flexibility.


26-65: Well-organized plugin entries with logical grouping and correct ordering.

The plugin entries follow a logical flow from core display/positioning utilities to transforms, layout, styling, and finally transitions. The transition plugins are correctly placed at the end to satisfy the dependency requirements where transitionProperty must be registered before timing utilities. The as const assertion ensures proper type safety.


69-76: Well-implemented derived constants with clear purposes.

The three derived constants are correctly implemented:

  • LYNX_PLUGIN_MAP provides O(1) plugin lookup with proper type safety
  • ORDERED_LYNX_PLUGIN_NAMES preserves the registration order for iteration
  • REPLACEABLE_LYNX_PLUGINS correctly excludes the always-required 'defaults' plugin

Each constant serves a specific purpose in the plugin system architecture.

@Dugyu Dugyu requested a review from upupming July 23, 2025 09:41
@Dugyu Dugyu force-pushed the feat/transition-property-expansion branch from 4159f51 to 1f285ee Compare July 23, 2025 09:46
@Dugyu Dugyu force-pushed the feat/transition-property-expansion branch from 1f285ee to 8ff850b Compare July 23, 2025 10:11
@Dugyu Dugyu requested a review from Huxpro July 24, 2025 02:01
Copy link
Collaborator

@upupming upupming left a comment

Choose a reason for hiding this comment

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

LGTM! We may need to update the docs at: https://lynxjs.org/rspeedy/styling.html#using-tailwind-css to add a new table like https://v3.tailwindcss.com/docs/transition-property, however we can do it ater this merged!

@Dugyu Dugyu added this pull request to the merge queue Jul 24, 2025
Merged via the queue into lynx-family:main with commit a6230e2 Jul 24, 2025
48 checks passed
@Dugyu Dugyu deleted the feat/transition-property-expansion branch July 24, 2025 04:01
colinaaa pushed a commit that referenced this pull request Jul 28, 2025
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @lynx-js/[email protected]

### Minor Changes

- feat: Force synchronous rendering for background initial renders to
support Suspense fallbacks
([#1323](#1323))

- Introduces `@lynx-js/react/compat` submodule exporting Preact
implementations of:
([#1316](#1316))

    -   `startTransition`
    -   `useTransition`

### Patch Changes

- fix: Ensure useEffect callbacks execute before event handlers from the
same render cycle
([#1348](#1348))

- Enable rendering of the `Suspense` fallback on initial render.
([#1285](#1285))

- fix: Prevent "cannot set property 'current' of undefined" error thrown
by MainThreadRef on engine data updates
([#1342](#1342))

## @lynx-js/[email protected]

### Patch Changes

- Should be able to override `performance.profile` when `DEBUG=rspeedy`.
([#1307](#1307))

## @lynx-js/[email protected]

### Patch Changes

- Be compat with `@lynx-js/react` v0.112.0
([#1323](#1323))

- Fix not having profile in development by default.
([#1306](#1306))

- Updated dependencies
\[[`fcafd54`](fcafd54),
[`fe38de5`](fe38de5),
[`7cd5ea2`](7cd5ea2)]:
    -   @lynx-js/[email protected]
    -   @lynx-js/[email protected]
    -   @lynx-js/[email protected]
    -   @lynx-js/[email protected]

## @lynx-js/[email protected]

### Patch Changes

- Add alias for `@lynx-js/react/compat`.
([#1316](#1316))

## @lynx-js/[email protected]

### Patch Changes

- Fix the thread switching bug in `lynx.getCoreContext` and
`lynx.getJSContext`.
([#1244](#1244))

## @lynx-js/[email protected]

### Patch Changes

- Improve transform transition compatibility with Lynx versions that do
not support animating CSS variables.
([#1320](#1320))

- Added Lynx specific solo transform utilities that avoid CSS variables:
`solo-translate-x-*`, `solo-scale-*`, `solo-rotate-*` etc. These
utilities are implemented without CSS variables using raw transform
functions such as `translateX()`, `scale()` and `rotate()`. They are
mutually exclusive and cannot be combined with normal transform
utilities.

- Enabled arbitrary values for `transform-[...]`: e.g.
`transform-[translateX(20px)_rotate(10deg)]`, following Tailwind v4
behavior.

- Fix `scale-*` utilities not supporting negative values. Now supports
`-scale-x-100`, `-scale-y-50` as expected.
([#1320](#1320))

- Add filter utilities: `blur-*`, `grayscale-*`.
([#1345](#1345))

- Note: On Lynx, filter functions are mutually exclusive, only one can
be active at a time.

- Introduce scoped timing utilities with auto-derived repeat count for
grouped transition properties, working around Lynx's lack of automatic
value expansion.
([#1324](#1324))

- Scoped utilities like `duration-colors-*`, `ease-colors-*`, and
`delay-colors-*` are generated when `transitionProperty.colors` contains
multiple properties.

- Scoped utilities like `duration-n-*`, `ease-n-*`,`delay-n-*` are
generated when the `transitionProperty.DEFAULT` group contains multiple
properties.

- For single-property transitions (e.g., `transition-opacity`,
`transition-transform`), you must use Tailwind's default `duration-*`,
`ease-*`, and `delay-*` utilities, no scoped timing utilities will be
generated in these cases.

## @lynx-js/[email protected]

### Patch Changes

- fix: improve compatibility with legacy template
([#1337](#1337))

    avoid "object Object" error for old version rspeedy outputs

-   Updated dependencies \[]:
    -   @lynx-js/[email protected]

## @lynx-js/[email protected]

### Patch Changes

- fix: improve compatibility with legacy template
([#1337](#1337))

    avoid "object Object" error for old version rspeedy outputs

- Updated dependencies
\[[`0da5ef0`](0da5ef0)]:
    -   @lynx-js/[email protected]
    -   @lynx-js/[email protected]
    -   @lynx-js/[email protected]
    -   @lynx-js/[email protected]

## @lynx-js/[email protected]

### Patch Changes

- Add crossorigin attribute support to x-image component
([#1340](#1340))

- Added `crossorigin` to the `observedAttributes` array in `ImageSrc.ts`
- Implemented `#handleCrossorigin` handler using the `bindToAttribute`
helper to forward the crossorigin attribute from the custom element to
the internal `<img>` element
- Added comprehensive test coverage to verify the attribute is properly
passed through to the shadow DOM

This enables CORS-enabled image loading when using `<x-image
crossorigin="anonymous">` or similar configurations.

-   Updated dependencies \[]:
    -   @lynx-js/[email protected]

## @lynx-js/[email protected]

### Patch Changes

- Updated dependencies
\[[`0da5ef0`](0da5ef0)]:
    -   @lynx-js/[email protected]

## @lynx-js/[email protected]

### Patch Changes

- Updated dependencies
\[[`0da5ef0`](0da5ef0)]:
    -   @lynx-js/[email protected]
    -   @lynx-js/[email protected]
    -   @lynx-js/[email protected]

## @lynx-js/[email protected]

### Patch Changes

- Be compat with `@lynx-js/react` v0.112.0
([#1323](#1323))

- Fix `REACT_PROFILE` not taking effect.
([#1306](#1306))

## [email protected]



## [email protected]



## @lynx-js/[email protected]



## @lynx-js/[email protected]



## @lynx-js/[email protected]

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants