snice 3.3.1 ā 3.4.1
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/bin/snice.js +56 -11
- package/bin/templates/CLAUDE.md +138 -0
- package/bin/templates/base/package.json +2 -2
- package/bin/templates/base/src/components/feature-card.ts +59 -0
- package/bin/templates/base/src/components/feature-card.types.ts +5 -0
- package/bin/templates/base/src/main.ts +7 -2
- package/bin/templates/base/src/pages/home-page.ts +38 -22
- package/bin/templates/base/src/types/api-response.ts +5 -0
- package/bin/templates/base/src/types/status.ts +1 -0
- package/bin/templates/base/src/types/theme.ts +1 -0
- package/bin/templates/base/src/types/user.ts +5 -0
- package/bin/templates/social/README.md +42 -0
- package/bin/templates/social/global.d.ts +14 -0
- package/bin/templates/social/index.html +13 -0
- package/bin/templates/social/package.json +21 -0
- package/bin/templates/social/public/vite.svg +1 -0
- package/bin/templates/social/src/main.ts +33 -0
- package/bin/templates/social/src/pages/feed-page.ts +111 -0
- package/bin/templates/social/src/pages/messages-page.ts +102 -0
- package/bin/templates/social/src/pages/not-found-page.ts +46 -0
- package/bin/templates/social/src/pages/profile-page.ts +99 -0
- package/bin/templates/social/src/pages/settings-page.ts +119 -0
- package/bin/templates/social/src/router.ts +9 -0
- package/bin/templates/social/src/styles/global.css +147 -0
- package/bin/templates/social/tsconfig.json +22 -0
- package/bin/templates/social/vite.config.ts +38 -0
- package/dist/components/theme/theme.css +234 -0
- package/dist/index.cjs +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.iife.js +1 -1
- package/dist/symbols.cjs +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/package.json +5 -1
package/bin/snice.js
CHANGED
|
@@ -11,27 +11,57 @@ const args = process.argv.slice(2);
|
|
|
11
11
|
const command = args[0];
|
|
12
12
|
|
|
13
13
|
if (command === 'create-app') {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
// Parse arguments - separate flags from positional arguments
|
|
15
|
+
const flags = {};
|
|
16
|
+
const positional = [];
|
|
17
|
+
|
|
18
|
+
for (let i = 1; i < args.length; i++) {
|
|
19
|
+
const arg = args[i];
|
|
20
|
+
if (arg.startsWith('--')) {
|
|
21
|
+
if (arg.includes('=')) {
|
|
22
|
+
const [key, value] = arg.split('=');
|
|
23
|
+
flags[key.slice(2)] = value;
|
|
24
|
+
} else {
|
|
25
|
+
flags[arg.slice(2)] = true;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
positional.push(arg);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const projectPath = positional[0] || '.';
|
|
33
|
+
const template = flags.template || 'base';
|
|
34
|
+
|
|
35
|
+
createApp(projectPath, template);
|
|
16
36
|
} else {
|
|
17
37
|
console.log(`
|
|
18
38
|
Snice CLI
|
|
19
39
|
|
|
20
40
|
Usage:
|
|
21
|
-
snice create-app <project-name>
|
|
22
|
-
snice create-app .
|
|
41
|
+
snice create-app [options] <project-name>
|
|
42
|
+
snice create-app [options] . Initialize in current directory
|
|
43
|
+
|
|
44
|
+
Options:
|
|
45
|
+
--template=<name> Template to use (default: base)
|
|
46
|
+
|
|
47
|
+
Templates:
|
|
48
|
+
base - Minimal starter with counter example (default)
|
|
49
|
+
social - Social media sample app showcasing components
|
|
23
50
|
|
|
24
51
|
Examples:
|
|
25
52
|
snice create-app my-app
|
|
26
|
-
|
|
53
|
+
snice create-app my-app --template=social
|
|
54
|
+
snice create-app --template=social my-app
|
|
55
|
+
npx snice create-app my-app --template=social
|
|
27
56
|
`);
|
|
28
57
|
}
|
|
29
58
|
|
|
30
|
-
function createApp(projectPath) {
|
|
59
|
+
function createApp(projectPath, template = 'base') {
|
|
31
60
|
const targetDir = resolve(process.cwd(), projectPath);
|
|
32
61
|
const projectName = projectPath === '.' ? basename(process.cwd()) : basename(targetDir);
|
|
33
|
-
|
|
62
|
+
|
|
34
63
|
console.log(`\nš Creating Snice app in ${targetDir}...\n`);
|
|
64
|
+
console.log(`š¦ Using template: ${template}\n`);
|
|
35
65
|
|
|
36
66
|
// Check if directory exists and is empty
|
|
37
67
|
if (projectPath !== '.') {
|
|
@@ -55,18 +85,33 @@ function createApp(projectPath) {
|
|
|
55
85
|
}
|
|
56
86
|
|
|
57
87
|
// Path to templates
|
|
58
|
-
const templateDir = join(__dirname, 'templates',
|
|
59
|
-
|
|
88
|
+
const templateDir = join(__dirname, 'templates', template);
|
|
89
|
+
|
|
90
|
+
// Check if template exists
|
|
91
|
+
if (!existsSync(templateDir)) {
|
|
92
|
+
console.error(`ā Template "${template}" not found!`);
|
|
93
|
+
console.error(`Available templates: base, social`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
60
97
|
// Copy template files
|
|
61
98
|
copyTemplateFiles(templateDir, targetDir, projectName);
|
|
62
99
|
|
|
100
|
+
// Copy shared CLAUDE.md
|
|
101
|
+
const claudeMdPath = join(__dirname, 'templates', 'CLAUDE.md');
|
|
102
|
+
if (existsSync(claudeMdPath)) {
|
|
103
|
+
console.log(` Creating CLAUDE.md...`);
|
|
104
|
+
const claudeMdContent = readFileSync(claudeMdPath, 'utf8');
|
|
105
|
+
writeFileSync(join(targetDir, 'CLAUDE.md'), claudeMdContent.replace(/\{\{projectName\}\}/g, projectName));
|
|
106
|
+
}
|
|
107
|
+
|
|
63
108
|
console.log(`\n⨠Project created successfully!\n`);
|
|
64
109
|
console.log('Next steps:');
|
|
65
|
-
|
|
110
|
+
|
|
66
111
|
if (projectPath !== '.') {
|
|
67
112
|
console.log(` cd ${projectPath}`);
|
|
68
113
|
}
|
|
69
|
-
|
|
114
|
+
|
|
70
115
|
console.log(' npm install');
|
|
71
116
|
console.log(' npm run dev\n');
|
|
72
117
|
console.log('Happy coding! š\n');
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Snice Project - AI Assistant Guide
|
|
2
|
+
|
|
3
|
+
## Documentation Location
|
|
4
|
+
|
|
5
|
+
AI-optimized docs shipped in: `node_modules/snice/docs/ai/`
|
|
6
|
+
|
|
7
|
+
**Read these files:**
|
|
8
|
+
- `api.md` - Complete API reference
|
|
9
|
+
- `patterns.md` - Usage examples
|
|
10
|
+
- `architecture.md` - System design
|
|
11
|
+
- `components/*.md` - Component docs (read only as needed)
|
|
12
|
+
|
|
13
|
+
## Project Structure
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
src/
|
|
17
|
+
pages/ # @page decorated route components
|
|
18
|
+
components/ # @element decorated UI components
|
|
19
|
+
controllers/ # @controller decorated behavior modules
|
|
20
|
+
styles/ # Global CSS
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Separation of concerns:**
|
|
24
|
+
- **Pages** - Orchestrate elements, handle URLs
|
|
25
|
+
- **Elements** - Pure presentation, no business logic
|
|
26
|
+
- **Controllers** - Behavior, data fetching, swappable
|
|
27
|
+
|
|
28
|
+
## Decorators
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// Class decorators
|
|
32
|
+
@page({ tag, routes, guards?, placard? })
|
|
33
|
+
@element('tag-name')
|
|
34
|
+
@controller('name')
|
|
35
|
+
@layout('name')
|
|
36
|
+
|
|
37
|
+
// Property/method decorators
|
|
38
|
+
@property() name = 'default'
|
|
39
|
+
@render() fn() { return html`...` }
|
|
40
|
+
@styles() fn() { return css`...` }
|
|
41
|
+
@ready() async fn() { ... }
|
|
42
|
+
@dispose() fn() { ... }
|
|
43
|
+
@watch('name') fn(oldVal, newVal) { ... }
|
|
44
|
+
@query('input') input!: HTMLInputElement
|
|
45
|
+
@queryAll('.item') items!: NodeListOf<HTMLElement>
|
|
46
|
+
@on('click', 'button') fn(e: Event) { ... }
|
|
47
|
+
@dispatch('value-changed') fn(val: string) => Event Detail
|
|
48
|
+
@context() fn(ctx: Context) { ... }
|
|
49
|
+
@request('user') fn(): () => Request
|
|
50
|
+
@respond('user') fn(req) => Response
|
|
51
|
+
@observe(() => this.el, options) fn(mutations) { ... }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick Examples
|
|
55
|
+
|
|
56
|
+
**Element:**
|
|
57
|
+
```typescript
|
|
58
|
+
@element('my-counter')
|
|
59
|
+
class Counter extends HTMLElement {
|
|
60
|
+
@property({ type: Number }) count = 0;
|
|
61
|
+
|
|
62
|
+
@render()
|
|
63
|
+
renderContent() {
|
|
64
|
+
return html`
|
|
65
|
+
<div>${this.count}</div>
|
|
66
|
+
<button @click=${() => this.count++}>+</button>
|
|
67
|
+
`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@styles()
|
|
71
|
+
componentStyles() {
|
|
72
|
+
return css`:host { display: block; }`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Page:**
|
|
78
|
+
```typescript
|
|
79
|
+
@page({ tag: 'user-page', routes: ['/users/:id'] })
|
|
80
|
+
class UserPage extends HTMLElement {
|
|
81
|
+
@property() id = '';
|
|
82
|
+
|
|
83
|
+
@ready()
|
|
84
|
+
async load() {
|
|
85
|
+
const user = await fetch(`/api/users/${this.id}`).then(r => r.json());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Controller:**
|
|
91
|
+
```typescript
|
|
92
|
+
@controller('data-loader')
|
|
93
|
+
class DataLoader implements IController {
|
|
94
|
+
element: HTMLElement;
|
|
95
|
+
|
|
96
|
+
async attach(el: HTMLElement) {
|
|
97
|
+
this.element = el;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async detach() {}
|
|
101
|
+
|
|
102
|
+
@on('click', '.item')
|
|
103
|
+
handleClick(e: Event) {}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Usage: <my-list controller="data-loader"></my-list>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Lists:**
|
|
110
|
+
```typescript
|
|
111
|
+
html`
|
|
112
|
+
${items.map(item => html`
|
|
113
|
+
<li key=${item.id}>${item.name}</li>
|
|
114
|
+
`)}
|
|
115
|
+
`
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Conditionals:**
|
|
119
|
+
```typescript
|
|
120
|
+
html`
|
|
121
|
+
<if ${condition}>Content</if>
|
|
122
|
+
`
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Communication
|
|
126
|
+
|
|
127
|
+
- **Parent ā Child:** Properties (`.prop=${value}`)
|
|
128
|
+
- **Child ā Parent:** Events (`@dispatch`)
|
|
129
|
+
- **Element ā Controller:** Request/Response (`@request`, `@respond`)
|
|
130
|
+
- **Global State:** Context (`@context()`)
|
|
131
|
+
|
|
132
|
+
## Build Commands
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npm run dev # Dev server
|
|
136
|
+
npm run build # Production build
|
|
137
|
+
npm run type-check # TypeScript check
|
|
138
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { element, property, render, styles, html, css } from 'snice';
|
|
2
|
+
|
|
3
|
+
@element('feature-card')
|
|
4
|
+
export class FeatureCard extends HTMLElement {
|
|
5
|
+
@property() icon = 'āØ';
|
|
6
|
+
@property() title = '';
|
|
7
|
+
@property() description = '';
|
|
8
|
+
|
|
9
|
+
@render()
|
|
10
|
+
renderContent() {
|
|
11
|
+
return html/*html*/`
|
|
12
|
+
<div class="card">
|
|
13
|
+
<div class="card__icon">${this.icon}</div>
|
|
14
|
+
<h3 class="card__title">${this.title}</h3>
|
|
15
|
+
<p class="card__description">${this.description}</p>
|
|
16
|
+
</div>
|
|
17
|
+
`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@styles()
|
|
21
|
+
componentStyles() {
|
|
22
|
+
return css/*css*/`
|
|
23
|
+
:host {
|
|
24
|
+
display: block;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.card {
|
|
28
|
+
padding: 2rem;
|
|
29
|
+
background: white;
|
|
30
|
+
border-radius: 12px;
|
|
31
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
32
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.card:hover {
|
|
36
|
+
transform: translateY(-4px);
|
|
37
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.card__icon {
|
|
41
|
+
font-size: 3rem;
|
|
42
|
+
margin-bottom: 1rem;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.card__title {
|
|
46
|
+
font-size: 1.25rem;
|
|
47
|
+
font-weight: 600;
|
|
48
|
+
margin: 0 0 0.5rem 0;
|
|
49
|
+
color: var(--text-color, #333);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.card__description {
|
|
53
|
+
margin: 0;
|
|
54
|
+
color: var(--text-light, #666);
|
|
55
|
+
line-height: 1.6;
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { initialize } from './router';
|
|
2
2
|
import './styles/global.css';
|
|
3
3
|
|
|
4
|
-
// Import
|
|
4
|
+
// Import snice layout
|
|
5
5
|
import 'snice/components/layout/snice-layout';
|
|
6
6
|
|
|
7
|
-
// Import components
|
|
7
|
+
// Import snice components
|
|
8
|
+
import 'snice/components/button/snice-button';
|
|
9
|
+
import 'snice/components/card/snice-card';
|
|
10
|
+
|
|
11
|
+
// Import custom components
|
|
8
12
|
import './components/counter-button';
|
|
13
|
+
import './components/feature-card';
|
|
9
14
|
|
|
10
15
|
// Import controllers
|
|
11
16
|
import './controllers/counter-controller';
|
|
@@ -19,14 +19,36 @@ export class HomePage extends HTMLElement {
|
|
|
19
19
|
<h1>Welcome to {{projectName}}</h1>
|
|
20
20
|
<p>Built with Snice</p>
|
|
21
21
|
|
|
22
|
-
<div class="
|
|
22
|
+
<div class="features">
|
|
23
|
+
<feature-card
|
|
24
|
+
icon="ā”"
|
|
25
|
+
title="Fast & Lightweight"
|
|
26
|
+
description="No virtual DOM overhead. Direct DOM updates with differential rendering.">
|
|
27
|
+
</feature-card>
|
|
28
|
+
|
|
29
|
+
<feature-card
|
|
30
|
+
icon="šØ"
|
|
31
|
+
title="Type-Safe"
|
|
32
|
+
description="Full TypeScript support with decorators for clean, maintainable code.">
|
|
33
|
+
</feature-card>
|
|
34
|
+
|
|
35
|
+
<feature-card
|
|
36
|
+
icon="š§"
|
|
37
|
+
title="Web Standards"
|
|
38
|
+
description="Built on native Web Components. Works everywhere, no framework lock-in.">
|
|
39
|
+
</feature-card>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<snice-card class="demo-section">
|
|
23
43
|
<h2>Interactive Counter Demo</h2>
|
|
24
44
|
<p>This counter persists its state using a controller:</p>
|
|
25
45
|
<counter-button controller="counter"></counter-button>
|
|
26
|
-
</
|
|
46
|
+
</snice-card>
|
|
27
47
|
|
|
28
48
|
<div class="nav">
|
|
29
|
-
<
|
|
49
|
+
<snice-button variant="primary" size="medium">
|
|
50
|
+
<a href="#/about" style="color: inherit; text-decoration: none;">Learn More</a>
|
|
51
|
+
</snice-button>
|
|
30
52
|
</div>
|
|
31
53
|
</div>
|
|
32
54
|
`;
|
|
@@ -59,31 +81,25 @@ export class HomePage extends HTMLElement {
|
|
|
59
81
|
margin-bottom: 2rem;
|
|
60
82
|
}
|
|
61
83
|
|
|
84
|
+
.features {
|
|
85
|
+
display: grid;
|
|
86
|
+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
87
|
+
gap: 2rem;
|
|
88
|
+
margin: 3rem 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
62
91
|
.demo-section {
|
|
63
92
|
margin: 3rem 0;
|
|
64
|
-
|
|
65
|
-
background: rgba(255, 255, 255, 0.5);
|
|
66
|
-
border-radius: 12px;
|
|
67
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
93
|
+
text-align: center;
|
|
68
94
|
}
|
|
69
|
-
|
|
95
|
+
|
|
96
|
+
.demo-section h2 {
|
|
97
|
+
margin-top: 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
70
100
|
.nav {
|
|
71
101
|
margin-top: 3rem;
|
|
72
102
|
}
|
|
73
|
-
|
|
74
|
-
.btn {
|
|
75
|
-
display: inline-block;
|
|
76
|
-
padding: 0.75rem 1.5rem;
|
|
77
|
-
background: var(--primary-color);
|
|
78
|
-
color: white;
|
|
79
|
-
text-decoration: none;
|
|
80
|
-
border-radius: 6px;
|
|
81
|
-
transition: background 0.3s ease;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.btn:hover {
|
|
85
|
-
background: var(--secondary-color);
|
|
86
|
-
}
|
|
87
103
|
`;
|
|
88
104
|
}
|
|
89
105
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Status = 'idle' | 'loading' | 'success' | 'error';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Theme = 'light' | 'dark' | 'auto';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Social Media Sample App
|
|
2
|
+
|
|
3
|
+
A sample social media application built with Snice showcasing various components.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
This template demonstrates:
|
|
8
|
+
|
|
9
|
+
### Components Used
|
|
10
|
+
- **snice-card** - Post containers and content cards
|
|
11
|
+
- **snice-avatar** - User profile pictures
|
|
12
|
+
- **snice-button** - Action buttons throughout
|
|
13
|
+
- **snice-badge** - Status indicators and labels
|
|
14
|
+
- **snice-input** - Form inputs in settings
|
|
15
|
+
- **snice-textarea** - Multi-line text input
|
|
16
|
+
- **snice-switch** - Toggle settings
|
|
17
|
+
- **snice-tabs** - Tabbed content on profile
|
|
18
|
+
- **snice-stat** - Statistics display
|
|
19
|
+
- **snice-layout-sidebar** - Sidebar navigation layout
|
|
20
|
+
|
|
21
|
+
### Pages
|
|
22
|
+
- **Feed** (`/`) - Social feed with posts showing cards, avatars, and badges
|
|
23
|
+
- **Profile** (`/profile`) - User profile with stats and tabs
|
|
24
|
+
- **Messages** (`/messages`) - Message list with avatars
|
|
25
|
+
- **Settings** (`/settings`) - Settings page with forms and switches
|
|
26
|
+
|
|
27
|
+
## Getting Started
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install
|
|
31
|
+
npm run dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Build for Production
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm run build
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Customize
|
|
41
|
+
|
|
42
|
+
Feel free to modify the pages, add new components, or change the styling to fit your needs.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare module '*.css' {
|
|
2
|
+
const content: string;
|
|
3
|
+
export default content;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
declare module '*.css?inline' {
|
|
7
|
+
const content: string;
|
|
8
|
+
export default content;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare module '*.html' {
|
|
12
|
+
const content: string;
|
|
13
|
+
export default content;
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>{{projectName}}</title>
|
|
7
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.ts"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc && vite build",
|
|
9
|
+
"type-check": "tsc --noEmit"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"snice": "^3.0.0"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@types/node": "^20.0.0",
|
|
16
|
+
"terser": "^5.24.0",
|
|
17
|
+
"typescript": "^5.3.3",
|
|
18
|
+
"unplugin-swc": "^1.5.7",
|
|
19
|
+
"vite": "^5.0.10"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { initialize } from './router';
|
|
2
|
+
import './styles/global.css';
|
|
3
|
+
|
|
4
|
+
// Import theme
|
|
5
|
+
import 'snice/components/theme/theme.css';
|
|
6
|
+
|
|
7
|
+
// Import layout
|
|
8
|
+
import 'snice/components/layout/snice-layout-sidebar';
|
|
9
|
+
|
|
10
|
+
// Import snice components
|
|
11
|
+
import 'snice/components/card/snice-card';
|
|
12
|
+
import 'snice/components/avatar/snice-avatar';
|
|
13
|
+
import 'snice/components/button/snice-button';
|
|
14
|
+
import 'snice/components/badge/snice-badge';
|
|
15
|
+
import 'snice/components/input/snice-input';
|
|
16
|
+
import 'snice/components/textarea/snice-textarea';
|
|
17
|
+
import 'snice/components/switch/snice-switch';
|
|
18
|
+
import 'snice/components/tabs/snice-tabs';
|
|
19
|
+
import 'snice/components/tabs/snice-tab';
|
|
20
|
+
import 'snice/components/tabs/snice-tab-panel';
|
|
21
|
+
import 'snice/components/stat/snice-stat';
|
|
22
|
+
import 'snice/components/list/snice-list';
|
|
23
|
+
import 'snice/components/nav/snice-nav';
|
|
24
|
+
|
|
25
|
+
// Import pages
|
|
26
|
+
import './pages/feed-page';
|
|
27
|
+
import './pages/profile-page';
|
|
28
|
+
import './pages/messages-page';
|
|
29
|
+
import './pages/settings-page';
|
|
30
|
+
import './pages/not-found-page';
|
|
31
|
+
|
|
32
|
+
// Initialize router
|
|
33
|
+
initialize();
|