React Broadcast Channel Demo ✨
This is a demo page for the @nayaabh/react-broadcast-channel library. Open this page in multiple tabs or windows to see how messages are broadcasted between them.
How It Works
Steps to use the demo:
- Pop out this window in a new tab.
- Enter a message and choose a color for the message.
- Click on the "Publish" button to broadcast the message.
- The message will be displayed in all open windows or tabs, based on the color selected.
 See @nayaabh/react-broadcast-channel demo in action
See @nayaabh/react-broadcast-channel demo in actionCode
Sample code for above example
🔴🟡🟢
demo-code.jsx
"use client";
import { Box, Button, ListItem, ListItemText, Paper, TextField, Typography, useTheme } from "@mui/material";
import { useBroadcastState } from "@nayaabh/react-broadcast-channel";
import { useCallback, useEffect, useState } from "react";
import { FixedSizeList, ListChildComponentProps } from "react-window";
const CHANNEL_NAME = "BroadcastChannel-001";
type MessageType = {
  message: string;
  color: string;
  timeStamp: string;
};
export const BroadcastSandbox = () => {
  const [message, setMessage] = useBroadcastState<MessageType>(CHANNEL_NAME);
  const [logs, setLogs] = useState<MessageType[]>([]);
  const theme = useTheme();
  const onPublish = useCallback((e: any) => {
    e.preventDefault();
    const data = new FormData(e.target);
    const text = data.get("message") as string;
    const color = data.get("color") as string;
    const dateTime = getTimestamp();
    setMessage({ message: text, color, timeStamp: dateTime });
  }, []);
  useEffect(() => {
    if (message) {
      setLogs((logs) => [message, ...logs]);
    }
  }, [message]);
  return (
    <>
      <Box
        component="form"
        onSubmit={onPublish}
        sx={{
          display: "flex",
          flexDirection: "row",
          gap: 2,
          marginBlock: 2,
        }}
      >
        <TextField
          name="message"
          variant="outlined"
          label="Enter a message"
          size="small"
          sx={{
            flexGrow: 1,
          }}
          slotProps={{
            htmlInput: {
              maxLength: 100,
            },
          }}
        />
        <Box
          component={"input"}
          type="color"
          name="color"
          defaultValue={theme.palette.grey[500]}
          sx={{
            alignSelf: "center",
          }}
        />
        <Button type="submit" variant="contained" color="primary">
          Publish
        </Button>
      </Box>
      <Paper
        variant="outlined"
        sx={{
          width: "100%",
          padding: 1,
        }}
      >
        <FixedSizeList height={200} width="100%" itemSize={32} itemCount={logs.length} overscanCount={5}>
          {(props: ListChildComponentProps) => {
            const { index, style } = props;
            const { message, timeStamp, color } = logs[index] || {};
            const log = `${timeStamp} - ${message}`;
            return (
              <ListItem style={style} id={index} component="div" disablePadding dense>
                <ListItemText
                  primary={
                    <Typography variant="caption" sx={{ color }}>
                      {log}
                    </Typography>
                  }
                />
              </ListItem>
            );
          }}
        </FixedSizeList>
      </Paper>
    </>
  );
};
function getTimestamp() {
  const date = new Date();
  const year = date.getFullYear();
  const month = `${date.getMonth() + 1}`.padStart(2, "0");
  const day = `${date.getDate()}`.padStart(2, "0");
  const hour = `${date.getHours()}`.padStart(2, "0");
  const minute = `${date.getMinutes()}`.padStart(2, "0");
  const second = `${date.getSeconds()}`.padStart(2, "0");
  const millisecond = `${date.getMilliseconds()}`.padStart(2, "0");
  return `${year}-${month}-${day} ${hour}:${minute}:${second}.${millisecond}`;
}