From 8f61997bb2e84ca33f260aea95d281f0cd498b85 Mon Sep 17 00:00:00 2001 From: andresin87 Date: Thu, 18 Apr 2024 10:33:03 +0200 Subject: [PATCH 01/20] chore: add POC scan adoption script --- packages/utils/cli/bin/spark-scan.mjs | 15 +++ packages/utils/cli/bin/spark.mjs | 2 +- packages/utils/cli/src/index.doc.mdx | 70 ++++++++++ packages/utils/cli/src/scan/index.mjs | 120 ++++++++++++++++++ packages/utils/cli/src/scan/scanCallback.mjs | 56 ++++++++ .../cli/src/scan/utils/extract-imports.mjs | 28 ++++ .../src/scan/utils/file-contains-import.mjs | 17 +++ packages/utils/cli/src/scan/utils/get-csv.mjs | 0 .../src/scan/utils/get-formated-timestamp.mjs | 7 + packages/utils/cli/src/scan/utils/index.mjs | 5 + packages/utils/cli/src/scan/utils/logger.mjs | 19 +++ .../cli/src/scan/utils/scan-directories.mjs | 46 +++++++ 12 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 packages/utils/cli/bin/spark-scan.mjs create mode 100644 packages/utils/cli/src/scan/index.mjs create mode 100644 packages/utils/cli/src/scan/scanCallback.mjs create mode 100644 packages/utils/cli/src/scan/utils/extract-imports.mjs create mode 100644 packages/utils/cli/src/scan/utils/file-contains-import.mjs create mode 100644 packages/utils/cli/src/scan/utils/get-csv.mjs create mode 100644 packages/utils/cli/src/scan/utils/get-formated-timestamp.mjs create mode 100644 packages/utils/cli/src/scan/utils/index.mjs create mode 100644 packages/utils/cli/src/scan/utils/logger.mjs create mode 100644 packages/utils/cli/src/scan/utils/scan-directories.mjs diff --git a/packages/utils/cli/bin/spark-scan.mjs b/packages/utils/cli/bin/spark-scan.mjs new file mode 100644 index 000000000..bc1403adb --- /dev/null +++ b/packages/utils/cli/bin/spark-scan.mjs @@ -0,0 +1,15 @@ +#! /usr/bin/env node + +import { Command } from 'commander' +import { scan } from '../src/scan/index.mjs' + +const program = new Command() + +program + .command('adoption') + .description('Scan @spark-ui adoption for .tsx files with given imports') + .option('-c, --configuration ', 'configuration file route', '.spark-ui.cjs') + .option('-o, --output ', 'output file route') + .action(scan) + +program.parse(process.argv) diff --git a/packages/utils/cli/bin/spark.mjs b/packages/utils/cli/bin/spark.mjs index c3adbc0b0..946d1d6b6 100755 --- a/packages/utils/cli/bin/spark.mjs +++ b/packages/utils/cli/bin/spark.mjs @@ -9,6 +9,6 @@ const { version } = require('../package.json') program.version(version, '--version') program.command('generate', 'Generate a component scaffolding').alias('g') -program.command('setup-themes', 'Set up Spark theming configuration') +program.command('scan', 'Scan a directory for components').alias('s') program.parse(process.argv) diff --git a/packages/utils/cli/src/index.doc.mdx b/packages/utils/cli/src/index.doc.mdx index 404babd39..4b23e5da3 100644 --- a/packages/utils/cli/src/index.doc.mdx +++ b/packages/utils/cli/src/index.doc.mdx @@ -40,3 +40,73 @@ Then, a command prompt will guide you through the process by asking you for: - the package name (required), - the template used (required, only `Component` template available right now) - and the package description (optional). + +## Scanning directory adoption + +For viewing the adoption of packages in a project directory, the following command can be executed: + +```bash +$ spark scan adoption +``` + +### Options + +#### Configuration + +```bash +$ spark scan adoption --configuration +``` + +alias + +```bash +$ spark scan adoption -c +``` + +example +example + +```bash +spark scan adoption -c "./spark-ui.cjs" +```` + + +### configuration filename structure + + ```js + // .spark-ui.cjs +module.exports = { + adoption: { + details: true, + alpha: false, + imports: ['@spark-ui'], + extensions: ['.tsx', '.ts'], + directory: './packages', + }, +} + ` + +- `details` (boolean) - whether to show the details of the adoption or not. Default: false +- `alpha` (boolean) - packages are sorted alphabetically. Default: false means sorted by adoption number +- `imports` (array) - the imports to be scanned. +- `extensions` (array) - the extensions to be scanned +- `directory` (string) - the directory to be scanned. Default: '.' means the current directory +``` + +#### Output +The output option is used to save the adoption data to a file. It is optional + +```bash +$ spark scan adoption --output +``` + alias + +```bash +$ spark scan adoption -o +``` + +example + +```bash +spark scan adoption -o "./adoption.$(date +"%Y%m%d_%H:%M:%S").json" +```` \ No newline at end of file diff --git a/packages/utils/cli/src/scan/index.mjs b/packages/utils/cli/src/scan/index.mjs new file mode 100644 index 000000000..ccd38566d --- /dev/null +++ b/packages/utils/cli/src/scan/index.mjs @@ -0,0 +1,120 @@ +import * as process from 'node:process' + +import { appendFileSync, existsSync } from 'fs' +import path from 'path' + +import { scanCallback } from './scanCallback.mjs' +import { logger } from './utils/logger.mjs' +import { scanDirectories } from './utils/scan-directories.mjs' + +const DEFAULT_CONFIG = { + details: false, + alpha: false, + imports: ['@spark-ui'], + extensions: ['.tsx', '.ts'], + directory: '.', +} + +export async function scan(options) { + let config = {} + + const configFileRoute = path.join(process.cwd(), options.configuration || '.spark-ui.cjs') + try { + if (existsSync(configFileRoute)) { + console.log('✨✨✨ loading spark-ui custom configuration file ✨✨✨') + const { default: customConfig } = await import( + path.join(process.cwd(), options.configuration) + ) + config = structuredClone(customConfig, DEFAULT_CONFIG) + } + } catch (error) { + logger.error(`❌ Error loading configuration file: ${error}`) + } + + const extensions = config.adoption.extensions + + let lastScanCount = 0 + const importCount = 0 + const importResults = {} + let importsUsed = {} + let importsCount = {} + config.adoption.imports.forEach(moduleName => { + console.log(`scanning adoption for ${moduleName}`) + const directoryPath = path.join(process.cwd(), config.adoption.directory) + scanDirectories(directoryPath, moduleName, extensions, scanCallback, { + importCount, + importResults, + importsUsed, + importsCount, + }) + if (importCount !== lastScanCount) { + logger.success( + `Found ${importCount - lastScanCount} files with "${moduleName}" imports across directory ${directoryPath}:` + ) + } else { + logger.warn(`No files found with "${moduleName}" imports across directory ${directoryPath}.`) + } + lastScanCount = importCount + }) + + // Sort importsUsed by alphabet + if (config.adoption.alpha) { + importsUsed = Object.fromEntries( + Object.entries(importsUsed) + .sort(([pkgNameA], [pkgNameB]) => pkgNameA.localeCompare(pkgNameB)) + .map(([pkgname, content]) => { + return [ + pkgname, + { + default: Object.fromEntries( + Object.entries(content.default).sort(([a], [b]) => a.localeCompare(b)) + ), + named: Object.fromEntries( + Object.entries(content.named).sort(([a], [b]) => a.localeCompare(b)) + ), + importsCount: content.importsCount, + }, + ] + }) + ) + } else { + // Sort importsUsed by most used + importsUsed = Object.fromEntries( + Object.entries(importsUsed) + .sort(([, contentA], [, contentB]) => contentB.importsCount - contentA.importsCount) + .map(([pkgName, content]) => { + return [ + pkgName, + { + default: Object.fromEntries( + Object.entries(content.default).sort(([, a], [, b]) => b - a) + ), + named: Object.fromEntries( + Object.entries(content.named).sort(([, a], [, b]) => b - a) + ), + importsCount: content.importsCount, + }, + ] + }) + ) + + importsCount = Object.fromEntries(Object.entries(importsCount).sort(([, a], [, b]) => b - a)) + } + + const result = Object.fromEntries( + Object.entries(importsUsed).map(([pkgName, value]) => [ + pkgName, + { ...value, ...(config.adoption.details && { results: importResults[pkgName] }) }, + ]) + ) + + if (options.output) { + try { + appendFileSync(`${options.output}`, JSON.stringify(result, null, 2)) + } catch (err) { + logger.error(`Error writing file: ${err}`) + } + } else { + logger.info(JSON.stringify(result, null, 2)) + } +} diff --git a/packages/utils/cli/src/scan/scanCallback.mjs b/packages/utils/cli/src/scan/scanCallback.mjs new file mode 100644 index 000000000..bd7b5e988 --- /dev/null +++ b/packages/utils/cli/src/scan/scanCallback.mjs @@ -0,0 +1,56 @@ +import extractImports from './utils/extract-imports.mjs' + +export function scanCallback(f, moduleName, { importResults, importsUsed, importsCount }) { + if (!f.fileContent) return + + const imports = extractImports(f.filePath, moduleName) + + Object.entries(imports).forEach(([key, importDeclarations]) => { + const moduleName = key.split('/').splice(0, 2).join('/') + importDeclarations.forEach(importDeclaration => { + const statement = importDeclaration.getText() + const defaultImport = importDeclaration.getDefaultImport()?.getText() || null + const namedImports = importDeclaration.getNamedImports().map(n => n.getText()) + + if (!importResults[moduleName]) { + importResults[moduleName] = [] + } + + importResults[moduleName].push({ + path: f.filePath, + statement, + hasDefault: !!defaultImport, + hasNamed: !!namedImports.length, + defaultImport, + namedImports, + }) + + if (!importsUsed[moduleName]) { + importsUsed[moduleName] = { + default: {}, + named: {}, + importsCount: 0, + } + } + + if (defaultImport) { + importsUsed[moduleName].default[defaultImport] = + importsUsed[moduleName].default[defaultImport] + 1 || 1 + importsUsed.importsCount = importsCount[defaultImport] + 1 + + importsCount[defaultImport] = importsCount[defaultImport] + 1 || 1 + } + + if (namedImports.length) { + namedImports.forEach(n => { + importsUsed[moduleName].named[n] = importsUsed[moduleName].named[n] + 1 || 1 + }) + + namedImports.forEach(n => { + importsUsed[moduleName].importsCount = importsUsed[moduleName].importsCount + 1 + importsCount[n] = importsCount[n] + 1 || 1 + }) + } + }) + }) +} diff --git a/packages/utils/cli/src/scan/utils/extract-imports.mjs b/packages/utils/cli/src/scan/utils/extract-imports.mjs new file mode 100644 index 000000000..294589898 --- /dev/null +++ b/packages/utils/cli/src/scan/utils/extract-imports.mjs @@ -0,0 +1,28 @@ +import { Project } from 'ts-morph' + +export function extractImports(filePath, requestedModuleName) { + const project = new Project() + const sourceFile = project.addSourceFileAtPath(filePath) + + const importStatements = {} + + const importNodes = sourceFile.getImportDeclarations() + + importNodes + .filter(node => { + const moduleName = node.getModuleSpecifierValue() + + return moduleName.includes(requestedModuleName) + }) + .forEach(node => { + const moduleName = node.getModuleSpecifierValue() + if (!importStatements[moduleName]) { + importStatements[moduleName] = [] + } + importStatements[moduleName].push(node) + }) + + return importStatements +} + +export default extractImports diff --git a/packages/utils/cli/src/scan/utils/file-contains-import.mjs b/packages/utils/cli/src/scan/utils/file-contains-import.mjs new file mode 100644 index 000000000..c42887ca2 --- /dev/null +++ b/packages/utils/cli/src/scan/utils/file-contains-import.mjs @@ -0,0 +1,17 @@ +import fs from 'fs' + +/** + * Check if a file contains an import from a given import name. + * @param filePath The path to the file to check. + * @param importName The name of the import to check for. + * @returns Whether the file contains an import from the given import name. + */ +export function fileContainsImport(filePath, importName) { + const fileContent = fs.readFileSync(filePath, 'utf8') + + if (new RegExp(`import.*from\\s+["']${importName}.*["']`, 'm').test(fileContent)) { + return { filePath, fileContent } + } + + return { filePath } +} diff --git a/packages/utils/cli/src/scan/utils/get-csv.mjs b/packages/utils/cli/src/scan/utils/get-csv.mjs new file mode 100644 index 000000000..e69de29bb diff --git a/packages/utils/cli/src/scan/utils/get-formated-timestamp.mjs b/packages/utils/cli/src/scan/utils/get-formated-timestamp.mjs new file mode 100644 index 000000000..e58250d19 --- /dev/null +++ b/packages/utils/cli/src/scan/utils/get-formated-timestamp.mjs @@ -0,0 +1,7 @@ +export function getFormatedTimestamp() { + const d = new Date() + const date = d.toISOString().split('T')[0] + const time = d.toTimeString().split(' ')[0].replace(/:/g, '-') + + return `${date} ${time}` +} diff --git a/packages/utils/cli/src/scan/utils/index.mjs b/packages/utils/cli/src/scan/utils/index.mjs new file mode 100644 index 000000000..0de2a35f9 --- /dev/null +++ b/packages/utils/cli/src/scan/utils/index.mjs @@ -0,0 +1,5 @@ +export { extractImports } from './extract-imports.mjs' +export { fileContainsImport } from './file-contains-import.mjs' +export { getFormatedTimestamp } from './get-formated-timestamp.mjs' +export { logger } from './logger.mjs' +export { scanDirectories } from './scan-directories.mjs' diff --git a/packages/utils/cli/src/scan/utils/logger.mjs b/packages/utils/cli/src/scan/utils/logger.mjs new file mode 100644 index 000000000..8ba30c614 --- /dev/null +++ b/packages/utils/cli/src/scan/utils/logger.mjs @@ -0,0 +1,19 @@ +import chalk from 'chalk' + +export const logger = { + error(...args) { + console.log(chalk.red(...args)) + }, + warn(...args) { + console.log(chalk.yellow(...args)) + }, + info(...args) { + console.log(chalk.cyan(...args)) + }, + success(...args) { + console.log(chalk.green(...args)) + }, + break() { + console.log('') + }, +} diff --git a/packages/utils/cli/src/scan/utils/scan-directories.mjs b/packages/utils/cli/src/scan/utils/scan-directories.mjs new file mode 100644 index 000000000..1f333fcd7 --- /dev/null +++ b/packages/utils/cli/src/scan/utils/scan-directories.mjs @@ -0,0 +1,46 @@ +import fs from 'fs' +import path from 'path' + +import { fileContainsImport } from './file-contains-import.mjs' + +export function scanDirectories( + directoryPath, + importName, + extensions, + scanningCallback, + { importCount, importResults, importsUsed, importsCount } +) { + const files = fs.readdirSync(directoryPath) + + for (const file of files) { + const filePath = path.join(directoryPath, file) + const stats = fs.statSync(filePath) + + if (stats.isDirectory()) { + scanDirectories(filePath, importName, extensions, scanningCallback, { + importCount, + importResults, + importsUsed, + importsCount, + }) + } else if (stats.isFile() && extensions.includes(path.extname(filePath))) { + const f = fileContainsImport(filePath, importName) + + if (f) { + scanningCallback( + { + filePath: f.filePath, + fileContent: f.fileContent, + }, + importName, + { + importCount, + importResults, + importsUsed, + importsCount, + } + ) + } + } + } +} From ef839cb1fbdd7c3fe00e236a9805d1b87dec55c6 Mon Sep 17 00:00:00 2001 From: andresin87 Date: Thu, 18 Apr 2024 11:25:33 +0200 Subject: [PATCH 02/20] chore: doc improvements --- packages/utils/cli/src/index.doc.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/utils/cli/src/index.doc.mdx b/packages/utils/cli/src/index.doc.mdx index 4b23e5da3..b3bb996ee 100644 --- a/packages/utils/cli/src/index.doc.mdx +++ b/packages/utils/cli/src/index.doc.mdx @@ -63,7 +63,6 @@ alias $ spark scan adoption -c ``` -example example ```bash @@ -71,7 +70,7 @@ spark scan adoption -c "./spark-ui.cjs" ```` -### configuration filename structure +##### configuration filename structure ```js // .spark-ui.cjs @@ -84,13 +83,14 @@ module.exports = { directory: './packages', }, } - ` -- `details` (boolean) - whether to show the details of the adoption or not. Default: false +/*** + - `details` (boolean) - whether to show the details of the adoption or not. Default: false - `alpha` (boolean) - packages are sorted alphabetically. Default: false means sorted by adoption number - `imports` (array) - the imports to be scanned. - `extensions` (array) - the extensions to be scanned - `directory` (string) - the directory to be scanned. Default: '.' means the current directory +***/ ``` #### Output From c2911bbc5fbc582fcac4c8f3a58bb7ba54a83409 Mon Sep 17 00:00:00 2001 From: andresin87 Date: Thu, 18 Apr 2024 18:40:57 +0200 Subject: [PATCH 03/20] chore: minor changes --- packages/utils/cli/bin/spark-scan.mjs | 4 ++-- packages/utils/cli/src/scan/index.mjs | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/utils/cli/bin/spark-scan.mjs b/packages/utils/cli/bin/spark-scan.mjs index bc1403adb..ec4d24a73 100644 --- a/packages/utils/cli/bin/spark-scan.mjs +++ b/packages/utils/cli/bin/spark-scan.mjs @@ -1,7 +1,7 @@ #! /usr/bin/env node import { Command } from 'commander' -import { scan } from '../src/scan/index.mjs' +import { adoption } from '../src/scan/index.mjs' const program = new Command() @@ -10,6 +10,6 @@ program .description('Scan @spark-ui adoption for .tsx files with given imports') .option('-c, --configuration ', 'configuration file route', '.spark-ui.cjs') .option('-o, --output ', 'output file route') - .action(scan) + .action(adoption) program.parse(process.argv) diff --git a/packages/utils/cli/src/scan/index.mjs b/packages/utils/cli/src/scan/index.mjs index ccd38566d..faefcf7e1 100644 --- a/packages/utils/cli/src/scan/index.mjs +++ b/packages/utils/cli/src/scan/index.mjs @@ -8,15 +8,17 @@ import { logger } from './utils/logger.mjs' import { scanDirectories } from './utils/scan-directories.mjs' const DEFAULT_CONFIG = { - details: false, - alpha: false, - imports: ['@spark-ui'], - extensions: ['.tsx', '.ts'], - directory: '.', + adoption: { + details: false, + alpha: false, + imports: ['@spark-ui'], + extensions: ['.tsx', '.ts'], + directory: '.', + }, } -export async function scan(options) { - let config = {} +export async function adoption(options) { + let config = DEFAULT_CONFIG const configFileRoute = path.join(process.cwd(), options.configuration || '.spark-ui.cjs') try { @@ -28,7 +30,7 @@ export async function scan(options) { config = structuredClone(customConfig, DEFAULT_CONFIG) } } catch (error) { - logger.error(`❌ Error loading configuration file: ${error}`) + logger.info('ℹ️ Loading default configuration') } const extensions = config.adoption.extensions From 9c70e26c32403a2e38f0ca63a133317c11aafefb Mon Sep 17 00:00:00 2001 From: andresin87 Date: Fri, 19 Apr 2024 09:45:20 +0200 Subject: [PATCH 04/20] chore: modify manifest --- packages/utils/cli/package.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/utils/cli/package.json b/packages/utils/cli/package.json index ef7108f7e..bd75407ae 100644 --- a/packages/utils/cli/package.json +++ b/packages/utils/cli/package.json @@ -12,7 +12,14 @@ ], "bin": { "spark": "./bin/spark.mjs", - "spark-generate": "./bin/spark-generate.mjs" + "spark-generate": "./bin/spark-generate.mjs", + "spark-scan": "./bin/spark-scan.mjs" + }, + "exports": { + ".": { + "import": "./src/index.mjs", + "require": "./src/index.js" + } }, "type": "module", "repository": { From 1a973d47617d8a06faf3005504355a4a05ad4df1 Mon Sep 17 00:00:00 2001 From: andresin87 Date: Fri, 19 Apr 2024 10:40:24 +0200 Subject: [PATCH 05/20] chore: modify export routes --- packages/utils/cli/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/utils/cli/package.json b/packages/utils/cli/package.json index bd75407ae..3c0a7603f 100644 --- a/packages/utils/cli/package.json +++ b/packages/utils/cli/package.json @@ -17,8 +17,7 @@ }, "exports": { ".": { - "import": "./src/index.mjs", - "require": "./src/index.js" + "import": "./bin/spark.mjs" } }, "type": "module", From 6c8132aee4beffa42de803f3195a0d8d32d1e310 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 07:01:50 +0000 Subject: [PATCH 06/20] build(npm): bump prettier-plugin-tailwindcss from 0.5.12 to 0.5.14 Bumps [prettier-plugin-tailwindcss](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) from 0.5.12 to 0.5.14. - [Release notes](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/compare/v0.5.12...v0.5.14) --- updated-dependencies: - dependency-name: prettier-plugin-tailwindcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 15 ++++++++------- package.json | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5a97fdfce..2d5983f1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -87,7 +87,7 @@ "nx": "^16.5.0", "postcss": "8.4.38", "prettier": "3.2.5", - "prettier-plugin-tailwindcss": "0.5.12", + "prettier-plugin-tailwindcss": "0.5.14", "react": "18.2.0", "react-dom": "18.2.0", "react-live": "3.2.0", @@ -29313,9 +29313,9 @@ } }, "node_modules/prettier-plugin-tailwindcss": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.12.tgz", - "integrity": "sha512-o74kiDBVE73oHW+pdkFSluHBL3cYEvru5YgEqNkBMFF7Cjv+w1vI565lTlfoJT4VLWDe0FMtZ7FkE/7a4pMXSQ==", + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.14.tgz", + "integrity": "sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q==", "dev": true, "engines": { "node": ">=14.21.3" @@ -29325,6 +29325,7 @@ "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", + "@zackad/prettier-plugin-twig-melody": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", @@ -29350,6 +29351,9 @@ "@trivago/prettier-plugin-sort-imports": { "optional": true }, + "@zackad/prettier-plugin-twig-melody": { + "optional": true + }, "prettier-plugin-astro": { "optional": true }, @@ -29379,9 +29383,6 @@ }, "prettier-plugin-svelte": { "optional": true - }, - "prettier-plugin-twig-melody": { - "optional": true } } }, diff --git a/package.json b/package.json index a1f67885e..d771a0a4b 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "nx": "^16.5.0", "postcss": "8.4.38", "prettier": "3.2.5", - "prettier-plugin-tailwindcss": "0.5.12", + "prettier-plugin-tailwindcss": "0.5.14", "react": "18.2.0", "react-dom": "18.2.0", "react-live": "3.2.0", From 6cd5ec3c28a126a8a3cb37f1fe48f45cadb36ea2 Mon Sep 17 00:00:00 2001 From: andresin87 Date: Mon, 22 Apr 2024 12:28:42 +0200 Subject: [PATCH 07/20] chore: log count --- packages/utils/cli/package.json | 5 ---- packages/utils/cli/src/scan/index.mjs | 12 ++++----- packages/utils/cli/src/scan/scanCallback.mjs | 16 ++++++++---- .../cli/src/scan/utils/scan-directories.mjs | 25 +++++++++---------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/utils/cli/package.json b/packages/utils/cli/package.json index 3c0a7603f..ac4410e0a 100644 --- a/packages/utils/cli/package.json +++ b/packages/utils/cli/package.json @@ -15,11 +15,6 @@ "spark-generate": "./bin/spark-generate.mjs", "spark-scan": "./bin/spark-scan.mjs" }, - "exports": { - ".": { - "import": "./bin/spark.mjs" - } - }, "type": "module", "repository": { "type": "git", diff --git a/packages/utils/cli/src/scan/index.mjs b/packages/utils/cli/src/scan/index.mjs index faefcf7e1..12bbe49b3 100644 --- a/packages/utils/cli/src/scan/index.mjs +++ b/packages/utils/cli/src/scan/index.mjs @@ -35,28 +35,28 @@ export async function adoption(options) { const extensions = config.adoption.extensions - let lastScanCount = 0 - const importCount = 0 + let importCount = 0 const importResults = {} let importsUsed = {} let importsCount = {} config.adoption.imports.forEach(moduleName => { console.log(`scanning adoption for ${moduleName}`) const directoryPath = path.join(process.cwd(), config.adoption.directory) - scanDirectories(directoryPath, moduleName, extensions, scanCallback, { + + const response = scanDirectories(directoryPath, moduleName, extensions, scanCallback, { importCount, importResults, importsUsed, importsCount, }) - if (importCount !== lastScanCount) { + if (importCount !== response.importCount) { logger.success( - `Found ${importCount - lastScanCount} files with "${moduleName}" imports across directory ${directoryPath}:` + `Found ${response.importCount - importCount} files with "${moduleName}" imports across directory ${directoryPath}.` ) } else { logger.warn(`No files found with "${moduleName}" imports across directory ${directoryPath}.`) } - lastScanCount = importCount + importCount = response.importCount }) // Sort importsUsed by alphabet diff --git a/packages/utils/cli/src/scan/scanCallback.mjs b/packages/utils/cli/src/scan/scanCallback.mjs index bd7b5e988..ef3882fb0 100644 --- a/packages/utils/cli/src/scan/scanCallback.mjs +++ b/packages/utils/cli/src/scan/scanCallback.mjs @@ -1,7 +1,12 @@ import extractImports from './utils/extract-imports.mjs' -export function scanCallback(f, moduleName, { importResults, importsUsed, importsCount }) { - if (!f.fileContent) return +export function scanCallback( + f, + moduleName, + { importCount, importResults, importsUsed, importsCount } +) { + const response = { importCount, importResults, importsUsed, importsCount } + if (!f.fileContent) return response const imports = extractImports(f.filePath, moduleName) @@ -39,18 +44,19 @@ export function scanCallback(f, moduleName, { importResults, importsUsed, import importsUsed.importsCount = importsCount[defaultImport] + 1 importsCount[defaultImport] = importsCount[defaultImport] + 1 || 1 + response.importCount++ } if (namedImports.length) { namedImports.forEach(n => { importsUsed[moduleName].named[n] = importsUsed[moduleName].named[n] + 1 || 1 - }) - - namedImports.forEach(n => { importsUsed[moduleName].importsCount = importsUsed[moduleName].importsCount + 1 importsCount[n] = importsCount[n] + 1 || 1 + response.importCount++ }) } }) }) + + return response } diff --git a/packages/utils/cli/src/scan/utils/scan-directories.mjs b/packages/utils/cli/src/scan/utils/scan-directories.mjs index 1f333fcd7..cb33b877d 100644 --- a/packages/utils/cli/src/scan/utils/scan-directories.mjs +++ b/packages/utils/cli/src/scan/utils/scan-directories.mjs @@ -12,35 +12,34 @@ export function scanDirectories( ) { const files = fs.readdirSync(directoryPath) + let response = { + importCount, + importResults, + importsUsed, + importsCount, + } + for (const file of files) { const filePath = path.join(directoryPath, file) const stats = fs.statSync(filePath) if (stats.isDirectory()) { - scanDirectories(filePath, importName, extensions, scanningCallback, { - importCount, - importResults, - importsUsed, - importsCount, - }) + response = scanDirectories(filePath, importName, extensions, scanningCallback, response) } else if (stats.isFile() && extensions.includes(path.extname(filePath))) { const f = fileContainsImport(filePath, importName) if (f) { - scanningCallback( + response = scanningCallback( { filePath: f.filePath, fileContent: f.fileContent, }, importName, - { - importCount, - importResults, - importsUsed, - importsCount, - } + response ) } } } + + return response } From b088cb8a766fe10a7171d698cbbe3d28f4a17936 Mon Sep 17 00:00:00 2001 From: andresin87 Date: Mon, 22 Apr 2024 12:31:36 +0200 Subject: [PATCH 08/20] chore: log msg error --- packages/utils/cli/src/scan/index.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/utils/cli/src/scan/index.mjs b/packages/utils/cli/src/scan/index.mjs index 12bbe49b3..4aef88078 100644 --- a/packages/utils/cli/src/scan/index.mjs +++ b/packages/utils/cli/src/scan/index.mjs @@ -51,7 +51,7 @@ export async function adoption(options) { }) if (importCount !== response.importCount) { logger.success( - `Found ${response.importCount - importCount} files with "${moduleName}" imports across directory ${directoryPath}.` + `Found ${response.importCount - importCount} imports with "${moduleName}" modules across directory ${directoryPath}.` ) } else { logger.warn(`No files found with "${moduleName}" imports across directory ${directoryPath}.`) @@ -64,9 +64,9 @@ export async function adoption(options) { importsUsed = Object.fromEntries( Object.entries(importsUsed) .sort(([pkgNameA], [pkgNameB]) => pkgNameA.localeCompare(pkgNameB)) - .map(([pkgname, content]) => { + .map(([pkgName, content]) => { return [ - pkgname, + pkgName, { default: Object.fromEntries( Object.entries(content.default).sort(([a], [b]) => a.localeCompare(b)) From 203e05e02285be18e5d0c6211f3ec04e4322837d Mon Sep 17 00:00:00 2001 From: andresin87 Date: Tue, 23 Apr 2024 16:32:14 +0200 Subject: [PATCH 09/20] feat(cli-utils): add scan adoption script --- .spark-ui.cjs | 0 packages/utils/cli/src/index.doc.mdx | 4 ++-- packages/utils/cli/src/scan/index.mjs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 .spark-ui.cjs diff --git a/.spark-ui.cjs b/.spark-ui.cjs new file mode 100644 index 000000000..e69de29bb diff --git a/packages/utils/cli/src/index.doc.mdx b/packages/utils/cli/src/index.doc.mdx index b3bb996ee..e6b3cd7dc 100644 --- a/packages/utils/cli/src/index.doc.mdx +++ b/packages/utils/cli/src/index.doc.mdx @@ -77,7 +77,7 @@ spark scan adoption -c "./spark-ui.cjs" module.exports = { adoption: { details: true, - alpha: false, + sort: 'count', // 'count' or 'alphabetical' imports: ['@spark-ui'], extensions: ['.tsx', '.ts'], directory: './packages', @@ -86,7 +86,7 @@ module.exports = { /*** - `details` (boolean) - whether to show the details of the adoption or not. Default: false -- `alpha` (boolean) - packages are sorted alphabetically. Default: false means sorted by adoption number +- `sort` ('count' | 'alphabetical') - packages are sorted alphabetically. Default: false means sorted by adoption number - `imports` (array) - the imports to be scanned. - `extensions` (array) - the extensions to be scanned - `directory` (string) - the directory to be scanned. Default: '.' means the current directory diff --git a/packages/utils/cli/src/scan/index.mjs b/packages/utils/cli/src/scan/index.mjs index 4aef88078..db1d0a59c 100644 --- a/packages/utils/cli/src/scan/index.mjs +++ b/packages/utils/cli/src/scan/index.mjs @@ -10,7 +10,7 @@ import { scanDirectories } from './utils/scan-directories.mjs' const DEFAULT_CONFIG = { adoption: { details: false, - alpha: false, + sort: 'count', imports: ['@spark-ui'], extensions: ['.tsx', '.ts'], directory: '.', @@ -60,7 +60,7 @@ export async function adoption(options) { }) // Sort importsUsed by alphabet - if (config.adoption.alpha) { + if (config.adoption.sort === 'alphabetical') { importsUsed = Object.fromEntries( Object.entries(importsUsed) .sort(([pkgNameA], [pkgNameB]) => pkgNameA.localeCompare(pkgNameB)) @@ -79,7 +79,7 @@ export async function adoption(options) { ] }) ) - } else { + } else if (config.adoption.sort === 'count') { // Sort importsUsed by most used importsUsed = Object.fromEntries( Object.entries(importsUsed) From fbde0e86467947dae71768eca62e9182413ab1dc Mon Sep 17 00:00:00 2001 From: andresin87 Date: Tue, 23 Apr 2024 16:39:46 +0200 Subject: [PATCH 10/20] chore: remove unnecesary file --- .spark-ui.cjs | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .spark-ui.cjs diff --git a/.spark-ui.cjs b/.spark-ui.cjs deleted file mode 100644 index e69de29bb..000000000 From fda53275c5405c2aa41993de74f87d8d21bc57da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 08:44:58 +0000 Subject: [PATCH 11/20] build(npm): bump ejs from 3.1.9 to 3.1.10 Bumps [ejs](https://github.com/mde/ejs) from 3.1.9 to 3.1.10. - [Release notes](https://github.com/mde/ejs/releases) - [Commits](https://github.com/mde/ejs/compare/v3.1.9...v3.1.10) --- updated-dependencies: - dependency-name: ejs dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a900c5d90..e17130d39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18065,9 +18065,9 @@ "dev": true }, "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, "dependencies": { "jake": "^10.8.5" From adf4c8b137d89ca3d6c5b6ace85a14bc37b64e43 Mon Sep 17 00:00:00 2001 From: Powerplex Date: Thu, 2 May 2024 17:17:05 +0200 Subject: [PATCH 12/20] fix(combobox): fix combobox highligh index while typing --- package-lock.json | 1 + .../components/combobox/src/ComboboxContext.tsx | 1 + .../components/combobox/src/ComboboxItem.tsx | 1 + .../src/useCombobox/multipleSelectionReducer.ts | 17 ++++++++++++++--- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 31cb9db0b..9da2d52fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2318,6 +2318,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { diff --git a/packages/components/combobox/src/ComboboxContext.tsx b/packages/components/combobox/src/ComboboxContext.tsx index 22c7731d4..f3e86e323 100644 --- a/packages/components/combobox/src/ComboboxContext.tsx +++ b/packages/components/combobox/src/ComboboxContext.tsx @@ -346,6 +346,7 @@ export const ComboboxProvider = ({ allowCustomValue, setSelectedItems: onInternalSelectedItemsChange, triggerAreaRef, + items: itemsMap, }) : singleSelectionReducer({ allowCustomValue, diff --git a/packages/components/combobox/src/ComboboxItem.tsx b/packages/components/combobox/src/ComboboxItem.tsx index 6b98b9b59..16f75b658 100644 --- a/packages/components/combobox/src/ComboboxItem.tsx +++ b/packages/components/combobox/src/ComboboxItem.tsx @@ -70,6 +70,7 @@ const ItemContent = forwardRef( item: itemCtx.itemData, index: itemCtx.index, }) + const ref = useMergeRefs(forwardedRef, downshiftRef) if (!isVisible) return null diff --git a/packages/components/combobox/src/useCombobox/multipleSelectionReducer.ts b/packages/components/combobox/src/useCombobox/multipleSelectionReducer.ts index 3161d3f5b..dfb88d4f1 100644 --- a/packages/components/combobox/src/useCombobox/multipleSelectionReducer.ts +++ b/packages/components/combobox/src/useCombobox/multipleSelectionReducer.ts @@ -1,10 +1,12 @@ import { useCombobox, UseComboboxProps, UseMultipleSelectionReturnValue } from 'downshift' import React from 'react' -import { ComboboxItem } from '../types' +import { ComboboxItem, ItemsMap } from '../types' +import { getIndexByKey } from '../utils' interface Props { allowCustomValue?: boolean + items: ItemsMap selectedItems: ComboboxItem[] multiselect: UseMultipleSelectionReturnValue setSelectedItems: (items: ComboboxItem[]) => void @@ -17,8 +19,9 @@ export const multipleSelectionReducer = ({ allowCustomValue = false, setSelectedItems, triggerAreaRef, + items, }: Props) => { - const reducer: UseComboboxProps['stateReducer'] = (state, { changes, type }) => { + const reducer: UseComboboxProps['stateReducer'] = (_, { changes, type }) => { const isFocusInsideTriggerArea = triggerAreaRef.current?.contains?.(document.activeElement) switch (type) { @@ -34,7 +37,10 @@ export const multipleSelectionReducer = ({ if (changes.selectedItem != null) { newState.inputValue = '' // keep input value after selection newState.isOpen = true // keep menu opened after selection - newState.highlightedIndex = state.highlightedIndex // preserve highlighted item index after selection + + const highlightedIndex = getIndexByKey(items, changes.selectedItem.value) + + newState.highlightedIndex = highlightedIndex // preserve highlighted item index after selection const isAlreadySelected = multiselect.selectedItems.some( selectedItem => selectedItem.value === changes.selectedItem?.value @@ -55,6 +61,11 @@ export const multipleSelectionReducer = ({ ...changes, inputValue: allowCustomValue ? changes.inputValue : '', } + case useCombobox.stateChangeTypes.InputChange: + return { + ...changes, + selectedItem: changes.highlightedIndex === -1 ? null : changes.selectedItem, + } case useCombobox.stateChangeTypes.InputBlur: return { ...changes, From f40fc78f79ee5626d9047b0a5bd85e8ca9c112b3 Mon Sep 17 00:00:00 2001 From: spark-ui-bot Date: Fri, 3 May 2024 10:30:57 +0000 Subject: [PATCH 13/20] chore: release packages [skip ci] - @spark-ui/combobox@0.12.1 --- package-lock.json | 3 +-- packages/components/combobox/CHANGELOG.md | 6 ++++++ packages/components/combobox/package.json | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9da2d52fe..651880be1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2318,7 +2318,6 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", - "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -35224,7 +35223,7 @@ }, "packages/components/combobox": { "name": "@spark-ui/combobox", - "version": "0.12.0", + "version": "0.12.1", "license": "MIT", "dependencies": { "@spark-ui/form-field": "^1.5.2", diff --git a/packages/components/combobox/CHANGELOG.md b/packages/components/combobox/CHANGELOG.md index 5d659e95e..e57ff1d84 100644 --- a/packages/components/combobox/CHANGELOG.md +++ b/packages/components/combobox/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.12.1](https://github.com/adevinta/spark/compare/@spark-ui/combobox@0.12.0...@spark-ui/combobox@0.12.1) (2024-05-03) + +### Bug Fixes + +- **combobox:** fix combobox highligh index while typing ([adf4c8b](https://github.com/adevinta/spark/commit/adf4c8b137d89ca3d6c5b6ace85a14bc37b64e43)) + # [0.12.0](https://github.com/adevinta/spark/compare/@spark-ui/combobox@0.11.12...@spark-ui/combobox@0.12.0) (2024-05-02) ### Features diff --git a/packages/components/combobox/package.json b/packages/components/combobox/package.json index f2fb31fd5..7367ae7a1 100644 --- a/packages/components/combobox/package.json +++ b/packages/components/combobox/package.json @@ -1,6 +1,6 @@ { "name": "@spark-ui/combobox", - "version": "0.12.0", + "version": "0.12.1", "description": "An input that behaves similarly to a select, with the addition of a free text input to filter options.", "publishConfig": { "access": "public" From 5d945ed8b0a31bf0d42382c560388c95a92f6411 Mon Sep 17 00:00:00 2001 From: spark-ui-bot Date: Fri, 3 May 2024 11:06:20 +0000 Subject: [PATCH 14/20] chore: release packages [skip ci] - @spark-ui/cli-utils@2.13.0 --- package-lock.json | 5 +++-- packages/utils/cli/CHANGELOG.md | 6 ++++++ packages/utils/cli/package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 15e5eaeca..6074f9118 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35811,7 +35811,7 @@ }, "packages/utils/cli": { "name": "@spark-ui/cli-utils", - "version": "2.12.10", + "version": "2.13.0", "license": "MIT", "dependencies": { "@clack/prompts": "0.7.0", @@ -35825,7 +35825,8 @@ }, "bin": { "spark": "bin/spark.mjs", - "spark-generate": "bin/spark-generate.mjs" + "spark-generate": "bin/spark-generate.mjs", + "spark-scan": "bin/spark-scan.mjs" }, "devDependencies": { "@types/fs-extra": "11.0.4" diff --git a/packages/utils/cli/CHANGELOG.md b/packages/utils/cli/CHANGELOG.md index 2c32d8105..509e5bacd 100644 --- a/packages/utils/cli/CHANGELOG.md +++ b/packages/utils/cli/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.13.0](https://github.com/adevinta/spark/compare/@spark-ui/cli-utils@2.12.10...@spark-ui/cli-utils@2.13.0) (2024-05-03) + +### Features + +- **cli-utils:** add scan adoption script ([203e05e](https://github.com/adevinta/spark/commit/203e05e02285be18e5d0c6211f3ec04e4322837d)) + ## [2.12.10](https://github.com/adevinta/spark/compare/@spark-ui/cli-utils@2.12.9...@spark-ui/cli-utils@2.12.10) (2024-04-29) **Note:** Version bump only for package @spark-ui/cli-utils diff --git a/packages/utils/cli/package.json b/packages/utils/cli/package.json index 3c9d5c9ed..c5d70db53 100644 --- a/packages/utils/cli/package.json +++ b/packages/utils/cli/package.json @@ -1,6 +1,6 @@ { "name": "@spark-ui/cli-utils", - "version": "2.12.10", + "version": "2.13.0", "description": "Spark CLI utils", "publishConfig": { "access": "public" From 9e1d55b5b3b73074d233c92aef72ef21236c1de4 Mon Sep 17 00:00:00 2001 From: Powerplex Date: Fri, 3 May 2024 12:26:49 +0200 Subject: [PATCH 15/20] fix(combobox): combobox content overflow on smaller screens --- package-lock.json | 1 + packages/components/combobox/src/ComboboxInput.tsx | 3 ++- packages/components/combobox/src/ComboboxTrigger.tsx | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6074f9118..e10353b59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2318,6 +2318,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { diff --git a/packages/components/combobox/src/ComboboxInput.tsx b/packages/components/combobox/src/ComboboxInput.tsx index e3b30f443..644c6342a 100644 --- a/packages/components/combobox/src/ComboboxInput.tsx +++ b/packages/components/combobox/src/ComboboxInput.tsx @@ -79,7 +79,8 @@ export const Input = forwardRef( type="text" placeholder={placeholder} className={cx( - 'h-sz-28 shrink-0 flex-grow basis-[80px] text-ellipsis bg-surface px-sm text-body-1 outline-none', + 'max-w-full shrink-0 grow basis-[80px]', + 'h-sz-28 text-ellipsis bg-surface px-sm text-body-1 outline-none', 'disabled:cursor-not-allowed disabled:bg-transparent disabled:text-on-surface/dim-3', 'read-only:cursor-default read-only:bg-transparent read-only:text-on-surface', className diff --git a/packages/components/combobox/src/ComboboxTrigger.tsx b/packages/components/combobox/src/ComboboxTrigger.tsx index 2f17d466d..15e00b3ee 100644 --- a/packages/components/combobox/src/ComboboxTrigger.tsx +++ b/packages/components/combobox/src/ComboboxTrigger.tsx @@ -92,14 +92,16 @@ export const Trigger = forwardRef(
{selectedItems} {input}
+ {hasClearButton && clearButton} + {disclosure} From 1d76dfc742bc1c9b35414cadc02fd4d6cfb90ba2 Mon Sep 17 00:00:00 2001 From: Powerplex Date: Fri, 3 May 2024 15:54:13 +0200 Subject: [PATCH 16/20] fix(combobox): missing padding in combobox empty view --- packages/components/combobox/src/ComboboxEmpty.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/components/combobox/src/ComboboxEmpty.tsx b/packages/components/combobox/src/ComboboxEmpty.tsx index ddaa8e736..59ab9560c 100644 --- a/packages/components/combobox/src/ComboboxEmpty.tsx +++ b/packages/components/combobox/src/ComboboxEmpty.tsx @@ -1,3 +1,4 @@ +import { cx } from 'class-variance-authority' import { forwardRef, type ReactNode, type Ref } from 'react' import { useComboboxContext } from './ComboboxContext' @@ -13,7 +14,7 @@ export const Empty = forwardRef( const hasNoItemVisible = ctx.filteredItemsMap.size === 0 return hasNoItemVisible ? ( -
+
{children}
) : null From 4ba34da2a5a8dbec9d48f735b624783d4df5f2fe Mon Sep 17 00:00:00 2001 From: Powerplex Date: Fri, 3 May 2024 16:35:43 +0200 Subject: [PATCH 17/20] fix(combobox): preserve combobox cursor position upon change --- packages/components/combobox/src/ComboboxInput.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/components/combobox/src/ComboboxInput.tsx b/packages/components/combobox/src/ComboboxInput.tsx index 644c6342a..4adbaf065 100644 --- a/packages/components/combobox/src/ComboboxInput.tsx +++ b/packages/components/combobox/src/ComboboxInput.tsx @@ -63,6 +63,15 @@ export const Input = forwardRef( multiselectInputProps.onKeyDown?.(event) ctx.setLastInteractionType('keyboard') }, + /** + * + * Important: + * - without this, the input cursor is moved to the end after every change. + * @see https://github.com/downshift-js/downshift/issues/1108#issuecomment-674180157 + */ + onChange: (e: React.ChangeEvent) => { + ctx.setInputValue(e.target.value) + }, ref: inputRef, }) From 3bb5c6915669b3eacbe2627900862b025d2c7ddb Mon Sep 17 00:00:00 2001 From: Powerplex Date: Mon, 6 May 2024 11:37:06 +0200 Subject: [PATCH 18/20] fix(combobox): clear internal input value on escape --- .../combobox/src/useCombobox/singleSelectionReducer.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/components/combobox/src/useCombobox/singleSelectionReducer.ts b/packages/components/combobox/src/useCombobox/singleSelectionReducer.ts index 9aec4c33f..9a60fcd31 100644 --- a/packages/components/combobox/src/useCombobox/singleSelectionReducer.ts +++ b/packages/components/combobox/src/useCombobox/singleSelectionReducer.ts @@ -19,6 +19,12 @@ export const singleSelectionReducer = ({ ) switch (type) { + case useCombobox.stateChangeTypes.InputKeyDownEscape: + if (!changes.selectedItem) { + setSelectedItem(null) + } + + return changes case useCombobox.stateChangeTypes.ItemClick: case useCombobox.stateChangeTypes.InputKeyDownEnter: if (changes.selectedItem) { From 7b479196b0fcf5be21f2f067fdcb63e1d77c3496 Mon Sep 17 00:00:00 2001 From: Powerplex Date: Mon, 6 May 2024 15:13:16 +0200 Subject: [PATCH 19/20] fix: wrong chmod on new ci script --- packages/utils/cli/bin/spark-scan.mjs | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 packages/utils/cli/bin/spark-scan.mjs diff --git a/packages/utils/cli/bin/spark-scan.mjs b/packages/utils/cli/bin/spark-scan.mjs old mode 100644 new mode 100755 From a12348542901a89721ba11f2ff11d204b09d3d99 Mon Sep 17 00:00:00 2001 From: spark-ui-bot Date: Mon, 6 May 2024 13:31:01 +0000 Subject: [PATCH 20/20] chore: release packages [skip ci] - @spark-ui/combobox@0.12.2 - @spark-ui/cli-utils@2.13.1 --- package-lock.json | 5 ++--- packages/components/combobox/CHANGELOG.md | 9 +++++++++ packages/components/combobox/package.json | 2 +- packages/utils/cli/CHANGELOG.md | 6 ++++++ packages/utils/cli/package.json | 2 +- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index e10353b59..2170b4c23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2318,7 +2318,6 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", - "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -35225,7 +35224,7 @@ }, "packages/components/combobox": { "name": "@spark-ui/combobox", - "version": "0.12.1", + "version": "0.12.2", "license": "MIT", "dependencies": { "@spark-ui/form-field": "^1.5.2", @@ -35812,7 +35811,7 @@ }, "packages/utils/cli": { "name": "@spark-ui/cli-utils", - "version": "2.13.0", + "version": "2.13.1", "license": "MIT", "dependencies": { "@clack/prompts": "0.7.0", diff --git a/packages/components/combobox/CHANGELOG.md b/packages/components/combobox/CHANGELOG.md index e57ff1d84..5095c38fb 100644 --- a/packages/components/combobox/CHANGELOG.md +++ b/packages/components/combobox/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.12.2](https://github.com/adevinta/spark/compare/@spark-ui/combobox@0.12.1...@spark-ui/combobox@0.12.2) (2024-05-06) + +### Bug Fixes + +- **combobox:** clear internal input value on escape ([3bb5c69](https://github.com/adevinta/spark/commit/3bb5c6915669b3eacbe2627900862b025d2c7ddb)) +- **combobox:** combobox content overflow on smaller screens ([9e1d55b](https://github.com/adevinta/spark/commit/9e1d55b5b3b73074d233c92aef72ef21236c1de4)) +- **combobox:** missing padding in combobox empty view ([1d76dfc](https://github.com/adevinta/spark/commit/1d76dfc742bc1c9b35414cadc02fd4d6cfb90ba2)) +- **combobox:** preserve combobox cursor position upon change ([4ba34da](https://github.com/adevinta/spark/commit/4ba34da2a5a8dbec9d48f735b624783d4df5f2fe)) + ## [0.12.1](https://github.com/adevinta/spark/compare/@spark-ui/combobox@0.12.0...@spark-ui/combobox@0.12.1) (2024-05-03) ### Bug Fixes diff --git a/packages/components/combobox/package.json b/packages/components/combobox/package.json index 7367ae7a1..c1601f1be 100644 --- a/packages/components/combobox/package.json +++ b/packages/components/combobox/package.json @@ -1,6 +1,6 @@ { "name": "@spark-ui/combobox", - "version": "0.12.1", + "version": "0.12.2", "description": "An input that behaves similarly to a select, with the addition of a free text input to filter options.", "publishConfig": { "access": "public" diff --git a/packages/utils/cli/CHANGELOG.md b/packages/utils/cli/CHANGELOG.md index 509e5bacd..3feff0603 100644 --- a/packages/utils/cli/CHANGELOG.md +++ b/packages/utils/cli/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.13.1](https://github.com/adevinta/spark/compare/@spark-ui/cli-utils@2.13.0...@spark-ui/cli-utils@2.13.1) (2024-05-06) + +### Bug Fixes + +- wrong chmod on new ci script ([7b47919](https://github.com/adevinta/spark/commit/7b479196b0fcf5be21f2f067fdcb63e1d77c3496)) + # [2.13.0](https://github.com/adevinta/spark/compare/@spark-ui/cli-utils@2.12.10...@spark-ui/cli-utils@2.13.0) (2024-05-03) ### Features diff --git a/packages/utils/cli/package.json b/packages/utils/cli/package.json index c5d70db53..b889ce3da 100644 --- a/packages/utils/cli/package.json +++ b/packages/utils/cli/package.json @@ -1,6 +1,6 @@ { "name": "@spark-ui/cli-utils", - "version": "2.13.0", + "version": "2.13.1", "description": "Spark CLI utils", "publishConfig": { "access": "public"