{"id":22957338,"url":"https://github.com/daylilyfield/svrollbar","last_synced_at":"2025-05-08T21:12:17.353Z","repository":{"id":40381299,"uuid":"342831346","full_name":"daylilyfield/svrollbar","owner":"daylilyfield","description":"simple custom scrollbar made by svelte","archived":false,"fork":false,"pushed_at":"2024-01-24T07:54:36.000Z","size":7169,"stargazers_count":85,"open_issues_count":15,"forks_count":11,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-08T21:11:29.607Z","etag":null,"topics":["custom-scrollbar","scrollbar","svelte","svelte-component"],"latest_commit_sha":null,"homepage":"https://daylilyfield.github.io/svrollbar/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daylilyfield.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}},"created_at":"2021-02-27T10:39:01.000Z","updated_at":"2025-03-05T02:16:43.000Z","dependencies_parsed_at":"2024-06-18T18:36:44.153Z","dependency_job_id":"0b991392-6e0d-415d-a456-213fd6bf7a1d","html_url":"https://github.com/daylilyfield/svrollbar","commit_stats":{"total_commits":61,"total_committers":1,"mean_commits":61.0,"dds":0.0,"last_synced_commit":"2467de3ae066b108c6d5050de59fa37f29d9f70d"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daylilyfield%2Fsvrollbar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daylilyfield%2Fsvrollbar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daylilyfield%2Fsvrollbar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daylilyfield%2Fsvrollbar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daylilyfield","download_url":"https://codeload.github.com/daylilyfield/svrollbar/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253149617,"owners_count":21861739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["custom-scrollbar","scrollbar","svelte","svelte-component"],"created_at":"2024-12-14T17:16:17.905Z","updated_at":"2025-05-08T21:12:17.295Z","avatar_url":"https://github.com/daylilyfield.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/daylilyfield/svrollbar/main/docs/svrollbar.png\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/daylilyfield/svrollbar/main/docs/svrollbar-default.gif\" /\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/daylilyfield/svrollbar/main/docs/svrollbar-gradation-track.gif\" /\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/daylilyfield/svrollbar/main/docs/svrollbar-crossfade.gif\" /\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/daylilyfield/svrollbar/main/docs/svrollbar-fly.gif\" /\u003e\n\u003c/p\u003e\n\n# svrollbar\n\n[![npm](https://badge.fury.io/js/svrollbar.svg)](https://badge.fury.io/js/svrollbar)\n[![license](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![actions](https://github.com/daylilyfield/svrollbar/workflows/build%20%26%20test/badge.svg)](https://github.com/daylilyfield/svrollbar/actions)\n[![coverall](https://coveralls.io/repos/github/daylilyfield/svrollbar/badge.svg?branch=main)](https://coveralls.io/github/daylilyfield/svrollbar?branch=main)\n\nsvrollbar is the custom scrollbar made by svelte.\n\n- [how to install](#how-to-install)\n- [examples](#examples)\n- [how to use](#how-to-use)\n  - [replace window scrollbar](#replace-window-scrollbar)\n  - [make scrollble area](#make-scrollable-area)\n  - [replace overflow-based scrollbar](#replace-overflow-based-scrollbar)\n  - [integrate 3rd party libraries](#integrate-3rd-party-libraries)\n- [components spec](#components-spec)\n- [how to customize transition](#how-to-customize-transition)\n- [how to customize style](#how-to-customize-style)\n- [how to customize scrollbar visibility](#how-to-customize-scrollbar-visibility)\n\n## how to install\n\n```bash\nnpm install svrollbar\n```\n\n## examples\n\nexample website is [here](https://daylilyfield.github.io/svrollbar/)\n\nexample svelte REPL is [here](https://svelte.dev/repl/d600db3bde4742ec8d9751e009d94159?version=3.35.0).\n\n## how to use\n\nsvrollbar has two components; `Svrollbar.svelte` and `Svroller.svelte`.\nsvrollbar is supposed to use with svelte,\nbut if you want, you can use svrollbar without svelte.\n\n### replace window scrollbar\n\nif you would like to customize your window scrollbar,\nyou simply write down `Svrollbar.svelte` with empty properties,\n\n```svelte\n\u003cSvrollbar /\u003e\n```\n\nthis is equivalent to:\n\n```svelte\n\u003cSvrollbar viewport={document.scrollingElement} contents={document.body} /\u003e\n```\n\nyes, you can see the customized scrollbar on the right side of your browser window.\nplease watch out [example website](https://daylilyfield.github.io/svrollbar/)\nto see the live example.\n\n### make scrollable area\n\nif you try to make scrollable area within a part of your web site,\nyou may prefer to use `Svroller.svelte`.\nthe below example shows you the list which has 50 rows\nin a 10rem x 10rem square scrollable area with the custom scrollbar.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { Svroller } from 'svrollbar'\n\n  const items = Array.from({ length: 50 }).map((_, i) =\u003e `item ${i}`)\n\u003c/script\u003e\n\n\u003cSvroller width=\"10rem\" height=\"10rem\"\u003e\n  {#each items as item (item)}\n    \u003cdiv\u003e{item}\u003c/div\u003e\n  {/each}\n\u003c/Svroller\u003e\n```\n\n### replace overflow-based scrollbar\n\non the other hand, it is better to use `Svrollbar.svelte`\nif you already have a kind of scrollable viewport or contents.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { Svrollbar } from 'svrollbar'\n\n  const items = Array.from({ length: 50 }).map((_, i) =\u003e `item ${i}`)\n\n  export let viewport: Element\n  export let contents: Element\n\u003c/script\u003e\n\n\u003cdiv class=\"wrapper\"\u003e\n  \u003cdiv bind:this={viewport} class=\"viewport\"\u003e\n    \u003cdiv bind:this={contents} class=\"contents\"\u003e\n      {#each items as item (item)}\n        \u003cdiv\u003e{item}\u003c/div\u003e\n      {/each}\n    \u003c/div\u003e\n  \u003c/div\u003e\n  \u003cSvrollbar {viewport} {contents} /\u003e\n\u003c/div\u003e\n\n\u003cstyle\u003e\n  .wrapper {\n    position: relative;\n    width: 10rem;\n  }\n\n  .viewport {\n    position: relative;\n    width: 10rem;\n    height: 10rem;\n    overflow: scroll;\n    border: 1px solid gray;\n    box-sizing: border-box;\n\n    /* hide scrollbar */\n    -ms-overflow-style: none;\n    scrollbar-width: none;\n  }\n\n  .viewport::-webkit-scrollbar {\n    /* hide scrollbar */\n    display: none;\n  }\n\u003c/style\u003e\n```\n\nnotice, you do not need to specify fixed value to width or height of viewport.\nyou can set min-\\*, max-\\*, and any dynamic and reactive value because\nsvrollbar observes both viewport size and its content size by ResizeObserver.\n\n### integrate 3rd party libraries\n\nif you would like to integrate svrollbar into some kind of virtual list\nimplemenation such as\n[svelte-virtual-list](https://github.com/sveltejs/svelte-virtual-list)\nor\n[svelte-tiny-virtual-list](https://github.com/Skayo/svelte-tiny-virtual-list),\nyou can do that in the following way.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { onMount } from 'svelte'\n  import VirtualList from 'svelte-tiny-virtual-list'\n  import { Svrollbar } from 'svrollbar'\n\n  const items = Array.from({ length: 50 }).map((_, i) =\u003e `item ${i}`)\n\n  let viewport: Element\n  let contents: Element\n\n  onMount(() =\u003e {\n    viewport = document.querySelector('.virtual-list-wrapper')\n    contents = document.querySelector('.virtual-list-inner')\n  })\n\u003c/script\u003e\n\n\u003cdiv class=\"wrapper\"\u003e\n  \u003cSvrollbar {viewport} {contents} /\u003e\n  \u003cVirtualList width=\"10rem\" height={160} itemCount={items.length} itemSize={16}\u003e\n    \u003cdiv slot=\"item\" let:index let:style {style}\u003e\n      {items[index]}\n    \u003c/div\u003e\n  \u003c/VirtualList\u003e\n\u003c/div\u003e\n\n\u003cstyle\u003e\n  :global(.virtual-list-wrapper) {\n    /* hide scrollbar */\n    -ms-overflow-style: none !important;\n    scrollbar-width: none !important;\n  }\n\n  :global(.virtual-list-wrapper::-webkit-scrollbar) {\n    /* hide scrollbar */\n    display: none !important;\n  }\n\n  .wrapper {\n    position: relative;\n    width: 10rem;\n  }\n\u003c/style\u003e\n```\n\n## components spec\n\nsee [here](./COMPONENT_INDEX.md).\n\n## how to customize transition\n\nsince the simple fade animation is really a bore,\nyou can replace the default fade (show/hide) animation with your one.\nthe transition function is compatible with the svelte transition.\n\n```svelte\n\u003cscript\u003e\n  import { fly } from 'svelte/transition'\n  import { Svroller } from 'svrollbar'\n\n  const items = Array.from({ length: 50 }).map((_, i) =\u003e `item ${i}`)\n  const flyLeft = (node) =\u003e fly(node, { x: -160 })\n  const flyRight = (node) =\u003e fly(node, { x: 30 })\n\u003c/script\u003e\n\n\u003cSvroller\n  width=\"10rem\"\n  height=\"10rem\"\n  vTrackIn={flyLeft}\n  vTrackOut={flyLeft}\n  vThumbIn={flyRight}\n  vThumbOut={flyRight}\u003e\n  {#each items as item (item)}\n    \u003cdiv\u003e{item}\u003c/div\u003e\n  {/each}\n\u003c/Svroller\u003e\n```\n\n## how to customize style\n\nyou can customize svrollbar style with css variables.\n\n| variable                     | default |\n| ---------------------------- | ------- |\n| --svrollbar-track-width      | 10px    |\n| --svrollbar-track-background | initial |\n| --svrollbar-track-radius     | initial |\n| --svrollbar-track-opacity    | 1       |\n| --svrollbar-track-shadow     | initial |\n| --svrollbar-thumb-width      | 6px     |\n| --svrollbar-thumb-background | gray    |\n| --svrollbar-thumb-radius     | 0.25rem |\n| --svrollbar-thumb-opacity    | 0.5     |\n| --svrollbar-thumb-shadow     | initial |\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { Svroller } from 'svrollbar'\n\n  const items = Array.from({ length: 50 }).map((_, i) =\u003e `item ${i}`)\n\u003c/script\u003e\n\n\u003cdiv class=\"container\"\u003e\n  \u003cSvroller width=\"10rem\" height=\"10rem\"\u003e\n    {#each items as item (item)}\n      \u003cdiv\u003e{item}\u003c/div\u003e\n    {/each}\n  \u003c/Svroller\u003e\n\u003c/div\u003e\n\n\u003cstyle\u003e\n  .container {\n    border: 3px solid #5d7150;\n    width: 10rem;\n\n    --svrollbar-track-width: 20px;\n    --svrollbar-track-background: #85b4b9;\n    --svrollbar-track-opacity: 1;\n\n    --svrollbar-thumb-width: 10px;\n    --svrollbar-thumb-background: #d9ab55;\n    --svrollbar-thumb-opacity: 1;\n  }\n\u003c/style\u003e\n```\n\n## how to customize scrollbar visibility\n\nyou can customize scrollbar visibility with `alwaysVisible` and `initiallyVisible` properties.\n\n| property         | default | description                          |\n| ---------------- | ------- | ------------------------------------ |\n| alwaysVisible    | false   | scrollbar is always visible          |\n| initiallyVisible | false   | scrollbar is visible until scrolling |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaylilyfield%2Fsvrollbar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaylilyfield%2Fsvrollbar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaylilyfield%2Fsvrollbar/lists"}