From a2dea0baf6a37f526b82a7b0c4b2177d63f6a180 Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Sun, 26 Oct 2025 19:12:39 -0400 Subject: [PATCH] added searchable to the Readme and the index.html :) --- README.md | 6 +- dist/auto.html | 372 -------------------------------------- dist/auto.min.html | 372 -------------------------------------- dist/bundled.html | 373 -------------------------------------- dist/bundled.min.html | 373 -------------------------------------- dist/esm.html | 375 --------------------------------------- dist/esm.min.html | 375 --------------------------------------- dist/example.css | 16 +- dist/example.min.css | 2 +- dist/sortable.css | 16 +- dist/sortable.min.css | 2 +- dist/standalone.html | 373 -------------------------------------- dist/standalone.min.html | 373 -------------------------------------- docs/example.css | 16 +- docs/index.html | 6 +- index.html | 6 +- package.json | 8 +- pnpm-lock.yaml | 292 +++++++++++------------------- src/scss/sortable.scss | 21 ++- tests/benchmark.spec.ts | 12 +- 20 files changed, 171 insertions(+), 3218 deletions(-) delete mode 100644 dist/auto.html delete mode 100644 dist/auto.min.html delete mode 100644 dist/bundled.html delete mode 100644 dist/bundled.min.html delete mode 100644 dist/esm.html delete mode 100644 dist/esm.min.html delete mode 100644 dist/standalone.html delete mode 100644 dist/standalone.min.html diff --git a/README.md b/README.md index 17c318e..db2fd02 100755 --- a/README.md +++ b/README.md @@ -6,7 +6,11 @@ Makes any table with **class="sortable"**, er, sortable. The user can click on a table header and change the sorting of the table rows. -Just include the JavaScript and it will work. No function calls are needed, everything is handled by an **eventListener**. +Just include the JavaScript and it will work. No function calls are needed, everything is handled by a [JavaScript HTML DOM EventListener](https://www.w3schools.com/js/js_htmldom_eventlistener.asp). + +

Related Projects

+ +🔍 **[searchable](https://github.com/tofsjonas/searchable)** - A companion library that makes tables searchable/filterable, perfect to use alongside sortable!

Demo

diff --git a/dist/auto.html b/dist/auto.html deleted file mode 100644 index 3b4bde8..0000000 --- a/dist/auto.html +++ /dev/null @@ -1,372 +0,0 @@ - - - - - - - sortable test - - - - -

Sortable examples

- -

Basic sort

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Tiebreaker

-

Sort by year

- - (Appearance manually changed using style attributes. Just for demonstration.) - -
-style="
-  --stripe-bg: #ff0;
-  --stripe-color: #000;
-  --stripe-bg-odd: #f0f;
-  --stripe-color-odd: #111;
-  --th-bg: blue;
-  --th-color: #fff;"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
- - -

Colspans

- - - - - - - - - - - - - - - - - - - - - - - - - -
nums + charsCHARS
333222BB
1111CCC
22333A
- -

Empty/null sorted last

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TextNumber
jkl0.4
abc0
should be sorted last(if click in this column)
def0.2
- -

class="no-sort"

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

numeric sorting

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
- -

Ascending sort

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Alternative sort

- - - - - - - - - - - - - - - - - - - - - - -
Movie NameSize
AB
DE
JK
- -

TR element with no TD element (invalid HTML)

- - - - - - - - - - - - - - - - - - - - -
Letters
CCC
DDD
AAA
- -

TD with "incorrect" whitespace

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
 SidekickMorty
- -

HTML Tag Support

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
- - - - - - - diff --git a/dist/auto.min.html b/dist/auto.min.html deleted file mode 100644 index 82a01d7..0000000 --- a/dist/auto.min.html +++ /dev/null @@ -1,372 +0,0 @@ - - - - - - - sortable test - - - - -

Sortable examples

- -

Basic sort

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Tiebreaker

-

Sort by year

- - (Appearance manually changed using style attributes. Just for demonstration.) - -
-style="
-  --stripe-bg: #ff0;
-  --stripe-color: #000;
-  --stripe-bg-odd: #f0f;
-  --stripe-color-odd: #111;
-  --th-bg: blue;
-  --th-color: #fff;"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
- - -

Colspans

- - - - - - - - - - - - - - - - - - - - - - - - - -
nums + charsCHARS
333222BB
1111CCC
22333A
- -

Empty/null sorted last

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TextNumber
jkl0.4
abc0
should be sorted last(if click in this column)
def0.2
- -

class="no-sort"

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

numeric sorting

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
- -

Ascending sort

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Alternative sort

- - - - - - - - - - - - - - - - - - - - - - -
Movie NameSize
AB
DE
JK
- -

TR element with no TD element (invalid HTML)

- - - - - - - - - - - - - - - - - - - - -
Letters
CCC
DDD
AAA
- -

TD with "incorrect" whitespace

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
 SidekickMorty
- -

HTML Tag Support

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
- - - - - - - diff --git a/dist/bundled.html b/dist/bundled.html deleted file mode 100644 index 12470d3..0000000 --- a/dist/bundled.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - - sortable test - - - - -

Sortable examples

- -

Basic sort

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Tiebreaker

-

Sort by year

- - (Appearance manually changed using style attributes. Just for demonstration.) - -
-style="
-  --stripe-bg: #ff0;
-  --stripe-color: #000;
-  --stripe-bg-odd: #f0f;
-  --stripe-color-odd: #111;
-  --th-bg: blue;
-  --th-color: #fff;"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
- - -

Colspans

- - - - - - - - - - - - - - - - - - - - - - - - - -
nums + charsCHARS
333222BB
1111CCC
22333A
- -

Empty/null sorted last

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TextNumber
jkl0.4
abc0
should be sorted last(if click in this column)
def0.2
- -

class="no-sort"

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

numeric sorting

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
- -

Ascending sort

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Alternative sort

- - - - - - - - - - - - - - - - - - - - - - -
Movie NameSize
AB
DE
JK
- -

TR element with no TD element (invalid HTML)

- - - - - - - - - - - - - - - - - - - - -
Letters
CCC
DDD
AAA
- -

TD with "incorrect" whitespace

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
 SidekickMorty
- -

HTML Tag Support

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
- - - - - - - - diff --git a/dist/bundled.min.html b/dist/bundled.min.html deleted file mode 100644 index 2140440..0000000 --- a/dist/bundled.min.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - - sortable test - - - - -

Sortable examples

- -

Basic sort

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Tiebreaker

-

Sort by year

- - (Appearance manually changed using style attributes. Just for demonstration.) - -
-style="
-  --stripe-bg: #ff0;
-  --stripe-color: #000;
-  --stripe-bg-odd: #f0f;
-  --stripe-color-odd: #111;
-  --th-bg: blue;
-  --th-color: #fff;"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
- - -

Colspans

- - - - - - - - - - - - - - - - - - - - - - - - - -
nums + charsCHARS
333222BB
1111CCC
22333A
- -

Empty/null sorted last

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TextNumber
jkl0.4
abc0
should be sorted last(if click in this column)
def0.2
- -

class="no-sort"

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

numeric sorting

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
- -

Ascending sort

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Alternative sort

- - - - - - - - - - - - - - - - - - - - - - -
Movie NameSize
AB
DE
JK
- -

TR element with no TD element (invalid HTML)

- - - - - - - - - - - - - - - - - - - - -
Letters
CCC
DDD
AAA
- -

TD with "incorrect" whitespace

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
 SidekickMorty
- -

HTML Tag Support

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
- - - - - - - - diff --git a/dist/esm.html b/dist/esm.html deleted file mode 100644 index 35cee2a..0000000 --- a/dist/esm.html +++ /dev/null @@ -1,375 +0,0 @@ - - - - - - - sortable test - - - - -

Sortable examples

- -

Basic sort

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Tiebreaker

-

Sort by year

- - (Appearance manually changed using style attributes. Just for demonstration.) - -
-style="
-  --stripe-bg: #ff0;
-  --stripe-color: #000;
-  --stripe-bg-odd: #f0f;
-  --stripe-color-odd: #111;
-  --th-bg: blue;
-  --th-color: #fff;"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
- - -

Colspans

- - - - - - - - - - - - - - - - - - - - - - - - - -
nums + charsCHARS
333222BB
1111CCC
22333A
- -

Empty/null sorted last

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TextNumber
jkl0.4
abc0
should be sorted last(if click in this column)
def0.2
- -

class="no-sort"

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

numeric sorting

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
- -

Ascending sort

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Alternative sort

- - - - - - - - - - - - - - - - - - - - - - -
Movie NameSize
AB
DE
JK
- -

TR element with no TD element (invalid HTML)

- - - - - - - - - - - - - - - - - - - - -
Letters
CCC
DDD
AAA
- -

TD with "incorrect" whitespace

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
 SidekickMorty
- -

HTML Tag Support

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
- - - - - - - diff --git a/dist/esm.min.html b/dist/esm.min.html deleted file mode 100644 index ca4ac8d..0000000 --- a/dist/esm.min.html +++ /dev/null @@ -1,375 +0,0 @@ - - - - - - - sortable test - - - - -

Sortable examples

- -

Basic sort

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Tiebreaker

-

Sort by year

- - (Appearance manually changed using style attributes. Just for demonstration.) - -
-style="
-  --stripe-bg: #ff0;
-  --stripe-color: #000;
-  --stripe-bg-odd: #f0f;
-  --stripe-color-odd: #111;
-  --th-bg: blue;
-  --th-color: #fff;"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
- - -

Colspans

- - - - - - - - - - - - - - - - - - - - - - - - - -
nums + charsCHARS
333222BB
1111CCC
22333A
- -

Empty/null sorted last

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TextNumber
jkl0.4
abc0
should be sorted last(if click in this column)
def0.2
- -

class="no-sort"

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

numeric sorting

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
- -

Ascending sort

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Alternative sort

- - - - - - - - - - - - - - - - - - - - - - -
Movie NameSize
AB
DE
JK
- -

TR element with no TD element (invalid HTML)

- - - - - - - - - - - - - - - - - - - - -
Letters
CCC
DDD
AAA
- -

TD with "incorrect" whitespace

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
 SidekickMorty
- -

HTML Tag Support

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
- - - - - - - diff --git a/dist/example.css b/dist/example.css index 6b8861c..aeabdac 100644 --- a/dist/example.css +++ b/dist/example.css @@ -72,18 +72,18 @@ vertical-align: baseline; white-space: nowrap; } -.sortable td, -.sortable th { - padding: 10px; -} -.sortable td:first-child, -.sortable th:first-child { +.sortable thead td:first-child, +.sortable thead th:first-child { border-top-left-radius: 4px; } -.sortable td:last-child, -.sortable th:last-child { +.sortable thead td:last-child, +.sortable thead th:last-child { border-top-right-radius: 4px; } +.sortable td, +.sortable th { + padding: 10px; +} body { font-size: 14px; diff --git a/dist/example.min.css b/dist/example.min.css index 6fa91a9..cae9e50 100644 --- a/dist/example.min.css +++ b/dist/example.min.css @@ -1 +1 @@ -.sortable thead th:not(.no-sort){cursor:pointer}.sortable thead th:not(.no-sort)::after,.sortable thead th:not(.no-sort)::before{transition:color .1s ease-in-out;font-size:1.2em;color:rgba(0,0,0,0)}.sortable thead th:not(.no-sort)::after{margin-left:3px;content:"▸"}.sortable thead th:not(.no-sort):hover::after{color:inherit}.sortable thead th:not(.no-sort)[aria-sort=descending]::after{color:inherit;content:"▾"}.sortable thead th:not(.no-sort)[aria-sort=ascending]::after{color:inherit;content:"▴"}.sortable thead th:not(.no-sort).indicator-left::after{content:""}.sortable thead th:not(.no-sort).indicator-left::before{margin-right:3px;content:"▸"}.sortable thead th:not(.no-sort).indicator-left:hover::before{color:inherit}.sortable thead th:not(.no-sort).indicator-left[aria-sort=descending]::before{color:inherit;content:"▾"}.sortable thead th:not(.no-sort).indicator-left[aria-sort=ascending]::before{color:inherit;content:"▴"}.sortable{--stripe-bg: #e4e4e4;--stripe-color: #000;--stripe-bg-odd: #fff;--stripe-color-odd: #111;--th-bg: #808080;--th-color: #fff;border-spacing:0}.sortable.sticky thead th{position:sticky;top:0;z-index:1}.sortable tbody tr{background-color:var(--stripe-bg);color:var(--stripe-color)}.sortable tbody tr:nth-child(odd){background-color:var(--stripe-bg-odd);color:var(--stripe-color-odd)}.sortable thead th{background:var(--th-bg);color:var(--th-color);font-weight:normal;text-align:left;text-transform:capitalize;vertical-align:baseline;white-space:nowrap}.sortable td,.sortable th{padding:10px}.sortable td:first-child,.sortable th:first-child{border-top-left-radius:4px}.sortable td:last-child,.sortable th:last-child{border-top-right-radius:4px}body{font-size:14px}p{line-height:1.7em}code{font-family:monospace;background:#eee;padding:5px;border-radius:2px}*{box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sortable:nth-of-type(4) th:nth-child(7),thead th.no-sort{background:pink !important;color:red !important}.sortable:nth-of-type(4) th:nth-child(7){pointer-events:none}.sortable:nth-of-type(4) th:nth-child(7)::after{color:red;content:"(also not sortable)";font-size:.9em;display:block}.lefty td:nth-child(2),.lefty th:nth-child(2){text-align:right}@media(prefers-color-scheme: dark){body{background-color:#121212;color:#e0e0e0}code{background:#333;color:#e0e0e0}.sortable:nth-of-type(4) th:nth-child(7),thead th.no-sort{background:#444 !important;color:#ff6b6b !important}.sortable:nth-of-type(4) th:nth-child(7)::after{color:#ff6b6b}*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}} \ No newline at end of file +.sortable thead th:not(.no-sort){cursor:pointer}.sortable thead th:not(.no-sort)::after,.sortable thead th:not(.no-sort)::before{transition:color .1s ease-in-out;font-size:1.2em;color:rgba(0,0,0,0)}.sortable thead th:not(.no-sort)::after{margin-left:3px;content:"▸"}.sortable thead th:not(.no-sort):hover::after{color:inherit}.sortable thead th:not(.no-sort)[aria-sort=descending]::after{color:inherit;content:"▾"}.sortable thead th:not(.no-sort)[aria-sort=ascending]::after{color:inherit;content:"▴"}.sortable thead th:not(.no-sort).indicator-left::after{content:""}.sortable thead th:not(.no-sort).indicator-left::before{margin-right:3px;content:"▸"}.sortable thead th:not(.no-sort).indicator-left:hover::before{color:inherit}.sortable thead th:not(.no-sort).indicator-left[aria-sort=descending]::before{color:inherit;content:"▾"}.sortable thead th:not(.no-sort).indicator-left[aria-sort=ascending]::before{color:inherit;content:"▴"}.sortable{--stripe-bg: #e4e4e4;--stripe-color: #000;--stripe-bg-odd: #fff;--stripe-color-odd: #111;--th-bg: #808080;--th-color: #fff;border-spacing:0}.sortable.sticky thead th{position:sticky;top:0;z-index:1}.sortable tbody tr{background-color:var(--stripe-bg);color:var(--stripe-color)}.sortable tbody tr:nth-child(odd){background-color:var(--stripe-bg-odd);color:var(--stripe-color-odd)}.sortable thead th{background:var(--th-bg);color:var(--th-color);font-weight:normal;text-align:left;text-transform:capitalize;vertical-align:baseline;white-space:nowrap}.sortable thead td:first-child,.sortable thead th:first-child{border-top-left-radius:4px}.sortable thead td:last-child,.sortable thead th:last-child{border-top-right-radius:4px}.sortable td,.sortable th{padding:10px}body{font-size:14px}p{line-height:1.7em}code{font-family:monospace;background:#eee;padding:5px;border-radius:2px}*{box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sortable:nth-of-type(4) th:nth-child(7),thead th.no-sort{background:pink !important;color:red !important}.sortable:nth-of-type(4) th:nth-child(7){pointer-events:none}.sortable:nth-of-type(4) th:nth-child(7)::after{color:red;content:"(also not sortable)";font-size:.9em;display:block}.lefty td:nth-child(2),.lefty th:nth-child(2){text-align:right}@media(prefers-color-scheme: dark){body{background-color:#121212;color:#e0e0e0}code{background:#333;color:#e0e0e0}.sortable:nth-of-type(4) th:nth-child(7),thead th.no-sort{background:#444 !important;color:#ff6b6b !important}.sortable:nth-of-type(4) th:nth-child(7)::after{color:#ff6b6b}*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}} \ No newline at end of file diff --git a/dist/sortable.css b/dist/sortable.css index b260eee..1622b66 100644 --- a/dist/sortable.css +++ b/dist/sortable.css @@ -72,15 +72,15 @@ vertical-align: baseline; white-space: nowrap; } -.sortable td, -.sortable th { - padding: 10px; -} -.sortable td:first-child, -.sortable th:first-child { +.sortable thead td:first-child, +.sortable thead th:first-child { border-top-left-radius: 4px; } -.sortable td:last-child, -.sortable th:last-child { +.sortable thead td:last-child, +.sortable thead th:last-child { border-top-right-radius: 4px; +} +.sortable td, +.sortable th { + padding: 10px; } \ No newline at end of file diff --git a/dist/sortable.min.css b/dist/sortable.min.css index 08e14fe..36c5b08 100644 --- a/dist/sortable.min.css +++ b/dist/sortable.min.css @@ -1 +1 @@ -.sortable thead th:not(.no-sort){cursor:pointer}.sortable thead th:not(.no-sort)::after,.sortable thead th:not(.no-sort)::before{transition:color .1s ease-in-out;font-size:1.2em;color:rgba(0,0,0,0)}.sortable thead th:not(.no-sort)::after{margin-left:3px;content:"▸"}.sortable thead th:not(.no-sort):hover::after{color:inherit}.sortable thead th:not(.no-sort)[aria-sort=descending]::after{color:inherit;content:"▾"}.sortable thead th:not(.no-sort)[aria-sort=ascending]::after{color:inherit;content:"▴"}.sortable thead th:not(.no-sort).indicator-left::after{content:""}.sortable thead th:not(.no-sort).indicator-left::before{margin-right:3px;content:"▸"}.sortable thead th:not(.no-sort).indicator-left:hover::before{color:inherit}.sortable thead th:not(.no-sort).indicator-left[aria-sort=descending]::before{color:inherit;content:"▾"}.sortable thead th:not(.no-sort).indicator-left[aria-sort=ascending]::before{color:inherit;content:"▴"}.sortable{--stripe-bg: #e4e4e4;--stripe-color: #000;--stripe-bg-odd: #fff;--stripe-color-odd: #111;--th-bg: #808080;--th-color: #fff;border-spacing:0}.sortable.sticky thead th{position:sticky;top:0;z-index:1}.sortable tbody tr{background-color:var(--stripe-bg);color:var(--stripe-color)}.sortable tbody tr:nth-child(odd){background-color:var(--stripe-bg-odd);color:var(--stripe-color-odd)}.sortable thead th{background:var(--th-bg);color:var(--th-color);font-weight:normal;text-align:left;text-transform:capitalize;vertical-align:baseline;white-space:nowrap}.sortable td,.sortable th{padding:10px}.sortable td:first-child,.sortable th:first-child{border-top-left-radius:4px}.sortable td:last-child,.sortable th:last-child{border-top-right-radius:4px} \ No newline at end of file +.sortable thead th:not(.no-sort){cursor:pointer}.sortable thead th:not(.no-sort)::after,.sortable thead th:not(.no-sort)::before{transition:color .1s ease-in-out;font-size:1.2em;color:rgba(0,0,0,0)}.sortable thead th:not(.no-sort)::after{margin-left:3px;content:"▸"}.sortable thead th:not(.no-sort):hover::after{color:inherit}.sortable thead th:not(.no-sort)[aria-sort=descending]::after{color:inherit;content:"▾"}.sortable thead th:not(.no-sort)[aria-sort=ascending]::after{color:inherit;content:"▴"}.sortable thead th:not(.no-sort).indicator-left::after{content:""}.sortable thead th:not(.no-sort).indicator-left::before{margin-right:3px;content:"▸"}.sortable thead th:not(.no-sort).indicator-left:hover::before{color:inherit}.sortable thead th:not(.no-sort).indicator-left[aria-sort=descending]::before{color:inherit;content:"▾"}.sortable thead th:not(.no-sort).indicator-left[aria-sort=ascending]::before{color:inherit;content:"▴"}.sortable{--stripe-bg: #e4e4e4;--stripe-color: #000;--stripe-bg-odd: #fff;--stripe-color-odd: #111;--th-bg: #808080;--th-color: #fff;border-spacing:0}.sortable.sticky thead th{position:sticky;top:0;z-index:1}.sortable tbody tr{background-color:var(--stripe-bg);color:var(--stripe-color)}.sortable tbody tr:nth-child(odd){background-color:var(--stripe-bg-odd);color:var(--stripe-color-odd)}.sortable thead th{background:var(--th-bg);color:var(--th-color);font-weight:normal;text-align:left;text-transform:capitalize;vertical-align:baseline;white-space:nowrap}.sortable thead td:first-child,.sortable thead th:first-child{border-top-left-radius:4px}.sortable thead td:last-child,.sortable thead th:last-child{border-top-right-radius:4px}.sortable td,.sortable th{padding:10px} \ No newline at end of file diff --git a/dist/standalone.html b/dist/standalone.html deleted file mode 100644 index 410b3d1..0000000 --- a/dist/standalone.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - - sortable test - - - - -

Sortable examples

- -

Basic sort

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Tiebreaker

-

Sort by year

- - (Appearance manually changed using style attributes. Just for demonstration.) - -
-style="
-  --stripe-bg: #ff0;
-  --stripe-color: #000;
-  --stripe-bg-odd: #f0f;
-  --stripe-color-odd: #111;
-  --th-bg: blue;
-  --th-color: #fff;"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
- - -

Colspans

- - - - - - - - - - - - - - - - - - - - - - - - - -
nums + charsCHARS
333222BB
1111CCC
22333A
- -

Empty/null sorted last

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TextNumber
jkl0.4
abc0
should be sorted last(if click in this column)
def0.2
- -

class="no-sort"

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

numeric sorting

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
- -

Ascending sort

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Alternative sort

- - - - - - - - - - - - - - - - - - - - - - -
Movie NameSize
AB
DE
JK
- -

TR element with no TD element (invalid HTML)

- - - - - - - - - - - - - - - - - - - - -
Letters
CCC
DDD
AAA
- -

TD with "incorrect" whitespace

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
 SidekickMorty
- -

HTML Tag Support

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
- - - - - - - - diff --git a/dist/standalone.min.html b/dist/standalone.min.html deleted file mode 100644 index 039e0fc..0000000 --- a/dist/standalone.min.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - - sortable test - - - - -

Sortable examples

- -

Basic sort

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Tiebreaker

-

Sort by year

- - (Appearance manually changed using style attributes. Just for demonstration.) - -
-style="
-  --stripe-bg: #ff0;
-  --stripe-color: #000;
-  --stripe-bg-odd: #f0f;
-  --stripe-color-odd: #111;
-  --th-bg: blue;
-  --th-color: #fff;"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
- - -

Colspans

- - - - - - - - - - - - - - - - - - - - - - - - - -
nums + charsCHARS
333222BB
1111CCC
22333A
- -

Empty/null sorted last

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TextNumber
jkl0.4
abc0
should be sorted last(if click in this column)
def0.2
- -

class="no-sort"

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

numeric sorting

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
- -

Ascending sort

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Alternative sort

- - - - - - - - - - - - - - - - - - - - - - -
Movie NameSize
AB
DE
JK
- -

TR element with no TD element (invalid HTML)

- - - - - - - - - - - - - - - - - - - - -
Letters
CCC
DDD
AAA
- -

TD with "incorrect" whitespace

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
 SidekickMorty
- -

HTML Tag Support

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
- - - - - - - - diff --git a/docs/example.css b/docs/example.css index 6b8861c..aeabdac 100644 --- a/docs/example.css +++ b/docs/example.css @@ -72,18 +72,18 @@ vertical-align: baseline; white-space: nowrap; } -.sortable td, -.sortable th { - padding: 10px; -} -.sortable td:first-child, -.sortable th:first-child { +.sortable thead td:first-child, +.sortable thead th:first-child { border-top-left-radius: 4px; } -.sortable td:last-child, -.sortable th:last-child { +.sortable thead td:last-child, +.sortable thead th:last-child { border-top-right-radius: 4px; } +.sortable td, +.sortable th { + padding: 10px; +} body { font-size: 14px; diff --git a/docs/index.html b/docs/index.html index 5c0aa76..1bd5005 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,6 +6,7 @@ sortable test + @@ -344,6 +345,7 @@

HTML Tag Support

setTimeout(() => { const table = document.createElement('table') table.classList.add('sortable') + table.classList.add('searchable') table.innerHTML = ` @@ -358,13 +360,15 @@

HTML Tag Support

` const div = document.createElement('div') div.innerHTML = `

MutationObserver Test

-

This table was added using setTimeout. It will be sorted by default when using the sortable.auto.js package.

` +

This table was added using setTimeout. It will be sorted by default when using the sortable.auto.js package.

+

Just for fun we made it searchable also.

` document.body.insertBefore(div, document.body.firstChild) // If I append the the table to the div before appending it to the body, // the MutationObserver will not trigger, since we are adding a div, not a table.. div.appendChild(table) }, 2000) // Long delay so you can see the table being added + diff --git a/index.html b/index.html index cb376aa..ac13fa1 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,7 @@ sortable test +

Sortable examples

@@ -343,6 +344,7 @@

HTML Tag Support

setTimeout(() => { const table = document.createElement('table') table.classList.add('sortable') + table.classList.add('searchable') table.innerHTML = ` @@ -357,13 +359,15 @@

HTML Tag Support

` const div = document.createElement('div') div.innerHTML = `

MutationObserver Test

-

This table was added using setTimeout. It will be sorted by default when using the sortable.auto.js package.

` +

This table was added using setTimeout. It will be sorted by default when using the sortable.auto.js package.

+

Just for fun we made it searchable also.

` document.body.insertBefore(div, document.body.firstChild) // If I append the the table to the div before appending it to the body, // the MutationObserver will not trigger, since we are adding a div, not a table.. div.appendChild(table) }, 2000) // Long delay so you can see the table being added + diff --git a/package.json b/package.json index 118222c..2f82988 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@eslint/js": "^9.38.0", "@playwright/test": "^1.56.1", "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.4", + "@rollup/plugin-typescript": "^12.3.0", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", "@types/jsdom": "^27.0.0", @@ -70,7 +70,7 @@ "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.4", "globals": "^16.4.0", - "google-closure-compiler": "^20251019.0.0", + "google-closure-compiler": "^20251021.0.0", "husky": "^9.1.7", "jest": "^30.2.0", "jsdom": "^27.0.1", @@ -83,7 +83,7 @@ "tslib": "^2.8.1", "tsx": "^4.20.6", "typescript": "^5.9.3", - "vite": "^7.1.11", - "vitest": "^3.2.4" + "vite": "^7.1.12", + "vitest": "^4.0.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f719224..987b26f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: ^0.4.4 version: 0.4.4(rollup@4.52.5) '@rollup/plugin-typescript': - specifier: ^12.1.4 - version: 12.1.4(rollup@4.52.5)(tslib@2.8.1)(typescript@5.9.3) + specifier: ^12.3.0 + version: 12.3.0(rollup@4.52.5)(tslib@2.8.1)(typescript@5.9.3) '@testing-library/dom': specifier: ^10.4.1 version: 10.4.1 @@ -66,8 +66,8 @@ importers: specifier: ^16.4.0 version: 16.4.0 google-closure-compiler: - specifier: ^20251019.0.0 - version: 20251019.0.0 + specifier: ^20251021.0.0 + version: 20251021.0.0 husky: specifier: ^9.1.7 version: 9.1.7 @@ -105,11 +105,11 @@ importers: specifier: ^5.9.3 version: 5.9.3 vite: - specifier: ^7.1.11 - version: 7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + specifier: ^7.1.12 + version: 7.1.12(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) vitest: - specifier: ^3.2.4 - version: 3.2.4(@types/node@24.9.1)(jsdom@27.0.1(postcss@8.5.6))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + specifier: ^4.0.3 + version: 4.0.3(@types/node@24.9.1)(jsdom@27.0.1(postcss@8.5.6))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) packages: @@ -790,8 +790,8 @@ packages: rollup: optional: true - '@rollup/plugin-typescript@12.1.4': - resolution: {integrity: sha512-s5Hx+EtN60LMlDBvl5f04bEiFZmAepk27Q+mr85L/00zPDn1jtzlTV6FWn81MaIwqfWzKxmOJrBWHU6vtQyedQ==} + '@rollup/plugin-typescript@12.3.0': + resolution: {integrity: sha512-7DP0/p7y3t67+NabT9f8oTBFE6gGkto4SA6Np2oudYmZE/m1dt8RB0SjL1msMxFpLo631qjRCcBlAbq1ml/Big==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^2.14.0||^3.0.0||^4.0.0 @@ -931,6 +931,9 @@ packages: '@sinonjs/fake-timers@13.0.5': resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -1153,34 +1156,34 @@ packages: cpu: [x64] os: [win32] - '@vitest/expect@3.2.4': - resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/expect@4.0.3': + resolution: {integrity: sha512-v3eSDx/bF25pzar6aEJrrdTXJduEBU3uSGXHslIdGIpJVP8tQQHV6x1ZfzbFQ/bLIomLSbR/2ZCfnaEGkWkiVQ==} - '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + '@vitest/mocker@4.0.3': + resolution: {integrity: sha512-evZcRspIPbbiJEe748zI2BRu94ThCBE+RkjCpVF8yoVYuTV7hMe+4wLF/7K86r8GwJHSmAPnPbZhpXWWrg1qbA==} peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + vite: ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@3.2.4': - resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/pretty-format@4.0.3': + resolution: {integrity: sha512-N7gly/DRXzxa9w9sbDXwD9QNFYP2hw90LLLGDobPNwiWgyW95GMxsCt29/COIKKh3P7XJICR38PSDePenMBtsw==} - '@vitest/runner@3.2.4': - resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + '@vitest/runner@4.0.3': + resolution: {integrity: sha512-1/aK6fPM0lYXWyGKwop2Gbvz1plyTps/HDbIIJXYtJtspHjpXIeB3If07eWpVH4HW7Rmd3Rl+IS/+zEAXrRtXA==} - '@vitest/snapshot@3.2.4': - resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + '@vitest/snapshot@4.0.3': + resolution: {integrity: sha512-amnYmvZ5MTjNCP1HZmdeczAPLRD6iOm9+2nMRUGxbe/6sQ0Ymur0NnR9LIrWS8JA3wKE71X25D6ya/3LN9YytA==} - '@vitest/spy@3.2.4': - resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/spy@4.0.3': + resolution: {integrity: sha512-82vVL8Cqz7rbXaNUl35V2G7xeNMAjBdNOVaHbrzznT9BmiCiPOzhf0FhU3eP41nP1bLDm/5wWKZqkG4nyU95DQ==} - '@vitest/utils@3.2.4': - resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@vitest/utils@4.0.3': + resolution: {integrity: sha512-qV6KJkq8W3piW6MDIbGOmn1xhvcW4DuA07alqaQ+vdx7YA49J85pnwnxigZVQFQw3tWnQNRKWwhz5wbP6iv/GQ==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -1326,10 +1329,6 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1345,8 +1344,8 @@ packages: caniuse-lite@1.0.30001751: resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==} - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + chai@6.2.0: + resolution: {integrity: sha512-aUTnJc/JipRzJrNADXVvpVqi6CO0dn3nx4EVPxijri+fj3LUUDyZQOgVeW54Ob3Y1Xh9Iz8f+CgaCl8v0mn9bA==} engines: {node: '>=18'} chalk@4.1.2: @@ -1361,10 +1360,6 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} - chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -1451,10 +1446,6 @@ packages: babel-plugin-macros: optional: true - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} - deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -1747,31 +1738,31 @@ packages: resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} engines: {node: '>=18'} - google-closure-compiler-java@20251019.0.0: - resolution: {integrity: sha512-cT2YhIWRPkQTkD4gI3IiLY8b0Ah9TrJdp89sASMM/EQqJl6AyMWBkMHNUIXCg2HSk/8O3OPHZziAZgHl/Ey5Vw==} + google-closure-compiler-java@20251021.0.0: + resolution: {integrity: sha512-/vftlI6xy44Zozn5IAo8sRDo2J8PqhgKBJOSKJes9PJKvbKV13RA+cSTnyBZ/3GgEHZdViW69y5nhMcnuB0zzQ==} - google-closure-compiler-linux-arm64@20251019.0.0: - resolution: {integrity: sha512-N5GkKpmWDulaULlXrncLvFluI85ORJcQksDfzThHsnn3yh6PwIOgsdwWHkAB1lZw3LUtgzyRhIvaxLrEQI6vwg==} + google-closure-compiler-linux-arm64@20251021.0.0: + resolution: {integrity: sha512-7KK3H0leUlYdnuE93OYCOuVinWpDrB+2Ci4wimHnJmksisMLfNUf4/exqtruj/QJDb7LWp2tXz8QUn+/jq1isw==} cpu: [arm64] os: [linux] - google-closure-compiler-linux@20251019.0.0: - resolution: {integrity: sha512-XlC9c3NVi+PpcbLY3XtgMvzZFCAoNcBZKqACu742wnZvGYWPhCaYEVow5gLnGsma9RmxDg+T6rc2HMjxg2vesw==} + google-closure-compiler-linux@20251021.0.0: + resolution: {integrity: sha512-ZSOLjEu/9F7S2r0iIwvptGGrl9TfXZCbHtqhloh3TF5YUUfBSnE17TzjtxM6ikmbSKQuNcJO6fcnMr3zJVESuA==} cpu: [x32, x64] os: [linux] - google-closure-compiler-macos@20251019.0.0: - resolution: {integrity: sha512-d4skTdyJ2lZHflgdj4vw7bfEAfLqWka4d1dI7vH5pH2iLAWnlF3KN18bwpfOC7eSyEsgwGvoBJyLEs/7lW8adw==} + google-closure-compiler-macos@20251021.0.0: + resolution: {integrity: sha512-MNuDs8bM73Yaxj6/bDwl7jeoQMSHlZPwvSA5OGa6rreyJhMNhHaBH65D6oLLr7aIZ3D9DTABalvrqV9i5V3SwQ==} cpu: [arm64] os: [darwin] - google-closure-compiler-windows@20251019.0.0: - resolution: {integrity: sha512-i3NRfaSmHVHDCwSz3jVv/at3GKC//eZKgOzHHOSa47usSx0rHag1WuP4xZAB5Xn77P7mPsKY2jXzuqsClYAXjw==} + google-closure-compiler-windows@20251021.0.0: + resolution: {integrity: sha512-lf/lw5V2EbiYtb/PNmKFtsxud+VkFWFkAFQaFnDIu9MgactYiH0iuXxjbgCK4LkvREG8jT23RuslsybWCH3dpw==} cpu: [x32, x64] os: [win32] - google-closure-compiler@20251019.0.0: - resolution: {integrity: sha512-ZmLF/Z7pRibX/7o2MZZ7zZx43VmXpAUB5Ioc76dT+FrY4GOND5lsF1Q9tBmaC25O63OsDqRRoar9vnNGxY1tDg==} + google-closure-compiler@20251021.0.0: + resolution: {integrity: sha512-P2IhtfYH/9LypJOZq+eU/pI3SKcs9Hz7/6EOXD8bh4FZQiG2z/XXnaEmzVmIJ8lrVE7JuO5dZwOyPwewxd2P+w==} engines: {node: '>=18'} hasBin: true @@ -2047,9 +2038,6 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -2117,9 +2105,6 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} - lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -2295,10 +2280,6 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2569,9 +2550,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@3.1.0: - resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2616,16 +2594,8 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} - - tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} - - tinyspy@4.0.4: - resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} tldts-core@7.0.17: @@ -2707,13 +2677,8 @@ packages: resolution: {integrity: sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==} engines: {node: '>=10.13.0'} - vite-node@3.2.4: - resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - - vite@7.1.11: - resolution: {integrity: sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==} + vite@7.1.12: + resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -2752,16 +2717,18 @@ packages: yaml: optional: true - vitest@3.2.4: - resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vitest@4.0.3: + resolution: {integrity: sha512-IUSop8jgaT7w0g1yOM/35qVtKjr/8Va4PrjzH1OUb0YH4c3OXB2lCZDkMAB6glA8T5w8S164oJGsbcmAecr4sA==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.4 - '@vitest/ui': 3.2.4 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.3 + '@vitest/browser-preview': 4.0.3 + '@vitest/browser-webdriverio': 4.0.3 + '@vitest/ui': 4.0.3 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -2771,7 +2738,11 @@ packages: optional: true '@types/node': optional: true - '@vitest/browser': + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': optional: true '@vitest/ui': optional: true @@ -3585,7 +3556,7 @@ snapshots: optionalDependencies: rollup: 4.52.5 - '@rollup/plugin-typescript@12.1.4(rollup@4.52.5)(tslib@2.8.1)(typescript@5.9.3)': + '@rollup/plugin-typescript@12.3.0(rollup@4.52.5)(tslib@2.8.1)(typescript@5.9.3)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.52.5) resolve: 1.22.11 @@ -3678,6 +3649,8 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 + '@standard-schema/spec@1.0.0': {} + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.27.1 @@ -3921,47 +3894,44 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@vitest/expect@3.2.4': + '@vitest/expect@4.0.3': dependencies: + '@standard-schema/spec': 1.0.0 '@types/chai': 5.2.3 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.3.3 - tinyrainbow: 2.0.0 + '@vitest/spy': 4.0.3 + '@vitest/utils': 4.0.3 + chai: 6.2.0 + tinyrainbow: 3.0.3 - '@vitest/mocker@3.2.4(vite@7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))': + '@vitest/mocker@4.0.3(vite@7.1.12(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))': dependencies: - '@vitest/spy': 3.2.4 + '@vitest/spy': 4.0.3 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - vite: 7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + vite: 7.1.12(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) - '@vitest/pretty-format@3.2.4': + '@vitest/pretty-format@4.0.3': dependencies: - tinyrainbow: 2.0.0 + tinyrainbow: 3.0.3 - '@vitest/runner@3.2.4': + '@vitest/runner@4.0.3': dependencies: - '@vitest/utils': 3.2.4 + '@vitest/utils': 4.0.3 pathe: 2.0.3 - strip-literal: 3.1.0 - '@vitest/snapshot@3.2.4': + '@vitest/snapshot@4.0.3': dependencies: - '@vitest/pretty-format': 3.2.4 + '@vitest/pretty-format': 4.0.3 magic-string: 0.30.19 pathe: 2.0.3 - '@vitest/spy@3.2.4': - dependencies: - tinyspy: 4.0.4 + '@vitest/spy@4.0.3': {} - '@vitest/utils@3.2.4': + '@vitest/utils@4.0.3': dependencies: - '@vitest/pretty-format': 3.2.4 - loupe: 3.2.1 - tinyrainbow: 2.0.0 + '@vitest/pretty-format': 4.0.3 + tinyrainbow: 3.0.3 acorn-jsx@5.3.2(acorn@8.15.0): dependencies: @@ -4119,8 +4089,6 @@ snapshots: buffer-from@1.1.2: {} - cac@6.7.14: {} - callsites@3.1.0: {} camelcase@5.3.1: {} @@ -4129,13 +4097,7 @@ snapshots: caniuse-lite@1.0.30001751: {} - chai@5.3.3: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 + chai@6.2.0: {} chalk@4.1.2: dependencies: @@ -4146,8 +4108,6 @@ snapshots: char-regex@1.0.2: {} - check-error@2.1.1: {} - chokidar@4.0.3: dependencies: readdirp: 4.1.2 @@ -4219,8 +4179,6 @@ snapshots: dedent@1.7.0: {} - deep-eql@5.0.2: {} - deep-is@0.1.4: {} deepmerge@4.3.1: {} @@ -4532,32 +4490,32 @@ snapshots: globals@16.4.0: {} - google-closure-compiler-java@20251019.0.0: {} + google-closure-compiler-java@20251021.0.0: {} - google-closure-compiler-linux-arm64@20251019.0.0: + google-closure-compiler-linux-arm64@20251021.0.0: optional: true - google-closure-compiler-linux@20251019.0.0: + google-closure-compiler-linux@20251021.0.0: optional: true - google-closure-compiler-macos@20251019.0.0: + google-closure-compiler-macos@20251021.0.0: optional: true - google-closure-compiler-windows@20251019.0.0: + google-closure-compiler-windows@20251021.0.0: optional: true - google-closure-compiler@20251019.0.0: + google-closure-compiler@20251021.0.0: dependencies: chalk: 5.6.2 - google-closure-compiler-java: 20251019.0.0 + google-closure-compiler-java: 20251021.0.0 minimist: 1.2.8 vinyl: 3.0.1 vinyl-sourcemaps-apply: 0.2.1 optionalDependencies: - google-closure-compiler-linux: 20251019.0.0 - google-closure-compiler-linux-arm64: 20251019.0.0 - google-closure-compiler-macos: 20251019.0.0 - google-closure-compiler-windows: 20251019.0.0 + google-closure-compiler-linux: 20251021.0.0 + google-closure-compiler-linux-arm64: 20251021.0.0 + google-closure-compiler-macos: 20251021.0.0 + google-closure-compiler-windows: 20251021.0.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -5005,8 +4963,6 @@ snapshots: js-tokens@4.0.0: {} - js-tokens@9.0.1: {} - js-yaml@3.14.1: dependencies: argparse: 1.0.10 @@ -5081,8 +5037,6 @@ snapshots: lodash@4.17.21: {} - loupe@3.2.1: {} - lru-cache@10.4.3: {} lru-cache@11.2.2: {} @@ -5235,8 +5189,6 @@ snapshots: pathe@2.0.3: {} - pathval@2.0.1: {} - picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -5491,10 +5443,6 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@3.1.0: - dependencies: - js-tokens: 9.0.1 - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -5546,11 +5494,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - tinypool@1.1.1: {} - - tinyrainbow@2.0.0: {} - - tinyspy@4.0.4: {} + tinyrainbow@3.0.3: {} tldts-core@7.0.17: {} @@ -5651,28 +5595,7 @@ snapshots: - bare-abort-controller - react-native-b4a - vite-node@3.2.4(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6): - dependencies: - cac: 6.7.14 - debug: 4.4.3 - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vite@7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6): + vite@7.1.12(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6): dependencies: esbuild: 0.25.11 fdir: 6.5.0(picomatch@4.0.3) @@ -5687,18 +5610,17 @@ snapshots: terser: 5.44.0 tsx: 4.20.6 - vitest@3.2.4(@types/node@24.9.1)(jsdom@27.0.1(postcss@8.5.6))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6): + vitest@4.0.3(@types/node@24.9.1)(jsdom@27.0.1(postcss@8.5.6))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6): dependencies: - '@types/chai': 5.2.3 - '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 3.2.4 - '@vitest/snapshot': 3.2.4 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.3.3 + '@vitest/expect': 4.0.3 + '@vitest/mocker': 4.0.3(vite@7.1.12(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + '@vitest/pretty-format': 4.0.3 + '@vitest/runner': 4.0.3 + '@vitest/snapshot': 4.0.3 + '@vitest/spy': 4.0.3 + '@vitest/utils': 4.0.3 debug: 4.4.3 + es-module-lexer: 1.7.0 expect-type: 1.2.2 magic-string: 0.30.19 pathe: 2.0.3 @@ -5707,10 +5629,8 @@ snapshots: tinybench: 2.9.0 tinyexec: 0.3.2 tinyglobby: 0.2.15 - tinypool: 1.1.1 - tinyrainbow: 2.0.0 - vite: 7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) - vite-node: 3.2.4(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + tinyrainbow: 3.0.3 + vite: 7.1.12(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.9.1 diff --git a/src/scss/sortable.scss b/src/scss/sortable.scss index ad857bb..4660738 100755 --- a/src/scss/sortable.scss +++ b/src/scss/sortable.scss @@ -24,12 +24,14 @@ tr { background-color: var(--stripe-bg); color: var(--stripe-color); + &:nth-child(odd) { background-color: var(--stripe-bg-odd); color: var(--stripe-color-odd); } } } + thead { th { background: var(--th-bg); @@ -40,17 +42,20 @@ vertical-align: baseline; white-space: nowrap; } + + td, + th { + &:first-child { + border-top-left-radius: 4px; + } + + &:last-child { + border-top-right-radius: 4px; + } + } } td, th { padding: 10px; - - &:first-child { - border-top-left-radius: 4px; - } - - &:last-child { - border-top-right-radius: 4px; - } } } diff --git a/tests/benchmark.spec.ts b/tests/benchmark.spec.ts index de056df..5584e9d 100644 --- a/tests/benchmark.spec.ts +++ b/tests/benchmark.spec.ts @@ -54,12 +54,14 @@ test.describe('Sortable Performance Benchmarks', () => { ) }) + // My current laptop has broken ram, so I need to double the time limits locally + const modifier = process.env.CI ? 1 : 2 const benchmarkConfigs = [ - { rows: 100, cols: 5, name: 'Small table', maxTime: 60 }, - { rows: 500, cols: 5, name: 'Medium table', maxTime: 200 }, - { rows: 1000, cols: 5, name: 'Large table', maxTime: 500 }, - { rows: 2000, cols: 5, name: 'Very large table', maxTime: 1000 }, - { rows: 100, cols: 10, name: 'Wide table', maxTime: 100 }, + { rows: 100, cols: 5, name: 'Small table', maxTime: 50 * modifier }, + { rows: 500, cols: 5, name: 'Medium table', maxTime: 200 * modifier }, + { rows: 1000, cols: 5, name: 'Large table', maxTime: 500 * modifier }, + { rows: 2000, cols: 5, name: 'Very large table', maxTime: 1000 * modifier }, + { rows: 100, cols: 10, name: 'Wide table', maxTime: 50 * modifier }, // width should have no impact ] for (const config of benchmarkConfigs) {