Package Exports
- @cal.macconnachie/web-components
- @cal.macconnachie/web-components/components/auth.js
- @cal.macconnachie/web-components/components/index
- @cal.macconnachie/web-components/components/index.d.ts
- @cal.macconnachie/web-components/components/theme-toggle.js
- @cal.macconnachie/web-components/stylesheets/main
Readme
Cals Web Components
Repo to handle any and all web components I may want to build
Install & use
Option 1: Load the full bundle (all components)
Load all components from the CDN:
<script type="module" src="https://cdn.cals-api.com/index"></script>Option 2: Load individual components (recommended)
Load only the components you need:
<!-- Load just the auth component -->
<script type="module" src="https://cdn.cals-api.com/components/auth.js"></script>Option 3: Using with Vue, React, or other frameworks
For framework projects (Vue, React, etc.), load the component via script tag in your index.html:
<!-- index.html -->
<script type="module" src="https://cdn.cals-api.com/components/auth.js"></script>Then create a type declaration file for TypeScript support:
// src/types/auth.d.ts
export interface Auth extends HTMLElement {
openModal(): void;
logout(): void;
}
declare global {
interface HTMLElementTagNameMap {
'auth': Auth;
}
}Now you can use it with full type safety in your components:
Vue:
<template>
<auth ref="authRef" app-name="Marketplace"></auth>
<button @click="openAuth">Login / Sign up</button>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import type { Auth } from '@/types/auth';
const authRef = ref<Auth>();
const openAuth = () => {
authRef.value?.openModal();
};
</script>React:
import { useRef } from 'react';
import type { Auth } from '@/types/auth';
function App() {
const authRef = useRef<Auth>(null);
return (
<>
<auth ref={authRef} app-name="Marketplace"></auth>
<button onClick={() => authRef.current?.openModal()}>
Login / Sign up
</button>
</>
);
}Usage Example
HTML:
<auth id="auth" app-name="Marketplace"></auth>
<button id="open-auth">Login / Sign up</button>
<button id="logout-auth">Logout</button>JavaScript:
const auth = document.querySelector('auth');
document.getElementById('open-auth')?.addEventListener('click', () => {
auth?.openModal();
});
document.getElementById('logout-auth')?.addEventListener('click', () => {
auth?.logout();
});TypeScript:
import type { Auth } from 'https://cdn.cals-api.com/components/auth.js';
const auth = document.querySelector<Auth>('auth');
document.getElementById('open-auth')?.addEventListener('click', () => {
auth?.openModal();
});
document.getElementById('logout-auth')?.addEventListener('click', () => {
auth?.logout();
});Available Components
auth- Authentication component with sign in, sign up, and password reset
Project Structure
This repository uses Yarn workspaces to manage two packages:
- Root package (
web-components): The Lit web component library - CDN package (
cdn/): AWS CDK infrastructure for deploying the component to CloudFront
Develop
Web Component Development
yarn install– install dependencies for all workspacesyarn dev– run the Vite playground athttp://localhost:5173yarn build– bundle the full library todist/yarn build:components– build individual components todist/components/{component-name}/yarn typecheck– run TypeScript without emitting
CDK Infrastructure
yarn cdk:synth– synthesize the CDK stackyarn cdk:diff– compare deployed stack with current stateyarn cdk:deploy– deploy the CDK stack to AWSyarn cdk:destroy– destroy the CDK stackyarn cdk <command>– run any CDK command
Publish
Publishing to the CDN is automated on pushes to main via .github/workflows/publish.yml.
The workflow:
- Builds the full bundle and individual components
- Deploys the CDK stack (S3 + CloudFront)
- Uploads files to S3:
- Full bundle at root:
https://cdn.cals-api.com/index.es.js - Individual components:
https://cdn.cals-api.com/components/{component-name}/index.es.js
- Full bundle at root:
- Invalidates CloudFront cache