{"id":42703765,"url":"https://github.com/tarobits/shelf-rendering-engine","last_synced_at":"2026-01-29T14:25:10.744Z","repository":{"id":332267797,"uuid":"1132188374","full_name":"tarobits/shelf-rendering-engine","owner":"tarobits","description":"A highly flexible rendering engine for virtual shelves, inventories, and catalog-like UIs, designed for Vue.js and powered by strict TypeScript models.","archived":false,"fork":false,"pushed_at":"2026-01-13T04:49:10.000Z","size":70,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T07:51:22.468Z","etag":null,"topics":["catalog","early-development","experimental","inventory","library","rendering","typescript","ui","virtual-shelf","visualization","vue","vuejs"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tarobits.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-11T13:56:04.000Z","updated_at":"2026-01-13T04:49:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tarobits/shelf-rendering-engine","commit_stats":null,"previous_names":["tarobits/shelf-rendering-engine"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/tarobits/shelf-rendering-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarobits%2Fshelf-rendering-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarobits%2Fshelf-rendering-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarobits%2Fshelf-rendering-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarobits%2Fshelf-rendering-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tarobits","download_url":"https://codeload.github.com/tarobits/shelf-rendering-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarobits%2Fshelf-rendering-engine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28879452,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-29T10:31:27.438Z","status":"ssl_error","status_checked_at":"2026-01-29T10:31:01.017Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["catalog","early-development","experimental","inventory","library","rendering","typescript","ui","virtual-shelf","visualization","vue","vuejs"],"created_at":"2026-01-29T14:25:10.686Z","updated_at":"2026-01-29T14:25:10.739Z","avatar_url":"https://github.com/tarobits.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shelf Rendering Engine\n\n![License](https://img.shields.io/badge/license-MPL--2.0-blue)\n![Version](https://img.shields.io/badge/version-v0.1.5-orange)\n\nA highly flexible rendering engine for virtual shelves, inventories, and catalog-like UIs, designed for Vue.js and powered by strict TypeScript models.\n\n\u003e [!WARNING]\n\u003e This is an early development release and currently not meant for production environments.\n\u003e All configuration options are subject to change at any point.\n\n## Installation\n\nJust run the following command in your project to install the engine.\n\n```sh\nnpm install @tarobits/shelf-rendering-engine\n```\n\nThen add the following two lines to the imports in the file you wish to use the engine:\n\n```ts\nimport '@tarobits/shelf-rendering-engine/style.css';\nimport { RenderableShelf, Shelf, type ShelfType, type ViewableShelf } from '@tarobits/shelf-rendering-engine';\n```\n\n## Usage\n\nTo create a shelf:\n\n```ts\nRenderableShelf.getShelfFromProps(shelfConfig).exportToViewable();\n```\n\n`shelfConfig` refers to an object matching the `ShelfType` type.\n\nOr\n\n```ts\nRenderableShelf.getShelfFromProps(shelfDataConfig, shelfSizesConfig).exportToViewable();\n```\n\n`shelfDataConfig` and `shelfSizesConfig` refer to objects matching the `ShelfData` and `ShelfSizes` types respectively.\n\n`getShelfFromProps` accepts either a full `ShelfType` object or a combination of `ShelfData` and `ShelfSizes` and returns a render-ready representation.\n\n`exportToViewable` converts the class into a reactive class Vue can work with.\n\n## Minimal Example\n\n```ts\nconst shelf = RenderableShelf.getShelfFromProps({\n    innerWidth: 100,\n    innerHeight: 50,\n    backgroundColor: '#eee',\n    outerColor: '#333',\n    topWidth: 3,\n    bottomWidth: 3,\n    leftWidth: 3,\n    rightWidth: 3,\n    model: []\n}).exportToViewable();\n```\n\n## Data Types\n\n\u003e [!NOTE]\n\u003e All widths and heights are relational. You may use centimeters, inches, or any other form of measurement.\n\u003e They will all be converted into pixels on rendering.\n\n### Main Types\n\n\u003cdetails\u003e\n\u003csummary\u003eShelfType\u003c/summary\u003e\n\n```ts\n\n{\n  title: string, // (Optional) if you want a title to be displayed above your shelf\n  subtitle: string, // (Optional) if you want a smaller text displayed below the title\n  innerWidth: number, // (Required) how wide the shelf is from inner wall to inner wall\n  innerHeight: number, // (Required) how tall the shelf is from inner bottom to inner top\n  location: EntityLocation[], // (Optional) defines where the shelf is located (Purely meta data)\n  backgroundColor: string, // (Required) what color to display in the background (Accepted: Any css color or an object with [r: 0-255, g: 0-255, b: 0-255])\n  outerColor: string, // (Required) what color the shelf walls etc. are (Accepted: Any css color or an object with [r: 0-255, g: 0-255, b: 0-255])\n  topWidth: number, // (Required) width of the top part of the shelf casing (0 if no top part exists)\n  bottomWidth: number, // (Required) width of the bottom part of the shelf casing (0 if no bottom part exists)\n  leftWidth: number, // (Required) width of the left part of the shelf casing (0 if no left part exists)\n  rightWidth: number, // (Required) width of the right part of the shelf casing (0 if no right part exists)\n  model: ShelfSection[] // (Required) an array of the shelf sections this shelf should contain.\n}\n```\n\n\u003c/details\u003e\n\n\u003e [!NOTE]\n\u003e For shelf sections you can also use percentages for the height and width related to the shelf.\n\n\u003e [!WARNING]\n\u003e For shelf sections bottom.width and wall.width will count towards the absolute size of the shelf section.\n\n\u003cdetails\u003e\n\u003csummary\u003eShelfSection\u003c/summary\u003e\n\n```ts\n{\n    width: number | string, // (Required) Width of the shelf section (Inner part)\n    height: number | string, // (Required) Height of the shelf section (Inner part)\n    x: number, // (Optional) If given the shelf will be at the given position inside the row. If left undefined, the section will be sorted at random\n    y: number, // (Optional) If given the shelf will be inside the given row. If left undefined, the section will be sorted at random\n    sortBooksInverted: boolean, // (Optional) If true the books will be sorted from right to left inside that section. Undefined or false will sort the books from left to right\n    bottom: { // (Required) Section base definition\n        width: number, // (Required) determines the thickness of the section base.\n        color: string // (Optional) Color of the section base. If left undefined it will assume the value of the property outerColor of the parent shelf. (Accepted: Any css color or an object with [r: 0-255, g: 0-255, b: 0-255])\n    }\n    wall: { // (Optional) Section separation wall\n        position: 'left' | 'right', // (Required) defines whether the wall will be rendered on the left or the right side of the section\n        color: string, // (Optional) defines the color of the separation wall. If undefined it will assume the value of outerColor of the parent shelf (Accepted: Any css color or an object with [r: 0-255, g: 0-255, b: 0-255])\n        width: number // (Required) defines how thick the wall is going to be\n    }\n    items: ShelfItem[] // (Required) an array of the shelf items this section contains\n}\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eShelfItem\u003c/summary\u003e\n\n```ts\n{\n    expandable: boolean, // (Required) determines whether the shelf item can be clicked on to display additional information\n    width: number, // (Required) defines the width of the given item\n    height: number, // (Required) defines the height of the given item\n    depth: number, // (Required if expandable is true) defines the depth of the item when the detail view is opened\n    frontView: FrontShelfView, // (Required) defines the view as it is displayed inside the shelf\n    title: string, // (Required) defines the name of the item [Is displayed on the frontView if its type is \"color\" and it has not been disabled]\n    subtitle: string, // (Optional) defines the subtitle of the item [Is displayed on the frontView if its type is \"color\" and it has not been disabled]\n    description: string, // (Optional) defines the description of the item\n    positionInRow: number, // (Optional) defines the position of the shelf item inside the section. If undefined the item will be sorted at random\n    identificationCode: IdentificationCode[], // (Optional) defines the identification codes of the item (e.g. ISBN, Asset-ID, etc.)\n    location: EntityLocation[], // (Optional) defines where the item is located (Purely meta data)\n    availability: 'unlimited' | 'limited', // (Required) defines the availability of the item. If unlimited the item cannot be \"out of stock\"\n    count: number, // (Required if availability is \"limited\") defines the number of available items\n    sideView: SideShelfView, // (Required if expandable is true) defines the view as it is displayed when clicked on\n}\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eFrontShelfView\u003c/summary\u003e\n\nIf you wish you item to be displayed as a colored \"block\" use the following\n\n```ts\n{\n    type: 'color', // (Required) defines that the color view type should be used\n    color: string, // (Required) defines the color that the item should be displayed as (Accepted: Any css color or an object with [r: 0-255, g: 0-255, b: 0-255]) \n    exclude: { // (Optional) determines whether to display certain information on that cover\n        title: boolean, // (Optional) determines whether the title should be rendered on the view\n        subtitle: boolean // (Optional) determines whether the subtitle should be rendered on the view\n    }\n}\n```\n\nIf you wish for the item to be displayed with an image use the following\n\n```ts\n{\n    type: 'image', // (Required) defines that the image view type should be used\n    url: string // (Required) defines the url of the image to display\n}\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eSideShelfView\u003c/summary\u003e\n\nIf you wish you item to be displayed as a colored \"block\" use the following\n\n```ts\n{\n    type: 'color', // (Required) defines that the color view type should be used\n    color: string, // (Required) defines the color that the item should be displayed as (Accepted: Any css color or an object with [r: 0-255, g: 0-255, b: 0-255]) \n    exclude: { // (Optional) determines whether to display certain information on that cover\n        title: boolean, // (Optional) determines whether the title should be rendered on the view\n        subtitle: boolean // (Optional) determines whether the subtitle should be rendered on the view\n    },\n    sideView: { // (Optional) defines how the sideView should be rendered\n        style: { // (Optional) if you wish to change the display styles of the given properties\n            background: DisplayStyle, // (Optional) if you wish to change the display background\n            title: DisplayStyle, // (Optional) if you wish to change how the title is displayed\n            subtitle: DisplayStyle, // (Optional) if you wish to change how the subtitle is displayed\n            description: DisplayStyle, // (Optional) if you wish to change how the description is displayed\n            location: Record\u003cstring, {\n                key: DisplayStyle, // (Optional) if you wish to change how the key is displayed for this location\n                value: DisplayStyle // (Optional) if you wish to change how the value is displayed for this location\n            }\u003e | {\n                key: DisplayStyle, // (Optional) if you wish to change how the key is displayed for all locations\n                value: DisplayStyle // (Optional) if you wish to change how the value is displayed for all locations\n            }, // (Optional) if you wish to change how all the locations are displayed or how specific locations are displayed. [This setting will override the individual location configuration]\n            identificationCode: Record\u003cstring, {\n                name: DisplayStyle, // (Optional) if you wish to change how the name is displayed for this identification code\n                value: DisplayStyle // (Optional) if you wish to change how the value is displayed for this identification code\n            }\u003e | {\n                name: DisplayStyle, // (Optional) if you wish to change how the name is displayed for all identification codes\n                value: DisplayStyle // (Optional) if you wish to change how the value is displayed for all identification codes\n            } // (Optional) if you wish to change how all the identification codes are displayed or how specific identification codes are displayed.\n        },\n        exclude: { // (Optional) if you wish to exclude specific properties from rendering\n            title: boolean, // (Optional) determines whether to render the title of the book [On the sideView]\n            subtitle: boolean, // (Optional) determines whether to render the subtitle of the book [On the sideView]\n            description: boolean, // (Optional) determines whether to render the description of the book\n            location: boolean, // (Optional) determines whether to render the location of the item\n            identificationCode: boolean | Array\u003cstring\u003e // (Optional) determines whether to render identification codes at all or if specific ones should be excluded\n        }\n    }\n}\n```\n\nIf you wish for the item to be displayed with an image use the following\n\n```ts\n{\n    type: 'image', // (Required) defines that the image view type should be used\n    url: string, // (Required) defines the url of the image to display\n    sideView: { // (Optional) defines how the sideView should be rendered\n        style: { // (Optional) if you wish to change the display styles of the given properties\n            background: DisplayStyle, // (Optional) if you wish to change the display background\n            title: DisplayStyle, // (Optional) if you wish to change how the title is displayed\n            subtitle: DisplayStyle, // (Optional) if you wish to change how the subtitle is displayed\n            description: DisplayStyle, // (Optional) if you wish to change how the description is displayed\n            location: Record\u003cstring, {\n                key: DisplayStyle, // (Optional) if you wish to change how the key is displayed for this location\n                value: DisplayStyle // (Optional) if you wish to change how the value is displayed for this location\n            }\u003e | {\n                key: DisplayStyle, // (Optional) if you wish to change how the key is displayed for all locations\n                value: DisplayStyle // (Optional) if you wish to change how the value is displayed for all locations\n            }, // (Optional) if you wish to change how all the locations are displayed or how specific locations are displayed. [This setting will override the individual location configuration]\n            identificationCode: Record\u003cstring, {\n                name: DisplayStyle, // (Optional) if you wish to change how the name is displayed for this identification code\n                value: DisplayStyle // (Optional) if you wish to change how the value is displayed for this identification code\n            }\u003e | {\n                name: DisplayStyle, // (Optional) if you wish to change how the name is displayed for all identification codes\n                value: DisplayStyle // (Optional) if you wish to change how the value is displayed for all identification codes\n            } // (Optional) if you wish to change how all the identification codes are displayed or how specific identification codes are displayed.\n        },\n        exclude: { // (Optional) if you wish to exclude specific properties from rendering\n            title: boolean, // (Optional) determines whether to render the title of the book [On the sideView]\n            subtitle: boolean, // (Optional) determines whether to render the subtitle of the book [On the sideView]\n            description: boolean, // (Optional) determines whether to render the description of the book\n            location: boolean, // (Optional) determines whether to render the location of the item\n            identificationCode: boolean | Array\u003cstring\u003e // (Optional) determines whether to render identification codes at all or if specific ones should be excluded\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eDisplayStyle\u003c/summary\u003e\n\n```ts\n{\n    color: string, // (Optional) if you wish to change the color of the given property (Accepted: Any css color or an object with [r: 0-255, g: 0-255, b: 0-255])\n    fontWeight: number, // (Optional) if you wish to change the fontWeight of the given property\n    classes: Array\u003cstring\u003e // (Optional) if you wish to apply specific CSS classes to the given property\n}\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eEntityLocation\u003c/summary\u003e\n\nDisplay:\n{key}: {value}\n\nExample:\nShelf: 7\nRow: 5\n\n```ts\n{\n    key: string, // (Required) defines the location key\n    value: string, // (Required) defines the value of the location\n    order: number, // (Required) defines the order the location is displayed in\n    style: { // (Optional) if you wish to change how this location is displayed\n        key: DisplayStyle, // (Optional) if you wish to change how the key is displayed\n        value: DisplayStyle // (Optional) if you wish to change how the value is displayed\n    }\n}\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eIdentificationCode\u003c/summary\u003e\n\nDisplay:\n{name or display_name}: {value}\nor if value is an array\n{name or display_name}: {value[0]}\n{name or display_name}: {value[1]}\n...\n\n```ts\n{\n    name: string, // (Required) defines the name of the location (Can also be used in the sideView exclude)\n    display_name: string, // (Optional) if you wish to change the name that is displayed\n    order: number, // (Optional) defines the order in which to display the identification codes\n    value: string | Array\u003cstring\u003e // (Required) can be a single string or an array of strings and defines the values of the given identification code\n}\n```\n\n\u003c/details\u003e\n\n### Other Types\n\n\u003cdetails\u003e\n\u003csummary\u003eShelfData\u003c/summary\u003e\n\n```ts\n\n{\n  title: string, // (Optional) if you want a title to be displayed above your shelf\n  subtitle: string, // (Optional) if you want a smaller text displayed below the title\n  location: EntityLocation[], // (Optional) defines where the shelf is located (Purely meta data)\n  backgroundColor: string, // (Required) what color to display in the background (Accepted: Any css color or an object with [r: 0-255, g: 0-255, b: 0-255])\n  outerColor: string, // (Required) what color the shelf walls etc. are (Accepted: Any css color or an object with [r: 0-255, g: 0-255, b: 0-255])\n  model: ShelfSection[] // (Required) an array of the shelf sections this shelf should contain.\n}\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eShelfSizes\u003c/summary\u003e\n\nIf you wish to use ShelfSizes you have to add `getShelfSizes` to the imports.\n\n```ts\ngetShelfSizes(\n    innerHeight: number,\n    innerWidth: number,\n    tbWidth: number,\n    lrWidth: number\n);\n\ngetShelfSizes(\n    innerHeight: number,\n    innerWidth: number,\n    topWidth: number,\n    bottomWidth: number,\n    rightWidth: number,\n    leftWidth: number\n);\n\ngetShelfSizes(\n    innerHeight: number,\n    innerWidth: number,\n    totalHeight: number,\n    totalWidth: number\n);\n\ngetShelfSizes(\n    totalHeight: number,\n    totalWidth: number,\n    tbWidth: number,\n    lrWidth: number\n);\n\ngetShelfSizes(\n    totalHeight: number,\n    totalWidth: number,\n    topWidth: number,\n    bottomWidth: number,\n    leftWidth: number,\n    rightWidth: number\n);\n\n```\n\n\u003c/details\u003e\n\n## License\n\nCopyright © 2026 Tarobits\nLicensed under the Mozilla Public License 2.0 (MPL-2.0).\nSee [https://mozilla.org/MPL/2.0/](https://mozilla.org/MPL/2.0/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarobits%2Fshelf-rendering-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftarobits%2Fshelf-rendering-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarobits%2Fshelf-rendering-engine/lists"}