{"_id":"@carl0zen/planby","_rev":"1-24c72adbeba9164fbf42ac14c1a9697c","name":"@carl0zen/planby","dist-tags":{"latest":"1.1.5"},"versions":{"1.1.4":{"name":"@carl0zen/planby","author":{"name":"Karol Kozer"},"version":"1.1.4","license":"MIT","repository":{"type":"git","url":"git+https://github.com/karolkozer/planby.git"},"homepage":"https://planby.netlify.app","funding":{"type":"opencollective","url":"https://opencollective.com/planby"},"main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"tsdx watch","build":"tsdx build","test":"tsdx test --passWithNoTests","lint":"tsdx lint","prepare":"tsdx build && bundlewatch","size":"bundlewatch","test:watch":"jest --watchAll"},"peerDependencies":{"react":">=16"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"prettier":{"printWidth":80,"semi":true,"singleQuote":true,"trailingComma":"es5"},"module":"dist/planby.esm.js","bundlewatch":{"files":[{"path":"dist/planby.cjs.production.min.js","maxSize":"30kB"},{"path":"dist/planby.esm.js","maxSize":"30kB"}]},"dependencies":{"@emotion/react":"^11.9.0","@emotion/styled":"^11.8.1","date-fns":"^2.28.0","use-debounce":"^7.0.1"},"keywords":["epg","schedule","harmongram","react","hooks","electronic","program","guide","timeline","events"],"devDependencies":{"@faker-js/faker":"^6.1.2","@size-limit/preset-small-lib":"^7.0.8","@types/jest":"^27.4.0","@types/react":"^17.0.38","bundlewatch":"^0.3.3","husky":"^7.0.4","jest":"^27.5.1","size-limit":"^7.0.8","ts-jest":"^27.1.3","tsdx":"^0.14.1","tslib":"^2.3.1","typescript":"^4.6.3"},"_id":"@carl0zen/planby@1.1.4","gitHead":"f8fc399523d78b1f76ce4f7eb73aa0825a0237df","description":"<div align=\"center\" style=\"margin-bottom: 10px\">   <a href=\"https://www.npmjs.com/package/planby\">     <img src=\"https://i.postimg.cc/J0XMPHNQ/planby-logo.png\" alt=\"Planby logo\" />   </a> </div>","bugs":{"url":"https://github.com/karolkozer/planby/issues"},"_nodeVersion":"20.6.1","_npmVersion":"9.8.1","dist":{"integrity":"sha512-K+jFHBdqjjfRu6Wa7Pm5UvKxTyKD+UW/57mZH+UE852sOiPDjgsOkO2sVO5dIuJJeDfP4Ba0/kFcPShGpCXvdg==","shasum":"47a7e071ff807c69a529a7a485c05c2cab03ffc1","tarball":"https://registry.npmjs.org/@carl0zen/planby/-/planby-1.1.4.tgz","fileCount":108,"unpackedSize":694072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCibqqMBCqH4Y7Mx3L0lxdf6X6QAFCBDC0V0T0KjV1tIQIgW5q44bJdSq1vaoxyghNZ6+wgfN+EFmizXRdi7cM3iUQ="}]},"_npmUser":{"name":"carl0zen","email":"carl0zen@proton.me"},"directories":{},"maintainers":[{"name":"carl0zen","email":"carl0zen@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/planby_1.1.4_1695840470191_0.2653619445013522"},"_hasShrinkwrap":false},"1.1.5":{"name":"@carl0zen/planby","author":{"name":"Karol Kozer"},"version":"1.1.5","license":"MIT","repository":{"type":"git","url":"https://github.com/karolkozer/planby"},"homepage":"https://planby.netlify.app/","funding":{"type":"opencollective","url":"https://opencollective.com/planby"},"main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"tsdx watch","build":"tsdx build","test":"tsdx test --passWithNoTests","lint":"tsdx lint","prepare":"tsdx build && bundlewatch","size":"bundlewatch","test:watch":"jest --watchAll"},"peerDependencies":{"react":">=16"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"prettier":{"printWidth":80,"semi":true,"singleQuote":true,"trailingComma":"es5"},"module":"dist/planby.esm.js","bundlewatch":{"files":[{"path":"dist/planby.cjs.production.min.js","maxSize":"30kB"},{"path":"dist/planby.esm.js","maxSize":"30kB"}]},"dependencies":{"@emotion/react":"^11.9.0","@emotion/styled":"^11.8.1","date-fns":"^2.28.0","use-debounce":"^7.0.1"},"keywords":["epg","schedule","harmongram","react","hooks","electronic","program","guide","timeline","events"],"devDependencies":{"@faker-js/faker":"^6.1.2","@size-limit/preset-small-lib":"^7.0.8","@types/jest":"^27.4.0","@types/react":"^17.0.38","bundlewatch":"^0.3.3","husky":"^7.0.4","jest":"^27.5.1","size-limit":"^7.0.8","ts-jest":"^27.1.3","tsdx":"^0.14.1","tslib":"^2.3.1","typescript":"^4.6.3"},"description":"Planby is a React based component for a quick implementation of Epg, schedules, live streaming, music events, timelines and many more ideas. It uses a custom virtual view which allows you to operate on a really big number of data. The component has a simp","licenseText":"MIT License\n\nCopyright (c) 2022 Karol Kozer\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","_id":"@carl0zen/planby@1.1.5","dist":{"shasum":"daec781f9780789352ed7f6ddac6b30051aff9bf","integrity":"sha512-LZPaOn08Pit7QSDOsFWVZHwNyfH9Hr/DmG9nv3QQE9obwGYRAQJmELiBFN+JIcpblwYR6nlxDxGymgzDg56WFQ==","tarball":"https://registry.npmjs.org/@carl0zen/planby/-/planby-1.1.5.tgz","fileCount":133,"unpackedSize":693403,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDjUVkvyporCxtyQ+ULS3h8dcsTU97O1grpuH3UTLP6wQIhAOS7xyasXL3qJRV9k75csOvFJUF63P9Pvt4ydBv2E3s1"}]},"_npmUser":{"name":"carl0zen","email":"carl0zen@proton.me"},"directories":{},"maintainers":[{"name":"carl0zen","email":"carl0zen@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/planby_1.1.5_1695931808743_0.5335829636480287"},"_hasShrinkwrap":false}},"time":{"created":"2023-09-27T18:47:50.113Z","1.1.4":"2023-09-27T18:47:50.457Z","modified":"2023-09-28T20:10:09.223Z","1.1.5":"2023-09-28T20:10:09.073Z"},"maintainers":[{"name":"carl0zen","email":"carl0zen@proton.me"}],"description":"Planby is a React based component for a quick implementation of Epg, schedules, live streaming, music events, timelines and many more ideas. It uses a custom virtual view which allows you to operate on a really big number of data. The component has a simp","homepage":"https://planby.netlify.app/","keywords":["epg","schedule","harmongram","react","hooks","electronic","program","guide","timeline","events"],"repository":{"type":"git","url":"https://github.com/karolkozer/planby"},"author":{"name":"Karol Kozer"},"license":"MIT","readme":"<div align=\"center\" style=\"margin-bottom: 10px\">\n  <a href=\"https://www.npmjs.com/package/planby\">\n    <img src=\"https://i.postimg.cc/J0XMPHNQ/planby-logo.png\" alt=\"Planby logo\" />\n  </a>\n</div>\n\n<div align=\"center\" style=\"margin-bottom: 20px\">\n  <a href=\"https://www.npmjs.com/package/planby\">\n    <img alt=\"npm\" src=\"https://img.shields.io/npm/v/planby\" />\n  </a>\n  <a href=\"https://npmjs.org/package/planby\">\n    <img alt=\"downloads\" src=\"https://badgen.net/npm/dm/planby\" />\n  </a>\n  <a href=\"https://npmjs.org/package/planby\">\n    <img alt=\"downloads\" src=\"https://img.shields.io/npm/dt/planby?color=%2327ae60&label=recent%20downloads\" />\n  </a> \n <a href=\"https://opencollective.com/planby#sponsor\"  target=\"_blank\"><img src=\"https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg\" alt=\"Support us\"></a>\n</div>\n\n## Description\n\nPlanby is a React based component for a quick implementation of Epg, schedules, live streaming, music events, timelines and many more ideas. It uses a custom virtual view which allows you to operate on a really big number of data. The component has a simple API that you can easily integrate with other third party UI libraries. The component theme is customised to the needs of the application design.\n\n<div align=\"center\" style=\"margin-bottom: 10px\">\n  <a href=\"https://planby.netlify.app/\">\n    <img src=\"https://i.postimg.cc/6p2GDGMX/tv-preview-custom.png\" alt=\"Planby preview\" />\n  </a>\n</div>\n<div align=\"center\" style=\"margin-bottom: 10px\">\n  <a href=\"https://planby.netlify.app/\">\n    <img src=\"https://i.postimg.cc/s2Pn9jGZ/planby-conf-event.png\" alt=\"Planby preview\" />\n  </a>\n</div>\n<div align=\"center\" style=\"margin-bottom: 10px\">\n  <a href=\"https://planby.netlify.app/\">\n    <img src=\"https://raw.githubusercontent.com/karolkozer/planby-demo-resources/master/planby-planner-week.png\" alt=\"Planby preview\" />\n  </a>\n</div>\n<div align=\"center\" style=\"margin-bottom: 10px\">\n  <a href=\"https://planby.netlify.app/\">\n    <img src=\"https://i.postimg.cc/50qZ05ST/planby-music-festival-event.png\" alt=\"Planby preview\" />\n  </a>\n</div>\n\n## Codesandbox example\n\n[Live example - Codesandbox](https://codesandbox.io/s/5o3tsy)\n\n[Live example - Typescript Codesandbox](https://codesandbox.io/s/planby-epg-demo-ts-lp66v5)\n\n[Live example - website with control panel](https://planby.netlify.app/)\n\n## Testimonials\n\n<div align=\"center\" >\n  <a href=\"https://planby.netlify.app/#testimonials\">\n    <img src=\"https://raw.githubusercontent.com/karolkozer/planby-demo-resources/master/they-use-planby.png\" alt=\"Planby preview\" />\n  </a>\n</div>\n<div align=\"center\" style=\"margin-bottom: 10px\">\n  <a href=\"https://planby.netlify.app/#testimonials\">\n    <img src=\"https://raw.githubusercontent.com/karolkozer/planby-demo-resources/master/testimonials.png\" alt=\"Planby preview\" />\n  </a>\n</div>\n\n## 🚀 [Become a Sponsor!](https://opencollective.com/planby) 🚀\n\nBecome a Sponsor and get exclusive access to Planby features and updates -> [GitHub Sponsors](https://github.com/sponsors/karolkozer)\n\n- Exclusive repository access 🚀\n- Exclusive content\n- New features\n- Updates\n- Support\n\n## Getting Started\n\n### Installation\n\n- yarn\n\n```sh\nyarn add planby\n```\n\n- npm\n\n```sh\nnpm install planby\n```\n\n## Usage\n\n```tsx\nimport { useEpg, Epg, Layout } from 'planby';\n\nconst channels = React.useMemo(\n  () => [\n    {\n      logo: 'https://via.placeholder.com',\n      uuid: '10339a4b-7c48-40ab-abad-f3bcaf95d9fa',\n      ...\n    },\n  ],\n  []\n);\n\nconst epg = React.useMemo(\n  () => [\n    {\n      channelUuid: '30f5ff1c-1346-480a-8047-a999dd908c1e',\n      description:\n        'Ut anim nisi consequat minim deserunt...',\n      id: 'b67ccaa3-3dd2-4121-8256-33dbddc7f0e6',\n      image: 'https://via.placeholder.com',\n      since: \"2022-02-02T23:50:00\",\n      till: \"2022-02-02T00:55:00\",\n      title: 'Title',\n      ...\n    },\n  ],\n  []\n);\n\nconst {\n  getEpgProps,\n  getLayoutProps,\n  onScrollToNow,\n  onScrollLeft,\n  onScrollRight,\n} = useEpg({\n  epg,\n  channels,\n  startDate: '2022/02/02', // or 2022-02-02T00:00:00\n});\n\nreturn (\n  <div>\n    <div style={{ height: '600px', width: '1200px' }}>\n      <Epg {...getEpgProps()}>\n        <Layout\n          {...getLayoutProps()}\n        />\n      </Epg>\n    </div>\n  </div>\n);\n```\n\nor\n\n#### Custom width and height\n\n```tsx\nconst {\n  getEpgProps,\n  getLayoutProps,\n  ...\n} = useEpg({\n  epg,\n  channels,\n startDate: '2022/02/02', // or 2022-02-02T00:00:00\n  width: 1200,\n  height: 600\n});\n\nreturn (\n  <div>\n     <Epg {...getEpgProps()}>\n        <Layout\n          {...getLayoutProps()}\n        />\n      </Epg>\n  </div>\n\n```\n\nor\n\n#### Time range\n\n```tsx\nconst {\n  getEpgProps,\n  getLayoutProps,\n  ...\n} = useEpg({\n  epg,\n  channels,\n  startDate: '2022-02-02T10:00:00',\n  endDate: '2022-02-02T20:00:00',\n  width: 1200,\n  height: 600\n});\n\nreturn (\n  <div>\n     <Epg {...getEpgProps()}>\n        <Layout\n          {...getLayoutProps()}\n        />\n      </Epg>\n  </div>\n\n```\n\n## API\n\n### useEpg\n\n#### Options\n\nAvailable options in useEpg\n\n| Property                  | Type                              | Status   | Description                                                                                                                                                                                                   | Access     |\n| ------------------------- | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |\n| `channels`                | `array`                           | required | Array with channels data                                                                                                                                                                                      |\n| `epg`                     | `array`                           | required | Array with epg data                                                                                                                                                                                           |\n| `width`                   | `number`                          | optional | Epg width                                                                                                                                                                                                     |\n| `height`                  | `number`                          | optional | Epg height                                                                                                                                                                                                    |\n| `sidebarWidth`            | `number`                          | optional | Width of the sidebar with channels                                                                                                                                                                            |\n| `timelineHeight`          | `number`                          | optional | Height of the timeline                                                                                                                                                                                        | `Sponsors` |\n| `itemHeight`              | `number`                          | optional | Height of channels and programs in the EPG. Default value is 80                                                                                                                                               |\n| `dayWidth`                | `number`                          | optional | Width of the day. Default value is 7200. Calculation to set up day width with own hour width value eg. 24h \\* 300px(your custom hour width) = 7200px -> dayWidth                                              |\n| `startDate`               | `string`                          | optional | Date format `2022/02/02` or `2022-02-02T00:00:00`. You can set your own start time eg. `2022-02-02T10:00:00`, `2022-02-02T14:00:00` etc. Full clock hours only.                                               |\n| `endDate`                 | `string`                          | optional | Date format `2022-02-02T00:00:00`. , `2022-02-02T:20:00` etc. Must be within the same 24-hour period as startDate. Full clock hours only. Scroll through `multiple days` is available only in `Sponsors` plan |\n| `hoursInDays`             | `array`                           | optional | Set start time and end time of each day in multiple days feature if you data for each day has some time spaces between items in the day.                                                                      | `Sponsors` |\n| `initialScrollPositions:` | `object`                          | optional | Set initial scroll position in Layout eg. `initialScrollPositions:{top: 500, left:800}`                                                                                                                       | `Sponsors` |\n| `liveRefreshTime`         | `number`                          | optional | Live refresh time of the events. Default value is 120 sec.                                                                                                                                                    | `Sponsors` |\n| `isBaseTimeFormat`        | `boolean`                         | optional | Convert to 12 hours format eg. `2:00am, 4:00pm` etc. Default value is false.                                                                                                                                  |\n| `isCurrentTime`           | `boolean`                         | optional | Show current time in Timeline. Default value is false.                                                                                                                                                        | `Sponsors` |\n| `isInitialScrollToNow`    | `boolean`                         | optional | Scroll to the current live element.                                                                                                                                                                           | `Sponsors` |\n| `isVerticalMode`          | `boolean`                         | optional | Show Timeline in vertical view. Default value is false.                                                                                                                                                       | `Sponsors` |\n| `isSidebar`               | `boolean`                         | optional | Show/hide sidebar                                                                                                                                                                                             |\n| `isTimeline`              | `boolean`                         | optional | Show/hide timeline                                                                                                                                                                                            |\n| `isLine`                  | `boolean`                         | optional | Show/hide line                                                                                                                                                                                                |\n| `isRTL`                   | `boolean`                         | optional | Change direction to RTL or LTR. Default value is false                                                                                                                                                        |\n| `theme`                   | `object`                          | optional | Object with theme schema                                                                                                                                                                                      |\n| `areas`                   | `array`                           | optional | Area gives possibilities to add field ranges to the Timeline layout.                                                                                                                                          | `Sponsors` |\n| `mode`                    | `{ type: string, style: string }` | optional | Type values: `day/week/month`. Style values: `default/modern` Define the mode and style of the timeline. Default mode is `day` and style is `default`                                                         | `Sponsors` |\n| `channelMapKey`           | `string`                          | optional | The Channel `uuid` attribute can be controlled by prop. Key map gives a possibilities to use specific prop from own data instead of needing to map to uuid in own data                                        | `Sponsors` |\n| `programChannelMapKey`    | `string`                          | optional | The Programs `channelUuid` attributes can be controlled by prop. Key map gives a possibilities to use a specific prop from own data instead of needing to map to channelUuid in your data                     | `Sponsors` |\n| `globalStyles`            | `string`                          | optional | Inject custom global styles and font. Font weight: 400,500,600. Default font is \"Inter\"                                                                                                                       | `Sponsors` |\n\n#### Note about width and height props\n\nWithout declaring the `width` and `length` properties, the component takes the dimensions of the parent element.\n\n#### globalStyles\n\nInject own custom font and other global styles.\n\n```tsx\nconst globalStyles = `\n  @import url(\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap\");\n\n/* Available in sponsors plan */\n .planby {\n  font-family: \"Inter\", system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica,\n    Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\";\n\n  /* Layout */\n  .planby-layout {}\n\n  /* Line */\n  .planby-line {}\n\n  /* Current time */\n  .planby-current-time {}\n  .planby-current-content {}\n\n  /* Channels */\n  .planby-channels {}\n\n  /* Channel */\n  .planby-channel {}\n\n  /* Program */\n  .planby-program {}\n  .planby-program-content {}\n  .planby-program-flex {}\n  .planby-program-stack {}\n  .planby-program-title {}\n  .planby-program-text {}\n\n  /* Timeline */\n  .planby-timeline-wrapper {}\n  .planby-timeline-box {}\n  .planby-timeline-time {}\n  .planby-timeline-dividers {}\n  .planby-timeline-wrapper {}\n}\n  \n`;\n```\n\n#### Instance Properties\n\nProperties returned from useEpg\n\n| Property        | Type                      | Description                          |\n| --------------- | ------------------------- | ------------------------------------ |\n| `scrollY`       | `number`                  | Current scroll y value               |\n| `scrollX`       | `number`                  | Current scroll x value               |\n| `onScrollLeft`  | `function(value: number)` | Default value is 300                 |\n| `onScrollRight` | `function(value: number)` | Default value is 300                 |\n| `onScrollToNow` | `function()`              | Scroll to current time/live programs |\n| `onScrollTop`   | `function(value: number)` | Default value is 300                 |\n\n### Channel schema\n\n| Property | Type     | Status   |\n| -------- | -------- | -------- |\n| `logo`   | `string` | required |\n| `uuid`   | `string` | required |\n\n### Epg schema\n\n| Property          | Type      | Status   | Description                                                          | Access   |\n| ----------------- | --------- | -------- | -------------------------------------------------------------------- | -------- |\n| `channelUuid`     | `string`  | required |\n| `id`              | `string`  | required |\n| `image`           | `string`  | required |\n| `since`           | `string`  | required |\n| `till`            | `string`  | required |\n| `title`           | `string`  | required |\n| `fixedVisibility` | `boolean` | optional | The element is always visible in the layout during the scroll events | Sponsors |\n\n### Epg\n\n#### Base props\n\nAvailable props in Epg\n\n| Property    | Type        | Description              | Status   |\n| ----------- | ----------- | ------------------------ | -------- |\n| `isLoading` | `boolean`   | Loader state             | optional |\n| `loader`    | `Component` | Loader custom cpomponent | optional |\n\n### Layout\n\n#### Base props\n\nAvailable props in Layout.\n\n| Property            | Type                                                                                  | Description                                                                                                     | Status   | Access     |\n| ------------------- | ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | -------- | ---------- |\n| `renderProgram`     | `function({ program: { data: object, position: object})`                              | `data` object contains all properties related to the program, `position` object includes all position styles    | optional |\n| `renderChannel`     | `function({ channel: { ..., position: object})`                                       | `channel` object contains all properties related to the channel, `position` object includes all position styles | optional |\n| `renderTimeline`    | `function({sidebarWidth: number})`                                                    | `sidebarWidth` value of the channel's sidebar width                                                             | optional |\n| `renderLine`        | `function({styles: object})`                                                          | basic `styles` and `position` values for the custom live tracking Line                                          | optional | `Sponsors` |\n| `renderCurrentTime` | `function({styles: object, isRTL: boolean, isBaseTimeFormat: boolean, time: string})` | basic `styles` values for the custom current time                                                               | optional | `Sponsors` |\n\n# Render functions\n\nYou can use Plaby's style components to develop main features. Moreover, you can integrate with third party UI library eg. Chakra UI, Material UI etc or make custom styles.\n\n## renderProgram\n\nBelow is an example that allows you to render your custom Program component using Plaby's style components.\n\n```tsx\nimport {\n  useEpg,\n  Epg,\n  Layout,\n  ProgramBox,\n  ProgramContent,\n  ProgramFlex,\n  ProgramStack,\n  ProgramTitle,\n  ProgramText,\n  ProgramImage,\n  useProgram,\n  Program,\n  ProgramItem\n} from \"planby\";\n\n\nconst Item = ({ program,...rest }: ProgramItem) => {\n  const { styles, formatTime, isLive, isMinWidth } = useProgram({ program,...rest });\n\n  const { data } = program;\n  const { image, title, since, till } = data;\n\n  const sinceTime = formatTime(since);\n  const tillTime = formatTime(till);\n\n  return (\n    <ProgramBox width={styles.width} style={styles.position}>\n      <ProgramContent\n        width={styles.width}\n        isLive={isLive}\n      >\n        <ProgramFlex>\n          {isLive && isMinWidth && <ProgramImage src={image} alt=\"Preview\" />}\n          <ProgramStack>\n            <ProgramTitle>{title}</ProgramTitle>\n            <ProgramText>\n              {sinceTime} - {tillTime}\n            </ProgramText>\n          </ProgramStack>\n        </ProgramFlex>\n      </ProgramContent>\n    </ProgramBox>\n  );\n};\n\nfunction App() {\n\n  ...\n\n const {\n  getEpgProps,\n  getLayoutProps,\n} = useEpg({\n  epg,\n  channels,\n  startDate: '2022/02/02', // or 2022-02-02T00:00:00\n});\n\nreturn (\n  <div>\n    <div style={{ height: '600px', width: '1200px' }}>\n      <Epg {...getEpgProps()}>\n        <Layout\n            {...getLayoutProps()}\n            renderProgram={({ program,...rest }) => (\n              <Item key={program.data.id} program={program} {...rest} />\n            )}\n          />\n      </Epg>\n    </div>\n  </div>\n);\n}\n\nexport default App;\n```\n\n## renderProgram - 12 hours time format\n\nBelow is an example that allows you to render your custom Program component with 12 hours time format using Plaby's style components.\n\n```tsx\n...\nconst Item = ({ program, ...rest }: ProgramItem) => {\n  const {\n    styles,\n    formatTime,\n    set12HoursTimeFormat,\n    isLive,\n    isMinWidth,\n  } = useProgram({\n    program,\n    ...rest\n  });\n\n  const { data } = program;\n  const { image, title, since, till } = data;\n\n  const sinceTime = formatTime(since, set12HoursTimeFormat()).toLowerCase();\n  const tillTime = formatTime(till, set12HoursTimeFormat()).toLowerCase();\n\n  return (\n    <ProgramBox width={styles.width} style={styles.position}>\n      <ProgramContent\n        width={styles.width}\n        isLive={isLive}\n      >\n        <ProgramFlex>\n          {isLive && isMinWidth && <ProgramImage src={image} alt=\"Preview\" />}\n          <ProgramStack>\n            <ProgramTitle>{title}</ProgramTitle>\n            <ProgramText>\n              {sinceTime} - {tillTime}\n            </ProgramText>\n          </ProgramStack>\n        </ProgramFlex>\n      </ProgramContent>\n    </ProgramBox>\n  );\n};\n\nfunction App() {\n\n  ...\n\n const {\n  getEpgProps,\n  getLayoutProps,\n} = useEpg({\n  epg,\n  channels,\n  isBaseTimeFormat: true,\n  startDate: '2022/02/02', // or 2022-02-02T00:00:00\n});\n\n...\n}\n\nexport default App;\n```\n\n## renderProgram - RTL direction\n\nBelow is an example that allows you to render your custom Program component with RTL direction using Plaby's style components.\n\n```tsx\n...\nconst Item = ({ program, ...rest }: ProgramItem) => {\n  const {\n    isRTL,\n    isLive,\n    isMinWidth,\n    formatTime,\n    styles,\n    set12HoursTimeFormat,\n    getRTLSinceTime,\n    getRTLTillTime,\n  } = useProgram({\n    program,\n    ...rest\n  });\n\n  const { data } = program;\n  const { image, title, since, till } = data;\n\n  const sinceTime = formatTime(\n    getRTLSinceTime(since),\n    set12HoursTimeFormat()\n  ).toLowerCase();\n  const tillTime = formatTime(\n    getRTLTillTime(till),\n    set12HoursTimeFormat()\n  ).toLowerCase();\n\n  return (\n    <ProgramBox width={styles.width} style={styles.position}>\n      <ProgramContent width={styles.width} isLive={isLive}>\n        <ProgramFlex>\n          {isLive && isMinWidth && <ProgramImage src={image} alt=\"Preview\" />}\n          <ProgramStack isRTL={isRTL}>\n            <ProgramTitle>{title}</ProgramTitle>\n            <ProgramText>\n              {sinceTime} - {tillTime}\n            </ProgramText>\n          </ProgramStack>\n        </ProgramFlex>\n      </ProgramContent>\n    </ProgramBox>\n  );\n};\n\nfunction App() {\n\n  ...\n\n const {\n  getEpgProps,\n  getLayoutProps,\n} = useEpg({\n  epg,\n  channels,\n  isBaseTimeFormat: true,\n  startDate: '2022/02/02', // or 2022-02-02T00:00:00\n});\n\n...\n}\n\nexport default App;\n```\n\n## renderChannel\n\nBelow is an example that allows you to render your custom Channel component using Plaby's style components.\n\n```tsx\nimport { useEpg, Epg, Layout, ChannelBox, ChannelLogo, Channel } from 'planby';\n\ninterface ChannelItemProps {\n  channel: Channel;\n}\n\nconst ChannelItem = ({ channel }: ChannelItemProps) => {\n  const { position, logo } = channel;\n  return (\n    <ChannelBox {...position}>\n      <ChannelLogo\n        onClick={() => console.log('channel', channel)}\n        src={logo}\n        alt=\"Logo\"\n      />\n    </ChannelBox>\n  );\n};\n\n\nfunction App() {\n\n  ...\n\n  const {\n    getEpgProps,\n    getLayoutProps,\n  } = useEpg({\n    epg,\n    channels,\n    startDate: '2022/02/02', // or 2022-02-02T00:00:00\n  });\n\n  return (\n    <div>\n      <div style={{ height: '600px', width: '1200px' }}>\n        <Epg {...getEpgProps()}>\n          <Layout\n              {...getLayoutProps()}\n              renderChannel={({ channel }) => (\n              <ChannelItem key={channel.uuid} channel={channel} />\n            )}\n            />\n        </Epg>\n      </div>\n    </div>\n  );\n}\n\n```\n\n## renderTimeline\n\nBelow is an example that allows you to render your custom Timeline component using Plaby's style components.\n\n```tsx\nimport {\n  TimelineWrapper,\n  TimelineBox,\n  TimelineTime,\n  TimelineDivider,\n  TimelineDividers,\n  useTimeline,\n} from 'planby';\n\ninterface TimelineProps {\n  isBaseTimeFormat: boolean;\n  isSidebar: boolean;\n  dayWidth: number;\n  hourWidth: number;\n  numberOfHoursInDay: number;\n  offsetStartHoursRange: number;\n  sidebarWidth: number;\n}\n\nexport function Timeline({\n  isBaseTimeFormat,\n  isSidebar,\n  dayWidth,\n  hourWidth,\n  numberOfHoursInDay,\n  offsetStartHoursRange,\n  sidebarWidth,\n}: TimelineProps) {\n  const { time, dividers, formatTime } = useTimeline(\n    numberOfHoursInDay,\n    isBaseTimeFormat\n  );\n\n  const renderTime = (index: number) => (\n    <TimelineBox key={index} width={hourWidth}>\n      <TimelineTime>\n        {formatTime(index + offsetStartHoursRange).toLowerCase()}\n      </TimelineTime>\n      <TimelineDividers>{renderDividers()}</TimelineDividers>\n    </TimelineBox>\n  );\n\n  const renderDividers = () =>\n    dividers.map((_, index) => (\n      <TimelineDivider key={index} width={hourWidth} />\n    ));\n\n  return (\n    <TimelineWrapper\n      dayWidth={dayWidth}\n      sidebarWidth={sidebarWidth}\n      isSidebar={isSidebar}\n    >\n      {time.map((_, index) => renderTime(index))}\n    </TimelineWrapper>\n  );\n}\n\nfunction App() {\n\n  ...\n\n  const {\n    getEpgProps,\n    getLayoutProps,\n  } = useEpg({\n    epg,\n    channels,\n    startDate: '2022/02/02', // or 2022-02-02T00:00:00\n  });\n\n  return (\n    <div>\n      <div style={{ height: '600px', width: '1200px' }}>\n        <Epg {...getEpgProps()}>\n          <Layout\n              {...getLayoutProps()}\n              renderTimeline={(props) => <Timeline {...props} />}\n            />\n        </Epg>\n      </div>\n    </div>\n  );\n}\n\nexport default App;\n```\n\n## renderTimeline - RTL direction\n\nBelow is an example that allows you to render your custom Timeline component using Plaby's style components.\n\n```tsx\nimport {\n  TimelineWrapper,\n  TimelineBox,\n  TimelineTime,\n  TimelineDivider,\n  TimelineDividers,\n  useTimeline,\n} from 'planby';\n\ninterface TimelineProps {\n  isRTL: boolean;\n  isBaseTimeFormat: boolean;\n  isSidebar: boolean;\n  dayWidth: number;\n  hourWidth: number;\n  numberOfHoursInDay: number;\n  offsetStartHoursRange: number;\n  sidebarWidth: number;\n}\n\nexport function Timeline({\n  isRTL,\n  isBaseTimeFormat,\n  isSidebar,\n  dayWidth,\n  hourWidth,\n  numberOfHoursInDay,\n  offsetStartHoursRange,\n  sidebarWidth,\n}: TimelineProps) {\n  const { time, dividers, formatTime } = useTimeline(\n    numberOfHoursInDay,\n    isBaseTimeFormat\n  );\n\n  const renderTime = (index: number) => (\n    <TimelineBox key={index} width={hourWidth}>\n      <TimelineTime isBaseTimeFormat={isBaseTimeFormat} isRTL={isRTL}>\n        {formatTime(index + offsetStartHoursRange).toLowerCase()}\n      </TimelineTime>\n      <TimelineDividers>{renderDividers()}</TimelineDividers>\n    </TimelineBox>\n  );\n\n ...\n}\n\n```\n\n## Theme\n\n### Schema\n\nMake your theme custom. Below is theme schema that you can pass as one of the options to `useEpg` hook.\n\n```jsx\nconst theme = {\n  primary: {\n    600: '#1a202c',\n    900: '#171923',\n  },\n  grey: { 300: '#d1d1d1' },\n  white: '#fff',\n  green: {\n    300: '#2C7A7B',\n  },\n  loader: {\n    teal: '#5DDADB',\n    purple: '#3437A2',\n    pink: '#F78EB6',\n    bg: '#171923db',\n  },\n  scrollbar: {\n    border: '#ffffff',\n    thumb: {\n      bg: '#e1e1e1',\n    },\n  },\n  gradient: {\n    blue: {\n      300: '#002eb3',\n      600: '#002360',\n      900: '#051937',\n    },\n  },\n  text: {\n    grey: {\n      300: '#a0aec0',\n      500: '#718096',\n    },\n  },\n  timeline: {\n    divider: {\n      bg: '#718096',\n    },\n  },\n};\n```\n\n## All import options\n\n```tsx\nimport {\n  Epg,\n  Layout,\n  ChannelBox,\n  ChannelLogo,\n  ProgramBox,\n  ProgramContent,\n  ProgramFlex,\n  ProgramStack,\n  ProgramTitle,\n  ProgramText,\n  ProgramImage,\n  TimelineWrapper,\n  TimelineBox,\n  TimelineTime,\n  TimelineDividers,\n  useEpg,\n  useProgram,\n  useTimeline,\n  Program, // Interface\n  Channel, // Interface\n  ProgramItem, // Interface for program render\n  Theme, // Interface\n} from 'planby';\n```\n\n## License\n\nDistributed under the MIT License. See `LICENSE` for more information.\n\n## Contact\n\nKarol Kozer - [@kozerkarol_twitter](https://twitter.com/kozerkarol)\n\nProject Link: [https://github.com/karolkozer/planby](https://github.com/karolkozer/planby)\n","readmeFilename":"README.md"}