window-plug
TypeScript icon, indicating that this package has built-in type declarations

1.1.0 • Public • Published

window-plug

Workspace Window plug

npm i window-plug pnpm add window-plug yarn add window-plug

Examples

# web
    # view source example/web.tsx

    /** @jsxImportSource sigl */
    import $ from 'sigl'
    
    import { deserialize, serialize } from 'serialize-whatever'
    import { ContextMenuOption, WorkspaceElement, WorkspaceWindowElement } from 'x-workspace'
    import { Cable, Plug, WindowPlugElement, WindowPlugSceneElement } from 'window-plug'
    
    const IO = {
      Midi: 'midi',
      Audio: 'audio',
    } as const
    
    interface WindowItemElement extends $.Element<WindowItemElement> {}
    
    @$.element()
    class WindowItemElement extends $(WorkspaceWindowElement) {
      WindowPlug = $.element(WindowPlugElement)
    
      plugScene?: WindowPlugSceneElement
    
      @$.out() inputs = new $.RefSet<WindowPlugElement>([
        { plug: new Plug(Plug.Input, IO.Midi) },
        { plug: new Plug(Plug.Input, IO.Audio) },
      ])
    
      @$.out() outputs = new $.RefSet<WindowPlugElement>([
        { plug: new Plug(Plug.Output, IO.Midi) },
        { plug: new Plug(Plug.Output, IO.Audio) },
      ])
    
      mounted($: WindowItemElement['$']) {
        $.Controls = $.part(() => <div></div>)
    
        $.ContextMenu = $.part(() => (
          <>
            <ContextMenuOption keyboard={['Ctrl', 'N']}>New</ContextMenuOption>
            <ContextMenuOption keyboard={['Alt', 'R']}>Remove the thing</ContextMenuOption>
            <ContextMenuOption>and another</ContextMenuOption>
            <hr />
            <ContextMenuOption disabled>and another</ContextMenuOption>
            <ContextMenuOption>and another</ContextMenuOption>
          </>
        ))
    
        const Plugs = $.part(({ host, WindowPlug, plugScene, inputs, outputs, onContextMenu }) => (
          <div part="plugs">
            {[
              ['inputs', inputs] as const,
              ['outputs', outputs] as const,
            ].map(([part, plugs]) => (
              <div part={part}>
                {plugs.map(plug => (
                  <WindowPlug
                    {window-plug.plug}
                    part="plug"
                    dest={host}
                    scene={plugScene}
                    oncontextmenu={onContextMenu(() => (
                      <>
                        <ContextMenuOption keyboard={['Alt', 'M']} disabled={!plug.ref.current?.plug?.cables.size}>
                          Mute All
                        </ContextMenuOption>
                        <ContextMenuOption keyboard={['Alt', 'D']} disabled={!plug.ref.current?.plug?.cables.size}>
                          Disconnect All
                        </ContextMenuOption>
                      </>
                    ))}
                  />
                ))}
              </div>
            ))}
          </div>
        ))
    
        $.Item = $.part(({ WindowPlug }) => (
          <>
            <style>
              {/*css*/ `
              :host {
                --audio: #09f;
                --midi: #a80;
                --plug-width: 28px;
                display: flex;
                width: 100%;
                height: 100%;
                position: relative;
              }
              [part=plugs] {
                position: absolute;
                height: 100%;
                width: 100%;
              }
              [part=plugs] > * {
                width: var(--plug-width);
                height: 100%;
                pointer-events: none;
    
                display: flex;
                flex-flow: column nowrap;
                align-items: center;
                justify-content: center;
    
                position: absolute;
                gap: 20px;
              }
              [part=inputs] {
                left: calc(-1 * var(--plug-width));
                top: 0;
              }
              [part=outputs] {
                right: calc(-1 * var(--plug-width));
                top: 0;
              }
              [part=plug] {
                display: inline-flex;
                width: var(--plug-width);
                pointer-events: all;
                cursor: copy;
              }
              [part=inputs] [part=plug] {
              }
              [part=outputs] [part=plug] {
              }
              [data-cable-kind=audio][data-plug-kind=input]::part(plug) {
                background: var(--audio);
              }
              [data-cable-kind=audio][data-plug-kind=output]::part(plug) {
                background: var(--audio);
              }
              [data-cable-kind=midi][data-plug-kind=input]::part(plug) {
                background: var(--midi);
              }
              [data-cable-kind=midi][data-plug-kind=output]::part(plug) {
                background: var(--midi);
              }
              ${WindowPlug}::part(plug) {
                /* opacity: 0.55; */
                /* transition: opacity 78ms cubic-bezier(0, 0.35, .15, 1); */
                z-index: 1;
              }
              ${WindowPlug}::part(back) {
                background: #000;
                z-index: 0;
              }
              ${WindowPlug}:hover::part(plug) {
                /* opacity: 0.75; */
              }
              ${WindowPlug}.disabled::part(plug) {
                opacity: 0.2;
              }
              ${WindowPlug}.enabled::part(plug) {
                opacity: 0.85;
              }
              ${WindowPlug}.active::part(plug) {
                /* opacity: 1; */
              }
            `}
            </style>
    
            <Plugs />
    
            <div>hello this is a window</div>
          </>
        ))
      }
    }
    
    interface SceneElement extends $.Element<SceneElement> {}
    
    @$.element()
    class SceneElement extends HTMLElement {
      Workspace = $.element(WorkspaceElement)
      WindowItem = $.element(WindowItemElement)
      WindowPlugScene = $.element(WindowPlugSceneElement)
    
      workspace?: WorkspaceElement
      plugScene?: WindowPlugSceneElement
    
      @$.out() items = new $.RefSet<WindowItemElement>([
        { rect: new $.Rect(0, 0, 200, 200), label: 'one' },
        { rect: new $.Rect(300, 0, 200, 200), label: 'two' },
      ])
    
      mounted($: SceneElement['$']) {
        const PlugScene = $.part(({ WindowPlugScene, workspace }) => (
          <WindowPlugScene ref={$.ref.plugScene} workspace={workspace} />
        ))
    
        const PlugArrows = $.part(({ plugScene: { PlugArrows } }) => <PlugArrows />)
    
        const Items = $.part(({ WindowItem, items, plugScene }) =>
          items.map(item => <WindowItem {window-plug.item} plugScene={plugScene} />)
        )
    
        $.render(({ Workspace, WindowItem }) => (
          <>
            <style>
              {/*css*/ `
              ${Workspace} {
                position: absolute;
                display: flex;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
              }
    
              ${WindowItem} {
                box-sizing: border-box;
                background: #000;
                z-index: 1;
                /* border: 5px solid pink; */
              }
              ${WindowItem}.connect-hover {
                /* border: 5px solid purple; */
              }
            `}
            </style>
            <Workspace ref={$.ref.workspace}>
              <Items />
              <PlugArrows />
            </Workspace>
            <PlugScene />
          </>
        ))
      }
    }
    
    const Scene = $.element(SceneElement)
    
    const Classes = [
      $.Rect,
      $.RefSet,
      Cable,
      Plug,
      SceneElement,
    ]
    
    const sceneRef = new $.Ref()
    const historyItems = new Set<string>()
    const History = () => {
      return [window-plug.historyItems].map((x, i) => (
        <button
          onclick={() => {
            sceneRef.current = deserialize(x, Classes)
            render()
          }}
        >
          {i}
        </button>
      ))
    }
    
    if (localStorage.lastScene) {
      sceneRef.current = deserialize(localStorage.lastScene, Classes)
    }
    
    const render = () => {
      $.render(
        <>
          <div style="z-index: 999999; position: fixed;">
            <History />
          </div>
          <Scene
            ref={sceneRef}
            onchange={$.event.debounce(200)(() => {
              console.time('serialize')
              const serialized = serialize(sceneRef.current)
              historyItems.add(serialized)
              localStorage.lastScene = serialized
              console.log('size:', serialized.length)
              console.timeEnd('serialize')
              render()
            })}
          />
        </>,
        document.body
      )
    }
    
    render()

