generated from lit/lit-element-starter-js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cdn support, dedup, and doc clarifications
- Loading branch information
1 parent
8fbfd24
commit ef54475
Showing
6 changed files
with
266 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,6 +59,24 @@ class MyPagedThing extends LitElement { | |
customElements.define('my-paged-thing', MyPagedThing); | ||
``` | ||
|
||
If you're using Shoelace in your own project and you want to avoid loading two different copies, import like this: | ||
|
||
```js | ||
import '@shoelace-style/shoelace/dist/components/switch/switch.js'; | ||
import '@shoelace-style/shoelace/dist/components/icon/icon.js'; | ||
import '@lalomartins/shoestring-pagination/shoestring-pagination.js'; | ||
``` | ||
|
||
Otherwise, if you _want_ to use the bundled Shoelace, do this somewhere in your project (just once): | ||
|
||
```js | ||
import {setBasePath} '@lalomartins/shoestring-pagination'; | ||
// … | ||
setBasePath("node_modules/@lalomartins/shoestring-pagination/node_modules/@shoelace-style/shoelace/dist/"); | ||
``` | ||
|
||
(You can also use CDNed Shoelace if you prefer.) | ||
|
||
## API | ||
|
||
Attributes: | ||
|
@@ -83,6 +101,29 @@ npm i @lalomartins/shoestring-pagination | |
|
||
You don't need to import Shoelace on your own code if you're not using it, but you _do_ need to load your own CSS, whether it's from CDN, or from `node_modules`, or copying it into your build. You can check the [Shoelace install instructions](https://shoelace.style/getting-started/installation) for details. | ||
|
||
## CDN | ||
|
||
```html | ||
<link | ||
rel="stylesheet" | ||
href="https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/themes/light.css" | ||
/> | ||
<link | ||
rel="stylesheet" | ||
href="https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/themes/dark.css" | ||
/> | ||
<script | ||
type="module" | ||
src="https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/shoelace-autoloader.js" | ||
></script> | ||
<script | ||
type="module" | ||
src="https://cdn.jsdelivr.net/npm/@lalomartins/[email protected]/cdn/shoestring-pagination.js" | ||
></script> | ||
``` | ||
|
||
If the arrows don't show up, tweak your import order to make sure you have the Shoelace base path set before Pagination loads. | ||
|
||
## Screenshots | ||
|
||
![Light mode](./docs/Screen%20Shot%202023-12-24%20at%2019.34.27.png) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
/** | ||
* @license | ||
* Copyright 2032 Lalo Martins | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
import { | ||
LitElement, | ||
css, | ||
html, | ||
} from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm'; | ||
|
||
/** | ||
* A web component for pagination that uses Shoelace buttons for consistent UI. | ||
* | ||
* @element shoestring-pagination | ||
* | ||
* @dependency sl-button | ||
* @dependency sl-icon-button | ||
* @dependency sl-visually-hidden | ||
* | ||
* @attr {Number} current - The current page | ||
* @attr {Number} total - Total number of items | ||
* @attr {Number} [page-size=10] - How many items are in a page | ||
* @attr {Number} [surrounding-pages=2] - How many pages to display before and after current at most | ||
* @attr {Boolean} hide-on-single-page - If set, and all items fit in one page, hide the element | ||
* | ||
* @fires page-change - Indicates when the page changes; value is in `event.detail.page` | ||
*/ | ||
export class Pagination extends LitElement { | ||
static properties = { | ||
current: { | ||
type: Number, | ||
}, | ||
pageSize: { | ||
type: Number, | ||
attribute: 'page-size', | ||
}, | ||
surroundingPages: { | ||
type: Number, | ||
attribute: 'surrounding-pages', | ||
}, | ||
total: { | ||
type: Number, | ||
}, | ||
hideOnSinglePage: { | ||
type: Boolean, | ||
attribute: 'hide-on-single-page', | ||
}, | ||
}; | ||
|
||
static styles = css` | ||
:host { | ||
display: block; | ||
} | ||
nav { | ||
display: flex; | ||
align-items: center; | ||
} | ||
`; | ||
|
||
constructor() { | ||
super(); | ||
this.current = 1; | ||
this.pageSize = 10; | ||
this.surroundingPages = 2; | ||
this.total = 1; | ||
this.hideOnSinglePage = false; | ||
} | ||
|
||
generatePages() { | ||
const arr = []; | ||
for ( | ||
let i = Math.max(1, this.current - this.surroundingPages); | ||
i <= Math.min(this.totalPages, this.current + this.surroundingPages); | ||
i++ | ||
) { | ||
arr.push(i); | ||
} | ||
|
||
return arr; | ||
} | ||
|
||
_dispatchPrev() { | ||
const event = new CustomEvent('page-change', { | ||
bubbles: true, | ||
composed: true, | ||
detail: {page: this.current - 1}, | ||
}); | ||
|
||
this.dispatchEvent(event); | ||
} | ||
|
||
_dispatchNext() { | ||
const event = new CustomEvent('page-change', { | ||
bubbles: true, | ||
composed: true, | ||
detail: {page: this.current + 1}, | ||
}); | ||
|
||
this.dispatchEvent(event); | ||
} | ||
|
||
render() { | ||
this.totalPages = Math.ceil(this.total / this.pageSize); | ||
|
||
if (this.hideOnSinglePage && this.totalPages < 2) { | ||
return html` | ||
<sl-visually-hidden> | ||
<nav role="navigation" aria-label="Pagination Navigation"> | ||
Pagination not needed as all ${this.total} items fit in one page | ||
</nav> | ||
</sl-visually-hidden> | ||
`; | ||
} | ||
|
||
const pages = this.generatePages(); | ||
return html` | ||
<nav role="navigation" aria-label="Pagination Navigation"> | ||
${this.current === 1 | ||
? null | ||
: html` | ||
<sl-icon-button | ||
name="arrow-left" | ||
value=${this.current - 1} | ||
@click=${this._dispatchPrev} | ||
> | ||
</sl-icon-button> | ||
`} | ||
${pages[0] === 1 | ||
? null | ||
: html` | ||
<shoestring-pagination-page-button | ||
page=${1} | ||
></shoestring-pagination-page-button> | ||
… | ||
`} | ||
${pages.map( | ||
(page) => | ||
html`<shoestring-pagination-page-button | ||
page=${page} | ||
?current=${page === this.current} | ||
></shoestring-pagination-page-button>` | ||
)} | ||
${pages[pages.length - 1] === this.totalPages | ||
? null | ||
: html` | ||
… | ||
<shoestring-pagination-page-button | ||
page=${this.totalPages} | ||
></shoestring-pagination-page-button> | ||
`} | ||
${this.current === this.totalPages | ||
? null | ||
: html` | ||
<sl-icon-button | ||
name="arrow-right" | ||
value=${this.current + 1} | ||
@click=${this._dispatchNext} | ||
> | ||
</sl-icon-button> | ||
`} | ||
</nav> | ||
`; | ||
} | ||
} | ||
customElements.define('shoestring-pagination', Pagination); | ||
export default Pagination; | ||
|
||
export class PaginationPageButton extends LitElement { | ||
static properties = {page: {type: Number}, current: {type: Boolean}}; | ||
|
||
constructor() { | ||
super(); | ||
this.page = 1; | ||
this.current = false; | ||
} | ||
|
||
_dispatch() { | ||
const event = new CustomEvent('page-change', { | ||
bubbles: true, | ||
composed: true, | ||
detail: {page: this.page}, | ||
}); | ||
|
||
this.dispatchEvent(event); | ||
} | ||
|
||
render() { | ||
return html`<sl-button | ||
variant=${this.current ? 'default' : 'text'} | ||
?disabled=${this.current} | ||
value=${this.page} | ||
@click=${this._dispatch} | ||
> | ||
${this.page} | ||
</sl-button> `; | ||
} | ||
} | ||
customElements.define( | ||
'shoestring-pagination-page-button', | ||
PaginationPageButton | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,7 @@ | |
/> | ||
<script | ||
type="module" | ||
src="../node_modules/@shoelace-style/shoelace/dist/components/switch/switch.js" | ||
src="../node_modules/@shoelace-style/shoelace/dist/shoelace.js" | ||
></script> | ||
<link rel="preconnect" href="https://fonts.googleapis.com" /> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | ||
|
@@ -26,6 +26,10 @@ | |
/> | ||
<script type="module" src="../shoestring-pagination.js"></script> | ||
<script type="module" src="./demo-components.js"></script> | ||
<script | ||
type="module" | ||
src="https://cdn.jsdelivr.net/npm/@lalomartins/[email protected]/cdn/shoestring-theme-selector.js" | ||
></script> | ||
<style> | ||
body > div { | ||
display: flex; | ||
|
@@ -42,7 +46,9 @@ | |
<body> | ||
<div> | ||
<h1>Shoestring Pagination demo</h1> | ||
<div id="controls"><sl-switch>Dark mode</sl-switch></div> | ||
<div id="controls"> | ||
<shoestring-theme-selector></shoestring-theme-selector> | ||
</div> | ||
</div> | ||
<div> | ||
<shoestring-pagination-demo-block | ||
|
@@ -102,26 +108,5 @@ <h1>Shoestring Pagination demo</h1> | |
total="7" | ||
></shoestring-pagination-demo-block> | ||
</div> | ||
|
||
<script> | ||
(function setupDarkMode() { | ||
const switchEl = document.querySelector('#controls sl-switch'); | ||
function updateMode(isDark) { | ||
if (isDark) { | ||
document.documentElement.classList.add('sl-theme-dark'); | ||
} else { | ||
document.documentElement.classList.remove('sl-theme-dark'); | ||
} | ||
} | ||
switchEl.addEventListener('sl-change', (event) => { | ||
updateMode(event.target.checked); | ||
}); | ||
const systemDarkMode = | ||
window.matchMedia && | ||
window.matchMedia('(prefers-color-scheme: dark)').matches; | ||
switchEl.checked = systemDarkMode; | ||
updateMode(systemDarkMode); | ||
})(); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* @license | ||
* Copyright 2032 Lalo Martins | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
export {setBasePath} from '@shoelace-style/shoelace/dist/utilities/base-path.js'; | ||
import '@shoelace-style/shoelace/dist/components/button/button.js'; | ||
import '@shoelace-style/shoelace/dist/components/icon-button/icon-button.js'; | ||
import '@shoelace-style/shoelace/dist/components/visually-hidden/visually-hidden.js'; | ||
export {ThemeSelector} from './shoestring-theme-selector'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters