Skip to content

Commit

Permalink
feat(Root): Add useRef
Browse files Browse the repository at this point in the history
  • Loading branch information
eanorambuena committed Jul 25, 2024
1 parent 4b707ff commit 925ec46
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 18 deletions.
7 changes: 5 additions & 2 deletions dist/hooks.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
type placeholderCallback = ((component: object) => void) | ((component?: object) => void) | (() => void);
export type DependencyArray = Array<(() => any) | any>;
export type UseState = (initialValue: any) => [() => any, (newValue: any) => void];
export type UseState = <T>(initialValue: T) => [() => T, (newValue: T) => void];
export type UseEffect = (callback: placeholderCallback, dependencies: DependencyArray) => void;
export declare function getValues(dependencies: DependencyArray): Array<any>;
export declare function useState(initialValue: any): [() => any, (newValue: any) => void];
export declare function useState<T>(initialValue: T): [() => T, (newValue: T) => void];
export declare function useEffect(callback: placeholderCallback, dependencies: DependencyArray): void;
export declare function useRef<T>(value?: T): {
current: T;
};
export {};
8 changes: 8 additions & 0 deletions dist/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export function useState(initialValue) {
return [state, setState];
}
export function useEffect(callback, dependencies) {
const isServer = globalThis.navigator.userAgent === 'Node';
if (isServer) {
console.warn('useEffect is not supported on the server');
return;
}
const oldEffectCallback = this.effectCallback;
if (!dependencies || dependencies.length === 0) {
this.effectCallback = (component) => {
Expand Down Expand Up @@ -45,3 +50,6 @@ export function useEffect(callback, dependencies) {
return false;
});
}
export function useRef(value) {
return { current: value };
}
4 changes: 2 additions & 2 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export { useEffect, useState } from './hooks.js';
export { Emmy, loadGlobalEmmy, RouteString, StyleObject, capitalizeFirstLetter, uncapitalizeFirstLetter, createInlineStyle, parseCSS, html, javascript, processGenerator, routerClassNames, vanillaElement } from './utils.js';
export declare const jsx: any;
export type MetaProps = {
el: EmmyComponent;
el: FunctionalComponent;
props: () => object;
children: () => string;
};
Expand Down Expand Up @@ -65,6 +65,6 @@ export declare class Router extends LightComponent {
handleLocation: () => void;
constructor();
}
export declare function launch(component: ClassComponent | FunctionalComponent, name: string): ClassComponent | FunctionalComponent;
export declare function launch(component: ClassComponent | FunctionalComponent, name: string): FunctionalComponent | ClassComponent;
export declare function createPageComponent(url: string, name: string): Promise<ClassComponent | FunctionalComponent>;
export declare function load(func: ComponentType, name: string): Promise<ClassComponent | FunctionalComponent>;
4 changes: 2 additions & 2 deletions dist/server.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export { Emmy, loadGlobalEmmy, RouteString, StyleObject, capitalizeFirstLetter,
import { UseEffect, UseState } from './hooks.js';
export declare const jsx: any;
export type MetaProps = {
el: EmmyComponent;
el: FunctionalComponent;
props: () => object;
children: () => string;
};
Expand Down Expand Up @@ -75,7 +75,7 @@ export declare class Router extends LightComponent {
handleLocation: () => void;
constructor();
}
export declare function launch(component: ClassComponent | FunctionalComponent, name: string): ClassComponent | FunctionalComponent;
export declare function launch(component: ClassComponent | FunctionalComponent, name: string): FunctionalComponent | ClassComponent;
export declare function createPageComponent(url: string, name: string): Promise<ClassComponent | FunctionalComponent>;
export declare function load(func: ComponentType, name: string): Promise<ClassComponent | FunctionalComponent>;
export declare function renderToString(component: ClassComponent | FunctionalComponent): Promise<string>;
Expand Down
15 changes: 12 additions & 3 deletions src/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
type placeholderCallback = ((component: object) => void) | ((component?: object) => void) | (() => void)

export type DependencyArray = Array<(() => any) | any>
export type UseState = (initialValue: any) => [() => any, (newValue: any) => void]
export type UseState = <T>(initialValue: T) => [() => T, (newValue: T) => void]
export type UseEffect = (callback: placeholderCallback, dependencies: DependencyArray) => void

export function getValues(dependencies: DependencyArray): Array<any> {
Expand All @@ -13,7 +13,7 @@ export function getValues(dependencies: DependencyArray): Array<any> {
})
}

export function useState(initialValue): [() => any, (newValue: any) => void] {
export function useState<T>(initialValue: T): [() => T, (newValue: T) => void] {
let value = initialValue
const state = () => value
const setState = (newValue) => {
Expand All @@ -22,7 +22,12 @@ export function useState(initialValue): [() => any, (newValue: any) => void] {
return [state, setState]
}

export function useEffect (callback: placeholderCallback, dependencies: DependencyArray) {
export function useEffect(callback: placeholderCallback, dependencies: DependencyArray) {
const isServer = globalThis.navigator.userAgent === 'Node'
if (isServer) {
console.warn('useEffect is not supported on the server')
return
}
const oldEffectCallback = this.effectCallback
if (!dependencies || dependencies.length === 0) {
this.effectCallback = (component) => {
Expand Down Expand Up @@ -53,3 +58,7 @@ export function useEffect (callback: placeholderCallback, dependencies: Dependen
return false
})
}

export function useRef<T>(value?: T) {
return { current: value }
}
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export {
export const jsx = renderJSX

export type MetaProps = {
el: EmmyComponent,
el: FunctionalComponent,
props: () => object,
children: () => string
}
Expand Down
2 changes: 1 addition & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ require('./ssr/register')
export const jsx = renderJSX

export type MetaProps = {
el: EmmyComponent,
el: FunctionalComponent,
props: () => object,
children: () => string
}
Expand Down
1 change: 1 addition & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,4 @@ export type RouteString = `/${string}`
export type StyleObject = string | {
[key: string]: StyleObject
}

37 changes: 31 additions & 6 deletions test/hooks.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest'
import { Component, FunctionalComponent, HTMLGenerator, bindHooks } from '../src/index.ts'
import { getValues, useState, useEffect } from '../src/hooks.ts'
import { Component, FunctionalComponent, HTMLGenerator, MetaProps, bindHooks } from '../src/index.ts'
import { getValues, useState, useEffect, useRef } from '../src/hooks.ts'
import { awaitDidMount } from './utils.ts'
// Even VSCode doesn't recognize the usage of HTMLElement, it is necessary to test components
import { HTMLElement } from 'happy-dom'
Expand Down Expand Up @@ -30,7 +30,7 @@ describe('useState', () => {
super()
const [state, setState] = useState(0)
this.render('<div></div>', () => {
this.setAttribute('state', state())
this.setAttribute('state', state().toString())
})
}
}
Expand All @@ -48,7 +48,7 @@ describe('useState', () => {
this.render('<div></div>')
const [state, setState] = useState(0)
setState(1)
this.setAttribute('state', state())
this.setAttribute('state', state().toString())
}
}
customElements.define('emmy-a', A)
Expand All @@ -65,10 +65,10 @@ describe('useEffect', () => {
})
it('should call a callback', () => {
expect((() => {
const functionalComponent = ({ el }) => {
const functionalComponent = ({ el }: MetaProps) => {
el.useEffect(() => {
el.setAttribute('callback', 'called')
})
}, [])
return ''
}
class A extends FunctionalComponent {
Expand Down Expand Up @@ -142,3 +142,28 @@ describe('bindHooks', () => {
expect(componentToBind.useEffect).toBeDefined()
})
})

describe('useRef', () => {
it('should be defined', () => {
expect(useRef).toBeDefined()
})
it('should return a ref', () => {
expect((() => {
const functionalComponent = ({ el } : MetaProps) => {
const ref = useRef(0)
el.setAttribute('ref', ref.current!.toString())
return ''
}
class A extends FunctionalComponent {
constructor() {
super(functionalComponent as HTMLGenerator)
}
}
customElements.define('emmy-a', A)
document.body.innerHTML = '<emmy-a></emmy-a>'
awaitDidMount('emmy-a')
const emmyElement = document.querySelector('emmy-a')
return emmyElement?.getAttribute('ref')
})()).toBe('0')
})
})
2 changes: 1 addition & 1 deletion test/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert, expect } from 'vitest'
import { assert } from 'vitest'
import { EmmyComponent } from '../src/index.ts'

export function awaitDidMount(componentName) {
Expand Down

0 comments on commit 925ec46

Please sign in to comment.