@aria-ui/core
Advanced tools
Comparing version 0.0.4 to 0.0.5
# @aria-ui/core | ||
## 0.0.5 | ||
### Patch Changes | ||
- 3db19be: Only consume the context when the element is connected. | ||
## 0.0.4 | ||
@@ -4,0 +10,0 @@ |
@@ -50,3 +50,3 @@ import { Signal } from '@preact/signals-core'; | ||
*/ | ||
interface Context<S extends Signal> { | ||
interface Context<T> { | ||
/** | ||
@@ -57,9 +57,10 @@ * Provides a signal to all children of the element. | ||
*/ | ||
provide(element: ConnectableElement, signal: S): void; | ||
provide(element: ConnectableElement, signal: Signal<T>): void; | ||
/** | ||
* Receives the signal from a parent element. | ||
* @param element The element to consume the signal from. | ||
* @returns The signal or undefined if the signal is not provided. | ||
* @param defaultValue The default value to return if the signal is not provided. | ||
* @returns A signal that is double bound to the provided signal. | ||
*/ | ||
consume(element: ConnectableElement): S | undefined; | ||
consume(element: ConnectableElement, defaultValue: T): Signal<T>; | ||
} | ||
@@ -69,3 +70,3 @@ /** | ||
*/ | ||
declare function createContext<S extends Signal>(key: string | symbol): Context<S>; | ||
declare function createContext<T>(key: string | symbol): Context<T>; | ||
@@ -72,0 +73,0 @@ declare function useEventListener<K extends keyof HTMLElementEventMap>(element: ConnectableElement, type: K, listener: (event: HTMLElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void; |
@@ -53,2 +53,24 @@ // src/base-element.ts | ||
// src/signals.ts | ||
import { | ||
batch, | ||
computed, | ||
effect, | ||
signal, | ||
untracked | ||
} from "@preact/signals-core"; | ||
function useEffect(element, callback) { | ||
let cleanup = void 0; | ||
const dispose = () => { | ||
cleanup == null ? void 0 : cleanup(); | ||
cleanup = void 0; | ||
}; | ||
element.addConnectedCallback(() => { | ||
cleanup == null ? void 0 : cleanup(); | ||
cleanup = effect(callback); | ||
return dispose; | ||
}); | ||
return dispose; | ||
} | ||
// src/context.ts | ||
@@ -76,40 +98,43 @@ var ContextRequestEvent = class extends Event { | ||
} | ||
consume(element) { | ||
let signal3; | ||
element.dispatchEvent( | ||
new ContextRequestEvent(this.key, (s) => { | ||
signal3 = s; | ||
}) | ||
); | ||
return signal3; | ||
consume(element, defaultValue) { | ||
const consumer = signal(defaultValue); | ||
let dispose = void 0; | ||
element.addConnectedCallback(() => { | ||
element.dispatchEvent( | ||
new ContextRequestEvent(this.key, (provider) => { | ||
dispose == null ? void 0 : dispose(); | ||
dispose = bind(provider, consumer); | ||
}) | ||
); | ||
return () => { | ||
dispose == null ? void 0 : dispose(); | ||
dispose = void 0; | ||
}; | ||
}); | ||
return consumer; | ||
} | ||
}; | ||
function bind(provider, consumer) { | ||
consumer.value = provider.peek(); | ||
const unsubscribeProvider = provider.subscribe((value) => { | ||
if (consumer.peek() !== value) { | ||
consumer.value = value; | ||
} | ||
}); | ||
const unsubscribeConsumer = consumer.subscribe((value) => { | ||
if (provider.peek() !== value) { | ||
provider.value = value; | ||
} | ||
}); | ||
return () => { | ||
unsubscribeProvider(); | ||
unsubscribeConsumer(); | ||
}; | ||
} | ||
function createContext(key) { | ||
return new ContextImpl( | ||
typeof key === "string" ? `aira-ui/context/${key}` : key | ||
typeof key === "string" ? `aria-ui/context/${key}` : key | ||
); | ||
} | ||
// src/signals.ts | ||
import { | ||
batch, | ||
computed, | ||
effect, | ||
signal, | ||
untracked | ||
} from "@preact/signals-core"; | ||
function useEffect(element, callback) { | ||
let cleanup = void 0; | ||
const dispose = () => { | ||
cleanup == null ? void 0 : cleanup(); | ||
cleanup = void 0; | ||
}; | ||
element.addConnectedCallback(() => { | ||
cleanup == null ? void 0 : cleanup(); | ||
cleanup = effect(callback); | ||
return dispose; | ||
}); | ||
return dispose; | ||
} | ||
// src/dom.ts | ||
@@ -116,0 +141,0 @@ function useEventListener(element, type, listener, options) { |
{ | ||
"name": "@aria-ui/core", | ||
"type": "module", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"private": false, | ||
@@ -6,0 +6,0 @@ "sideEffects": false, |
# @aria-ui/core | ||
A compact and efficient toolkit for building reactive web components. It powers the [Aria UI](https://github.com/ocavue/aria-ui) library, but it can also be used independently. | ||
## Key Features | ||
### Reactive Signals | ||
Uses signals to manage state reactively and automatically update the DOM in response to state changes. It's powered by the mature and battle-tested [`@preact/signals-core`](https://github.com/preactjs/signals) library. | ||
### Context Management | ||
Shares signals easily across widely nested HTML elements through context. | ||
### DOM Manipulation Utilities | ||
A comprehensive collection of utilities for DOM interactions, enabling declarative management of attributes, styles, and event listeners. | ||
## Classes | ||
@@ -19,12 +35,8 @@ | ||
<!-- prettier-ignore-start --> | ||
| Property | Type | Description | | ||
| :------ | :------ | :------ | | ||
| :-- | :-- | :-- | | ||
| `addConnectedCallback` | (`callback`: () => `void` \| `VoidFunction`) => `void` | Registers a callback to be called when the element is connected to the DOM.<br />This callback can return a cleanup function that will be called when the<br />element is disconnected from the DOM. | | ||
<!-- prettier-ignore-end --> | ||
### Context\<T\> | ||
### Context\<S\> | ||
A context is a way to provide and consume signals in a HTML tree. | ||
@@ -37,3 +49,3 @@ | ||
```ts | ||
consume(element: ConnectableElement): undefined | S | ||
consume(element: ConnectableElement, defaultValue: T): Signal<T> | ||
``` | ||
@@ -46,3 +58,3 @@ | ||
```ts | ||
provide(element: ConnectableElement, signal: S): void | ||
provide(element: ConnectableElement, signal: Signal<T>): void | ||
``` | ||
@@ -82,3 +94,3 @@ | ||
```ts | ||
function createContext<S>(key: string | symbol): Context<S>; | ||
function createContext<T>(key: string | symbol): Context<T>; | ||
``` | ||
@@ -85,0 +97,0 @@ |
import type { ConnectableElement } from "./connectable-element" | ||
import type { Signal } from "./signals" | ||
import { createSignal, type Signal } from "./signals" | ||
class ContextRequestEvent<S extends Signal> extends Event { | ||
class ContextRequestEvent<T> extends Event { | ||
public constructor( | ||
public readonly key: string | symbol, | ||
public readonly callback: (singal: S) => void, | ||
public readonly callback: (singal: Signal<T>) => void, | ||
) { | ||
@@ -16,3 +16,3 @@ super("aria-ui/context-request", { bubbles: true, composed: true }) | ||
*/ | ||
export interface Context<S extends Signal> { | ||
export interface Context<T> { | ||
/** | ||
@@ -23,12 +23,13 @@ * Provides a signal to all children of the element. | ||
*/ | ||
provide(element: ConnectableElement, signal: S): void | ||
provide(element: ConnectableElement, signal: Signal<T>): void | ||
/** | ||
* Receives the signal from a parent element. | ||
* @param element The element to consume the signal from. | ||
* @returns The signal or undefined if the signal is not provided. | ||
* @param defaultValue The default value to return if the signal is not provided. | ||
* @returns A signal that is double bound to the provided signal. | ||
*/ | ||
consume(element: ConnectableElement): S | undefined | ||
consume(element: ConnectableElement, defaultValue: T): Signal<T> | ||
} | ||
class ContextImpl<S extends Signal> implements Context<S> { | ||
class ContextImpl<T> implements Context<T> { | ||
public constructor(private readonly key: string | symbol) { | ||
@@ -39,5 +40,5 @@ this.provide = this.provide.bind(this) | ||
public provide(element: ConnectableElement, signal: S): void { | ||
public provide(element: ConnectableElement, signal: Signal<T>): void { | ||
element.addEventListener("aria-ui/context-request", (event) => { | ||
const { key, callback } = event as ContextRequestEvent<S> | ||
const { key, callback } = event as ContextRequestEvent<T> | ||
if (key === this.key) { | ||
@@ -49,22 +50,51 @@ callback(signal) | ||
public consume(element: ConnectableElement): S | undefined { | ||
let signal: S | undefined | ||
element.dispatchEvent( | ||
new ContextRequestEvent<S>(this.key, (s) => { | ||
signal = s | ||
}), | ||
) | ||
return signal | ||
public consume(element: ConnectableElement, defaultValue: T): Signal<T> { | ||
const consumer = createSignal<T>(defaultValue) | ||
let dispose: VoidFunction | undefined = undefined | ||
element.addConnectedCallback(() => { | ||
element.dispatchEvent( | ||
new ContextRequestEvent<T>(this.key, (provider) => { | ||
dispose?.() | ||
dispose = bind(provider, consumer) | ||
}), | ||
) | ||
return () => { | ||
dispose?.() | ||
dispose = undefined | ||
} | ||
}) | ||
return consumer | ||
} | ||
} | ||
function bind<T>(provider: Signal<T>, consumer: Signal<T>): VoidFunction { | ||
consumer.value = provider.peek() | ||
const unsubscribeProvider = provider.subscribe((value) => { | ||
if (consumer.peek() !== value) { | ||
consumer.value = value | ||
} | ||
}) | ||
const unsubscribeConsumer = consumer.subscribe((value) => { | ||
if (provider.peek() !== value) { | ||
provider.value = value | ||
} | ||
}) | ||
return () => { | ||
unsubscribeProvider() | ||
unsubscribeConsumer() | ||
} | ||
} | ||
/** | ||
* Creates a new context. | ||
*/ | ||
export function createContext<S extends Signal>( | ||
key: string | symbol, | ||
): Context<S> { | ||
return new ContextImpl<S>( | ||
typeof key === "string" ? `aira-ui/context/${key}` : key, | ||
export function createContext<T>(key: string | symbol): Context<T> { | ||
return new ContextImpl<T>( | ||
typeof key === "string" ? `aria-ui/context/${key}` : key, | ||
) | ||
} |
@@ -0,1 +1,26 @@ | ||
/** | ||
* A compact and efficient toolkit for building reactive web components. It | ||
* powers the [Aria UI](https://github.com/ocavue/aria-ui) library, but it can | ||
* also be used independently. | ||
* | ||
* ## Key Features | ||
* | ||
* ### Reactive Signals | ||
* | ||
* Uses signals to manage state reactively and automatically update the DOM in | ||
* response to state changes. It's powered by the mature and battle-tested | ||
* [`@preact/signals-core`](https://github.com/preactjs/signals) library. | ||
* | ||
* ### Context Management | ||
* | ||
* Shares signals easily across widely nested HTML elements through context. | ||
* | ||
* ### DOM Manipulation Utilities | ||
* | ||
* A comprehensive collection of utilities for DOM interactions, enabling | ||
* declarative management of attributes, styles, and event listeners. | ||
* | ||
* @module | ||
*/ | ||
export { BaseElement } from "./base-element" | ||
@@ -2,0 +27,0 @@ export type { ConnectableElement } from "./connectable-element" |
import type { ConnectableElement } from "./connectable-element"; | ||
import type { Signal } from "./signals"; | ||
import { type Signal } from "./signals"; | ||
/** | ||
* A context is a way to provide and consume signals in a HTML tree. | ||
*/ | ||
export interface Context<S extends Signal> { | ||
export interface Context<T> { | ||
/** | ||
@@ -12,9 +12,10 @@ * Provides a signal to all children of the element. | ||
*/ | ||
provide(element: ConnectableElement, signal: S): void; | ||
provide(element: ConnectableElement, signal: Signal<T>): void; | ||
/** | ||
* Receives the signal from a parent element. | ||
* @param element The element to consume the signal from. | ||
* @returns The signal or undefined if the signal is not provided. | ||
* @param defaultValue The default value to return if the signal is not provided. | ||
* @returns A signal that is double bound to the provided signal. | ||
*/ | ||
consume(element: ConnectableElement): S | undefined; | ||
consume(element: ConnectableElement, defaultValue: T): Signal<T>; | ||
} | ||
@@ -24,3 +25,3 @@ /** | ||
*/ | ||
export declare function createContext<S extends Signal>(key: string | symbol): Context<S>; | ||
export declare function createContext<T>(key: string | symbol): Context<T>; | ||
//# sourceMappingURL=context.d.ts.map |
@@ -0,1 +1,25 @@ | ||
/** | ||
* A compact and efficient toolkit for building reactive web components. It | ||
* powers the [Aria UI](https://github.com/ocavue/aria-ui) library, but it can | ||
* also be used independently. | ||
* | ||
* ## Key Features | ||
* | ||
* ### Reactive Signals | ||
* | ||
* Uses signals to manage state reactively and automatically update the DOM in | ||
* response to state changes. It's powered by the mature and battle-tested | ||
* [`@preact/signals-core`](https://github.com/preactjs/signals) library. | ||
* | ||
* ### Context Management | ||
* | ||
* Shares signals easily across widely nested HTML elements through context. | ||
* | ||
* ### DOM Manipulation Utilities | ||
* | ||
* A comprehensive collection of utilities for DOM interactions, enabling | ||
* declarative management of attributes, styles, and event listeners. | ||
* | ||
* @module | ||
*/ | ||
export { BaseElement } from "./base-element"; | ||
@@ -2,0 +26,0 @@ export type { ConnectableElement } from "./connectable-element"; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
170
0
84497
40
833