Initial commit
This commit is contained in:
commit
f663a390e5
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
*
|
||||
|
||||
# Metadata files
|
||||
!readme.md
|
||||
!UNLICENSE
|
||||
|
||||
# Config files
|
||||
!package.json
|
||||
!package-lock.json
|
||||
!tsconfig.json
|
||||
!.gitignore
|
||||
!vite.config.ts
|
||||
!uno.config.ts
|
||||
!biome.json
|
||||
|
||||
# Backbone files
|
||||
!index.html
|
||||
|
||||
# Assets files
|
||||
!public/
|
||||
!public/**/
|
||||
!public/**/*.svg
|
||||
!public/**/*.png
|
||||
|
||||
# Source code
|
||||
!src/
|
||||
!src/**/
|
||||
!src/**/*.d.ts
|
||||
!src/**/*.tsx
|
||||
!src/**/*.css
|
||||
24
UNLICENSE
Normal file
24
UNLICENSE
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org/>
|
||||
15
biome.json
Normal file
15
biome.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "tab"
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"semicolons": "asNeeded"
|
||||
}
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
13
index.html
Normal file
13
index.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + TypeScript + WebJSX</title>
|
||||
</head>
|
||||
<body>
|
||||
<x-app></x-app>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
2538
package-lock.json
generated
Normal file
2538
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
package.json
Normal file
25
package.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "webcomponents-initial-template",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview",
|
||||
"lint": "biome check .",
|
||||
"format": "biome format --write .",
|
||||
"check": "biome check --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.2.4",
|
||||
"@unocss/preset-attributify": "^66.5.2",
|
||||
"typescript": "~5.8.3",
|
||||
"unocss": "^66.5.2",
|
||||
"vite": "^7.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@unocss/reset": "^66.5.2",
|
||||
"webjsx": "^0.0.73"
|
||||
}
|
||||
}
|
||||
1
public/vite.svg
Normal file
1
public/vite.svg
Normal file
|
|
@ -0,0 +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>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
BIN
public/webjsx.png
Normal file
BIN
public/webjsx.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.4 KiB |
47
readme.md
Normal file
47
readme.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Vite + WebJSX Template Repository
|
||||
|
||||

|
||||
|
||||
This is a template repository for creating an initialized front-end project. Clone this template and those libraries are pre-installed and pre-configured without further actions:
|
||||
|
||||
- [Vite](https://vite.dev)
|
||||
- [TypeScript](https://www.typescriptlang.org)
|
||||
- [WebJSX](https://webjsx.org) with [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) support (Shadow DOM not included)
|
||||
- [UnoCSS](https://unocss.dev) with Tailwind CSS-reset presets and attributify mode enabled
|
||||
- [Biome](https://biomejs.dev) with tab character indentation (instead of spaces) and avoiding semicolons
|
||||
- `.gitignore` file with whitelist mode
|
||||
|
||||
## How to Use
|
||||
- Click `Use this template` at the top-right, then `Create a new repository`
|
||||
- Fill in the information
|
||||
- Clone the new project to your local machine
|
||||
- `npm i` then `npm run dev`
|
||||
- See the template on your browser
|
||||
|
||||
Don’t forget to:
|
||||
|
||||
- Modify this `readme.md` file
|
||||
- Modify the name in `package.json` config
|
||||
- Check the `.gitignore` (since it is in whitelist mode)
|
||||
- Check the preset of `biome.json`, and set the git hook
|
||||
- Remove unlicense statement and replace it as your own (if necessary)
|
||||
|
||||
## But Why
|
||||
The vanilla-flavored (a.k.a. native environment) front-end is more powerful than we expected, especially for people who have a lot of experience with “modern frameworks” like React, Vue, Angular, etc. Web Components is a really powerful technology and you should have a try and consider replacing the bulky frameworks.
|
||||
|
||||
I made a lightweight framework (which in learning purpose) based on Web Components technology called [Laterano](https://codeberg.org/Astrian/Laterano) and works fine. However, it doesn’t resolve an issue to traditional Web Components. For example, the editor cannot highlight the syntax of inline HTML strings, also it cannot check the type of the components, etc.
|
||||
|
||||
That’s why WebJSX was introduced. WebJSX is a JSX/TSX transpiler instead of a fully functional front-end framework. You can enjoy the benefits from JSX/TSX language, such as HTML syntax highlighting, list rendering and conditional rendering, type check and more. I believe it is a great improvement of the development experience of Web Components (although I am actually not a fan of JSX/TSX language).
|
||||
|
||||
Since Vite doesn’t provide the project initialize preset of Web Components/WebJSX, I created this template repository to avoid re-configurating when I create a new front-end project.
|
||||
|
||||
For UnoCSS and Biome, it just my personal preference.
|
||||
|
||||
UnoCSS is a lighter version of Tailwind and give you a larger flexibility of styling and higher performance on CSS generating. Same reason of choosing Biome instead of Prettier.
|
||||
|
||||
You may notice I prefer to use tab character and avoid semicolons as indentation. This is a very personal choice, which I believe it can save more storage no matter on local machine or remote hosting. Also I think tab character can let user to choose their indentation length instead of fixed 2 or 4 width.
|
||||
|
||||
You can clone and get rid of all my personal quirk anytime.
|
||||
|
||||
## (Un)license
|
||||
This template is totally in public domain and anyone can use, modify and distribute the template as they wish. See [UNLICENSE](./UNLICENSE)
|
||||
43
src/counter.tsx
Normal file
43
src/counter.tsx
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { applyDiff } from "webjsx"
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
"x-counter": {
|
||||
onclick?: () => void
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CounterComp extends HTMLElement {
|
||||
counter = 0
|
||||
|
||||
connectedCallback() {
|
||||
this.render()
|
||||
}
|
||||
|
||||
render = () => {
|
||||
const content = (
|
||||
<button
|
||||
type="button"
|
||||
rounded="0.5rem"
|
||||
border="~ transparent hover:#646cff"
|
||||
p="y-0.6rem x-1.2rem"
|
||||
font="medium"
|
||||
bg="#f9f9f9 dark:#1a1a1a"
|
||||
onClick={this.counterPlus}
|
||||
>
|
||||
Count is {this.counter}
|
||||
</button>
|
||||
)
|
||||
applyDiff(this, content)
|
||||
}
|
||||
|
||||
counterPlus = () => {
|
||||
this.counter++
|
||||
this.render()
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("x-counter", CounterComp)
|
||||
52
src/main.tsx
Normal file
52
src/main.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { applyDiff } from "webjsx"
|
||||
import viteLogo from "/vite.svg"
|
||||
import webjsxlogo from "/webjsx.png"
|
||||
import "@unocss/reset/tailwind.css"
|
||||
import "virtual:uno.css"
|
||||
import "./style.css"
|
||||
import "./counter"
|
||||
|
||||
class App extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.render()
|
||||
}
|
||||
|
||||
render = () => {
|
||||
const content = (
|
||||
<div w="100vw">
|
||||
<div
|
||||
max-w="80rem"
|
||||
m="y-0 x-auto"
|
||||
p="8"
|
||||
un-text="align-center"
|
||||
flex="~ col"
|
||||
items="center"
|
||||
>
|
||||
<div flex="~">
|
||||
<a href="https://vite.dev" target="_blank" rel="noreferrer">
|
||||
<img src={viteLogo} alt="Vite logo" h="24" p="6" />
|
||||
</a>
|
||||
<a href="https://webjsx.org/" target="_blank" rel="noreferrer">
|
||||
<img src={webjsxlogo} alt="TypeScript logo" h="24" p="6" />
|
||||
</a>
|
||||
</div>
|
||||
<h1 font="medium" un-text="3.2rem">
|
||||
Vite + TypeScript + WebJSX
|
||||
</h1>
|
||||
<div class="card">
|
||||
<button id="counter" type="button"></button>
|
||||
</div>
|
||||
<div p="8">
|
||||
<x-counter />
|
||||
</div>
|
||||
<p text="#888">Click on the Vite and WebJSX logos to learn more</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
applyDiff(this, content)
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("x-app", App)
|
||||
29
src/style.css
Normal file
29
src/style.css
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 20rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
1
src/vite-env.d.ts
vendored
Normal file
1
src/vite-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/// <reference types="vite/client" />
|
||||
26
tsconfig.json
Normal file
26
tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
/* JSX Configuration for WebJSX */
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "webjsx",
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
10
uno.config.ts
Normal file
10
uno.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig, presetAttributify, presetWind3 } from "unocss"
|
||||
|
||||
export default defineConfig({
|
||||
presets: [
|
||||
presetWind3({
|
||||
dark: "media",
|
||||
}),
|
||||
presetAttributify({}),
|
||||
],
|
||||
})
|
||||
9
vite.config.ts
Normal file
9
vite.config.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import UnoCSS from "unocss/vite"
|
||||
import { defineConfig } from "vite"
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [UnoCSS()],
|
||||
esbuild: {
|
||||
jsxImportSource: "webjsx",
|
||||
},
|
||||
})
|
||||
Loading…
Reference in New Issue
Block a user