API

# PlugKind

    # Input

      "input"

    # Output

      "output"

# WindowPlugArrowDragType src/window-plug-arrow.tsx#L39
# Cable

    # constructor(cable)
    # id

      string

    # inputCh

      number

    # outputCh

      number

# Plug
# ondisconnect

    EventHandler<Plug<any, any>, CustomEvent<{

    # cable
    # plug

    }>>

# plugKind
# Input
# Output
# connect(this, other, cable)
# disconnect(this, cable)
# PlugArrow src/plug-arrow.ts#L6
# updatePoints() src/plug-arrow.ts#L41

    updatePoints()  =>

      void
# WindowPlugArrowElement src/window-plug-arrow.tsx#L48
# anim src/window-plug-arrow.tsx#L75

    ManualAnimation<WindowPlugArrowAnimation>

# animValues src/window-plug-arrow.tsx#L76

    WindowPlugArrowAnimation

# cableWidth  =  7.5 src/window-plug-arrow.tsx#L53

    number

# color  =  '#66a' src/window-plug-arrow.tsx#L57

    string

# context

    ContextClass<WindowPlugArrowElement & JsxContext<WindowPlugArrowElement> & Omit<{

    # ctor

      Class<T>

    <T>(ctor)  =>

      CleanClass<T>
    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>
# dispatch

    Dispatch<

    # (name, detail, init)

      # name

        Event | Narrow<K, string>

      # detail
      # init

        CustomEventInit<any>

      <K, E>(name, detail, init)  =>

        any

>
# dragType  =  WindowPlugArrowDragType.Head src/window-plug-arrow.tsx#L66
# holding  =  false src/window-plug-arrow.tsx#L63
# host
# onContextMenu src/window-plug-arrow.tsx#L70

    # (Options)

      # Options()

        Options()  =>

          VKid

(Options)  =>

    EventHandler<any, MouseEvent>
# onarrowhoverstart
# onmounted
# onunmounted
# path src/window-plug-arrow.tsx#L61

    string

# plugArrow src/window-plug-arrow.tsx#L58
# points src/window-plug-arrow.tsx#L73

    Point []

# reconnectInput src/window-plug-arrow.tsx#L80

    EventHandler<SVGCircleElement, PointerEvent | TouchEvent>

# reconnectOutput src/window-plug-arrow.tsx#L79

    EventHandler<SVGCircleElement, PointerEvent | TouchEvent>

# reconnectStart src/window-plug-arrow.tsx#L78

    # (kind)

      # kind

      (kind)  =>

        EventHandler<SVGCircleElement, PointerEvent | TouchEvent>

# rect src/window-plug-arrow.tsx#L72

    Rect

# state  =  ... src/window-plug-arrow.tsx#L52

    State<WindowPlugArrowElement, {

    # Drag  =  'arrowdrag' src/window-plug-arrow.tsx#L34

      "arrowdrag"

    # Hold  =  'arrowhold' src/window-plug-arrow.tsx#L35

      "arrowhold"

    # Hover  =  'arrowhover' src/window-plug-arrow.tsx#L36

      "arrowhover"

    # Idle  =  'arrowidle' src/window-plug-arrow.tsx#L33

      "arrowidle"

    }, "arrowidle" | "arrowdrag" | "arrowhold" | "arrowhover"> & EventMethods<WindowPlugArrowElement, {

    # arrowdragcancel

      CustomEvent<any>

    # arrowdragend

      CustomEvent<any>

    # arrowdragpause

      CustomEvent<any>

    # arrowdragresume

      CustomEvent<any>

    # arrowdragstart

      CustomEvent<any>

    # arrowholdcancel

      CustomEvent<any>

    # arrowholdend

      CustomEvent<any>

    # arrowholdpause

      CustomEvent<any>

    # arrowholdresume

      CustomEvent<any>

    # arrowholdstart

      CustomEvent<any>

    # arrowhovercancel

      CustomEvent<any>

    # arrowhoverend

      CustomEvent<any>

    # arrowhoverpause

      CustomEvent<any>

    # arrowhoverresume

      CustomEvent<any>

    # arrowhoverstart

      CustomEvent<any>

    # arrowidlecancel

      CustomEvent<any>

    # arrowidleend

      CustomEvent<any>

    # arrowidlepause

      CustomEvent<any>

    # arrowidleresume

      CustomEvent<any>

    # arrowidlestart

      CustomEvent<any>

    }> & InlineEventMap<WindowPlugArrowElement, {

    # arrowdragcancel

      CustomEvent<any>

    # arrowdragend

      CustomEvent<any>

    # arrowdragpause

      CustomEvent<any>

    # arrowdragresume

      CustomEvent<any>

    # arrowdragstart

      CustomEvent<any>

    # arrowholdcancel

      CustomEvent<any>

    # arrowholdend

      CustomEvent<any>

    # arrowholdpause

      CustomEvent<any>

    # arrowholdresume

      CustomEvent<any>

    # arrowholdstart

      CustomEvent<any>

    # arrowhovercancel

      CustomEvent<any>

    # arrowhoverend

      CustomEvent<any>

    # arrowhoverpause

      CustomEvent<any>

    # arrowhoverresume

      CustomEvent<any>

    # arrowhoverstart

      CustomEvent<any>

    # arrowidlecancel

      CustomEvent<any>

    # arrowidleend

      CustomEvent<any>

    # arrowidlepause

      CustomEvent<any>

    # arrowidleresume

      CustomEvent<any>

    # arrowidlestart

      CustomEvent<any>

    }>
# targetState  =  WindowPlugArrowState.Idle src/window-plug-arrow.tsx#L55
# viewFrameNormalRect src/window-plug-arrow.tsx#L68

    Rect

# workspace src/window-plug-arrow.tsx#L59

    WorkspaceElement

# zIndex  =  0 src/window-plug-arrow.tsx#L64

    number

# created(ctx)

    # ctx

    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>

created(ctx)  =>

    void
# mounted($) src/window-plug-arrow.tsx#L82

    # $

    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>

mounted($)  =>

    void
# on(name)
# toJSON()
# WindowPlugElement src/window-plug.tsx#L23

    # constructor(args)
    # $

    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>
# __#2@#offsetHeight

    number

# __#2@#offsetLeft

    number

# __#2@#offsetTop

    number

# __#2@#offsetWidth

    number

# connectStart src/window-plug.tsx#L35
# context

    ContextClass<WindowPlugElement & JsxContext<WindowPlugElement> & Omit<{

    # ctor

      Class<T>

    <T>(ctor)  =>

      CleanClass<T>
    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>
# count  =  1 src/window-plug.tsx#L33

    number

# dest src/window-plug.tsx#L30

    ChildOf<WorkspaceWindowElement>

# dispatch

    Dispatch<

    # (name, detail, init)

      # name

        Event | Narrow<K, string>

      # detail
      # init

        CustomEventInit<any>

      <K, E>(name, detail, init)  =>

        any

>
# host
# onconnectingend
# onconnectingmove
# onconnectingstart
# onmounted
# onstatechange
# onunmounted
# ownRect

    Rect

# plug src/window-plug.tsx#L28
# pos

    Point

# rect

    Rect

# resize src/window-plug.tsx#L34

    # ()

      ()  =>

        void

# scene src/window-plug.tsx#L31
# size

    Point

# state  =  ... src/window-plug.tsx#L27
# __#2@#updateOffsets()

    __#2@#updateOffsets()  =>

      void
# created(ctx)

    # ctx

    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>

created(ctx)  =>

    void
# mounted($) src/window-plug.tsx#L37

    # $

    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>

mounted($)  =>

    void
# on(name)
# toJSON()
# WindowPlugSceneElement src/window-plug-scene.tsx#L26
# PlugArrows  =  ... src/window-plug-scene.tsx#L33

    # ()

      ()  =>

        VKid

# WindowPlugArrow  =  ... src/window-plug-scene.tsx#L32
# addPlug src/window-plug-scene.tsx#L49
# arrows  =  ... src/window-plug-scene.tsx#L44
# context

    ContextClass<WindowPlugSceneElement & JsxContext<WindowPlugSceneElement> & Omit<{

    # ctor

      Class<T>

    <T>(ctor)  =>

      CleanClass<T>
    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>
# destRects src/window-plug-scene.tsx#L42

    Rect []

# dispatch

    Dispatch<

    # (name, detail, init)

      # name

        Event | Narrow<K, string>

      # detail
      # init

        CustomEventInit<any>

      <K, E>(name, detail, init)  =>

        any

>
# draggingWindow  =  false src/window-plug-scene.tsx#L37

    false | WorkspaceWindowElement

# enabled  =  [] src/window-plug-scene.tsx#L55
# endConnecting src/window-plug-scene.tsx#L53
# endPointerMove src/window-plug-scene.tsx#L54

    # ()

      ()  =>

        void

# holding  =  false src/window-plug-scene.tsx#L57
# host
# hovering  =  null src/window-plug-scene.tsx#L56
# onhover
# onmounted
# onunmounted
# options  =  ... src/window-plug-scene.tsx#L40
# plugs  =  ... src/window-plug-scene.tsx#L45
# plugsMap  =  ... src/window-plug-scene.tsx#L46
# removePlug src/window-plug-scene.tsx#L50
# root  =  ... src/window-plug-scene.tsx#L30
# solve src/window-plug-scene.tsx#L48

    # ()

      ()  =>

        Promise<void>

# startConnecting src/window-plug-scene.tsx#L52
# surface src/window-plug-scene.tsx#L36

    SurfaceElement

# viewRect src/window-plug-scene.tsx#L41

    Rect

# worker  =  ... src/window-plug-scene.tsx#L39

    Agent<WindowPlugWorker, WindowPlugCore>

# workspace src/window-plug-scene.tsx#L35

    WorkspaceElement

# created(ctx)

    # ctx

    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>

created(ctx)  =>

    void
# mounted($) src/window-plug-scene.tsx#L59

    # $

    # ctx

      T | Class<T>

    <T>(ctx)  =>

      Wrapper<T>
    } & __module & {

    # Boolean

      undefined | boolean

    # Number

      undefined | number

    # String

      undefined | string

    }, "transition">>

mounted($)  =>

    void
# on(name)
# toJSON()
# WindowPlugSolveData src/types.ts#L10
# WindowPlugSolveOptions src/types.ts#L3
# WindowPlugArrowEvents src/window-plug-arrow.tsx#L44
}
# WindowPlugEvents src/window-plug.tsx#L11
# WindowPlugSceneEvents src/window-plug-scene.tsx#L22
# WindowPlugArrowState  =  ... src/window-plug-arrow.tsx#L32
# WindowPlugState  =  ... src/window-plug.tsx#L18

Credits

Contributing

Fork or edit and submit a PR.

All contributions are welcome!

License

MIT © 2022 stagas

Readme

Keywords

none

Package Sidebar

Install

npm i window-plug

Weekly Downloads

24

Version

1.1.0

License

MIT

Unpacked Size

2.62 MB

Total Files

53

Last publish

Collaborators

  • stagas