Skip to content

Commit

Permalink
feat(generation): generate playgrounds for guides (#3098)
Browse files Browse the repository at this point in the history
* Conditional prompting

* Improve console.log copy

* Adjust templates for guide playground generation

* Add validation

---------

Co-authored-by: Brandy Carney <[email protected]>
  • Loading branch information
mapsandapps and brandyscarney authored Aug 28, 2023
1 parent ab5c450 commit f593596
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 80 deletions.
4 changes: 2 additions & 2 deletions _templates/playground/new/angular.md.ejs.t
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
# this file's location depends on whether or not the css option or angular_ts option is selected via the prompt
to: "<%= `static/usage/v${version}/${name.replace('ion-', '')}/${path}/${(css || angular_ts) ? 'angular/example_component_html.md' : 'angular.md'}` %>"
to: "<%= `static/usage/v${version}/${name}/${path}/${(css || angular_ts) ? 'angular/example_component_html.md' : 'angular.md'}` %>"
---
```html
<<%= name %>></<%= name %>>
<<%= component %>></<%= component %>>
```
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
# this file only gets generated if `css` (from the command line prompt) is true
to: "<%= css ? `static/usage/v${version}/${name.replace('ion-', '')}/${path}/angular/example_component_css.md` : null %>"
to: "<%= css ? `static/usage/v${version}/${name}/${path}/angular/example_component_css.md` : null %>"
---
```css
<%= name %> {
<%= component %> {
/* styles go here */
}
```
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
# this file only gets generated if `angular_ts` (from the command line prompt) is true
to: "<%= angular_ts ? `static/usage/v${version}/${name.replace('ion-', '')}/${path}/angular/example_component_ts.md` : null %>"
to: "<%= angular_ts ? `static/usage/v${version}/${name}/${path}/angular/example_component_ts.md` : null %>"
---
```ts
import { Component } from '@angular/core';
Expand Down
10 changes: 5 additions & 5 deletions _templates/playground/new/demo.html.ejs.t
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
---
arbitrary: <% nameWithoutIon = name.replace('ion-', ''); numberOfAncestors = (path.match(/\//g) || []).length; directoryChanges = '../'.repeat(numberOfAncestors) %>
to: "<%= `static/usage/v${version}/${nameWithoutIon}/${path}/demo.html` %>"
arbitrary: <% numberOfAncestors = (path.match(/\//g) || []).length; directoryChanges = '../'.repeat(numberOfAncestors) %>
to: "<%= `static/usage/v${version}/${name}/${path}/demo.html` %>"
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= h.changeCase.titleCase(nameWithoutIon) %></title>
<title><%= h.changeCase.titleCase(name) %></title>
<link rel="stylesheet" href="<%= directoryChanges %>../../../common.css" />
<script src="<%= directoryChanges %>../../../common.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@<%= version %>/dist/ionic/ionic.esm.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@<%= version %>/css/ionic.bundle.css" /><% if (css){ %>
<style>
<%= name %> {
<%= component %> {
/* styles go here */
}
</style><% } %>
Expand All @@ -24,7 +24,7 @@ to: "<%= `static/usage/v${version}/${nameWithoutIon}/${path}/demo.html` %>"
<ion-app>
<ion-content>
<div class="container">
<<%= name %>></<%= name %>>
<<%= component %>></<%= component %>>
</div>
</ion-content>
</ion-app>
Expand Down
127 changes: 75 additions & 52 deletions _templates/playground/new/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,83 @@ const changeCase = require('change-case');
//
module.exports = {
prompt: ({ inquirer }) => {
const questions = [
{
type: 'input',
name: 'name',
message: 'Which component is this playground for?',
initial: 'ion-button',
validate(value) {
return value.match(/^ion-[a-z/-]*[a-z]+$/) ? true : "Component name must be kebab-case and begin with 'ion-'";
return inquirer
.prompt([
{
type: 'toggle',
name: 'is_component',
message: 'Is this playground for a component?',
initial: true,
},
},
{
type: 'input',
name: 'path',
message: 'What should the playground path be?',
hint: 'e.g. `basic` or `theming/colors`',
validate(value) {
return value.match(/^[a-z]+[a-z/-]*[a-z]+$/)
? true
: "Path should begin and end with a letter and only contain lowercase letters, '-', or '/'";
},
},
{
type: 'select',
name: 'version',
message: 'Select the Ionic Framework version for the playground',
initial: '7',
choices: ['6', '7'],
},
{
type: 'toggle',
name: 'css',
message: 'Generate custom CSS files?',
enabled: 'Yes',
disabled: 'No',
},
{
type: 'toggle',
name: 'angular_ts',
message: 'Generate an Angular TypeScript file?',
enabled: 'Yes',
disabled: 'No',
},
];
])
.then((answers) => {
return inquirer
.prompt([
// ask a different question for components vs. other playgrounds
answers.is_component
? {
type: 'input',
name: 'component',
message: 'Which component is this playground for?',
initial: 'ion-button',
validate(value) {
return value.match(/^ion-[a-z/-]*[a-z]+$/)
? true
: "Component name must be kebab-case and begin with 'ion-'";
},
}
: {
type: 'input',
name: 'name',
message: 'Which guide section is this playground for?',
initial: 'animations',
validate(value) {
return value.match(/^[a-z/-]+$/) ? true : 'Section must be kebab-case';
},
},
{
type: 'input',
name: 'path',
message: 'What should the playground path be?',
hint: 'e.g. `basic` or `theming/colors`',
validate(value) {
return value.match(/^[a-z]+[a-z/-]*[a-z]+$/)
? true
: "Path should begin and end with a letter and only contain lowercase letters, '-', or '/'";
},
},
{
type: 'select',
name: 'version',
message: 'Select the Ionic Framework version for the playground',
initial: '7',
choices: ['6', '7'],
},
{
type: 'toggle',
name: 'css',
message: 'Generate custom CSS files?',
},
{
type: 'toggle',
name: 'angular_ts',
message: 'Generate an Angular TypeScript file?',
},
])
.then((answers) => {
answers.name = answers.name || answers.component.replace('ion-', '');

// if the playground is not for a component,
// include an ion-card in the playground
answers.component = answers.component || 'ion-card';

return inquirer.prompt(questions).then((answers) => {
const componentName = changeCase.pascal(answers.path.split('/').pop());
console.log(
`\nTo use this component in a docs markdown file, include\nthe following:\n\n## ${componentName}\n\nimport ${componentName} from '@site/static/usage/v7/${answers.name.replace(
'ion-',
''
)}/${answers.path}/index.md';\n\n<${componentName} />\n`
);
const playgroundName = changeCase.pascal(answers.path.split('/').pop());
console.log(
`\nTo use this playground in a docs markdown file, include\nthe following:\n\n## ${playgroundName}\n\nimport ${playgroundName} from '@site/static/usage/v7/${answers.name}/${answers.path}/index.md';\n\n<${playgroundName} />\n`
);

return answers;
});
return answers;
});
});
},
};
5 changes: 2 additions & 3 deletions _templates/playground/new/index.md.ejs.t
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
arbitrary: <% nameWithoutIon = name.replace('ion-', '') %>
to: "<%= `static/usage/v${version}/${nameWithoutIon}/${path}/index.md` %>"
to: "<%= `static/usage/v${version}/${name}/${path}/index.md` %>"
---
import Playground from '@site/src/components/global/Playground';

Expand Down Expand Up @@ -56,5 +55,5 @@ import angular_example_component_css from './angular/example_component_css.md';
angular,
<% } -%>
}}
src="usage/v<%= version %>/<%= nameWithoutIon %>/<%= path %>/demo.html"
src="usage/v<%= version %>/<%= name %>/<%= path %>/demo.html"
/>
6 changes: 3 additions & 3 deletions _templates/playground/new/javascript.md.ejs.t
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
to: "<%= `static/usage/v${version}/${name.replace('ion-', '')}/${path}/javascript.md` %>"
to: "<%= `static/usage/v${version}/${name}/${path}/javascript.md` %>"
---
```html
<<%= name %>></<%= name %>>
<<%= component %>></<%= component %>>
<% if (css){ -%>
<style>
<%= name %> {
<%= component %> {
/* styles go here */
}
</style>
Expand Down
8 changes: 4 additions & 4 deletions _templates/playground/new/react.md.ejs.t
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
arbitrary: <% pascalName = h.changeCase.pascal(name) %>
arbitrary: <% pascalComponent = h.changeCase.pascal(component) %>
# this file's location depends on whether or not the css option is selected via the prompt
to: "<%= `static/usage/v${version}/${name.replace('ion-', '')}/${path}/${css ? 'react/main_tsx.md' : 'react.md'}` %>"
to: "<%= `static/usage/v${version}/${name}/${path}/${css ? 'react/main_tsx.md' : 'react.md'}` %>"
---
```tsx
import React from 'react';
import { <%= pascalName %> } from '@ionic/react';<% if (css){ %>
import { <%= pascalComponent %> } from '@ionic/react';<% if (css){ %>
import './main.css';<% } %>

function Example() {
return (
<<%= pascalName %>></<%= pascalName %>>
<<%= pascalComponent %>></<%= pascalComponent %>>
);
}
export default Example;
Expand Down
4 changes: 2 additions & 2 deletions _templates/playground/new/react_main_css.md.ejs.t
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
# this file only gets generated if `css` (from the command line prompt) is true
to: "<%= css ? `static/usage/v${version}/${name.replace('ion-', '')}/${path}/react/main_css.md` : null %>"
to: "<%= css ? `static/usage/v${version}/${name}/${path}/react/main_css.md` : null %>"
---
```css
<%= name %> {
<%= component %> {
/* styles go here */
}
```
12 changes: 6 additions & 6 deletions _templates/playground/new/vue.md.ejs.t
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
---
arbitrary: <% pascalName = h.changeCase.pascal(name) %>
to: "<%= `static/usage/v${version}/${name.replace('ion-', '')}/${path}/vue.md` %>"
arbitrary: <% pascalComponent = h.changeCase.pascal(component) %>
to: "<%= `static/usage/v${version}/${name}/${path}/vue.md` %>"
---
```html
<template>
<<%= name %>></<%= name %>>
<<%= component %>></<%= component %>>
</template>

<script lang="ts">
import { <%= pascalName %> } from '@ionic/vue';
import { <%= pascalComponent %> } from '@ionic/vue';
import { defineComponent } from 'vue';
export default defineComponent({
components: {
<%= pascalName %>,
<%= pascalComponent %>,
},
});
</script>
<% if (css){ -%>
<style scoped>
<%= name %> {
<%= component %> {
/* styles go here */
}
</style>
Expand Down

1 comment on commit f593596

@vercel
Copy link

@vercel vercel bot commented on f593596 Aug 28, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

ionic-docs – ./

ionic-docs-git-main-ionic1.vercel.app
ionic-docs-gqykycf8t.vercel.app
ionic-docs-ionic1.vercel.app

Please sign in to comment.