New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@wix/react-velo

Package Overview
Dependencies
Maintainers
18
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@wix/react-velo

Add the ability to use native React APIs (components and hooks) to Velo, by creating a React structure which corresponds to dynamic elements in the editor. React Velo supports React native APIs (`ref` supports only ref callback syntax and has a slightly d

latest
Source
npmnpm
Version
1.0.51
Version published
Maintainers
18
Created
Source

React Velo

Add the ability to use native React APIs (components and hooks) to Velo, by creating a React structure which corresponds to dynamic elements in the editor. React Velo supports React native APIs (ref supports only ref callback syntax and has a slightly different API),

Installation

This module is aimed to be used in Wix Velo environment.

  • Open a Wix Site
  • Enable Dev Mode
  • Add @wix/react-velo npm module
  • Add react npm module

velo-sources-panel.png

Usage Example

Given a site with the following elements (and their Velo IDs), simple-example.png

A Velo User can control these elements the behavior, style and content using the following React Velo code

import React, { useState } from 'react';
import { render, W } from '@wix/react-velo';

function App() {
  const [background, setBackground] = useState('green');
  return (
    <W.myContainer style={{backgroundColor: background}}>
      <W.title text={'Click to change background'} />
      <W.okButton onClick={() => setBackground('red')} />
    </W.myContainer>
  );
}

$w.onReady(() => render(App, $w, React));

API

Module Exports

MemberTypeDescription
renderMethodThe method which initiates the link between the editor elements and the react component which represents their behavior.
It should be invoked in $w.onReady method
WObjectAn object representing the Wix Editor/ Editor X elements such that W.<id> is a React representation of the Editor element in this page. The returned component's props are identical to the Velo representation of the Element returned by using $w(<id>).
For exact props and usages, see Wix Editor Elements ($w) API

Render method

render(Component, $w, React, callback?)

MemberTypeDescription
ComponentMethodThe React component root
$w$wThe Wix query element provided in a page API
ReactReact InstanceThe React instance used in this page, in order to assure that react-velo is using the same React version as the hosting page
callback() => void(Optional) A callback to be passed to the react-velo react-reconsiler implementation, see React Reconsiler documentation for more details

Repeaters

A Repeater is a special Wix Editor Element which is responsible to generate a list of elements from either a data-set (dynamic) or an array set by Velo code). In order to provide a React component API, React Velo creates a specialized react component which allows controlling the rendering of each item using a renderItem prop, as seen in the following example:

Given A following page with a repeater repeater-example.png

Its React implementation can be controlled using the following code

import React, { useState } from 'react';
import { render, W } from '@wix/react-velo';

function App() {
  const [todos, setTodos] = useState([{
    _id: '1',
    description: 'Item 1',
    status: 'In Progress',
  }, {
    _id: '2',
    description: 'Item 2',
    status: 'Done',
  }]);
  // Actions to control the list can be added
  return <W.TodoList data={todos} renderItem={({ description, status }) => 
    (
      <>
        <W.Description text={description}/>
        <W.Status text={status}/>
      </>
    )
  }/>;
}

$w.onReady(() => render(App, $w, React));
Repeater Component API
propTypeDescription
dataArrayThe data to be used by the repeater, similar to $w('#TodoList').data
renderItem(itemData) => voidThe representation of each item, similarly to $w('#TodoList').onItemReady
Native Elements access

A velo user can access "native" velo components (i.e. the object you get from $w('#someid')) using react's ref mechanism. For example, if you want to use some Text's scrollTo() method, we can do something like that:

let textRef;
const setTextRef = (element) => {
    textRef = element;
};
// ...
<W.MyButton onClick={() => {
    if (textRef) {
        console.log('Scrolling...'); 
        textRef.scrollTo();
    }
}} />
<W.text3 text={`Selected: ${selectedColorName}`} ref={setTextRef} />
Animation

Animation can be achivied using wix-animation as usual, simply by getting the element's native reference and creating a proper animation timeline.

import React from 'react'; // import react for JSX transpilation
import { W, render } from '@wix/react-velo'; // import this library
import wixAnimations from 'wix-animations'; // animations library

const timeline = wixAnimations.timeline();
function App() {
  const effect = {scale: 2, duration: 200, "rotate": 360};
  let refSet = false;
  const setRef = (element) => {
    if (!refSet && element) {
      refSet = true;
      timeline.add(element, effect);
    }
  };

  return (
    <W.MyButton
      ref={setRef} 
      onMouseIn={() => timeline.play()}
      onMouseOut={() => timeline.reverse()}
    />
  );
}

$w.onReady(() => render(App, $w, React));

Sometimes a velo user would like to compose multiple elements to a single timeline animation, Here is an example of how it can be achieved:

// A helper function to collect the native element refs
function createAnimation(animationOptionsArray) {
  const timeline = wixAnimations.timeline();
  let refsSetCounter = 0;
  const refsArray = animationOptionsArray.map(() => null);

  const applyAnimationSettings = () => {
    if (refsSetCounter < animationOptionsArray.length) {
      return;
    }

    animationOptionsArray.forEach((animationOptions, idx) => {
      timeline.add(refsArray[idx], animationOptions);
    });
  };
  
  return {
    timeline,
    setRefs: animationOptionsArray.map((_, idx) => (el) => {
      if (!refsArray[idx] && el) {
        refsSetCounter++;
        refsArray[idx] = el;
        applyAnimationSettings();
      }
    })
  };
}
// ...
// Usage:
const animation = createAnimation([
  {scale: 0.8, duration: 200},
  {opacity: 1, duration: 100},
  {opacity: 0, duration: 10},
]);
const onMouseIn = () => animation.timeline.play();
const onMouseOut = () => animation.timeline.reverse();
/// ...
return (
  <W.container1 onClick={onClick}>
    <W.mainColor
      ref={animation.setRefs[0]} 
      style={{backgroundColor: props.color}} 
      onMouseIn={onMouseIn} 
      onMouseOut={onMouseOut}>
    </W.mainColor>
    <W.blackBorder ref={animation.setRefs[1]} />
    <W.emptyBorder ref={animation.setRefs[2]} />
  </W.container1>
);
Widget interaction (Blocks)

You can use $widget.props and $widget.onPropsChanged(...) to get props for your widget, like so:

// Your component
function App() {
  const [items, setItems] = useState($widget.props.items);
  useEffect(() => {
    $widget.onPropsChanged((_, newProps) => {
      setItems(newProps.items);
     });
  }, []); // we want to subscribe to props changed only once
}

or create a HoC that will abstract that away, for example like that:

import React from 'react';
import { render } from '@wix/react-velo';

const withWidgetProps = (ReactInstance, Component) => {
 const [props, setProps] = ReactInstance.useState($widget.props);
 ReactInstance.useEffect(
  () => $widget.onPropsChanged((_, newProps) => setProps({ ...newProps })),
  []
 );

 return <Component {...props} />;
};

// ... and later:
$w.onReady(() => render(withWidgetProps(React, App), $w, React));

FAQs

Package last updated on 22 Mar 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts