piral-core 0.15.0-alpha.4098 → 0.15.0-alpha.4257

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.
@@ -17,21 +17,29 @@ const renderExtensions = [
17
17
  defaults: {},
18
18
  pilet: '',
19
19
  reference: {
20
- displayName: 'RenderExtension',
20
+ displayName: 'AnyComponent',
21
21
  },
22
22
  },
23
23
  ];
24
+ function defaultOrder(extensions) {
25
+ return extensions;
26
+ }
24
27
  /**
25
28
  * The extension slot component to be used when the available
26
29
  * extensions of a given name should be rendered at a specific
27
30
  * location.
28
31
  */
29
32
  export function ExtensionSlot(props) {
30
- const { name, render = defaultRender, empty, params, children } = props;
33
+ const { name, render = defaultRender, empty, params, children, emptySkipsRender = false, order = defaultOrder, } = props;
31
34
  const extensions = useGlobalState((s) => (name ? s.registry.extensions[name] || none : renderExtensions));
32
- return render(extensions.length === 0 && isfunc(empty)
35
+ const isEmpty = extensions.length === 0 && isfunc(empty);
36
+ const content = isEmpty
33
37
  ? [defaultRender(empty(), 'empty')]
34
- : extensions.map(({ component: Component, reference, defaults = {} }, i) => (React.createElement(Component, { key: `${(reference === null || reference === void 0 ? void 0 : reference.displayName) || '_'}${i}`, children: children, params: Object.assign(Object.assign({}, defaults), (params || {})) }))));
38
+ : order(extensions).map(({ component: Component, reference, defaults = {} }, i) => (React.createElement(Component, { key: `${(reference === null || reference === void 0 ? void 0 : reference.displayName) || '_'}${i}`, children: children, params: Object.assign(Object.assign({}, defaults), params) })));
39
+ if (isEmpty && emptySkipsRender) {
40
+ return content[0];
41
+ }
42
+ return render(content);
35
43
  }
36
44
  ExtensionSlot.displayName = `ExtensionSlot`;
37
45
  //# sourceMappingURL=ExtensionSlot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExtensionSlot.js","sourceRoot":"","sources":["../../src/components/ExtensionSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAG/C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AAE1D,MAAM,gBAAgB,GAA4B;IAChD;QACE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;YACtC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7B,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;YAChD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAC7G,OAAO,oBAAC,SAAS,oBAAK,IAAI,EAAI,CAAC;QACjC,CAAC;QACD,QAAQ,EAAE,EAAE;QACZ,KAAK,EAAE,EAAE;QACT,SAAS,EAAE;YACT,WAAW,EAAE,iBAAiB;SAC/B;KACF;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAmB,KAA4B;IAC1E,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACxE,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC1G,OAAO,MAAM,CACX,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC;QACtC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CACxE,oBAAC,SAAS,IACR,GAAG,EAAE,GAAG,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,KAAI,GAAG,GAAG,CAAC,EAAE,EAC3C,QAAQ,EAAE,QAAQ,EAClB,MAAM,kCACD,QAAQ,GACR,CAAC,MAAM,IAAI,EAAE,CAAC,IAEnB,CACH,CAAC,CACP,CAAC;AACJ,CAAC;AAED,aAAa,CAAC,WAAW,GAAG,eAAe,CAAC"}
1
+ {"version":3,"file":"ExtensionSlot.js","sourceRoot":"","sources":["../../src/components/ExtensionSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAG/C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AAE1D,MAAM,gBAAgB,GAA4B;IAChD;QACE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;YACtC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7B,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;YAChD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAC7G,OAAO,oBAAC,SAAS,oBAAK,IAAI,EAAI,CAAC;QACjC,CAAC;QACD,QAAQ,EAAE,EAAE;QACZ,KAAK,EAAE,EAAE;QACT,SAAS,EAAE;YACT,WAAW,EAAE,cAAc;SAC5B;KACF;CACF,CAAC;AAEF,SAAS,YAAY,CAAC,UAAwC;IAC5D,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAmB,KAA4B;IAC1E,MAAM,EACJ,IAAI,EACJ,MAAM,GAAG,aAAa,EACtB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,gBAAgB,GAAG,KAAK,EACxB,KAAK,GAAG,YAAY,GACrB,GAAG,KAAK,CAAC;IACV,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC1G,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,OAAO;QACrB,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAC/E,oBAAC,SAAS,IACR,GAAG,EAAE,GAAG,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,KAAI,GAAG,GAAG,CAAC,EAAE,EAC3C,QAAQ,EAAE,QAAQ,EAClB,MAAM,kCACD,QAAQ,GACR,MAAM,IAEX,CACH,CAAC,CAAC;IAEP,IAAI,OAAO,IAAI,gBAAgB,EAAE;QAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;KACnB;IAED,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED,aAAa,CAAC,WAAW,GAAG,eAAe,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { ForeignComponent, BaseComponentProps, ComponentContext } from '../types';
2
+ import type { ForeignComponent, BaseComponentProps, ComponentContext } from '../types';
3
3
  interface ForeignComponentContainerProps<T> {
4
4
  $portalId: string;
5
5
  $component: ForeignComponent<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"ForeignComponentContainer.js","sourceRoot":"","sources":["../../src/components/ForeignComponentContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAWpC,MAAM,OAAO,yBAA6B,SAAQ,KAAK,CAAC,SAA4C;IAApG;;QACU,WAAM,GAAyB,EAAE,CAAC;QAGlC,YAAO,GAAG,CAAC,EAAe,EAAE,EAAE;YACpC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;YAClC,EAAE,CAAC,eAAe,EAAE,CAAC;YACrB,UAAU,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1E,CAAC,CAAC;QAEM,YAAO,GAAG,CAAC,IAAoB,EAAE,EAAE;YACzC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC,CAAC;IA6CJ,CAAC;IA3CC,iBAAiB;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;QAE7B,IAAI,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE;YACzB,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/C,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC3D;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,kBAAkB;QAChB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QACnC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;QAE9B,IAAI,OAAO,KAAK,QAAQ,EAAE;YACxB,QAAQ,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACxC,OAAO,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;SACrC;aAAM,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE;YACzB,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;SACpD;IACH,CAAC;IAED,oBAAoB;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAClC,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;QAE/B,IAAI,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE;YAC3B,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC9D;QAED,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,OAAO,+CAAqB,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,GAAI,CAAC;IAC/D,CAAC;CACF"}
1
+ {"version":3,"file":"ForeignComponentContainer.js","sourceRoot":"","sources":["../../src/components/ForeignComponentContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAUpC,MAAM,OAAO,yBAA6B,SAAQ,KAAK,CAAC,SAA4C;IAApG;;QACU,WAAM,GAAyB,EAAE,CAAC;QAGlC,YAAO,GAAG,CAAC,EAAe,EAAE,EAAE;YACpC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;YAClC,EAAE,CAAC,eAAe,EAAE,CAAC;YACrB,UAAU,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1E,CAAC,CAAC;QAEM,YAAO,GAAG,CAAC,IAAoB,EAAE,EAAE;YACzC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC,CAAC;IA6CJ,CAAC;IA3CC,iBAAiB;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;QAE7B,IAAI,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE;YACzB,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/C,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC3D;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,kBAAkB;QAChB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QACnC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;QAE9B,IAAI,OAAO,KAAK,QAAQ,EAAE;YACxB,QAAQ,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACxC,OAAO,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;SACrC;aAAM,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE;YACzB,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;SACpD;IACH,CAAC;IAED,oBAAoB;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAClC,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;QAE/B,IAAI,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE;YAC3B,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC9D;QAED,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,OAAO,+CAAqB,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,GAAI,CAAC;IAC/D,CAAC;CACF"}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { AnyComponent, ComponentConverters, PiletApi, BaseComponentProps } from '../types';
2
+ import type { AnyComponent, ComponentConverters, PiletApi, BaseComponentProps } from '../types';
3
3
  interface CapturedProps {
4
4
  piral: PiletApi;
5
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"withApi.js","sourceRoot":"","sources":["../../src/state/withApi.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,cAAc,GAA0C,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEvG,SAAS,UAAU,CAAC,QAAkD,EAAE,WAAmB;IACzF,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IAEvC,IAAI,OAAO,IAAI,QAAQ,EAAE;QACvB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAChB,oBAAC,OAAO,oBAAK,KAAK;YAChB,oBAAC,QAAQ,oBAAK,KAAK,EAAI,CACf,CACX,CAAC;KACH;IAED,OAAO,QAAQ,IAAI,OAAO,IAAI,cAAc,CAAC;AAC/C,CAAC;AAED,SAAS,WAAW,CAClB,OAA2B,EAC3B,UAAe,EACf,WAAmB,EACnB,SAAuB;IAEvB,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAE5F,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAChB,oBAAC,YAAY,oBAAK,UAAU,EAAM,KAAK;QACrC,oBAAC,aAAa,oBAAK,UAAU,EAAM,KAAK,IAAE,SAAS,EAAE,SAAS,KAC3D,KAAK,CAAC,QAAQ,CACD,CACH,CAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,OAA2B,EAC3B,SAAoD,EACpD,KAAe,EACf,SAAuB,EACvB,cAAsB,SAAS,EAC/B,QAAQ,GAAG,EAAE;IAEb,MAAM,UAAU,mCAAQ,QAAQ,KAAE,KAAK,GAAE,CAAC;IAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,MAAM,OAAO,GAAG,WAAW,CAAS,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IACjF,OAAO,aAAa,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"withApi.js","sourceRoot":"","sources":["../../src/state/withApi.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,cAAc,GAA0C,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEvG,SAAS,UAAU,CAAC,QAAkD,EAAE,WAAmB;IACzF,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IAEvC,IAAI,OAAO,IAAI,QAAQ,EAAE;QACvB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAChB,oBAAC,OAAO,oBAAK,KAAK;YAChB,oBAAC,QAAQ,oBAAK,KAAK,EAAI,CACf,CACX,CAAC;KACH;IAED,OAAO,QAAQ,IAAI,OAAO,IAAI,cAAc,CAAC;AAC/C,CAAC;AAED,SAAS,WAAW,CAClB,OAA2B,EAC3B,UAAe,EACf,WAAmB,EACnB,SAAuB;IAEvB,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAE5F,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAChB,oBAAC,YAAY,oBAAK,UAAU,EAAM,KAAK;QACrC,oBAAC,aAAa,oBAAK,UAAU,EAAM,KAAK,IAAE,SAAS,EAAE,SAAS,KAC3D,KAAK,CAAC,QAAQ,CACD,CACH,CAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,OAA2B,EAC3B,SAAoD,EACpD,KAAe,EACf,SAAuB,EACvB,cAAsB,SAAS,EAC/B,QAAQ,GAAG,EAAE;IAEb,MAAM,UAAU,mCAAQ,QAAQ,KAAE,KAAK,GAAE,CAAC;IAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,MAAM,OAAO,GAAG,WAAW,CAAS,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IACjF,OAAO,aAAa,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { ReactElement } from 'react';
1
+ import type { ReactElement, ReactNode } from 'react';
2
2
  import type { RouteComponentProps } from 'react-router';
3
3
  import type { PiletApi, Pilet, PiletEntry, PiletEntries, PiletMetadata, EventEmitter, PiletLoader, PiletLoadingStrategy } from 'piral-base';
4
4
  import type { PiletCustomApi, PiralCustomPageMeta } from './custom';
@@ -33,6 +33,10 @@ export interface ExtensionComponentProps<T> extends BaseComponentProps {
33
33
  * The provided parameters for showing the extension.
34
34
  */
35
35
  params: T extends keyof PiralExtensionSlotMap ? PiralExtensionSlotMap[T] : T extends string ? any : T;
36
+ /**
37
+ * The optional children to receive, if any.
38
+ */
39
+ children?: ReactNode;
36
40
  }
37
41
  /**
38
42
  * The meta data registered for a page.
@@ -53,6 +57,15 @@ export interface PageComponentProps<T = any, S = any> extends RouteBaseProps<T,
53
57
  */
54
58
  meta: PiralPageMeta;
55
59
  }
60
+ /**
61
+ * The meta data registered for a page.
62
+ */
63
+ export interface PiralPageMeta extends PiralCustomPageMeta {
64
+ }
65
+ /**
66
+ * Shorthand for the definition of an extension component.
67
+ */
68
+ export declare type AnyExtensionComponent<TName> = TName extends keyof PiralExtensionSlotMap ? AnyComponent<ExtensionComponentProps<TName>> : TName extends string ? AnyComponent<ExtensionComponentProps<any>> : AnyComponent<ExtensionComponentProps<TName>>;
56
69
  /**
57
70
  * Defines the Pilet API from piral-core.
58
71
  * This interface will be consumed by pilet developers so that their pilet can interact with the piral instance.
@@ -93,14 +106,14 @@ export interface PiletCoreApi {
93
106
  * @param Component The component to be rendered.
94
107
  * @param defaults Optionally, sets the default values for the expected data.
95
108
  */
96
- registerExtension<TName>(name: TName extends string ? TName : string, Component: AnyComponent<ExtensionComponentProps<TName>>, defaults?: Partial<ExtensionParams<TName>>): RegistrationDisposer;
109
+ registerExtension<TName>(name: TName extends string ? TName : string, Component: AnyExtensionComponent<TName>, defaults?: Partial<ExtensionParams<TName>>): RegistrationDisposer;
97
110
  /**
98
111
  * Unregisters a global extension component.
99
112
  * Only previously registered extension components can be unregistered.
100
113
  * @param name The name of the extension slot to unregister from.
101
114
  * @param Component The registered extension component to unregister.
102
115
  */
103
- unregisterExtension<TName>(name: TName extends string ? TName : string, Component: AnyComponent<ExtensionComponentProps<TName>>): void;
116
+ unregisterExtension<TName>(name: TName extends string ? TName : string, Component: AnyExtensionComponent<TName>): void;
104
117
  /**
105
118
  * React component for displaying extensions for a given name.
106
119
  * @param props The extension's rendering props.
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode, ReactElement } from 'react';
2
2
  import type { PiralCustomExtensionSlotMap } from './custom';
3
+ import type { ExtensionRegistration } from './state';
3
4
  /**
4
5
  * The mapping of the existing (known) extension slots.
5
6
  */
@@ -18,9 +19,27 @@ export interface BaseExtensionSlotProps<TName, TParams> {
18
19
  * for the specified extension.
19
20
  */
20
21
  empty?(): ReactNode;
22
+ /**
23
+ * Determines if the `render` function should be called in case no
24
+ * components are available for the specified extension.
25
+ *
26
+ * If true, `empty` will be called and returned from the slot.
27
+ * If false, `render` will be called with the result of calling `empty`.
28
+ * The result of calling `render` will then be returned from the slot.
29
+ */
30
+ emptySkipsRender?: boolean;
31
+ /**
32
+ * Defines the order of the components to render.
33
+ * May be more convient than using `render` w.r.t. ordering extensions
34
+ * by their supplied metadata.
35
+ * @param extensions The registered extensions.
36
+ * @returns The ordered extensions.
37
+ */
38
+ order?(extensions: Array<ExtensionRegistration>): Array<ExtensionRegistration>;
21
39
  /**
22
40
  * Defines how the provided nodes should be rendered.
23
41
  * @param nodes The rendered extension nodes.
42
+ * @returns The rendered nodes, i.e., an ReactElement.
24
43
  */
25
44
  render?(nodes: Array<ReactNode>): ReactElement<any, any> | null;
26
45
  /**
@@ -21,21 +21,39 @@ export declare type WrappedComponent<TProps> = ComponentType<PropsWithChildren<W
21
21
  * The base type for pilet component registration in the global state context.
22
22
  */
23
23
  export interface BaseRegistration {
24
+ /**
25
+ * The pilet registering the component.
26
+ */
24
27
  pilet: string;
25
28
  }
26
29
  /**
27
30
  * The interface modeling the registration of a pilet page component.
28
31
  */
29
32
  export interface PageRegistration extends BaseRegistration {
33
+ /**
34
+ * The registered page component.
35
+ */
30
36
  component: WrappedComponent<PageComponentProps>;
37
+ /**
38
+ * The page's associated metadata.
39
+ */
31
40
  meta: PiralPageMeta;
32
41
  }
33
42
  /**
34
43
  * The interface modeling the registration of a pilet extension component.
35
44
  */
36
45
  export interface ExtensionRegistration extends BaseRegistration {
46
+ /**
47
+ * The wrapped registered extension component.
48
+ */
37
49
  component: WrappedComponent<ExtensionComponentProps<string>>;
50
+ /**
51
+ * The original extension component that has been registered.
52
+ */
38
53
  reference: any;
54
+ /**
55
+ * The default params (i.e., meta) of the extension.
56
+ */
39
57
  defaults: any;
40
58
  }
41
59
  /**
@@ -20,21 +20,29 @@ const renderExtensions = [
20
20
  defaults: {},
21
21
  pilet: '',
22
22
  reference: {
23
- displayName: 'RenderExtension',
23
+ displayName: 'AnyComponent',
24
24
  },
25
25
  },
26
26
  ];
27
+ function defaultOrder(extensions) {
28
+ return extensions;
29
+ }
27
30
  /**
28
31
  * The extension slot component to be used when the available
29
32
  * extensions of a given name should be rendered at a specific
30
33
  * location.
31
34
  */
32
35
  function ExtensionSlot(props) {
33
- const { name, render = utils_1.defaultRender, empty, params, children } = props;
36
+ const { name, render = utils_1.defaultRender, empty, params, children, emptySkipsRender = false, order = defaultOrder, } = props;
34
37
  const extensions = (0, hooks_1.useGlobalState)((s) => (name ? s.registry.extensions[name] || utils_1.none : renderExtensions));
35
- return render(extensions.length === 0 && (0, piral_base_1.isfunc)(empty)
38
+ const isEmpty = extensions.length === 0 && (0, piral_base_1.isfunc)(empty);
39
+ const content = isEmpty
36
40
  ? [(0, utils_1.defaultRender)(empty(), 'empty')]
37
- : extensions.map(({ component: Component, reference, defaults = {} }, i) => (React.createElement(Component, { key: `${(reference === null || reference === void 0 ? void 0 : reference.displayName) || '_'}${i}`, children: children, params: Object.assign(Object.assign({}, defaults), (params || {})) }))));
41
+ : order(extensions).map(({ component: Component, reference, defaults = {} }, i) => (React.createElement(Component, { key: `${(reference === null || reference === void 0 ? void 0 : reference.displayName) || '_'}${i}`, children: children, params: Object.assign(Object.assign({}, defaults), params) })));
42
+ if (isEmpty && emptySkipsRender) {
43
+ return content[0];
44
+ }
45
+ return render(content);
38
46
  }
39
47
  exports.ExtensionSlot = ExtensionSlot;
40
48
  ExtensionSlot.displayName = `ExtensionSlot`;
@@ -1 +1 @@
1
- {"version":3,"file":"ExtensionSlot.js","sourceRoot":"","sources":["../../src/components/ExtensionSlot.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,2CAAoC;AACpC,mDAAgD;AAChD,oCAAiE;AACjE,oCAA+C;AAG/C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,IAAA,qBAAa,EAAC,QAAQ,CAAC,CAAC;AAE1D,MAAM,gBAAgB,GAA4B;IAChD;QACE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,MAAM,OAAO,GAAG,IAAA,6BAAqB,GAAE,CAAC;YACxC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;YACtC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7B,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;YAChD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,6BAAa,EAAC,UAAU,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAC7G,OAAO,oBAAC,SAAS,oBAAK,IAAI,EAAI,CAAC;QACjC,CAAC;QACD,QAAQ,EAAE,EAAE;QACZ,KAAK,EAAE,EAAE;QACT,SAAS,EAAE;YACT,WAAW,EAAE,iBAAiB;SAC/B;KACF;CACF,CAAC;AAEF;;;;GAIG;AACH,SAAgB,aAAa,CAAmB,KAA4B;IAC1E,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,qBAAa,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACxE,MAAM,UAAU,GAAG,IAAA,sBAAc,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,YAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC1G,OAAO,MAAM,CACX,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,IAAA,mBAAM,EAAC,KAAK,CAAC;QACtC,CAAC,CAAC,CAAC,IAAA,qBAAa,EAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CACxE,oBAAC,SAAS,IACR,GAAG,EAAE,GAAG,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,KAAI,GAAG,GAAG,CAAC,EAAE,EAC3C,QAAQ,EAAE,QAAQ,EAClB,MAAM,kCACD,QAAQ,GACR,CAAC,MAAM,IAAI,EAAE,CAAC,IAEnB,CACH,CAAC,CACP,CAAC;AACJ,CAAC;AAjBD,sCAiBC;AAED,aAAa,CAAC,WAAW,GAAG,eAAe,CAAC"}
1
+ {"version":3,"file":"ExtensionSlot.js","sourceRoot":"","sources":["../../src/components/ExtensionSlot.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,2CAAoC;AACpC,mDAAgD;AAChD,oCAAiE;AACjE,oCAA+C;AAG/C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,IAAA,qBAAa,EAAC,QAAQ,CAAC,CAAC;AAE1D,MAAM,gBAAgB,GAA4B;IAChD;QACE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,MAAM,OAAO,GAAG,IAAA,6BAAqB,GAAE,CAAC;YACxC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;YACtC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7B,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;YAChD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,6BAAa,EAAC,UAAU,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAC7G,OAAO,oBAAC,SAAS,oBAAK,IAAI,EAAI,CAAC;QACjC,CAAC;QACD,QAAQ,EAAE,EAAE;QACZ,KAAK,EAAE,EAAE;QACT,SAAS,EAAE;YACT,WAAW,EAAE,cAAc;SAC5B;KACF;CACF,CAAC;AAEF,SAAS,YAAY,CAAC,UAAwC;IAC5D,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAmB,KAA4B;IAC1E,MAAM,EACJ,IAAI,EACJ,MAAM,GAAG,qBAAa,EACtB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,gBAAgB,GAAG,KAAK,EACxB,KAAK,GAAG,YAAY,GACrB,GAAG,KAAK,CAAC;IACV,MAAM,UAAU,GAAG,IAAA,sBAAc,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,YAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC1G,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,IAAA,mBAAM,EAAC,KAAK,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,OAAO;QACrB,CAAC,CAAC,CAAC,IAAA,qBAAa,EAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAC/E,oBAAC,SAAS,IACR,GAAG,EAAE,GAAG,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,KAAI,GAAG,GAAG,CAAC,EAAE,EAC3C,QAAQ,EAAE,QAAQ,EAClB,MAAM,kCACD,QAAQ,GACR,MAAM,IAEX,CACH,CAAC,CAAC;IAEP,IAAI,OAAO,IAAI,gBAAgB,EAAE;QAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;KACnB;IAED,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AA9BD,sCA8BC;AAED,aAAa,CAAC,WAAW,GAAG,eAAe,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { ForeignComponent, BaseComponentProps, ComponentContext } from '../types';
2
+ import type { ForeignComponent, BaseComponentProps, ComponentContext } from '../types';
3
3
  interface ForeignComponentContainerProps<T> {
4
4
  $portalId: string;
5
5
  $component: ForeignComponent<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"ForeignComponentContainer.js","sourceRoot":"","sources":["../../src/components/ForeignComponentContainer.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,2CAAoC;AAWpC,MAAa,yBAA6B,SAAQ,KAAK,CAAC,SAA4C;IAApG;;QACU,WAAM,GAAyB,EAAE,CAAC;QAGlC,YAAO,GAAG,CAAC,EAAe,EAAE,EAAE;YACpC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;YAClC,EAAE,CAAC,eAAe,EAAE,CAAC;YACrB,UAAU,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1E,CAAC,CAAC;QAEM,YAAO,GAAG,CAAC,IAAoB,EAAE,EAAE;YACzC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC,CAAC;IA6CJ,CAAC;IA3CC,iBAAiB;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;QAE7B,IAAI,IAAI,IAAI,IAAA,mBAAM,EAAC,KAAK,CAAC,EAAE;YACzB,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/C,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC3D;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,kBAAkB;QAChB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QACnC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;QAE9B,IAAI,OAAO,KAAK,QAAQ,EAAE;YACxB,QAAQ,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACxC,OAAO,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;SACrC;aAAM,IAAI,IAAA,mBAAM,EAAC,MAAM,CAAC,EAAE;YACzB,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;SACpD;IACH,CAAC;IAED,oBAAoB;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAClC,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;QAE/B,IAAI,IAAI,IAAI,IAAA,mBAAM,EAAC,OAAO,CAAC,EAAE;YAC3B,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC9D;QAED,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,OAAO,+CAAqB,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,GAAI,CAAC;IAC/D,CAAC;CACF;AAzDD,8DAyDC"}
1
+ {"version":3,"file":"ForeignComponentContainer.js","sourceRoot":"","sources":["../../src/components/ForeignComponentContainer.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,2CAAoC;AAUpC,MAAa,yBAA6B,SAAQ,KAAK,CAAC,SAA4C;IAApG;;QACU,WAAM,GAAyB,EAAE,CAAC;QAGlC,YAAO,GAAG,CAAC,EAAe,EAAE,EAAE;YACpC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;YAClC,EAAE,CAAC,eAAe,EAAE,CAAC;YACrB,UAAU,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1E,CAAC,CAAC;QAEM,YAAO,GAAG,CAAC,IAAoB,EAAE,EAAE;YACzC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC,CAAC;IA6CJ,CAAC;IA3CC,iBAAiB;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;QAE7B,IAAI,IAAI,IAAI,IAAA,mBAAM,EAAC,KAAK,CAAC,EAAE;YACzB,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/C,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC3D;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,kBAAkB;QAChB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QACnC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;QAE9B,IAAI,OAAO,KAAK,QAAQ,EAAE;YACxB,QAAQ,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACxC,OAAO,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;SACrC;aAAM,IAAI,IAAA,mBAAM,EAAC,MAAM,CAAC,EAAE;YACzB,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;SACpD;IACH,CAAC;IAED,oBAAoB;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAClC,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;QAE/B,IAAI,IAAI,IAAI,IAAA,mBAAM,EAAC,OAAO,CAAC,EAAE;YAC3B,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC9D;QAED,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,OAAO,+CAAqB,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,GAAI,CAAC;IAC/D,CAAC;CACF;AAzDD,8DAyDC"}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { AnyComponent, ComponentConverters, PiletApi, BaseComponentProps } from '../types';
2
+ import type { AnyComponent, ComponentConverters, PiletApi, BaseComponentProps } from '../types';
3
3
  interface CapturedProps {
4
4
  piral: PiletApi;
5
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"withApi.js","sourceRoot":"","sources":["../../src/state/withApi.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAE/B,8CAA6D;AAC7D,oCAAyC;AAGzC,MAAM,cAAc,GAA0C,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,qBAAa,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEvG,SAAS,UAAU,CAAC,QAAkD,EAAE,WAAmB;IACzF,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IAEvC,IAAI,OAAO,IAAI,QAAQ,EAAE;QACvB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAChB,oBAAC,OAAO,oBAAK,KAAK;YAChB,oBAAC,QAAQ,oBAAK,KAAK,EAAI,CACf,CACX,CAAC;KACH;IAED,OAAO,QAAQ,IAAI,OAAO,IAAI,cAAc,CAAC;AAC/C,CAAC;AAED,SAAS,WAAW,CAClB,OAA2B,EAC3B,UAAe,EACf,WAAmB,EACnB,SAAuB;IAEvB,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAE5F,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAChB,oBAAC,YAAY,oBAAK,UAAU,EAAM,KAAK;QACrC,oBAAC,0BAAa,oBAAK,UAAU,EAAM,KAAK,IAAE,SAAS,EAAE,SAAS,KAC3D,KAAK,CAAC,QAAQ,CACD,CACH,CAChB,CAAC;AACJ,CAAC;AAED,SAAgB,OAAO,CACrB,OAA2B,EAC3B,SAAoD,EACpD,KAAe,EACf,SAAuB,EACvB,cAAsB,SAAS,EAC/B,QAAQ,GAAG,EAAE;IAEb,MAAM,UAAU,mCAAQ,QAAQ,KAAE,KAAK,GAAE,CAAC;IAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,MAAM,OAAO,GAAG,WAAW,CAAS,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IACjF,OAAO,IAAA,0BAAa,EAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC;AAZD,0BAYC"}
1
+ {"version":3,"file":"withApi.js","sourceRoot":"","sources":["../../src/state/withApi.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,8CAA6D;AAC7D,oCAAyC;AAGzC,MAAM,cAAc,GAA0C,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,qBAAa,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEvG,SAAS,UAAU,CAAC,QAAkD,EAAE,WAAmB;IACzF,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IAEvC,IAAI,OAAO,IAAI,QAAQ,EAAE;QACvB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAChB,oBAAC,OAAO,oBAAK,KAAK;YAChB,oBAAC,QAAQ,oBAAK,KAAK,EAAI,CACf,CACX,CAAC;KACH;IAED,OAAO,QAAQ,IAAI,OAAO,IAAI,cAAc,CAAC;AAC/C,CAAC;AAED,SAAS,WAAW,CAClB,OAA2B,EAC3B,UAAe,EACf,WAAmB,EACnB,SAAuB;IAEvB,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAE5F,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAChB,oBAAC,YAAY,oBAAK,UAAU,EAAM,KAAK;QACrC,oBAAC,0BAAa,oBAAK,UAAU,EAAM,KAAK,IAAE,SAAS,EAAE,SAAS,KAC3D,KAAK,CAAC,QAAQ,CACD,CACH,CAChB,CAAC;AACJ,CAAC;AAED,SAAgB,OAAO,CACrB,OAA2B,EAC3B,SAAoD,EACpD,KAAe,EACf,SAAuB,EACvB,cAAsB,SAAS,EAC/B,QAAQ,GAAG,EAAE;IAEb,MAAM,UAAU,mCAAQ,QAAQ,KAAE,KAAK,GAAE,CAAC;IAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,MAAM,OAAO,GAAG,WAAW,CAAS,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IACjF,OAAO,IAAA,0BAAa,EAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC;AAZD,0BAYC"}
@@ -1,4 +1,4 @@
1
- import type { ReactElement } from 'react';
1
+ import type { ReactElement, ReactNode } from 'react';
2
2
  import type { RouteComponentProps } from 'react-router';
3
3
  import type { PiletApi, Pilet, PiletEntry, PiletEntries, PiletMetadata, EventEmitter, PiletLoader, PiletLoadingStrategy } from 'piral-base';
4
4
  import type { PiletCustomApi, PiralCustomPageMeta } from './custom';
@@ -33,6 +33,10 @@ export interface ExtensionComponentProps<T> extends BaseComponentProps {
33
33
  * The provided parameters for showing the extension.
34
34
  */
35
35
  params: T extends keyof PiralExtensionSlotMap ? PiralExtensionSlotMap[T] : T extends string ? any : T;
36
+ /**
37
+ * The optional children to receive, if any.
38
+ */
39
+ children?: ReactNode;
36
40
  }
37
41
  /**
38
42
  * The meta data registered for a page.
@@ -53,6 +57,15 @@ export interface PageComponentProps<T = any, S = any> extends RouteBaseProps<T,
53
57
  */
54
58
  meta: PiralPageMeta;
55
59
  }
60
+ /**
61
+ * The meta data registered for a page.
62
+ */
63
+ export interface PiralPageMeta extends PiralCustomPageMeta {
64
+ }
65
+ /**
66
+ * Shorthand for the definition of an extension component.
67
+ */
68
+ export declare type AnyExtensionComponent<TName> = TName extends keyof PiralExtensionSlotMap ? AnyComponent<ExtensionComponentProps<TName>> : TName extends string ? AnyComponent<ExtensionComponentProps<any>> : AnyComponent<ExtensionComponentProps<TName>>;
56
69
  /**
57
70
  * Defines the Pilet API from piral-core.
58
71
  * This interface will be consumed by pilet developers so that their pilet can interact with the piral instance.
@@ -93,14 +106,14 @@ export interface PiletCoreApi {
93
106
  * @param Component The component to be rendered.
94
107
  * @param defaults Optionally, sets the default values for the expected data.
95
108
  */
96
- registerExtension<TName>(name: TName extends string ? TName : string, Component: AnyComponent<ExtensionComponentProps<TName>>, defaults?: Partial<ExtensionParams<TName>>): RegistrationDisposer;
109
+ registerExtension<TName>(name: TName extends string ? TName : string, Component: AnyExtensionComponent<TName>, defaults?: Partial<ExtensionParams<TName>>): RegistrationDisposer;
97
110
  /**
98
111
  * Unregisters a global extension component.
99
112
  * Only previously registered extension components can be unregistered.
100
113
  * @param name The name of the extension slot to unregister from.
101
114
  * @param Component The registered extension component to unregister.
102
115
  */
103
- unregisterExtension<TName>(name: TName extends string ? TName : string, Component: AnyComponent<ExtensionComponentProps<TName>>): void;
116
+ unregisterExtension<TName>(name: TName extends string ? TName : string, Component: AnyExtensionComponent<TName>): void;
104
117
  /**
105
118
  * React component for displaying extensions for a given name.
106
119
  * @param props The extension's rendering props.
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode, ReactElement } from 'react';
2
2
  import type { PiralCustomExtensionSlotMap } from './custom';
3
+ import type { ExtensionRegistration } from './state';
3
4
  /**
4
5
  * The mapping of the existing (known) extension slots.
5
6
  */
@@ -18,9 +19,27 @@ export interface BaseExtensionSlotProps<TName, TParams> {
18
19
  * for the specified extension.
19
20
  */
20
21
  empty?(): ReactNode;
22
+ /**
23
+ * Determines if the `render` function should be called in case no
24
+ * components are available for the specified extension.
25
+ *
26
+ * If true, `empty` will be called and returned from the slot.
27
+ * If false, `render` will be called with the result of calling `empty`.
28
+ * The result of calling `render` will then be returned from the slot.
29
+ */
30
+ emptySkipsRender?: boolean;
31
+ /**
32
+ * Defines the order of the components to render.
33
+ * May be more convient than using `render` w.r.t. ordering extensions
34
+ * by their supplied metadata.
35
+ * @param extensions The registered extensions.
36
+ * @returns The ordered extensions.
37
+ */
38
+ order?(extensions: Array<ExtensionRegistration>): Array<ExtensionRegistration>;
21
39
  /**
22
40
  * Defines how the provided nodes should be rendered.
23
41
  * @param nodes The rendered extension nodes.
42
+ * @returns The rendered nodes, i.e., an ReactElement.
24
43
  */
25
44
  render?(nodes: Array<ReactNode>): ReactElement<any, any> | null;
26
45
  /**
@@ -21,21 +21,39 @@ export declare type WrappedComponent<TProps> = ComponentType<PropsWithChildren<W
21
21
  * The base type for pilet component registration in the global state context.
22
22
  */
23
23
  export interface BaseRegistration {
24
+ /**
25
+ * The pilet registering the component.
26
+ */
24
27
  pilet: string;
25
28
  }
26
29
  /**
27
30
  * The interface modeling the registration of a pilet page component.
28
31
  */
29
32
  export interface PageRegistration extends BaseRegistration {
33
+ /**
34
+ * The registered page component.
35
+ */
30
36
  component: WrappedComponent<PageComponentProps>;
37
+ /**
38
+ * The page's associated metadata.
39
+ */
31
40
  meta: PiralPageMeta;
32
41
  }
33
42
  /**
34
43
  * The interface modeling the registration of a pilet extension component.
35
44
  */
36
45
  export interface ExtensionRegistration extends BaseRegistration {
46
+ /**
47
+ * The wrapped registered extension component.
48
+ */
37
49
  component: WrappedComponent<ExtensionComponentProps<string>>;
50
+ /**
51
+ * The original extension component that has been registered.
52
+ */
38
53
  reference: any;
54
+ /**
55
+ * The default params (i.e., meta) of the extension.
56
+ */
39
57
  defaults: any;
40
58
  }
41
59
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "piral-core",
3
- "version": "0.15.0-alpha.4098",
3
+ "version": "0.15.0-alpha.4257",
4
4
  "description": "The core library for creating a Piral instance.",
5
5
  "keywords": [
6
6
  "portal",
@@ -29,6 +29,19 @@
29
29
  "module": "esm/index.js",
30
30
  "main": "lib/index.js",
31
31
  "typings": "lib/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "import": "./esm/index.js",
35
+ "require": "./lib/index.js"
36
+ },
37
+ "./esm/*": {
38
+ "import": "./esm/*"
39
+ },
40
+ "./lib/*": {
41
+ "require": "./lib/*"
42
+ },
43
+ "./package.json": "./package.json"
44
+ },
32
45
  "sideEffects": false,
33
46
  "files": [
34
47
  "esm",
@@ -60,8 +73,8 @@
60
73
  },
61
74
  "dependencies": {
62
75
  "@dbeining/react-atom": "^4.0.0",
63
- "piral-base": "0.15.0-alpha.4098",
64
- "piral-debug-utils": "0.15.0-alpha.4098"
76
+ "piral-base": "0.15.0-alpha.4257",
77
+ "piral-debug-utils": "0.15.0-alpha.4257"
65
78
  },
66
79
  "peerDependencies": {
67
80
  "react": ">=16.8.0",
@@ -91,5 +104,5 @@
91
104
  "@libre/atom",
92
105
  "@dbeining/react-atom"
93
106
  ],
94
- "gitHead": "02ef35574b29cc5dd93c515bfdf27dd523893b28"
107
+ "gitHead": "61f4ebc7b6c7cea553e2159b075cb761216f8e85"
95
108
  }
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { render, unmountComponentAtNode } from 'react-dom';
2
+ import { createRoot } from 'react-dom/client';
3
3
  import { act } from 'react-dom/test-utils';
4
4
  import { RootListener } from './RootListener';
5
5
 
@@ -15,7 +15,8 @@ describe('RootListener Component', () => {
15
15
  const removed = jest.fn();
16
16
  document.body.appendChild(element);
17
17
  const container = document.body.appendChild(document.createElement('div'));
18
- render(<RootListener />, container);
18
+ const root = createRoot(container);
19
+ root.render(<RootListener />);
19
20
  document.body.removeEventListener = removed;
20
21
  await act(() => {
21
22
  const event = new CustomEvent('render-html', {
@@ -23,7 +24,7 @@ describe('RootListener Component', () => {
23
24
  detail: {
24
25
  target: element,
25
26
  props: {},
26
- }
27
+ },
27
28
  });
28
29
  element.dispatchEvent(event);
29
30
  return Promise.resolve();
@@ -35,10 +36,11 @@ describe('RootListener Component', () => {
35
36
  it('removes the RootListener successfully', async () => {
36
37
  const container = document.body.appendChild(document.createElement('div'));
37
38
  const removed = jest.fn();
38
- render(<RootListener />, container);
39
+ const root = createRoot(container);
40
+ root.render(<RootListener />);
39
41
  document.body.removeEventListener = removed;
40
42
  await act(() => Promise.resolve());
41
- unmountComponentAtNode(container);
43
+ root.unmount();
42
44
  await act(() => Promise.resolve());
43
45
  expect(removed).toHaveBeenCalled();
44
46
  });
@@ -1,3 +1,4 @@
1
+ import { mount } from 'enzyme';
1
2
  import { createElement } from 'react';
2
3
  import { Atom, deref } from '@dbeining/react-atom';
3
4
  import { createListener, Pilet } from 'piral-base';
@@ -11,7 +12,6 @@ import {
11
12
  setRoute,
12
13
  } from './app';
13
14
  import { createActions } from '../state';
14
- import { mount } from 'enzyme';
15
15
  import { RootListener } from '../RootListener';
16
16
 
17
17
  const pilet: Pilet = {
@@ -49,6 +49,11 @@ const state = {
49
49
  component: StubComponent3,
50
50
  },
51
51
  ],
52
+ lol: [
53
+ {
54
+ component: StubComponent1,
55
+ },
56
+ ],
52
57
  },
53
58
  },
54
59
  };
@@ -118,7 +123,7 @@ describe('Extension Module', () => {
118
123
  it('overrides the empty renderer on not available extension', () => {
119
124
  const node = mount(<ExtensionSlot name="qxz" empty={() => <StubComponent1 key="empty" />} />);
120
125
  expect(node.find(StubComponent1).length).toBe(1);
121
- expect(node.find(StubComponent1).length).toBe(1);
126
+ expect(node.find(StubComponent2).length).toBe(0);
122
127
  });
123
128
 
124
129
  it('overrides the empty renderer on an available extension', () => {
@@ -138,4 +143,30 @@ describe('Extension Module', () => {
138
143
  expect(node.find(StubComponent1).length).toBe(1);
139
144
  expect(node.find(StubComponent2).length).toBe(1);
140
145
  });
146
+
147
+ it('does not use the render function with empty when emptySkipsRender is set', () => {
148
+ const node = mount(
149
+ <ExtensionSlot
150
+ name="foo"
151
+ emptySkipsRender
152
+ empty={() => <StubComponent2 key="empty" />}
153
+ render={(nodes) => <StubComponent1 children={nodes} />}
154
+ />,
155
+ );
156
+ expect(node.find(StubComponent1).length).toBe(0);
157
+ expect(node.find(StubComponent2).length).toBe(1);
158
+ });
159
+
160
+ it('does use the render function without empty independent if emptySkipsRender is set', () => {
161
+ const node = mount(
162
+ <ExtensionSlot
163
+ name="lol"
164
+ emptySkipsRender
165
+ empty={() => <StubComponent2 key="empty" />}
166
+ render={(nodes) => <StubComponent1 children={nodes} />}
167
+ />,
168
+ );
169
+ expect(node.find(StubComponent1).length).toBe(2);
170
+ expect(node.find(StubComponent2).length).toBe(0);
171
+ });
141
172
  });
@@ -20,33 +20,50 @@ const renderExtensions: [ExtensionRegistration] = [
20
20
  defaults: {},
21
21
  pilet: '',
22
22
  reference: {
23
- displayName: 'RenderExtension',
23
+ displayName: 'AnyComponent',
24
24
  },
25
25
  },
26
26
  ];
27
27
 
28
+ function defaultOrder(extensions: Array<ExtensionRegistration>) {
29
+ return extensions;
30
+ }
31
+
28
32
  /**
29
33
  * The extension slot component to be used when the available
30
34
  * extensions of a given name should be rendered at a specific
31
35
  * location.
32
36
  */
33
37
  export function ExtensionSlot<T extends string>(props: ExtensionSlotProps<T>) {
34
- const { name, render = defaultRender, empty, params, children } = props;
38
+ const {
39
+ name,
40
+ render = defaultRender,
41
+ empty,
42
+ params,
43
+ children,
44
+ emptySkipsRender = false,
45
+ order = defaultOrder,
46
+ } = props;
35
47
  const extensions = useGlobalState((s) => (name ? s.registry.extensions[name] || none : renderExtensions));
36
- return render(
37
- extensions.length === 0 && isfunc(empty)
38
- ? [defaultRender(empty(), 'empty')]
39
- : extensions.map(({ component: Component, reference, defaults = {} }, i) => (
40
- <Component
41
- key={`${reference?.displayName || '_'}${i}`}
42
- children={children}
43
- params={{
44
- ...defaults,
45
- ...(params || {}),
46
- }}
47
- />
48
- )),
49
- );
48
+ const isEmpty = extensions.length === 0 && isfunc(empty);
49
+ const content = isEmpty
50
+ ? [defaultRender(empty(), 'empty')]
51
+ : order(extensions).map(({ component: Component, reference, defaults = {} }, i) => (
52
+ <Component
53
+ key={`${reference?.displayName || '_'}${i}`}
54
+ children={children}
55
+ params={{
56
+ ...defaults,
57
+ ...params,
58
+ }}
59
+ />
60
+ ));
61
+
62
+ if (isEmpty && emptySkipsRender) {
63
+ return content[0];
64
+ }
65
+
66
+ return render(content);
50
67
  }
51
68
 
52
69
  ExtensionSlot.displayName = `ExtensionSlot`;
@@ -1,13 +1,21 @@
1
1
  import * as React from 'react';
2
- import { render, unmountComponentAtNode } from 'react-dom';
2
+ import { createRoot } from 'react-dom/client';
3
+ import { act } from 'react-dom/test-utils';
3
4
  import { ForeignComponentContainer } from './ForeignComponentContainer';
4
5
 
6
+ async function render(element: any, container: Element) {
7
+ const root = createRoot(container);
8
+ root.render(element);
9
+ await act(() => Promise.resolve());
10
+ return root;
11
+ }
12
+
5
13
  describe('ForeignComponentContainer component', () => {
6
- it('mounts an HTML component', () => {
14
+ it('mounts an HTML component', async () => {
7
15
  const container = document.body.appendChild(document.createElement('div'));
8
16
  const mount = jest.fn();
9
17
  const component = { mount };
10
- render(
18
+ await render(
11
19
  <ForeignComponentContainer $component={component} $context={undefined} $portalId="foo" innerProps={{}} />,
12
20
  container,
13
21
  );
@@ -15,28 +23,28 @@ describe('ForeignComponentContainer component', () => {
15
23
  container.remove();
16
24
  });
17
25
 
18
- it('unmounts an HTML component', () => {
26
+ it('unmounts an HTML component', async () => {
19
27
  const container = document.body.appendChild(document.createElement('div'));
20
28
  const mount = jest.fn();
21
29
  const unmount = jest.fn();
22
30
  const component = { mount, unmount };
23
- render(
31
+ const root = await render(
24
32
  <ForeignComponentContainer $component={component} $context={undefined} $portalId="foo" innerProps={{}} />,
25
33
  container,
26
34
  );
27
35
  expect(mount).toHaveBeenCalled();
28
36
  expect(unmount).not.toHaveBeenCalled();
29
- unmountComponentAtNode(container);
37
+ root.unmount();
30
38
  expect(unmount).toHaveBeenCalled();
31
39
  container.remove();
32
40
  });
33
41
 
34
- it('updates an HTML component', () => {
42
+ it('updates an HTML component', async () => {
35
43
  const container = document.body.appendChild(document.createElement('div'));
36
44
  const mount = jest.fn();
37
45
  const update = jest.fn();
38
46
  const component = { mount, update };
39
- render(
47
+ const root = await render(
40
48
  <ForeignComponentContainer
41
49
  $component={component}
42
50
  $context={undefined}
@@ -47,20 +55,20 @@ describe('ForeignComponentContainer component', () => {
47
55
  );
48
56
  expect(mount).toHaveBeenCalled();
49
57
  expect(update).not.toHaveBeenCalled();
50
- render(
58
+ root.render(
51
59
  <ForeignComponentContainer
52
60
  $component={component}
53
61
  $context={undefined}
54
62
  $portalId="foo"
55
63
  innerProps={{ a: 'foo' }}
56
64
  />,
57
- container,
58
65
  );
66
+ await act(() => Promise.resolve());
59
67
  expect(update).toHaveBeenCalled();
60
68
  container.remove();
61
69
  });
62
70
 
63
- it('forces re-rendering of an HTML component', () => {
71
+ it('forces re-rendering of an HTML component', async () => {
64
72
  const container = document.body.appendChild(document.createElement('div'));
65
73
  const componentDidMount = ForeignComponentContainer.prototype.componentDidMount;
66
74
  ForeignComponentContainer.prototype.componentDidMount = function () {
@@ -73,7 +81,7 @@ describe('ForeignComponentContainer component', () => {
73
81
  const update = jest.fn();
74
82
  const unmount = jest.fn();
75
83
  const component = { mount, update, unmount };
76
- render(
84
+ const root = await render(
77
85
  <ForeignComponentContainer
78
86
  $component={component}
79
87
  $context={undefined}
@@ -85,27 +93,27 @@ describe('ForeignComponentContainer component', () => {
85
93
  expect(mount).toHaveBeenCalled();
86
94
  expect(unmount).not.toHaveBeenCalled();
87
95
  expect(update).not.toHaveBeenCalled();
88
- render(
96
+ root.render(
89
97
  <ForeignComponentContainer
90
98
  $component={component}
91
99
  $context={undefined}
92
100
  $portalId="foo"
93
101
  innerProps={{ a: 'foo' }}
94
102
  />,
95
- container,
96
103
  );
104
+ await act(() => Promise.resolve());
97
105
  expect(update).not.toHaveBeenCalled();
98
106
  expect(unmount).toHaveBeenCalled();
99
107
  container.remove();
100
108
  });
101
109
 
102
- it('listens to render-html', () => {
110
+ it('listens to render-html', async () => {
103
111
  const container = document.body.appendChild(document.createElement('div'));
104
112
  const mount = jest.fn();
105
113
  const renderHtmlExtension = jest.fn();
106
114
  const component = { mount };
107
115
  const props = { piral: { renderHtmlExtension }, meta: {} };
108
- render(
116
+ await render(
109
117
  <ForeignComponentContainer $component={component} $context={undefined} $portalId="foo" innerProps={props} />,
110
118
  container,
111
119
  );
@@ -113,6 +121,7 @@ describe('ForeignComponentContainer component', () => {
113
121
  const node = document.querySelector('[data-portal-id=foo]');
114
122
  expect(renderHtmlExtension).not.toHaveBeenCalled();
115
123
  node.dispatchEvent(new CustomEvent('render-html', { detail: {} }));
124
+ await act(() => Promise.resolve());
116
125
  expect(renderHtmlExtension).toHaveBeenCalled();
117
126
  container.remove();
118
127
  });
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { isfunc } from 'piral-base';
3
- import { __RouterContext } from 'react-router';
4
- import { ForeignComponent, BaseComponentProps, ComponentContext } from '../types';
3
+ import type { ForeignComponent, BaseComponentProps, ComponentContext } from '../types';
5
4
 
6
5
  interface ForeignComponentContainerProps<T> {
7
6
  $portalId: string;
@@ -17,45 +17,45 @@ StubErrorInfo.displayName = 'StubErrorInfo';
17
17
  const StubLoader: React.FC = () => <div />;
18
18
  StubLoader.displayName = 'StubLoader';
19
19
 
20
- const StubRouter: React.FC = ({ children }) => <div>{children}</div>;
20
+ const StubRouter: React.FC<React.PropsWithChildren<{}>> = ({ children }) => <div>{children}</div>;
21
21
  StubRouter.displayName = 'StubRouter';
22
22
 
23
- const StubLayout: React.FC = ({ children }) => <div>{children}</div>;
23
+ const StubLayout: React.FC<React.PropsWithChildren<{}>> = ({ children }) => <div>{children}</div>;
24
24
  StubLayout.displayName = 'StubLayout';
25
25
 
26
26
  jest.mock('../hooks');
27
27
  jest.mock('./PiralRoutes');
28
28
 
29
29
  const state = {
30
- app: {
31
- error: undefined,
32
- loading: true,
33
- },
34
- components: {
35
- ErrorInfo: StubErrorInfo,
36
- LoadingIndicator: StubLoader,
37
- Router: StubRouter,
38
- Layout: StubLayout,
39
- },
40
- registry: {
41
- pages: {},
42
- extensions: {},
43
- },
44
- portals: {},
45
- routes: {},
46
- provider: undefined,
30
+ app: {
31
+ error: undefined,
32
+ loading: true,
33
+ },
34
+ components: {
35
+ ErrorInfo: StubErrorInfo,
36
+ LoadingIndicator: StubLoader,
37
+ Router: StubRouter,
38
+ Layout: StubLayout,
39
+ },
40
+ registry: {
41
+ pages: {},
42
+ extensions: {},
43
+ },
44
+ portals: {},
45
+ routes: {},
46
+ provider: undefined,
47
47
  };
48
48
 
49
49
  (hooks as any).useGlobalState = (select: any) => select(state);
50
50
 
51
- (routes as any).PiralRoutes = ({ }) => <StubDashboard />;
51
+ (routes as any).PiralRoutes = ({}) => <StubDashboard />;
52
52
 
53
53
  describe('Portal Module', () => {
54
- it('In this test window should be undefined', () => {
55
- state.app.loading = false;
56
- state.app.error = undefined;
57
- const node = render(<PiralView />);
58
- expect(typeof window).toBe("undefined")
59
- expect(node.length).toBe(1);
60
- });
54
+ it('In this test window should be undefined', () => {
55
+ state.app.loading = false;
56
+ state.app.error = undefined;
57
+ const node = render(<PiralView children={undefined} />);
58
+ expect(typeof window).toBe('undefined');
59
+ expect(node.length).toBe(1);
60
+ });
61
61
  });
@@ -4,7 +4,7 @@ import { PortalRenderer } from './PortalRenderer';
4
4
  import { ForeignComponentContainer } from './ForeignComponentContainer';
5
5
  import { useGlobalStateContext } from '../hooks';
6
6
  import { convertComponent, none } from '../utils';
7
- import { AnyComponent, ComponentConverters, ForeignComponent, PiletApi, BaseComponentProps } from '../types';
7
+ import type { AnyComponent, ComponentConverters, ForeignComponent, PiletApi, BaseComponentProps } from '../types';
8
8
 
9
9
  // this is an arbitrary start number to have 6 digits
10
10
  let portalIdBase = 123456;
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { act } from 'react-dom/test-utils';
3
- import { render } from 'react-dom';
3
+ import { createRoot } from 'react-dom/client';
4
4
  import { useSetter } from './setter';
5
5
 
6
6
  describe('UseSetter Hook Module', () => {
@@ -12,7 +12,8 @@ describe('UseSetter Hook Module', () => {
12
12
  return null;
13
13
  };
14
14
 
15
- render(React.createElement(MyComponent), document.body.appendChild(document.createElement('div')));
15
+ const root = createRoot(document.body.appendChild(document.createElement('div')));
16
+ root.render(React.createElement(MyComponent));
16
17
  await act(() => Promise.resolve());
17
18
  expect(cb).toHaveBeenCalled();
18
19
  });
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import { __RouterContext } from 'react-router';
3
2
  import { ErrorBoundary, wrapComponent } from '../components';
4
3
  import { defaultRender } from '../utils';
5
4
  import { AnyComponent, Errors, PiletApi, BaseComponentProps, GlobalStateContext } from '../types';
package/src/types/api.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ReactElement } from 'react';
1
+ import type { ReactElement, ReactNode } from 'react';
2
2
  import type { RouteComponentProps } from 'react-router';
3
3
  import type {
4
4
  PiletApi,
@@ -46,6 +46,10 @@ export interface ExtensionComponentProps<T> extends BaseComponentProps {
46
46
  * The provided parameters for showing the extension.
47
47
  */
48
48
  params: T extends keyof PiralExtensionSlotMap ? PiralExtensionSlotMap[T] : T extends string ? any : T;
49
+ /**
50
+ * The optional children to receive, if any.
51
+ */
52
+ children?: ReactNode;
49
53
  }
50
54
 
51
55
  /**
@@ -70,6 +74,20 @@ export interface PageComponentProps<T = any, S = any> extends RouteBaseProps<T,
70
74
  meta: PiralPageMeta;
71
75
  }
72
76
 
77
+ /**
78
+ * The meta data registered for a page.
79
+ */
80
+ export interface PiralPageMeta extends PiralCustomPageMeta {}
81
+
82
+ /**
83
+ * Shorthand for the definition of an extension component.
84
+ */
85
+ export type AnyExtensionComponent<TName> = TName extends keyof PiralExtensionSlotMap
86
+ ? AnyComponent<ExtensionComponentProps<TName>>
87
+ : TName extends string
88
+ ? AnyComponent<ExtensionComponentProps<any>>
89
+ : AnyComponent<ExtensionComponentProps<TName>>;
90
+
73
91
  /**
74
92
  * Defines the Pilet API from piral-core.
75
93
  * This interface will be consumed by pilet developers so that their pilet can interact with the piral instance.
@@ -112,7 +130,7 @@ export interface PiletCoreApi {
112
130
  */
113
131
  registerExtension<TName>(
114
132
  name: TName extends string ? TName : string,
115
- Component: AnyComponent<ExtensionComponentProps<TName>>,
133
+ Component: AnyExtensionComponent<TName>,
116
134
  defaults?: Partial<ExtensionParams<TName>>,
117
135
  ): RegistrationDisposer;
118
136
  /**
@@ -123,7 +141,7 @@ export interface PiletCoreApi {
123
141
  */
124
142
  unregisterExtension<TName>(
125
143
  name: TName extends string ? TName : string,
126
- Component: AnyComponent<ExtensionComponentProps<TName>>,
144
+ Component: AnyExtensionComponent<TName>,
127
145
  ): void;
128
146
  /**
129
147
  * React component for displaying extensions for a given name.
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode, ReactElement } from 'react';
2
2
  import type { PiralCustomExtensionSlotMap } from './custom';
3
+ import type { ExtensionRegistration } from './state';
3
4
 
4
5
  /**
5
6
  * The mapping of the existing (known) extension slots.
@@ -19,9 +20,27 @@ export interface BaseExtensionSlotProps<TName, TParams> {
19
20
  * for the specified extension.
20
21
  */
21
22
  empty?(): ReactNode;
23
+ /**
24
+ * Determines if the `render` function should be called in case no
25
+ * components are available for the specified extension.
26
+ *
27
+ * If true, `empty` will be called and returned from the slot.
28
+ * If false, `render` will be called with the result of calling `empty`.
29
+ * The result of calling `render` will then be returned from the slot.
30
+ */
31
+ emptySkipsRender?: boolean;
32
+ /**
33
+ * Defines the order of the components to render.
34
+ * May be more convient than using `render` w.r.t. ordering extensions
35
+ * by their supplied metadata.
36
+ * @param extensions The registered extensions.
37
+ * @returns The ordered extensions.
38
+ */
39
+ order?(extensions: Array<ExtensionRegistration>): Array<ExtensionRegistration>;
22
40
  /**
23
41
  * Defines how the provided nodes should be rendered.
24
42
  * @param nodes The rendered extension nodes.
43
+ * @returns The rendered nodes, i.e., an ReactElement.
25
44
  */
26
45
  render?(nodes: Array<ReactNode>): ReactElement<any, any> | null;
27
46
  /**
@@ -47,6 +47,9 @@ export type WrappedComponent<TProps> = ComponentType<PropsWithChildren<Without<T
47
47
  * The base type for pilet component registration in the global state context.
48
48
  */
49
49
  export interface BaseRegistration {
50
+ /**
51
+ * The pilet registering the component.
52
+ */
50
53
  pilet: string;
51
54
  }
52
55
 
@@ -54,7 +57,13 @@ export interface BaseRegistration {
54
57
  * The interface modeling the registration of a pilet page component.
55
58
  */
56
59
  export interface PageRegistration extends BaseRegistration {
60
+ /**
61
+ * The registered page component.
62
+ */
57
63
  component: WrappedComponent<PageComponentProps>;
64
+ /**
65
+ * The page's associated metadata.
66
+ */
58
67
  meta: PiralPageMeta;
59
68
  }
60
69
 
@@ -62,8 +71,17 @@ export interface PageRegistration extends BaseRegistration {
62
71
  * The interface modeling the registration of a pilet extension component.
63
72
  */
64
73
  export interface ExtensionRegistration extends BaseRegistration {
74
+ /**
75
+ * The wrapped registered extension component.
76
+ */
65
77
  component: WrappedComponent<ExtensionComponentProps<string>>;
78
+ /**
79
+ * The original extension component that has been registered.
80
+ */
66
81
  reference: any;
82
+ /**
83
+ * The default params (i.e., meta) of the extension.
84
+ */
67
85
  defaults: any;
68
86
  }
69
87