A react menu that inspired by KFC menu and functions like it. this package works in conjunction with react-tabs-scrollable , so in order to use this package you have to install react-tabs-scrollable to use its tabs in the menu.
I took the idea while I was exlporing the KFC menu on their website and I liked the idea and I thought it's practical and simple and it can be used on restaurants and cafes menu.
npm install --save react-kfc-menu
yarn add react-kfc-menu
I'm using a fixed indicator div inside the blocks' container so I can indicate if a block is overlaping the indicator so I can determine where in the page is the selected block located passed on that indicator. When you click on a tab the page will scroll to that indicator position + the current position of that block.
import React from "react";
import { Tabs, Tab } from "react-tabs-scrollable";
import { Menu, MenuBlock } from "react-kfc-menu";
import "react-tabs-scrollable/dist/rts.css";
function App() {
const [activeTab, setActiveTab] = React.useState(10);
// define a onClick function to bind the value on tab click
const menuRef = useRef < any > null;
const onTabClick = (e, index) => {
setActiveTab(index);
menuRef.current?.scrollSelectedToBlock(index);
};
const onBlockIntersection = (index) => {
setActiveTab(index);
};
return (
<>
<div className="sticky-top bg-light">
<div className="containr">
<Tabs activeTab={activeTab} onTabClick={onTabClick}>
{/* generating an array to loop through it */}
{[...Array(20).keys()].map((item) => (
<Tab key={item}>Tab {item}</Tab>
))}
</Tabs>
</div>
</div>
<div className="row mx-auto justify-content-center">
<div className="col-md-12">
<Menu
onBlockIntersection={onBlockIntersection}
activeBlock={activeTab}
action={menuRef}
>
{[...Array(20).keys()].map((item) => (
<MenuBlock key={item}>
<div className="display-4">Block {item}</div>{" "}
<div className="row">
{[...Array(8).keys()].map((card) => (
<div key={card} className="col-md-3 my-2">
<div className="card">
<div className="card-body">
{card} Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Modi deleniti natus voluptates
doloribus voluptate voluptas ab eum dolorem asperiores
sequi consequatur magnam architecto iure sed tempora,
doloremque nam? Nesciunt, ad!
<button className="btn btn-primary d-block w-100 mt-2">
order
</button>
</div>
</div>
</div>
))}
</div>
</MenuBlock>
))}
</Menu>
</div>
</div>
</>
);
}
export default App;
Name | Default | Type | Description |
activeBlock* |
- | integer | the selected block value which must be passed to the commponent, and it's the same as activeTab state (I'm using it just to know what is the initial state of the block so I can scroll to it on the first mount) |
onBlockIntersection* |
- | function | function(event, value) => void callback function fires on block intersection.
When you scroll to a certain block this function fires. It has two props, the first one is the event object of window.onscroll function the second one is the intersected block index |
action* |
- | ref | react ref fires when the component mounts. you must use it in order to use the scrollSelectedToBlock function inside onTabClick function and pass the index to it in order to scroll to the block when you click the tabs: ref.current.scrollSelectedToBlock(index)
|
containerClassName |
- | string | sets the container className of the blocks |
indicatorClassName |
- | string | sets the indicator className |
indicatorTopPostion |
80 | integer | sets the top position of the indicator. Note : the indicator is the point where the page's scroll will stop, where a certain block overlaps with the indicator, the onBlockIntersection will trigger, so by changing the top position of it, you can control where the page will land and where the onBlockIntersection will trigger. |
showIndicator |
false | indicator | if you want to show the indicator so you can know where it's exactly located in the page so you can customize its position |
scrollBahavior |
"instant" | string | the bahavior of window.scrollTo() function that I use it to scroll to the selected block. default instant but you can change it to "auto" or "smooth" |
Name | Default | Type | Description |
className |
- | string | sets the className of MenuBlocks container div |
{...props} |
- | object | I'm usign props spread operator so basically you can use anything |
Please let me see your reviews and if there're any features you want me to add to them
If you liked this project consider buying me a coffe
MIT © Mohammed Aliwi