Skip to content

Feat: rules.with() API implement #234 #242

Merged
github-actions[bot] merged 2 commits intomainfrom
css-rule-with
Sep 28, 2025
Merged

Feat: rules.with() API implement #234 #242
github-actions[bot] merged 2 commits intomainfrom
css-rule-with

Conversation

@black7375
Copy link
Contributor

@black7375 black7375 commented Sep 28, 2025

Description

Implement rules.with() API

Related Issue

Summary by CodeRabbit

  • New Features
    • Added rules.with() to compose and transform rule sets via callbacks.
    • Added a unified css export that bundles the primary CSS function with helpers (raw, multiple, with).
  • Refactor
    • Consolidated CSS utilities under a single callable export for simpler imports and discovery.
    • Relaxed generics for multi-variant mapping to improve type ergonomics for consumers.
  • Chores
    • Bumped @mincho-js/css in a minor release to publish the expanded API.

Additional context

Checklist

@changeset-bot
Copy link

changeset-bot bot commented Sep 28, 2025

🦋 Changeset detected

Latest commit: aafcd1c

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

This PR includes changesets to release 4 packages
Name Type
@mincho-js/css Minor
@mincho-js/react Patch
@mincho-js/vite Patch
react-babel 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

coderabbitai bot commented Sep 28, 2025

Walkthrough

Adds a new rules.with() builder and exposes css.with by consolidating helpers (raw, multiple, with) onto the callable css and rules exports; broadens some generics and introduces internal type aliases to scope restricted rule typing. Changeset updated for a minor release.

Changes

Cohort / File(s) Summary
Release notes
\.changeset/eager-lemons-wink.md
Documents a minor version bump for @mincho-js/css and introduces the new rules.with() API.
CSS entrypoint consolidation
packages/css/src/css/index.ts
Re-exports a unified css object via Object.assign(cssImpl, { raw, multiple, with }) while keeping cssImpl. Adjusts cssWithMultiple generic constraint from (value: Data[Key], key: Key) to (value: Data[keyof Data], key: keyof Data). Adds internal RestrictedCSSRule alias and removes a redundant export block.
Rules API augmentation
packages/css/src/rules/index.ts
Augments rules with with via Object.assign(rulesImpl, { multiple, raw, with }). Adds rulesWith builder plus rulesWithImpl, rulesWithRaw, and rulesWithMultiple implementations, related type helpers, and branching for map-data vs single-rule inputs.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Dev as Consumer
  participant CSS as css (callable + helpers)
  participant Rules as rules (callable + helpers)
  participant Core as Internal helpers

  Note over CSS,Rules: New `with` helper attached to callable exports

  Dev->>CSS: css.with(config)(baseRule)
  CSS->>Core: cssWith → cssWithRaw / cssWithMultiple
  Core-->>Dev: composed RuntimeFn / rule

  Dev->>Rules: rules.with(transform)(options)
  Rules->>Core: rulesWith → rulesWithRaw / rulesWithMultiple
  Core-->>Dev: rule map / RuntimeFn
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

I hop through fields of tidy code,
A tiny with sprouts down the road.
Rules and css now hold my paw—
Helpers snug like thistle straw.
I munch a carrot, stamp and cheer, new APIs appear! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The description includes only a one-line statement and leaves the auto-generated summary placeholder, additional context, and checklist sections empty, failing to meet the repository’s template requirements for a comprehensive overview and reviewer guidance. Please expand the Description with implementation details, populate or remove the auto-generated summary placeholder, add any relevant context under Additional context, and complete the Checklist to guide reviewers.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly identifies the feature addition of the rules.with() API and references the related issue, clearly conveying the primary intent of the changeset.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch css-rule-with

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.

@github-actions
Copy link
Contributor

Triggered from #242 by @​black7375.

Checking if we can fast forward main (6f7b980) to css-rule-with (f360c85).

Target branch (main):

