kopia lustrzana https://github.com/shoelace-style/shoelace
				
				
				
			use plop for npm run create
							rodzic
							
								
									94fe4f1f46
								
							
						
					
					
						commit
						19dba93cca
					
				|  | @ -1,3 +1,4 @@ | |||
| *.hbs | ||||
| *.md | ||||
| .cache | ||||
| .github | ||||
|  |  | |||
|  | @ -48,6 +48,7 @@ | |||
|   - [Tag](/components/tag) | ||||
|   - [Textarea](/components/textarea) | ||||
|   - [Tooltip](/components/tooltip) | ||||
|   <!--plop:component--> | ||||
| 
 | ||||
| - Utilities | ||||
|   - [Animation](/components/animation) | ||||
|  |  | |||
										
											
												Plik diff jest za duży
												Load Diff
											
										
									
								
							|  | @ -33,7 +33,7 @@ | |||
|     "build": "node scripts/build.js", | ||||
|     "prepublishOnly": "npm run build && npm run test", | ||||
|     "prettier": "prettier --write --loglevel warn .", | ||||
|     "create": "node scripts/create-component.js", | ||||
|     "create": "plop --plopfile scripts/plop/plopfile.cjs", | ||||
|     "test": "web-test-runner \"src/**/*.test.ts\" --node-resolve --puppeteer", | ||||
|     "test:watch": "web-test-runner \"src/**/*.test.ts\" --node-resolve --puppeteer --watch" | ||||
|   }, | ||||
|  | @ -66,6 +66,7 @@ | |||
|     "front-matter": "^4.0.2", | ||||
|     "get-port": "^5.1.1", | ||||
|     "husky": "^4.3.8", | ||||
|     "plop": "^2.7.4", | ||||
|     "prettier": "^2.2.1", | ||||
|     "recursive-copy": "^2.0.11", | ||||
|     "sass": "^1.32.7", | ||||
|  |  | |||
|  | @ -1,153 +0,0 @@ | |||
| import chalk from 'chalk'; | ||||
| import fs from 'fs'; | ||||
| import mkdirp from 'mkdirp'; | ||||
| import path from 'path'; | ||||
| import process from 'process'; | ||||
| 
 | ||||
| const args = process.argv.slice(2); | ||||
| const tagName = (args[0] + '').toLowerCase().trim(); | ||||
| const tagNameWithoutPrefix = tagName.replace(/^sl-/, ''); | ||||
| const className = tagName.replace(/(^\w|-\w)/g, string => string.replace(/-/, '').toUpperCase()); | ||||
| const readableName = tagNameWithoutPrefix | ||||
|   .replace(/-/g, ' ') | ||||
|   .replace(/\w\S*/g, string => string.charAt(0).toUpperCase() + string.substr(1).toLowerCase()); | ||||
| 
 | ||||
| const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8')); | ||||
| const minorVersion = packageData.version.split('.').slice(0, 2).join('.'); | ||||
| 
 | ||||
| // Check for tag name
 | ||||
| if (!tagName) { | ||||
|   console.error('Please provide a tag name for the new component.\n'); | ||||
|   process.exit(); | ||||
| } | ||||
| 
 | ||||
| // Verify tag name prefix
 | ||||
| if (!/^sl-/.test(tagName)) { | ||||
|   console.error('Tag names must start with the sl- prefix.\n'); | ||||
|   process.exit(); | ||||
| } | ||||
| 
 | ||||
| // Generate a source file
 | ||||
| const componentFile = `src/components/${tagNameWithoutPrefix}/${tagNameWithoutPrefix}.ts`; | ||||
| if (fs.existsSync(componentFile)) { | ||||
|   console.error(`There is already a component using the <${tagName}> tag!\n`); | ||||
|   process.exit(); | ||||
| } | ||||
| 
 | ||||
| const componentSource = ` | ||||
| import { LitElement, html, unsafeCSS } from 'lit'; | ||||
| import { customElement } from 'lit/decorators.js'; | ||||
| import styles from 'sass:./${tagNameWithoutPrefix}.scss'; | ||||
| 
 | ||||
| /** | ||||
|  * @since ${minorVersion} | ||||
|  * @status experimental | ||||
|  * | ||||
|  * @dependency sl-tag-here | ||||
|  * @dependency sl-tag-here | ||||
|  * | ||||
|  * @slot - The default slot. | ||||
|  * @slot example - A named slot called example. | ||||
|  * | ||||
|  * @part base - The component's base wrapper. | ||||
|  * | ||||
|  * @customProperty example - An example custom property | ||||
|  * | ||||
|  * @animation example.show - An example animation. | ||||
|  * @animation example.hide - An example animation. | ||||
|  */ | ||||
| @customElement('${tagName}') | ||||
| export default class ${className} extends LitElement { | ||||
|   static styles = unsafeCSS(styles); | ||||
| 
 | ||||
|   render() { | ||||
|     return html\` | ||||
|       <div part="base"> | ||||
|         <slot></slot> | ||||
|       </div> | ||||
|     \`;
 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| declare global { | ||||
|   interface HTMLElementTagNameMap { | ||||
|     '${tagName}': ${className}; | ||||
|   } | ||||
| } | ||||
| `.trimLeft();
 | ||||
