create-elit 3.6.5 → 3.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -68
- package/dist/index.js +121 -8
- package/dist/templates/{elit.config.ts → auth-fullstack-example/elit.config.ts} +51 -0
- package/dist/templates/auth-fullstack-example/package.json +26 -0
- package/dist/templates/auth-fullstack-example/src/native-screen.ts +10 -0
- package/dist/templates/auth-fullstack-example/wapkignore +10 -0
- package/dist/templates/auth-fullstack-example/wapkpatch +1 -0
- package/dist/templates/basic-example/README.md +39 -0
- package/dist/templates/basic-example/elit.config.ts +114 -0
- package/dist/templates/basic-example/gitignore +7 -0
- package/dist/templates/basic-example/package.json +26 -0
- package/dist/templates/basic-example/public/favicon.svg +22 -0
- package/dist/templates/basic-example/public/index.html +14 -0
- package/dist/templates/basic-example/src/client.ts +15 -0
- package/dist/templates/basic-example/src/main.ts +89 -0
- package/dist/templates/basic-example/src/mobile.ts +35 -0
- package/dist/templates/basic-example/src/styles.ts +273 -0
- package/dist/templates/basic-example/tsconfig.json +24 -0
- package/dist/templates/basic-example/wapkignore +10 -0
- package/dist/templates/basic-example/wapkpatch +1 -0
- package/dist/templates/todo-fullstack-example/README.md +39 -0
- package/dist/templates/todo-fullstack-example/databases/todo.ts +41 -0
- package/dist/templates/todo-fullstack-example/elit.config.ts +123 -0
- package/dist/templates/todo-fullstack-example/gitignore +7 -0
- package/dist/templates/todo-fullstack-example/package.json +26 -0
- package/dist/templates/todo-fullstack-example/public/favicon.svg +22 -0
- package/dist/templates/todo-fullstack-example/public/index.html +14 -0
- package/dist/templates/todo-fullstack-example/src/client.ts +15 -0
- package/dist/templates/todo-fullstack-example/src/components/AppFooter.ts +16 -0
- package/dist/templates/todo-fullstack-example/src/components/AppHeader.ts +23 -0
- package/dist/templates/todo-fullstack-example/src/main.ts +7 -0
- package/dist/templates/todo-fullstack-example/src/mobile.ts +36 -0
- package/dist/templates/todo-fullstack-example/src/pages/TodoPage.ts +491 -0
- package/dist/templates/todo-fullstack-example/src/router.ts +16 -0
- package/dist/templates/todo-fullstack-example/src/server.ts +226 -0
- package/dist/templates/todo-fullstack-example/src/styles.ts +768 -0
- package/dist/templates/todo-fullstack-example/src/todo-types.ts +19 -0
- package/dist/templates/todo-fullstack-example/src/web.ts +16 -0
- package/dist/templates/todo-fullstack-example/tsconfig.json +24 -0
- package/dist/templates/todo-fullstack-example/wapkignore +10 -0
- package/dist/templates/todo-fullstack-example/wapkpatch +1 -0
- package/package.json +1 -1
- package/dist/templates/package.json +0 -17
- package/dist/templates/src/client.test.ts +0 -292
- package/dist/templates/src/components/Footer.test.ts +0 -226
- package/dist/templates/src/components/Header.test.ts +0 -493
- package/dist/templates/src/pages/ChatListPage.test.ts +0 -603
- package/dist/templates/src/pages/ChatPage.test.ts +0 -530
- package/dist/templates/src/pages/ForgotPasswordPage.test.ts +0 -484
- package/dist/templates/src/pages/HomePage.test.ts +0 -601
- package/dist/templates/src/pages/LoginPage.test.ts +0 -619
- package/dist/templates/src/pages/PrivateChatPage.test.ts +0 -556
- package/dist/templates/src/pages/ProfilePage.test.ts +0 -628
- package/dist/templates/src/pages/RegisterPage.test.ts +0 -661
- /package/dist/templates/{README.md → auth-fullstack-example/README.md} +0 -0
- /package/dist/templates/{databases → auth-fullstack-example/databases}/users.ts +0 -0
- /package/dist/templates/{gitignore → auth-fullstack-example/gitignore} +0 -0
- /package/dist/templates/{public → auth-fullstack-example/public}/favicon.svg +0 -0
- /package/dist/templates/{public → auth-fullstack-example/public}/index.html +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/client.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/components/Footer.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/components/Header.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/components/index.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/main.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/ChatListPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/ChatPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/ForgotPasswordPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/HomePage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/LoginPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/PrivateChatPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/ProfilePage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/RegisterPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/router.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/server.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/styles.ts +0 -0
- /package/dist/templates/{tsconfig.json → auth-fullstack-example/tsconfig.json} +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { button, div, h1, h2, p, section, span } from 'elit/el';
|
|
2
|
+
import { dom } from 'elit/dom';
|
|
3
|
+
import { createState, reactive } from 'elit/state';
|
|
4
|
+
import { injectStyles } from './styles';
|
|
5
|
+
|
|
6
|
+
const count = createState(0);
|
|
7
|
+
|
|
8
|
+
const highlights = [
|
|
9
|
+
{
|
|
10
|
+
title: 'Minimal setup',
|
|
11
|
+
body: 'Start with one page, one entry file, and enough styling to shape your own direction quickly.'
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
title: 'Reactive by default',
|
|
15
|
+
body: 'The counter panel is deliberately small so you can replace it with your real state and interactions.'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
title: 'Ready to extend',
|
|
19
|
+
body: 'Keep this starter simple for small tools, or grow it into a larger app with routing, APIs, and persistence later.'
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const nextSteps = [
|
|
24
|
+
'Rename the placeholder copy to fit your project.',
|
|
25
|
+
'Replace the counter with your first real feature.',
|
|
26
|
+
'Use elit.config.ts as the place to add build, mobile, or desktop tweaks.'
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
function HighlightCard(title: string, body: string) {
|
|
30
|
+
return div({ className: 'highlight-card' },
|
|
31
|
+
h2({ className: 'highlight-title' }, title),
|
|
32
|
+
p({ className: 'highlight-copy' }, body)
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function StepItem(index: number, label: string) {
|
|
37
|
+
return div({ className: 'step-item' },
|
|
38
|
+
span({ className: 'step-index' }, String(index).padStart(2, '0')),
|
|
39
|
+
p({ className: 'step-copy' }, label)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function App() {
|
|
44
|
+
return div({ className: 'app-shell' },
|
|
45
|
+
section({ className: 'hero-panel' },
|
|
46
|
+
div({ className: 'hero-copy' },
|
|
47
|
+
span({ className: 'hero-kicker' }, 'basic-example'),
|
|
48
|
+
h1({ className: 'hero-title' }, 'A clean Elit starter for small ideas and fast prototypes.'),
|
|
49
|
+
p({ className: 'hero-description' },
|
|
50
|
+
'Use this template when you want the simplest possible starting point with a tasteful UI, one reactive example, and room to reshape the structure immediately.'
|
|
51
|
+
),
|
|
52
|
+
div({ className: 'hero-actions' },
|
|
53
|
+
button({ className: 'btn btn-primary', onclick: () => count.value += 1 }, 'Try the counter'),
|
|
54
|
+
button({ className: 'btn btn-secondary', onclick: () => count.value = 0 }, 'Reset')
|
|
55
|
+
)
|
|
56
|
+
),
|
|
57
|
+
div({ className: 'counter-panel' },
|
|
58
|
+
span({ className: 'counter-label' }, 'Reactive state'),
|
|
59
|
+
reactive(count, (value: number) =>
|
|
60
|
+
div({ className: 'counter-value' }, String(value))
|
|
61
|
+
),
|
|
62
|
+
p({ className: 'counter-copy' }, 'This is intentionally small. Swap it for your first form, dashboard metric, or workflow state without undoing a heavy starter.'),
|
|
63
|
+
div({ className: 'counter-row' },
|
|
64
|
+
button({ className: 'btn btn-ghost', onclick: () => count.value -= 1 }, 'Decrease'),
|
|
65
|
+
button({ className: 'btn btn-primary', onclick: () => count.value += 1 }, 'Increase')
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
),
|
|
69
|
+
section({ className: 'content-grid' },
|
|
70
|
+
div({ className: 'panel' },
|
|
71
|
+
h2({ className: 'section-title' }, 'Why this starter exists'),
|
|
72
|
+
p({ className: 'section-copy' }, 'Not every new project needs auth, a database, or a multi-page workflow on day one. This template keeps the footprint low while still feeling intentional.'),
|
|
73
|
+
div({ className: 'highlight-grid' },
|
|
74
|
+
...highlights.map((item) => HighlightCard(item.title, item.body))
|
|
75
|
+
)
|
|
76
|
+
),
|
|
77
|
+
div({ className: 'panel panel-accent' },
|
|
78
|
+
h2({ className: 'section-title section-title-light' }, 'First moves'),
|
|
79
|
+
p({ className: 'section-copy section-copy-light' }, 'A good starter should disappear quickly. Use these as the first edits after scaffolding the app.'),
|
|
80
|
+
div({ className: 'steps-list' },
|
|
81
|
+
...nextSteps.map((step, index) => StepItem(index + 1, step))
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
injectStyles();
|
|
89
|
+
dom.render('#app', App());
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { button, div, h1, p, span } from 'elit/el';
|
|
2
|
+
|
|
3
|
+
function Tile(title: string, body: string) {
|
|
4
|
+
return div(
|
|
5
|
+
{
|
|
6
|
+
style: {
|
|
7
|
+
display: 'flex',
|
|
8
|
+
flexDirection: 'column',
|
|
9
|
+
gap: '6px',
|
|
10
|
+
padding: '14px 16px',
|
|
11
|
+
borderRadius: '18px',
|
|
12
|
+
background: '#fffaf4'
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
span({ style: { fontWeight: '700', color: '#173447' } }, title),
|
|
16
|
+
p({ style: { margin: '0', color: '#6d7c88' } }, body)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const screen = () => div(
|
|
21
|
+
{
|
|
22
|
+
style: {
|
|
23
|
+
padding: '24px',
|
|
24
|
+
display: 'flex',
|
|
25
|
+
flexDirection: 'column',
|
|
26
|
+
gap: '18px',
|
|
27
|
+
background: '#f4ede5'
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
h1({ style: { margin: '0', color: '#173447' } }, 'Basic Example'),
|
|
31
|
+
p({ style: { margin: '0', color: '#607180' } }, 'A small native-friendly preview for the create-elit basic starter.'),
|
|
32
|
+
Tile('One page first', 'Keep the initial scope small and prove the interaction model quickly.'),
|
|
33
|
+
Tile('Reactive state', 'Use the same Elit syntax to sketch mobile or desktop follow-up views.'),
|
|
34
|
+
button({ onClick: () => undefined }, 'Sync mobile shell')
|
|
35
|
+
);
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import styles from 'elit/style';
|
|
2
|
+
|
|
3
|
+
styles.addTag('*', {
|
|
4
|
+
margin: 0,
|
|
5
|
+
padding: 0,
|
|
6
|
+
boxSizing: 'border-box'
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
styles.addTag('body', {
|
|
10
|
+
minHeight: '100vh',
|
|
11
|
+
fontFamily: "'Aptos', 'Trebuchet MS', sans-serif",
|
|
12
|
+
color: '#173447',
|
|
13
|
+
background: 'linear-gradient(160deg, #f7f1e9 0%, #efe4d8 54%, #e6d8c9 100%)'
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
styles.addTag('button', {
|
|
17
|
+
fontFamily: 'inherit'
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
styles.addClass('app-shell', {
|
|
21
|
+
maxWidth: '1120px',
|
|
22
|
+
margin: '0 auto',
|
|
23
|
+
padding: '32px 20px 48px',
|
|
24
|
+
display: 'flex',
|
|
25
|
+
flexDirection: 'column',
|
|
26
|
+
gap: '20px'
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
styles.addClass('hero-panel', {
|
|
30
|
+
display: 'grid',
|
|
31
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
|
|
32
|
+
gap: '20px',
|
|
33
|
+
alignItems: 'stretch'
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
styles.addClass('hero-copy', {
|
|
37
|
+
background: 'rgba(255, 250, 244, 0.8)',
|
|
38
|
+
borderRadius: '30px',
|
|
39
|
+
padding: '28px',
|
|
40
|
+
border: '1px solid rgba(255, 255, 255, 0.7)',
|
|
41
|
+
boxShadow: '0 22px 46px rgba(23, 52, 71, 0.08)',
|
|
42
|
+
display: 'flex',
|
|
43
|
+
flexDirection: 'column',
|
|
44
|
+
gap: '14px'
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
styles.addClass('hero-kicker', {
|
|
48
|
+
display: 'inline-flex',
|
|
49
|
+
width: 'fit-content',
|
|
50
|
+
padding: '7px 12px',
|
|
51
|
+
borderRadius: '999px',
|
|
52
|
+
background: 'rgba(47, 125, 109, 0.12)',
|
|
53
|
+
color: '#25695d',
|
|
54
|
+
fontSize: '12px',
|
|
55
|
+
fontWeight: 800,
|
|
56
|
+
letterSpacing: '0.08em',
|
|
57
|
+
textTransform: 'uppercase'
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
styles.addClass('hero-title', {
|
|
61
|
+
fontSize: 'clamp(2.4rem, 4vw, 4.4rem)',
|
|
62
|
+
lineHeight: 0.98,
|
|
63
|
+
color: '#173447',
|
|
64
|
+
maxWidth: '11ch'
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
styles.addClass('hero-description', {
|
|
68
|
+
fontSize: '1rem',
|
|
69
|
+
lineHeight: 1.7,
|
|
70
|
+
color: '#5f6f7d',
|
|
71
|
+
maxWidth: '40rem'
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
styles.addClass('hero-actions', {
|
|
75
|
+
display: 'flex',
|
|
76
|
+
flexWrap: 'wrap',
|
|
77
|
+
gap: '12px',
|
|
78
|
+
marginTop: '4px'
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
styles.addClass('counter-panel', {
|
|
82
|
+
background: 'linear-gradient(160deg, #173447 0%, #24566c 100%)',
|
|
83
|
+
borderRadius: '30px',
|
|
84
|
+
padding: '28px',
|
|
85
|
+
color: '#fffaf4',
|
|
86
|
+
boxShadow: '0 24px 48px rgba(23, 52, 71, 0.16)',
|
|
87
|
+
display: 'flex',
|
|
88
|
+
flexDirection: 'column',
|
|
89
|
+
gap: '14px',
|
|
90
|
+
justifyContent: 'space-between'
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
styles.addClass('counter-label', {
|
|
94
|
+
fontSize: '12px',
|
|
95
|
+
fontWeight: 800,
|
|
96
|
+
letterSpacing: '0.08em',
|
|
97
|
+
textTransform: 'uppercase',
|
|
98
|
+
color: 'rgba(255, 250, 244, 0.74)'
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
styles.addClass('counter-value', {
|
|
102
|
+
fontSize: 'clamp(4rem, 10vw, 6rem)',
|
|
103
|
+
lineHeight: 0.9,
|
|
104
|
+
fontWeight: 800,
|
|
105
|
+
color: '#fffaf4'
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
styles.addClass('counter-copy', {
|
|
109
|
+
fontSize: '0.96rem',
|
|
110
|
+
lineHeight: 1.7,
|
|
111
|
+
color: 'rgba(255, 250, 244, 0.78)'
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
styles.addClass('counter-row', {
|
|
115
|
+
display: 'flex',
|
|
116
|
+
flexWrap: 'wrap',
|
|
117
|
+
gap: '12px'
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
styles.addClass('content-grid', {
|
|
121
|
+
display: 'grid',
|
|
122
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
|
|
123
|
+
gap: '20px'
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
styles.addClass('panel', {
|
|
127
|
+
background: 'rgba(255, 250, 244, 0.82)',
|
|
128
|
+
borderRadius: '30px',
|
|
129
|
+
padding: '28px',
|
|
130
|
+
border: '1px solid rgba(255, 255, 255, 0.72)',
|
|
131
|
+
boxShadow: '0 22px 46px rgba(23, 52, 71, 0.08)',
|
|
132
|
+
display: 'flex',
|
|
133
|
+
flexDirection: 'column',
|
|
134
|
+
gap: '16px'
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
styles.addClass('panel-accent', {
|
|
138
|
+
background: 'linear-gradient(150deg, #2f7d6d 0%, #3b8f7d 60%, #f18f5a 130%)'
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
styles.addClass('section-title', {
|
|
142
|
+
fontSize: '1.4rem',
|
|
143
|
+
color: '#173447'
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
styles.addClass('section-title-light', {
|
|
147
|
+
color: '#fffaf4'
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
styles.addClass('section-copy', {
|
|
151
|
+
fontSize: '0.96rem',
|
|
152
|
+
lineHeight: 1.7,
|
|
153
|
+
color: '#61707e'
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
styles.addClass('section-copy-light', {
|
|
157
|
+
color: 'rgba(255, 250, 244, 0.82)'
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
styles.addClass('highlight-grid', {
|
|
161
|
+
display: 'grid',
|
|
162
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))',
|
|
163
|
+
gap: '14px'
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
styles.addClass('highlight-card', {
|
|
167
|
+
background: '#fffaf4',
|
|
168
|
+
borderRadius: '22px',
|
|
169
|
+
padding: '18px',
|
|
170
|
+
border: '1px solid rgba(23, 52, 71, 0.08)',
|
|
171
|
+
display: 'flex',
|
|
172
|
+
flexDirection: 'column',
|
|
173
|
+
gap: '8px'
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
styles.addClass('highlight-title', {
|
|
177
|
+
fontSize: '1rem',
|
|
178
|
+
color: '#173447'
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
styles.addClass('highlight-copy', {
|
|
182
|
+
fontSize: '0.9rem',
|
|
183
|
+
lineHeight: 1.6,
|
|
184
|
+
color: '#64727f'
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
styles.addClass('steps-list', {
|
|
188
|
+
display: 'flex',
|
|
189
|
+
flexDirection: 'column',
|
|
190
|
+
gap: '12px'
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
styles.addClass('step-item', {
|
|
194
|
+
display: 'grid',
|
|
195
|
+
gridTemplateColumns: '54px 1fr',
|
|
196
|
+
gap: '12px',
|
|
197
|
+
alignItems: 'start',
|
|
198
|
+
padding: '14px 0',
|
|
199
|
+
borderTop: '1px solid rgba(255, 250, 244, 0.18)'
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
styles.addClass('step-index', {
|
|
203
|
+
display: 'inline-flex',
|
|
204
|
+
alignItems: 'center',
|
|
205
|
+
justifyContent: 'center',
|
|
206
|
+
width: '54px',
|
|
207
|
+
height: '54px',
|
|
208
|
+
borderRadius: '18px',
|
|
209
|
+
background: 'rgba(255, 250, 244, 0.15)',
|
|
210
|
+
color: '#fffaf4',
|
|
211
|
+
fontWeight: 800
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
styles.addClass('step-copy', {
|
|
215
|
+
paddingTop: '10px',
|
|
216
|
+
color: '#fffaf4',
|
|
217
|
+
lineHeight: 1.6,
|
|
218
|
+
fontSize: '0.95rem'
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
styles.addClass('btn', {
|
|
222
|
+
border: 'none',
|
|
223
|
+
borderRadius: '999px',
|
|
224
|
+
padding: '14px 18px',
|
|
225
|
+
fontSize: '0.95rem',
|
|
226
|
+
fontWeight: 800,
|
|
227
|
+
cursor: 'pointer',
|
|
228
|
+
display: 'inline-flex',
|
|
229
|
+
alignItems: 'center',
|
|
230
|
+
justifyContent: 'center',
|
|
231
|
+
gap: '8px',
|
|
232
|
+
transition: 'transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease, color 0.2s ease'
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
styles.addClass('btn-primary', {
|
|
236
|
+
background: 'linear-gradient(135deg, #f18f5a 0%, #f06f45 100%)',
|
|
237
|
+
color: '#fffaf4',
|
|
238
|
+
boxShadow: '0 16px 30px rgba(240, 111, 69, 0.22)'
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
styles.addPseudoClass('hover', {
|
|
242
|
+
transform: 'translateY(-1px)',
|
|
243
|
+
boxShadow: '0 20px 36px rgba(240, 111, 69, 0.28)'
|
|
244
|
+
}, '.btn-primary');
|
|
245
|
+
|
|
246
|
+
styles.addClass('btn-secondary', {
|
|
247
|
+
background: '#fffaf4',
|
|
248
|
+
color: '#173447',
|
|
249
|
+
border: '1px solid rgba(23, 52, 71, 0.12)',
|
|
250
|
+
boxShadow: '0 10px 22px rgba(23, 52, 71, 0.08)'
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
styles.addPseudoClass('hover', {
|
|
254
|
+
transform: 'translateY(-1px)',
|
|
255
|
+
background: '#ffffff'
|
|
256
|
+
}, '.btn-secondary');
|
|
257
|
+
|
|
258
|
+
styles.addClass('btn-ghost', {
|
|
259
|
+
background: 'transparent',
|
|
260
|
+
color: '#fffaf4',
|
|
261
|
+
border: '1px solid rgba(255, 250, 244, 0.2)'
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
styles.addPseudoClass('hover', {
|
|
265
|
+
transform: 'translateY(-1px)',
|
|
266
|
+
background: 'rgba(255, 250, 244, 0.08)'
|
|
267
|
+
}, '.btn-ghost');
|
|
268
|
+
|
|
269
|
+
export function injectStyles() {
|
|
270
|
+
styles.inject('basic-example-styles');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export default styles;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": [
|
|
7
|
+
"ES2020",
|
|
8
|
+
"DOM",
|
|
9
|
+
"DOM.Iterable"
|
|
10
|
+
],
|
|
11
|
+
"strict": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"types": [
|
|
17
|
+
"node",
|
|
18
|
+
"elit/test-globals"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"include": [
|
|
22
|
+
"src"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dist
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# ELIT_PROJECT_NAME
|
|
2
|
+
|
|
3
|
+
A fullstack todo starter for Elit with file-backed persistence powered by `elit/database`.
|
|
4
|
+
|
|
5
|
+
## What is included
|
|
6
|
+
|
|
7
|
+
- A polished todo dashboard UI
|
|
8
|
+
- REST API routes in `src/server.ts`
|
|
9
|
+
- File persistence in `databases/todo.ts`
|
|
10
|
+
- Build, preview, mobile, desktop, and WAPK config already wired in `elit.config.ts`
|
|
11
|
+
|
|
12
|
+
## Getting started
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install
|
|
16
|
+
npm run dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Open http://localhost:3003 and start adding tasks. Every create, update, complete, or delete action writes back to `databases/todo.ts`.
|
|
20
|
+
|
|
21
|
+
## Project structure
|
|
22
|
+
|
|
23
|
+
- `src/pages/TodoPage.ts` - main todo experience
|
|
24
|
+
- `src/server.ts` - CRUD API powered by `elit/database`
|
|
25
|
+
- `databases/todo.ts` - starter data file that acts as your local database
|
|
26
|
+
- `src/mobile.ts` - native preview entry for mobile mode
|
|
27
|
+
|
|
28
|
+
## Useful scripts
|
|
29
|
+
|
|
30
|
+
- `npm run dev` - start the dev server with HMR
|
|
31
|
+
- `npm run build` - build the web app for production
|
|
32
|
+
- `npm run preview` - preview the production build locally
|
|
33
|
+
- `npm run mobile:sync` - sync the web build into the mobile shell
|
|
34
|
+
- `npm run desktop:run` - run the desktop shell
|
|
35
|
+
|
|
36
|
+
## Learn more
|
|
37
|
+
|
|
38
|
+
- [Elit Documentation](https://d-osc.github.io/elit)
|
|
39
|
+
- [GitHub Repository](https://github.com/d-osc/elit)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type TodoPriority = 'low' | 'medium' | 'high';
|
|
2
|
+
|
|
3
|
+
export interface TodoItem {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
notes: string;
|
|
7
|
+
priority: TodoPriority;
|
|
8
|
+
completed: boolean;
|
|
9
|
+
createdAt: string;
|
|
10
|
+
updatedAt: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const todos: TodoItem[] = [
|
|
14
|
+
{
|
|
15
|
+
id: 'todo_launch_board',
|
|
16
|
+
title: 'Ship the first database-backed board',
|
|
17
|
+
notes: 'Wire the server endpoints and confirm every action writes back to databases/todo.ts.',
|
|
18
|
+
priority: 'high',
|
|
19
|
+
completed: false,
|
|
20
|
+
createdAt: '2026-04-17T09:00:00.000Z',
|
|
21
|
+
updatedAt: '2026-04-17T09:00:00.000Z'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 'todo_polish_copy',
|
|
25
|
+
title: 'Tune the starter copy',
|
|
26
|
+
notes: 'Replace placeholders with a short workflow that makes sense for your team.',
|
|
27
|
+
priority: 'medium',
|
|
28
|
+
completed: false,
|
|
29
|
+
createdAt: '2026-04-17T09:30:00.000Z',
|
|
30
|
+
updatedAt: '2026-04-17T09:30:00.000Z'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'todo_cleanup_template',
|
|
34
|
+
title: 'Prune example tasks you do not need',
|
|
35
|
+
notes: 'Keep the board lean so the starter feels like your own project from day one.',
|
|
36
|
+
priority: 'low',
|
|
37
|
+
completed: true,
|
|
38
|
+
createdAt: '2026-04-17T08:15:00.000Z',
|
|
39
|
+
updatedAt: '2026-04-17T10:15:00.000Z'
|
|
40
|
+
}
|
|
41
|
+
];
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { server } from './src/server';
|
|
2
|
+
import { client } from './src/client';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
dev: {
|
|
6
|
+
port: 3003,
|
|
7
|
+
host: 'localhost',
|
|
8
|
+
open: true,
|
|
9
|
+
logging: true,
|
|
10
|
+
outDir: './dev-dist',
|
|
11
|
+
outFile: 'index.js',
|
|
12
|
+
clients: [{
|
|
13
|
+
root: '.',
|
|
14
|
+
basePath: '',
|
|
15
|
+
ssr: () => client,
|
|
16
|
+
api: server
|
|
17
|
+
}]
|
|
18
|
+
},
|
|
19
|
+
build: [{
|
|
20
|
+
entry: './src/main.ts',
|
|
21
|
+
outDir: './dist',
|
|
22
|
+
outFile: 'main.js',
|
|
23
|
+
format: 'esm',
|
|
24
|
+
minify: true,
|
|
25
|
+
sourcemap: true,
|
|
26
|
+
target: 'es2020',
|
|
27
|
+
copy: [
|
|
28
|
+
{
|
|
29
|
+
from: './public/index.html', to: './index.html',
|
|
30
|
+
transform: (content: string, config: { basePath: string }) => {
|
|
31
|
+
// Replace script src
|
|
32
|
+
let html = content.replace('src="../src/main.ts"', 'src="main.js"');
|
|
33
|
+
|
|
34
|
+
// Inject base tag if basePath is configured
|
|
35
|
+
if (config.basePath) {
|
|
36
|
+
const baseTag = `<base href="${config.basePath}/">`;
|
|
37
|
+
html = html.replace(
|
|
38
|
+
'<meta name="viewport" content="width=device-width, initial-scale=1.0">',
|
|
39
|
+
`<meta name="viewport" content="width=device-width, initial-scale=1.0">\n ${baseTag}`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return html;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{ from: './public/favicon.svg', to: './favicon.svg' }
|
|
47
|
+
]
|
|
48
|
+
}],
|
|
49
|
+
preview: {
|
|
50
|
+
port: 3000,
|
|
51
|
+
host: 'localhost',
|
|
52
|
+
open: false,
|
|
53
|
+
logging: true,
|
|
54
|
+
root: './dist',
|
|
55
|
+
basePath: '',
|
|
56
|
+
index: './index.html'
|
|
57
|
+
},
|
|
58
|
+
test: {
|
|
59
|
+
include: ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
60
|
+
exclude: ['node_modules', 'dist', 'benchmark', 'docs', 'coverage'],
|
|
61
|
+
testTimeout: 5000,
|
|
62
|
+
bail: false,
|
|
63
|
+
globals: true,
|
|
64
|
+
watch: false,
|
|
65
|
+
reporter: 'verbose',
|
|
66
|
+
coverage: {
|
|
67
|
+
enabled: false,
|
|
68
|
+
provider: 'v8',
|
|
69
|
+
reporter: ['text', 'html', 'lcov', 'json', 'coverage-final.json', 'clover'],
|
|
70
|
+
include: ['**/*.ts'], // รวมทุกไฟล์ TypeScript ในโปรเจกต์
|
|
71
|
+
exclude: ['**/*.test.ts', '**/*.spec.ts', '**/node_modules/**', '**/dist/**', '**/coverage/**']
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
mobile: {
|
|
75
|
+
cwd: ".",
|
|
76
|
+
appId: "com.elit.androidnativeexample",
|
|
77
|
+
appName: "ElitAndroidNativeExample",
|
|
78
|
+
webDir: "dist",
|
|
79
|
+
mode: "hybrid", // native, webview, or hybrid
|
|
80
|
+
permissions: [
|
|
81
|
+
"android.permission.INTERNET",
|
|
82
|
+
"android.permission.ACCESS_NETWORK_STATE"
|
|
83
|
+
],
|
|
84
|
+
native: {
|
|
85
|
+
entry: "./src/mobile.ts",
|
|
86
|
+
exportName: "screen",
|
|
87
|
+
ios: {
|
|
88
|
+
enabled: false
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
desktop: {
|
|
93
|
+
compiler: 'auto',
|
|
94
|
+
entry: './src/main.ts',
|
|
95
|
+
mode: 'hybrid',
|
|
96
|
+
outDir: './desktop-dist',
|
|
97
|
+
runtime: 'quickjs',
|
|
98
|
+
},
|
|
99
|
+
wapk: {
|
|
100
|
+
name: 'elit-todo-example',
|
|
101
|
+
version: '1.0.0',
|
|
102
|
+
runtime: 'node',
|
|
103
|
+
entry: './dist/main.js',
|
|
104
|
+
script: {
|
|
105
|
+
start: 'node ./dist/main.js',
|
|
106
|
+
},
|
|
107
|
+
env: {
|
|
108
|
+
APP_NAME: 'Elit Todo Example',
|
|
109
|
+
},
|
|
110
|
+
run: {
|
|
111
|
+
runtime: 'node',
|
|
112
|
+
useWatcher: true,
|
|
113
|
+
watchArchive: true,
|
|
114
|
+
syncInterval: 150,
|
|
115
|
+
archiveSyncInterval: 150,
|
|
116
|
+
},
|
|
117
|
+
// desktop: {
|
|
118
|
+
// width: 1024,
|
|
119
|
+
// height: 768,
|
|
120
|
+
// title: "WAPK Example App"
|
|
121
|
+
// }
|
|
122
|
+
}
|
|
123
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ELIT_PROJECT_NAME",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "elit dev",
|
|
7
|
+
"build": "elit build",
|
|
8
|
+
"preview": "elit preview",
|
|
9
|
+
"mobile:init": "elit mobile init . --app-id com.elit.mobileexample --app-name ElitMobileExample --web-dir dist",
|
|
10
|
+
"mobile:sync": "elit mobile sync --cwd . --web-dir dist",
|
|
11
|
+
"mobile:doctor": "elit mobile doctor --cwd . --json",
|
|
12
|
+
"mobile:run:android": "elit mobile run android --cwd .",
|
|
13
|
+
"mobile:run:ios": "elit mobile run ios --cwd .",
|
|
14
|
+
"mobile:build:android": "elit mobile build android --cwd .",
|
|
15
|
+
"mobile:build:ios": "elit mobile build ios --cwd .",
|
|
16
|
+
"desktop:run": "elit desktop run",
|
|
17
|
+
"desktop:build": "elit desktop build",
|
|
18
|
+
"test": "elit test",
|
|
19
|
+
"test:watch": "elit test --watch",
|
|
20
|
+
"test:coverage": "elit test --coverage"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@types/node": "^25.0.9",
|
|
24
|
+
"elit": "^ELIT_VERSION"
|
|
25
|
+
}
|
|
26
|
+
}
|