Skip to content

Commit

Permalink
feat: slot index and tour block
Browse files Browse the repository at this point in the history
  • Loading branch information
VojtechVidra committed Oct 1, 2024
1 parent a72a5c5 commit 58927d3
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 20 deletions.
4 changes: 2 additions & 2 deletions workspaces/react/src/flows-context.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createContext, useContext } from "react";
import { type Block, type Components } from "./types";
import { type TourBlock, type Block, type Components } from "./types";

export interface RunningTour {
block: Block;
currentBlockIndex: number;
setCurrentBlockIndex: (changeFn: (prevIndex: number) => number) => void;
activeStep?: Block;
activeStep?: TourBlock;
}

export interface IFlowsContext {
Expand Down
34 changes: 22 additions & 12 deletions workspaces/react/src/flows-slot.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
import { type FC, type ReactNode } from "react";
import { useMemo, type FC, type ReactNode } from "react";
import { Block } from "./block";
import { useFlowsContext } from "./flows-context";
import { TourBlock } from "./tour-block";
import { type RunningTour, useFlowsContext } from "./flows-context";
import { getSlot } from "./selectors";
import { type Block as IBlock } from "./types";
import { TourBlock } from "./tour-block";

export interface FlowsSlotProps {
id: string;
placeholder?: ReactNode;
}

const isBlock = (item: IBlock | RunningTour): item is IBlock => "type" in item;

const getSlotIndex = (item: IBlock | RunningTour): number => {
if (isBlock(item)) return item.slotIndex ?? 0;
return item.activeStep?.slotIndex ?? 0;
};

export const FlowsSlot: FC<FlowsSlotProps> = ({ id, placeholder }) => {
const { blocks, runningTours } = useFlowsContext();

const slotBlocks = blocks.filter((b) => getSlot(b) === id);
const slotTourBlocks = runningTours.filter((b) => getSlot(b.activeStep) === id);
if (slotBlocks.length || slotTourBlocks.length)
const sortedItems = useMemo(() => {
const slotBlocks = blocks.filter((b) => getSlot(b) === id);
const slotTourBlocks = runningTours.filter((b) => getSlot(b.activeStep) === id);
return [...slotBlocks, ...slotTourBlocks].sort((a, b) => getSlotIndex(a) - getSlotIndex(b));
}, [blocks, id, runningTours]);

if (sortedItems.length)
return (
<>
{slotBlocks.map((block) => (
<Block key={block.id} block={block} />
))}
{slotTourBlocks.map((tour) => (
<TourBlock key={tour.block.id} tour={tour} />
))}
{sortedItems.map((item) => {
if (isBlock(item)) return <Block key={item.id} block={item} />;
return <TourBlock key={item.block.id} tour={item} />;
})}
</>
);

Expand Down
5 changes: 2 additions & 3 deletions workspaces/react/src/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { type Block } from "./types";
import { type TourBlock, type Block } from "./types";

export const getSlot = (block?: Block): string | undefined =>
block?.data.f__slot as string | undefined;
export const getSlot = (block?: Block | TourBlock): string | undefined => block?.slotId;
14 changes: 14 additions & 0 deletions workspaces/react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ export interface Block {
type: string;
data: Record<string, unknown>;
exitNodes: string[];

slotId?: string;
slotIndex?: number;

tourBlocks?: TourBlock[];
}

export interface TourBlock {
id: string;
type: string;
data: Record<string, unknown>;

slotId?: string;
slotIndex?: number;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ignore
Expand Down
5 changes: 2 additions & 3 deletions workspaces/react/src/use-running-tours.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const useRunningTours = (blocks: Block[]): RunningTour[] => {
};

setRunningTours((prev) => {
const tourBlocks = blocks.filter((block) => block.type === "Tour");
const tourBlocks = blocks.filter((block) => block.type === "tour");
const newRunningTours = tourBlocks.map((block): StateItem => {
const currentBlockIndex =
prev.find((tour) => tour.blockId === block.id)?.currentBlockIndex ?? 0;
Expand All @@ -48,8 +48,7 @@ export const useRunningTours = (blocks: Block[]): RunningTour[] => {
.map(({ blockId, currentBlockIndex, setCurrentBlockIndex }): RunningTour | undefined => {
const block = blocks.find((b) => b.id === blockId);
if (!block) return;
const tourBlocks = block.data.blocks as Block[] | undefined;
const activeStep = Array.isArray(tourBlocks) ? tourBlocks[currentBlockIndex] : undefined;
const activeStep = block.tourBlocks?.[currentBlockIndex];
return { currentBlockIndex, setCurrentBlockIndex, activeStep, block };
})
.filter((x): x is RunningTour => Boolean(x)),
Expand Down

0 comments on commit 58927d3

Please sign in to comment.