UNPKG

vanilla-hamburger

Version:

A tiny framework agnostic hamburger button element for modern web apps

212 lines (156 loc) 8.33 kB
<p align="center"> <a href="https://web-padawan.github.io/vanilla-hamburger/"> <img alt="Preview" src="https://raw.githubusercontent.com/web-padawan/vanilla-hamburger/master/preview.gif" height="80" width="310"> </a> </p> <div align="center"> <a href="https://npmjs.org/package/vanilla-hamburger"> <img alt="npm" src="https://img.shields.io/npm/v/vanilla-hamburger.svg" /> </a> <a href="https://github.com/web-padawan/vanilla-hamburger/actions"> <img alt="build" src="https://github.com/web-padawan/vanilla-hamburger/workflows/tests/badge.svg" /> </a> <a href="https://bundlephobia.com/result?p=vanilla-hamburger"> <img alt="gzip size" src="https://badgen.net/bundlephobia/minzip/vanilla-hamburger" /> </a> </div> <p align="center"> <strong>vanilla-hamburger</strong> is a port of <a href="https://github.com/luukdv/hamburger-react">hamburger-react</a> to vanilla Custom Elements. </p> ## Features - **Small**: Just 1,8 KB (minified and gzipped). [Size Limit](https://github.com/ai/size-limit) controls the size. - **Fast**: Built with standards based Custom Elements. - **Bulletproof**: Written in strict TypeScript and covered by 30+ tests. - **Framework-agnostic**: Can be used [with any framework](https://custom-elements-everywhere.com/). - **Simple**: Uses native `<button>` with a `click` listener internally. - **Accessible**: Follows [WAI-ARIA](https://www.w3.org/TR/wai-aria-practices/#button) guidelines for toggle buttons. - **No dependencies** ## Live demo - [Website](https://web-padawan.github.io/vanilla-hamburger/) - [Angular example](https://components.studio/edit/B6UIy18tBWekjsdlcIzg) - [LitElement example](https://components.studio/edit/MwlJAn0K1B5neVtunpFI) - [React example](https://components.studio/edit/1Cta6NtUgJSSgyOYXB2n) - [Svelte example](https://components.studio/edit/uL3KYNle783i1ehAlXJa) - [Vue example](https://components.studio/edit/rsRiCxbap2Gh0wl3JZJn) ## Installation ``` npm install vanilla-hamburger --save ``` Or use one of the following content delivery networks: [unpkg.com CDN](https://unpkg.com/vanilla-hamburger?module): ```html <script type="module" src="https://unpkg.com/vanilla-hamburger?module"></script> ``` [Skypack CDN](https://cdn.skypack.dev/vanilla-hamburger): ```html <script type="module" src="https://cdn.skypack.dev/vanilla-hamburger"></script> ``` ## Usage ```html <tilt-burger size="lg" label="Menu"></tilt-burger> <script type="module"> import 'vanilla-hamburger'; const burger = document.querySelector('tilt-burger'); burger.addEventListener('pressed-changed', (event) => { const pressed = event.detail.value; }); </script> ``` ## ES modules **vanilla-hamburger** is authored using ES modules which are [natively supported](https://caniuse.com/es6-module) by modern browsers. However, it also uses "bare module imports" which are [not yet standardized](https://github.com/WICG/import-maps) and require a small transform. We recommend the following tools for the ES modules based development: - [`@web/dev-server`](https://modern-web.dev/docs/dev-server/overview/) resolves bare module imports on the fly. - [`snowpack`](https://www.snowpack.dev) performs one-time transform when installing dependencies. - [`@rollup/plugin-node-resolve`](https://github.com/rollup/plugins/tree/master/packages/node-resolve) is needed when using Rollup. None of these tools are needed when importing the component from CDN. ## Available variants **vanilla-hamburger** provides 13 separate elements for different hamburger types. | File to import | HTML element | | --------------------- | ------------------ | | `"cross-burger.js"` | `<cross-burger>` | | `"fade-burger.js"` | `<fade-burger>` | | `"pivot-burger.js"` | `<pivot-burger>` | | `"rotate-burger.js"` | `<rotate-burger>` | | `"slant-burger.js"` | `<slant-burger>` | | `"sling-burger.js"` | `<sling-burger>` | | `"spin-burger.js"` | `<spin-burger>` | | `"spiral-burger.js"` | `<spiral-burger>` | | `"squash-burger.js"` | `<squash-burger>` | | `"squeeze-burger.js"` | `<squeeze-burger>` | | `"tilt-burger.js"` | `<tilt-burger>` | | `"turn-burger.js"` | `<turn-burger>` | | `"twirl-burger.js"` | `<twirl-burger>` | When using one hamburger, ~1.8 KB will be added to your bundle (min + gzip). ## Properties The following properties can be used to customize hamburger elements: | Property | Default | Description | | ----------- | -------------------------- | ------------------------------------------------------- | | `direction` | `left` | The animation direction of the icon, left or right. | | `disabled` | `false` | When set to true, the internal `<button>` id disabled. | | `distance` | `md` | The distance between the lines: `sm`, `md` or `lg`. | | `duration` | `0.4` | The duration of the animation. Can be set to zero. | | `easing` | `cubic-bezier(0, 0, 0, 1)` | A valid `transition-timing-function` CSS value. | | `label` | `hamburger` | Accessible label set on the internal `<button>`. | | `pressed` | `false` | Set to true when element is pressed. | | `size` | `32` | Size of the icon. Should be a number between 12 and 48. | **Note**: `direction` property is not supported by `<squash-burger>` and `<squeeze-burger>`. ## Overriding styles **vanilla-hamburger** exposes [CSS Shadow Parts](https://developer.mozilla.org/en-US/docs/Web/CSS/::part) allowing to override the default styles: ```css cross-burger { color: #999; } cross-burger[pressed] { color: #666; } cross-burger[disabled] { opacity: 0.7; } cross-burger::part(bar) { border-radius: 9em; } cross-burger::part(button) { outline: none; background: currentColor; border-radius: 50%; opacity: 0; transition: opacity 0.5s; } cross-burger::part(button):hover { opacity: 0.12; } cross-burger::part(button):focus { opacity: 0.16; } ``` ## Base classes **vanilla-hamburger** provides a set of base classes that can be imported without registering custom elements. This is useful if you want to create your own hamburger icon with a different tag name. ```js import { Cross } from 'vanilla-hamburger/lib/entrypoints/cross.js'; customElements.define('custom-burger', class extends Cross {}); ``` ## Accessibility It is recommended to have a tap/click area of at least 48x48 pixels. Therefore, padding will be added around the icon to create a surface of exactly this size. Keyboard interaction is provided using native `<button>`, which dispatches the `click` event on <kbd>Enter</kbd> and <kbd>Space</kbd> keys. The underlying native button has `aria-pressed` attribute set based on the `pressed` property. Remember to use `label` property to provide an accessible label for the native button. ## TypeScript support **vanilla-hamburger** supports TypeScript and ships with types in the library itself; no need for any other install. All the included custom elements are compatible with [lit-analyzer](https://www.npmjs.com/package/lit-analyzer) and [lit-plugin](https://marketplace.visualstudio.com/items?itemName=runem.lit-plugin) extension for Visual Studio Code, so you can benefit from type checking in lit-html templates. ## Browser support **vanilla-hamburger** uses [Custom Elements](https://caniuse.com/#feat=custom-elementsv1) and [Shadow DOM](https://caniuse.com/#feat=shadowdomv1), and does not support IE11 or legacy Edge. ## Why vanilla-hamburger? **vanilla-hamburger** has all the benefits of [hamburger-react](https://github.com/luukdv/hamburger-react#yet-another-hamburger-library) with one important difference. While `hamburger-react` does not have direct dependencies, it still expects you to use React. This means that Angular, Vue, Svelte or vanilla JS users would have an **extra** dependency in their apps. Now when all the evergreen browsers support standards based [Custom Elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements), it's perfect time to build such tiny and lightweight UI controls as web components rather than framework components.