@sproutsocial/racine 26.14.9 → 27.0.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,72 @@
1
1
  # Change Log
2
2
 
3
+ ## 27.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [5e20b0b]
8
+ - Updated dependencies [8f6ba8d]
9
+ - @sproutsocial/seeds-react-tooltip@1.0.9
10
+ - @sproutsocial/seeds-networkcolor@2.21.0
11
+ - @sproutsocial/seeds-react-theme@3.2.0
12
+ - @sproutsocial/seeds-react-numeral@1.0.9
13
+ - @sproutsocial/seeds-react-avatar@1.0.5
14
+ - @sproutsocial/seeds-react-banner@1.0.10
15
+ - @sproutsocial/seeds-react-box@1.1.6
16
+ - @sproutsocial/seeds-react-card@1.1.7
17
+ - @sproutsocial/seeds-react-chart-legend@1.0.7
18
+ - @sproutsocial/seeds-react-data-table@2.0.1
19
+ - @sproutsocial/seeds-react-datepicker@1.0.7
20
+ - @sproutsocial/seeds-react-drawer@1.1.5
21
+ - @sproutsocial/seeds-react-duration@1.0.5
22
+ - @sproutsocial/seeds-react-empty-state@1.0.5
23
+ - @sproutsocial/seeds-react-fieldset@1.0.5
24
+ - @sproutsocial/seeds-react-form-field@1.0.5
25
+ - @sproutsocial/seeds-react-hooks@3.0.6
26
+ - @sproutsocial/seeds-react-icon@1.1.8
27
+ - @sproutsocial/seeds-react-image@1.0.5
28
+ - @sproutsocial/seeds-react-indicator@1.0.7
29
+ - @sproutsocial/seeds-react-keyboard-key@1.0.5
30
+ - @sproutsocial/seeds-react-label@1.0.5
31
+ - @sproutsocial/seeds-react-link@1.0.5
32
+ - @sproutsocial/seeds-react-loader@1.0.5
33
+ - @sproutsocial/seeds-react-loader-button@1.0.8
34
+ - @sproutsocial/seeds-react-message@1.0.8
35
+ - @sproutsocial/seeds-react-mixins@4.1.5
36
+ - @sproutsocial/seeds-react-modal@2.1.1
37
+ - @sproutsocial/seeds-react-partner-logo@1.3.7
38
+ - @sproutsocial/seeds-react-rating@1.0.7
39
+ - @sproutsocial/seeds-react-segmented-control@1.0.5
40
+ - @sproutsocial/seeds-react-select@1.1.7
41
+ - @sproutsocial/seeds-react-skeleton@1.1.5
42
+ - @sproutsocial/seeds-react-stack@1.0.5
43
+ - @sproutsocial/seeds-react-table@1.0.8
44
+ - @sproutsocial/seeds-react-tabs@1.1.8
45
+ - @sproutsocial/seeds-react-textarea@1.0.5
46
+ - @sproutsocial/seeds-react-theme-provider@1.1.6
47
+ - @sproutsocial/seeds-react-toast@1.0.7
48
+ - @sproutsocial/seeds-react-token@1.4.4
49
+ - @sproutsocial/seeds-react-token-input@1.4.10
50
+ - @sproutsocial/seeds-react-visually-hidden@1.0.6
51
+ - @sproutsocial/seeds-react-badge@2.0.1
52
+ - @sproutsocial/seeds-react-checkbox@1.3.7
53
+ - @sproutsocial/seeds-react-collapsible@1.0.6
54
+ - @sproutsocial/seeds-react-input@1.4.10
55
+ - @sproutsocial/seeds-react-popout@2.4.10
56
+ - @sproutsocial/seeds-react-button@1.3.4
57
+ - @sproutsocial/seeds-react-switch@1.2.7
58
+ - @sproutsocial/seeds-react-radio@1.3.4
59
+
60
+ ## 27.0.0
61
+
62
+ ### Major Changes
63
+
64
+ - Updated dependencies [1814969]
65
+ - Updated dependencies [38d9e82]
66
+ - @sproutsocial/seeds-react-modal@2.1.0
67
+ - @sproutsocial/seeds-react-badge@2.0.0
68
+ - @sproutsocial/seeds-react-rating@1.0.6
69
+
3
70
  ## 26.14.9