commit 6f7b9801c216a3ae4d7a2359a78bbad6427aa63b (HEAD -> main, origin/main)
Author: alstjr7375 <alstjr7375@daum.net>
Date:   Mon Jul 28 00:00:00 2025 +0900

    Feat: rulesVariant Funtion #154
    
    Co-authored-by: Jeong-jj <rgfdds98@gmail.com>

Pull request (css-rule-with):

commit f360c85c47b2c5ca9bb85e607a80453cc78fd478 (pull_request/css-rule-with)
Author: alstjr7375 <alstjr7375@daum.net>
Date:   Tue Jul 29 00:00:00 2025 +0900

    Feat: `rules.with()` API implement #234

It is possible to fast forward main (6f7b980) to css-rule-with (f360c85). If you have write access to the target repository, you can add a comment with /fast-forward to fast forward main to css-rule-with.

Copy link

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f7b980 and f360c85.

📒 Files selected for processing (3)
  • .changeset/eager-lemons-wink.md (1 hunks)
  • packages/css/src/css/index.ts (2 hunks)
  • packages/css/src/rules/index.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-09T13:00:38.449Z
Learnt from: black7375
PR: mincho-js/mincho#113
File: packages/css/src/index.ts:33-33
Timestamp: 2024-10-09T13:00:38.449Z
Learning: `recipe` is properly exported from './rules' in `packages/css/src/rules/index.ts`.

Applied to files:

  • packages/css/src/rules/index.ts
  • packages/css/src/css/index.ts
🧬 Code graph analysis (3)
.changeset/eager-lemons-wink.md (1)
packages/transform-to-vanilla/src/types/style-rule.ts (2)
  • CSSPropertiesWithConditions (45-47)
  • CSSPropertiesWithVars (49-52)
packages/css/src/rules/index.ts (7)
packages/css/src/compat.ts (13)
  • rules (42-42)
  • VariantGroups (32-32)
  • VariantDefinitions (37-37)
  • ComplexPropDefinitions (35-35)
  • PropTarget (36-36)
  • PatternOptions (33-33)
  • CSSRule (47-47)
  • CSSRuleWith (26-26)
  • RuntimeFn (31-31)
  • ConditionalVariants (38-38)
  • createVar (10-10)
  • fallbackVar (11-11)
  • css (23-23)
packages/css/src/rules/types.ts (9)
  • VariantGroups (52-52)
  • VariantDefinitions (43-43)
  • ComplexPropDefinitions (77-79)
  • PropTarget (75-75)
  • PatternOptions (179-194)
  • RuntimeFn (201-208)
  • ConditionalVariants (168-177)
  • PropDefinition (80-85)
  • RecipeStyleRule (31-31)
packages/transform-to-vanilla/src/types/style-rule.ts (3)
  • CSSRule (33-35)
  • PureCSSVarKey (129-129)
  • CSSPropertiesWithConditions (45-47)
packages/css/src/css/types.ts (1)
  • CSSRuleWith (9-23)
packages/transform-to-vanilla/src/utils/object.ts (1)
  • mergeObject (5-11)
packages/css/src/utils.ts (2)
  • getDebugName (13-15)
  • getVarName (20-29)
packages/css/src/css/index.ts (1)
  • css (105-109)
packages/css/src/css/index.ts (3)
packages/css/src/compat.ts (3)
  • css (23-23)
  • cssMultiple (24-24)
  • ComplexCSSRule (46-46)
packages/transform-to-vanilla/src/types/style-rule.ts (1)
  • ComplexCSSRule (26-26)
packages/transform-to-vanilla/src/transform.ts (1)
  • transform (16-42)
🪛 markdownlint-cli2 (0.18.1)
.changeset/eager-lemons-wink.md

5-5: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (3)
packages/css/src/css/index.ts (3)

115-118: LGTM: cssImpl remains the single execution path.

Calls transform then vStyle with debugId, consistent with existing usage and tests.


