protected function renderNode($node)
    {
        if (is_string($node)) {
            $node = ['name' => $node];
        }
        if (!isset($node['name'])) {
            throw new InvalidConfigException("The 'name' option is required.");
        }

        $lines = [];

        $nodeOptions = array_merge([
            'data-node-id' => $node['id'],
            'data-node-name' => Html::encode($node['name']),
            'data-action-name' => 'move',   ///[node move action]
            'data-action-url' => Url::to(ArrayHelper::getValue($node, 'move-url', $this->createUrl('move', $node))),
            // more node data ...
        ], $this->nodeOptions, ArrayHelper::getValue($node, 'options', []));
        $tag = ArrayHelper::remove($nodeOptions, 'tag', 'li');

        $lines[] = Html::beginTag($tag, $nodeOptions);

        $lines[] = Html::beginTag('div');

        $lines[] = $this->renderNodeName($node);
        $lines[] = $this->renderNodeActions($node);

        $lines[] = Html::endTag('div');

        if (!empty($node['nodes'])) {
            $lines[] =  $this->renderNodes($node['nodes']);
        }

        $lines[] =  Html::endTag($tag);

        return implode("\n", $lines);
    }