@bbki.ng/site 5.8.4 → 5.8.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @bbki.ng/site
2
2
 
3
+ ## 5.8.6
4
+
5
+ ### Patch Changes
6
+
7
+ - b578955: add transition to arrow
8
+
9
+ ## 5.8.5
10
+
11
+ ### Patch Changes
12
+
13
+ - 6b14c28: add empty placeholder
14
+
3
15
  ## 5.8.4
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbki.ng/site",
3
- "version": "5.8.4",
3
+ "version": "5.8.6",
4
4
  "description": "code behind bbki.ng",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -3,6 +3,8 @@ import { LinkProps, LinkListProps, LinkList } from '@bbki.ng/ui';
3
3
 
4
4
  import { usePluginEntries } from '#/app/hooks/use_plugin_entries';
5
5
  import { useMiddlewareTransformedData } from '#/core/hooks/useMiddlewareTransData';
6
+ import { Slot } from '#/core/components/SlotComp';
7
+ import { useGlobalLoading } from '#/app/hooks/use_global_loading';
6
8
 
7
9
  const CenterLinkList = (props: LinkListProps) => {
8
10
  return (
@@ -29,9 +31,13 @@ export const Cover = (_: { className?: string }) => {
29
31
  entries
30
32
  ) as Array<LinkProps>;
31
33
 
34
+ const { isLoading } = useGlobalLoading();
35
+ const hasEntries = pluginEntries.length > 1 && !isLoading;
36
+
32
37
  return (
33
38
  <>
34
39
  <CenterLinkList className="select-none" links={transformedEntries} />
40
+ <Slot name="centerEntryArea" data={hasEntries} />
35
41
  </>
36
42
  );
37
43
  };
@@ -1,10 +1,12 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useEffect, useMemo, useState } from 'react';
2
2
 
3
3
  import { SystemUIService } from '#/core/plugin-system/services/systemUIService';
4
4
  import { IPluginEntry } from '#/types/plugin';
5
5
 
6
6
  const protectedRoutesSet = new Set<string>(['/bot', '/', 'default']);
7
7
 
8
+ const emptyEntries: Array<IPluginEntry> = [];
9
+
8
10
  export const usePluginEntries = () => {
9
11
  const [entries, setEntries] = useState<Array<IPluginEntry>>(() =>
10
12
  SystemUIService.getInstance().getPluginEntries()
@@ -23,7 +25,10 @@ export const usePluginEntries = () => {
23
25
  };
24
26
  }, []);
25
27
 
26
- const safeEntries = entries?.filter(entry => !protectedRoutesSet.has(entry.path));
28
+ const safeEntries = useMemo(
29
+ () => entries?.filter(entry => !protectedRoutesSet.has(entry.path)),
30
+ [entries]
31
+ );
27
32
 
28
- return safeEntries ?? [];
33
+ return safeEntries ?? emptyEntries;
29
34
  };
@@ -43,13 +43,23 @@ export const usePlugins = () => {
43
43
 
44
44
  const installedPlugins = PluginStore.getInstance().getInstalledPlugins();
45
45
 
46
+ const { setGlobalLoading } = useGlobalLoading();
47
+
46
48
  const pluginIds: Array<PluginID> = useMemo(
47
- () => ['store', ...Array.from(installedPlugins)],
49
+ () => [...Array.from(installedPlugins), 'store'],
48
50
  [installedPlugins]
49
51
  );
50
52
 
51
53
  usePluginsLoading();
52
54
 
55
+ useEffect(() => {
56
+ const unregister = setGlobalLoading('plugins', !done);
57
+
58
+ return () => {
59
+ unregister();
60
+ };
61
+ }, [done, setGlobalLoading]);
62
+
53
63
  useEffect(() => {
54
64
  let cancelled = false;
55
65
 
@@ -38,7 +38,13 @@ export interface IBaseUIService<T extends string, K extends string> {
38
38
  runMiddlewares: <S>(point: K, data: S) => Promise<S>;
39
39
  }
40
40
 
41
- export type SystemSlotName = 'leftCol' | 'rightCol' | 'logo' | 'pageFooter' | 'nav-right';
41
+ export type SystemSlotName =
42
+ | 'leftCol'
43
+ | 'rightCol'
44
+ | 'logo'
45
+ | 'pageFooter'
46
+ | 'nav-right'
47
+ | 'centerEntryArea';
42
48
 
43
49
  export type SystemDataHookPoint = 'transformBreadcrumbPath' | 'transformEntryLink';
44
50
 
@@ -0,0 +1,34 @@
1
+ import { FC, useEffect, useState } from 'react';
2
+
3
+ import { IComPropsRegisteredToSlot } from '#/types/slots';
4
+
5
+ import { ArrowSvg } from './ArrowSvg';
6
+
7
+ export const ArrowCom: FC<IComPropsRegisteredToSlot> = ({ data }) => {
8
+ const hasEntry = data as boolean;
9
+
10
+ const [visible, setVisible] = useState(false);
11
+
12
+ useEffect(() => {
13
+ // Delay one frame so the initial opacity:0 is painted first
14
+ const raf = requestAnimationFrame(() => setVisible(true));
15
+ return () => cancelAnimationFrame(raf);
16
+ }, []);
17
+
18
+ if (hasEntry) {
19
+ return null;
20
+ }
21
+
22
+ // transition from opacity 0 to 1 when hasEntry changes from true to false
23
+
24
+ return (
25
+ <div
26
+ style={{
27
+ opacity: visible ? 1 : 0,
28
+ transition: 'opacity 1s ease-in',
29
+ }}
30
+ >
31
+ <ArrowSvg />
32
+ </div>
33
+ );
34
+ };