137-137: Good generic widening on css.with().multiple().

Using Data[keyof Data] and keyof Data aligns overloads with cssMultiple and improves inference for mixed key/value maps.


105-109: Drop the cssImpl wrapper; mutation is safe
cssImpl isn’t publicly exported, so Object.assign(cssImpl, …) can’t leak to consumers. Retain the warning about destructuring with—use css.with (or rename on import) instead.

Likely an incorrect or invalid review comment.

Comment on lines +5 to +8
**css**

## New
- Add `rules.with()` API No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix markdownlint MD036: use a heading instead of emphasis.

Switch the emphasized "css" line to a proper heading to satisfy markdownlint and keep changesets consistent.

-**css**
+### css
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**css**
## New
- Add `rules.with()` API
### css
## New
- Add `rules.with()` API
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

5-5: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🤖 Prompt for AI Agents
In .changeset/eager-lemons-wink.md around lines 5 to 8, replace the emphasized
line "**css**" with a proper Markdown heading (for example "### css") so it uses
a heading level instead of emphasis; update that single line and keep the rest
of the changeset content unchanged.

@github-actions
Copy link
Contributor

Triggered from #242 by @​black7375.

Checking if we can fast forward main (6f7b980) to css-rule-with (aafcd1c).

Target branch (main):

commit 6f7b9801c216a3ae4d7a2359a78bbad6427aa63b (HEAD -> main, origin/main)
Author: alstjr7375 <alstjr7375@daum.net>
Date:   Mon Jul 28 00:00:00 2025 +0900

    Feat: rulesVariant Funtion #154
    
    Co-authored-by: Jeong-jj <rgfdds98@gmail.com>

Pull request (css-rule-with):

commit aafcd1c4380d6778f7ee1864c08a56f46944ae91 (pull_request/css-rule-with)
Author: alstjr7375 <alstjr7375@daum.net>
Date:   Tue Jul 29 00:00:00 2025 +0900

    Feat: `rules.with()` API implement #234

It is possible to fast forward main (6f7b980) to css-rule-with (aafcd1c). If you have write access to the target repository, you can add a comment with /fast-forward to fast forward main to css-rule-with.

Copy link

@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 UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f360c85 and aafcd1c.

📒 Files selected for processing (3)
  • .changeset/eager-lemons-wink.md (1 hunks)
  • packages/css/src/css/index.ts (2 hunks)
  • packages/css/src/rules/index.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/css/src/css/index.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-09T13:00:38.449Z
Learnt from: black7375
PR: mincho-js/mincho#113
File: packages/css/src/index.ts:33-33
Timestamp: 2024-10-09T13:00:38.449Z
Learning: `recipe` is properly exported from './rules' in `packages/css/src/rules/index.ts`.

Applied to files:

  • packages/css/src/rules/index.ts
🧬 Code graph analysis (2)
packages/css/src/rules/index.ts (7)
packages/css/src/index.ts (13)
  • rules (30-30)
  • VariantGroups (35-35)
  • VariantDefinitions (40-40)
  • ComplexPropDefinitions (38-38)
  • PropTarget (39-39)
  • PatternOptions (36-36)
  • CSSRule (5-5)
  • CSSRuleWith (29-29)
  • RuntimeFn (34-34)
  • ConditionalVariants (41-41)
  • createVar (17-17)
  • fallbackVar (18-18)
  • css (28-28)
packages/css/src/rules/types.ts (9)
  • VariantGroups (52-52)
  • VariantDefinitions (43-43)
  • ComplexPropDefinitions (77-79)
  • PropTarget (75-75)
  • PatternOptions (179-194)
  • RuntimeFn (201-208)
  • ConditionalVariants (168-177)
  • PropDefinition (80-85)
  • RecipeStyleRule (31-31)
packages/transform-to-vanilla/src/types/style-rule.ts (2)
  • CSSRule (33-35)
  • PureCSSVarKey (129-129)
