tailwind_merge 1.5.4 → 1.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c8e3fe7605ec55fd88225d16bcc919092e3710a81ee581ded2fa09e0bb06013
4
- data.tar.gz: 71053feef40855a9f240bf7e9e32945239adcb36206b570e137fc6ec99d2044f
3
+ metadata.gz: f048ad3bad246e67618239dd63a7155c2cf2b75a8be211ac14510f195ef8fc62
4
+ data.tar.gz: 7e59c5aee2a7df93eb807799446fc49ffab26a3a4363507b84fd44d56a7be778
5
5
  SHA512:
6
- metadata.gz: 643732e00316338a5fbf76e146eceed8dfead1bf5aa779c01766778e345824068014632a30096b0ea14a4a2fe17a65d6a0f1dd4900d65e524cf3e32f165b4419
7
- data.tar.gz: 5e7f29df21553b91c046b57781006a7673f06b24a29718a17aaca6ebe98b851f0481eaebb46299a8756d4aec823a82ee1844d31715d258ea783b5958699422bd
6
+ metadata.gz: a976cb0068d4d73e124052923d6bcc12acb92570e34c8337df914a353d6808b17227c6fbf4a51cc301597a3bbc9a8a6d7b90797a7879b7e15cbebc7f7f62d21d
7
+ data.tar.gz: e8daab44638f2c203b51a3796d4fe9fb57a6770baadb30cac41427b467f04ddcbb733192307d326101fefcc3edc1dad20ddede70fb2ed41840d25592cdc76239
@@ -0,0 +1,161 @@
1
+ ---
2
+ name: port-upstream
3
+ description: >-
4
+ Check GitHub notifications for upstream dcastil/tailwind-merge pull requests
5
+ and port merged ones into this Ruby gem (branch, translated code, tests,
6
+ commit, PR). Use whenever the user asks to check upstream, check their GitHub
7
+ notifications, sync or catch up with tailwind-merge, port upstream fixes, or
8
+ asks "anything new upstream?" — even if they don't explicitly say "port".
9
+ ---
10
+
11
+ # Port upstream tailwind-merge changes
12
+
13
+ This gem is a Ruby port of [dcastil/tailwind-merge](https://github.com/dcastil/tailwind-merge)
14
+ (TypeScript). Upstream fixes — usually to the default config — need to be
15
+ re-implemented here by hand. This skill turns the user's GitHub notification
16
+ inbox into a triage report, then ports the approved PRs one at a time.
17
+
18
+ The single source of truth for "already ported" is a commit-message trailer:
19
+ every port commit ends with a line like `Ports dcastil/tailwind-merge#705.`
20
+ Grep git history for that marker instead of keeping a separate state file —
21
+ history can't drift out of sync with itself.
22
+
23
+ ## Phase 1 — Triage
24
+
25
+ 1. Fetch unread notifications for the upstream repo, keeping the thread `id`
26
+ (needed later to mark it read) and the PR number from the subject URL:
27
+
28
+ ```bash
29
+ gh api notifications --paginate \
30
+ -q '.[] | select(.repository.full_name == "dcastil/tailwind-merge") | {thread_id: .id, type: .subject.type, title: .subject.title, url: .subject.url}'
31
+ ```
32
+
33
+ Ignore non-PullRequest subjects (issues, releases) unless the user asks
34
+ about them. Dedupe if several threads point at the same PR. If the inbox is
35
+ empty, say so and stop — unless the user asked for a **sweep** (see below).
36
+
37
+ 2. For each PR number, fetch its state and metadata:
38
+
39
+ ```bash
40
+ gh pr view <N> -R dcastil/tailwind-merge --json state,title,url,mergedAt,body,files
41
+ ```
42
+
43
+ Sort the PRs into three buckets:
44
+
45
+ - **Not merged yet** (`OPEN`): leave the notification unread and don't
46
+ track it — porting unmerged work is speculative. Mention these in one
47
+ summary line so the user knows why they weren't handled.
48
+ - **Merged, already ported**: check with
49
+ `git log -E --grep 'dcastil/tailwind-merge#<N>([^0-9]|$)'`
50
+ (the character class stops #70 from matching #708). If a commit exists,
51
+ mark the notification read right away — the inbox should reflect
52
+ remaining work:
53
+ `gh api --method PATCH /notifications/threads/<thread_id>`
54
+ - **Merged, not ported**: this is the work queue.
55
+
56
+ 3. Present a triage report for the work queue: upstream title, link, merge
57
+ date, which upstream files it touches, and which Ruby files that maps to
58
+ (see the translation table). Flag PRs that likely have nothing to port —
59
+ changes confined to TypeScript types, docs, bundling, CI, or dependency
60
+ bumps have no Ruby counterpart.
61
+
62
+ 4. Ask the user which PRs to port before writing any code (recommend all the
63
+ applicable ones). PRs the user decides to skip as not applicable also get
64
+ their notification marked read — a conscious "no" is handled work.
65
+
66
+ ## Phase 2 — Port (one upstream PR at a time)
67
+
68
+ Port approved PRs **oldest merge first** — upstream PRs often touch adjacent
69
+ config lines, so applying them in merge order avoids self-inflicted conflicts.
70
+ Each port is its own branch off `main`, its own commit, its own PR here.
71
+
72
+ For each PR:
73
+
74
+ 1. Start clean: `git checkout main && git pull`.
75
+ 2. Branch using the repo's convention: `fix/<kebab-summary>` (or `feat/` if
76
+ the upstream change adds behavior).
77
+ 3. Read the full upstream change: `gh pr diff <N> -R dcastil/tailwind-merge`,
78
+ plus the PR body — dcastil's descriptions usually explain the CSS-level
79
+ *why*, which belongs in the commit message here.
80
+ 4. Translate the diff using the table and idioms below. Port the upstream
81
+ test changes too — a port without its tests isn't verified.
82
+ 5. Run the suite and linter:
83
+
84
+ ```bash
85
+ bundle exec rake test && bundle exec rake rubocop
86
+ ```
87
+
88
+ Fix failures before committing. Do **not** touch `version.rb` or
89
+ `CHANGELOG.md` — release-please generates both from conventional commits.
90
+ 6. Commit with a conventional message modeled on `git show 66d8e2a`:
91
+ `fix(config): <subject>`, a body explaining the CSS behavior being fixed
92
+ (not just "port upstream"), and the trailer as the final line:
93
+
94
+ ```
95
+ Ports dcastil/tailwind-merge#<N>.
96
+ ```
97
+
98
+ That trailer is the tracking mechanism — omitting it means the PR shows up
99
+ as unported forever.
100
+
101
+ Commits are signed through 1Password's SSH agent. If `git commit` fails
102
+ with `1Password: failed to fill whole buffer`, 1Password is locked — ask
103
+ the user to unlock it and retry (the commit may also need to run outside
104
+ the sandbox to reach the agent).
105
+ 7. Push and open a PR against `main` with `gh pr create`, linking the
106
+ upstream PR in the description.
107
+ 8. Mark the notification thread read:
108
+ `gh api --method PATCH /notifications/threads/<thread_id>`
109
+
110
+ Finish with a summary: PRs opened here (with links), PRs skipped and why, and
111
+ anything left unread in the inbox (e.g. unmerged upstream PRs).
112
+
113
+ ## Translation table
114
+
115
+ | Upstream (TypeScript) | Here (Ruby) |
116
+ | ------------------------------ | -------------------------------------- |
117
+ | `src/lib/default-config.ts` | `lib/tailwind_merge/config.rb` |
118
+ | `src/lib/validators.ts` | `lib/tailwind_merge/validators.rb` |
119
+ | `src/lib/parse-class-name.ts` | `lib/tailwind_merge/parse_class_name.rb` |
120
+ | `src/lib/sort-modifiers.ts` | `lib/tailwind_merge/sort_modifiers.rb` |
121
+ | `src/lib/class-group-utils.ts` | `lib/tailwind_merge/class_group_utils.rb` |
122
+ | `tests/<kebab-name>.test.ts` | `test/test_<snake_name>.rb` |
123
+
124
+ Idiom mapping — the port is deliberately close to a mechanical rename:
125
+
126
+ - `scaleFooBar()` helper → `SCALE_FOO_BAR` lambda constant; spread with
127
+ `*SCALE_FOO_BAR.call` where TS uses `...scaleFooBar()`.
128
+ - `themeSpacing` / other theme getters → `THEME_SPACING` etc.
129
+ - `isNumber` and friends → `IS_NUMBER` lambda constants in `validators.rb`;
130
+ inside `config.rb` they appear bare (the module includes `Validators`) or as
131
+ `Validators::IS_NUMBER` — match whichever the surrounding lines use.
132
+ - Object literals → string-keyed hashes: `{ shadow: [...] }` becomes
133
+ `{ "shadow" => [...] }`.
134
+ - vitest `expect(twMerge('a b')).toBe('b')` → Minitest
135
+ `assert_equal("b", @merger.merge("a b"))` with `@merger` from `setup`.
136
+
137
+ When an upstream diff touches a file with no row in the table, check whether
138
+ the change is behavior (needs a Ruby home) or TypeScript plumbing (skip it,
139
+ and say so in the report). Doc-comment tweaks (like `@see` link fixes) only
140
+ apply if the Ruby file carries the same comment.
141
+
142
+ **Port to the post-PR state.** If the surrounding Ruby code doesn't match
143
+ what the upstream diff shows as the "before", the port has drifted — an
144
+ earlier upstream change was missed. Don't apply just the PR's delta onto the
145
+ stale code; bring the whole expression to upstream's post-PR state and call
146
+ out the extra repair in the commit body. (This happened with the `columns`
147
+ group, which had drifted to matching only t-shirt sizes while upstream had
148
+ long since moved to numbers + the container scale.)
149
+
150
+ ## Sweep mode (optional)
151
+
152
+ Notifications are ephemeral — if the user dismissed some, merged upstream work
153
+ can slip through. When the user asks for a "sweep" or suspects gaps, also
154
+ cross-check recent merged upstream PRs against the trailer markers:
155
+
156
+ ```bash
157
+ gh pr list -R dcastil/tailwind-merge --state merged --limit 20 --json number,title,mergedAt,url
158
+ ```
159
+
160
+ Any PR without a matching `Ports dcastil/tailwind-merge#<N>` commit joins the
161
+ triage report (there's no notification thread to mark read for these).
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.5.5](https://github.com/gjtorikian/tailwind_merge/compare/v1.5.4...v1.5.5) (2026-08-24)
2
+
3
+ ### Bug Fixes
4
+
5
+ * **config:** merge bare bg-conic with other background image classes ([#92](https://github.com/gjtorikian/tailwind_merge/pull/92))
6
+ * **config:** make columns-auto conflict with other columns classes ([#91](https://github.com/gjtorikian/tailwind_merge/pull/91))
7
+ * **config:** support container scale in inline sizing groups ([#90](https://github.com/gjtorikian/tailwind_merge/pull/90))
8
+ * **config:** add none option to max-h class group ([#89](https://github.com/gjtorikian/tailwind_merge/pull/89))
9
+
10
+ ### Miscellaneous Chores
11
+
12
+ * add port-upstream skill ([#93](https://github.com/gjtorikian/tailwind_merge/pull/93))
13
+
14
+
1
15
  ## [1.5.4](https://github.com/gjtorikian/tailwind_merge/compare/v1.5.3...v1.5.4) (2026-08-13)
2
16
 
3
17
  ### Bug Fixes
@@ -117,6 +117,7 @@ module TailwindMerge
117
117
  }
118
118
  SCALE_SIZING_INLINE = -> {
119
119
  [
120
+ THEME_CONTAINER,
120
121
  IS_FRACTION,
121
122
  "screen",
122
123
  "full",
@@ -276,7 +277,7 @@ module TailwindMerge
276
277
  # Columns
277
278
  # @see https://tailwindcss.com/docs/columns
278
279
  ##
279
- "columns" => [{ "columns" => [IS_TSHIRT_SIZE] }],
280
+ "columns" => [{ "columns" => [IS_NUMBER, "auto", IS_ARBITRARY_VALUE, IS_ARBITRARY_VARIABLE, THEME_CONTAINER] }],
280
281
  ##
281
282
  # Break After
282
283
  # @see https://tailwindcss.com/docs/break-after
@@ -696,22 +697,22 @@ module TailwindMerge
696
697
  # Margin X
697
698
  # @see https://tailwindcss.com/docs/margin
698
699
  ##
699
- "mx" => [{ "mx" => SCALE_MARGIN.call }],
700
+ "mx" => [{ "mx" => SCALE_MARGIN.call }],
700
701
  ##
701
702
  # Margin Y
702
703
  # @see https://tailwindcss.com/docs/margin
703
704
  ##
704
- "my" => [{ "my" => SCALE_MARGIN.call }],
705
+ "my" => [{ "my" => SCALE_MARGIN.call }],
705
706
  #
706
707
  # Margin Start
707
708
  # @see https://tailwindcss.com/docs/margin
708
709
  #
709
- "ms" => [{ "ms" => SCALE_MARGIN.call }],
710
+ "ms" => [{ "ms" => SCALE_MARGIN.call }],
710
711
  #
711
712
  # Margin End
712
713
  # @see https://tailwindcss.com/docs/margin
713
714
  #
714
- "me" => [{ "me" => SCALE_MARGIN.call }],
715
+ "me" => [{ "me" => SCALE_MARGIN.call }],
715
716
  #
716
717
  # Margin Block Start
717
718
  # @see https://tailwindcss.com/docs/margin
@@ -731,17 +732,17 @@ module TailwindMerge
731
732
  # Margin Right
732
733
  # @see https://tailwindcss.com/docs/margin
733
734
  ##
734
- "mr" => [{ "mr" => SCALE_MARGIN.call }],
735
+ "mr" => [{ "mr" => SCALE_MARGIN.call }],
735
736
  ##
736
737
  # Margin Bottom
737
738
  # @see https://tailwindcss.com/docs/margin
738
739
  ##
739
- "mb" => [{ "mb" => SCALE_MARGIN.call }],
740
+ "mb" => [{ "mb" => SCALE_MARGIN.call }],
740
741
  ##
741
742
  # Margin Left
742
743
  # @see https://tailwindcss.com/docs/margin
743
744
  ##
744
- "ml" => [{ "ml" => SCALE_MARGIN.call }],
745
+ "ml" => [{ "ml" => SCALE_MARGIN.call }],
745
746
  ##
746
747
  # Space Between X
747
748
  # @see https://tailwindcss.com/docs/margin#adding-space-between-children
@@ -849,7 +850,7 @@ module TailwindMerge
849
850
  # Max-Height
850
851
  # @see https://tailwindcss.com/docs/max-height
851
852
  ##
852
- "max-h" => [{ "max-h" => ["screen", "lh", *SCALE_SIZING.call] }],
853
+ "max-h" => [{ "max-h" => ["screen", "lh", "none", *SCALE_SIZING.call] }],
853
854
 
854
855
  ############
855
856
  # Typography
@@ -1144,7 +1145,7 @@ module TailwindMerge
1144
1145
  IS_ARBITRARY_VALUE,
1145
1146
  ],
1146
1147
  "radial" => ["", IS_ARBITRARY_VARIABLE, IS_ARBITRARY_VALUE],
1147
- "conic" => [IS_INTEGER, IS_ARBITRARY_VARIABLE, IS_ARBITRARY_VALUE],
1148
+ "conic" => ["", IS_INTEGER, IS_ARBITRARY_VARIABLE, IS_ARBITRARY_VALUE],
1148
1149
  },
1149
1150
  IS_ARBITRARY_VARIABLE_IMAGE,
1150
1151
  IS_ARBITRARY_IMAGE,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TailwindMerge
4
- VERSION = "1.5.4"
4
+ VERSION = "1.5.5"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tailwind_merge
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.4
4
+ version: 1.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen J. Torikian
@@ -57,6 +57,7 @@ executables: []
57
57
  extensions: []
58
58
  extra_rdoc_files: []
59
59
  files:
60
+ - ".claude/skills/port-upstream/SKILL.md"
60
61
  - ".rubocop.yml"
61
62
  - ".ruby-version"
62
63
  - CHANGELOG.md
@@ -74,15 +75,15 @@ files:
74
75
  - lib/tailwind_merge/version.rb
75
76
  - script/test
76
77
  - tailwind_merge.gemspec
77
- homepage: https://github.com/gjtorikian/tailwind_merge/tree/v1.5.4
78
+ homepage: https://github.com/gjtorikian/tailwind_merge/tree/v1.5.5
78
79
  licenses:
79
80
  - MIT
80
81
  metadata:
81
- homepage_uri: https://github.com/gjtorikian/tailwind_merge/tree/v1.5.4
82
- source_code_uri: https://github.com/gjtorikian/tailwind_merge/tree/v1.5.4
83
- changelog_uri: https://github.com/gjtorikian/tailwind_merge/blob/v1.5.4/CHANGELOG.md
82
+ homepage_uri: https://github.com/gjtorikian/tailwind_merge/tree/v1.5.5
83
+ source_code_uri: https://github.com/gjtorikian/tailwind_merge/tree/v1.5.5
84
+ changelog_uri: https://github.com/gjtorikian/tailwind_merge/blob/v1.5.5/CHANGELOG.md
84
85
  bug_tracker_uri: https://github.com/gjtorikian/tailwind_merge/issues
85
- documentation_uri: https://rubydoc.info/gems/tailwind_merge/1.5.4
86
+ documentation_uri: https://rubydoc.info/gems/tailwind_merge/1.5.5
86
87
  funding_uri: https://github.com/sponsors/gjtorikian
87
88
  rubygems_mfa_required: 'true'
88
89
  rdoc_options: []