4
71
 
5
72
  ### Patch Changes
package/README.md CHANGED
@@ -83,7 +83,7 @@ There are a few ways to get involved:
83
83
 
84
84
  Racine's file structure is set up like this:
85
85
 
86
- - `codemods` - For major updates to Racine that have breaking changes, codemods are included for automatically handling component API updates.
86
+ - `codemods` - For major updates to Racine that have breaking changes, codemods are included for automatically handling component API updates. Codemods are also discovered from other `@sproutsocial/seeds-react-*` packages automatically.
87
87
  - `src`
88
88
  - `ComponentName` - Deprecated components that won't get added to the monorepo have a folder within the `src` directory.
89
89
 
@@ -103,6 +103,37 @@ And you can interact with Racine via the command line with these commands:
103
103
  - `yarn clean` - Delete all generated files and directories.
104
104
  - `yarn release` - This will trigger the release process for creating a new version of the Racine package on npm. **Only Racine administrators can perform the release process.**
105
105
 
106
+ ### **🔄 Running Codemods**
107
+
108
+ Codemods are automated scripts that help migrate code when component APIs change. They're available via the `racine-codemod` CLI tool and are automatically discovered from both racine and other `@sproutsocial/seeds-react-*` packages.
109
+
110
+ **List available codemods:**
111
+ ```bash
112
+ racine-codemod
113
+ ```
114
+
115
+ **View codemod documentation:**
116
+ ```bash
117
+ racine-codemod <codemod-name>
118
+ ```
119
+
120
+ **Run a codemod:**
121
+ ```bash
122
+ racine-codemod <codemod-name> <path-to-files>
123
+ ```
124
+
125
+ **Example:**
126
+ ```bash
127
+ racine-codemod badge-1.x-to-2.x src --parser=tsx --quote=double
128
+ ```
129
+
130
+ After running a codemod, you should run Prettier to fix any formatting issues:
131
+ ```bash
132
+ yarn format
133
+ ```
134
+
135
+ For more information on codemods, see the [migration documentation](https://sproutsocial.com/seeds/components/migration) on the Seeds reference site.
136
+
106
137
  ### **✅ Step 3: Make your changes**
107
138
 
108
139
  Cut a feature branch off `main` and start coding! As updates are merged into `main` by other developers over time you'll want to pull those updates into your branch, ideally via rebase, to avoid any conflicts when you open a pull request.
@@ -145,3 +176,70 @@ When the PR is merged, [GitHub will kick off a publish of the new version](https
145
176
  ### **✍ Step 6: Document your changes**
146
177
 
147
178
  Racine components are documented in [Seeds](https://sproutsocial.com/seeds/components), Sprout's design system. You can open a PR to the [reference site app](https://github.com/sproutsocial/seeds/tree/main/apps/reference-site) to add or edit component documentation. It's a good idea to have documentation changes ready to go at the same time your Racine contributions are deployed, so start early! Reach out to the Design Systems team if you need help getting started.
179
+
180
+ ### **🔧 Adding Codemods**
181
+
182
+ When making breaking changes to a component API, you should create a codemod to help users migrate their code. Codemods should be added to the package that needs migration (not racine), and will be automatically discovered by the `racine-codemod` CLI.
183
+
184
+ **When to create a codemod:**
185
+ - Removing or renaming props
186
+ - Changing prop types or values
187
+ - Breaking API changes that affect multiple files
188
+
189
+ **Initial Setup** (for packages adding their first codemod):
190
+
191
+ 1. **Update `tsup.config.ts`**:
192
+ - Add a separate config entry for codemods:
193
+ ```typescript
194
+ export default defineConfig([
195
+ // Main package build
196
+ { entry: ["src/index.ts"], format: ["cjs", "esm"], /* ... */ },
197
+ // Codemods build (CJS only)
198
+ { entry: ["codemods/**/*.ts"], format: ["cjs"], dts: false, /* ... */ },
199
+ ]);
200
+ ```
201
+
202
+ 2. **Update `package.json`**:
203
+ - Add `exports` field for codemods:
204
+ ```json
205
+ {
206
+ "exports": {
207
+ ".": { /* existing exports */ },
208
+ "./codemods/*": {
209
+ "require": "./dist/codemods/*.js"
210
+ }
211
+ },
212
+ "files": ["dist", "codemods"]
213
+ }
214
+ ```
215
+ - Add `@types/jscodeshift` and `jscodeshift` to devDependencies (if not already present)
216
+
217
+ 3. **Update `tsconfig.json`**:
218
+ - Add `codemods/**/*` to the `include` array
219
+
220
+ **Creating a New Codemod:**
221
+
222
+ 1. Create codemod file in `codemods/` directory (e.g., `codemods/my-codemod.ts`)
223
+ 2. Write in TypeScript - use proper types from `jscodeshift` (avoid `any` types)
224
+ 3. Export as CommonJS: `module.exports = transformer;`
225
+ 4. Add tests in `codemods/__tests__/my-codemod.test.ts`
226
+ 5. Add documentation entry to `racine/codemods/codemod-docs.js`
227
+ 6. Build process handles compilation automatically (`yarn build` or `turbo build`)
228
+ 7. Codemod will be discoverable via `racine-codemod` CLI after package is built
229
+
230
+ **Testing codemods locally:**
231
+ - Run `yarn build` to compile codemod to JavaScript
232
+ - Run `yarn test` to run codemod tests
233
+ - Test codemod execution: `racine-codemod my-codemod path/to/test/files`
234
+
235
+ **Example structure:**
236
+ ```
237
+ my-package/
238
+ codemods/
239
+ my-codemod.ts
240
+ __tests__/
241
+ my-codemod.test.ts
242
+ dist/
243
+ codemods/
244
+ my-codemod.js (built automatically)
245
+ ```
@@ -11,20 +11,109 @@ const docs = require("../codemods/codemod-docs");
11
11
  const currentDir = process.cwd();
12
12
  process.chdir(__dirname);
13
13
 
14
- const codemods = fs
15
- .readdirSync("../codemods")
16
- .filter((x) => x.slice(-3) === ".js")
17
- .map((x) => x.slice(0, -3))
18
- .filter((x) => x !== "codemod-docs");
14
+ // Discover codemods from local racine and dependencies
15
+ function discoverCodemods() {
16
+ const localCodemods = [];
17
+ const dependencyCodemods = [];
18
+ const codemodPaths = new Map(); // Map codemod name to file path
19
+
20
+ // Get local racine codemods
21
+ try {
22
+ const localDir = path.join(__dirname, "../codemods");
23
+ if (fs.existsSync(localDir)) {
24
+ const localFiles = fs.readdirSync(localDir);
25
+ localFiles
26
+ .filter((x) => x.endsWith(".js") && x !== "codemod-docs.js")
27
+ .forEach((file) => {
28
+ const name = file.slice(0, -3);
29
+ localCodemods.push(name);
30
+ codemodPaths.set(name, path.join(localDir, file));
31
+ });
32
+ }
33
+ } catch (err) {
34
+ // Silently skip if directory doesn't exist
35
+ }
36
+
37
+ // Discover codemods from dependencies
38
+ try {
39
+ const nodeModulesPath = path.join(currentDir, "node_modules");
40
+ if (fs.existsSync(nodeModulesPath)) {
41
+ const packages = fs.readdirSync(nodeModulesPath);
42
+ packages.forEach((pkg) => {
43
+ // Handle scoped packages (e.g., @sproutsocial)
44
+ try {
45
+ const scopedDir = path.join(nodeModulesPath, pkg);
46
+ const scopedPackages = fs.readdirSync(scopedDir);
47
+ scopedPackages.forEach((scopedPkg) => {
48
+ const fullPackageName = `${pkg}/${scopedPkg}`;
49
+ if (fullPackageName.startsWith("@sproutsocial/seeds-react-")) {
50
+ const codemodsDir = path.join(
51
+ nodeModulesPath,
52
+ pkg,
53
+ scopedPkg,
54
+ "dist",
55
+ "codemods"
56
+ );
57
+ if (fs.existsSync(codemodsDir)) {
58
+ try {
59
+ const codemodFiles = fs.readdirSync(codemodsDir);
60
+ codemodFiles
61
+ .filter((file) => file.endsWith(".js"))
62
+ .forEach((file) => {
63
+ const name = file.slice(0, -3);
64
+ // Only add if not already in local codemods (local takes precedence)
65
+ if (!localCodemods.includes(name)) {
66
+ if (!dependencyCodemods.includes(name)) {
67
+ dependencyCodemods.push(name);
68
+ }
69
+ // Store path, but local takes precedence if exists
70
+ if (!codemodPaths.has(name)) {
71
+ codemodPaths.set(name, path.join(codemodsDir, file));
72
+ }
73
+ } else {
74
+ // Warn if duplicate found
75
+ console.warn(
76
+ `Warning: Codemod '${name}' found in both racine and ${fullPackageName}. Using racine version.`
77
+ );
78
+ }
79
+ });
80
+ } catch (err) {
81
+ // Silently skip if directory can't be read
82
+ }
83
+ }
84
+ }
85
+ });
86
+ } catch (err) {
87
+ // Silently skip if scoped directory can't be read
88
+ }
89
+ });
90
+ }
91
+ } catch (err) {
92
+ // Silently skip if node_modules doesn't exist or can't be read
93
+ }
94
+
95
+ return {
96
+ local: localCodemods,
97
+ dependencies: dependencyCodemods,
98
+ paths: codemodPaths,
99
+ };
100
+ }
101
+
102
+ const {
103
+ local: localCodemods,
104
+ dependencies: dependencyCodemods,
105
+ paths: codemodPaths,
106
+ } = discoverCodemods();
107
+ const allCodemods = [...localCodemods, ...dependencyCodemods];
19
108
 
20
109
  const transform = process.argv[2];
21
110
  const dest = process.argv[3];
22
111
  const usage = `racine-codemod <transformName> <path> <...otherArgs>\n`;
23
- if (!transform || codemods.indexOf(transform) === -1) {
112
+ if (!transform || allCodemods.indexOf(transform) === -1) {
24
113
  console.log(usage);
25
114
  console.error(
26
115
  "Missing/invalid transform name. Pick one of:\n" +
27
- codemods.map((x) => "- " + x).join("\n")
116
+ allCodemods.map((x) => "- " + x).join("\n")
28
117
  );
29
118
  process.exit(1);
30
119
  }
@@ -57,17 +146,26 @@ if (!dest) {
57
146
  process.exit(1);
58
147
  }
59
148
 
60
- const filePath = path.join("../codemods", transform + ".js");
149
+ // Resolve codemod path (local takes precedence, then dependencies)
150
+ const codemodPath = codemodPaths.get(transform);
151
+ if (!codemodPath || !fs.existsSync(codemodPath)) {
152
+ console.error(
153
+ `Error: Codemod '${transform}' not found. Built file may be missing. Run 'yarn build' in the package that provides this codemod.`
154
+ );
155
+ process.exit(1);
156
+ }
157
+
61
158
  const relativePath = path.join(currentDir, dest);
62
159
  const userArgs = [...process.argv]
63
160
  .slice(4)
64
161
  .map((arg) => arg.replace(/\s/g, ""));
65
162
 
163
+ // Run codemod with jscodeshift (all codemods are now compiled JS)
66
164
  const args = [
67
165
  "jscodeshift",
68
166
  "--",
69
167
  "-t",
70
- filePath,
168
+ codemodPath,
71
169
  relativePath,
72
170
  "--ignore-pattern=**/node_modules/**",
73
171
  ...userArgs,
@@ -57,4 +57,13 @@ module.exports = {
57
57
  "racine-codemod icon-name-substitution src/constants.js --quote=double --parser=tsx",
58
58
  arguments: { quote, parser },
59
59
  },
60
+ "badge-1.x-to-2.x": {
61
+ description:
62
+ "Migrates Badge component usage from v1.x (with deprecated props) to v2.x (without them). Removes deprecated props: 'size' (default), 'type', 'text', and 'tip'. Replaces 'size=\"default\"' with 'size=\"large\"', maps 'type' values to 'badgeColor', converts 'text' prop to children, and removes 'tip' prop. Adds TODO comments for dynamic type values and data attribute references that need manual updates.",
63
+ example: "racine-codemod badge-1.x-to-2.x src --parser=tsx --quote=double",
64
+ arguments: {
65
+ quote,
66
+ parser,
67
+ },
68
+ },
60
69
  };