regor 1.5.2 → 1.5.4

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/README.md CHANGED
@@ -369,8 +369,8 @@ Regor provides a set of directives that allow you to enhance the behavior and ap
369
369
  - **`:key`** Provides a unique identifier for each item in a list, aiding efficient updates and rendering.
370
370
  - **`:is`** Specifies the component to dynamically render based on a value or expression.
371
371
  - **`r-teleport`** Teleports the element to anywhere in the DOM. Unlike Vue, teleport is a directive to avoid component overhead.
372
- - **`:props`** Vue uses v-bind for component property passing. However, this can conflict with v-bind's attribute fall-through logic. Hence, Regor defines a dedicated directive to pass properties using object syntax. It enables passing properties without defining them in the component's props contract.
373
- - **`:props-once`** Similar to :props but it doesn't observe entire reactive tree of the template expression. Tail reactivity still works.
372
+ - **`:context`** Assigns an object into a component instance context, reactively. Use it for object-style component input, including fields that are not declared in the component `props` list.
373
+ - **`r-context`** Alias of `:context` with the same behavior.
374
374
  - **`@`** Shorthand for `r-on` to bind event listeners.
375
375
  - **`:`** Shorthand for `r-bind` to bind element attributes.
376
376
  - **`.`** Shorthand for `r-bind.prop` to set properties.
package/dist/regor.d.ts CHANGED
@@ -147,24 +147,36 @@ export declare class ComponentHead<TContext extends IRegorContext | object = IRe
147
147
  */
148
148
  ctx: IRegorContext[];
149
149
  /**
150
- * Controls whether Regor should automatically apply incoming `head.props`
151
- * values to the component context after `context(head)` returns.
150
+ * Controls whether Regor automatically merges parent-provided component inputs
151
+ * into the object returned by `context(head)`.
152
152
  *
153
- * Think of it as "auto wire parent inputs into my component fields".
153
+ * There are two runtime data sources for a component:
154
+ *
155
+ * 1. Parent inputs:
156
+ * values passed from the component host, such as `:title="abc"` or
157
+ * `:context="{ ... }"`. These are exposed on `head.props`.
158
+ *
159
+ * 2. Component context:
160
+ * the object returned by `context(head)`. This is the component's own local
161
+ * state.
162
+ *
163
+ * `autoProps` controls the third step: how those two sources are merged.
154
164
  *
155
165
  * - `true` (default):
156
- * - If a key exists in `head.props` but does not exist on the object
157
- * returned by `context(head)`, Regor adds that key to component context.
158
- * - Existing ref fields can receive incoming values automatically.
159
- * - Ref-to-ref inputs can be entangled when `head.entangle` is enabled.
160
- * - `false`:
161
- * - Regor does not auto-apply props.
162
- * - You fully control mapping manually inside `context(head)`.
166
+ * Regor automatically applies `head.props` to the component context.
167
+ * If a parent input name is missing from the component context, Regor adds it.
168
+ * Isolates the declared component properties,
169
+ * so a component does not accidentally inherit unwanted values from its ancestors.
163
170
  *
164
- * Use `false` when you need strict custom mapping/validation/transforms
165
- * before any value touches component state.
171
+ * - `false`:
172
+ * Regor does not merge `head.props` into the returned context.
173
+ * The component author must map values manually from `head.props`.
174
+ * Disables isolation for declared props.
166
175
  *
167
- * "Missing key" is always checked against the returned component context object.
176
+ * In short:
177
+ * - `head.props` = what the parent passed
178
+ * - `context(head)` return value = what the component defines
179
+ * - `autoProps` = whether Regor should merge the first into the second
168
180
  *
169
181
  * Example (auto add):
170
182
  * ```ts
@@ -321,6 +333,7 @@ export type BivariantAnyRefCall = {
321
333
  bivarianceHack(newValue?: unknown, eventSource?: unknown): unknown;
322
334
  }["bivarianceHack"];
323
335
  export type AnyRef = BivariantAnyRefCall;
336
+ export type RefOrValue<TValueType> = Ref<TValueType> | SRef<TValueType> | TValueType;
324
337
  export type Ref<TValueType> = ((newValue?: RefContent<TValueType> | Ref<RefParam<TValueType>> | SRef<RefContent<TValueType>>, eventSource?: unknown) => RefContent<TValueType>) & {
325
338
  value: RefContent<TValueType>;
326
339
  };
@@ -555,24 +555,36 @@ var ComponentHead = class {
555
555
  */
556
556
  __publicField(this, "ctx");
557
557
  /**
558
- * Controls whether Regor should automatically apply incoming `head.props`
559
- * values to the component context after `context(head)` returns.
558
+ * Controls whether Regor automatically merges parent-provided component inputs
559
+ * into the object returned by `context(head)`.
560
560
  *
561
- * Think of it as "auto wire parent inputs into my component fields".
561
+ * There are two runtime data sources for a component:
562
+ *
563
+ * 1. Parent inputs:
564
+ * values passed from the component host, such as `:title="abc"` or
565
+ * `:context="{ ... }"`. These are exposed on `head.props`.
566
+ *
567
+ * 2. Component context:
568
+ * the object returned by `context(head)`. This is the component's own local
569
+ * state.
570
+ *
571
+ * `autoProps` controls the third step: how those two sources are merged.
562
572
  *
563
573
  * - `true` (default):
564
- * - If a key exists in `head.props` but does not exist on the object
565
- * returned by `context(head)`, Regor adds that key to component context.
566
- * - Existing ref fields can receive incoming values automatically.
567
- * - Ref-to-ref inputs can be entangled when `head.entangle` is enabled.
568
- * - `false`:
569
- * - Regor does not auto-apply props.
570
- * - You fully control mapping manually inside `context(head)`.
574
+ * Regor automatically applies `head.props` to the component context.
575
+ * If a parent input name is missing from the component context, Regor adds it.
576
+ * Isolates the declared component properties,
577
+ * so a component does not accidentally inherit unwanted values from its ancestors.
571
578
  *
572
- * Use `false` when you need strict custom mapping/validation/transforms
573
- * before any value touches component state.
579
+ * - `false`:
580
+ * Regor does not merge `head.props` into the returned context.
581
+ * The component author must map values manually from `head.props`.
582
+ * Disables isolation for declared props.
574
583
  *
575
- * "Missing key" is always checked against the returned component context object.
584
+ * In short:
585
+ * - `head.props` = what the parent passed
586
+ * - `context(head)` return value = what the component defines
587
+ * - `autoProps` = whether Regor should merge the first into the second
576
588
  *
577
589
  * Example (auto add):
578
590
  * ```ts
@@ -1681,6 +1693,7 @@ var ComponentBinder = class {
1681
1693
  return isTemplate(node) && node.getAttributeNames().length === 0;
1682
1694
  }
1683
1695
  __unwrapComponents(element) {
1696
+ var _a, _b;
1684
1697
  const binder = this.__binder;
1685
1698
  const parser = binder.__parser;
1686
1699
  const registeredComponents = binder.__config.__components;
@@ -1714,6 +1727,7 @@ var ComponentBinder = class {
1714
1727
  const contextName = binder.__config.__builtInNames.context;
1715
1728
  const contextAliasName = binder.__config.__builtInNames.contextAlias;
1716
1729
  const bindName = binder.__config.__builtInNames.bind;
1730
+ const definedProps = (_b = (_a = registeredComponent.props) == null ? void 0 : _a.map(camelize)) != null ? _b : [];
1717
1731
  const getProps = (component2, capturedContext2) => {
1718
1732
  const props = {};
1719
1733
  const hasContext = component2.hasAttribute(contextName);
@@ -1724,9 +1738,7 @@ var ComponentBinder = class {
1724
1738
  } else if (component2.hasAttribute(contextAliasName)) {
1725
1739
  binder.__bind(contextDirective, component2, contextAliasName);
1726
1740
  }
1727
- let definedProps = registeredComponent.props;
1728
- if (!definedProps || definedProps.length === 0) return;
1729
- definedProps = definedProps.map(camelize);
1741
+ if (definedProps.length === 0) return;
1730
1742
  const definedPropsByLowerCase = new Map(
1731
1743
  definedProps.map((definedProp) => [
1732
1744
  definedProp.toLowerCase(),
@@ -1765,7 +1777,7 @@ var ComponentBinder = class {
1765
1777
  };
1766
1778
  const capturedContext = [...parser.__capture()];
1767
1779
  const createComponentCtx = () => {
1768
- var _a;
1780
+ var _a2;
1769
1781
  const props = getProps(component, capturedContext);
1770
1782
  const head2 = new ComponentHead(
1771
1783
  props,
@@ -1776,8 +1788,8 @@ var ComponentBinder = class {
1776
1788
  binder.__config.propValidationMode
1777
1789
  );
1778
1790
  const componentCtx2 = useScope(() => {
1779
- var _a2;
1780
- return (_a2 = registeredComponent.context(head2)) != null ? _a2 : {};
1791
+ var _a3;
1792
+ return (_a3 = registeredComponent.context(head2)) != null ? _a3 : {};
1781
1793
  }).context;
1782
1794
  if (head2.autoProps) {
1783
1795
  for (const [key, propsValue] of Object.entries(props)) {
@@ -1801,7 +1813,11 @@ var ComponentBinder = class {
1801
1813
  }
1802
1814
  } else componentCtx2[key] = propsValue;
1803
1815
  }
1804
- (_a = head2.onAutoPropsAssigned) == null ? void 0 : _a.call(head2);
1816
+ for (const key of definedProps) {
1817
+ if (key in componentCtx2) continue;
1818
+ componentCtx2[key] = void 0;
1819
+ }
1820
+ (_a2 = head2.onAutoPropsAssigned) == null ? void 0 : _a2.call(head2);
1805
1821
  }
1806
1822
  return { componentCtx: componentCtx2, head: head2 };
1807
1823
  };
@@ -1810,7 +1826,7 @@ var ComponentBinder = class {
1810
1826
  const len = childNodes.length;
1811
1827
  const isEmptyComponent = component.childNodes.length === 0;
1812
1828
  const expandSlot = (slot) => {
1813
- var _a;
1829
+ var _a2;
1814
1830
  const parent2 = slot.parentElement;
1815
1831
  let name = slot.name;
1816
1832
  if (isNullOrWhitespace(name)) {
@@ -1843,9 +1859,9 @@ var ComponentBinder = class {
1843
1859
  const unnamedTemplates = component.querySelectorAll(
1844
1860
  "template:not([name])"
1845
1861
  );
1846
- compTemplate = (_a = [...unnamedTemplates].find(
1862
+ compTemplate = (_a2 = [...unnamedTemplates].find(
1847
1863
  (x) => this.__isDefaultSlotTemplateShortcut(x)
1848
- )) != null ? _a : null;
1864
+ )) != null ? _a2 : null;
1849
1865
  }
1850
1866
  const createSwitchContext = (childNodes2) => {
1851
1867
  if (!head.enableSwitch) return;