Skip to content

Commit

Permalink
Feature/#36 stage 3 (#37)
Browse files Browse the repository at this point in the history
* feature(#36): This update introduce the possibility to use stage 3 decorators. This refactor changed the RadiantElement class to be more concise and organised.

---------

Co-authored-by: Andrea Zanenghi <[email protected]>
  • Loading branch information
andeeplus and Andrea Zanenghi authored Oct 14, 2024
1 parent 2bb09b0 commit bf7d904
Show file tree
Hide file tree
Showing 88 changed files with 2,499 additions and 933 deletions.
5 changes: 5 additions & 0 deletions .changeset/loud-starfishes-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ecopages/radiant": minor
---

This update introduce the possibility to use stage 3 decorators. This refactor changed the RadiantElement class to be more concise and organised.
2 changes: 1 addition & 1 deletion apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"devDependencies": {
"@ecopages/core": "npm:@jsr/ecopages__core@latest",
"@ecopages/radiant": "^0.1.8",
"@ecopages/radiant": "*",
"@ecopages/bun-mdx-kitajs-loader": "npm:@jsr/ecopages__bun-mdx-kitajs-loader@latest",
"@ecopages/bun-postcss-loader": "npm:@jsr/ecopages__bun-postcss-loader@latest",
"@ecopages/kitajs": "npm:@jsr/ecopages__kitajs@latest",
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/components/burger/burger.script.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BurgerEvents } from '@/components/burger/burger.events';
import { RadiantElement } from '@ecopages/radiant/core';
import { RadiantElement } from '@ecopages/radiant/core/radiant-element';
import { customElement } from '@ecopages/radiant/decorators/custom-element';
import { debounce } from '@ecopages/radiant/decorators/debounce';
import { onEvent } from '@ecopages/radiant/decorators/on-event';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RadiantElement } from '@ecopages/radiant/core';
import { RadiantElement } from '@ecopages/radiant/core/radiant-element';
import { customElement } from '@ecopages/radiant/decorators/custom-element';
import { onEvent } from '@ecopages/radiant/decorators/on-event';
import { onUpdated } from '@ecopages/radiant/decorators/on-updated';
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/layouts/docs-layout/docs-layout.script.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BurgerEvents } from '@/components/burger/burger.events';
import { onEvent } from '@ecopages/radiant';
import { RadiantElement } from '@ecopages/radiant/core';
import { RadiantElement } from '@ecopages/radiant/core/radiant-element';
import { customElement } from '@ecopages/radiant/decorators/custom-element';

@customElement('radiant-navigation')
Expand Down
202 changes: 194 additions & 8 deletions apps/docs/src/pages/docs/core/radiant-element.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,203 @@ export const getMetadata = () => ({
# Radiant Element
---

This is the base class for all Radiant. It provides a set of decorators that can be used to define the behavior of the element.
The `RadiantElement` class serves as a base for creating custom web components with reactive properties, event handling, and template rendering capabilities. It extends the native `HTMLElement` and implements the `IRadiantElement` interface, providing a robust framework for building interactive and dynamic elements.

Please note that this class is not meant to be used directly. Instead, you should extend it to create your own custom elements.
The suggested way to create a custom element is to extend the `RadiantElement` class and use the provided decorators and methods to define reactive properties, event listeners, and template rendering logic. This approach simplifies the process of creating and managing custom elements, making it easier to build complex and interactive components.

You can use the `@customElement` decorator to define a custom element.
It is still possible to use the `RadiantElement` class without decorators by manually calling the corresponding methods. However, using decorators is the recommended way to take advantage of the built-in features and simplify the code.

Go to the [Decorator Section](/docs/decorators/custom-element) to see all the available decorators.
Please have a look to the [Decorator Section](/docs/decorators/custom-element) to see the available decorators.

<CodeBlock >
## Key Features

- **Reactive Properties**: Automatically update the UI when properties change.
- **Event Management**: Subscribe to and manage events easily.
- **Template Rendering**: Render HTML templates dynamically within the component.


### Example

Following is an example of a custom element created using the `RadiantElement` class with decorators:

<CodeBlock>
```typescript
@customElement('my-custom-element')
class MyCustomElement extends RadiantElement {
@reactiveProp({ type: String, defaultValue: 'Foo' }) foo: string;
@query({ ref: 'paragraph' }) paragraph!: HTMLParagraphElement;

@onUpdated('foo')
updateParagraph() {
this.paragraph.textContent = `Hello ${this.foo}`;
}

@onEvent({ selector: 'button', type: 'click' })
handleClick() {
this.foo = 'World';
}
}
```
</CodeBlock>

The above example demonstrates how to create a custom element using the `RadiantElement` class with decorators. The element has a reactive property `foo`, a reference to a paragraph element, and an event listener for a button click. When the button is clicked, the `foo` property is updated, triggering the `updateParagraph` method to update the paragraph text.

## Example without Decorators

<CodeBlock>
```typescript
@customElement('lc-demo')
export class MyElement extends RadiantElement {}
class MyCustomElement extends RadiantElement {
declare foo: string;
paragraph = this.getRef<HTMLParagraphElement>('paragraph');

constructor() {
super();
this.createReactiveProp('foo', { type: String, defaultValue: 'Foo' });
this.registerUpdateCallback('foo', () => {
this.paragraph.textContent = `Hello ${this.foo}`;
});
this.subscribeEvent({
selector: 'button',
type: 'click',
listener: () => {
this.foo = 'World';
},
});
}
}
customElements.define('my-custom-element-plain', MyCustomElementPlain);
```
</CodeBlock>
</CodeBlock>

The above example demonstrates how to create a custom element using the `RadiantElement` class without decorators. The element has a reactive property `foo`, a reference to a paragraph element, and an event listener for a button click. When the button is clicked, the `foo` property is updated, triggering the update callback to update the paragraph text.

## Usage

<CodeBlock>
```html
<my-custom-element>
<p data-ref="paragraph"></p>
<button>Click me</button>
</my-custom-element>
```
</CodeBlock>

## Methods

### createReactiveProp

Creates a reactive property for the element.

- **Parameters**:
- `name`: The name of the property.
- `options`: The property configuration options.

This method defines a reactive property on the element, allowing it to automatically update the UI when the property changes.

---
### createReactiveField

Creates a reactive field for the element.

- **Parameters**:
- `name`: The name of the field.

This method defines a reactive field on the element, allowing it to automatically update the UI when the field changes.

---
### registerUpdateCallback

Registers a callback to be executed when a property is updated.

- **Parameters**:
- `property`: The name of the property to watch for updates.
- `callback`: The callback function to execute when the property is updated.

This method allows you to define custom logic that runs when a specific property is updated.


---
### notifyUpdate

Called when a property of the element is updated.

- **Parameters**:
- `changedProperty`: The name of the changed property.
- `oldValue`: The old value of the property.
- `newValue`: The new value of the property.

This method triggers any registered update callbacks for the specified property.

---
### subscribeEvent

Subscribes to a specific event on the Radiant element.

- **Parameters**:
- `event`: The event listener configuration to subscribe to.
- **Returns**: An unsubscription callback for the event.

This method allows you to listen for events and execute a callback when the event occurs.

---
### subscribeEvents

Subscribes to multiple events at once.

- **Parameters**:
- `events`: An array of event listener configurations to subscribe to.
- **Returns**: An array of unsubscription callbacks for each event.

This method is useful for batch subscribing to multiple events for the element.

---
### removeAllSubscribedEvents

Removes all event listeners that have been subscribed to the Radiant element.

This method is important for cleaning up event listeners to avoid memory leaks.

---
### registerCleanupCallback

Registers a callback to be executed when the element is disconnected from the DOM.

- **Parameters**:
- `callback`: The cleanup function to be executed.

This method allows you to define cleanup logic that runs when the element is removed from the DOM.

---
### renderTemplate

Renders a specified template into a target element.

- **Parameters**:
- `options`: The rendering options.
- `target`: The target element to render the template into.
- `template`: The HTML template string to render.
- `insert`: The position to insert the rendered template (optional).

This method allows you to dynamically insert HTML content into the element.

---
### connectedContextCallback

Called when the Radiant element is connected to a specific context.

- **Parameters**:
- `context`: The context to which the element is connected.

This method can be overridden to perform actions when the element is connected to a context.

---
### getRef

Retrieves a child element by its `data-ref` attribute.

- **Parameters**:
- `ref`: The value of the `data-ref` attribute to search for.
- `all`: Whether to return all matching elements (true) or just the first one (false).
- **Returns**: The matching element(s) or null if none are found.

This method simplifies accessing child elements based on their `data-ref` attributes.
24 changes: 22 additions & 2 deletions apps/docs/src/pages/docs/getting-started/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,33 @@ export const getMetadata = () => ({
description: 'The place to learn about @ecopages/radiant',
})

<div class="banner banner--info mt-4" role="alert">
<p class="banner__title">Notes</p>
<p>The Radiant library is still in development and subject to change. Please use with caution and report any issues or suggestions on the [GitHub repository](https://github.com/ecopages/radiant).</p>
</div>

# Introduction
---

<div class="bg-orange-50 rounded-md p-4 text-sm">
## radiant
/ˈreɪdɪənt/

**adjective**
<p>1. sending out light; shining or glowing brightly.</p>
<ul class="list-disc text-gray-800">
<li>"a bird with radiant green and red plumage"</li>
</ul>
<p>2. (of electromagnetic energy, especially heat) transmitted by radiation, rather than conduction or convection.</p>
<ul class="list-disc text-gray-800">
<li>"plants convert the radiant energy of the sun into chemical energy"</li>
</ul>
**noun**
</div>

Radiant is a minimalist web component library designed for simplicity and flexibility.

It leverages the light DOM, allowing components to be styled and manipulated with standard CSS and JavaScript, unlike traditional web components that use the shadow DOM.

This approach deviates from conventional web component best practices, offering a trade-off for a more streamlined development experience.

Ideal for small to medium-sized projects, Radiant provides a lightweight alternative to full web components implementations, reducing unnecessary overhead for projects that don't demand the full capabilities of the standard.
Ideal for small to medium-sized projects, Radiant provides a lightweight alternative to full web components implementations, reducing unnecessary overhead for projects that don't demand the full encapsulation of the standard.
Loading

0 comments on commit bf7d904

Please sign in to comment.