
Web Components Community Building — สร้าง
Web Components

Web Components Custom Elements Shadow DOM HTML Templates Design System Storybook Reusable Community Open Source npm Framework-agnostic React Vue Angular
| Library | Size | DX | Framework | เหมาะกับ |
|---|---|---|---|---|
| Lit | 5KB | ดีมาก | Any | Production |
| Stencil | Compiler | ดี | Any + React/Vue | Enterprise |
| Vanilla | 0KB | ปานกลาง | Any | Simple Components |
| Shoelace | Full Library | ดีมาก | Any | Ready-made UI |
Custom Elements
=== Web Components with Lit ===
npm install lit
my-button.ts
import { LitElement, html, css } from 'lit';
import { customElement, property } from 'lit/decorators.js';
@customElement('my-button')
export class MyButton extends LitElement {
static styles = css`
:host {
display: inline-block;
}
button {
padding: 8px 16px;
border: none;
border-radius: 6px;
font-size: 14px;
cursor: pointer;
transition: all 0.2s;
background: var(--btn-bg, #3b82f6);
color: var(--btn-color, white);
}
button:hover {
opacity: 0.9;
transform: translateY(-1px);
}
button[disabled] {
opacity: 0.5;
cursor: not-allowed;
}
:host([variant="outline"]) button {
background: transparent;
border: 2px solid var(--btn-bg, #3b82f6);
color: var(--btn-bg, #3b82f6);
}
`;
@property() variant = 'solid';
@property({ type: Boolean }) disabled = false;
@property() size = 'md';
render() {
return html`
<button
?disabled=
@click=
>
<slot></slot>
</button>
`;
}
_handleClick(e) {
if (!this.disabled) {
this.dispatchEvent(new CustomEvent('btn-click', {
bubbles: true, composed: true
}));
}
}
}
Usage in HTML:
<my-button>Click Me</my-button>
<my-button variant="outline">Outline</my-button>
<my-button disabled>Disabled</my-button>
Vanilla Web Component (no library)
class MyCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<div class="card">
<div class="title"><slot name="title"></slot></div>
<slot></slot>
</div>
`;
}
}
customElements.define('my-card', MyCard);
from dataclasses import dataclass
@dataclass
class Component:
name: str
category: str
props: int
events: int
slots: int
status: str
components = [
Component("my-button", "Action", 5, 1, 1, "Stable"),
Component("my-input", "Form", 8, 3, 2, "Stable"),
Component("my-card", "Layout", 3, 0, 3, "Stable"),
Component("my-modal", "Overlay", 4, 2, 2, "Stable"),
Component("my-table", "Data", 6, 4, 3, "Beta"),
Component("my-toast", "Feedback", 4, 1, 1, "Stable"),
Component("my-tabs", "Navigation", 3, 2, 2, "Stable"),
Component("my-dropdown", "Action", 5, 3, 2, "Beta"),
]
print("=== Component Library ===")
for c in components:
print(f" [{c.status}] <{c.name}> ({c.category})")
print(f" Props: {c.props} | Events: {c.events} | Slots: {c.slots}")
Design System
=== Design System Setup ===
Design Tokens (CSS Custom Properties)
:root {
/* Colors */
--color-primary: #3b82f6;
--color-secondary: #6366f1;
--color-success: #22c55e;
--color-warning: #f59e0b;
--color-error: #ef4444;
/* Typography */
--font-sans: 'Inter', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
--text-xs: 0.75rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.125rem;
/* Spacing */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-4: 1rem;
--space-8: 2rem;
/* Border Radius */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-full: 9999px;
}
Storybook Setup
npx storybook@latest init
npm run storybook
my-button.stories.ts
import { html } from 'lit';
import './my-button';
export default {
title: 'Components/Button',
component: 'my-button',
argTypes: {
variant: { control: 'select', options: ['solid', 'outline'] },
disabled: { control: 'boolean' },
},
};
export const Primary = { args: {} };
export const Outline = { args: { variant: 'outline' } };
export const Disabled = { args: { disabled: true } };
design_tokens = {
"Colors": "Primary, Secondary, Success, Warning, Error + Shades",
"Typography": "Font Family, Sizes (xs-2xl), Weight, Line Height",
"Spacing": "4px base, Scale 1-12 (4px-48px)",
"Border Radius": "sm 4px, md 8px, lg 12px, full",
"Shadows": "sm, md, lg, xl for elevation",
"Breakpoints": "sm 640px, md 768px, lg 1024px, xl 1280px",
"Animation": "Duration 150ms-500ms, Easing ease-in-out",
}
print("\nDesign Tokens:")
for category, tokens in design_tokens.items():
print(f" [{category}]: {tokens}")
Community Building
=== Open Source Community ===
GitHub Repository Structure
my-components/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ ├── PULL_REQUEST_TEMPLATE.md
│ └── workflows/ci.yml
├── src/
│ ├── components/
│ │ ├── button/
│ │ ├── input/
│ │ └── card/
│ └── styles/tokens.css
├── docs/
├── .storybook/
├── package.json
├── CONTRIBUTING.md
├── CHANGELOG.md
└── README.md
npm publish
npm login
npm version patch # 1.0.0 -> 1.0.1
npm publish --access public
CI/CD — GitHub Actions
name: CI
on: [push, pull_request]
jobs:

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npm test
- run: npm run build
publish:
if: startsWith(github.ref, 'refs/tags/')
needs: test
steps:
- run: npm publish
env:
NODE_AUTH_TOKEN: }
community_metrics = {
"GitHub Stars": "1,250",
"npm Weekly Downloads": "5,800",
"Contributors": "28",
"Open Issues": "15",
"Closed Issues": "342",
"Components": "24",
"Discord Members": "180",
"Storybook Views/mo": "3,200",
}
print("Community Metrics:")
for k, v in community_metrics.items():
print(f" {k}: {v}")
growth_tips = [
"README ดี มี Demo GIF ตัวอย่าง Quick Start",
"Storybook Deploy บน Chromatic หรือ GitHub Pages",
"CONTRIBUTING.md อธิบายวิธี Contribute ชัดเจน",
"Good First Issue Label สำหรับคนใหม่",
"Semantic Versioning + Changelog ทุก Release",
"Blog Post อธิบาย Component Design Decision",
"Twitter/X แชร์ Update ใหม่ สม่ำเสมอ",
"Conference Talk แชร์ประสบการณ์ Design System",
]
print(f"\n\nCommunity Growth Tips:")
for i, t in enumerate(growth_tips, 1):
print(f" {i}. {t}")
เคล็ดลับ
- Lit: ใช้ Lit สำหรับ Web Components เร็ว เบา 5KB
- Tokens: ใช้ CSS Custom Properties เป็น Design Tokens
- Storybook: สร้าง Storybook สำหรับ Document และ Demo
- npm: Publish บน npm ให้คนใช้ง่าย
- Community: Good First Issue + CONTRIBUTING.md สำคัญ
Web Components คืออะไร
Web Standard Reusable Custom Elements Shadow DOM HTML Templates ทุก Framework React Vue Angular Vanilla Browser Design System