Skip to content

Commit

Permalink
orchestra vanilla
Browse files Browse the repository at this point in the history
  • Loading branch information
clementroche committed Nov 23, 2023
1 parent 3e25913 commit 1f51bda
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 54 deletions.
107 changes: 71 additions & 36 deletions libs/orchestra/index.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,84 @@
import { broadcast } from 'libs/zustand-broadcast'
import { useEffect, useState } from 'react'
import { create } from 'zustand'
import { shared } from 'libs/zustand-shared'
// import { create } from 'zustand'
import { createJSONStorage, persist } from 'zustand/middleware'
import { createStore } from 'zustand/vanilla'

// avoid to display debug tools on orchestra page
let isOrchestraPage = false

const useOrchestraStore = create(
const ID = 'orchestra'
let store = createStore(
persist(() => ({}), {
name: 'orchestra',
name: ID,
storage: createJSONStorage(() => localStorage),
}),
)

broadcast(useOrchestraStore, 'orchestra')

export function useOrchestra() {
const values = useOrchestraStore()
store = shared(store, ID)

const [isVisible, setIsVisible] = useState(false)
class Toggle {
constructor(id, content) {
this.id = id
this.content = content
this.domElement = document.createElement('button')
this.domElement.innerText = content
this.domElement.title = id
this.domElement.style.fontSize = '64px'
this.domElement.addEventListener('click', this.onToggle, false)
}

useEffect(() => {
setIsVisible(!isOrchestraPage)
}, [])
onToggle = () => {
store.setState((state) => ({ ...state, [this.id]: !state[this.id] }))
}

return isVisible && values
destroy() {
this.domElement.removeEventListener('click', this.onToggle, false)
this.domElement.remove()
}
}

// to be added to debug pages
export function OrchestraToggle({ children, title, id }) {
isOrchestraPage = true

return (
<button
onClick={() => {
useOrchestraStore.setState((state) => {
const clone = { ...state }
clone[id] = !clone[id]
return clone
})
}}
title={title}
style={{ fontSize: '64px' }}
>
{children}
</button>
)
class Orchestra {
constructor() {
this.domElement = document.createElement('div')

this.isDebug = false
this.toggles = []
}

get state() {
return !this.isDebug && store.getState()
}

subscribe(callback) {
if (!this.isDebug) store.subscribe(callback)
}

add(id, content) {
// check if already exists
if (this.toggles.find((toggle) => toggle.id === id)) return this

const toggle = new Toggle(id, content)
this.toggles.push(toggle)
this.domElement.appendChild(toggle.domElement)

return this
}

remove(id) {
const toggle = this.toggles.find((toggle) => toggle.id === id)
// this.domElement.removeChild(toggle.domElement)
toggle.destroy()
this.toggles = this.toggles.filter((toggle) => toggle.id !== id)

return this
}
}

const isClient = typeof window !== 'undefined'

export default isClient && new Orchestra()

// To be added to debug page
// Orchestra.isDebug = true
// Orchestra.add('studio', '⚙️')
// Orchestra.add('stats', '📈')
// Orchestra.add('grid', '🌐')
// Orchestra.add('dev', '🚧')
// document.body.appendChild(Orchestra.domElement)
34 changes: 34 additions & 0 deletions libs/orchestra/react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useEffect, useRef, useState } from 'react'
import Orchestra from '.'

export function useOrchestra() {
const [state, setState] = useState({})

useEffect(() => {
setState(Orchestra.state)
Orchestra.subscribe((state) => {
setState(state)
})
}, [])

return state
}

export function OrchestraToggle({ id, children }) {
if (Orchestra) Orchestra.isDebug = true

const elementRef = useRef()

useEffect(() => {
Orchestra.add(id, children)
const toggle = Orchestra.toggles.find((toggle) => toggle.id === id)
elementRef.current.appendChild(toggle.domElement)

return () => {
Orchestra.remove(id)
toggle.domElement.remove()
}
}, [id, children])

return <span ref={elementRef} />
}
42 changes: 42 additions & 0 deletions libs/orchestra/react.old.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useEffect, useState } from 'react'

// avoid to display debug tools on orchestra page
let isOrchestraPage = false

let useOrchestraStore = create(
persist(() => ({}), {
name: 'orchestra',
storage: createJSONStorage(() => localStorage),
}),
)

useOrchestraStore = shared(useOrchestraStore, 'orchestra')

export function useOrchestra() {
const values = useOrchestraStore()

const [isVisible, setIsVisible] = useState(false)

useEffect(() => {
setIsVisible(!isOrchestraPage)
}, [])

return isVisible && values
}

// to be added to debug pages
export function OrchestraToggle({ children, title, id }) {
isOrchestraPage = true

return (
<button
onClick={() => {
useOrchestraStore.setState((state) => ({ [id]: !state[id] }))
}}
title={title}
style={{ fontSize: '64px' }}
>
{children}
</button>
)
}
2 changes: 1 addition & 1 deletion libs/theatre/hooks/use-studio.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useOrchestra } from 'libs/orchestra'
import { useOrchestra } from 'libs/orchestra/react'
import { useEffect, useState } from 'react'

let studioPackage
Expand Down
4 changes: 3 additions & 1 deletion libs/zustand-broadcast.js → libs/zustand-shared.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function broadcast(store, id = 'zustand-broadcast') {
export function shared(store, id = 'zustand-broadcast') {
if ('BroadcastChannel' in globalThis) {
let justReceived = false
const channel = new BroadcastChannel(id)
Expand All @@ -15,4 +15,6 @@ export function broadcast(store, id = 'zustand-broadcast') {
}
})
}

return store
}
2 changes: 1 addition & 1 deletion pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DeviceDetectionProvider } from 'components/device-detection'
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/dist/ScrollTrigger'
import { GTM_ID } from 'libs/analytics'
import { useOrchestra } from 'libs/orchestra'
import { useOrchestra } from 'libs/orchestra/react'
import { useStore } from 'libs/store'
import { ProjectProvider, RafDriverProvider } from 'libs/theatre'
import dynamic from 'next/dynamic'
Expand Down
22 changes: 7 additions & 15 deletions pages/_debug/orchestra/index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import { OrchestraToggle } from 'libs/orchestra'
import { OrchestraToggle } from 'libs/orchestra/react'
import { forwardRef } from 'react'

const Orchestra = forwardRef(function Orchestra({}) {
const OrchestraPage = forwardRef(function OrchestraPage({}) {
return (
<>
<OrchestraToggle title="studio" id="studio">
⚙️
</OrchestraToggle>
<OrchestraToggle title="performance" id="stats">
📈
</OrchestraToggle>
<OrchestraToggle title="grid" id="grid">
🌐
</OrchestraToggle>
<OrchestraToggle title="dev" id="dev">
🚧
</OrchestraToggle>
<OrchestraToggle id="studio">⚙️</OrchestraToggle>
<OrchestraToggle id="stats">📈</OrchestraToggle>
<OrchestraToggle id="grid">🌐</OrchestraToggle>
<OrchestraToggle id="dev">🚧</OrchestraToggle>
</>
)
})

export default Orchestra
export default OrchestraPage

1 comment on commit 1f51bda

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"⚡️ Lighthouse report for the changes in this commit:

🟢 Performance: 100
🟢 Accessibility: 97
🟢 Best practices: 92
🟠 SEO: 75
🔴 PWA: 40

Lighthouse ran on https://satus-nf92x8x77-studio-freight.vercel.app/"

Please sign in to comment.