Mercurial > nebulaweb3
diff default/node_modules/tablesaw/src/tables.swipetoggle.js @ 0:1d038bc9b3d2 default tip
Up:default
author | Liny <dev@neowd.com> |
---|---|
date | Sat, 31 May 2025 09:21:51 +0800 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/default/node_modules/tablesaw/src/tables.swipetoggle.js Sat May 31 09:21:51 2025 +0800 @@ -0,0 +1,369 @@ +/* +* tablesaw: A set of plugins for responsive tables +* Swipe Toggle: swipe gesture (or buttons) to navigate which columns are shown. +* Copyright (c) 2013 Filament Group, Inc. +* MIT License +*/ + +(function() { + var classes = { + hideBtn: "disabled", + persistWidths: "tablesaw-fix-persist", + hiddenCol: "tablesaw-swipe-cellhidden", + persistCol: "tablesaw-swipe-cellpersist", + allColumnsVisible: "tablesaw-all-cols-visible" + }; + var attrs = { + disableTouchEvents: "data-tablesaw-no-touch", + ignorerow: "data-tablesaw-ignorerow", + subrow: "data-tablesaw-subrow" + }; + + function createSwipeTable(tbl, $table) { + var tblsaw = $table.data("tablesaw"); + + var $btns = $("<div class='tablesaw-advance'></div>"); + // TODO next major version: remove .btn + var $prevBtn = $( + "<a href='#' class='btn tablesaw-nav-btn tablesaw-btn btn-micro left'>" + + Tablesaw.i18n.swipePreviousColumn + + "</a>" + ).appendTo($btns); + // TODO next major version: remove .btn + var $nextBtn = $( + "<a href='#' class='btn tablesaw-nav-btn tablesaw-btn btn-micro right'>" + + Tablesaw.i18n.swipeNextColumn + + "</a>" + ).appendTo($btns); + + var $headerCells = tbl._getPrimaryHeaderCells(); + var $headerCellsNoPersist = $headerCells.not('[data-tablesaw-priority="persist"]'); + var headerWidths = []; + var $head = $(document.head || "head"); + var tableId = $table.attr("id"); + + if (!$headerCells.length) { + throw new Error("tablesaw swipe: no header cells found."); + } + + $table.addClass("tablesaw-swipe"); + + function initMinHeaderWidths() { + $table.css({ + width: "1px" + }); + + // remove any hidden columns + $table.find("." + classes.hiddenCol).removeClass(classes.hiddenCol); + + headerWidths = []; + // Calculate initial widths + $headerCells.each(function() { + headerWidths.push(this.offsetWidth); + }); + + // reset props + $table.css({ + width: "" + }); + } + + initMinHeaderWidths(); + + $btns.appendTo(tblsaw.$toolbar); + + if (!tableId) { + tableId = "tableswipe-" + Math.round(Math.random() * 10000); + $table.attr("id", tableId); + } + + function showColumn(headerCell) { + tblsaw._$getCells(headerCell).removeClass(classes.hiddenCol); + } + + function hideColumn(headerCell) { + tblsaw._$getCells(headerCell).addClass(classes.hiddenCol); + } + + function persistColumn(headerCell) { + tblsaw._$getCells(headerCell).addClass(classes.persistCol); + } + + function isPersistent(headerCell) { + return $(headerCell).is('[data-tablesaw-priority="persist"]'); + } + + function unmaintainWidths() { + $table.removeClass(classes.persistWidths); + $("#" + tableId + "-persist").remove(); + } + + function maintainWidths() { + var prefix = "#" + tableId + ".tablesaw-swipe ", + styles = [], + tableWidth = $table.width(), + hash = [], + newHash; + + // save persistent column widths (as long as they take up less than 75% of table width) + $headerCells.each(function(index) { + var width; + if (isPersistent(this)) { + width = this.offsetWidth; + + if (width < tableWidth * 0.75) { + hash.push(index + "-" + width); + styles.push( + prefix + + " ." + + classes.persistCol + + ":nth-child(" + + (index + 1) + + ") { width: " + + width + + "px; }" + ); + } + } + }); + newHash = hash.join("_"); + + if (styles.length) { + $table.addClass(classes.persistWidths); + var $style = $("#" + tableId + "-persist"); + // If style element not yet added OR if the widths have changed + if (!$style.length || $style.data("tablesaw-hash") !== newHash) { + // Remove existing + $style.remove(); + + $("<style>" + styles.join("\n") + "</style>") + .attr("id", tableId + "-persist") + .data("tablesaw-hash", newHash) + .appendTo($head); + } + } + } + + function getNext() { + var next = [], + checkFound; + + $headerCellsNoPersist.each(function(i) { + var $t = $(this), + isHidden = $t.css("display") === "none" || $t.is("." + classes.hiddenCol); + + if (!isHidden && !checkFound) { + checkFound = true; + next[0] = i; + } else if (isHidden && checkFound) { + next[1] = i; + + return false; + } + }); + + return next; + } + + function getPrev() { + var next = getNext(); + return [next[1] - 1, next[0] - 1]; + } + + function nextpair(fwd) { + return fwd ? getNext() : getPrev(); + } + + function canAdvance(pair) { + return pair[1] > -1 && pair[1] < $headerCellsNoPersist.length; + } + + function matchesMedia() { + var matchMedia = $table.attr("data-tablesaw-swipe-media"); + return !matchMedia || ("matchMedia" in window && window.matchMedia(matchMedia).matches); + } + + function fakeBreakpoints() { + if (!matchesMedia()) { + return; + } + + var containerWidth = $table.parent().width(), + persist = [], + sum = 0, + sums = [], + visibleNonPersistantCount = $headerCells.length; + + $headerCells.each(function(index) { + var $t = $(this), + isPersist = $t.is('[data-tablesaw-priority="persist"]'); + + persist.push(isPersist); + sum += headerWidths[index]; + sums.push(sum); + + // is persistent or is hidden + if (isPersist || sum > containerWidth) { + visibleNonPersistantCount--; + } + }); + + // We need at least one column to swipe. + var needsNonPersistentColumn = visibleNonPersistantCount === 0; + + $headerCells.each(function(index) { + if (sums[index] > containerWidth) { + hideColumn(this); + } + }); + + $headerCells.each(function(index) { + if (persist[index]) { + // for visual box-shadow + persistColumn(this); + return; + } + + if (sums[index] <= containerWidth || needsNonPersistentColumn) { + needsNonPersistentColumn = false; + showColumn(this); + tblsaw.updateColspanCells(classes.hiddenCol, this, true); + } + }); + + unmaintainWidths(); + + $table.trigger("tablesawcolumns"); + } + + function advance(fwd) { + var pair = nextpair(fwd); + if (canAdvance(pair)) { + if (isNaN(pair[0])) { + if (fwd) { + pair[0] = 0; + } else { + pair[0] = $headerCellsNoPersist.length - 1; + } + } + + // TODO just blindly hiding the previous column and showing the next column can result in + // column content overflow + maintainWidths(); + hideColumn($headerCellsNoPersist.get(pair[0])); + tblsaw.updateColspanCells(classes.hiddenCol, $headerCellsNoPersist.get(pair[0]), false); + + showColumn($headerCellsNoPersist.get(pair[1])); + tblsaw.updateColspanCells(classes.hiddenCol, $headerCellsNoPersist.get(pair[1]), true); + + $table.trigger("tablesawcolumns"); + } + } + + $prevBtn.add($nextBtn).on("click", function(e) { + advance(!!$(e.target).closest($nextBtn).length); + e.preventDefault(); + }); + + function getCoord(event, key) { + return (event.touches || event.originalEvent.touches)[0][key]; + } + + if (!$table.is("[" + attrs.disableTouchEvents + "]")) { + $table.on("touchstart.swipetoggle", function(e) { + var originX = getCoord(e, "pageX"); + var originY = getCoord(e, "pageY"); + var x; + var y; + var scrollTop = window.pageYOffset; + + $(window).off(Tablesaw.events.resize, fakeBreakpoints); + + $(this) + .on("touchmove.swipetoggle", function(e) { + x = getCoord(e, "pageX"); + y = getCoord(e, "pageY"); + }) + .on("touchend.swipetoggle", function() { + var cfg = tbl.getConfig({ + swipeHorizontalThreshold: 30, + swipeVerticalThreshold: 30 + }); + + // This config code is a little awkward because shoestring doesn’t support deep $.extend + // Trying to work around when devs only override one of (not both) horizontalThreshold or + // verticalThreshold in their TablesawConfig. + // @TODO major version bump: remove cfg.swipe, move to just use the swipePrefix keys + var verticalThreshold = cfg.swipe + ? cfg.swipe.verticalThreshold + : cfg.swipeVerticalThreshold; + var horizontalThreshold = cfg.swipe + ? cfg.swipe.horizontalThreshold + : cfg.swipeHorizontalThreshold; + + var isPageScrolled = Math.abs(window.pageYOffset - scrollTop) >= verticalThreshold; + var isVerticalSwipe = Math.abs(y - originY) >= verticalThreshold; + + if (!isVerticalSwipe && !isPageScrolled) { + if (x - originX < -1 * horizontalThreshold) { + advance(true); + } + if (x - originX > horizontalThreshold) { + advance(false); + } + } + + window.setTimeout(function() { + $(window).on(Tablesaw.events.resize, fakeBreakpoints); + }, 300); + + $(this).off("touchmove.swipetoggle touchend.swipetoggle"); + }); + }); + } + + $table + .on("tablesawcolumns.swipetoggle", function() { + var canGoPrev = canAdvance(getPrev()); + var canGoNext = canAdvance(getNext()); + $prevBtn[canGoPrev ? "removeClass" : "addClass"](classes.hideBtn); + $nextBtn[canGoNext ? "removeClass" : "addClass"](classes.hideBtn); + + tblsaw.$toolbar[!canGoPrev && !canGoNext ? "addClass" : "removeClass"]( + classes.allColumnsVisible + ); + }) + .on("tablesawnext.swipetoggle", function() { + advance(true); + }) + .on("tablesawprev.swipetoggle", function() { + advance(false); + }) + .on(Tablesaw.events.destroy + ".swipetoggle", function() { + var $t = $(this); + + $t.removeClass("tablesaw-swipe"); + tblsaw.$toolbar.find(".tablesaw-advance").remove(); + $(window).off(Tablesaw.events.resize, fakeBreakpoints); + + $t.off(".swipetoggle"); + }) + .on(Tablesaw.events.refresh, function() { + unmaintainWidths(); + initMinHeaderWidths(); + fakeBreakpoints(); + }); + + fakeBreakpoints(); + $(window).on(Tablesaw.events.resize, fakeBreakpoints); + } + + // on tablecreate, init + $(document).on(Tablesaw.events.create, function(e, tablesaw) { + if (tablesaw.mode === "swipe") { + createSwipeTable(tablesaw, tablesaw.$table); + } + }); + + // TODO OOP this and add to Tablesaw object +})();