Skip to content

Commit

Permalink
chore!: Rename ref and refs
Browse files Browse the repository at this point in the history
BREAKING CHANGE: to migrate name all ref/refs related arguments and
types:
- `refs` -> `refsAll`  (`registerComponent('name', { refsAll })`)
- `ref` -> `refs` (`registerComponent('name', { refs })`)
- `DefineRef` -> `DefineRefs`
- `DefineRefs` -> `DefineRefsAll`
  • Loading branch information
arnoson committed Feb 21, 2023
1 parent 66d8049 commit cb259d4
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 28 deletions.
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ npm i @very-simple/components
import { registerComponent, defineProps } from '@very-simple/components'

const props = defineProps({ loop: Boolean })
registerComponent('gallery', ({ el, ref, refs }) => {
registerComponent('gallery', ({ el, refs, refsAll }) => {
// Props are read from el's dataset and automatically converted to the correct
// type. Default values are also possible, see documentation.
const { loop } = props(el)

// Multiple HTML elements can have the same `ref` name. They will be
// grouped in `refs` ...
const { slides } = refs
// grouped in `refsAll` ...
const { slides } = refsAll

// ... whereas `ref` only stores a single element per name.
const { prev, next } = ref
// ... whereas `refs` only stores a single element per name.
const { prev, next } = refs

let currentIndex = 0
const maxIndex = slides.length - 1
Expand Down Expand Up @@ -80,8 +80,8 @@ registerComponent(name: string, component: Component)

type Component = (payload: {
el: HTMLElement
ref: Record<string, HTMLElement | undefined>
refs: Record<string, HTMLElement[]>
refs: Record<string, HTMLElement | undefined>
refsAll: Record<string, HTMLElement[]>
}) => any
```
Expand Down Expand Up @@ -187,19 +187,22 @@ const el = document.getElementById<SimpleElement<typeof MyComponent>>('my-id')
el.$component.sayHello() // <- this gets autocompleted
```

### Define Ref(s) Types
### Define Ref Types

Refs are of type HTMLElement by default, but it can be useful to define a more
specific type for some of them:

```ts
import type { DefineRef, DefineRefs } from '@very-simple/components'
import type { DefineRefs, DefineRefsAll } from '@very-simple/components'

registerComponent('my-component', ({ refs, ref }) => {
const { slides, videos } = refs as DefineRefs<{ videos: HTMLVideoElement[] }>
registerComponent('my-component', ({ refs, refsAll }) => {
const { slides, videos } = refsAll as DefineRefsAll<{
videos: HTMLVideoElement[]
}>
// slides -> HTMLElement[]
// videos -> HTMLVideoElement[]
const { container, img } = ref as DefineRef<{ img: HTMLImageElement }>

const { container, img } = refs as DefineRefs<{ img: HTMLImageElement }>
// container -> HTMLElement
// img -> HTMLImageElement
})
Expand Down
14 changes: 7 additions & 7 deletions src/mountComponent.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getComponent } from './registerComponent'
import { SimpleRef, SimpleRefs } from './types'
import { SimpleRefs, SimpleRefsAll } from './types'
import { walkComponent } from './walkComponent'

const getRefs = (el: HTMLElement): SimpleRefs => {
const refs: SimpleRefs = {}
const getRefsAll = (el: HTMLElement): SimpleRefsAll => {
const refs: SimpleRefsAll = {}
walkComponent(el, el => {
const { ref } = el.dataset
if (ref) {
Expand All @@ -26,14 +26,14 @@ const mountChildComponents = (el: HTMLElement) => {
export const mountComponent = (el: HTMLElement, isChild = false) => {
// Don't re-initialize component.
if (!(el as any).$component) {
const refs = getRefs(el)
const ref: SimpleRef = Object.fromEntries(
Object.entries(refs).map(([key, value]) => [key, value[0]])
const refsAll = getRefsAll(el)
const refs: SimpleRefs = Object.fromEntries(
Object.entries(refsAll).map(([key, value]) => [key, value[0]])
)

const component = getComponent(el)
if (component) {
;(el as any).$component = component({ el, ref, refs }) || {}
;(el as any).$component = component({ el, refs, refsAll }) || {}
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export type SimpleRef = Record<string, HTMLElement | undefined>
export type SimpleRefs = Record<string, HTMLElement | undefined>

export type SimpleRefs = Record<string, HTMLElement[]>
export type SimpleRefsAll = Record<string, HTMLElement[]>

export type DefineRef<T> = SimpleRef & Partial<T>
export type DefineRefs<T> = SimpleRefs & Partial<T>

export type DefineRefs<T> = SimpleRefs & T
export type DefineRefsAll<T> = SimpleRefsAll & T

export type SimpleInstance<C extends SimpleComponent> = ReturnType<C>

Expand All @@ -14,8 +14,8 @@ export type SimpleElement<C extends SimpleComponent, T = HTMLElement> = T & {

export interface SimpleComponentPayload<T> {
el: T
ref: SimpleRef
refs: SimpleRefs
refsAll: SimpleRefsAll
}

export type SimpleComponent<T = HTMLElement> = (
Expand Down
8 changes: 4 additions & 4 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ it(`doesn't walk elements with data-simple-ignore attribute`, () => {
expect(component).toBeCalledWith(expect.objectContaining({ refs: {} }))
})

it('provides a record of single refs', () => {
it.only('provides a record of single refs', () => {
const component = vi.fn()
registerComponent('test', component)

Expand All @@ -79,10 +79,10 @@ it('provides a record of single refs', () => {
`
mountComponents(document.body)
const myRef = document.querySelector(`[data-ref='myRef']`)
expect(component).toBeCalledWith(expect.objectContaining({ ref: { myRef } }))
expect(component).toBeCalledWith(expect.objectContaining({ refs: { myRef } }))
})

it('provides a record of groups of refs with the same name', () => {
it.only('provides a record of groups of refs with the same name', () => {
const component = vi.fn()
registerComponent('test', component)

Expand All @@ -99,7 +99,7 @@ it('provides a record of groups of refs with the same name', () => {
document.querySelector('#ref2'),
document.querySelector('#ref3')
]
expect(component).toBeCalledWith(expect.objectContaining({ refs: { myRef } }))
expect(component).toBeCalledWith(expect.objectContaining({ refsAll: { myRef } }))
})

it(`parses props`, () => {
Expand Down

0 comments on commit cb259d4

Please sign in to comment.