Skip to content

Commit 2892a71

Browse files
authored
feat(create-rstack): add Svelte library templates (#261)
1 parent 53f0c65 commit 2892a71

22 files changed

Lines changed: 513 additions & 0 deletions

File tree

‎packages/create-rstack/README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ npx create-rstack -d my-project -t app-vanilla-ts
4141
- `lib-react-ts` - TypeScript React library
4242
- `lib-vue-js` - JavaScript Vue library
4343
- `lib-vue-ts` - TypeScript Vue library
44+
- `lib-svelte-js` - JavaScript Svelte library
45+
- `lib-svelte-ts` - TypeScript Svelte library
4446
- `lib-solid-js` - JavaScript Solid library
4547
- `lib-solid-ts` - TypeScript Solid library
4648
- `doc-basic` - Basic documentation site

‎packages/create-rstack/src/index.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ const getTemplateName = async ({ template }: Argv): Promise<string> => {
8484
{ value: 'node', label: 'Node.js' },
8585
{ value: 'react', label: 'React' },
8686
{ value: 'vue', label: 'Vue' },
87+
{ value: 'svelte', label: 'Svelte' },
8788
{ value: 'solid', label: 'Solid' },
8889
],
8990
}),
@@ -126,6 +127,8 @@ await create({
126127
'lib-react-ts',
127128
'lib-vue-js',
128129
'lib-vue-ts',
130+
'lib-svelte-js',
131+
'lib-svelte-ts',
129132
'lib-solid-js',
130133
'lib-solid-ts',
131134
'doc-basic',
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# AGENTS.md
2+
3+
## Commands
4+
5+
- `{{ packageManager }} run build` - Build the library for production
6+
- `{{ packageManager }} run dev` - Rebuild the library when source files change
7+
- `{{ packageManager }} run test` - Run tests
8+
- `{{ packageManager }} run test:watch` - Run tests in watch mode
9+
10+
## Docs
11+
12+
- Rslib: https://rslib.rs/llms.txt
13+
- Rspack: https://rspack.rs/llms.txt
14+
- Rstest: https://rstest.rs/llms.txt
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Rstack library
2+
3+
## Setup
4+
5+
Install the dependencies:
6+
7+
```bash
8+
{{ packageManager }} install
9+
```
10+
11+
## Get started
12+
13+
Build the library:
14+
15+
```bash
16+
{{ packageManager }} run build
17+
```
18+
19+
Build the library in watch mode:
20+
21+
```bash
22+
{{ packageManager }} run dev
23+
```
24+
25+
Run tests:
26+
27+
```bash
28+
{{ packageManager }} run test
29+
```
30+
31+
Run tests in watch mode:
32+
33+
```bash
34+
{{ packageManager }} run test:watch
35+
```
36+
37+
## Learn more
38+
39+
- [Rstack documentation](https://rstack.rs)
40+
- [Rslib documentation](https://rslib.rs)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "rstack-lib-svelte-js",
3+
"version": "0.0.0",
4+
"type": "module",
5+
"exports": {
6+
".": {
7+
"default": "./dist/index.js"
8+
}
9+
},
10+
"files": [
11+
"dist",
12+
"README.md"
13+
],
14+
"scripts": {
15+
"build": "rs lib",
16+
"dev": "rs lib --watch",
17+
"format": "rs fmt",
18+
"lint": "rs lint",
19+
"test": "rs test",
20+
"test:watch": "rs test --watch"
21+
},
22+
"devDependencies": {
23+
"@rsbuild/plugin-svelte": "^2.0.1",
24+
"happy-dom": "^20.11.1",
25+
"prettier-plugin-svelte": "^4.1.1",
26+
"rstack": "^0.3.5",
27+
"svelte": "^5.56.8"
28+
},
29+
"peerDependencies": {
30+
"svelte": "^5.0.0"
31+
},
32+
"publishConfig": {
33+
"access": "public"
34+
}
35+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// @ts-check
2+
// Rstack configuration guide: https://rstack.rs/config
3+
import { define } from 'rstack';
4+
5+
define.lib(async () => {
6+
const { pluginSvelte } = await import('@rsbuild/plugin-svelte');
7+
8+
return {
9+
bundle: false,
10+
source: {
11+
entry: {
12+
index: ['./src/**'],
13+
},
14+
},
15+
output: {
16+
target: 'web',
17+
},
18+
plugins: [pluginSvelte()],
19+
};
20+
});
21+
22+
define.test({
23+
testEnvironment: 'happy-dom',
24+
});
25+
26+
define.lint(async () => {
27+
const { js } = await import('rstack/lint');
28+
29+
return [js.configs.recommended];
30+
});
31+
32+
define.fmt({
33+
plugins: ['prettier-plugin-svelte'],
34+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script>
2+
import './button.css';
3+
4+
let {
5+
primary = false,
6+
backgroundColor,
7+
size = 'medium',
8+
label = 'Demo Button',
9+
onClick,
10+
} = $props();
11+
12+
const mode = $derived(
13+
primary ? 'demo-button--primary' : 'demo-button--secondary',
14+
);
15+
</script>
16+
17+
<button
18+
type="button"
19+
class={['demo-button', `demo-button--${size}`, mode].join(' ')}
20+
style:background-color={backgroundColor}
21+
onclick={onClick}
22+
>
23+
{label}
24+
</button>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
.demo-button {
2+
font-weight: 700;
3+
border: 0;
4+
border-radius: 3em;
5+
cursor: pointer;
6+
display: inline-block;
7+
line-height: 1;
8+
}
9+
10+
.demo-button--primary {
11+
color: white;
12+
background-color: #1ea7fd;
13+
}
14+
15+
.demo-button--secondary {
16+
color: #333;
17+
background-color: transparent;
18+
box-shadow: rgba(0, 0, 0, 0.15) 0 0 0 1px inset;
19+
}
20+
21+
.demo-button--small {
22+
font-size: 12px;
23+
padding: 10px 16px;
24+
}
25+
26+
.demo-button--medium {
27+
font-size: 14px;
28+
padding: 11px 20px;
29+
}
30+
31+
.demo-button--large {
32+
font-size: 16px;
33+
padding: 12px 24px;
34+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as Button } from './Button.svelte';
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { expect, test } from 'rstack/test';
2+
import { mount, unmount } from 'svelte';
3+
import Button from '../src/Button.svelte';
4+
5+
test('The button should render the default label', () => {
6+
const target = document.createElement('div');
7+
document.body.append(target);
8+
const component = mount(Button, { target });
9+
const button = target.querySelector('button');
10+
11+
if (!button) {
12+
throw new Error('Expected button to be rendered');
13+
}
14+
15+
expect(button.textContent).toBe('Demo Button');
16+
17+
unmount(component);
18+
target.remove();
19+
});

0 commit comments

Comments
 (0)