@trimble-oss/moduswebcomponents
Version:
Modus Web Components is a modern, accessible UI library built with Stencil JS that provides reusable web components following Trimble's Modus design system. This updated version focuses on improved flexibility, enhanced theming options, comprehensive cust
114 lines (105 loc) • 15.1 kB
JavaScript
import { h, r as registerInstance, c as createEvent, g as getElement } from './index-D_4hbGjA.js';
import { i as inheritAriaAttributes } from './utils-DQvnWXRl.js';
const convertPropsToClasses = ({ size, }) => {
let classes = '';
if (size) {
classes = `${classes} modus-wc-btn-${size}`;
}
return classes.trim();
};
const ChevronDoubleLeftSolidIcon = ({ className, }) => (h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "currentColor", class: `mi-chevron-double-left ${className || ''}`, viewBox: "0 0 24 24" },
h("path", { d: "m14.42 12 3.88-3.88a.996.996 0 1 0-1.41-1.41L12.3 11.3a.996.996 0 0 0 0 1.41l4.59 4.59c.38.38 1.01.38 1.4-.01a.996.996 0 0 0 0-1.41zm-2.71-5.29a.996.996 0 0 0-1.41 0L5.71 11.3a.996.996 0 0 0 0 1.41l4.59 4.59c.38.38 1.01.38 1.4-.01s.39-1.02 0-1.41L7.83 12l3.88-3.88a.996.996 0 0 0 0-1.41" })));
const ChevronDoubleRightSolidIcon = ({ className, }) => (h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "currentColor", class: `mi-chevron-double-right ${className || ''}`, viewBox: "0 0 24 24" },
h("path", { d: "M7.12 6.71c-.39-.39-1.03-.39-1.42 0a.996.996 0 0 0 0 1.41L9.58 12 5.7 15.88a.996.996 0 1 0 1.41 1.41l4.59-4.59a.996.996 0 0 0 0-1.41zm11.17 4.58L13.7 6.7c-.38-.38-1.02-.38-1.41 0a.996.996 0 0 0 0 1.41l3.88 3.88-3.88 3.88a.996.996 0 1 0 1.41 1.41l4.59-4.59a.996.996 0 0 0 0-1.41Z" })));
const ChevronLeftSolidIcon = ({ className, }) => (h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "currentColor", class: `mi-chevron-left ${className || ''}`, viewBox: "0 0 24 24" },
h("path", { d: "M14.71 6.71a.996.996 0 0 0-1.41 0L8.71 11.3a.996.996 0 0 0 0 1.41l4.59 4.59a.996.996 0 1 0 1.41-1.41L10.83 12l3.88-3.88c.39-.39.38-1.03 0-1.41" })));
const ChevronRightSolidIcon = ({ className, }) => (h("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "currentColor", class: `mi-chevron-right ${className || ''}`, viewBox: "0 0 24 24" },
h("path", { d: "M9.29 6.71a.996.996 0 0 0 0 1.41L13.17 12l-3.88 3.88a.996.996 0 1 0 1.41 1.41l4.59-4.59a.996.996 0 0 0 0-1.41L10.7 6.7c-.38-.38-1.02-.38-1.41.01" })));
const modusWcPaginationCss = "modus-wc-pagination .modus-wc-pagination{background-color:var(--modus-wc-color-base-100);color:var(--modus-wc-color-base-content)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn{background-color:var(--modus-wc-color-base-100);border-color:transparent}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:hover{background-color:var(--modus-wc-color-base-100);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:focus{background-color:var(--modus-wc-color-base-200);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:active{background-color:var(--modus-wc-color-primary-pale);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn-selected{background-color:var(--modus-wc-color-primary-pale);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn-active{background-color:var(--modus-wc-color-primary-pale);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn-open{background-color:var(--modus-wc-color-primary-pale);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.selected{background-color:var(--modus-wc-color-primary-pale);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.active{background-color:var(--modus-wc-color-primary-pale);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn-disabled:hover{background-color:inherit}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn--active{background-color:var(--modus-wc-color-primary-pale);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn--selected{background-color:var(--modus-wc-color-primary-pale);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:checked{background-color:var(--modus-wc-color-primary);color:var(--modus-wc-color-primary-content)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.checked{background-color:var(--modus-wc-color-primary);color:var(--modus-wc-color-primary-content)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn-checked{background-color:var(--modus-wc-color-primary);color:var(--modus-wc-color-primary-content)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.pressed{background-color:var(--modus-wc-color-primary);color:var(--modus-wc-color-primary-content)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn-pressed{background-color:var(--modus-wc-color-primary);color:var(--modus-wc-color-primary-content)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn[aria-pressed=true]{background-color:var(--modus-wc-color-primary);color:var(--modus-wc-color-primary-content)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.modus-wc-btn-sm .modus-wc-pagination-icon{height:var(--modus-wc-line-height-sm);width:var(--modus-wc-line-height-sm)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.modus-wc-btn-md .modus-wc-pagination-icon{height:var(--modus-wc-ling-height-md);width:var(--modus-wc-line-height-md)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.modus-wc-btn-lg .modus-wc-pagination-icon{height:var(--modus-wc-line-height-lg);width:var(--modus-wc-line-height-lg)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-button-text{padding:calc(var(--modus-wc-spacing-sm) - 2px);width:auto !important}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:not(:disabled){background-color:var(--modus-wc-color-base-100);color:var(--modus-wc-color-base-content)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:not(:disabled).modus-wc-btn-active{background-color:var(--modus-wc-color-primary-pale);color:var(--modus-wc-color-primary)}modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:not(:disabled):hover:not(.modus-wc-btn-active){background-color:var(--modus-wc-color-base-300);border-color:transparent}[data-theme=modus-classic-dark] modus-wc-pagination .modus-wc-pagination,[data-theme=modus-classic-light] modus-wc-pagination .modus-wc-pagination{background-color:transparent}[data-theme=modus-classic-dark] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn,[data-theme=modus-classic-light] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn{background-color:transparent;border:none;border-radius:var(--modus-wc-border-radius-md) !important;box-shadow:none}[data-theme=modus-classic-dark] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.modus-wc-btn-sm,[data-theme=modus-classic-light] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.modus-wc-btn-sm{height:var(--modus-wc-line-height-md);max-height:var(--modus-wc-line-height-md);min-height:var(--modus-wc-line-height-md);width:var(--modus-wc-line-height-md)}[data-theme=modus-classic-dark] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.modus-wc-btn-md,[data-theme=modus-classic-light] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.modus-wc-btn-md{height:var(--modus-wc-line-height-lg);max-height:var(--modus-wc-line-height-lg);min-height:var(--modus-wc-line-height-lg);width:var(--modus-wc-line-height-lg)}[data-theme=modus-classic-dark] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.modus-wc-btn-lg,[data-theme=modus-classic-light] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn.modus-wc-btn-lg{height:var(--modus-wc-line-height-xl);max-height:var(--modus-wc-line-height-xl);min-height:var(--modus-wc-line-height-xl);width:var(--modus-wc-line-height-xl)}[data-theme=modus-classic-light] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:not(:disabled){color:var(--modus-wc-color-trimble-gray)}[data-theme=modus-classic-light] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:not(:disabled).modus-wc-btn-active{background-color:var(--modus-wc-color-blue-pale);color:var(--modus-wc-color-blue-light)}[data-theme=modus-classic-light] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:not(:disabled):hover:not(.modus-wc-btn-active){background-color:var(--modus-wc-color-gray-0)}[data-theme=modus-classic-dark] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:not(:disabled){color:var(--modus-wc-color-gray-2)}[data-theme=modus-classic-dark] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:not(:disabled).modus-wc-btn-active{background-color:var(--modus-wc-color-highlight-blue);color:var(--modus-wc-color-trimble-gray)}[data-theme=modus-classic-dark] modus-wc-pagination .modus-wc-pagination .modus-wc-pagination-btn:not(:disabled):hover:not(.modus-wc-btn-active){background-color:var(--modus-wc-color-gray-8)}";
const ModusWcPagination = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.pageChange = createEvent(this, "pageChange");
this.inheritedAttributes = {};
this.maxVisibleButtons = 5;
/** Total number of pages */
this.count = 1;
/** Custom CSS class to apply */
this.customClass = '';
/** The current page number */
this.page = 1;
/** Size of the pagination buttons */
this.size = 'md';
/** Internal state to track visible page numbers */
this.visiblePages = [];
this.handlePageClick = (newPage) => {
if (newPage === this.page || newPage < 1 || newPage > this.count) {
return;
}
this.pageChange.emit({ newPage, prevPage: this.page });
this.page = newPage;
};
}
// Creates a sliding "window" of page buttons that tries to keep the current page centered when possible.
calculateVisiblePages() {
const pages = [];
// Calculates how many page buttons should ideally appear on each side of current page.
const halfVisible = Math.floor(this.maxVisibleButtons / 2);
let startPage = Math.max(1, this.page - halfVisible);
let endPage = Math.min(this.count, startPage + this.maxVisibleButtons - 1);
// Handles edge case when near end of the page count.
// If we can't fit enough buttons after current page, then shift window left.
if (endPage - startPage + 1 < this.maxVisibleButtons) {
startPage = Math.max(1, endPage - this.maxVisibleButtons + 1);
}
for (let i = startPage; i <= endPage; i++) {
pages.push(i);
}
this.visiblePages = pages;
}
componentWillLoad() {
this.calculateVisiblePages();
this.inheritedAttributes = inheritAriaAttributes(this.el);
}
getClasses() {
const buttonClassList = [
'modus-wc-pagination-btn',
'modus-wc-join-item',
'modus-wc-btn',
'modus-wc-btn-square',
];
const paginationClassList = ['modus-wc-pagination', 'modus-wc-join'];
// The order CSS classes are added matters to CSS specificity
if (this.customClass)
paginationClassList.push(this.customClass);
const paginationClasses = paginationClassList.join(' ');
const propClasses = convertPropsToClasses({ size: this.size });
if (propClasses)
buttonClassList.push(propClasses);
const buttonClasses = buttonClassList.join(' ');
return { paginationClasses, buttonClasses };
}
render() {
var _a, _b, _c, _d, _e;
const { paginationClasses, buttonClasses } = this.getClasses();
const isFirstPage = this.page === 1;
const isLastPage = this.page === this.count;
const shouldShowFirstLastButtons = this.count > this.maxVisibleButtons;
// Default aria values if not provided
const ariaLabels = {
firstPage: ((_a = this.ariaLabelValues) === null || _a === void 0 ? void 0 : _a.firstPage) || 'First page',
lastPage: ((_b = this.ariaLabelValues) === null || _b === void 0 ? void 0 : _b.lastPage) || 'Last page',
nextPage: ((_c = this.ariaLabelValues) === null || _c === void 0 ? void 0 : _c.nextPage) || 'Next page',
page: ((_d = this.ariaLabelValues) === null || _d === void 0 ? void 0 : _d.page) || 'Page {0}',
previousPage: ((_e = this.ariaLabelValues) === null || _e === void 0 ? void 0 : _e.previousPage) || 'Previous page',
};
return (h("div", Object.assign({ key: '72316d01cd146f24cb6e56ec80d3bab1427fc4ad', class: paginationClasses }, this.inheritedAttributes), shouldShowFirstLastButtons && (h("button", { key: 'f10a3364940e3baca9690eb3f6758c3043a62bd3', "aria-label": ariaLabels.firstPage, class: buttonClasses, disabled: isFirstPage, onClick: () => this.handlePageClick(1) }, h(ChevronDoubleLeftSolidIcon, { key: 'fbcf1f88982e677f40c26e24db74446ceda1ff7f', className: "modus-wc-pagination-icon" }))), h("button", { key: '8d137fcdaa312a37dd832be8e8fca694436c377f', "aria-label": this.prevButtonText ? undefined : ariaLabels.previousPage, class: `${buttonClasses} ${this.prevButtonText ? 'modus-wc-pagination-button-text' : ''}`, disabled: isFirstPage, onClick: () => this.handlePageClick(this.page - 1) }, this.prevButtonText ? (h("span", null, this.prevButtonText)) : (h(ChevronLeftSolidIcon, { className: "modus-wc-pagination-icon" }))), this.visiblePages.map((page) => (h("button", { "aria-current": this.page === page ? 'page' : undefined, "aria-label": ariaLabels.page.replace('{0}', page.toString()), class: `${buttonClasses} ${this.page === page ? 'modus-wc-btn-active' : ''}`, onClick: () => this.handlePageClick(page) }, page))), h("button", { key: '1d59b0f2b947b5945632c2d56f06449e46653a85', "aria-label": this.nextButtonText ? undefined : ariaLabels.nextPage, class: `${buttonClasses} ${this.nextButtonText ? 'modus-wc-pagination-button-text' : ''}`, disabled: isLastPage, onClick: () => this.handlePageClick(this.page + 1) }, this.nextButtonText ? (h("span", null, this.nextButtonText)) : (h(ChevronRightSolidIcon, { className: "modus-wc-pagination-icon" }))), shouldShowFirstLastButtons && (h("button", { key: '03158d267c53d3d68b9dbeb03220edb5ea528fab', "aria-label": ariaLabels.lastPage, class: buttonClasses, disabled: isLastPage, onClick: () => this.handlePageClick(this.count) }, h(ChevronDoubleRightSolidIcon, { key: '3bea8fab8a15558b6c1f398b9a3ce619aac4f518', className: "modus-wc-pagination-icon" })))));
}
get el() { return getElement(this); }
static get watchers() { return {
"page": ["calculateVisiblePages"],
"count": ["calculateVisiblePages"]
}; }
};
ModusWcPagination.style = modusWcPaginationCss;
export { ModusWcPagination as modus_wc_pagination };