| 
 | ||||
| // Generate a stylesheet
 | ||||
| const stylesFile = `src/components/${tagNameWithoutPrefix}/${tagNameWithoutPrefix}.scss`; | ||||
| const stylesSource = ` | ||||
| @use '../../styles/component'; | ||||
| 
 | ||||
| :host { | ||||
|   display: block; | ||||
| } | ||||
| `.trimLeft();
 | ||||
| 
 | ||||
| // Generate a docs page
 | ||||
| const docsFile = `docs/components/${tagNameWithoutPrefix}.md`; | ||||
| const docsSource = ` | ||||
| # ${readableName} | ||||
| 
 | ||||
| [component-header:${tagName}] | ||||
| 
 | ||||
| Brief description of the component here, followed by an example. | ||||
| 
 | ||||
| \`\`\`html preview
 | ||||
| <${tagName}> | ||||
|   Hello, world! | ||||
| </${tagName}> | ||||
| \`\`\` | ||||
| 
 | ||||
| ## Examples | ||||
| 
 | ||||
| ### Variation | ||||
| 
 | ||||
| A description of the variation, followed by an example. | ||||
| 
 | ||||
| \`\`\`html preview
 | ||||
| <${tagName}> | ||||
|   Here is a variation | ||||
| </${tagName}> | ||||
| \`\`\` | ||||
| 
 | ||||
| [component-metadata:${tagName}] | ||||
| `.trimLeft();
 | ||||
| 
 | ||||
| // Create the files
 | ||||
| mkdirp.sync(path.dirname(componentFile)); | ||||
| mkdirp.sync(path.dirname(stylesFile)); | ||||
| mkdirp.sync(path.dirname(docsFile)); | ||||
| 
 | ||||
| fs.writeFileSync(componentFile, componentSource, 'utf8'); | ||||
| fs.writeFileSync(stylesFile, stylesSource, 'utf8'); | ||||
| fs.writeFileSync(docsFile, docsSource, 'utf8'); | ||||
| 
 | ||||
| // Add it to shoelace.ts
 | ||||
| const allExports = fs.readFileSync('src/shoelace.ts', 'utf8'); | ||||
| fs.writeFileSync( | ||||
|   'src/shoelace.ts', | ||||
|   `${allExports.trimRight()}\nexport { default as ${className} } from './components/${tagNameWithoutPrefix}/${tagNameWithoutPrefix}';\n`, | ||||
|   'utf8' | ||||
| ); | ||||
| 
 | ||||
| // Add it to _sidebar.md
 | ||||
| const sidebar = fs.readFileSync('docs/_sidebar.md', 'utf8'); | ||||
| fs.writeFileSync( | ||||
|   'docs/_sidebar.md', | ||||
|   sidebar.replace('- Components', `- Components\n  - [${readableName}](/components/${tagNameWithoutPrefix}.md)`), | ||||
|   'utf8' | ||||
| ); | ||||
| 
 | ||||
| console.log(chalk.green(`The <${tagName}> component has been created:`)); | ||||
| console.log(` | ||||
| - created ${componentFile} | ||||
| - created ${stylesFile} | ||||
| - created ${docsFile} | ||||
| - updated src/shoelace.ts | ||||
| - updated docs/_sidebar.md | ||||
| 
 | ||||
| Use ${chalk.cyan('npm start')} to launch the dev server. | ||||
| `);
 | ||||
|  | @ -0,0 +1,67 @@ | |||
| module.exports = function (plop) { | ||||
|   plop.setHelper('tagWithoutPrefix', tag => tag.replace(/^sl-/, '')); | ||||
| 
 | ||||
|   plop.setHelper('tagToTitle', tag => { | ||||
|     const withoutPrefix = plop.getHelper('tagWithoutPrefix'); | ||||
|     const titleCase = plop.getHelper('titleCase'); | ||||
|     return titleCase(withoutPrefix(tag)); | ||||
|   }); | ||||
| 
 | ||||
|   plop.setGenerator('component', { | ||||
|     description: 'Generate a new component', | ||||
|     prompts: [ | ||||
|       { | ||||
|         type: 'input', | ||||
|         name: 'tag', | ||||
|         message: 'Tag name? (e.g. sl-button)', | ||||
|         validate: value => { | ||||
|           // Start with sl- and include only a-z + dashes
 | ||||
|           if (!/^sl-[a-z-+]+/.test(value)) { | ||||
|             return false; | ||||
|           } | ||||
| 
 | ||||
|           // No double dashes or ending dash
 | ||||
|           if (value.includes('--') || value.endsWith('-')) { | ||||
|             return false; | ||||
|           } | ||||
| 
 | ||||
|           return true; | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     actions: [ | ||||
|       { | ||||
|         type: 'add', | ||||
|         path: '../../src/components/{{ tagWithoutPrefix tag }}/{{ tagWithoutPrefix tag }}.ts', | ||||
|         templateFile: 'templates/component/component.hbs' | ||||
|       }, | ||||
|       { | ||||
|         type: 'add', | ||||
|         path: '../../src/components/{{ tagWithoutPrefix tag }}/{{ tagWithoutPrefix tag }}.scss', | ||||
|         templateFile: 'templates/component/styles.hbs' | ||||
|       }, | ||||
|       { | ||||
|         type: 'add', | ||||
|         path: '../../src/components/{{ tagWithoutPrefix tag }}/{{ tagWithoutPrefix tag }}.test.ts', | ||||
|         templateFile: 'templates/component/tests.hbs' | ||||
|       }, | ||||
|       { | ||||
|         type: 'add', | ||||
|         path: '../../docs/components/{{ tagWithoutPrefix tag }}.md', | ||||
|         templateFile: 'templates/component/docs.hbs' | ||||
|       }, | ||||
|       { | ||||
|         type: 'modify', | ||||
|         path: '../../docs/_sidebar.md', | ||||
|         pattern: /<!--plop:component-->/, | ||||
|         template: `- [{{ tagToTitle tag }}](/components/{{ tagWithoutPrefix tag }})\n  <!--plop:component-->` | ||||
|       }, | ||||
|       { | ||||
|         type: 'modify', | ||||
|         path: '../../src/shoelace.ts', | ||||
|         pattern: /\/\* plop:component \*\//, | ||||
|         template: `export { default as {{ properCase tag }} } from './components/{{ tagWithoutPrefix tag }}/{{ tagWithoutPrefix tag }}';\n/* plop:component */` | ||||
|       } | ||||
|     ] | ||||
|   }); | ||||
| }; | ||||
|  | @ -0,0 +1,36 @@ | |||
| import { LitElement, html, unsafeCSS } from 'lit'; | ||||
| import { customElement, property } from 'lit/decorators.js'; | ||||
| import { event, EventEmitter } from '../../internal/decorators'; | ||||
| import styles from 'sass:./{{ tagWithoutPrefix tag }}.scss'; | ||||
| 
 | ||||
| /** | ||||
|  * @since 2.0 | ||||
|  * @status experimental | ||||
|  * | ||||
|  * @dependency sl-example | ||||
|  * | ||||
|  * @slot - The default slot. | ||||
|  * @slot example - An example slot. | ||||
|  * | ||||
|  * @part base - The component's base wrapper. | ||||
|  */ | ||||
| @customElement('{{ tag }}') | ||||
| export default class {{ properCase tag }} extends LitElement { | ||||
|   static styles = unsafeCSS(styles); | ||||
| 
 | ||||
|   /** An example property. */ | ||||
|   @property() prop = 'example'; | ||||
| 
 | ||||
|   /** An example event. */ | ||||
|   @event('sl-event') slEvent: EventEmitter<void>; | ||||
| 
 | ||||
|   render() { | ||||
|     return html` <slot></slot> `; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| declare global { | ||||
|   interface HTMLElementTagNameMap { | ||||
|     '{{ tag }}': {{ properCase tag }}; | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,21 @@ | |||
| # {{ tagToTitle tag }} | ||||
| 
 | ||||
| [component-header:{{ tag }}] | ||||
| 
 | ||||
| A description of the component goes here. | ||||
| 
 | ||||
| ```html preview | ||||
| <{{ tag }}></{{ tag }}> | ||||
| ``` | ||||
| 
 | ||||
| ## Examples | ||||
| 
 | ||||
| ### First Example | ||||
| 
 | ||||
| TODO | ||||
| 
 | ||||
| ### Second Example | ||||
| 
 | ||||
| TODO | ||||
| 
 | ||||
| [component-metadata:{{ tag }}] | ||||
|  | @ -0,0 +1 @@ | |||
| @use '../../styles/component'; | ||||
|  | @ -0,0 +1,13 @@ | |||
| import { expect, fixture, html, waitUntil } from '@open-wc/testing'; | ||||
| // import sinon from 'sinon'; | ||||
| 
 | ||||
| import '../../../dist/shoelace.js'; | ||||
| import type {{ properCase tag }} from './{{ tagWithoutPrefix tag }}'; | ||||
| 
 | ||||
| describe('<{{ tag }}>', () => { | ||||
|   it('should render a component', async () => { | ||||
|     const el = await fixture(html` <{{ tag }}></{{ tag }}> `); | ||||
| 
 | ||||
|     expect(el).to.exist; | ||||
|   }); | ||||
| }); | ||||
|  | @ -45,6 +45,7 @@ export { default as SlTabPanel } from './components/tab-panel/tab-panel'; | |||
| export { default as SlTag } from './components/tag/tag'; | ||||
| export { default as SlTextarea } from './components/textarea/textarea'; | ||||
| export { default as SlTooltip } from './components/tooltip/tooltip'; | ||||
| /* plop:component */ | ||||
| 
 | ||||
| // Utilities
 | ||||
| export * from './utilities/animation'; | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Cory LaViska
						Cory LaViska