packages/css/src/css/types.ts (1)
  • CSSRuleWith (9-23)
packages/transform-to-vanilla/src/utils/object.ts (1)
  • mergeObject (5-11)
packages/css/src/utils.ts (2)
  • getDebugName (13-15)
  • getVarName (20-29)
packages/css/src/css/index.ts (1)
  • css (105-109)
.changeset/eager-lemons-wink.md (1)
packages/transform-to-vanilla/src/types/style-rule.ts (4)
  • CSSPropertiesWithConditions (45-47)
  • CSSPropertiesWithVars (49-52)
  • CSSRule (33-35)
  • CSSComplexProperties (54-56)
🪛 markdownlint-cli2 (0.18.1)
.changeset/eager-lemons-wink.md

5-5: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (1)
.changeset/eager-lemons-wink.md (1)

5-5: Switch the emphasized section label to a heading

markdownlint (MD036) still fires on the **css** line—please turn it into a heading (e.g. ### css) so the changeset passes lint.

Comment on lines +119 to +132
return rulesMultiple(
data,
(value: Parameters<typeof callback>[0], key: keyof Data) =>
mapData(callback(value) as Parameters<MapData>[0], key),
debugId
) as TransformDataMapping<Data, MapData>;
} else {
const ruleMap = ruleMapOrData as Data;
const debugId = mapDataOrDebugId;
return rulesMultiple(
ruleMap,
callback as unknown as MapData,
debugId
) as TransformRuleMap<Data>;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix the rules.with().multiple mapData plumbing

In the mapData overload you’re calling mapData(callback(value) …), but callback returns a PatternOptions object while mapData is typed (and, at runtime, written) to receive a RestrictedCSSRule. Because of the cast, TS stays quiet but the runtime value no longer matches the declared contract—any consumer that expects to read CSS properties (per the signature) will instead see a PatternOptions shape and produce nonsense output (e.g. trying to spread the rule into { base: rule } ends up nesting base.base). In practice this makes rules.with(cb).multiple(data, mapData) unusable as soon as the second argument looks at the rule it’s been promised.

Please feed mapData the actual RulePattern type and update the overload/return type accordingly so both the types and runtime value line up. For example:

-  function rulesWithMultiple<
-    Data extends Record<string | number, RestrictedCSSRule>,
-    MapData extends (
-      value: Data[keyof Data],
-      key: keyof Data
-    ) => PatternOptions<
-      VariantGroups | undefined,
-      VariantDefinitions | undefined,
-      ComplexPropDefinitions<PropTarget> | undefined
-    >
-  >(
-    data: Data,
-    mapData: MapData,
-    debugId?: string
-  ): TransformDataMapping<Data, MapData>;
+  function rulesWithMultiple<
+    Data extends Record<string | number, RestrictedCSSRule>,
+    MapData extends (
+      value: RulePattern,
+      key: keyof Data
+    ) => PatternOptions<
+      VariantGroups | undefined,
+      VariantDefinitions | undefined,
+      ComplexPropDefinitions<PropTarget> | undefined
+    >
+  >(
+    data: Data,
+    mapData: MapData,
+    debugId?: string
+  ): TransformRuleMap<Data>;
@@
-      return rulesMultiple(
-        data,
-        (value: Parameters<typeof callback>[0], key: keyof Data) =>
-          mapData(callback(value) as Parameters<MapData>[0], key),
-        debugId
-      ) as TransformDataMapping<Data, MapData>;
+      return rulesMultiple(
+        data,
+        (value: RestrictedCSSRule, key: keyof Data) =>
+          mapData(callback(value), key),
+        debugId
+      ) as TransformRuleMap<Data>;

This keeps the behaviour aligned with the API contract instead of swapping the data out from under the consumer.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return rulesMultiple(
data,
(value: Parameters<typeof callback>[0], key: keyof Data) =>
mapData(callback(value) as Parameters<MapData>[0], key),
debugId
) as TransformDataMapping<Data, MapData>;
} else {
const ruleMap = ruleMapOrData as Data;
const debugId = mapDataOrDebugId;
return rulesMultiple(
ruleMap,
callback as unknown as MapData,
debugId
) as TransformRuleMap<Data>;
// --- overload signatures for rulesWithMultiple ---
// before:
- function rulesWithMultiple<
- Data extends Record<string | number, RestrictedCSSRule>,
- MapData extends (
- value: Data[keyof Data],
- key: keyof Data
- ) => PatternOptions<
- VariantGroups | undefined,
- VariantDefinitions | undefined,
- ComplexPropDefinitions<PropTarget> | undefined
- >
- >(
- data: Data,
- mapData: MapData,
- debugId?: string
- ): TransformDataMapping<Data, MapData>;
// after:
function rulesWithMultiple<
Data extends Record<string | number, RestrictedCSSRule>,
MapData extends (
value: RulePattern,
key: keyof Data
) => PatternOptions<
VariantGroups | undefined,
VariantDefinitions | undefined,
ComplexPropDefinitions<PropTarget> | undefined
>
>(
data: Data,
mapData: MapData,
debugId?: string
): TransformRuleMap<Data>;
// --- implementation of the mapData branch ---
// before:
return rulesMultiple(
data,
(value: Parameters<typeof callback>[0], key: keyof Data) =>
mapData(callback(value) as Parameters<MapData>[0], key),
debugId
) as TransformDataMapping<Data, MapData>;
// after:
return rulesMultiple(
data,
(value: RestrictedCSSRule, key: keyof Data) =>
mapData(callback(value), key),
debugId
) as TransformRuleMap<Data>;
🤖 Prompt for AI Agents
In packages/css/src/rules/index.ts around lines 119–132, the mapData overload
incorrectly calls mapData(callback(value)...) passing a PatternOptions-shaped
value into a function typed/expected to receive a RestrictedCSSRule/RulePattern;
change the plumbing to pass an actual RulePattern into mapData (i.e., feed
mapData the rule pattern produced by the rule factory rather than the callback's
PatternOptions), and update the overload signatures/return types so the second
argument to rulesMultiple is typed as (rule: RulePattern, key: keyof Data) =>
MapData (and adjust TransformDataMapping/TransformRuleMap types accordingly) so
the runtime shape and TypeScript signatures align.

@black7375
Copy link
Contributor Author

/fast-forward

@github-actions
Copy link
Contributor

Triggered from #242 (comment) by @​black7375.

Trying to fast forward main (6f7b980) to css-rule-with (aafcd1c).

Target branch (main):

commit 6f7b9801c216a3ae4d7a2359a78bbad6427aa63b (HEAD -> main, origin/main)
Author: alstjr7375 <alstjr7375@daum.net>
Date:   Mon Jul 28 00:00:00 2025 +0900

    Feat: rulesVariant Funtion #154
    
    Co-authored-by: Jeong-jj <rgfdds98@gmail.com>

Pull request (css-rule-with):

commit aafcd1c4380d6778f7ee1864c08a56f46944ae91 (pull_request/css-rule-with)
Author: alstjr7375 <alstjr7375@daum.net>
Date:   Tue Jul 29 00:00:00 2025 +0900

    Feat: `rules.with()` API implement #234

Fast forwarding main (6f7b980) to css-rule-with (aafcd1c).

$ git push origin aafcd1c4380d6778f7ee1864c08a56f46944ae91:main
To https://github.com/mincho-js/mincho.git
   6f7b980..aafcd1c  aafcd1c4380d6778f7ee1864c08a56f46944ae91 -> main

@github-actions github-actions bot merged commit aafcd1c into main Sep 28, 2025
12 checks passed
@github-actions github-actions bot deleted the css-rule-with branch September 28, 2025 11:15
@github-actions github-actions bot mentioned this pull request Sep 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant