ladrillosjs 2.0.0-beta.3.6 → 2.0.0-beta.4
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 +296 -0
- package/dist/{index-BCmcPNOm.mjs → index-BcPgsuUl.mjs} +99 -77
- package/dist/{index-BCmcPNOm.mjs.map → index-BcPgsuUl.mjs.map} +1 -1
- package/dist/{index-QzAQ6RiB.js → index-FW6ZH_yR.js} +8 -8
- package/dist/{index-QzAQ6RiB.js.map → index-FW6ZH_yR.js.map} +1 -1
- package/dist/index.d.ts +94 -0
- package/dist/ladrillosjs.cjs.js +1 -1
- package/dist/ladrillosjs.es.js +14 -10
- package/dist/ladrillosjs.umd.js +47 -25
- package/dist/ladrillosjs.umd.js.map +1 -1
- package/dist/types/LadrilloTypes.d.ts +85 -0
- package/dist/webcomponent-BbbpAvoT.js +111 -0
- package/dist/webcomponent-BbbpAvoT.js.map +1 -0
- package/dist/{webcomponent-BbpwGH9E.mjs → webcomponent-Dt-f2pQx.mjs} +272 -224
- package/dist/webcomponent-Dt-f2pQx.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/webcomponent-BbpwGH9E.mjs.map +0 -1
- package/dist/webcomponent-DQzGWQsO.js +0 -89
- package/dist/webcomponent-DQzGWQsO.js.map +0 -1
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ A lightweight, zero-dependency web component framework for building modular web
|
|
|
23
23
|
- [List Rendering](#list-rendering)
|
|
24
24
|
- [Slots](#slots)
|
|
25
25
|
- [Component Props](#component-props)
|
|
26
|
+
- [Lifecycle Hooks](#lifecycle-hooks)
|
|
26
27
|
- [Advanced Features](#advanced-features)
|
|
27
28
|
- [Lazy Loading](#lazy-loading)
|
|
28
29
|
- [Global Event Bus](#global-event-bus)
|
|
@@ -30,6 +31,7 @@ A lightweight, zero-dependency web component framework for building modular web
|
|
|
30
31
|
- [Shadow DOM](#shadow-dom)
|
|
31
32
|
- [Styling Components](#styling-components)
|
|
32
33
|
- [Performance & Caching](#performance--caching)
|
|
34
|
+
- [Creating Component Libraries](#creating-component-libraries)
|
|
33
35
|
- [Common Patterns](#common-patterns)
|
|
34
36
|
- [Keyboard Events](#keyboard-events)
|
|
35
37
|
- [Form Validation](#form-validation)
|
|
@@ -783,6 +785,189 @@ Pass data to components using HTML attributes:
|
|
|
783
785
|
<my-greeting name="Jane" age="30"></my-greeting>
|
|
784
786
|
```
|
|
785
787
|
|
|
788
|
+
### Lifecycle Hooks
|
|
789
|
+
|
|
790
|
+
LadrillosJS provides Vue.js-style lifecycle hooks so you can run code at specific times in a component's lifecycle. These hooks are tied directly to Web Component lifecycle methods for maximum control.
|
|
791
|
+
|
|
792
|
+
#### Available Hooks
|
|
793
|
+
|
|
794
|
+
| Hook | Called | Purpose |
|
|
795
|
+
| ------------ | ------------------------------------------------ | ---------------------------------- |
|
|
796
|
+
| `$onMount` | After component is mounted and fully initialized | Setup, initialization, API calls |
|
|
797
|
+
| `$onUpdate` | After component state changes and re-renders | React to state changes |
|
|
798
|
+
| `$onUnmount` | Before component is removed from DOM | Cleanup, unsubscribe, clear timers |
|
|
799
|
+
|
|
800
|
+
#### `$onMount(callback)`
|
|
801
|
+
|
|
802
|
+
Called once when the component is fully mounted and ready. Perfect for initialization, API calls, and setup logic.
|
|
803
|
+
|
|
804
|
+
```html
|
|
805
|
+
<div>
|
|
806
|
+
<h2>User Profile</h2>
|
|
807
|
+
<p $if="{loading}">Loading...</p>
|
|
808
|
+
<div $else>
|
|
809
|
+
<h3>{user.name}</h3>
|
|
810
|
+
<p>{user.email}</p>
|
|
811
|
+
</div>
|
|
812
|
+
</div>
|
|
813
|
+
|
|
814
|
+
<script>
|
|
815
|
+
let user = { name: "", email: "" };
|
|
816
|
+
let loading = true;
|
|
817
|
+
|
|
818
|
+
// Called after component mounts with state ready
|
|
819
|
+
$onMount(() => {
|
|
820
|
+
console.log("✅ Component mounted!");
|
|
821
|
+
|
|
822
|
+
// Perfect for API calls, initialization, etc
|
|
823
|
+
fetch("/api/user/123")
|
|
824
|
+
.then((res) => res.json())
|
|
825
|
+
.then((data) => {
|
|
826
|
+
user = data;
|
|
827
|
+
loading = false;
|
|
828
|
+
});
|
|
829
|
+
});
|
|
830
|
+
</script>
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
**When to use `$onMount`:**
|
|
834
|
+
|
|
835
|
+
- ✅ Fetch data from APIs
|
|
836
|
+
- ✅ Initialize timers or subscriptions
|
|
837
|
+
- ✅ Set up event listeners
|
|
838
|
+
- ✅ Run component setup logic
|
|
839
|
+
- ✅ Validate initial state
|
|
840
|
+
|
|
841
|
+
#### `$onUpdate(callback)`
|
|
842
|
+
|
|
843
|
+
Called after component state changes and the component re-renders. Perfect for reacting to state changes.
|
|
844
|
+
|
|
845
|
+
```html
|
|
846
|
+
<div>
|
|
847
|
+
<p>Count: {count}</p>
|
|
848
|
+
<button onclick="count++">Increment</button>
|
|
849
|
+
</div>
|
|
850
|
+
|
|
851
|
+
<script>
|
|
852
|
+
let count = 0;
|
|
853
|
+
|
|
854
|
+
$onUpdate(() => {
|
|
855
|
+
console.log("🔄 Component updated! New count:", count);
|
|
856
|
+
|
|
857
|
+
// React to state changes
|
|
858
|
+
if (count === 10) {
|
|
859
|
+
console.log("Count reached 10!");
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
</script>
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
**When to use `$onUpdate`:**
|
|
866
|
+
|
|
867
|
+
- ✅ Log state changes for debugging
|
|
868
|
+
- ✅ Trigger side effects when specific properties change
|
|
869
|
+
- ✅ Sync with external systems
|
|
870
|
+
- ✅ Perform validations on updated state
|
|
871
|
+
|
|
872
|
+
#### `$onUnmount(callback)`
|
|
873
|
+
|
|
874
|
+
Called before the component is removed from the DOM. Perfect for cleanup operations.
|
|
875
|
+
|
|
876
|
+
```html
|
|
877
|
+
<div>
|
|
878
|
+
<p>Timer: {seconds}</p>
|
|
879
|
+
</div>
|
|
880
|
+
|
|
881
|
+
<script>
|
|
882
|
+
let seconds = 0;
|
|
883
|
+
let interval = null;
|
|
884
|
+
|
|
885
|
+
$onMount(() => {
|
|
886
|
+
// Start timer
|
|
887
|
+
interval = setInterval(() => {
|
|
888
|
+
seconds++;
|
|
889
|
+
}, 1000);
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
$onUnmount(() => {
|
|
893
|
+
console.log("❌ Component unmounting, cleaning up...");
|
|
894
|
+
|
|
895
|
+
// Clear timer to prevent memory leaks
|
|
896
|
+
if (interval) {
|
|
897
|
+
clearInterval(interval);
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
</script>
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
**When to use `$onUnmount`:**
|
|
904
|
+
|
|
905
|
+
- ✅ Clear timers and intervals
|
|
906
|
+
- ✅ Remove event listeners
|
|
907
|
+
- ✅ Unsubscribe from observables
|
|
908
|
+
- ✅ Cleanup resources
|
|
909
|
+
- ✅ Cancel pending API requests
|
|
910
|
+
|
|
911
|
+
#### Complete Lifecycle Example
|
|
912
|
+
|
|
913
|
+
```html
|
|
914
|
+
<div>
|
|
915
|
+
<h3>Lifecycle Demo</h3>
|
|
916
|
+
<p>Status: {status}</p>
|
|
917
|
+
<button onclick="status = 'active'">Activate</button>
|
|
918
|
+
<button onclick="status = 'inactive'">Deactivate</button>
|
|
919
|
+
</div>
|
|
920
|
+
|
|
921
|
+
<script>
|
|
922
|
+
let status = "initializing";
|
|
923
|
+
|
|
924
|
+
$onMount(() => {
|
|
925
|
+
console.log("✅ $onMount - Component ready to go!");
|
|
926
|
+
status = "ready";
|
|
927
|
+
});
|
|
928
|
+
|
|
929
|
+
$onUpdate(() => {
|
|
930
|
+
console.log("🔄 $onUpdate - Status changed to:", status);
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
$onUnmount(() => {
|
|
934
|
+
console.log("❌ $onUnmount - Cleaning up before removal");
|
|
935
|
+
});
|
|
936
|
+
</script>
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
#### Lifecycle Timing Diagram
|
|
940
|
+
|
|
941
|
+
```
|
|
942
|
+
┌─────────────────────────────────────────────────────────┐
|
|
943
|
+
│ Element added to DOM │
|
|
944
|
+
│ ↓ │
|
|
945
|
+
│ connectedCallback() starts │
|
|
946
|
+
│ ├─ Parse template │
|
|
947
|
+
│ ├─ Load styles │
|
|
948
|
+
│ ├─ Execute scripts & initialize state │
|
|
949
|
+
│ ├─ Render bindings, conditionals, loops │
|
|
950
|
+
│ │ │
|
|
951
|
+
│ ├─→ $onMount() called ← Component ready! │
|
|
952
|
+
│ │ │
|
|
953
|
+
│ State changes (click, setState, etc) │
|
|
954
|
+
│ ├─ Proxy detects change │
|
|
955
|
+
│ ├─ Schedule update (requestAnimationFrame) │
|
|
956
|
+
│ ├─ Re-render bindings, conditionals, loops │
|
|
957
|
+
│ │ │
|
|
958
|
+
│ ├─→ $onUpdate() called ← After each update │
|
|
959
|
+
│ │ ... (can happen many times) │
|
|
960
|
+
│ │ │
|
|
961
|
+
│ Element removed from DOM │
|
|
962
|
+
│ ├─→ $onUnmount() called ← Before cleanup │
|
|
963
|
+
│ │ │
|
|
964
|
+
│ disconnectedCallback() cleanup │
|
|
965
|
+
│ ├─ Remove event listeners │
|
|
966
|
+
│ ├─ Clear subscriptions │
|
|
967
|
+
│ └─ Complete │
|
|
968
|
+
└─────────────────────────────────────────────────────────┘
|
|
969
|
+
```
|
|
970
|
+
|
|
786
971
|
## Advanced Features
|
|
787
972
|
|
|
788
973
|
### Lazy Loading
|
|
@@ -1410,6 +1595,117 @@ LadrillosJS includes built-in performance optimizations:
|
|
|
1410
1595
|
- Event listeners are automatically cleaned up
|
|
1411
1596
|
- Conditional rendering skips hidden elements
|
|
1412
1597
|
|
|
1598
|
+
## Creating Component Libraries
|
|
1599
|
+
|
|
1600
|
+
LadrillosJS makes it easy to create and publish reusable component libraries. Developers can use your components in their projects with full TypeScript support.
|
|
1601
|
+
|
|
1602
|
+
### Quick Example
|
|
1603
|
+
|
|
1604
|
+
**Create a library:**
|
|
1605
|
+
|
|
1606
|
+
```typescript
|
|
1607
|
+
// src/types/index.ts - Define interfaces
|
|
1608
|
+
export interface ButtonProps {
|
|
1609
|
+
variant?: 'primary' | 'secondary';
|
|
1610
|
+
size?: 'sm' | 'md' | 'lg';
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
export interface AwesomeButton extends HTMLElement {
|
|
1614
|
+
variant?: ButtonProps['variant'];
|
|
1615
|
+
size?: ButtonProps['size'];
|
|
1616
|
+
setLoading(state: boolean): void;
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
// src/components/Button/button.html
|
|
1620
|
+
<button class="btn-{variant}" onclick="handleClick()">
|
|
1621
|
+
<slot>{label}</slot>
|
|
1622
|
+
</button>
|
|
1623
|
+
|
|
1624
|
+
<script>
|
|
1625
|
+
let variant = this.getAttribute('variant') || 'primary';
|
|
1626
|
+
let label = this.getAttribute('label') || 'Click';
|
|
1627
|
+
|
|
1628
|
+
export const handleClick = () => {
|
|
1629
|
+
$emit('button:click', { timestamp: Date.now() });
|
|
1630
|
+
};
|
|
1631
|
+
</script>
|
|
1632
|
+
|
|
1633
|
+
// src/index.ts - Export registry
|
|
1634
|
+
export * from './types';
|
|
1635
|
+
export * from './components/Button';
|
|
1636
|
+
|
|
1637
|
+
export const AWESOME_COMPONENTS = [
|
|
1638
|
+
{ name: 'awesome-button', path: './components/Button/button.html' }
|
|
1639
|
+
];
|
|
1640
|
+
|
|
1641
|
+
export const registerAwesomeComponents = async () => {
|
|
1642
|
+
const { registerComponents } = await import('ladrillosjs');
|
|
1643
|
+
return registerComponents(AWESOME_COMPONENTS);
|
|
1644
|
+
};
|
|
1645
|
+
```
|
|
1646
|
+
|
|
1647
|
+
**Consumers use it:**
|
|
1648
|
+
|
|
1649
|
+
```typescript
|
|
1650
|
+
import {
|
|
1651
|
+
registerAwesomeComponents,
|
|
1652
|
+
createButton,
|
|
1653
|
+
type AwesomeButton,
|
|
1654
|
+
} from "@awesome/ui";
|
|
1655
|
+
|
|
1656
|
+
// Register all components
|
|
1657
|
+
await registerAwesomeComponents();
|
|
1658
|
+
|
|
1659
|
+
// Use in HTML
|
|
1660
|
+
<awesome-button variant="primary" label="Click Me"></awesome-button>;
|
|
1661
|
+
|
|
1662
|
+
// Or programmatically with types
|
|
1663
|
+
const btn = createButton() as AwesomeButton;
|
|
1664
|
+
btn.setAttribute("variant", "secondary");
|
|
1665
|
+
btn.setLoading(true);
|
|
1666
|
+
|
|
1667
|
+
// Type-safe events
|
|
1668
|
+
btn.addEventListener("button:click", (e) => {
|
|
1669
|
+
console.log("Clicked:", e.detail.timestamp);
|
|
1670
|
+
});
|
|
1671
|
+
```
|
|
1672
|
+
|
|
1673
|
+
### Key Features for Libraries
|
|
1674
|
+
|
|
1675
|
+
✅ **TypeScript Interfaces** - Full type definitions for all props, events, and methods
|
|
1676
|
+
✅ **Component Registry** - Easy batch registration
|
|
1677
|
+
✅ **Helper Functions** - `createButton()`, `configureCard()`, etc.
|
|
1678
|
+
✅ **Metadata Export** - Component documentation and metadata
|
|
1679
|
+
✅ **Multiple Formats** - ESM, CJS, UMD outputs
|
|
1680
|
+
✅ **Tree-Shakeable** - Only import what you use
|
|
1681
|
+
|
|
1682
|
+
### Creating Your Library
|
|
1683
|
+
|
|
1684
|
+
1. **Define TypeScript interfaces** for props, events, and typed element references
|
|
1685
|
+
2. **Create single-file `.html` components** with template, styles, and scripts
|
|
1686
|
+
3. **Export helper functions** for programmatic component creation
|
|
1687
|
+
4. **Create component registry** for batch registration
|
|
1688
|
+
5. **Configure package.json** with exports field for subpath imports
|
|
1689
|
+
6. **Build and publish** to NPM
|
|
1690
|
+
|
|
1691
|
+
### Example Projects
|
|
1692
|
+
|
|
1693
|
+
- **[Full Example Library](samples/component-library/)** - Complete Button, Card, Modal components with TypeScript
|
|
1694
|
+
- **[Library Demo App](samples/apps/component-library-demo/)** - Shows all usage patterns and integrations
|
|
1695
|
+
|
|
1696
|
+
### Complete Guide
|
|
1697
|
+
|
|
1698
|
+
For detailed instructions on creating, building, and publishing component libraries, see the **[Library Authoring Guide](docs/LIBRARY_AUTHORING.md)**.
|
|
1699
|
+
|
|
1700
|
+
Topics covered:
|
|
1701
|
+
|
|
1702
|
+
- Project structure and best practices
|
|
1703
|
+
- Component creation with HTML + TypeScript
|
|
1704
|
+
- Building with Vite
|
|
1705
|
+
- Publishing to NPM
|
|
1706
|
+
- Consumer usage examples
|
|
1707
|
+
- React/Vue integration patterns
|
|
1708
|
+
|
|
1413
1709
|
## Common Patterns
|
|
1414
1710
|
|
|
1415
1711
|
### Keyboard Events
|