posthtml-component 1.0.0-beta.10 → 1.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posthtml-component",
3
- "version": "1.0.0-beta.10",
3
+ "version": "1.0.0-beta.11",
4
4
  "description": "PostHTML Components Blade-like with slots, attributes as props and custom tag",
5
5
  "license": "MIT",
6
6
  "repository": "thewebartisan7/posthtml-components",
@@ -13,7 +13,7 @@
13
13
  "version": "conventional-changelog -i changelog.md -s -r 0 && git add changelog.md",
14
14
  "test": "c8 ava",
15
15
  "pretest": "clinton && xo",
16
- "build-examples": "node ./examples"
16
+ "build": "node ./docs-src"
17
17
  },
18
18
  "keywords": [
19
19
  "posthtml",
package/readme.md CHANGED
@@ -17,7 +17,7 @@ npm i -D posthtml-component
17
17
  ## Introduction
18
18
 
19
19
  This PostHTML plugin provides an HTML-friendly syntax for write components in your templates.
20
- If you are familiar with Blade, you will find similar syntax as this plugin was inspired by it.
20
+ If you are familiar with Blade, you will find similar syntax as this plugin is inspired by it.
21
21
  See below a basic example, as code is worth a thousand words.
22
22
 
23
23
  > This plugin is still in early stage of development and the current API may change.
@@ -69,13 +69,11 @@ Result:
69
69
  </html>
70
70
  ```
71
71
 
72
- You may ask yourself many questions about this basic examples, and you will find most if not all answers in this readme. In case is missing something, feel free to ask via discussions.
72
+ You may notice that our `src/button.html` component has a `type` and `class` attribute, and when we use the component in `src/index.html` we add type and class attribute.
73
+ The result is that `type` is override, and `class` is merged.
73
74
 
74
- But I want to explain a few things now.
75
-
76
- First you may notice that our `src/button.html` component has a `type` and `class` attribute, and when we use the component in `src/index.html` we add type and class attribute. The result is that `type` is override, and `class` is merged.
77
-
78
- By default `class` and `style` attributes are merged, while all others attribute are override. You can also override class and style attribute by prepending `override:` to the class attribute. Example:
75
+ By default `class` and `style` attributes are merged, while all others attribute are override.
76
+ You can also override class and style attribute by prepending `override:` to the class attribute. Example:
79
77
 
80
78
  ```html
81
79
  <x-button override:class="btn-custom">Submit</x-button>
@@ -84,41 +82,43 @@ By default `class` and `style` attributes are merged, while all others attribute
84
82
  <button type="button" class="btn-custom">Submit</button>
85
83
  ```
86
84
 
87
- All attributes you pass to the component will be added to the first root element of your component, and only if they are not defined as `props` via `<script props>`. More details on this later.
88
-
89
- Second you may notice a `<yield>` tag.
90
-
91
- This is where your content will be injected.
85
+ All attributes you pass to the component will be added to the first node of your component or to the node with an attribute names `attributes`,
86
+ and only if they are not defined as `props` via `<script props>`. More details on this in [Attributes](#attributes) section.
92
87
 
93
- In next section you can find all available options and then more examples.
88
+ The `<yield>` tag is where your content will be injected.
89
+ In next section you can find all available options and then examples for each features.
94
90
 
95
- See also the `examples` folder. You can run `npm run build-examples` to compile them.
91
+ See also the `docs-src` folder where you can find more examples. You can run `npm run build` to compile them.
96
92
 
97
93
  ## Options
98
94
 
99
- | Option | Default | Description |
100
- |:----------------------:|:----------------------------:|:--------------------------------------------------------------------------------------------------------------------------------|
101
- | **root** | `'./'` | String value as root path for components lookup. |
102
- | **folders** | `['']` | Array of additional multi folders path from `options.root` or any defined namespaces root, fallback or custom. |
103
- | **tagPrefix** | `x-` | String for tag prefix. The plugin will use RegExp with this string. |
104
- | **tag** | `false` | String or boolean value for component tag. Use this with `options.attribute`. Boolean only false. |
105
- | **attribute** | `src` | String value for component attribute for set path. |
106
- | **namespaces** | `[]` | Array of namespace's root path, fallback path and custom path for override. |
107
- | **namespaceSeparator** | `::` | String value for namespace separator to be used with tag name. Example `<x-namespace::button>` |
108
- | **fileExtension** | `html` | String value for file extension of the components used for retrieve x-tag file. |
109
- | **yield** | `yield` | String value for `<yield>` tag name. Where main content of component is injected. |
110
- | **slot** | `slot` | String value for `<slot>` tag name. Used with RegExp by appending `:` (example `<slot:slot-name>`). |
111
- | **fill** | `fill` | String value for `<fill>` tag name. Used with RegExp by appending `:` (example `<fill:slot-name>`). |
112
- | **slotSeparator** | `:` | String value used for separate `<slot>` and `<fill>` tag from their names. |
113
- | **push** | `push` | String value for `<push>` tag name. |
114
- | **stack** | `stack` | String value for `<stack>` tag name. |
115
- | **localsAttr** | `props` | String value used in `<script props>` parsed by the plugin to retrieve locals in the components. |
116
- | **expressions** | `{}` | Object to configure `posthtml-expressions`. You can pre-set locals or customize the delimiters for example. |
117
- | **plugins** | `[]` | PostHTML plugins to apply for every parsed components. |
118
- | **matcher** | `[{tag: options.tagPrefix}]` | Array of object used to match the tags. |
119
- | **attrsParserRules** | `{}` | Additional rules for attributes parser plugin. |
120
- | **strict** | `true` | Boolean value for enable or disable throw an exception. |
121
- | **mergeCustomizer** | `function` | Function callback passed to lodash `mergeWith` for merge `options.expressions.locals` and locals passed via attribute `locals`. |
95
+ | Option | Default | Description |
96
+ |:------------------------:|:--------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------|
97
+ | **root** | `'./'` | String value as root path for components lookup. |
98
+ | **folders** | `['']` | Array of additional multi folders path from `options.root` or any defined namespaces root, fallback or custom. |
99
+ | **tagPrefix** | `x-` | String for tag prefix. The plugin will use RegExp with this string. |
100
+ | **tag** | `false` | String or boolean value for component tag. Use this with `options.attribute`. Boolean only false. |
101
+ | **attribute** | `src` | String value for component attribute for set path. |
102
+ | **namespaces** | `[]` | Array of namespace's root path, fallback path and custom path for override. |
103
+ | **namespaceSeparator** | `::` | String value for namespace separator to be used with tag name. Example `<x-namespace::button>` |
104
+ | **fileExtension** | `html` | String value for file extension of the components used for retrieve x-tag file. |
105
+ | **yield** | `yield` | String value for `<yield>` tag name. Where main content of component is injected. |
106
+ | **slot** | `slot` | String value for `<slot>` tag name. Used with RegExp by appending `:` (example `<slot:slot-name>`). |
107
+ | **fill** | `fill` | String value for `<fill>` tag name. Used with RegExp by appending `:` (example `<fill:slot-name>`). |
108
+ | **slotSeparator** | `:` | String value used for separate `<slot>` and `<fill>` tag from their names. |
109
+ | **push** | `push` | String value for `<push>` tag name. |
110
+ | **stack** | `stack` | String value for `<stack>` tag name. |
111
+ | **propsScriptAttribute** | `props` | String value used as attribute in `<script props>` parsed by the plugin to retrieve props of the component. |
112
+ | **propsContext** | `props` | String value used as object name inside the script to process process before passed to the component. |
113
+ | **propsAttribute** | `props` | String value for props attribute to define props as JSON. |
114
+ | **propsSlot** | `props` | String value used to retrieve the props passed to slot via `$slots.slotName.props`. |
115
+ | **expressions** | `{}` | Object to configure `posthtml-expressions`. You can pre-set locals or customize the delimiters for example. |
116
+ | **plugins** | `[]` | PostHTML plugins to apply for every parsed components. |
117
+ | **matcher** | `[{tag: options.tagPrefix}]` | Array of object used to match the tags. |
118
+ | **attrsParserRules** | `{}` | Additional rules for attributes parser plugin. |
119
+ | **strict** | `true` | Boolean value for enable or disable throw an exception. |
120
+ | **mergeCustomizer** | `function` | Function callback passed to lodash `mergeWith` for merge `options.expressions.locals` and props passed via attribute `props`. |
121
+ | **utilities** | `{merge: _.mergeWith, template: _.template}` | Object of utilities methods to be passed to `<script props>`. By default lodash `mergeWith` and `template`. |
122
122
 
123
123
  ## Features
124
124
 
@@ -515,7 +515,7 @@ Create the component:
515
515
  <!-- src/my-component.html -->
516
516
  <script props>
517
517
  module.exports = {
518
- prop: locals.prop || 'Default prop value'
518
+ prop: props.prop || 'Default prop value'
519
519
  }
520
520
  </script>
521
521
  <div>
@@ -556,7 +556,7 @@ The output will be:
556
556
  If you don't add the props in `<script props>` inside your component, all props will be added as attributes to the first node of your component or to the node with attribute `attributes`.
557
557
  More details on this in the next section.
558
558
 
559
- So in the `<script props>` you have access to passed props via object `locals`, and you can add any logic you need inside of it.
559
+ So in the `<script props>` you have access to passed props via object `props`, and you can add any logic you need inside it.
560
560
 
561
561
  Create the component:
562
562
 
@@ -564,9 +564,9 @@ Create the component:
564
564
  <!-- src/modal.html -->
565
565
  <script props>
566
566
  module.exports = {
567
- title: locals.title || 'Default title',
568
- size: locals.size ? `modal-${locals.size}` : '',
569
- items: Array.isArray(locals.items) ? locals.items.concat(['first', 'second']) : ['first', 'second']
567
+ title: props.title || 'Default title',
568
+ size: props.size ? `modal-${props.size}` : '',
569
+ items: Array.isArray(props.items) ? props.items.concat(['first', 'second']) : ['first', 'second']
570
570
  }
571
571
  </script>
572
572
  <div class="modal {{ size }}">
@@ -603,7 +603,7 @@ The output will be:
603
603
 
604
604
  You can also notice how the `class` attribute is merged with `class` attribute of the first node. Let's see in next section more about this.
605
605
 
606
- You can change how attributes are merged with global locals defined via options by passing a callback function used by lodash method [mergeWith](https://lodash.com/docs/4.17.15#mergeWith).
606
+ You can change how attributes are merged with global props defined via options by passing a callback function used by lodash method [mergeWith](https://lodash.com/docs/4.17.15#mergeWith).
607
607
 
608
608
  By default, all props are scoped to the component, and are not available to nested components. You can however change this accordingly to your need.
609
609
  Let's see below example.
@@ -614,7 +614,7 @@ Create a component:
614
614
  <!-- src/child.html -->
615
615
  <script props>
616
616
  module.exports = {
617
- prop: locals.prop || 'Default prop value'
617
+ prop: props.prop || 'Default prop value'
618
618
  }
619
619
  </script>
620
620
  <div>
@@ -629,7 +629,7 @@ Create another component that use the first one:
629
629
  <!-- src/parent.html -->
630
630
  <script props>
631
631
  module.exports = {
632
- prop: locals.prop || 'Default prop value'
632
+ prop: props.prop || 'Default prop value'
633
633
  }
634
634
  </script>
635
635
  <div>
@@ -686,7 +686,7 @@ As already seen in basic example:
686
686
  <!-- src/button.html -->
687
687
  <script props>
688
688
  module.exports = {
689
- label: locals.label || 'A button'
689
+ label: props.label || 'A button'
690
690
  }
691
691
  </script>
692
692
  <button type="button" class="btn">
@@ -760,7 +760,7 @@ You can add custom rules how attributes are parsed, as behind the scene it's use
760
760
  ## Examples
761
761
 
762
762
  You can work with `<slot>` and `<fill>` or you can create component for each "block" of your component, and you can also support both of them.
763
- You can find an example of this inside `examples/components/modal`. Below is a short explanation about the both approach.
763
+ You can find an example of this inside `docs-src/components/modal`. Below is a short explanation about the both approach.
764
764
 
765
765
  ### Using slots
766
766
 
@@ -919,7 +919,7 @@ You can also combine both way, and then use them with slots or with small compon
919
919
  </x-modal.body>
920
920
  </if>
921
921
  <if condition="$slots.footer?.filled">
922
- <x-modal.footer close="{{ $slots.footer?.locals.close }}">
922
+ <x-modal.footer close="{{ $slots.footer?.props.close }}">
923
923
  <slot:footer></slot:footer>
924
924
  </x-modal.footer>
925
925
  </if>
package/src/index.js CHANGED
@@ -6,10 +6,12 @@ const {parser} = require('posthtml-parser');
6
6
  const {match} = require('posthtml/lib/api');
7
7
  const expressions = require('posthtml-expressions');
8
8
  const findPathFromTag = require('./find-path');
9
- const processLocals = require('./locals');
10
- const processAttributes = require('./attributes');
11
- const {processPushes, processStacks} = require('./stacks');
12
- const {setFilledSlots, processSlotContent, processFillContent} = require('./slots');
9
+ const processProps = require('./process-props');
10
+ const processAttributes = require('./process-attributes');
11
+ const {processPushes, processStacks} = require('./process-stacks');
12
+ const {setFilledSlots, processSlotContent, processFillContent} = require('./process-slots');
13
+ const mergeWith = require('lodash/mergeWith');
14
+ const template = require('lodash/template');
13
15
 
14
16
  // const {inspect} = require('util');
15
17
  // const debug = true;
@@ -35,14 +37,18 @@ module.exports = (options = {}) => tree => {
35
37
  options.slotSeparator = options.slotSeparator || ':';
36
38
  options.push = options.push || 'push';
37
39
  options.stack = options.stack || 'stack';
38
- options.localsAttr = options.localsAttr || 'props';
40
+ options.propsScriptAttribute = options.propsScriptAttribute || 'props';
41
+ options.propsContext = options.propsContext || 'props';
42
+ options.propsAttribute = options.propsAttribute || 'props';
43
+ options.propsSlot = options.propsSlot || 'props';
39
44
  options.expressions = options.expressions || {};
40
45
  options.plugins = options.plugins || [];
41
46
  options.attrsParserRules = options.attrsParserRules || {};
42
47
  options.strict = typeof options.strict === 'undefined' ? true : options.strict;
48
+ options.utilities = options.utilities || {merge: mergeWith, template};
43
49
 
44
50
  // Merge customizer callback passed to lodash mergeWith
45
- // for merge attribute `locals` and all attributes starting with `merge:`
51
+ // for merge attribute `props` and all attributes starting with `merge:`
46
52
  // @see https://lodash.com/docs/4.17.15#mergeWith
47
53
  options.mergeCustomizer = options.mergeCustomizer || ((objectValue, sourceValue) => {
48
54
  if (Array.isArray(objectValue)) {
@@ -86,7 +92,7 @@ module.exports = (options = {}) => tree => {
86
92
  }
87
93
  });
88
94
 
89
- options.locals = {...options.expressions.locals};
95
+ options.props = {...options.expressions.locals};
90
96
  options.aware = {};
91
97
 
92
98
  const pushedContent = {};
@@ -140,10 +146,10 @@ function processTree(options) {
140
146
  setFilledSlots(currentNode, filledSlots, options);
141
147
  // setFilledSlots(nextNode, filledSlots, options);
142
148
 
143
- // Reset previous locals with passed global and keep aware locals
144
- options.expressions.locals = {...options.locals, ...options.aware};
149
+ // Reset options.expressions.locals and keep aware locals
150
+ options.expressions.locals = {...options.props, ...options.aware};
145
151
 
146
- const {attributes, locals} = processLocals(currentNode, nextNode, filledSlots, options);
152
+ const {attributes, props} = processProps(currentNode, nextNode, filledSlots, options, componentPath);
147
153
 
148
154
  options.expressions.locals = attributes;
149
155
  options.expressions.locals.$slots = filledSlots;
@@ -172,11 +178,11 @@ function processTree(options) {
172
178
  currentNode.tag = false;
173
179
  currentNode.content = content;
174
180
 
175
- processAttributes(currentNode, attributes, locals, options);
181
+ processAttributes(currentNode, attributes, props, options);
176
182
 
177
183
  // log(currentNode, 'currentNode', 'currentNode')
178
184
  // currentNode.attrs.counter = processCounter;
179
- // currentNode.attrs.data = JSON.stringify({ attributes, locals });
185
+ // currentNode.attrs.data = JSON.stringify({ attributes, props });
180
186
 
181
187
  // messages.push({
182
188
  // type: 'dependency',
@@ -11,15 +11,15 @@ const has = require('lodash/has');
11
11
  const extend = require('lodash/extend');
12
12
 
13
13
  /**
14
- * Map component attributes that it's not defined as locals to first element of node
14
+ * Map component attributes that it's not defined as props to first element of node
15
15
  *
16
16
  * @param {Object} currentNode
17
17
  * @param {Object} attributes
18
- * @param {Object} locals
18
+ * @param {Object} props
19
19
  * @param {Object} options
20
20
  * @return {void}
21
21
  */
22
- module.exports = (currentNode, attributes, locals, options) => {
22
+ module.exports = (currentNode, attributes, props, options) => {
23
23
  let mainNode;
24
24
  match.call(currentNode, {attrs: {attributes: ''}}, node => {
25
25
  delete node.attrs.attributes;
@@ -40,7 +40,7 @@ module.exports = (currentNode, attributes, locals, options) => {
40
40
 
41
41
  const nodeAttrs = parseAttrs(mainNode.attrs, options.attrsParserRules);
42
42
 
43
- const mainNodeAttributes = omit(attributes, union(keys(locals), [options.attribute], keys(options.aware), keys(options.locals), ['$slots']));
43
+ const mainNodeAttributes = omit(attributes, union(keys(props), [options.attribute], keys(options.aware), keys(options.props), ['$slots']));
44
44
 
45
45
  each(mainNodeAttributes, (value, key) => {
46
46
  if (['class', 'style'].includes(key)) {
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const scriptDataLocals = require('posthtml-expressions/lib/locals');
3
+ const processScript = require('./process-script');
4
4
  const pick = require('lodash/pick');
5
5
  const each = require('lodash/each');
6
6
  const assign = require('lodash/assign');
@@ -9,15 +9,16 @@ const mergeWith = require('lodash/mergeWith');
9
9
  const attributeTypes = ['aware', 'merge'];
10
10
 
11
11
  /**
12
- * Parse locals from attributes, globals and via script
12
+ * Parse props from attributes, globals and via script
13
13
  *
14
14
  * @param {Object} currentNode - PostHTML tree
15
15
  * @param {Array} nextNode - PostHTML tree
16
- * @param {Object} filledSlots - Slot locals
16
+ * @param {Object} filledSlots - Filled slots
17
17
  * @param {Object} options - Plugin options
18
- * @return {Object} - Attribute locals and script locals
18
+ * @param {string} componentPath - Component path
19
+ * @return {Object} - Attribute props and script props
19
20
  */
20
- module.exports = (currentNode, nextNode, filledSlots, options) => {
21
+ module.exports = (currentNode, nextNode, filledSlots, options, componentPath) => {
21
22
  let attributes = {...currentNode.attrs};
22
23
 
23
24
  const attributesByTypeName = {};
@@ -47,26 +48,26 @@ module.exports = (currentNode, nextNode, filledSlots, options) => {
47
48
  } catch {}
48
49
  });
49
50
 
50
- // Merge or extend attribute locals
51
- if (attributes.locals) {
52
- if (attributesByTypeName.merge.includes('locals')) {
53
- attributesByTypeName.merge.splice(attributesByTypeName.merge.indexOf('locals'), 1);
54
- mergeWith(attributes, attributes.locals, options.mergeCustomizer);
51
+ // Merge or extend attribute props
52
+ if (attributes[options.propsAttribute]) {
53
+ if (attributesByTypeName.merge.includes(options.propsAttribute)) {
54
+ attributesByTypeName.merge.splice(attributesByTypeName.merge.indexOf(options.propsAttribute), 1);
55
+ mergeWith(attributes, attributes[options.propsAttribute], options.mergeCustomizer);
55
56
  } else {
56
- assign(attributes, attributes.locals);
57
+ assign(attributes, attributes[options.propsAttribute]);
57
58
  }
58
59
 
59
- delete attributes.locals;
60
+ delete attributes[options.propsAttribute];
60
61
  }
61
62
 
62
63
  // Merge with global
63
64
  attributes = mergeWith({}, options.expressions.locals, attributes, options.mergeCustomizer);
64
65
 
65
- // Retrieve default locals from <script props> for merge with attributes
66
- const {locals} = scriptDataLocals(nextNode, {localsAttr: options.localsAttr, removeScriptLocals: true, locals: {...attributes, $slots: filledSlots}});
66
+ // Process props from <script props>
67
+ const {props} = processScript(nextNode, {props: {...attributes}, $slots: filledSlots, propsScriptAttribute: options.propsScriptAttribute, propsContext: options.propsContext, utilities: options.utilities}, componentPath.replace(`.${options.fileExtension}`, '.js'));
67
68
 
68
- if (locals) {
69
- assign(attributes, locals);
69
+ if (props) {
70
+ assign(attributes, props);
70
71
  // if (attributesByTypeName.merge.length > 0) {
71
72
  // assign(attributes, mergeWith(pick(locals, attributesByTypeName.merge), pick(attributes, attributesByTypeName.merge), options.mergeCustomizer));
72
73
  // }
@@ -77,5 +78,5 @@ module.exports = (currentNode, nextNode, filledSlots, options) => {
77
78
  options.aware = pick(attributes, attributesByTypeName.aware);
78
79
  }
79
80
 
80
- return {attributes, locals};
81
+ return {attributes, props};
81
82
  };
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ const vm = require('vm');
4
+ const {existsSync, readFileSync} = require('fs');
5
+ const {render} = require('posthtml-render');
6
+ const {match} = require('posthtml/lib/api');
7
+
8
+ const ctx = vm.createContext({module, require});
9
+
10
+ /**
11
+ * Get the script tag with props from a node list and return process props.
12
+ * Custom posthtml-expressions/lib/locals.
13
+ *
14
+ * @param {Array} tree Nodes
15
+ * @param {Object} options Options
16
+ * @param {string} scriptPath - Component path
17
+ * @return {Object} {} Locals
18
+ */
19
+ module.exports = (tree, options, scriptPath) => {
20
+ const props = {};
21
+ const propsContext = options.props;
22
+ const utilities = {...options.utilities};
23
+ const context = {...utilities, ...ctx, [options.propsContext]: propsContext, $slots: options.$slots};
24
+
25
+ const runInContext = code => {
26
+ try {
27
+ const parsedContext = vm.createContext(context);
28
+ const parsedProps = vm.runInContext(code, parsedContext);
29
+
30
+ Object.assign(props, parsedProps);
31
+ } catch {}
32
+ };
33
+
34
+ if (existsSync(scriptPath)) {
35
+ runInContext(readFileSync(scriptPath, 'utf8'));
36
+ }
37
+
38
+ match.call(tree, {tag: 'script', attrs: {[options.propsScriptAttribute]: ''}}, node => {
39
+ if (node.content) {
40
+ runInContext(render(node.content));
41
+ }
42
+
43
+ return '';
44
+ });
45
+
46
+ return {
47
+ props
48
+ };
49
+ };
@@ -14,7 +14,7 @@ const omit = require('lodash/omit');
14
14
  * @param {String} slotSeparator Slot separator
15
15
  * @return {void}
16
16
  */
17
- function setFilledSlots(currentNode, filledSlots, {fill, slotSeparator}) {
17
+ function setFilledSlots(currentNode, filledSlots, {fill, slotSeparator, propsSlot}) {
18
18
  match.call(currentNode, {tag: fill}, fillNode => {
19
19
  if (!fillNode.attrs) {
20
20
  fillNode.attrs = {};
@@ -22,10 +22,10 @@ function setFilledSlots(currentNode, filledSlots, {fill, slotSeparator}) {
22
22
 
23
23
  const name = fillNode.tag.split(slotSeparator)[1];
24
24
 
25
- const locals = omit(fillNode.attrs, ['append', 'prepend', 'aware']);
25
+ const props = omit(fillNode.attrs, ['append', 'prepend', 'aware']);
26
26
 
27
- if (locals) {
28
- each(locals, (value, key, attrs) => {
27
+ if (props) {
28
+ each(props, (value, key, attrs) => {
29
29
  try {
30
30
  attrs[key] = JSON.parse(value);
31
31
  } catch {}
@@ -39,7 +39,7 @@ function setFilledSlots(currentNode, filledSlots, {fill, slotSeparator}) {
39
39
  attrs: fillNode.attrs,
40
40
  content: fillNode.content,
41
41
  source: render(fillNode.content),
42
- locals
42
+ [propsSlot]: props
43
43
  };
44
44
 
45
45
  return fillNode;
File without changes