0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

[create-astro] Finalize developer experience... with gradients 🚀 (#3313)

* wip: port gradient helpers from sandbox ideas

* feat: wire up rocket gradient 🚀

* feat: wire up rocket gradient on install step

* refactor: update "next steps" wording

* deps: add chalk (for rendering gradient)

* chore: changeset

* chore: clean up sstray template string
This commit is contained in:
Ben Holmes 2022-05-11 10:38:42 -06:00 committed by GitHub
parent f40705d906
commit 1a5335ed9a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 124 additions and 24 deletions

View file

@ -0,0 +1,5 @@
---
'create-astro': patch
---
Update "next steps" with more informative text on each CLI command. Oh, and gradients. A lot more gradients.

View file

@ -30,6 +30,7 @@
"dependencies": {
"@types/degit": "^2.8.3",
"@types/prompts": "^2.0.14",
"chalk": "^5.0.1",
"degit": "^2.8.4",
"execa": "^6.1.0",
"kleur": "^4.1.4",

View file

@ -0,0 +1,91 @@
import chalk from 'chalk';
import ora from 'ora';
import type { Ora } from 'ora';
const gradientColors = [
`#ff5e00`,
`#ff4c29`,
`#ff383f`,
`#ff2453`,
`#ff0565`,
`#ff007b`,
`#f5008b`,
`#e6149c`,
`#d629ae`,
`#c238bd`,
];
export const rocketAscii = '■■▶';
// get a reference to scroll through while loading
// visual representation of what this generates:
// gradientColors: "..xxXX"
// referenceGradient: "..xxXXXXxx....xxXX"
const referenceGradient = [
...gradientColors,
// draw the reverse of the gradient without
// accidentally mutating the gradient (ugh, reverse())
...[...gradientColors].reverse(),
...gradientColors,
];
// async-friendly setTimeout
const sleep = (time: number) =>
new Promise((resolve) => {
setTimeout(resolve, time);
});
function getGradientAnimFrames() {
const frames = [];
for (let start = 0; start < gradientColors.length * 2; start++) {
const end = start + gradientColors.length - 1;
frames.push(
referenceGradient
.slice(start, end)
.map((g) => chalk.bgHex(g)(' '))
.join('')
);
}
return frames;
}
function getIntroAnimFrames() {
const frames = [];
for (let end = 1; end <= gradientColors.length; end++) {
const leadingSpacesArr = Array.from(
new Array(Math.abs(gradientColors.length - end - 1)),
() => ' '
);
const gradientArr = gradientColors.slice(0, end).map((g) => chalk.bgHex(g)(' '));
frames.push([...leadingSpacesArr, ...gradientArr].join(''));
}
return frames;
}
/**
* Generate loading spinner with rocket flames!
* @param text display text next to rocket
* @returns Ora spinner for running .stop()
*/
export async function loadWithRocketGradient(text: string): Promise<Ora> {
const frames = getIntroAnimFrames();
const intro = ora({
spinner: {
interval: 30,
frames,
},
text: `${rocketAscii} ${text}`,
});
intro.start();
await sleep((frames.length - 1) * intro.interval);
intro.stop();
const spinner = ora({
spinner: {
interval: 80,
frames: getGradientAnimFrames(),
},
text: `${rocketAscii} ${text}`,
}).start();
return spinner;
}

View file

@ -8,6 +8,7 @@ import ora from 'ora';
import { TEMPLATES } from './templates.js';
import { logger, defaultLogLevel } from './logger.js';
import { execa, execaCommand } from 'execa';
import { loadWithRocketGradient, rocketAscii } from './gradient.js';
// NOTE: In the v7.x version of npm, the default behavior of `npm init` was changed
// to no longer require `--` to pass args and instead pass `--` directly to us. This
@ -42,10 +43,6 @@ export async function main() {
logger.debug('Verbose logging turned on');
console.log(`\n${bold('Welcome to Astro!')} ${gray(`(create-astro v${version})`)}`);
let spinner = ora({ color: 'green', text: 'Prepare for liftoff.' });
spinner.succeed();
let cwd = args['_'][2] as string;
if (cwd && isEmpty(cwd)) {
@ -95,6 +92,8 @@ export async function main() {
process.exit(1);
}
const templateSpinner = await loadWithRocketGradient('Copying project files...');
const hash = args.commit ? `#${args.commit}` : '';
const templateTarget = `withastro/astro/examples/${options.template}#latest`;
@ -111,8 +110,6 @@ export async function main() {
verbose: defaultLogLevel === 'debug' ? true : false,
});
spinner = ora({ color: 'green', text: 'Copying project files...' }).start();
// Copy
if (!args.dryrun) {
try {
@ -152,7 +149,7 @@ export async function main() {
)
);
}
spinner.fail();
templateSpinner.fail();
process.exit(1);
}
@ -167,8 +164,8 @@ export async function main() {
);
}
spinner.succeed();
console.log(bold(green('✔') + ' Done!'));
templateSpinner.text = green('Template copied!');
templateSpinner.succeed();
const installResponse = await prompts({
type: 'confirm',
@ -184,15 +181,18 @@ export async function main() {
if (installResponse.install && !args.dryrun) {
const installExec = execa(pkgManager, ['install'], { cwd });
const installingPackagesMsg = `Installing packages${emojiWithFallback(' 📦', '...')}`;
spinner = ora({ color: 'green', text: installingPackagesMsg }).start();
const installSpinner = await loadWithRocketGradient(installingPackagesMsg);
await new Promise<void>((resolve, reject) => {
installExec.stdout?.on('data', function (data) {
spinner.text = `${installingPackagesMsg}\n${bold(`[${pkgManager}]`)} ${data}`;
installSpinner.text = `${rocketAscii} ${installingPackagesMsg}\n${bold(
`[${pkgManager}]`
)} ${data}`;
});
installExec.on('error', (error) => reject(error));
installExec.on('close', () => resolve());
});
spinner.succeed();
installSpinner.text = green('Packages installed!');
installSpinner.succeed();
}
const astroAddCommand = installResponse.install
@ -240,21 +240,22 @@ export async function main() {
await execaCommand('git init', { cwd });
}
ora({ text: green('Done. Ready for liftoff!') }).succeed();
console.log(`\n${bgCyan(black(' Next steps '))}\n`);
const relative = path.relative(process.cwd(), cwd);
const startCommand = [];
if (relative !== '') {
startCommand.push(bold(cyan(`cd ${relative}`)));
}
if (!installResponse.install) {
startCommand.push(bold(cyan(`${pkgManager} install`)));
}
startCommand.push(bold(cyan(pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`)));
console.log(startCommand.join(' && '));
const projectDir = path.relative(process.cwd(), cwd);
const devCmd = pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`;
console.log(`\nTo close the dev server, hit ${bold(cyan('Ctrl-C'))}`);
console.log(`Stuck? Visit us at ${cyan('https://astro.build/chat')}\n`);
console.log(
`You can now ${bold(cyan('cd'))} into the ${bold(cyan(projectDir))} project directory.`
);
console.log(
`Run ${bold(cyan(devCmd))} to start the Astro dev server. ${bold(cyan('CTRL-C'))} to close.`
);
if (!installResponse.install) {
console.log(yellow(`Remember to install dependencies first!`));
}
console.log(`\nStuck? Come join us at ${bold(cyan('https://astro.build/chat'))}`);
}
function emojiWithFallback(char: string, fallback: string) {

View file

@ -1256,6 +1256,7 @@ importers:
'@types/yargs-parser': ^21.0.0
astro-scripts: workspace:*
chai: ^4.3.6
chalk: ^5.0.1
degit: ^2.8.4
execa: ^6.1.0
kleur: ^4.1.4
@ -1267,6 +1268,7 @@ importers:
dependencies:
'@types/degit': 2.8.3
'@types/prompts': 2.0.14
chalk: 5.0.1
degit: 2.8.4
execa: 6.1.0
kleur: 4.1.4