diff --git a/.vscode/settings.json b/.vscode/settings.json
index 2568ea7b3..bd6e1b612 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -3,5 +3,6 @@
"javascript",
"typescript"
],
- "typescript.format.semicolons": "insert"
+ "typescript.format.semicolons": "insert",
+ "typescript.tsdk": "node_modules\\typescript\\lib"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ddfc46584..13c5aa42f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,21 +4,80 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [5.0.0-beta.3](https://github.com/ghiscoding/slickgrid-universal/compare/v5.0.0-beta.2...v5.0.0-beta.3) (2024-05-09)
+
+### Bug Fixes
+
+* **common:** consider target size when auto-position picker/modal ([#1517](https://github.com/ghiscoding/slickgrid-universal/issues/1517)) ([e3a70b8](https://github.com/ghiscoding/slickgrid-universal/commit/e3a70b810d04c963f48454b78053c1bd45f96ebf)) - by @ghiscoding
+* **common:** Select Editor should always close with Escape key ([#1512](https://github.com/ghiscoding/slickgrid-universal/issues/1512)) ([e37bb28](https://github.com/ghiscoding/slickgrid-universal/commit/e37bb281ee83c25e9c4e15930e06bf9a044c65e9)) - by @ghiscoding
+* **core:** tweak setupColumnSort() to fix exception with hidden col ([#1509](https://github.com/ghiscoding/slickgrid-universal/issues/1509)) ([94b836a](https://github.com/ghiscoding/slickgrid-universal/commit/94b836a025ecb19b72f439079382280740b51027)) - by @ghiscoding
+* **editors:** body click or Escape key should cancel Select Editor ([#1513](https://github.com/ghiscoding/slickgrid-universal/issues/1513)) ([3d765a9](https://github.com/ghiscoding/slickgrid-universal/commit/3d765a9d282b684c38c550a1e5736cb1b2132f8e)) - by @ghiscoding
+* make some more cleanup with now optional DOMPurify ([#1508](https://github.com/ghiscoding/slickgrid-universal/issues/1508)) ([7fafbcc](https://github.com/ghiscoding/slickgrid-universal/commit/7fafbcc21fccfcd83d3ab103f313398c9d4b82e2)) - by @ghiscoding
+* **plugins:** clicking a grid cell should close any open menu ([#1515](https://github.com/ghiscoding/slickgrid-universal/issues/1515)) ([383792d](https://github.com/ghiscoding/slickgrid-universal/commit/383792d389e56239d62874842a50ec838f0bd3e9)) - by @ghiscoding
+* **styling:** improve UI & fix small issues found after testing upstream ([#1510](https://github.com/ghiscoding/slickgrid-universal/issues/1510)) ([a4ef70f](https://github.com/ghiscoding/slickgrid-universal/commit/a4ef70f70953c13f7abb0075586439931f18af74)) - by @ghiscoding
+* **tooltip:** only show tooltip that has value ([#1511](https://github.com/ghiscoding/slickgrid-universal/issues/1511)) ([2ff15da](https://github.com/ghiscoding/slickgrid-universal/commit/2ff15da4a21cd98b63f251b9b248454658dac698)) - by @ghiscoding
+
+## [5.0.0-beta.2](https://github.com/ghiscoding/slickgrid-universal/compare/v4.7.0...v5.0.0-beta.2) (2024-05-07)
+
+### ⚠ BREAKING CHANGES
+
+* migrate from Moment to Tempo (#1507)
+* **common:** make DOMPurify as optional sanitizer grid option (#1503)
+* **styling:** delete "bare" Themes but keep "lite" & add to Bootstrap (#1493)
+* **common:** migrate from `moment` to `moment-tiny` (#1456)
+* **filters:** remove native `Filters.select` (#1485)
+* **styling:** delete `checkmarkFormatter` and any Font-Awesome related (#1484)
+* **common:** migrate from Flatpickr to Vanilla-Calendar (#1466)
+* **styling:** remove SASS `math.div` polyfill (#1483)
+* **styling:** convert SVG icons to pure CSS (#1474)
+
+### Features
+
+* **common:** make DOMPurify as optional sanitizer grid option ([#1503](https://github.com/ghiscoding/slickgrid-universal/issues/1503)) ([0aa0859](https://github.com/ghiscoding/slickgrid-universal/commit/0aa085955f81303c0193fbdcd36ff220263814e3)) - by @ghiscoding
+* **common:** migrate from `moment` to `moment-tiny` ([#1456](https://github.com/ghiscoding/slickgrid-universal/issues/1456)) ([90690f4](https://github.com/ghiscoding/slickgrid-universal/commit/90690f4b6a4c8f8a7a221ddc1df69077384f48a9)) - by @ghiscoding
+* **common:** migrate from Flatpickr to Vanilla-Calendar ([#1466](https://github.com/ghiscoding/slickgrid-universal/issues/1466)) ([fb6e950](https://github.com/ghiscoding/slickgrid-universal/commit/fb6e950f429b4abd868fca86d9c304580a745b1c)) - by @ghiscoding
+* **filters:** remove native `Filters.select` ([#1485](https://github.com/ghiscoding/slickgrid-universal/issues/1485)) ([fae4c4a](https://github.com/ghiscoding/slickgrid-universal/commit/fae4c4a199409cec40ebb2703b6ae6d0d14e4af7)) - by @ghiscoding
+* migrate from Moment to Tempo ([#1507](https://github.com/ghiscoding/slickgrid-universal/issues/1507)) ([adef47f](https://github.com/ghiscoding/slickgrid-universal/commit/adef47f21a0e32bd32ec4efce931770dc252d3b5)) - by @ghiscoding
+* **styling:** convert SVG icons to pure CSS ([#1474](https://github.com/ghiscoding/slickgrid-universal/issues/1474)) ([70cda8a](https://github.com/ghiscoding/slickgrid-universal/commit/70cda8aa9304ac8ea4bab06390dc1b4c4423df2e)) - by @ghiscoding
+* **styling:** delete "bare" Themes but keep "lite" & add to Bootstrap ([#1493](https://github.com/ghiscoding/slickgrid-universal/issues/1493)) ([ca5ac06](https://github.com/ghiscoding/slickgrid-universal/commit/ca5ac0663c1670f9e9af1f88d6f6c85e9e064359)) - by @ghiscoding
+* **styling:** delete `checkmarkFormatter` and any Font-Awesome related ([#1484](https://github.com/ghiscoding/slickgrid-universal/issues/1484)) ([2de3fe2](https://github.com/ghiscoding/slickgrid-universal/commit/2de3fe2d07a14225a31fbc77e72c47895de664d6)) - by @ghiscoding
+* **styling:** remove SASS `math.div` polyfill ([#1483](https://github.com/ghiscoding/slickgrid-universal/issues/1483)) ([12661a3](https://github.com/ghiscoding/slickgrid-universal/commit/12661a3ff13ea844f6e16028216e1ed8808ee4d9)) - by @ghiscoding
+
+### Bug Fixes
+
+* **core:** col name from HTML shouldn't disappear in picker, fixes [#1475](https://github.com/ghiscoding/slickgrid-universal/issues/1475) ([#1476](https://github.com/ghiscoding/slickgrid-universal/issues/1476)) ([15a590b](https://github.com/ghiscoding/slickgrid-universal/commit/15a590b2e52f8864aeccc38f9a708c0453b6e4a6)) - by @ghiscoding
+* **editor:** autocomplete should only save empty when val is null ([#1500](https://github.com/ghiscoding/slickgrid-universal/issues/1500)) ([8de1340](https://github.com/ghiscoding/slickgrid-universal/commit/8de13402d244cb3aa2fcdb4af62e05b06f6cb27c)) - by @ghiscoding
+* **editor:** input editor should call save on focusout or blur of input ([#1497](https://github.com/ghiscoding/slickgrid-universal/issues/1497)) ([ccd344e](https://github.com/ghiscoding/slickgrid-universal/commit/ccd344ecd2e6abcff1d7b9f5e7d7fe85a4c20fdd)) - by @ghiscoding
+* **editor:** new Date Editor input clear button wasn't working ([#1487](https://github.com/ghiscoding/slickgrid-universal/issues/1487)) ([4ac34ee](https://github.com/ghiscoding/slickgrid-universal/commit/4ac34ee6d95398c77f10f89b0ad4c3168765b6a0)) - by @ghiscoding
+* **styling:** couple of small alignment issues when using flex ([#1496](https://github.com/ghiscoding/slickgrid-universal/issues/1496)) ([2188242](https://github.com/ghiscoding/slickgrid-universal/commit/21882420eb9c31b7922038fa45f373d42e2fb35f)) - by @ghiscoding
+* **styling:** empty warning should separate icon & text ([#1491](https://github.com/ghiscoding/slickgrid-universal/issues/1491)) ([240cbd3](https://github.com/ghiscoding/slickgrid-universal/commit/240cbd3b5a8cfb6a6cab563bc43d705332d59beb)) - by @ghiscoding
+* **styling:** properly import Vanilla-Calendar CSS and only once ([#1492](https://github.com/ghiscoding/slickgrid-universal/issues/1492)) ([75dce74](https://github.com/ghiscoding/slickgrid-universal/commit/75dce746659796f7d1c21e5ebcfd0418588df4c0)) - by @ghiscoding
+* **styling:** Row Move icon shouldn't show extra dot ([69f7bfc](https://github.com/ghiscoding/slickgrid-universal/commit/69f7bfcb7eb078815f5edb6d84d53c0905df27a1)) - by @ghiscoding-SE
+* **tooltip:** don't sanitize empty text, fixes empty tooltip being shown ([#1495](https://github.com/ghiscoding/slickgrid-universal/issues/1495)) ([dcc693b](https://github.com/ghiscoding/slickgrid-universal/commit/dcc693b26677873b93ccb770ff8ef9a514085341)) - by @ghiscoding
+* tweak setupColumnSort() to fix exception when col no longer exists ([#1477](https://github.com/ghiscoding/slickgrid-universal/issues/1477)) ([094d760](https://github.com/ghiscoding/slickgrid-universal/commit/094d7602d7170b2f395985ce5635041bb2b803d2)) - by @ghiscoding
+
# [4.7.0](https://github.com/ghiscoding/slickgrid-universal/compare/v4.6.3...v4.7.0) (2024-04-20)
### Bug Fixes
* **common:** don't try to strip tags on object input to calc cell width ([#1453](https://github.com/ghiscoding/slickgrid-universal/issues/1453)) ([5ab671b](https://github.com/ghiscoding/slickgrid-universal/commit/5ab671bee805f7b7d9b139e9bf7a14b31b5aea56)) - by @ghiscoding
+
* **common:** switch back to `autocompleter` with ESM build ([#1450](https://github.com/ghiscoding/slickgrid-universal/issues/1450)) ([ad66a12](https://github.com/ghiscoding/slickgrid-universal/commit/ad66a121b4a6b7718009948d873ceb8f5c66a32c)) - by @ghiscoding
+
* **core:** Editor.keyCaptureList is an array of numbers ([#1458](https://github.com/ghiscoding/slickgrid-universal/issues/1458)) ([62a686e](https://github.com/ghiscoding/slickgrid-universal/commit/62a686e7db4dc4ef65d0c426c8623dc8f1e3f9d9)) - by @ghiscoding
+
* **OData:** sorting columns via `id` instead of field property name, fixes [#1467](https://github.com/ghiscoding/slickgrid-universal/issues/1467) ([#1469](https://github.com/ghiscoding/slickgrid-universal/issues/1469)) ([0a4d402](https://github.com/ghiscoding/slickgrid-universal/commit/0a4d40255e240bddf752a2e7bf39a99ae234cc6e)) - by @zewa666
+
* **styling:** improve button & text colors for Dark Mode ([9414ab4](https://github.com/ghiscoding/slickgrid-universal/commit/9414ab4e24482d080f3113d32d96fe635856a871)) - by @ghiscoding-SE
+
* wrong operator comparison ([#1461](https://github.com/ghiscoding/slickgrid-universal/issues/1461)) ([abe772b](https://github.com/ghiscoding/slickgrid-universal/commit/abe772b9ad9480688ef000dddfa86d2cdc6b7e52)) - by @zewa666
### Features
* **common:** add global `defaultEditorOptions` & `defaultFilterOptions` ([#1470](https://github.com/ghiscoding/slickgrid-universal/issues/1470)) ([0462f17](https://github.com/ghiscoding/slickgrid-universal/commit/0462f17b215d5c1b88e1a9fe482877ed733486b3)) - by @ghiscoding
+
* **core:** add `getFilterArgs()` to `SlickDataView` ([#1457](https://github.com/ghiscoding/slickgrid-universal/issues/1457)) ([7563126](https://github.com/ghiscoding/slickgrid-universal/commit/7563126cfbf792fc86a494850e5a3bad7d8991f7)) - by @ghiscoding
+
* notify onValidationError on paste if validation failed ([#1462](https://github.com/ghiscoding/slickgrid-universal/issues/1462)) ([38b465c](https://github.com/ghiscoding/slickgrid-universal/commit/38b465cb8ebcdd6012b939677a4367c2dce010e9)) - by @zewa666
## [4.6.3](https://github.com/ghiscoding/slickgrid-universal/compare/v4.6.1...v4.6.3) (2024-03-31)
@@ -30,11 +89,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** move DOMPurify/SortableJS [@types](https://github.com/types) as dependencies ([51eaec7](https://github.com/ghiscoding/slickgrid-universal/commit/51eaec756120c93f0fbb9ed58b5784025b808e59)) - by @ghiscoding
+
* **common:** switch to `autocompleter-es` to get ESM build ([#1449](https://github.com/ghiscoding/slickgrid-universal/issues/1449)) ([aa59334](https://github.com/ghiscoding/slickgrid-universal/commit/aa59334d280d76078bc9cf36e66daa0bd4c6fac1)) - by @ghiscoding
+
* improve Dark Mode styling for icons barely visible in dark ([16b1a6e](https://github.com/ghiscoding/slickgrid-universal/commit/16b1a6e52bec83ed25bca077fe2ea30b5966f3ab)) - by @ghiscoding
+
* **pubsub:** externalize PubSub event to SlickEventData to stop bubbling ([#1444](https://github.com/ghiscoding/slickgrid-universal/issues/1444)) ([973d0ab](https://github.com/ghiscoding/slickgrid-universal/commit/973d0abb0a4df050ad68a6c7e6493bf7ae4abd52)) - by @ghiscoding
+
* revisit package `exports` to pass "are the types wrong" ([#1440](https://github.com/ghiscoding/slickgrid-universal/issues/1440)) ([20229f7](https://github.com/ghiscoding/slickgrid-universal/commit/20229f78adef51078f99fce3f5a46ac88280a048)) - by @ghiscoding
+
* **styling:** missing/too many borders compound filters w/group addon ([#1446](https://github.com/ghiscoding/slickgrid-universal/issues/1446)) ([863933f](https://github.com/ghiscoding/slickgrid-universal/commit/863933f8cd1988f5ae1b387839a99532cd58d92d)) - by @ghiscoding
+
* **tooltip:** allow multiple tooltips per grid cell ([#1448](https://github.com/ghiscoding/slickgrid-universal/issues/1448)) ([061c4a0](https://github.com/ghiscoding/slickgrid-universal/commit/061c4a087484238f7285eb27a1c238ac75972f19)) - by @ghiscoding
# [4.6.0](https://github.com/ghiscoding/slickgrid-universal/compare/v4.5.0...v4.6.0) (2024-03-23)
@@ -42,22 +107,35 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* `column.editor` and `gridOptions.editorFactory` type changed ([#1428](https://github.com/ghiscoding/slickgrid-universal/issues/1428)) ([bf8c5b9](https://github.com/ghiscoding/slickgrid-universal/commit/bf8c5b95aca22bced0d926d6ac118c9fa0e61411)) - by @ghiscoding
+
* **build:** add ESLint-TS rules to enforce `type` imports and exports ([#1432](https://github.com/ghiscoding/slickgrid-universal/issues/1432)) ([cce4693](https://github.com/ghiscoding/slickgrid-universal/commit/cce4693556e01d7f664fbe832ae4e7fd5776dc6b)) - by @ghiscoding
+
* **build:** add ESLint-TS rules to enforce `type` imports and exports ([#1437](https://github.com/ghiscoding/slickgrid-universal/issues/1437)) ([324c4fe](https://github.com/ghiscoding/slickgrid-universal/commit/324c4fee22f83655a3b25b08ae73dbcca2e1e6e7)) - by @ghiscoding
+
* **common:** add missing Filter `model` Type of `FilterConstructor` ([#1430](https://github.com/ghiscoding/slickgrid-universal/issues/1430)) ([3f3e952](https://github.com/ghiscoding/slickgrid-universal/commit/3f3e952b20b41dda5bf2cd1648c6d6f02e7c7943)) - by @ghiscoding
+
* **common:** bump ms-select to fix compatibility problem in Salesforce ([#1425](https://github.com/ghiscoding/slickgrid-universal/issues/1425)) ([d3d2d39](https://github.com/ghiscoding/slickgrid-universal/commit/d3d2d390a8a1b17d0cd3699ddebfea855fdc5f77)) - by @ghiscoding
+
* **common:** Select All checkbox shouldn't disappear w/Dark Mode toggle ([#1421](https://github.com/ghiscoding/slickgrid-universal/issues/1421)) ([5fab179](https://github.com/ghiscoding/slickgrid-universal/commit/5fab1792cfdf24172bd46556b6fe5513c93d19d1)) - by @ghiscoding
+
* Join type ([#1427](https://github.com/ghiscoding/slickgrid-universal/issues/1427)) ([21c76cc](https://github.com/ghiscoding/slickgrid-universal/commit/21c76cc9d921ad34516bd38070afd791ff55de56)) - by @zewa666
+
* **styling:** add border & box-shadow to Flatpickr in Dark Mode ([fdbb6ae](https://github.com/ghiscoding/slickgrid-universal/commit/fdbb6ae9de7069968af747240a9b2ad74b0c8184)) - by @ghiscoding
+
* **styling:** add missing orange border for Salesforce modified inputs ([e830dd3](https://github.com/ghiscoding/slickgrid-universal/commit/e830dd3df4c6c0176ac88304247571f5ef05d4ef)) - by @ghiscoding
+
* **styling:** add more visual cue for column picker uncheck row select ([b4712e9](https://github.com/ghiscoding/slickgrid-universal/commit/b4712e9a8c03b60457d9033f11affb7364231de2)) - by @ghiscoding
+
* **styling:** don't add filled border all side for group-addon btn ([30be835](https://github.com/ghiscoding/slickgrid-universal/commit/30be8353101157a00440dba0357f88879bd3acda)) - by @ghiscoding-SE
+
* **styling:** small Composite Editor fixes for Dark Mode ([#1417](https://github.com/ghiscoding/slickgrid-universal/issues/1417)) ([7e00087](https://github.com/ghiscoding/slickgrid-universal/commit/7e000877a85059e23d3aa4c00c04d0e4e1e0abc1)) - by @ghiscoding
### Features
* **common:** add optional "Toggle Dark Mode" in Grid Menu ([#1418](https://github.com/ghiscoding/slickgrid-universal/issues/1418)) ([990c1df](https://github.com/ghiscoding/slickgrid-universal/commit/990c1df2a39a6b5098c991b16f43c5679daf4bb5)) - by @ghiscoding
+
* **core:** rename SG `editorClass` & deprecate `internalColumnEditor` ([#1429](https://github.com/ghiscoding/slickgrid-universal/issues/1429)) ([409115c](https://github.com/ghiscoding/slickgrid-universal/commit/409115cecb132556e88abf6e281f4fcb52414d71)) - by @ghiscoding
+
* upgrade to ms-select-vanilla v3.x ([#1439](https://github.com/ghiscoding/slickgrid-universal/issues/1439)) ([8f2378e](https://github.com/ghiscoding/slickgrid-universal/commit/8f2378e6cfed3489ce487fe84947bdabd04e31d2)) - by @ghiscoding
# [4.5.0](https://github.com/ghiscoding/slickgrid-universal/compare/v4.4.1...v4.5.0) (2024-03-05)
@@ -65,22 +143,35 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* auto-resize not just grid but also headers for Salesforce tabs ([#1395](https://github.com/ghiscoding/slickgrid-universal/issues/1395)) ([6180461](https://github.com/ghiscoding/slickgrid-universal/commit/6180461b543cb7d4cc14d1504cb0db7d35990164)) - by @ghiscoding
+
* **common:** switch to `isomorphic-dompurify` for SSR support ([#1413](https://github.com/ghiscoding/slickgrid-universal/issues/1413)) ([b619453](https://github.com/ghiscoding/slickgrid-universal/commit/b619453fd9825500f2d9589e31bdcf5e17ac412d)), closes [/github.com/ghiscoding/Angular-Slickgrid/discussions/838#discussioncomment-8574215](https://github.com//github.com/ghiscoding/Angular-Slickgrid/discussions/838/issues/discussioncomment-8574215) - by @ghiscoding
+
* **core:** add extra checks for some objects to be a bit more strict ([#1404](https://github.com/ghiscoding/slickgrid-universal/issues/1404)) ([8b95c50](https://github.com/ghiscoding/slickgrid-universal/commit/8b95c505ed2409cde7b790f97b4fbc0d666ca459)) - by @ghiscoding
+
* **plugin:** the RowMove plugin cell should be selectable ([#1408](https://github.com/ghiscoding/slickgrid-universal/issues/1408)) ([8c01a13](https://github.com/ghiscoding/slickgrid-universal/commit/8c01a1361898fe3f3b6cfdba3239f93f2e8acec9)) - by @ghiscoding
+
* **styling:** add full width to grid container ([#1409](https://github.com/ghiscoding/slickgrid-universal/issues/1409)) ([eedc162](https://github.com/ghiscoding/slickgrid-universal/commit/eedc162e243b3c0bbf450bd404b199f5ee511926)) - by @ghiscoding
+
* **styling:** add menu shadow & increase contrast for Dark Mode ([bff2da0](https://github.com/ghiscoding/slickgrid-universal/commit/bff2da0dd027103c30fa86635b9e45460b10e700)) - by @ghiscoding
+
* **styling:** ms-select filter should use same color as other filters ([#1396](https://github.com/ghiscoding/slickgrid-universal/issues/1396)) ([a30d590](https://github.com/ghiscoding/slickgrid-universal/commit/a30d59066419d2c3324718f1d5497e8e89ebf749)) - by @ghiscoding
+
* **styling:** ms-select highlight bg-color same as nav highlight ([fe77341](https://github.com/ghiscoding/slickgrid-universal/commit/fe77341645f72be6c03a8e210dc08e6d0ef131d4)) - by @ghiscoding-SE
+
* **styling:** properly align flexbox ms-select icon+text vertically ([#1397](https://github.com/ghiscoding/slickgrid-universal/issues/1397)) ([e744d02](https://github.com/ghiscoding/slickgrid-universal/commit/e744d0256d25ba6ad5d538b827460828b6e0666f)) - by @ghiscoding
+
* **styling:** remove header menu open class for Dark Mode ([6a2e7e1](https://github.com/ghiscoding/slickgrid-universal/commit/6a2e7e13a18921c2b70caeb2690298173310aece)) - by @ghiscoding
+
* **styling:** tweak Composite Editor form disabled buttons style ([5052ba1](https://github.com/ghiscoding/slickgrid-universal/commit/5052ba19858ff2bced69f0846e00bbb36c9d0fde)) - by @ghiscoding
### Features
* **common:** upgrade `multiple-select-vanilla` to v2 ([#1401](https://github.com/ghiscoding/slickgrid-universal/issues/1401)) ([d6bb1d7](https://github.com/ghiscoding/slickgrid-universal/commit/d6bb1d7ef76100268456b2ab499c496a78debdd8)) - by @ghiscoding
+
* **deps:** simplify package TS Types exports ([#1402](https://github.com/ghiscoding/slickgrid-universal/issues/1402)) ([19bac52](https://github.com/ghiscoding/slickgrid-universal/commit/19bac52e5fcb8e523a26ab1f6564f0b6a2b93ef4)) - by @ghiscoding
+
* **editor:** add `onRendered` lifecycle callback option ([#1410](https://github.com/ghiscoding/slickgrid-universal/issues/1410)) ([9d348d6](https://github.com/ghiscoding/slickgrid-universal/commit/9d348d6e4b693e23a2959917e02a7bcfa55a0c90)) - by @ghiscoding
+
* **styling:** add Dark Mode grid option ([#1407](https://github.com/ghiscoding/slickgrid-universal/issues/1407)) ([855151b](https://github.com/ghiscoding/slickgrid-universal/commit/855151b9f47a5238e3069f8c85ba4ed8a5bf9bb6)) - by @ghiscoding
## [4.4.1](https://github.com/ghiscoding/slickgrid-universal/compare/v4.3.1...v4.4.1) (2024-02-13)
@@ -88,10 +179,15 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **ci:** disable Husky when pushing new release ([#1390](https://github.com/ghiscoding/slickgrid-universal/issues/1390)) ([6f9372e](https://github.com/ghiscoding/slickgrid-universal/commit/6f9372ebfb07a294935f81a09eff07549fab5185)) - by @ghiscoding
+
* **core:** replace `any` types by valid types ([#1378](https://github.com/ghiscoding/slickgrid-universal/issues/1378)) ([02c4bc1](https://github.com/ghiscoding/slickgrid-universal/commit/02c4bc15e0da31c055c0fac9eecb7c4a17df3eb7)) - by @ghiscoding
+
* **demo:** change trading demo full screen z-index lower than ms-select ([1f4a9ac](https://github.com/ghiscoding/slickgrid-universal/commit/1f4a9acd68bc9559420d48597f9214c16f48556e)) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#1381](https://github.com/ghiscoding/slickgrid-universal/issues/1381)) ([2562352](https://github.com/ghiscoding/slickgrid-universal/commit/25623527d05dd713123e1031b682f0a80cca37de)) - by @renovate-bot
+
* mouse cell selection with active editor ([#1382](https://github.com/ghiscoding/slickgrid-universal/issues/1382)) ([17549b8](https://github.com/ghiscoding/slickgrid-universal/commit/17549b89933b10688fe8d186ab18ab4c8b7e9f87)) - by @zewa666
+
* **publish:** do not npm publish `tsconfig.tsbuildinfo` ([#1373](https://github.com/ghiscoding/slickgrid-universal/issues/1373)) ([9223338](https://github.com/ghiscoding/slickgrid-universal/commit/922333843852ae861015e4bbec053d4937222aa2)) - by @ghiscoding
### Features
@@ -103,10 +199,15 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** replace `any` types by valid types ([#1378](https://github.com/ghiscoding/slickgrid-universal/issues/1378)) ([02c4bc1](https://github.com/ghiscoding/slickgrid-universal/commit/02c4bc15e0da31c055c0fac9eecb7c4a17df3eb7)) - by @ghiscoding
+
* **demo:** change trading demo full screen z-index lower than ms-select ([1f4a9ac](https://github.com/ghiscoding/slickgrid-universal/commit/1f4a9acd68bc9559420d48597f9214c16f48556e)) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#1381](https://github.com/ghiscoding/slickgrid-universal/issues/1381)) ([2562352](https://github.com/ghiscoding/slickgrid-universal/commit/25623527d05dd713123e1031b682f0a80cca37de)) - by @renovate-bot
+
* mouse cell selection with active editor ([#1382](https://github.com/ghiscoding/slickgrid-universal/issues/1382)) ([17549b8](https://github.com/ghiscoding/slickgrid-universal/commit/17549b89933b10688fe8d186ab18ab4c8b7e9f87)) - by @zewa666
+
* **publish:** do not npm publish `tsconfig.tsbuildinfo` ([#1373](https://github.com/ghiscoding/slickgrid-universal/issues/1373)) ([9223338](https://github.com/ghiscoding/slickgrid-universal/commit/922333843852ae861015e4bbec053d4937222aa2)) - by @ghiscoding
+
* **common:** make "ctrl + c" great again ([#1379](https://github.com/ghiscoding/slickgrid-universal/pull/1379)) ([3bf59e](3bf59e04f2fd9e234ca063b5827e6403a6fcd044)) - by @zewa666
### Features
@@ -118,15 +219,21 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** frozen grid w/hidden column should remove from DOM ([#1372](https://github.com/ghiscoding/slickgrid-universal/issues/1372)) ([2c1346e](https://github.com/ghiscoding/slickgrid-universal/commit/2c1346e53e0e5cba57c949f7b70d2b20d3dc1d22)) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#1368](https://github.com/ghiscoding/slickgrid-universal/issues/1368)) ([b49e895](https://github.com/ghiscoding/slickgrid-universal/commit/b49e89524815006c348917039342e53f00871110)) - by @renovate-bot
+
* Salesforce doesn't support Document Fragment ([#1365](https://github.com/ghiscoding/slickgrid-universal/issues/1365)) ([9e3fb5f](https://github.com/ghiscoding/slickgrid-universal/commit/9e3fb5f2f3220d6e57d2efc20fd85105a8a39454)) - by @ghiscoding
+
* **styling:** remove different bg-color on unorderable column ([#1358](https://github.com/ghiscoding/slickgrid-universal/issues/1358)) ([91426d1](https://github.com/ghiscoding/slickgrid-universal/commit/91426d1f6801680a5c40b3b900ab1a64cd771277)) - by @ghiscoding
### Performance Improvements
* **core:** convert `for..in` to `Object.keys().forEach` for better perf ([#1370](https://github.com/ghiscoding/slickgrid-universal/issues/1370)) ([29111a9](https://github.com/ghiscoding/slickgrid-universal/commit/29111a94756c34a2e01f2431c14b7ed806349a94)) - by @ghiscoding
+
* decrease calls to setItems & grid invalidate ([#1363](https://github.com/ghiscoding/slickgrid-universal/issues/1363)) ([cab6898](https://github.com/ghiscoding/slickgrid-universal/commit/cab68989ebd53178dfcee5ed293379dc8932a72f)) - by @ghiscoding
+
* **plugins:** decrease number of calls to translate all extensions only once ([#1359](https://github.com/ghiscoding/slickgrid-universal/issues/1359)) ([3e002f1](https://github.com/ghiscoding/slickgrid-universal/commit/3e002f15a06abd06893783e0667798f5ff8893cf)) - by @ghiscoding
+
* **plugins:** Row Base Editing tooltip title should be translated only once ([#1360](https://github.com/ghiscoding/slickgrid-universal/issues/1360)) ([ef4e8f9](https://github.com/ghiscoding/slickgrid-universal/commit/ef4e8f9f4bf491d670986c6dac8531274aaaa46b)) - by @ghiscoding
# [4.3.0](https://github.com/ghiscoding/slickgrid-universal/compare/v4.2.0...v4.3.0) (2024-01-20)
@@ -134,31 +241,53 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* `getCellFromPoint()` should return row/cell -1 outside grid canvas ([#1325](https://github.com/ghiscoding/slickgrid-universal/issues/1325)) ([b483e62](https://github.com/ghiscoding/slickgrid-universal/commit/b483e62fc3931f836c77677db67557adb2ca4edd)) - by @ghiscoding
+
* add grid & cell `role` for screen ready accessibility ([#1337](https://github.com/ghiscoding/slickgrid-universal/issues/1337)) ([7309fa8](https://github.com/ghiscoding/slickgrid-universal/commit/7309fa8de4fc00f930e68af090010d91080b6213)) - by @ghiscoding
+
* **core:** allow extra spaces in `headerCssClass` & other `cssClass` ([#1303](https://github.com/ghiscoding/slickgrid-universal/issues/1303)) ([59ebaa6](https://github.com/ghiscoding/slickgrid-universal/commit/59ebaa65b6882ed3274a3185f457ecef4b2c5b51)) - by @ghiscoding
+
* **core:** allow extra spaces to be striped to any css classes ([#1352](https://github.com/ghiscoding/slickgrid-universal/issues/1352)) ([e5e29c0](https://github.com/ghiscoding/slickgrid-universal/commit/e5e29c063a9e018c2148685cfea5fc43c89426b9)) - by @ghiscoding
+
* **core:** column resize handle could throw when invalid elm ([#1344](https://github.com/ghiscoding/slickgrid-universal/issues/1344)) ([41f6058](https://github.com/ghiscoding/slickgrid-universal/commit/41f60583831b7284cba56f2af9cfe45b4a09d617)) - by @ghiscoding
+
* **core:** DataView `inlineFilters` should allow ES6 arrow functions ([#1304](https://github.com/ghiscoding/slickgrid-universal/issues/1304)) ([25b9a10](https://github.com/ghiscoding/slickgrid-universal/commit/25b9a10fdd14585f1b303361b2814e860c6e7031)) - by @ghiscoding
+
* **core:** don't show column header empty title tooltip ([#1317](https://github.com/ghiscoding/slickgrid-universal/issues/1317)) ([8b20407](https://github.com/ghiscoding/slickgrid-universal/commit/8b2040754f1810191fb26f0a5a91a19eae13ebfd)) - by @ghiscoding
+
* **core:** EventHandler subscribed event should be SlickEventData type ([#1327](https://github.com/ghiscoding/slickgrid-universal/issues/1327)) ([2573310](https://github.com/ghiscoding/slickgrid-universal/commit/25733102dbcefcbacc2ce5d6f4c07bd9d1cce6a1)) - by @ghiscoding
+
* **core:** remove editor keydown keyCaptureList duplicate code ([#1322](https://github.com/ghiscoding/slickgrid-universal/issues/1322)) ([c5f6b85](https://github.com/ghiscoding/slickgrid-universal/commit/c5f6b8575513aa6eb0215a47a0365fdab0059c3e)) - by @ghiscoding
+
* **core:** SlickEvent handler event should be type of ArgType ([#1328](https://github.com/ghiscoding/slickgrid-universal/issues/1328)) ([a9cb8ee](https://github.com/ghiscoding/slickgrid-universal/commit/a9cb8ee3f1a5da4249851e5b701b027b3f72ad26)), closes [#1327](https://github.com/ghiscoding/slickgrid-universal/issues/1327) - by @ghiscoding
+
* **demo:** Unsaved Cell CSS Styling follow sort/filter/pagination ([#1313](https://github.com/ghiscoding/slickgrid-universal/issues/1313)) ([7619579](https://github.com/ghiscoding/slickgrid-universal/commit/761957987e85ed9829900739e659d8d02230ea12)) - by @ghiscoding
+
* Editors/Filters should create SlickEventData with event arg ([#1326](https://github.com/ghiscoding/slickgrid-universal/issues/1326)) ([e008902](https://github.com/ghiscoding/slickgrid-universal/commit/e008902e6d85a7a424ed8c9e32786490daac66ce)) - by @ghiscoding
+
* **plugin:** CustomDataView for CellSelectionModel & SlickCustomTooltip ([#1306](https://github.com/ghiscoding/slickgrid-universal/issues/1306)) ([3bdd300](https://github.com/ghiscoding/slickgrid-universal/commit/3bdd30038b93af2db1f2f4a8b7df72ca6a06a06e)) - by @ghiscoding
+
* regression with `onSelectedRowsChanged` not receiving correct `caller` prop ([#1341](https://github.com/ghiscoding/slickgrid-universal/issues/1341)) ([03cad4a](https://github.com/ghiscoding/slickgrid-universal/commit/03cad4a34bf13a8e1342306f9210525f5025321f)) - by @ghiscoding
+
* SlickEmptyWarningComponent should accept native HTML for CSP safe ([#1333](https://github.com/ghiscoding/slickgrid-universal/issues/1333)) ([4740f96](https://github.com/ghiscoding/slickgrid-universal/commit/4740f961813666cbae918cb4940e7c2ec57bec2d)) - by @ghiscoding
+
* when `onDragInit` return false it should stop ([#1340](https://github.com/ghiscoding/slickgrid-universal/issues/1340)) ([d9c714c](https://github.com/ghiscoding/slickgrid-universal/commit/d9c714c042739d5cbdbe51b876f16a3152d200e6)), closes [#1339](https://github.com/ghiscoding/slickgrid-universal/issues/1339) - by @ghiscoding
+
* when `onResizeStart` return false it should stop ([#1339](https://github.com/ghiscoding/slickgrid-universal/issues/1339)) ([5a3bd1c](https://github.com/ghiscoding/slickgrid-universal/commit/5a3bd1c0c6a19294fe6578766d6b2d56ac8e2cac)) - by @ghiscoding
### Features
* add `name` option to CheckboxSelectColumn plugin on columDef ([#1331](https://github.com/ghiscoding/slickgrid-universal/issues/1331)) ([abe344b](https://github.com/ghiscoding/slickgrid-universal/commit/abe344b025b385630077bfb63d5534a88b3b7d71)) - by @ghiscoding
+
* add `onBeforePasteCell` event to excel copy buffer ([#1298](https://github.com/ghiscoding/slickgrid-universal/issues/1298)) ([22037ca](https://github.com/ghiscoding/slickgrid-universal/commit/22037ca7918fc4bfb55bb4bf619cd280b564a351)) - by @zewa666
+
* add column `reorderable` option to optionally lock a column ([#1357](https://github.com/ghiscoding/slickgrid-universal/issues/1357)) ([44f6c08](https://github.com/ghiscoding/slickgrid-universal/commit/44f6c085f009ec41bec711aa14ae7fbb3fcbc156)) - by @ghiscoding
+
* convert CheckSelectColumn plugin to native HTML for CSP safe code ([#1332](https://github.com/ghiscoding/slickgrid-universal/issues/1332)) ([2b9216d](https://github.com/ghiscoding/slickgrid-universal/commit/2b9216df3e1796ffb4081127cdaa9011e4d48b23)) - by @ghiscoding
+
* **core:** expose all SlickEvent via internal PubSub Service ([#1311](https://github.com/ghiscoding/slickgrid-universal/issues/1311)) ([f56edef](https://github.com/ghiscoding/slickgrid-universal/commit/f56edef91b76ab044134ddf36d67599e6d80f39c)) - by @ghiscoding
+
* **editor:** auto commit before save; add `onBeforeEditMode` callback ([#1353](https://github.com/ghiscoding/slickgrid-universal/issues/1353)) ([f33bf52](https://github.com/ghiscoding/slickgrid-universal/commit/f33bf5202e0db30121bf52ce184555f6524dde85)) - by @zewa666
+
* **plugin:** new Row Based Editor ([#1323](https://github.com/ghiscoding/slickgrid-universal/issues/1323)) ([64d464c](https://github.com/ghiscoding/slickgrid-universal/commit/64d464c2094c014024ddeaf49bd4f6ec898b1c25)) - by @zewa666
### Performance Improvements
@@ -170,17 +299,25 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* `updateColumns()` should be public use with column hidden ([#1288](https://github.com/ghiscoding/slickgrid-universal/issues/1288)) ([211180b](https://github.com/ghiscoding/slickgrid-universal/commit/211180b8c1f32250e6fc7a559baaa203154473e0)) - by @ghiscoding
+
* applyDefaults use provided grid options before applying defaults ([#1283](https://github.com/ghiscoding/slickgrid-universal/issues/1283)) ([7fc772f](https://github.com/ghiscoding/slickgrid-universal/commit/7fc772fb80a80e0eafa900fc688667d12e1f9429)) - by @ghiscoding
+
* **core:** `SlickGroupItemMetadataProvider` should implements `SlickPlugin` ([#1294](https://github.com/ghiscoding/slickgrid-universal/issues/1294)) ([5aac2b6](https://github.com/ghiscoding/slickgrid-universal/commit/5aac2b6a37cdd21938fa54769b72ce317562e45d)) - by @ghiscoding
+
* **core:** add missing option to control row highlight duration after CRUD ([#1278](https://github.com/ghiscoding/slickgrid-universal/issues/1278)) ([8240c8c](https://github.com/ghiscoding/slickgrid-universal/commit/8240c8c9710f4e5d902ec9961f6a721ae0f84f7f)) - by @ghiscoding
+
* GroupingGetterFunction should be allowed to return arbitrary value ([#1296](https://github.com/ghiscoding/slickgrid-universal/issues/1296)) ([3807116](https://github.com/ghiscoding/slickgrid-universal/commit/38071168e0fe5eea7d5e1ee117fae98c09057a4c)) - by @ghiscoding
+
* **RowDetail:** sort change should collapse all Row Detail ([#1284](https://github.com/ghiscoding/slickgrid-universal/issues/1284)) ([21f6031](https://github.com/ghiscoding/slickgrid-universal/commit/21f60310a402dd12c80bf4553588c6cd777a131a)) - by @ghiscoding
+
* use correct argument type on `setData()` ([#1287](https://github.com/ghiscoding/slickgrid-universal/issues/1287)) ([0b0b86c](https://github.com/ghiscoding/slickgrid-universal/commit/0b0b86c2325ea2a11b74d8fe8debeb02e23bb014)) - by @ghiscoding
### Features
* (re)add option to cancel Row Detail opening ([#1286](https://github.com/ghiscoding/slickgrid-universal/issues/1286)) ([f08925c](https://github.com/ghiscoding/slickgrid-universal/commit/f08925c50c1dd18448a04a55c8303736e3cc2289)) - by @ghiscoding
+
* datasetIdPropertyName respected in newRowCreator ([#1279](https://github.com/ghiscoding/slickgrid-universal/issues/1279)) ([9d60a9d](https://github.com/ghiscoding/slickgrid-universal/commit/9d60a9d82e605ae2351822c66ff8757349b906cf)) - by @zewa666
+
* make DataView Grouping `compileAccumulatorLoop` CSP safe ([#1295](https://github.com/ghiscoding/slickgrid-universal/issues/1295)) ([af82208](https://github.com/ghiscoding/slickgrid-universal/commit/af8220881b2791be2cc3f6605eda3955428094c7)) - by @ghiscoding
### Performance Improvements
@@ -192,11 +329,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **composite:** `onSave` always include last dataContext on few inserts ([#1271](https://github.com/ghiscoding/slickgrid-universal/issues/1271)) ([14791e7](https://github.com/ghiscoding/slickgrid-universal/commit/14791e7edd99b84c8bfefff3d287399cbba9ffad)) - by @ghiscoding
+
* **npm:** publish src folder for source maps, fixes downstream builds ([#1269](https://github.com/ghiscoding/slickgrid-universal/issues/1269)) ([701da75](https://github.com/ghiscoding/slickgrid-universal/commit/701da752565384408e22857a201828379bfc26ff)) - by @ghiscoding
### Features
* **core:** add `rowHighlightCssClass` & `highlightRow()` to SlickGrid ([#1272](https://github.com/ghiscoding/slickgrid-universal/issues/1272)) ([31c38ad](https://github.com/ghiscoding/slickgrid-universal/commit/31c38ad4d0a2e5c07ad92964fee303b31a192b59)) - by @ghiscoding
+
* **utils:** replace slick-core extend utils with `node-extend` ([#1277](https://github.com/ghiscoding/slickgrid-universal/issues/1277)) ([3439118](https://github.com/ghiscoding/slickgrid-universal/commit/3439118da344cd852a1b1af5bd83c4b894213464)) - by @ghiscoding
## [4.0.3](https://github.com/ghiscoding/slickgrid-universal/compare/v4.0.2...v4.0.3) (2023-12-16)
@@ -206,6 +345,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
* add back moment rollup patch with default import ([2e81421](https://github.com/ghiscoding/slickgrid-universal/commit/2e814214fe7246c76fe8e1398c87cd20cc41c862)) - by @ghiscoding
## [4.0.2](https://github.com/ghiscoding/slickgrid-universal/compare/v3.7.2...v4.0.2) (2023-12-15)
+
### Follow the [Migration 4.x Guide](https://ghiscoding.gitbook.io/slickgrid-universal/migrations/migration-to-4.x)
### Bug Fixes
@@ -229,8 +369,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* `stripTags` shouldn't throw with null/undefined ([8f706fc](https://github.com/ghiscoding/slickgrid-universal/commit/8f706fc95f837c6352fb3217952c86b4326f8aaf)) - by @ghiscoding
+
* **core:** SlickEventHandler handler args should have Types ([#1261](https://github.com/ghiscoding/slickgrid-universal/issues/1261)) ([a33129b](https://github.com/ghiscoding/slickgrid-universal/commit/a33129b0ce1443443e7dcebb3562ffd538b6a731)) - by @ghiscoding
+
* regression, Row Detail no longer displayed after CSP safe code ([#1259](https://github.com/ghiscoding/slickgrid-universal/issues/1259)) ([a35f0a4](https://github.com/ghiscoding/slickgrid-universal/commit/a35f0a488775e8ccb68ec8fe0ece9abc47c358f4)) - by @ghiscoding
+
* **utils:** undefined html shouldn't throw on stripTags ([05361e7](https://github.com/ghiscoding/slickgrid-universal/commit/05361e7430694d9a41075f744460eaf187a50b11)) - by @ghiscoding
# [4.0.0-alpha.0](https://github.com/ghiscoding/slickgrid-universal/compare/v3.7.1...v4.0.0-alpha.0) (2023-12-09)
@@ -238,21 +381,33 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* `setActiveCellInternal()` should not throw when cell/row undefined ([dbe6413](https://github.com/ghiscoding/slickgrid-universal/commit/dbe64132294bc88f5dc13ac23a6f6f84ac5e1ffd)) - by @ghiscoding
+
* change dynamic html string w/CSP safe code to fix scroll ([#1210](https://github.com/ghiscoding/slickgrid-universal/issues/1210)) ([cd03907](https://github.com/ghiscoding/slickgrid-universal/commit/cd03907b20468190db7f84f3ae24fbd531e4f6e4)) - by @ghiscoding
+
* Draggable shouldn't trigger dragEnd without first dragging ([#1211](https://github.com/ghiscoding/slickgrid-universal/issues/1211)) ([47cb36e](https://github.com/ghiscoding/slickgrid-universal/commit/47cb36e78995f70933807aa33ba3afa0fecf491e)) - by @ghiscoding
+
* escape glob pattern for SASS copy to work in CI ([0590b24](https://github.com/ghiscoding/slickgrid-universal/commit/0590b24bf2ac140ba69149bd55cbff95b3493112)) - by @ghiscoding-SE
+
* only allow row drag on cell w/`dnd` or `cell-reorder`, fix [#937](https://github.com/ghiscoding/slickgrid-universal/issues/937) ([6a2ab55](https://github.com/ghiscoding/slickgrid-universal/commit/6a2ab550a253a4a1f35e4e81a120fa9247ce753b)), closes [#897](https://github.com/ghiscoding/slickgrid-universal/issues/897) - by @ghiscoding-SE
+
* remove CellRange, SlickRange, SlickGroup, ... unused interfaces ([#1219](https://github.com/ghiscoding/slickgrid-universal/issues/1219)) ([a4cc469](https://github.com/ghiscoding/slickgrid-universal/commit/a4cc469e9c21c5ed851bfbaafdc6b580e7389272)) - by @ghiscoding
+
* the `devMode` should be `false` or an object with other options ([ac57992](https://github.com/ghiscoding/slickgrid-universal/commit/ac57992abd821cdd6fec823464944dadfa1e7b2c)) - by @ghiscoding-SE
+
* the `devMode` should be `false` or an object with other options ([ad2285a](https://github.com/ghiscoding/slickgrid-universal/commit/ad2285a3890442b28dfc7c668ab1b1376e17d3df)) - by @ghiscoding-SE
+
* try adding sort icon on non `sortable` column shouldn't throw ([4791fc8](https://github.com/ghiscoding/slickgrid-universal/commit/4791fc89078d9f3212d034fb1d5e43b8bbfffc5d)) - by @ghiscoding-SE
### Features
* convert GroupItemMetadataProvider Formatter to native HTML for CSP ([#1215](https://github.com/ghiscoding/slickgrid-universal/issues/1215)) ([d723856](https://github.com/ghiscoding/slickgrid-universal/commit/d723856777329f2e40fe3a12d3c59e33afd0e3a8)) - by @ghiscoding
+
* introduce devMode to support nodejs based unit testing ([#1251](https://github.com/ghiscoding/slickgrid-universal/issues/1251)) ([596737d](https://github.com/ghiscoding/slickgrid-universal/commit/596737d52a2ec8c42320152342144ff32191ebfd)) - by @ghiscoding
+
* remove unnecessary Formatters, replace by `cssClass` ([#1225](https://github.com/ghiscoding/slickgrid-universal/issues/1225)) ([de26496](https://github.com/ghiscoding/slickgrid-universal/commit/de26496aa5dc462869a4a1ff966b32baf86e188b)) - by @ghiscoding
+
* rewrite all Formatters as native HTML elements ([#1229](https://github.com/ghiscoding/slickgrid-universal/issues/1229)) ([5cb4dd5](https://github.com/ghiscoding/slickgrid-universal/commit/5cb4dd5757adc401ed4e6deab0e41bcd08a827a3)) - by @ghiscoding
+
* use PubSub Service singleton to subscribe to any SlickEvent ([#1248](https://github.com/ghiscoding/slickgrid-universal/issues/1248)) ([388bd11](https://github.com/ghiscoding/slickgrid-universal/commit/388bd115c1a15f853da8ac943a6e5e3574630438)) - by @ghiscoding
### Performance Improvements
@@ -264,6 +419,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* the `devMode` should be `false` or an object with other options ([ad2285a](https://github.com/ghiscoding/slickgrid-universal/commit/ad2285a3890442b28dfc7c668ab1b1376e17d3df)) - by @ghiscoding-SE
+
* use !important on CSS text utils ([7fdbeb6](https://github.com/ghiscoding/slickgrid-universal/commit/7fdbeb6c46201ae80d6e71e2df7016735b771bf2)) - by @ghiscoding
## [3.7.1](https://github.com/ghiscoding/slickgrid-universal/compare/v3.7.0...v3.7.1) (2023-12-08)
@@ -277,13 +433,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* cell selection range with key combos were incorrect ([#1244](https://github.com/ghiscoding/slickgrid-universal/issues/1244)) ([79d86fe](https://github.com/ghiscoding/slickgrid-universal/commit/79d86fea99258ccf82a5d3d8c684410623e6753b)) - by @ghiscoding
+
* DraggableGrouping & Select Filter `collectionAsync` mem leaks ([#1247](https://github.com/ghiscoding/slickgrid-universal/issues/1247)) ([7dcf53a](https://github.com/ghiscoding/slickgrid-universal/commit/7dcf53ac4d7873c75e82e01c2b4a806f88d8ff39)) - by @ghiscoding
+
* **formatters:** show console error on invalid multiple formatters ([#1227](https://github.com/ghiscoding/slickgrid-universal/issues/1227)) ([fd69ac0](https://github.com/ghiscoding/slickgrid-universal/commit/fd69ac01c68496d4e7d5dd2f06186fba961016d9)) - by @ghiscoding
+
* registered external resouces should keep singleton ref ([#1242](https://github.com/ghiscoding/slickgrid-universal/issues/1242)) ([adf2054](https://github.com/ghiscoding/slickgrid-universal/commit/adf2054bdc8ef7701e6fab78e685d49b8424da29)) - by @ghiscoding
### Features
* **Formatters:** add new `Formatters.iconBoolean` for icon w/truthy val ([#1228](https://github.com/ghiscoding/slickgrid-universal/issues/1228)) ([17ab965](https://github.com/ghiscoding/slickgrid-universal/commit/17ab965102c1f71270ea2423f9d6e0fd4ad73c14)) - by @ghiscoding
+
* **GraphQL:** Provide ability to specify operationName ([#1224](https://github.com/ghiscoding/slickgrid-universal/issues/1224)) ([4db6c34](https://github.com/ghiscoding/slickgrid-universal/commit/4db6c343fd7ce5f4c81ee0d1df0f964d0aac9d48)) - by @Harsgalt86
# 3.6.0 (2023-11-26)
@@ -297,6 +457,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** ms-select-vanilla requires `@types/trusted-types` dep ([#1190](https://github.com/ghiscoding/slickgrid-universal/issues/1190)) ([284a379](https://github.com/ghiscoding/slickgrid-universal/commit/284a3791027423d0d7f45a950e0a3b8a8a684612)) - by @ghiscoding
+
* improve build & types exports for all targets, Node, CJS/ESM ([#1188](https://github.com/ghiscoding/slickgrid-universal/issues/1188)) ([980fd68](https://github.com/ghiscoding/slickgrid-universal/commit/980fd68f6ce9564bb1fcac5f6ee68fd35f839e8f)) - by @ghiscoding
# [3.5.0](https://github.com/ghiscoding/slickgrid-universal/compare/v3.4.2...v3.5.0) (2023-11-10)
@@ -304,13 +465,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** SlickCellRangeSelector shouldn't stop editor event bubbling ([#1183](https://github.com/ghiscoding/slickgrid-universal/issues/1183)) ([7bb9d25](https://github.com/ghiscoding/slickgrid-universal/commit/7bb9d25c40c3f7f53be57c45917802e5f426c599)) - by @ghiscoding
+
* **graphql:** deprecate `isWithCursor` in favor of simpler `useCursor` ([#1187](https://github.com/ghiscoding/slickgrid-universal/issues/1187)) ([7b3590f](https://github.com/ghiscoding/slickgrid-universal/commit/7b3590f323ea2fe3d3f312674205fc94485213fa)) - by @ghiscoding
+
* **pagination:** should recreate pagination on cursor based changed ([#1175](https://github.com/ghiscoding/slickgrid-universal/issues/1175)) ([c7836aa](https://github.com/ghiscoding/slickgrid-universal/commit/c7836aae4a4ea0892791acc79a7bcb338ddb2038)) - by @ghiscoding
+
* **styles:** menu command with & without icons aren't aligned ([#1180](https://github.com/ghiscoding/slickgrid-universal/issues/1180)) ([35f040d](https://github.com/ghiscoding/slickgrid-universal/commit/35f040dbd1f2d384aadbfbe351dd0e55f8d34c68)) - by @ghiscoding
### Features
* **common:** add `compoundOperatorAltTexts` grid option ([#1181](https://github.com/ghiscoding/slickgrid-universal/issues/1181)) ([dc0aa5e](https://github.com/ghiscoding/slickgrid-universal/commit/dc0aa5e28351af989e9dd691916af909e3a5fdf5)) - by @ghiscoding
+
* **GraphQL:** add verbatim search terms to backend services ([#1174](https://github.com/ghiscoding/slickgrid-universal/issues/1174)) ([eadc5ef](https://github.com/ghiscoding/slickgrid-universal/commit/eadc5ef636e8bf331d89f37be4596e7cc534b974)) - by @Harsgalt86
## [3.4.2](https://github.com/ghiscoding/slickgrid-universal/compare/v3.4.1...v3.4.2) (2023-11-02)
@@ -328,30 +493,51 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** `unbindAll` with a group name should remove all tagged ones ([#1152](https://github.com/ghiscoding/slickgrid-universal/issues/1152)) ([5014354](https://github.com/ghiscoding/slickgrid-universal/commit/5014354803d4561409c0f9622ad8bc5093d494cf)), closes [#1150](https://github.com/ghiscoding/slickgrid-universal/issues/1150) - by @ghiscoding
+
* **common:** calling `bind` with multiple events should add group name ([#1157](https://github.com/ghiscoding/slickgrid-universal/issues/1157)) ([9023b54](https://github.com/ghiscoding/slickgrid-universal/commit/9023b54146b72c0305128484f9fd6f9d1ac47b48)), closes [#1150](https://github.com/ghiscoding/slickgrid-universal/issues/1150) - by @ghiscoding
+
* **common:** clicking Menu close button should only close current menu ([#1160](https://github.com/ghiscoding/slickgrid-universal/issues/1160)) ([b524ef1](https://github.com/ghiscoding/slickgrid-universal/commit/b524ef1af6c662bc4ebcd87ad95aa99dd077a119)) - by @ghiscoding
+
* **common:** context menu should close when clicking another cell ([#1163](https://github.com/ghiscoding/slickgrid-universal/issues/1163)) ([bd132c5](https://github.com/ghiscoding/slickgrid-universal/commit/bd132c52a082147c2366b2fade124e145834902f)) - by @ghiscoding
+
* **common:** disable throwWhenFrozenNotAllViewable w/frozen grids ([#1149](https://github.com/ghiscoding/slickgrid-universal/issues/1149)) ([9a06875](https://github.com/ghiscoding/slickgrid-universal/commit/9a06875d8654c47d97aaaa0fd5191c1bfeae7288)) - by @ghiscoding
+
* **common:** make sure destroy is a function before calling it ([#1148](https://github.com/ghiscoding/slickgrid-universal/issues/1148)) ([dba9606](https://github.com/ghiscoding/slickgrid-universal/commit/dba96060666a929eb616bcacb492f6f5f3f56106)) - by @ghiscoding
+
* **common:** mouseover disabled sub-menu shouldn't open it ([#1167](https://github.com/ghiscoding/slickgrid-universal/issues/1167)) ([550f103](https://github.com/ghiscoding/slickgrid-universal/commit/550f1031ca2c56649ed630ab753d757a3fb799fa)) - by @ghiscoding
+
* **common:** replace `innerHTML: '×'` with `textContent: '×'` ([#1156](https://github.com/ghiscoding/slickgrid-universal/issues/1156)) ([e8b2cfb](https://github.com/ghiscoding/slickgrid-universal/commit/e8b2cfb4b3d182de429ba367d1c83b873670fabc)) - by @ghiscoding
+
* **common:** rollback event capture causing multiple calls ([#1168](https://github.com/ghiscoding/slickgrid-universal/issues/1168)) ([90876c9](https://github.com/ghiscoding/slickgrid-universal/commit/90876c9a57f291271a3510541e4a24a4ef86413c)) - by @ghiscoding
+
* deprecate HeaderMenu `items` in favor of `commandItems` ([634441c](https://github.com/ghiscoding/slickgrid-universal/commit/634441c34e17a0a11c672df32c71014309efc13e)) - by @ghiscoding
+
* deprecate HeaderMenu `items` in favor of `commandItems` ([#1159](https://github.com/ghiscoding/slickgrid-universal/issues/1159)) ([2b26d6d](https://github.com/ghiscoding/slickgrid-universal/commit/2b26d6da1232f4ad4a7d0db8ad077b3b2e3c6bd7)) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#1136](https://github.com/ghiscoding/slickgrid-universal/issues/1136)) ([a755b0f](https://github.com/ghiscoding/slickgrid-universal/commit/a755b0f0ff8af47c6d1d534930b1354fd28a781f)) - by @renovate-bot
+
* **deps:** update all non-major dependencies ([#1138](https://github.com/ghiscoding/slickgrid-universal/issues/1138)) ([82a602e](https://github.com/ghiscoding/slickgrid-universal/commit/82a602e8c3c25a45979d3e3bbf4766d1bae33f80)) - by @renovate-bot
+
* **gridMenu:** remove GridMenu from DOM after closing it ([#1169](https://github.com/ghiscoding/slickgrid-universal/issues/1169)) ([87b242f](https://github.com/ghiscoding/slickgrid-universal/commit/87b242fdebd6d8ce838842458e192a6e90de3d80)) - by @ghiscoding
+
* move `innerHTML` as separate assignment to improve CSP trusted types ([#1162](https://github.com/ghiscoding/slickgrid-universal/issues/1162)) ([9c6a002](https://github.com/ghiscoding/slickgrid-universal/commit/9c6a002666f16b1096d3f928900ad412a4124233)) - by @ghiscoding
### Features
* add `subMenuOpenByEvent` option to open sub-menus via mouseover ([#1161](https://github.com/ghiscoding/slickgrid-universal/issues/1161)) ([609f88b](https://github.com/ghiscoding/slickgrid-universal/commit/609f88b2b80515a540bd7ae1c8366b57bd288dbc)) - by @ghiscoding
+
* add sub-menu(s) to CellMenu & ContextMenu plugins ([#1141](https://github.com/ghiscoding/slickgrid-universal/issues/1141)) ([bd18af1](https://github.com/ghiscoding/slickgrid-universal/commit/bd18af1ee960f9417cb7625ff8c3fb5d9567d16e)) - by @ghiscoding
+
* add sub-menu(s) to GridMenu plugin ([#1151](https://github.com/ghiscoding/slickgrid-universal/issues/1151)) ([5178310](https://github.com/ghiscoding/slickgrid-universal/commit/5178310c0247d5524300841aac7aea7c4f3df733)) - by @ghiscoding
+
* add sub-menu(s) to HeaderMenu plugin ([#1158](https://github.com/ghiscoding/slickgrid-universal/issues/1158)) ([eeab42e](https://github.com/ghiscoding/slickgrid-universal/commit/eeab42e270e53341a8572ab55ed758276a4d30d6)) - by @ghiscoding
+
* add support for grid inside Shadow DOM ([#1166](https://github.com/ghiscoding/slickgrid-universal/issues/1166)) ([f7b8c46](https://github.com/ghiscoding/slickgrid-universal/commit/f7b8c46593c71b7114ac85610c12ad6187e3f6de)) - by @ghiscoding
+
* **common:** add group name to `bind` and `unbindAll` methods ([#1150](https://github.com/ghiscoding/slickgrid-universal/issues/1150)) ([6c3b90e](https://github.com/ghiscoding/slickgrid-universal/commit/6c3b90e774906621d5b1584a2372ba633d2366ff)) - by @ghiscoding
+
* **common:** create ColumnPicker dynamically every time ([#1165](https://github.com/ghiscoding/slickgrid-universal/issues/1165)) ([7e8d80e](https://github.com/ghiscoding/slickgrid-universal/commit/7e8d80e807176ba2064cbb71d06fb53995aae06c)) - by @ghiscoding
+
* **graphql:** add optional cursor pagination to GraphQL backend service ([#1153](https://github.com/ghiscoding/slickgrid-universal/issues/1153)) ([29579b2](https://github.com/ghiscoding/slickgrid-universal/commit/29579b23ab1e531b3323cbf10eb9e9882e244b8f)) - by @Harsgalt86
## [3.3.2](https://github.com/ghiscoding/slickgrid-universal/compare/v3.3.1...v3.3.2) (2023-10-06)
@@ -375,6 +561,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Features
* add option to cancel Row Detail opening ([#1125](https://github.com/ghiscoding/slickgrid-universal/issues/1125)) ([82ba377](https://github.com/ghiscoding/slickgrid-universal/commit/82ba377132d90335ea2bca5bf628ab47841fc913)) - by @ghiscoding
+
* add pageUp/pageDown/home/end to SlickCellSelection ([#1126](https://github.com/ghiscoding/slickgrid-universal/issues/1126)) ([b7e9e0d](https://github.com/ghiscoding/slickgrid-universal/commit/b7e9e0db9fde184c76cb835858d195ad28657b05)) - by @ghiscoding
## [3.2.2](https://github.com/ghiscoding/slickgrid-universal/compare/v3.2.1...v3.2.2) (2023-09-24)
@@ -382,8 +569,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** update all non-major dependencies ([#1113](https://github.com/ghiscoding/slickgrid-universal/issues/1113)) ([37741fe](https://github.com/ghiscoding/slickgrid-universal/commit/37741fe572e866ca5e1c7c53280eb9a1a2da6518)) - by @renovate-bot
+
* **deps:** update dependency multiple-select-vanilla to ^0.4.10 ([#1098](https://github.com/ghiscoding/slickgrid-universal/issues/1098)) ([ab97b9d](https://github.com/ghiscoding/slickgrid-universal/commit/ab97b9df3205f1a55f69f3722d276c8c71d8fd29)) - by @renovate-bot
+
* **GridService:** clear any opened highlight timers before disposing ([#1116](https://github.com/ghiscoding/slickgrid-universal/issues/1116)) ([c6a0957](https://github.com/ghiscoding/slickgrid-universal/commit/c6a095702a672e14b442e71be492942c07d6f1e6)) - by @ghiscoding
+
* **resizer:** resize without container ([#1117](https://github.com/ghiscoding/slickgrid-universal/issues/1117)) ([9013522](https://github.com/ghiscoding/slickgrid-universal/commit/90135223130dacfdd376b56d4cf49437328b08ae)) - by @zewa666
### Reverts
@@ -395,6 +585,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** Select Filter/Editor enableRenderHtml was wrong ([#1096](https://github.com/ghiscoding/slickgrid-universal/issues/1096)) ([1f09eef](https://github.com/ghiscoding/slickgrid-universal/commit/1f09eefaf2dbb13434fd90b54b5361ef9f08116c)) - by @ghiscoding
+
* **deps:** update dependency conventional-changelog-conventionalcommits to v7 ([#1091](https://github.com/ghiscoding/slickgrid-universal/issues/1091)) ([6c23aef](https://github.com/ghiscoding/slickgrid-universal/commit/6c23aef29ac19735b18bdbfd1d8f51423f249989)) - by @renovate-bot
## [3.2.0](https://github.com/ghiscoding/slickgrid-universal/compare/v3.1.0...v3.2.0) (2023-08-21)
@@ -402,15 +593,21 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Features
* **export:** add `autoDetectCellFormat` flag to Excel Export Options ([#1083](https://github.com/ghiscoding/slickgrid-universal/issues/1083)) ([839b09a](https://github.com/ghiscoding/slickgrid-universal/commit/839b09a10ceba889bc96a7f229f58412a6d5649c)) - by @ghiscoding
+
* **TreeData:** add auto-recalc feature for Tree Totals w/Aggregators ([#1084](https://github.com/ghiscoding/slickgrid-universal/issues/1084)) ([e884c03](https://github.com/ghiscoding/slickgrid-universal/commit/e884c0356595c161b746ca370efa4bd74088c458)) - by @ghiscoding
+
* **TreeData:** add optional Aggregators to Tree Data grids ([#1074](https://github.com/ghiscoding/slickgrid-universal/issues/1074)) ([6af5fd1](https://github.com/ghiscoding/slickgrid-universal/commit/6af5fd17b582834b24655b06c34c634a99c93c6e)) - by @ghiscoding
### Bug Fixes
* adding dataset hierarchical item shouldn't cause scroll flickering ([#1076](https://github.com/ghiscoding/slickgrid-universal/issues/1076)) ([8536e0e](https://github.com/ghiscoding/slickgrid-universal/commit/8536e0e04f1168648251f517cb47ea2e7129e231)) - by @ghiscoding
+
* **common:** Sort Service could throw on 3rd with undefined columnId ([#1059](https://github.com/ghiscoding/slickgrid-universal/issues/1059)) ([1141230](https://github.com/ghiscoding/slickgrid-universal/commit/114123040a6b69d40f928955627121189a6feb75)) - by @ghiscoding
+
* copying multiple times only kept last undo CellExternalCopyManager ([#1075](https://github.com/ghiscoding/slickgrid-universal/issues/1075)) ([e3beee2](https://github.com/ghiscoding/slickgrid-universal/commit/e3beee208fcd223e911d2d88a15b9d2950267eda)) - by @ghiscoding
+
* **deps:** update dependency autocompleter to v9 ([#1051](https://github.com/ghiscoding/slickgrid-universal/issues/1051)) ([0e05f2a](https://github.com/ghiscoding/slickgrid-universal/commit/0e05f2a4c9f3c9640a3982b7cfa04ea71cfaab96)) - by @renovate-bot
+
* **TreeData:** auto-recalc should update totals for collapsed items too ([#1086](https://github.com/ghiscoding/slickgrid-universal/issues/1086)) ([25d39f2](https://github.com/ghiscoding/slickgrid-universal/commit/25d39f277093990f150ec4aa471c079eab73e4b1)) - by @ghiscoding
## [3.1.0](https://github.com/ghiscoding/slickgrid-universal/compare/v3.0.1...v3.1.0) (2023-07-20)
@@ -422,6 +619,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** update dependency dompurify to ^3.0.5 ([#1030](https://github.com/ghiscoding/slickgrid-universal/issues/1030)) ([728bc58](https://github.com/ghiscoding/slickgrid-universal/commit/728bc58b6844544479695f29984221c9ea099936)) - by @renovate-bot
+
* **plugins:** RowMoveManager shouldn't add cssClass when not usable ([#1044](https://github.com/ghiscoding/slickgrid-universal/issues/1044)) ([f25eeec](https://github.com/ghiscoding/slickgrid-universal/commit/f25eeec7a277d4b915d1423f12e688ad8ac98e7c)) - by @ghiscoding
## [3.0.1](https://github.com/ghiscoding/slickgrid-universal/compare/v3.0.0...v3.0.1) (2023-07-01)
@@ -429,12 +627,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** Select Filter/Editor regular text shouldn't be html encoded ([#1011](https://github.com/ghiscoding/slickgrid-universal/issues/1011)) ([c203a2c](https://github.com/ghiscoding/slickgrid-universal/commit/c203a2ce4d4e5cf6dfb0e05a25f5fd6b0c4cbe4d)), closes [#976](https://github.com/ghiscoding/slickgrid-universal/issues/976) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#1016](https://github.com/ghiscoding/slickgrid-universal/issues/1016)) ([c34ed84](https://github.com/ghiscoding/slickgrid-universal/commit/c34ed84c8c5aa20876c70b6350f711e16fe6b965)) - by @renovate-bot
+
* **deps:** update dependency autocompleter to ^8.0.4 ([#996](https://github.com/ghiscoding/slickgrid-universal/issues/996)) ([3adf3a1](https://github.com/ghiscoding/slickgrid-universal/commit/3adf3a1a4cf960963ce1447617b3f34b68b6ff4d)) - by @renovate-bot
+
* **deps:** update dependency conventional-changelog-conventionalcommits to v6 ([#990](https://github.com/ghiscoding/slickgrid-universal/issues/990)) ([b3fbcf5](https://github.com/ghiscoding/slickgrid-universal/commit/b3fbcf57556a7eb964782eb967c187f4307323f8)) - by @renovate-bot
+
* **deps:** update dependency slickgrid to ^4.0.1 ([#1017](https://github.com/ghiscoding/slickgrid-universal/issues/1017)) ([2750816](https://github.com/ghiscoding/slickgrid-universal/commit/2750816b7b669a820362934daa9bbfd5d60f3ac5)) - by @renovate-bot
+
* **GridState:** calling `getAssociatedGridColumns` should extend column ([#1014](https://github.com/ghiscoding/slickgrid-universal/issues/1014)) ([77cec0c](https://github.com/ghiscoding/slickgrid-universal/commit/77cec0cd052ec3145d73a7a16d0c7f5c663e3901)) - by @ghiscoding
+
* **GridState:** calling getAssociatedGridColumns should extend column (part2) ([#1015](https://github.com/ghiscoding/slickgrid-universal/issues/1015)) ([3ea1d02](https://github.com/ghiscoding/slickgrid-universal/commit/3ea1d0289ba260325a2592fda42fecce10499525)) - by @ghiscoding
+
* **grouping:** DraggableGrouping could throw when leaving page ([#1019](https://github.com/ghiscoding/slickgrid-universal/issues/1019)) ([c233a9c](https://github.com/ghiscoding/slickgrid-universal/commit/c233a9c5db1fc06395e75f1bc5bb34ea3431ba1f)) - by @ghiscoding
## [3.0.0](https://github.com/ghiscoding/slickgrid-universal/compare/v2.6.4...v3.0.0) (2023-05-29)
@@ -458,11 +663,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### ⚠ BREAKING CHANGES
* drop jQuery requirement (#962)
+
* **common:** migrate to multiple-select-vanilla (#919)
### Features
* **common:** migrate to multiple-select-vanilla ([#919](https://github.com/ghiscoding/slickgrid-universal/issues/919)) ([bc74207](https://github.com/ghiscoding/slickgrid-universal/commit/bc74207e9b2ec46209e87b126e1fcff596c162af)) - by @ghiscoding
+
* drop jQuery requirement ([#962](https://github.com/ghiscoding/slickgrid-universal/issues/962)) ([3da21da](https://github.com/ghiscoding/slickgrid-universal/commit/3da21daacc391a0fb309fcddd78442642c5269f6)) - by @ghiscoding
## [2.6.4](https://github.com/ghiscoding/slickgrid-universal/compare/v2.6.3...v2.6.4) (2023-05-20)
@@ -470,11 +677,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **binding:** remove unnecessary sanitizer in BindingService ([#947](https://github.com/ghiscoding/slickgrid-universal/issues/947)) ([32a9a35](https://github.com/ghiscoding/slickgrid-universal/commit/32a9a35861647510ccb0d3dd14340cd3a1689fc1)) - by @ghiscoding
+
* **core:** add better aria accessibility missing on menus and checkboxes ([#968](https://github.com/ghiscoding/slickgrid-universal/issues/968)) ([8041c11](https://github.com/ghiscoding/slickgrid-universal/commit/8041c1189afd7460bbcc0226c49086878c3b5f90)) - by @ghiscoding
+
* **core:** set `wheel` event listener to passive for better perf ([#971](https://github.com/ghiscoding/slickgrid-universal/issues/971)) ([e4417e8](https://github.com/ghiscoding/slickgrid-universal/commit/e4417e865f6fdf4bcb27eebfc476d959a16d47ea)) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#975](https://github.com/ghiscoding/slickgrid-universal/issues/975)) ([c4313b0](https://github.com/ghiscoding/slickgrid-universal/commit/c4313b014da67826b46324c2933f923ea90e7088)) - by @renovate-bot
+
* **deps:** update dependency @faker-js/faker to v8 ([#973](https://github.com/ghiscoding/slickgrid-universal/issues/973)) ([0f2837e](https://github.com/ghiscoding/slickgrid-universal/commit/0f2837e61862016cbbdeef8e4e2517ccfaea2202)) - by @renovate-bot
+
* **export:** fix negative number exports to Excel ([#977](https://github.com/ghiscoding/slickgrid-universal/issues/977)) ([edf5721](https://github.com/ghiscoding/slickgrid-universal/commit/edf5721007ce0745fc81f3f0261fb7e25340cbc1)) - by @ghiscoding
+
* SlickDraggableGrouping should hide group elms when dragging ([#965](https://github.com/ghiscoding/slickgrid-universal/issues/965)) ([6601998](https://github.com/ghiscoding/slickgrid-universal/commit/660199896df040a34f8947acf81a5d720d11a8c4)) - by @ghiscoding
## [2.6.3](https://github.com/ghiscoding/slickgrid-universal/compare/v2.6.2...v2.6.3) (2023-03-23)
@@ -500,6 +713,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* Edt cell mouseout should save & excel copy buffer should still work ([#917](https://github.com/ghiscoding/slickgrid-universal/issues/917)) ([18ba0fc](https://github.com/ghiscoding/slickgrid-universal/commit/18ba0fc4ed2cb2f678dc4a5486439d59e051a94a)), closes [#901](https://github.com/ghiscoding/slickgrid-universal/issues/901) [#901](https://github.com/ghiscoding/slickgrid-universal/issues/901) - by @ghiscoding
+
* **tooltip:** only create tooltip on header row/column from title attr ([#915](https://github.com/ghiscoding/slickgrid-universal/issues/915)) ([1d9c185](https://github.com/ghiscoding/slickgrid-universal/commit/1d9c185621ecdaa3a4f7c36f521579cbe5d79989)) - by @ghiscoding
### Features
@@ -511,12 +725,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **autocomplete:** Autocomplete drop container should take content width ([#897](https://github.com/ghiscoding/slickgrid-universal/issues/897)) ([9690a38](https://github.com/ghiscoding/slickgrid-universal/commit/9690a38f678ca6f0632b847aebfe93e5b7f0bc12)) - by @ghiscoding
+
* **build:** package exports prop had invalid ESM import link ([#892](https://github.com/ghiscoding/slickgrid-universal/issues/892)) ([7f95f69](https://github.com/ghiscoding/slickgrid-universal/commit/7f95f698447f8178cb7ceec416c35f4957fddbe9)) - by @ghiscoding
+
* **common:** Excel copy cell ranges shouldn't lose its cell focus ([#901](https://github.com/ghiscoding/slickgrid-universal/issues/901)) ([1dc8b76](https://github.com/ghiscoding/slickgrid-universal/commit/1dc8b762b4fc8070eec003161fdc9c4ebf60afd2)) - by @ghiscoding
+
* **deps:** update dependency autocompleter to v8 ([#895](https://github.com/ghiscoding/slickgrid-universal/issues/895)) ([7df225d](https://github.com/ghiscoding/slickgrid-universal/commit/7df225d844ec5629800373da59aeed44eee04e1b)) - by @renovate-bot
+
* **deps:** update dependency dompurify to v3 ([#907](https://github.com/ghiscoding/slickgrid-universal/issues/907)) ([66c8b4d](https://github.com/ghiscoding/slickgrid-universal/commit/66c8b4d602d88d733070b2189468bf1b6508d7eb)) - by @renovate-bot
+
* **editor:** comparing select editor value against `['']` isn't valid ([#909](https://github.com/ghiscoding/slickgrid-universal/issues/909)) ([d93fd5f](https://github.com/ghiscoding/slickgrid-universal/commit/d93fd5f163e393c47fad8c8d285a5788b3834adf)) - by @ghiscoding
+
* **export:** Excel export auto-detect number with Formatters.multiple ([#902](https://github.com/ghiscoding/slickgrid-universal/issues/902)) ([be33a68](https://github.com/ghiscoding/slickgrid-universal/commit/be33a68cadbdaed0c60b00bdcd123f3a4797fb8a)) - by @ghiscoding
+
* **RowDetail:** Row Detail extension should work with editable grid ([#896](https://github.com/ghiscoding/slickgrid-universal/issues/896)) ([99677f0](https://github.com/ghiscoding/slickgrid-universal/commit/99677f08b9cb383a2b64540700e501c7bdfe9f72)) - by @ghiscoding
### Features
@@ -544,6 +765,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **filters:** provide flag to disable special chars input filter parsing ([#873](https://github.com/ghiscoding/slickgrid-universal/issues/873)) ([7e35dae](https://github.com/ghiscoding/slickgrid-universal/commit/7e35dae2258c191e76dbdf01ac654f4a54b5b547)), closes [/stackoverflow.com/questions/75155658/in-angular-slickgrid-the-records-with-special-characters-are-not-gett/75160978#75160978](https://github.com//stackoverflow.com/questions/75155658/in-angular-slickgrid-the-records-with-special-characters-are-not-gett/75160978/issues/75160978) - by @ghiscoding
+
* **styling:** do not remove ul>li bullet on html root, fixes [#868](https://github.com/ghiscoding/slickgrid-universal/issues/868) ([#872](https://github.com/ghiscoding/slickgrid-universal/issues/872)) ([59fa0ba](https://github.com/ghiscoding/slickgrid-universal/commit/59fa0badad181172bf37a31ecf4ef0f44ee47e8d)) - by @ghiscoding
### Features
@@ -567,19 +789,29 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **editors:** Autocomplete list should be using same width as cell width ([#846](https://github.com/ghiscoding/slickgrid-universal/issues/846)) ([0055f8a](https://github.com/ghiscoding/slickgrid-universal/commit/0055f8a925f7ec6e381c9b9b05dccdb405b7a420)) - by @ghiscoding
+
* **export:** create custom Excel cell format with Formatters.decimal ([#844](https://github.com/ghiscoding/slickgrid-universal/issues/844)) ([a7a626c](https://github.com/ghiscoding/slickgrid-universal/commit/a7a626ccaaa510d084979d38d9a6b5a439f24e6d)) - by @ghiscoding
+
* **exports:** Date should always export w/Formatter unless false ([#856](https://github.com/ghiscoding/slickgrid-universal/issues/856)) ([1b249e8](https://github.com/ghiscoding/slickgrid-universal/commit/1b249e88e3033ff4c432346ae32ce3183537237b)) - by @ghiscoding
+
* **formatters:** add all missing Date Formatters ([#855](https://github.com/ghiscoding/slickgrid-universal/issues/855)) ([9d29e59](https://github.com/ghiscoding/slickgrid-universal/commit/9d29e59818ae4e7d3cac692f0479e0147cc2ba8d)) - by @ghiscoding
+
* **formatters:** Date Formatter should work with Date object ([#854](https://github.com/ghiscoding/slickgrid-universal/issues/854)) ([30b80e2](https://github.com/ghiscoding/slickgrid-universal/commit/30b80e27b209dbafda25963864116d980650a648)) - by @ghiscoding
+
* **styling:** Grid Menu & Col Picker overflow in Firefox ([#845](https://github.com/ghiscoding/slickgrid-universal/issues/845)) ([9b0aef7](https://github.com/ghiscoding/slickgrid-universal/commit/9b0aef74d569c73e18d64e29034d777315c19cf8)) - by @ghiscoding
### Features
* Excel exporter will now observe if numeric type has dollar formatter. If it does, it will use the dollarFormatter stylesheet. ([#843](https://github.com/ghiscoding/slickgrid-universal/issues/843)) ([ebabbaf](https://github.com/ghiscoding/slickgrid-universal/commit/ebabbafa240f114c7bdbd11d5d29fe1864d5bcba)) - by @austinsimpson
+
* **exports:** add Excel auto-detect format by field types & formatters ([#848](https://github.com/ghiscoding/slickgrid-universal/issues/848)) ([27a18c4](https://github.com/ghiscoding/slickgrid-universal/commit/27a18c416e71a2a1f418d5c2c850fd331262bf7f)) - by @ghiscoding
+
* **exports:** add Excel custom cell (column) styling ([#851](https://github.com/ghiscoding/slickgrid-universal/issues/851)) ([dd92d44](https://github.com/ghiscoding/slickgrid-universal/commit/dd92d44e0ac27c94a72c98af314cfa23f525f94c)) - by @ghiscoding
+
* **exports:** add optional Excel export parser callback functions ([#852](https://github.com/ghiscoding/slickgrid-universal/issues/852)) ([975da5b](https://github.com/ghiscoding/slickgrid-universal/commit/975da5b1d87ac287c1240e7ec88be4760e22ca74)) - by @ghiscoding
+
* **exports:** add optional file MIME type to Excel export service ([#849](https://github.com/ghiscoding/slickgrid-universal/issues/849)) ([05402e5](https://github.com/ghiscoding/slickgrid-universal/commit/05402e5b3a4cec9306ed21a495cc89c31b3816d8)) - by @ghiscoding
+
* **formatters:** add Currency Formatter and GroupTotalFormatter ([#850](https://github.com/ghiscoding/slickgrid-universal/issues/850)) ([ad373ab](https://github.com/ghiscoding/slickgrid-universal/commit/ad373abd84468367d43bf4fa0feccb99ae22821c)) - by @ghiscoding
## [2.1.3](https://github.com/ghiscoding/slickgrid-universal/compare/v2.1.2...v2.1.3) (2022-12-08)
@@ -587,9 +819,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** Date Sorting was shuffling other lines with same dates ([#831](https://github.com/ghiscoding/slickgrid-universal/issues/831)) ([db34213](https://github.com/ghiscoding/slickgrid-universal/commit/db34213bc8594ae12a6fd241f9fb6d6bfd1b8334)) - by @ghiscoding
+
* **common:** Resizer Service regression still resize container width ([#834](https://github.com/ghiscoding/slickgrid-universal/issues/834)) ([0db8b7e](https://github.com/ghiscoding/slickgrid-universal/commit/0db8b7ec9ecb3c7e88ee6905037da7e13064c60f)) - by @ghiscoding
+
* **common:** Resizer Service should only resize grid not its container ([#833](https://github.com/ghiscoding/slickgrid-universal/issues/833)) ([7d21233](https://github.com/ghiscoding/slickgrid-universal/commit/7d21233deb16a1bda99799fe54401a8b9410197a)) - by @ghiscoding
+
* Grid Menu filtering options should be removed when option disabled ([#837](https://github.com/ghiscoding/slickgrid-universal/issues/837)) ([9bc29d2](https://github.com/ghiscoding/slickgrid-universal/commit/9bc29d2682256605dd80475015b85879e1298381)) - by @ghiscoding
+
* Fix for page being cleared when using copy and paste with selectEditor ([#836](https://github.com/ghiscoding/slickgrid-universal/pull/836)) ([f1cadb33](https://github.com/ghiscoding/slickgrid-universal/commit/f1cadb33d99bcd98bc3c79221fbe55a5b1d72cfd)) - by @austinsimpson
## [2.1.2](https://github.com/ghiscoding/slickgrid-universal/compare/v2.1.1...v2.1.2) (2022-12-02)
@@ -597,12 +833,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **addons:** do not add special columns twice (like Row Selection) ([#822](https://github.com/ghiscoding/slickgrid-universal/issues/822)) ([a80d6f8](https://github.com/ghiscoding/slickgrid-universal/commit/a80d6f8f2cae674e0a870eb9c450de991cd84837)) - by @ghiscoding
+
* **addons:** onGroupChanged callback should be executed with Draggable ([#826](https://github.com/ghiscoding/slickgrid-universal/issues/826)) ([35c2631](https://github.com/ghiscoding/slickgrid-universal/commit/35c2631feb00a5b2efe6903e9bfdfe5c95df318e)) - by @ghiscoding
+
* all querySelector should be specific to a grid UID ([#823](https://github.com/ghiscoding/slickgrid-universal/issues/823)) ([bc2b65c](https://github.com/ghiscoding/slickgrid-universal/commit/bc2b65c676762d21ef45e7b76caf900708c1422f)) - by @ghiscoding
+
* **common:** remove unused console log ([593928a](https://github.com/ghiscoding/slickgrid-universal/commit/593928af8a7e92ecf2a8c67e4cff4c8e5da58468)) - by @ghiscoding
+
* **core:** grid service `resetGrid` method wasn't always resetting ([57de9c8](https://github.com/ghiscoding/slickgrid-universal/commit/57de9c85b33d78fcdfbe843ae2067ddcbe430f54)) - by @ghiscoding
+
* **core:** grid service `resetGrid` method wasn't always resetting ([#829](https://github.com/ghiscoding/slickgrid-universal/issues/829)) ([1ffc382](https://github.com/ghiscoding/slickgrid-universal/commit/1ffc38265006e8b6e584e6de8f6c4fe53c2e2bf8)) - by @ghiscoding
+
* **styling:** editor clear button should always be centered ([3e9f330](https://github.com/ghiscoding/slickgrid-universal/commit/3e9f3304dc2b02450e859af27af254fee1fbd650)) - by @ghiscoding
+
* **styling:** focused compound input box-shadow css ([2c50c47](https://github.com/ghiscoding/slickgrid-universal/commit/2c50c47a76556ae4a6f842c483800d5af90637fc)) - by @ghiscoding
## [2.1.1](https://github.com/ghiscoding/slickgrid-universal/compare/v2.1.0...v2.1.1) (2022-11-19)
@@ -610,6 +853,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **plugin:** do not show drag group sort when column is not sortable ([#819](https://github.com/ghiscoding/slickgrid-universal/issues/819)) ([049303b](https://github.com/ghiscoding/slickgrid-universal/commit/049303b0f6d085e7d022a2c87572c9ac90082b3e)) - by @ghiscoding
+
* **plugins:** rollback PR [#781](https://github.com/ghiscoding/slickgrid-universal/issues/781) to fix regression with Grid Presets ([#820](https://github.com/ghiscoding/slickgrid-universal/issues/820)) ([60e4a29](https://github.com/ghiscoding/slickgrid-universal/commit/60e4a299a2cbdee947b36dbfbb690f22156f8693)) - by @ghiscoding
# [2.1.0](https://github.com/ghiscoding/slickgrid-universal/compare/v2.0.0...v2.1.0) (2022-11-17)
@@ -617,42 +861,65 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** upgrading to TypeScript 4.9 brought new build issue ([#816](https://github.com/ghiscoding/slickgrid-universal/issues/816)) ([4d46d8a](https://github.com/ghiscoding/slickgrid-universal/commit/4d46d8ab251bd78671140f82cb143b973e5422b3)) - by @ghiscoding
+
* **common:** changing Slider value(s) should update Tooltip instantly ([#800](https://github.com/ghiscoding/slickgrid-universal/issues/800)) ([9c6be27](https://github.com/ghiscoding/slickgrid-universal/commit/9c6be271a956876edaa03be7bf4bda9821840910)) - by @ghiscoding
+
* **common:** Slider Range should update both number addons ([#803](https://github.com/ghiscoding/slickgrid-universal/issues/803)) ([3cfd84e](https://github.com/ghiscoding/slickgrid-universal/commit/3cfd84e7ec4e45cf6a4896dc6143da1fecb0402c)) - by @ghiscoding
+
* **deps:** update dependency autocompleter to v7 ([#804](https://github.com/ghiscoding/slickgrid-universal/issues/804)) ([c298646](https://github.com/ghiscoding/slickgrid-universal/commit/c298646fca64059ca3a59a370f870ad4b3a573da)) - by @renovate-bot
+
* **deps:** update dependency dompurify to ^2.4.1 ([#806](https://github.com/ghiscoding/slickgrid-universal/issues/806)) ([a33d8fb](https://github.com/ghiscoding/slickgrid-universal/commit/a33d8fbf3e48bfa29b9173f9263620e61608fffb)) - by @renovate-bot
+
* **editors:** disable browser autofill on the Editors.autocompleter ([#776](https://github.com/ghiscoding/slickgrid-universal/issues/776)) ([fd2cf53](https://github.com/ghiscoding/slickgrid-universal/commit/fd2cf535c0bd941203951c665bb3da00f4a4677e)) - by @ghiscoding
+
* **editors:** Slider editor track not showing after Slider filter change ([#792](https://github.com/ghiscoding/slickgrid-universal/issues/792)) ([2ad02d2](https://github.com/ghiscoding/slickgrid-universal/commit/2ad02d22cfbb2187df62f0ec19b26f828fec57a6)) - by @ghiscoding
+
* **filters:** changing Slider value should update tooltip value ([#788](https://github.com/ghiscoding/slickgrid-universal/issues/788)) ([509a31d](https://github.com/ghiscoding/slickgrid-universal/commit/509a31d5630689c6c91cc2cef4e87b8dea72a243)) - by @ghiscoding
+
* **filters:** Slider default operator should be greater or equal (>=) ([#793](https://github.com/ghiscoding/slickgrid-universal/issues/793)) ([b895864](https://github.com/ghiscoding/slickgrid-universal/commit/b895864bc39a415622ac9f2a4b79565aa3d89179)) - by @ghiscoding
+
* **styling:** new Slider not flexed correctly ([#799](https://github.com/ghiscoding/slickgrid-universal/issues/799)) ([83a86d0](https://github.com/ghiscoding/slickgrid-universal/commit/83a86d0575a47ed3a11ede31af2a8a3a8186fb9d)) - by @ghiscoding
+
* **toolip:** left & right align were inverted ([#797](https://github.com/ghiscoding/slickgrid-universal/issues/797)) ([91c4a5c](https://github.com/ghiscoding/slickgrid-universal/commit/91c4a5c61a4f78478929f2be41a17e3e2d210a30)) - by @ghiscoding
### Features
* **addon:** add group by sorting to SlickDraggableGrouping ([#814](https://github.com/ghiscoding/slickgrid-universal/issues/814)) ([962a756](https://github.com/ghiscoding/slickgrid-universal/commit/962a756fb17476221867c977752e28bd1d74f6db)) - by @ghiscoding
+
* **common:** add "targetSelector" to onFilterChanged & Grid State ([#813](https://github.com/ghiscoding/slickgrid-universal/issues/813)) ([a25791a](https://github.com/ghiscoding/slickgrid-universal/commit/a25791a5d11b73fd88d80ef8a6f788b27d7390ec)) - by @ghiscoding
+
* **common:** use editorOptions/filterOptions instead of params ([#798](https://github.com/ghiscoding/slickgrid-universal/issues/798)) ([a3c8b6e](https://github.com/ghiscoding/slickgrid-universal/commit/a3c8b6e48dbe3db7eb154837f15ce10780923b32)) - by @ghiscoding
+
* **core:** expose EventPubSub Service on SlickerGridInstance ([#780](https://github.com/ghiscoding/slickgrid-universal/issues/780)) ([8ad54b5](https://github.com/ghiscoding/slickgrid-universal/commit/8ad54b5739772eb8d96d23e1be04ebb426dfa596)) - by @ghiscoding
+
* **filters:** add "target" prop to `onBeforeSearchChange` ([#796](https://github.com/ghiscoding/slickgrid-universal/issues/796)) ([c4606fd](https://github.com/ghiscoding/slickgrid-universal/commit/c4606fde3cf206f81ab5f83d150cf3ce29cbfe75)) - by @ghiscoding
+
* **filters:** add back Slider Range filter in pure JS ([#784](https://github.com/ghiscoding/slickgrid-universal/issues/784)) ([b84525c](https://github.com/ghiscoding/slickgrid-universal/commit/b84525c3c087582854e30b386a1015f6ce3156b4)) - by @ghiscoding
+
* **filters:** add grid option `skipCompoundOperatorFilterWithNullInput` ([#794](https://github.com/ghiscoding/slickgrid-universal/issues/794)) ([617c88d](https://github.com/ghiscoding/slickgrid-universal/commit/617c88d7432c35b8ac0c0f40066a2f55a58b6d35)) - by @ghiscoding
+
* **filters:** add Slider filter track filled track color ([#795](https://github.com/ghiscoding/slickgrid-universal/issues/795)) ([5fbd9c9](https://github.com/ghiscoding/slickgrid-universal/commit/5fbd9c9036844e7e88a99fea6a4d1e1f0fd2377a)) - by @ghiscoding
+
* **plugins:** sync column definitions to user after plugin adds column ([#781](https://github.com/ghiscoding/slickgrid-universal/issues/781)) ([0755b65](https://github.com/ghiscoding/slickgrid-universal/commit/0755b655b7be5911345334e094544a14c3698b51)) - by @ghiscoding
+
* **tooltip:** add a new "center" position option to SlickCustomTooltip ([#787](https://github.com/ghiscoding/slickgrid-universal/issues/787)) ([b019de5](https://github.com/ghiscoding/slickgrid-universal/commit/b019de50244836a984314ea6e6f5cee639551438)) - by @ghiscoding
### Performance Improvements
* **filters:** merge all date range & compound filters into one class ([#812](https://github.com/ghiscoding/slickgrid-universal/issues/812)) ([ca9adfa](https://github.com/ghiscoding/slickgrid-universal/commit/ca9adfae84ca8fd57b61548b1222ade5a8b9c498)) - by @ghiscoding
+
* **filters:** merge all input & compound filters into one class ([#809](https://github.com/ghiscoding/slickgrid-universal/issues/809)) ([6d08f4d](https://github.com/ghiscoding/slickgrid-universal/commit/6d08f4dc9fc471b316f375d77fa8ae1805dc9b83)) - by @ghiscoding
+
* **filters:** merge all Slider filters into one class ([#791](https://github.com/ghiscoding/slickgrid-universal/issues/791)) ([fc4304b](https://github.com/ghiscoding/slickgrid-universal/commit/fc4304b3dd47ac10df65f5b8dda9d8ce5aad8ed9)) - by @ghiscoding
# [2.0.0](https://github.com/ghiscoding/slickgrid-universal/compare/v1.4.0...v2.0.0) (2022-10-17)
⚠️ Breaking Change - Follow the [Migration 2.x Guide](https://github.com/ghiscoding/slickgrid-universal/wiki/Migration-to-2.x)
+
### Bug Fixes
* **deps:** update all non-major dependencies ([#769](https://github.com/ghiscoding/slickgrid-universal/issues/769)) ([4e05a4b](https://github.com/ghiscoding/slickgrid-universal/commit/4e05a4b977c760511fc90903c0f62673859bd65f)) - by @renovate-bot
+
* **styling:** fix some styling issues with input groups and Firefox ([#750](https://github.com/ghiscoding/slickgrid-universal/issues/750)) ([1aa849e](https://github.com/ghiscoding/slickgrid-universal/commit/1aa849ea81461dc9bbd7b3bc05a092bb14c88be2)) - by @ghiscoding
### Features
@@ -664,12 +931,15 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** update all non-major dependencies ([#769](https://github.com/ghiscoding/slickgrid-universal/issues/769)) ([4e05a4b](https://github.com/ghiscoding/slickgrid-universal/commit/4e05a4b977c760511fc90903c0f62673859bd65f)) - by @renovate-bot
+
* **styling:** fix some styling issues with input groups and Firefox ([#750](https://github.com/ghiscoding/slickgrid-universal/issues/750)) ([1aa849e](https://github.com/ghiscoding/slickgrid-universal/commit/1aa849ea81461dc9bbd7b3bc05a092bb14c88be2)) - by @ghiscoding
## ⚠️ Breaking Change
+
### - Features
* **common:** replace jQueryUI Autocomplete with Kradeen Autocomplete ([#752](https://github.com/ghiscoding/slickgrid-universal/issues/752)) ([991d29c](https://github.com/ghiscoding/slickgrid-universal/commit/991d29c4c8c85d800d69c4ba16d608d7a20d2a90)) - by @ghiscoding
+
* **common:** remove & replace jQueryUI with SortableJS in common & SlickDraggableGrouping ([#756](https://github.com/ghiscoding/slickgrid-universal/issues/756)) ([b1c5a84](https://github.com/ghiscoding/slickgrid-universal/commit/b1c5a84bb9a10ff805dfd13996ecf60dae3ab609)) - by @ghiscoding
# [1.4.0](https://github.com/ghiscoding/slickgrid-universal/compare/v1.3.7...v1.4.0) (2022-08-15)
@@ -677,16 +947,23 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **bundle:** fetch API isn't always an instance of Response ([#744](https://github.com/ghiscoding/slickgrid-universal/issues/744)) ([72a6f24](https://github.com/ghiscoding/slickgrid-universal/commit/72a6f2489a88974c8f5faf0041184ac78d6c7caa)) - by @ghiscoding
+
* **collectionAsync:** hidden column does not load edit field selection ([#742](https://github.com/ghiscoding/slickgrid-universal/issues/742)) ([763c61c](https://github.com/ghiscoding/slickgrid-universal/commit/763c61cfa7e82dd82b88f22db3eb47dc274a5eb3)) - by @mcallegario
+
* **common:** duplicate translation namespace prefix, fixes [#738](https://github.com/ghiscoding/slickgrid-universal/issues/738) ([#739](https://github.com/ghiscoding/slickgrid-universal/issues/739)) ([ed6b0cc](https://github.com/ghiscoding/slickgrid-universal/commit/ed6b0cc4f664e27830357ac45d523d0571c94bce)) - by @someusersomeuser
+
* **demo:** edit outline should follow on filter/pagination changed ([3e9a6c7](https://github.com/ghiscoding/slickgrid-universal/commit/3e9a6c7538af5e714cc20ec5926f343912e63b20)) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#740](https://github.com/ghiscoding/slickgrid-universal/issues/740)) ([c8acb65](https://github.com/ghiscoding/slickgrid-universal/commit/c8acb6542a768b2a2b4e0ea0e1f71533d7077927)) - by @renovate-bot
+
* **filters:** fetch API isn't always an instance of Response ([#746](https://github.com/ghiscoding/slickgrid-universal/issues/746)) ([11be5c2](https://github.com/ghiscoding/slickgrid-universal/commit/11be5c2f9554c8fad2b984864ec7180698d02d19)), closes [#744](https://github.com/ghiscoding/slickgrid-universal/issues/744) - by @ghiscoding
+
* **utils:** the `isObject` method was not always correct ([#745](https://github.com/ghiscoding/slickgrid-universal/issues/745)) ([9b09e4a](https://github.com/ghiscoding/slickgrid-universal/commit/9b09e4aa2ca102100a113d4e2996f80c75aa6c2f)) - by @ghiscoding
### Features
* **common:** remove jquery-ui-dist from deps, use jquery-ui only ([#733](https://github.com/ghiscoding/slickgrid-universal/issues/733)) ([b89d1f1](https://github.com/ghiscoding/slickgrid-universal/commit/b89d1f169bfde21d8a46520aed580c12db5f668f)) - by @ghiscoding
+
* **common:** update title prop on change event for Slider Filter/Editor ([#743](https://github.com/ghiscoding/slickgrid-universal/issues/743)) ([0ca6f3f](https://github.com/ghiscoding/slickgrid-universal/commit/0ca6f3f4d8894d4bb9459cabca9a3492e7cca0ad)) - by @ghiscoding
## [1.3.7](https://github.com/ghiscoding/slickgrid-universal/compare/v1.3.6...v1.3.7) (2022-08-02)
@@ -694,6 +971,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **service:** should be able to update dataview item not shown in grid ([#730](https://github.com/ghiscoding/slickgrid-universal/issues/730)) ([dc88c87](https://github.com/ghiscoding/slickgrid-universal/commit/dc88c870e046e904b160546239ab2d403237d98a)) - by @ghiscoding
+
* **uilts:** able to use setDeepValue on undefined/empty object ([#732](https://github.com/ghiscoding/slickgrid-universal/issues/732)) ([e370eef](https://github.com/ghiscoding/slickgrid-universal/commit/e370eef758a7e5fe20e87729bc407ca2bdd55504)) - by @ghiscoding
## [1.3.6](https://github.com/ghiscoding/slickgrid-universal/compare/v1.3.5...v1.3.6) (2022-07-28)
@@ -713,6 +991,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** update dependency jquery-ui to ^1.13.2 ([#720](https://github.com/ghiscoding/slickgrid-universal/issues/720)) ([8351f14](https://github.com/ghiscoding/slickgrid-universal/commit/8351f144192ec5e91ad52678787a448cf42f975f)) - by @renovate-bot
+
* **utils:** setDeepValue should accept array properties ([#728](https://github.com/ghiscoding/slickgrid-universal/issues/728)) ([0dedeba](https://github.com/ghiscoding/slickgrid-universal/commit/0dedeba76ac817f73320778e63c1987a1708360e)), closes [SO](https://github.com//stackoverflow.com/questions/62423893/in-slick-grid-inline-edit-i-cant-able-to-get-the-entire-object/73153946/issues/73153946) - by @ghiscoding
## [1.3.3](https://github.com/ghiscoding/slickgrid-universal/compare/v1.3.2...v1.3.3) (2022-07-07)
@@ -726,6 +1005,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **composite:** selected row count always 0 on mass-selected ([#712](https://github.com/ghiscoding/slickgrid-universal/issues/712)) ([ec42dc7](https://github.com/ghiscoding/slickgrid-universal/commit/ec42dc753fbf8c84040e252f328e51ea4a98cedf))
+
* **deps:** update all non-major dependencies ([230291c](https://github.com/ghiscoding/slickgrid-universal/commit/230291c94506fdd12e7f843a3d7f324922ef97f6))
# [1.3.0](https://github.com/ghiscoding/slickgrid-universal/compare/v1.2.6...v1.3.0) (2022-06-18)
@@ -733,9 +1013,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** add missing depency in vanilla bundle package ([fa08fe6](https://github.com/ghiscoding/slickgrid-universal/commit/fa08fe6f097461c2bf8029307e59631738b1654b))
+
* **deps:** add missing dependencies in child package ([97d0230](https://github.com/ghiscoding/slickgrid-universal/commit/97d02306899e583779c3b6d5b219b2798a5f9cfd))
+
* **deps:** update all non-major dependencies ([5097cea](https://github.com/ghiscoding/slickgrid-universal/commit/5097ceae88c0ea212e0aa6ea2a5b1020368f3216))
+
* **deps:** update yarn lock file ([0bd337f](https://github.com/ghiscoding/slickgrid-universal/commit/0bd337ffcae800ae91670b886ebfd1ef155c80c1))
+
* **deps:** use chore dependency package name ([2fce29c](https://github.com/ghiscoding/slickgrid-universal/commit/2fce29c5e64f160203529b5bf9435562cf5f5941))
### Features
@@ -765,9 +1049,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** deleting Slicker object caused issue with cache ([3f3e261](https://github.com/ghiscoding/slickgrid-universal/commit/3f3e261c1855e7eb695e00a105b7c797462ed298)), closes [#606](https://github.com/ghiscoding/slickgrid-universal/issues/606)
+
* **editors:** select editor should call save only once ([d111c2f](https://github.com/ghiscoding/slickgrid-universal/commit/d111c2f7799151236c6053d7a5288d1fdd530550))
+
* **resizer:** use default resize when resizeByContent has no data ([8499b61](https://github.com/ghiscoding/slickgrid-universal/commit/8499b61b5cc6365af0035d254a9487c79b74bd7f))
+
* **selections:** selected rows doesn't update when hidden column shown ([0d1cf29](https://github.com/ghiscoding/slickgrid-universal/commit/0d1cf294e8ae944672a9c9a2cece1de553c2f973)), closes [#661](https://github.com/ghiscoding/slickgrid-universal/issues/661)
+
* **styling:** add pointer cursor on ms-filter, avoid Bootstrap override ([11e1e12](https://github.com/ghiscoding/slickgrid-universal/commit/11e1e12115896e73096e10b34575e4e8ebe5b819))
## [1.2.1](https://github.com/ghiscoding/slickgrid-universal/compare/v1.2.0...v1.2.1) (2022-01-18)
@@ -775,7 +1063,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **memory:** clear & dispose of grid to avoid mem leaks & detached elm ([7035db5](https://github.com/ghiscoding/slickgrid-universal/commit/7035db5f878187f6fb8b9d2effacb7443f25e2c9))
+
* **odata:** fix range filtering with ".." ([b07af88](https://github.com/ghiscoding/slickgrid-universal/commit/b07af88c6d2912f58e976a428927e63c9fdffbad))
+
* **odata:** fix range filtering with ".." ([d14d3e9](https://github.com/ghiscoding/slickgrid-universal/commit/d14d3e9f92fad2c14a7227b8f822dffc79c8934c))
# [1.2.0](https://github.com/ghiscoding/slickgrid-universal/compare/v1.1.1...v1.2.0) (2022-01-06)
@@ -783,35 +1073,61 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** optimize dev watch ([ab7d405](https://github.com/ghiscoding/slickgrid-universal/commit/ab7d405ecffc047e9bd4289dd796899c94c0db62))
+
* **demo:** latest change with Filter container breaks other demos ([129cc78](https://github.com/ghiscoding/slickgrid-universal/commit/129cc78ac34ad632f2a265d49a631e04b119250b))
+
* **dev:** optimize webpack dev watch ([1340c51](https://github.com/ghiscoding/slickgrid-universal/commit/1340c51b7e2554e9c29ebb9b8ab9b27a3f20cfe9))
+
* **filter:** add the "filled" class for styling purposes ([ea7974a](https://github.com/ghiscoding/slickgrid-universal/commit/ea7974a9a7d54150c16d22ccb8008c692faf6132))
+
* **filter:** add the "filled" class for styling purposes - better code ([4a650cd](https://github.com/ghiscoding/slickgrid-universal/commit/4a650cd269852ab20088b274939e89b2cfc96ec8))
+
* **filter:** add the "filled" class for styling purposes - ajust code format ([abe481e](https://github.com/ghiscoding/slickgrid-universal/commit/abe481e0cd11bfe204399814c1be0eeb66d3f91a))
+
* **filter:** add the "filled" class for styling purposes - ajust format ([fc8c899](https://github.com/ghiscoding/slickgrid-universal/commit/fc8c8992381b001d6ada449352d7b66c6ca08e00))
+
* **filter:** update multiple-select to fix select filtering ([63dcd08](https://github.com/ghiscoding/slickgrid-universal/commit/63dcd0873026fb8ba036ca52ba31f583d6ad136f)), closes [#865](https://github.com/ghiscoding/slickgrid-universal/issues/865)
+
* **plugins:** Draggable Grouping Toggle All should follow `collapsed` ([7fedfa1](https://github.com/ghiscoding/slickgrid-universal/commit/7fedfa1129e12a3bf665efe0bd9160b6a7a1b6a9))
+
* **services:** unsubscribe shouldn't remove when poping out of array ([e841da9](https://github.com/ghiscoding/slickgrid-universal/commit/e841da9df7a23bf7b789e4a13803488ab479ff15))
### Features
* **binding:** make Binding Service a little smarter ([98a7661](https://github.com/ghiscoding/slickgrid-universal/commit/98a766173638246b6a17e31812929a9bba1eb52b))
+
* **composite:** add new `validateMassUpdateChange` callback & bug fixes ([#603](https://github.com/ghiscoding/slickgrid-universal/issues/603)) ([2c1559b](https://github.com/ghiscoding/slickgrid-universal/commit/2c1559b7a3b0b1a642a664e59a025ce78a747946))
+
* **demo:** add new Example to demo Real-time Market Trading ([e50434a](https://github.com/ghiscoding/slickgrid-universal/commit/e50434ac3dab98644e23266c81d09b3789ea7de4))
+
* **filters:** change-filter-element-Container ([31c6e54](https://github.com/ghiscoding/slickgrid-universal/commit/31c6e54a3b2e0d135d8407c74b7bfa329a85e0c5))
+
* **filters:** change-filter-element-Container ([d455d27](https://github.com/ghiscoding/slickgrid-universal/commit/d455d2781f19fc9865600b6123f679ab3526cf04))
+
* **filters:** change-filter-element-Container ([704c52a](https://github.com/ghiscoding/slickgrid-universal/commit/704c52a1d5dec9fedbe837ceca41b96a0d673061))
+
* **filters:** change-filter-element-Container-ajust-code-format ([efb0189](https://github.com/ghiscoding/slickgrid-universal/commit/efb0189b0ce357b07025e2f9f29717a41128ab6b))
+
* **filters:** change-filter-element-Container-ajust-test ([268ccb4](https://github.com/ghiscoding/slickgrid-universal/commit/268ccb4d6be916959f2eadd87d7c506dff1df472))
+
* **filters:** change-filter-element-Container-data-test ([78c3ec7](https://github.com/ghiscoding/slickgrid-universal/commit/78c3ec757a71388eafd0b90e6c48d86f85b0e9db))
+
* **filters:** change-filter-element-Container-Example ([369c6ef](https://github.com/ghiscoding/slickgrid-universal/commit/369c6ef27e639147a755fb1289abcb2eed307153))
+
* **filters:** change-filter-element-Container-test ([61e29c5](https://github.com/ghiscoding/slickgrid-universal/commit/61e29c5851487f7470e6f631c890c346f07ed242))
+
* **filters:** filter-element-Container- DOMPurify ([3749fc4](https://github.com/ghiscoding/slickgrid-universal/commit/3749fc48387412abefe69414db6060d947a704b5))
+
* **filters:** inclusion of the modal filter in example 7 ([1ac2da9](https://github.com/ghiscoding/slickgrid-universal/commit/1ac2da9da5540a5653ac72b825ad6624b331aa8f))
+
* **filters:** modal-filter-example ([ab46202](https://github.com/ghiscoding/slickgrid-universal/commit/ab46202bfbd99497af39830cf59068682f5f8bd1))
+
* **plugins:** Apply auto scroll when dragging on RowMoveManager plugin ([1c14a4f](https://github.com/ghiscoding/slickgrid-universal/commit/1c14a4fd06693425be52e91f405d1c8739699627)), closes [#662](https://github.com/ghiscoding/slickgrid-universal/issues/662)
+
* **selection:** auto-scroll the viewport when dragging with selection ([ecd9c57](https://github.com/ghiscoding/slickgrid-universal/commit/ecd9c57bd6c1315e2358722785a87582ec939f85)), closes [#656](https://github.com/ghiscoding/slickgrid-universal/issues/656)
+
* **services:** add `skipError` to CRUD methods in Grid Service ([869ed87](https://github.com/ghiscoding/slickgrid-universal/commit/869ed87bfa4e60d089138bcba1da5f4bb120e73b))
+
* **services:** add extra features to EventPubSub Service ([9bd02b5](https://github.com/ghiscoding/slickgrid-universal/commit/9bd02b5d92bcf6aaf89a828c4e6496a24e795c53))
## [1.1.1](https://github.com/ghiscoding/slickgrid-universal/compare/v1.1.0...v1.1.1) (2021-12-11)
@@ -825,53 +1141,97 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** add DOM purify optional default import to fix rollup builds ([73bc3c0](https://github.com/ghiscoding/slickgrid-universal/commit/73bc3c0756cf6d28b292f0162afffc06412a126e))
+
* **build:** DOMPurify import fix for all framework ([c551d0c](https://github.com/ghiscoding/slickgrid-universal/commit/c551d0c64d4c7325578acf4feb5d22132c7d7f91))
+
* **comp:** replace `prepend` not supported in IE/Salesforce ([b210f9d](https://github.com/ghiscoding/slickgrid-universal/commit/b210f9d6a7e13f7ca69330955b674b9786dd29bb))
+
* **comp:** replace `prepend` not supported in IE/Salesforce ([13bd9a4](https://github.com/ghiscoding/slickgrid-universal/commit/13bd9a4f8c4fdaedccc65db7100527be0e84eb00))
+
* **context:** remove fixed width on ContextMenu use auto instead ([403679b](https://github.com/ghiscoding/slickgrid-universal/commit/403679be5ca8547b53ed2525a4017923302afae7))
+
* **context:** strip hidden special chars on context menu Copy command ([5d81644](https://github.com/ghiscoding/slickgrid-universal/commit/5d81644a194b66e7fb5efc550a08962d8087f0e3))
+
* **context:** strip hidden special chars on context menu Copy command ([f94ca83](https://github.com/ghiscoding/slickgrid-universal/commit/f94ca834b1fdee94e4e44bdc3d245956a4437de6))
+
* **docs:** fix a typo in readme to force push a release ([00eba2e](https://github.com/ghiscoding/slickgrid-universal/commit/00eba2ec3f14492b822082ccfc1724450a25b9c7))
+
* **filters:** remove Filters from DOM after header row gets destroyed ([3f08162](https://github.com/ghiscoding/slickgrid-universal/commit/3f08162cd8b5fbb407c77b6dc441e60239ba5788))
+
* **locales:** add missing text & remove global config texts fix Locales ([655a872](https://github.com/ghiscoding/slickgrid-universal/commit/655a872d7160ab53530f8e2fdc575817af782b5d))
+
* **plugin:** Copy command from Context Menu should work with numbers ([9d36491](https://github.com/ghiscoding/slickgrid-universal/commit/9d36491c407beb0fdc53588ffc6264306fab607a))
+
* **plugin:** providing usability override via grid option should work ([6446a10](https://github.com/ghiscoding/slickgrid-universal/commit/6446a1061d7d0126cfe655518b7179d93356aa83)), closes [#555](https://github.com/ghiscoding/slickgrid-universal/issues/555)
+
* **plugins:** remove invalid export for build to work ([9353022](https://github.com/ghiscoding/slickgrid-universal/commit/9353022593ba9b16e34a8b3dd3ad62bc5b5e7569))
+
* **styling:** better support of auto width on drop menu ([8a48dd2](https://github.com/ghiscoding/slickgrid-universal/commit/8a48dd2a224c757534a631e88a4864e151496438))
+
* **styling:** Grid Menu Title not aligned correctly with Bootstrap ([e2b991f](https://github.com/ghiscoding/slickgrid-universal/commit/e2b991fb05b8ca94e5a0e3986aabaefc7bc245fb))
+
* **styling:** slightly off Autocomplete position ([cd03f67](https://github.com/ghiscoding/slickgrid-universal/commit/cd03f67f50db301cfe74a1e20efd998102bcf3bf))
+
* **styling:** tweak & fix all styling with Salesforce & other frameworks ([86dbb76](https://github.com/ghiscoding/slickgrid-universal/commit/86dbb76b439a99773a3fe6fd154440eacb20d510))
+
* **tree:** reset to initial tree sort when calling "Clear all Sorting" ([8bd3f4f](https://github.com/ghiscoding/slickgrid-universal/commit/8bd3f4f68247681f8eb57e7aabd59b636face7e7))
+
* **treeGrid:** Bug in onCellClick event ([42155af](https://github.com/ghiscoding/slickgrid-universal/commit/42155af12b0808fc95d5f1c00fcec9bfaef64c44))
+
* apply fixes & refactoring after testing in Aurelia-Slickgrid ([038fa3f](https://github.com/ghiscoding/slickgrid-universal/commit/038fa3f56f202465f2b40af57e8acf752fe31f60))
+
* switch normal/frozen should always show Grid Menu on far right ([6bef090](https://github.com/ghiscoding/slickgrid-universal/commit/6bef0901652a2bdbf661cf5a0fc0d9a7c325a44a))
+
* translation wasn't working with context menu ([889e443](https://github.com/ghiscoding/slickgrid-universal/commit/889e44387279c7834944600417c0c2da11b7991f))
### Features
* **build:** create `salesforce-vanilla-bundle` standalone package ([214d8e7](https://github.com/ghiscoding/slickgrid-universal/commit/214d8e77646d3fdac278cf18227c96f346c94522))
+
* **controls:** add `minHeight` option to ColumnPicker/GridMenu ([cfcfc85](https://github.com/ghiscoding/slickgrid-universal/commit/cfcfc8588b854530425f2bea19e8aa7c5256d059))
+
* **controls:** convert and add ColumnPicker into Slickgrid-Universal ([1f937b9](https://github.com/ghiscoding/slickgrid-universal/commit/1f937b9a3abe43cf1a2bb1f52ba625c34431e328))
+
* **controls:** move external Grid Menu into Slickgrid-Universal ([40adff4](https://github.com/ghiscoding/slickgrid-universal/commit/40adff49c2a74769823dfbed3d32b239608e2a59))
+
* **core:** add TS utility to infer extension instance by name ([3f4f65f](https://github.com/ghiscoding/slickgrid-universal/commit/3f4f65fb1c4f01cddca0e356a0a770b575a7384a))
+
* **plugins:** add all Cell Range/Selection plugins into Universal ([3b4ddca](https://github.com/ghiscoding/slickgrid-universal/commit/3b4ddcaff6e2e8db5804b995ff2282f306cc1a7a))
+
* **plugins:** add extra callback methods to checkbox selector ([#570](https://github.com/ghiscoding/slickgrid-universal/issues/570)) ([a9245f9](https://github.com/ghiscoding/slickgrid-universal/commit/a9245f920397bab0ef5105404babe8443654785c))
+
* **plugins:** add Row Detail plugin final code & tests ([045ea6d](https://github.com/ghiscoding/slickgrid-universal/commit/045ea6d0e49e55163edcbe1ec6e796f51349667b))
+
* **plugins:** make it possible to use both Header Button/Menu together ([965bd58](https://github.com/ghiscoding/slickgrid-universal/commit/965bd588aeba7528031f309020bdfd3c611ebeab))
+
* **plugins:** move Checkbox and Row Selection plugins to universal ([06f0ab1](https://github.com/ghiscoding/slickgrid-universal/commit/06f0ab155a2f0ee06681d3e94780397c5e4f9f67))
+
* **plugins:** move external Cell Menu into Slickgrid-Universal ([6f34c10](https://github.com/ghiscoding/slickgrid-universal/commit/6f34c10b9a8522ae430e13c9519083451bf71ebf))
+
* **plugins:** move external cell related plugins to universal ([11e15d8](https://github.com/ghiscoding/slickgrid-universal/commit/11e15d88360b7b30ca7ab94624a7928201f15945))
+
* **plugins:** move external Context Menu into Slickgrid-Universal ([2170bb4](https://github.com/ghiscoding/slickgrid-universal/commit/2170bb4e3f02ef6f45ad13a1c59730047942651e))
+
* **plugins:** move external Draggable Grouping into Slickgrid-Universal ([8e6eb48](https://github.com/ghiscoding/slickgrid-universal/commit/8e6eb4881741313b7d582d2e3d17ffef582ecb35))
+
* **plugins:** move external GroupItemMetataProvider into Universal ([8f18c7d](https://github.com/ghiscoding/slickgrid-universal/commit/8f18c7d3d616e4cd72eb5478d544ec241c53154f))
+
* **plugins:** move external Header Button into Slickgrid-Universal ([69711ad](https://github.com/ghiscoding/slickgrid-universal/commit/69711aded5aa835091789800214f82cd7c72753e))
+
* **plugins:** move external Header Menu into Slickgrid-Universal ([aeba480](https://github.com/ghiscoding/slickgrid-universal/commit/aeba4801fdb5cba3976984f5c591be8c1ad97e4b))
+
* **plugins:** move Row Detail View plugin to universal ([9700ff4](https://github.com/ghiscoding/slickgrid-universal/commit/9700ff49132e9408b808f916f634976d80e12579))
+
* **plugins:** move Row Detail View plugin to universal ([fb327a6](https://github.com/ghiscoding/slickgrid-universal/commit/fb327a6abe85b86683572cde2a550de43a01f9e1))
+
* **plugins:** move Row Move Manager plugin to universal ([b19b2ed](https://github.com/ghiscoding/slickgrid-universal/commit/b19b2ed2da669662fbbdcf9fdefac243132909b2))
+
* **plugins:** replace AutoTooltips Extension by plugin ([80df14d](https://github.com/ghiscoding/slickgrid-universal/commit/80df14da9b66e9e1b8314e5adb1b96890cc7baa1))
+
* **plugins:** show bullet when command menu icon missing ([cbe580a](https://github.com/ghiscoding/slickgrid-universal/commit/cbe580a97313b7b90e287586b4a6420f0a983f20))
+
* **selection:** add `caller` property to `onSelectedRowsChanged` event ([cc5f4ae](https://github.com/ghiscoding/slickgrid-universal/commit/cc5f4aec7334b6d001bde55dacf83722c3b2763b))
+
* **utils:** replace ext lib `assign-deep` by local `deepMerge` util ([2f56bd3](https://github.com/ghiscoding/slickgrid-universal/commit/2f56bd3571d9c5fb689a09d21cfb3813f5b70e89))
## [0.19.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.19.1...v0.19.2) (2021-11-19)
@@ -879,8 +1239,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** add DOM purify optional default import to fix rollup builds ([3bd335d](https://github.com/ghiscoding/slickgrid-universal/commit/3bd335dd62d0829c1581ca0fde560c93dcd84458))
+
* **resizer:** use autosize width when total width smaller than viewport ([555fb0c](https://github.com/ghiscoding/slickgrid-universal/commit/555fb0cb793c111de837ffe6e9f212fcbf5ed701))
+
* **translation:** add new UNFREEZE_COLUMNS to fix translation ([0010861](https://github.com/ghiscoding/slickgrid-universal/commit/001086165434f619f1e90f664e2185b77fb6a92e))
+
* **translation:** add new UNFREEZE_COLUMNS to fix translation ([22ed231](https://github.com/ghiscoding/slickgrid-universal/commit/22ed2313c45587f2ebdb279c9e47df881c6f83d6))
## [0.19.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.19.0...v0.19.1) (2021-11-15)
@@ -888,10 +1251,15 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** typo on script package name to rename ([76cee09](https://github.com/ghiscoding/slickgrid-universal/commit/76cee094f4ef771ebfdb79386c3e8577f89d397e))
+
* **context:** strin hidden special chars on context menu Copy command ([221c05d](https://github.com/ghiscoding/slickgrid-universal/commit/221c05d8d6345d090074c92e423071888e4a2686))
+
* **context:** when copying use opacity 0 on temp element ([3f0896f](https://github.com/ghiscoding/slickgrid-universal/commit/3f0896fab30aa5a3da278912f00272ce434b8c15))
+
* **export:** sanitize any html that could exist in header titles ([abdae52](https://github.com/ghiscoding/slickgrid-universal/commit/abdae52822c4496286a653ed84be964213e1d32f))
+
* **subscriptions:** unsubscribe every subcriptions while disposing comp ([bf0dcd4](https://github.com/ghiscoding/slickgrid-universal/commit/bf0dcd4963171b703f07e705aac7230402c84dbf))
+
* **tree:** reset to initial tree sort when calling "Clear all Sorting" ([984e3a7](https://github.com/ghiscoding/slickgrid-universal/commit/984e3a7bf0bf734f035514d32d44c6164c6fdab1))
# [0.19.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.18.0...v0.19.0) (2021-10-28)
@@ -899,14 +1267,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **frozen:** calling `setPinning` with empty object/null should clear it ([48b11f7](https://github.com/ghiscoding/slickgrid-universal/commit/48b11f74f2ce6541b6e6e03bf7fe194e5be96d0e))
+
* **style:** remove unnecessary css source map ([4e6fc08](https://github.com/ghiscoding/slickgrid-universal/commit/4e6fc085abe19389d28bf7a8cea3f83859582bdc))
+
* **styling:** cleanup CSS files to ship smaller bundle ([69b18bf](https://github.com/ghiscoding/slickgrid-universal/commit/69b18bf3505fc5538de878b7dbf33104faa8b11a))
+
* **tree:** Grid State should have Tree Data initial sort ([b24ce40](https://github.com/ghiscoding/slickgrid-universal/commit/b24ce4032ea671aa6de6d8e2bb8b045359fd897b))
+
* **tree:** use previous state when refreshing dataset afterward ([0982474](https://github.com/ghiscoding/slickgrid-universal/commit/09824741be404d3d05ccff4417f243c4b1c5c113))
### Features
* **plugin:** add row move shadown item while moving/dragging row ([c665ec8](https://github.com/ghiscoding/slickgrid-universal/commit/c665ec88be859feeea89e5ab8826f2b0a57c5cfb))
+
* **plugin:** create new Custom Tooltip plugin ([4c8c4f6](https://github.com/ghiscoding/slickgrid-universal/commit/4c8c4f62423665bc2e1dcf0675b1300607397b6a))
# [0.18.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.17.0...v0.18.0) (2021-09-29)
@@ -914,20 +1287,31 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **comp:** replace `prepend` not supported in IE/Salesforce ([f183115](https://github.com/ghiscoding/slickgrid-universal/commit/f183115e19b3a72d2496db778fab47be35e1aa40))
+
* **context:** Copy Cell via Context Menu shouldn't include Tree symbols ([f710084](https://github.com/ghiscoding/slickgrid-universal/commit/f710084c06cd47d900daccd389de131209e19163))
+
* **filters:** css "filled" class on filters should also work w/Grid View ([e8edae7](https://github.com/ghiscoding/slickgrid-universal/commit/e8edae79bcd5c28438203e269d26f107e26c4ae5))
+
* **resizer:** clear pending resizeGrid on dispose ([07ed6a0](https://github.com/ghiscoding/slickgrid-universal/commit/07ed6a0390f235341b116d981aa4ee84719b029b))
+
* **resizer:** only bind autoresize when enabled ([ca894c0](https://github.com/ghiscoding/slickgrid-universal/commit/ca894c0a83b5762a42b703f28fc59bdb38e01944))
+
* **styling:** List bullets shouldn't show in any frameworks, fixes [#487](https://github.com/ghiscoding/slickgrid-universal/issues/487) ([53ea537](https://github.com/ghiscoding/slickgrid-universal/commit/53ea5379c6109383630362717b980a1dbe099681))
+
* **tree:** when Tree Data is filtered then Sort, footer count is invalid ([4f5fc44](https://github.com/ghiscoding/slickgrid-universal/commit/4f5fc443fbc7a0ab3cbe46722fc6bd85fd4b1594))
### Features
* **context:** expose 3 events for Tree/Grouping clear/collapse/expand ([317f3ad](https://github.com/ghiscoding/slickgrid-universal/commit/317f3ad443f8ac81c7cacacaec6d38553bec147b))
+
* **pagination:** rewrite in vanilla JS make it usable in any framework ([0211181](https://github.com/ghiscoding/slickgrid-universal/commit/0211181d0353f1f8d2baa0eaba3c2e85073285e7))
+
* **Resizer:** add useResizeObserver option ([bb33cdd](https://github.com/ghiscoding/slickgrid-universal/commit/bb33cdd716834913846ab2fcf74a84f8424acf92))
+
* **sorts:** option to ignore accent while sorting text ([1b4fe81](https://github.com/ghiscoding/slickgrid-universal/commit/1b4fe81d613b780aefcc0ba3e7b16c20eaebd0aa))
+
* **styling:** increase highlight of filters that are filled w/values ([8f93534](https://github.com/ghiscoding/slickgrid-universal/commit/8f9353418190ee3e11aca65d1a57fa4204331011))
+
* **tree:** new `excludeChildrenWhenFilteringTree` set as new default ([47df943](https://github.com/ghiscoding/slickgrid-universal/commit/47df943414f383a47062a7ad9245700a1bd8a24e))
# [0.17.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.16.2...v0.17.0) (2021-09-09)
@@ -935,29 +1319,49 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **bundle:** don't assume slickgrid/dataview are always defined ([0505713](https://github.com/ghiscoding/slickgrid-universal/commit/050571315f0d11f1eff853b3961f3be941a99e51))
+
* **composite:** calling Edit change shouldn't affect Mass-Update ([0ae2a90](https://github.com/ghiscoding/slickgrid-universal/commit/0ae2a90e2aad095f122c308e9d1343f475ad7190))
+
* **core:** potential event binding leaks not all removed when disposing ([3e61712](https://github.com/ghiscoding/slickgrid-universal/commit/3e61712156f3b76b48b04d66bb05f2533f041831))
+
* **filters:** IN_CONTAINS should be sanitized when used with html ([961d8fd](https://github.com/ghiscoding/slickgrid-universal/commit/961d8fd7ea6f915dd8f0749d0329219b82923fea))
+
* **filters:** remove Filters from DOM after header row gets destroyed ([b08d4ba](https://github.com/ghiscoding/slickgrid-universal/commit/b08d4ba070ec9d9d131d6830e4625e6ef950ac09))
+
* **footer:** use `getFilteredItemCount` to show correct count, fix [#469](https://github.com/ghiscoding/slickgrid-universal/issues/469) ([963235c](https://github.com/ghiscoding/slickgrid-universal/commit/963235c017c28309460d2cb88de88c880ac0cb4f))
+
* **grouping:** Draggable Grouping should clear preheader when called ([37811a5](https://github.com/ghiscoding/slickgrid-universal/commit/37811a51d2af04e78aedc88ff5d8eae8a622ac40))
+
* **resizer:** regression introduced by [#462](https://github.com/ghiscoding/slickgrid-universal/issues/462) for the grid resize in SF ([f34d8b9](https://github.com/ghiscoding/slickgrid-universal/commit/f34d8b9678c7ee9e76534a7f7ffdf2c4d7f9f772))
+
* **resizer:** resizer not always triggered in SF and show broken UI ([89fc62e](https://github.com/ghiscoding/slickgrid-universal/commit/89fc62eff7fac8b5cf43b3b6acd7590ed84288f6))
+
* **state:** don't use previous columns ref when getting current cols ([f312c60](https://github.com/ghiscoding/slickgrid-universal/commit/f312c60349d5bc95527ec93cb752f449d1c761f7))
+
* **styling:** add ms-select placeholder bg-color to fix Bootstrap 5 ([2c34d12](https://github.com/ghiscoding/slickgrid-universal/commit/2c34d1229c14bd36bd034062cc7eb7a7cbe1bf5c))
+
* **styling:** add ms-select placeholder bg-color to fix Bootstrap 5 ([5d6454e](https://github.com/ghiscoding/slickgrid-universal/commit/5d6454e9f175b8694f372a7e26492ae573eb918f))
### Features
* **aggregators:** add better TS typing for all Aggregators ([1518d6a](https://github.com/ghiscoding/slickgrid-universal/commit/1518d6aef194f184390316f8421f51d23a1d470a))
+
* **backend:** add cancellable onBeforeSearchChange & revert on error ([b26a53d](https://github.com/ghiscoding/slickgrid-universal/commit/b26a53d2e1fc7172c8c054b9c27ab1b3a2d3dff6))
+
* **backend:** add cancellable onBeforeSort & revert sort on error ([958f823](https://github.com/ghiscoding/slickgrid-universal/commit/958f823a6bffedc2c146c7c68d49a29419812995))
+
* **backend:** add cancellable Pagination change & revert on error ([7a8d903](https://github.com/ghiscoding/slickgrid-universal/commit/7a8d9038f230ba433f2773c02992a211a322ebd4))
+
* **composite:** move SlickGrid Composite Editor factory into universal ([c813cea](https://github.com/ghiscoding/slickgrid-universal/commit/c813ceac1ed6535963df15e7933a444de3a8790a))
+
* **editors:** add Ctrl+S combo to enhance LongText (textarea) Editor ([5116bbd](https://github.com/ghiscoding/slickgrid-universal/commit/5116bbd9e837a3bbd9835b10b2167edf3561cd3d))
+
* **filters:** option to ignore accent while filtering text, closes [#470](https://github.com/ghiscoding/slickgrid-universal/issues/470) ([cba9a4e](https://github.com/ghiscoding/slickgrid-universal/commit/cba9a4e4d12b6dfaaec06af5edf4c629b2943feb))
+
* **sanitize:** make sure any string sent to innerHtml are sanitized ([fe55046](https://github.com/ghiscoding/slickgrid-universal/commit/fe550461d27d01cb5c54d93812db82fa7213f96b))
+
* **styling:** only show header menu caret when hovering ([41e7856](https://github.com/ghiscoding/slickgrid-universal/commit/41e7856f9483f7228d1455f2e3810ae58a5f5c8d))
+
* **tree:** add `dynamicallyToggledItemState` method to toggle parent(s) ([26369f9](https://github.com/ghiscoding/slickgrid-universal/commit/26369f9b6c9e81ad5705f580896ab28cf362d090))
## [0.16.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.16.1...v0.16.2) (2021-07-23)
@@ -965,6 +1369,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **formatters:** Complex Object Formatter shouldn't throw with null data ([3421465](https://github.com/ghiscoding/slickgrid-universal/commit/342146557c16b560b5b8ef0f0e47f971179bc765))
+
* **tree:** exclude the correct type from interface argument ([af51784](https://github.com/ghiscoding/slickgrid-universal/commit/af51784aa3471dcc88c567f4c3762ab7590184f6))
## [0.16.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.16.0...v0.16.1) (2021-07-16)
@@ -978,10 +1383,15 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **events:** use nullish coalescing in slickgrid event prefix ([6ff551b](https://github.com/ghiscoding/slickgrid-universal/commit/6ff551b6dab1ba1d8b471273f3419bdb29a60a35))
+
* **examples:** onBeforeEditCell should return bool true/false ([382bfc8](https://github.com/ghiscoding/slickgrid-universal/commit/382bfc8d9f8bc2c176d617bd49e9b9b230c47be9))
+
* **filter:** refreshTreeDataFilters only when Tree is enabled ([07c70d5](https://github.com/ghiscoding/slickgrid-universal/commit/07c70d5d17dab464cefb1046c72abbd41da4c834))
+
* **filters:** always find locale even without TranslaterService ([c4b17c4](https://github.com/ghiscoding/slickgrid-universal/commit/c4b17c4f51ba6f80b907dab0fd0493a8b0944908))
+
* **styling:** remove css variable on width causing UX problem ([df69f9c](https://github.com/ghiscoding/slickgrid-universal/commit/df69f9c33604187f91adaf5bb8b43b6abd624d32))
+
* **tree:** same dataset length but w/different prop should refresh Tree ([549008a](https://github.com/ghiscoding/slickgrid-universal/commit/549008a40ef34a95200c275fbf84bbf7b10aa4bb))
### Features
@@ -989,7 +1399,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
* **aria:** add aria-label to all Editors/Filters & other html templates ([1a4f8f7](https://github.com/ghiscoding/slickgrid-universal/commit/1a4f8f7873d76b7da5a7d38debed598d3d395c10))
* make constructor arguments as readonly ([a4588ea](https://github.com/ghiscoding/slickgrid-universal/commit/a4588ea5722ae44b647b8c0d02cf8e2a60ff5963))
+
* **services:** make everything extendable by using `protected` ([ecbb93a](https://github.com/ghiscoding/slickgrid-universal/commit/ecbb93a56abba39dd050bbd6019b86694495edd1))
+
* **styling:** add support for CSS Variables ([674dd1a](https://github.com/ghiscoding/slickgrid-universal/commit/674dd1a064d4d42af1d5841ac87ba8ea35a26b2f))
# [0.15.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.14.1...v0.15.0) (2021-07-06)
@@ -997,56 +1409,103 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **addon:** providing columnIndexPosition should always work ([42c8cff](https://github.com/ghiscoding/slickgrid-universal/commit/42c8cff7dd6cf9103149445969be289710549590))
+
* **build:** the "files" property should be included in pkg.json ([3d8f12e](https://github.com/ghiscoding/slickgrid-universal/commit/3d8f12e5f55079445c6fb5cde767f8e0b4511ebb))
+
* **demo:** we should be able to move row(s) and keep selections ([d5669a1](https://github.com/ghiscoding/slickgrid-universal/commit/d5669a1d9c07680540d084dad6e1ef06faca0357))
+
* **editors:** longText Editor (textarea) was scrolling to page bottom ([a4e37a0](https://github.com/ghiscoding/slickgrid-universal/commit/a4e37a0baf329a100f72fe12c35af67fa072829a))
+
* **editors:** select dropdown value is undefined it shouldn't call save ([015294b](https://github.com/ghiscoding/slickgrid-universal/commit/015294b86e431e8109ce540dda7856b7e9e27575))
+
* **export:** expanded Row Detail shouldn't be exported, fixes [#390](https://github.com/ghiscoding/slickgrid-universal/issues/390) ([cef826c](https://github.com/ghiscoding/slickgrid-universal/commit/cef826c1deb458c316bdeaa4fdeba27e748595f3))
+
* **filters:** filtering with IN_CONTAINS should also work with spaces ([ab54724](https://github.com/ghiscoding/slickgrid-universal/commit/ab5472437b94fe81270f809ab6fd00f204c688b8))
+
* **formatters:** shouldn't auto-add editor formatter multiple times ([177b8d4](https://github.com/ghiscoding/slickgrid-universal/commit/177b8d44cddbbcdece48360071fbed25ceab10eb))
+
* **frozen:** in some occasion column pinning changes column positions ([70cb74e](https://github.com/ghiscoding/slickgrid-universal/commit/70cb74ef1119a60b37d438130d4a463a87a8939a))
+
* **menu:** toggle filter bar could be out of sync w/horizontal scroll ([ab7f589](https://github.com/ghiscoding/slickgrid-universal/commit/ab7f58929b10d1b250765b707363aedd9f9d7866))
+
* **pagination:** able to change translate pubsub event name in component ([4745063](https://github.com/ghiscoding/slickgrid-universal/commit/4745063930374a21986fc11d736d3bd05c9d6e41))
+
* **pagination:** should be able to toggle Pagination ([c0367c2](https://github.com/ghiscoding/slickgrid-universal/commit/c0367c24da2ccb3558e1b27f8e70a81d84201479))
+
* **Pagination:** the Pagination wasn't showing when using dataset setter ([ac3f933](https://github.com/ghiscoding/slickgrid-universal/commit/ac3f933d9829edcf89e5ea15571da9a7e4b7c4ba))
+
* **plugin:** row move shouldn't go further when onBefore returns false ([e9bfb5c](https://github.com/ghiscoding/slickgrid-universal/commit/e9bfb5ceba6a18a020b8b34f72abba6e3d13d8b8))
+
* **resizer:** few fixes & adjustments after trying in SF ([32e80ec](https://github.com/ghiscoding/slickgrid-universal/commit/32e80ecdbc5072c1619593d101289a3c1ea92b3a))
+
* **resizer:** tweak resize check to stop much earlier ([ea35b08](https://github.com/ghiscoding/slickgrid-universal/commit/ea35b08973e7b58b49969337875816bcad78e0ba))
+
* **services:** toggle pagination was not displaying all row selection ([e51ccb4](https://github.com/ghiscoding/slickgrid-universal/commit/e51ccb4352bf3a578159b8b63f0a6caf891c382a))
+
* **state:** changeColumnsArrangement should work w/columnIndexPosition ([7c1e9d3](https://github.com/ghiscoding/slickgrid-universal/commit/7c1e9d3d243988d6d99a9696b0afbe8f62ac45b4))
+
* **state:** Grid View/Columns dynamically should work w/row move ([a7cf1df](https://github.com/ghiscoding/slickgrid-universal/commit/a7cf1dfb73c770908aadf01fd67680c985449f9d))
+
* **state:** Grid View/Columns dynamically should work w/row selection ([865944f](https://github.com/ghiscoding/slickgrid-universal/commit/865944f5d6aadc0c05c7f83db7c11a569a33118f))
+
* **styling:** address latest dart-sass math division deprecation warning ([b7317d8](https://github.com/ghiscoding/slickgrid-universal/commit/b7317d8fa619b35fb65789e12b268d65ff65968c))
+
* **styling:** header title should show ellipsis if too long ([607e14d](https://github.com/ghiscoding/slickgrid-universal/commit/607e14d7fffa4f9854eff5103e1a1a0881664286))
+
* **tree:** calling updateItems should not lose the Tree collapsing icon ([45b9622](https://github.com/ghiscoding/slickgrid-universal/commit/45b96225dd5a676b6a85bbb2c8146137eb95b33f))
+
* **tree:** using `initiallyCollapsed` change internal toggled state ([380f2f9](https://github.com/ghiscoding/slickgrid-universal/commit/380f2f903d9908e2bed5b3f44d04e28e5d5b9c63))
+
* initial grid state should also include toggled presets ([f1fe39f](https://github.com/ghiscoding/slickgrid-universal/commit/f1fe39f5d68487e815be7fd3d7ca5a6fd4cba7c6))
+
* make sure dataset is array before getting his length ([702d9fd](https://github.com/ghiscoding/slickgrid-universal/commit/702d9fddb5e753bfa5323bd2f25fd0bb33cb749a))
+
* option labels weren't showing correctly after running Cypress tests ([10d4339](https://github.com/ghiscoding/slickgrid-universal/commit/10d4339da70cce4977707a6a19a79cceb4bf87df))
+
* provide input type directly in constructor before init() is called ([e89c3bd](https://github.com/ghiscoding/slickgrid-universal/commit/e89c3bd3da66e4b16342cefe1eedd5df96363e45))
### Features
* **components:** extract Custom Footer to be an external component ([1794c27](https://github.com/ghiscoding/slickgrid-universal/commit/1794c27d7669c172f606d709d3360bc5d2f77798))
+
* **editors:** convert jQuery to native element on slider editor ([3181cf0](https://github.com/ghiscoding/slickgrid-universal/commit/3181cf069d9f3bc85dc0d13ceeb9623d21ae8eff))
+
* **editors:** replace jQuery with native element on date editor ([062f1f9](https://github.com/ghiscoding/slickgrid-universal/commit/062f1f9713c8f236c30b4d631b601b24b56a530d))
+
* **editors:** use class inheritance to extend main input editor ([ad3e696](https://github.com/ghiscoding/slickgrid-universal/commit/ad3e6965d4cd4295086401de26b5d3aad13a7650))
+
* **filters:** build multiple-select options from native dom elements ([aa548a9](https://github.com/ghiscoding/slickgrid-universal/commit/aa548a9bc05da0d4d5233a2633ae3055fd9f7178))
+
* **filters:** convert jQuery to native element on more filters ([b46eb5e](https://github.com/ghiscoding/slickgrid-universal/commit/b46eb5ebdb177e7d0d6c93cb6df541cedc7eb5d1))
+
* **filters:** convert jQuery to native elements on multiple filters ([3a80996](https://github.com/ghiscoding/slickgrid-universal/commit/3a80996bec96e465d23a30387af707289f4089e3))
+
* **footer:** add option to customize right footer text ([2ea41cc](https://github.com/ghiscoding/slickgrid-universal/commit/2ea41cc8ab38ebc5d5276c90de33b57247c4476f))
+
* **formatters:** add Bootstrap Dropdown Formatter ([5ba9423](https://github.com/ghiscoding/slickgrid-universal/commit/5ba9423200e60460c22f05253901707ef7055782))
+
* **Pagination:** decouple the Pagination Component to separate package ([606795b](https://github.com/ghiscoding/slickgrid-universal/commit/606795b677956a88c2e4b5e943fddcaba3113b51))
+
* **services:** convert jQuery to native elements ([4da0a20](https://github.com/ghiscoding/slickgrid-universal/commit/4da0a201aaa866447a0c76e3b9c16503e2ed6af9))
+
* **services:** decouple the EventPubSubService to separate package ([9f51665](https://github.com/ghiscoding/slickgrid-universal/commit/9f516655e9ce5f06e0cfeabc43536834dc38c70b))
+
* **services:** move Resizer Service w/common services folder for reuse ([d127ac7](https://github.com/ghiscoding/slickgrid-universal/commit/d127ac797ee787ea7785e8ae9f4c0bcaed786afd))
+
* **styling:** add a new `color-disabled-dark` ([55c3062](https://github.com/ghiscoding/slickgrid-universal/commit/55c30621241ec5da7a2e19879265c4e15a6ad907))
+
* **styling:** add a new `color-disabled` ([7151198](https://github.com/ghiscoding/slickgrid-universal/commit/7151198dd393c0bc93151cc4dc9c3295917b6b3e))
+
* **styling:** add extra material icons & new color ([4205b66](https://github.com/ghiscoding/slickgrid-universal/commit/4205b664e80af691c72d5520e4778ad4cd7d94b3))
+
* **tree:** add `getItemCount` method with optional tree level ([b3f8f94](https://github.com/ghiscoding/slickgrid-universal/commit/b3f8f9484e7ea352b2ed264c6a27e1e091eaf918))
+
* **tree:** add Tree Collapse Grid State/Preset ([998b01a](https://github.com/ghiscoding/slickgrid-universal/commit/998b01a2f10ccee5636f616921dd86b35a4feaec))
+
* **tree:** add ways to reapply Tree Collapse previous state ([3702ed3](https://github.com/ghiscoding/slickgrid-universal/commit/3702ed32629f84397349147c978ca650043c45eb))
+
* add new Input Password Editor which uses common inputEditor ([87e547c](https://github.com/ghiscoding/slickgrid-universal/commit/87e547c0dbccc106a1109c3902ac2027fbd52138))
+
* convert jQuery to native element on few more filters ([7d5e1e8](https://github.com/ghiscoding/slickgrid-universal/commit/7d5e1e859a0331699d6fb07d2d35797d7274d1df))
## [0.14.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.14.0...v0.14.1) (2021-05-22)
@@ -1060,31 +1519,53 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **backend:** able to preset filters on hidden columns & all queried ([f1d92cd](https://github.com/ghiscoding/slickgrid-universal/commit/f1d92cda4cb3fabee00bb10dae36d68cd1d861e5))
+
* **backend:** able to preset filters on hidden columns & all queried ([c610979](https://github.com/ghiscoding/slickgrid-universal/commit/c610979c54170c069b97a71864d95d0363d75e80))
+
* **editors:** select editor inline blur save before destroy ([0e591b1](https://github.com/ghiscoding/slickgrid-universal/commit/0e591b1812fc1c733c03f7afcf81dee7a3e4b107))
+
* **formatters:** Tree Data use nullish coallescing w/optional chaining ([f6cf14c](https://github.com/ghiscoding/slickgrid-universal/commit/f6cf14c06518d47742ee17d82a22a39af490c9e7))
+
* **frozen:** rollback previous commit since the issue was found in SlickGrid (core) ([780bcd7](https://github.com/ghiscoding/slickgrid-universal/commit/780bcd7bfae35e26cd84c9a6d220e2dab9eca3b4))
+
* **presets:** loading columns presets should only be done once ([4273aa9](https://github.com/ghiscoding/slickgrid-universal/commit/4273aa9f123d429d5fe4d2163b19407cece86ba9)), closes [#341](https://github.com/ghiscoding/slickgrid-universal/issues/341)
+
* **resizer:** fix a regression bug caused by previous PR [#341](https://github.com/ghiscoding/slickgrid-universal/issues/341) ([462e330](https://github.com/ghiscoding/slickgrid-universal/commit/462e330d9457300fa3ef4e67bf8e012d8167ca2c))
+
* **resizer:** remove delay to call resize by content to avoid flickering ([961efe6](https://github.com/ghiscoding/slickgrid-universal/commit/961efe6fe7ad721e8196c76ed4c35205830b6b83))
+
* **services:** fix couple of issues found with custom grid views ([db06736](https://github.com/ghiscoding/slickgrid-universal/commit/db0673688b2b6e6dde8f25af9551bf6c27174a44))
+
* **sorting:** multi-column sort shouldn't work when option is disabled ([bfc8651](https://github.com/ghiscoding/slickgrid-universal/commit/bfc865128de0a9e4c21ff0dc8b564c15c88dea93))
+
* **styling:** add a better search filter magnify glass icon as placeholder ([5464824](https://github.com/ghiscoding/slickgrid-universal/commit/5464824f3719ebddb303ee1b82161638d870a288))
+
* **styling:** center horizontally checkbox selector in column header ([bb5aebc](https://github.com/ghiscoding/slickgrid-universal/commit/bb5aebc355a22e19b0071bfe993bbeb0e1090265))
+
* **styling:** dart-sass deprecation warnings use math utils instead ([b5d8103](https://github.com/ghiscoding/slickgrid-universal/commit/b5d81030eb859524e09547ef13642dbed2902ea5))
+
* **tree:** Tree Data export should also include correct indentation ([f1e06c1](https://github.com/ghiscoding/slickgrid-universal/commit/f1e06c11f9eaa9ee778d319bfbaba20bb9abfcc9))
+
* **tree:** couple of issues found in Tree Data, fixes [#307](https://github.com/ghiscoding/slickgrid-universal/issues/307) ([e684d1a](https://github.com/ghiscoding/slickgrid-universal/commit/e684d1af1c078a8861c3c94fe5486cbe68d57b85))
### Features
* **addon:** provide grid menu labels for all built-in commands ([44c72d3](https://github.com/ghiscoding/slickgrid-universal/commit/44c72d3ca0b8a88e6ae5022a25b11c4d41fd2897))
+
* **editors:** add `compositeEditorFormOrder` option ([03f2d66](https://github.com/ghiscoding/slickgrid-universal/commit/03f2d662a69d71edf4b61cdda862fb4eef0f9b47))
+
* **editors:** add ways to preload date without closing date picker ([3088038](https://github.com/ghiscoding/slickgrid-universal/commit/30880380584b281c756e0ad437031631e6f607e0))
+
* **resizer:** add `resizeByContentOnlyOnFirstLoad` grid option ([ffe7dc4](https://github.com/ghiscoding/slickgrid-universal/commit/ffe7dc4c2a7ae778c8e731fd7637b154c10035f0))
+
* **resizer:** add single Column Resize by Content dblClick & headerMenu ([683389f](https://github.com/ghiscoding/slickgrid-universal/commit/683389fcc343ac5c0378a9e34b7f11dda97fc719))
+
* **services:** add onBeforeResizeByContent (onAfter) ([3e99fab](https://github.com/ghiscoding/slickgrid-universal/commit/3e99fabb8554161e4301c0596eaebd9e0d246de7))
+
* **styling:** add new marker material icons for project ([9b386fa](https://github.com/ghiscoding/slickgrid-universal/commit/9b386fa3e6af8e76cf4beb5aa0b5322db2f270af))
+
* **tree:** improve Tree Data speed considerably ([5487798](https://github.com/ghiscoding/slickgrid-universal/commit/548779801d06cc9ae7e319e72d351c8a868ed79f))
+
* **editors:** replace jQuery with native elements ([d6e8f4e](https://github.com/ghiscoding/slickgrid-universal/commit/d6e8f4e59823673df290b179d7ee277e3d7bb1af))
# [0.13.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.12.0...v0.13.0) (2021-04-27)
@@ -1092,24 +1573,39 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **demo:** call `scrollColumnIntoView` after changing view ([b751151](https://github.com/ghiscoding/slickgrid-universal/commit/b751151fb11dfaeb48ff1f4daf5ed32ad56122a0))
+
* **editors:** Composite Editor modal compo should work w/complex objects ([#298](https://github.com/ghiscoding/slickgrid-universal/issues/298)) ([721a6c5](https://github.com/ghiscoding/slickgrid-universal/commit/721a6c5627369cfc89710705384995f8aba3a178))
+
* **exports:** grid with colspan should be export accordingly ([#311](https://github.com/ghiscoding/slickgrid-universal/issues/311)) ([e899fbb](https://github.com/ghiscoding/slickgrid-universal/commit/e899fbba3daa41261dcaa57b0555e37e9bdfafb4))
+
* **footer:** add correct implemtation of locale usage in custom footer ([6e18bf9](https://github.com/ghiscoding/slickgrid-universal/commit/6e18bf9a8af070428bbb3cb429392df1eb19be54))
+
* **observables:** http cancellable Subject should be unsubscribed ([cbc951b](https://github.com/ghiscoding/slickgrid-universal/commit/cbc951bcf5891658f55981e88887f41b4fb5d5c4))
+
* **resize:** columns reposition not coming back after grid setOptions ([f2027e6](https://github.com/ghiscoding/slickgrid-universal/commit/f2027e60f418bb94f9d32c779d0474de4d87a5c9))
+
* **selection:** full row selection should be selected w/show hidden row ([f76e30c](https://github.com/ghiscoding/slickgrid-universal/commit/f76e30cdca476c947089d88069bd21e42639ba7e))
+
* **tests:** try setting fixed TZ while running Jest ([d316db9](https://github.com/ghiscoding/slickgrid-universal/commit/d316db98acada214b082c2ff9925449822df96e8))
### Features
* **editors:** add `onBeforeOpen` optional callback to Composite Editor ([#306](https://github.com/ghiscoding/slickgrid-universal/issues/306)) ([a642482](https://github.com/ghiscoding/slickgrid-universal/commit/a642482254009115366ca4992e2e60647f8ae9b0))
+
* **editors:** add `target` to `onBeforeEditCell` w/called by composite ([#301](https://github.com/ghiscoding/slickgrid-universal/issues/301)) ([7440ff5](https://github.com/ghiscoding/slickgrid-universal/commit/7440ff58988acd7abd1ce249b1ceb72556cceb1d))
+
* **filters:** add option to filter empty values for select filter ([#310](https://github.com/ghiscoding/slickgrid-universal/issues/310)) ([c58a92a](https://github.com/ghiscoding/slickgrid-universal/commit/c58a92a8e2b29ea216211e3561d5567c43f0376a))
+
* **filters:** option to add custom compound operator list ([3e8d2cb](https://github.com/ghiscoding/slickgrid-universal/commit/3e8d2cbcea6181e3ce3157798f003a8479d11011))
+
* **footer:** add row selection count to the footer component ([8ba146c](https://github.com/ghiscoding/slickgrid-universal/commit/8ba146cd4cbdccdb61f3441918065fad4561ff84))
+
* **resize:** add column resize by cell content ([#309](https://github.com/ghiscoding/slickgrid-universal/issues/309)) ([515a072](https://github.com/ghiscoding/slickgrid-universal/commit/515a072b3a16d3aca0f48e62c968ae89a1510669))
+
* **services:** remove deprecated hideColumnByIndex form Grid Service ([#312](https://github.com/ghiscoding/slickgrid-universal/issues/312)) ([b00c64d](https://github.com/ghiscoding/slickgrid-universal/commit/b00c64d8f88d4560c677f667a84d95ba30e96399))
+
* **styling:** switch from node-sass to dart-sass (sass) ([81f8d9f](https://github.com/ghiscoding/slickgrid-universal/commit/81f8d9fbd1381b4c877eeeb4992bdcc90c1cd677))
+
* **typing:** add missing item metadata interface ([#299](https://github.com/ghiscoding/slickgrid-universal/issues/299)) ([7cf0a21](https://github.com/ghiscoding/slickgrid-universal/commit/7cf0a2185c73dcb7748a193ba2272bb7af699266))
# [0.12.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.11.2...v0.12.0) (2021-03-24)
@@ -1117,27 +1613,45 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **editors:** show all editors as 100% height in their cell container ([#277](https://github.com/ghiscoding/slickgrid-universal/issues/277)) ([3f49aea](https://github.com/ghiscoding/slickgrid-universal/commit/3f49aeabd6016c705d4d6b809345fe1ac948cfc5))
+
* **filters:** rollback a change made in PR [#288](https://github.com/ghiscoding/slickgrid-universal/issues/288) causing preset issues ([18ffc0c](https://github.com/ghiscoding/slickgrid-universal/commit/18ffc0c8285e4e2306bc60817fba357734a65b61))
+
* **filters:** SearchTerms shouldn't come back after calling clearFilters ([04f3d12](https://github.com/ghiscoding/slickgrid-universal/commit/04f3d1267de493b9dc1e922dca3b433b9cb34fde))
+
* **filters:** string <> should be Not Contains instead of Not Equal ([#276](https://github.com/ghiscoding/slickgrid-universal/issues/276)) ([960884d](https://github.com/ghiscoding/slickgrid-universal/commit/960884ddf58b1e87ad5ef71e3713f8836e6190c0))
+
* **firefox:** add all missing SVG color filter classes for Firefox/SF ([#296](https://github.com/ghiscoding/slickgrid-universal/issues/296)) ([a07ebdf](https://github.com/ghiscoding/slickgrid-universal/commit/a07ebdfbd2c2197c28102efe1f4a685ea61185e1))
+
* **lerna:** downgrade Lerna to previous version to fix thread leaking ([#281](https://github.com/ghiscoding/slickgrid-universal/issues/281)) ([ffde71c](https://github.com/ghiscoding/slickgrid-universal/commit/ffde71c84fd12e9a9fed878b818521fea96c99a5))
+
* **pinning:** reordering cols position freezing cols shouldn't affect ([#275](https://github.com/ghiscoding/slickgrid-universal/issues/275)) ([a30665d](https://github.com/ghiscoding/slickgrid-universal/commit/a30665d54da583c47b1f533002173af99e9ab20d))
+
* **plugin:** Grid Menu Clear Frozen Cols shouldn't change cols positions ([#291](https://github.com/ghiscoding/slickgrid-universal/issues/291)) ([4fdab08](https://github.com/ghiscoding/slickgrid-universal/commit/4fdab08357d12349b6402e3007f4ab399d9a2140))
+
* **presets:** Filter & Sorting presets & Footer metrics issues ([#285](https://github.com/ghiscoding/slickgrid-universal/issues/285)) ([3174c86](https://github.com/ghiscoding/slickgrid-universal/commit/3174c86e011b4927510b99a348e8019adb4baa00))
+
* **presets:** Multiple Select Filter Grid Presets values should be shown ([dd1f231](https://github.com/ghiscoding/slickgrid-universal/commit/dd1f231850819bde455e24d743b9e1637767ecb3))
+
* **resizer:** allow gridHeight/gridWidth to be passed as string ([#284](https://github.com/ghiscoding/slickgrid-universal/issues/284)) ([20bda50](https://github.com/ghiscoding/slickgrid-universal/commit/20bda50bf3ab647ae4ee3d7ffe0c9c8b58e8f187)), closes [#534](https://github.com/ghiscoding/slickgrid-universal/issues/534)
+
* **sorting:** add some unit tests that were previously commented out ([#290](https://github.com/ghiscoding/slickgrid-universal/issues/290)) ([2a91fa6](https://github.com/ghiscoding/slickgrid-universal/commit/2a91fa6f672650bb525a4ba1774d02c5ac435c5b))
### Features
* **editors:** add `onSelect` callback to Autocomplete Editor ([#286](https://github.com/ghiscoding/slickgrid-universal/issues/286)) ([2d106d4](https://github.com/ghiscoding/slickgrid-universal/commit/2d106d4df0a259d36bee3d910320706ddb7e8580))
+
* **filters:** add new IN_COLLECTION operator to allow searching cell value as Array ([#282](https://github.com/ghiscoding/slickgrid-universal/issues/282)) ([ecce93c](https://github.com/ghiscoding/slickgrid-universal/commit/ecce93c92b7424522ad2af0d7d82963a3a56ca97))
+
* **filters:** add optional `filterTypingDebounce` for filters w/keyup ([#289](https://github.com/ghiscoding/slickgrid-universal/issues/289)) ([3aecc89](https://github.com/ghiscoding/slickgrid-universal/commit/3aecc899ebd78d9597cc4ed4919c0a8dd26673a8))
+
* **filters:** add optional `filterTypingDebounce` for keyboard filters ([#283](https://github.com/ghiscoding/slickgrid-universal/issues/283)) ([bb7dcd3](https://github.com/ghiscoding/slickgrid-universal/commit/bb7dcd3a9e28f45c7339e2f30685220b7a152507))
+
* **filters:** add possibility to filter by text range like "a..e" ([#279](https://github.com/ghiscoding/slickgrid-universal/issues/279)) ([e44145d](https://github.com/ghiscoding/slickgrid-universal/commit/e44145d897da570bf6ea15b156c7961ce96ce6f0))
+
* **filters:** display operator into input text filter from Grid Presets ([#288](https://github.com/ghiscoding/slickgrid-universal/issues/288)) ([3fad4fe](https://github.com/ghiscoding/slickgrid-universal/commit/3fad4fe9ef3bec290dabb860d7ea4baf8f182a4a))
+
* **resources:** add RxJS support into Slickgrid-Universal via external package ([#280](https://github.com/ghiscoding/slickgrid-universal/issues/280)) ([c10fc33](https://github.com/ghiscoding/slickgrid-universal/commit/c10fc339019c04ec0f7c4357ccdb3949a2358460))
+
* **state:** add Pinning (frozen) to Grid State & Presets ([#292](https://github.com/ghiscoding/slickgrid-universal/issues/292)) ([ba703d8](https://github.com/ghiscoding/slickgrid-universal/commit/ba703d8353a243ffed4d40804c0f977119424f6c))
## [0.11.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.11.1...v0.11.2) (2021-02-27)
@@ -1157,20 +1671,31 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **backend:** incorrect item count with GraphQL and useLocalFiltering ([3996cf4](https://github.com/ghiscoding/slickgrid-universal/commit/3996cf45b59c721b777e04dba3c10bbf03667bdb))
+
* **build:** enable tsconfig strict mode tsconfig ([#269](https://github.com/ghiscoding/slickgrid-universal/issues/269)) ([095fc71](https://github.com/ghiscoding/slickgrid-universal/commit/095fc71052c1f4e776544781da5fe762cfa16238))
+
* **filters:** don't use indexOf NOT_IN_CONTAINS ([#262](https://github.com/ghiscoding/slickgrid-universal/issues/262)) ([310be30](https://github.com/ghiscoding/slickgrid-universal/commit/310be30efb653151a75dde0a14b1ed3f9946b333))
+
* **filters:** use defaultFilterOperator in range when none provided ([#271](https://github.com/ghiscoding/slickgrid-universal/issues/271)) ([993675f](https://github.com/ghiscoding/slickgrid-universal/commit/993675f6b0d76e76010d5cadc6696134a73dad66))
+
* **helpers:** should be able to highlight first row (0) ([#268](https://github.com/ghiscoding/slickgrid-universal/issues/268)) ([a58be17](https://github.com/ghiscoding/slickgrid-universal/commit/a58be17959e28ab9a1280c3d7d7c8df9db02587e)), closes [#527](https://github.com/ghiscoding/slickgrid-universal/issues/527)
+
* **plugin:** recreate header menu when adding column dynamically ([#257](https://github.com/ghiscoding/slickgrid-universal/issues/257)) ([16c4984](https://github.com/ghiscoding/slickgrid-universal/commit/16c49845c5d3388502811c15f0a23daa1a01f850))
### Features
* **demo:** add Example 13 Header Button Plugin ([f345cd1](https://github.com/ghiscoding/slickgrid-universal/commit/f345cd18b89f849f3f873538c214d3ac24ff12f8))
+
* **editors:** add a Clear (X) button to the Autocomplete Editor ([#270](https://github.com/ghiscoding/slickgrid-universal/issues/270)) ([ffbd188](https://github.com/ghiscoding/slickgrid-universal/commit/ffbd188534992c31848691154517deb64694f3b2))
+
* **filters:** add updateSingleFilter for a single external filter ([#265](https://github.com/ghiscoding/slickgrid-universal/issues/265)) ([20564a3](https://github.com/ghiscoding/slickgrid-universal/commit/20564a3096948626beada698460b72374a18ca7c))
+
* **perf:** huge filtering speed improvements ([a101ed1](https://github.com/ghiscoding/slickgrid-universal/commit/a101ed1b62c2fbfec2712f64e08192a4852bce9d))
+
* **perf:** improve date sorting speed ([258da22](https://github.com/ghiscoding/slickgrid-universal/commit/258da2238bba3693eada058f9405012f68af150b))
+
* **perf:** improve date sorting speed ([#259](https://github.com/ghiscoding/slickgrid-universal/issues/259)) ([a52f4fc](https://github.com/ghiscoding/slickgrid-universal/commit/a52f4fcee1627ac5906388f8dcf4b7fe3f5c4aa7))
+
* **services:** add bulk transactions in Grid Service CRUD methods ([#256](https://github.com/ghiscoding/slickgrid-universal/issues/256)) ([03385d9](https://github.com/ghiscoding/slickgrid-universal/commit/03385d9ac58cb3ce7501a409394706c0cb4f4d29))
## [0.10.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.10.1...v0.10.2) (2021-01-28)
@@ -1190,28 +1715,47 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **comp:** empty data warning should work with autoheight grid ([#240](https://github.com/ghiscoding/slickgrid-universal/issues/240)) ([8c9cb84](https://github.com/ghiscoding/slickgrid-universal/commit/8c9cb84847bfd08a678d333a8555ae6fc9295670))
+
* **component:** Composite Editor sometime shows empty mass update form ([#244](https://github.com/ghiscoding/slickgrid-universal/issues/244)) ([d3ad4db](https://github.com/ghiscoding/slickgrid-universal/commit/d3ad4db45d259fa8ab977cd45c830a7d3bd342d8))
+
* **components:** empty data warning should work with autoheight grid ([#234](https://github.com/ghiscoding/slickgrid-universal/issues/234)) ([16daa36](https://github.com/ghiscoding/slickgrid-universal/commit/16daa368f0e46112fc1d1dd0b1a944ec2b60ced0))
+
* **core:** fix types index.d.ts url ([a76b3a3](https://github.com/ghiscoding/slickgrid-universal/commit/a76b3a3d97a6d211ec2e7e8d9060fd8dd0719f58))
+
* **editors:** add blank disabled fields in Composite Editor form values ([#233](https://github.com/ghiscoding/slickgrid-universal/issues/233)) ([b634902](https://github.com/ghiscoding/slickgrid-universal/commit/b6349029b705991b7ac2d1df99f5b330fe69ef36))
+
* **editors:** add option to skip missing composite editor ([#232](https://github.com/ghiscoding/slickgrid-universal/issues/232)) ([925dba8](https://github.com/ghiscoding/slickgrid-universal/commit/925dba86aca57825ab04d0cdc01484d52bf99265))
+
* **editors:** fix clear date & blank disabled field w/Composite Editor ([#235](https://github.com/ghiscoding/slickgrid-universal/issues/235)) ([9aac97d](https://github.com/ghiscoding/slickgrid-universal/commit/9aac97d2d433c809facc8d7092467780d55ca01a))
+
* **exports:** Excel Export custom width applies the width to next column ([#242](https://github.com/ghiscoding/slickgrid-universal/issues/242)) ([146f64f](https://github.com/ghiscoding/slickgrid-universal/commit/146f64f1b89005e6bb5e982721b5c7e43ecf5ac4))
+
* **filters:** Grid State filters should always include an operator ([#238](https://github.com/ghiscoding/slickgrid-universal/issues/238)) ([f64ed37](https://github.com/ghiscoding/slickgrid-universal/commit/f64ed37f7ffe01346c8f68d4bd170ffdce54839d))
+
* **frozen:** hiding multiple columns when using pinning gets out of sync ([#243](https://github.com/ghiscoding/slickgrid-universal/issues/243)) ([b255220](https://github.com/ghiscoding/slickgrid-universal/commit/b255220ec37dbdc9df4f3ecccb4397656cf9f2a6))
+
* **lint:** add eslint as a pre task when bundling & fix linting errors ([#246](https://github.com/ghiscoding/slickgrid-universal/issues/246)) ([6f7ccd8](https://github.com/ghiscoding/slickgrid-universal/commit/6f7ccd8ee4cc5e005034965a2c2dcc0499f06a73))
+
* **pinning:** recalculate frozen idx properly when column shown changes ([#241](https://github.com/ghiscoding/slickgrid-universal/issues/241)) ([3b55972](https://github.com/ghiscoding/slickgrid-universal/commit/3b559726acdff96970c68c10c8d256d0403d6c4f))
+
* **plugins:** add missing Row Detail filtering code ([#239](https://github.com/ghiscoding/slickgrid-universal/issues/239)) ([d9cad63](https://github.com/ghiscoding/slickgrid-universal/commit/d9cad635840650d2b2dd91444ffa0121147f4140))
+
* **plugins:** throw error when Tree Data used with Pagination ([#229](https://github.com/ghiscoding/slickgrid-universal/issues/229)) ([85718e1](https://github.com/ghiscoding/slickgrid-universal/commit/85718e18cd181734df3ba1a2440ead4368741c53))
+
* **tsc:** running dev watch was overriding commonjs folder ([#249](https://github.com/ghiscoding/slickgrid-universal/issues/249)) ([e466f62](https://github.com/ghiscoding/slickgrid-universal/commit/e466f6214d9450b593daecfdee6682f1f7c9ed19))
### Features
* **editors:** add Clone functionality to Composite Editor ([#236](https://github.com/ghiscoding/slickgrid-universal/issues/236)) ([df545e4](https://github.com/ghiscoding/slickgrid-universal/commit/df545e4ec64271307b1979feb5e786f449433639))
+
* **editors:** add Column Editor collectionOverride option ([0efb18f](https://github.com/ghiscoding/slickgrid-universal/commit/0efb18f916ecd407ec1589bc18f076907fa356c7))
+
* **editors:** change all private keyword to protected for extensability ([#247](https://github.com/ghiscoding/slickgrid-universal/issues/247)) ([089b6cb](https://github.com/ghiscoding/slickgrid-universal/commit/089b6cbbdd6284d94f765fdad08642e0d0d81ff0))
+
* **filters:** change all private keyword to protected for extensability ([#245](https://github.com/ghiscoding/slickgrid-universal/issues/245)) ([52cc702](https://github.com/ghiscoding/slickgrid-universal/commit/52cc7022c4b847566d89e91a80c423373538a15a))
+
* **formatters:** add grid option to auto add custom editor formatter ([#248](https://github.com/ghiscoding/slickgrid-universal/issues/248)) ([db77d46](https://github.com/ghiscoding/slickgrid-universal/commit/db77d464ee37eda573351e89d4c5acc9b5648649))
+
* add nameCompositeEditor override to be used by Composite Editor ([fcdb2e9](https://github.com/ghiscoding/slickgrid-universal/commit/fcdb2e92ed736b09e947cdbcf39ee157afc4acab))
# [0.9.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.8.0...v0.9.0) (2021-01-06)
@@ -1219,15 +1763,21 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **backend:** GraphQL queries with input filter ([#217](https://github.com/ghiscoding/slickgrid-universal/issues/217)) ([ff7f1e5](https://github.com/ghiscoding/slickgrid-universal/commit/ff7f1e5e8733d25a1fd7869e4de2b1bc700b8a7b))
+
* **backend:** OData queries with input filter ([#224](https://github.com/ghiscoding/slickgrid-universal/issues/224)) ([fec1ce8](https://github.com/ghiscoding/slickgrid-universal/commit/fec1ce879507998a04088bf494cfd5a595e90160))
+
* **build:** import Flatpickr Locale on demand via regular imports ([#227](https://github.com/ghiscoding/slickgrid-universal/issues/227)) ([6644822](https://github.com/ghiscoding/slickgrid-universal/commit/664482210557fc1a7a178856e2641f71b9580c44))
+
* **core:** adjust vscode debugger path overrides for WebPack 5 debugging ([a45b3d2](https://github.com/ghiscoding/slickgrid-universal/commit/a45b3d2aa318012366c98fa5b4b3c95cc647120d))
### Features
* **build:** upgrade to WebPack 5 ([#225](https://github.com/ghiscoding/slickgrid-universal/issues/225)) ([c6b3ad3](https://github.com/ghiscoding/slickgrid-universal/commit/c6b3ad3eb6fb64306bfd8bd300fcc1e86b27e5a6))
+
* **ci:** replace CircleCI with GitHub Actions ([#211](https://github.com/ghiscoding/slickgrid-universal/issues/211)) ([4f91140](https://github.com/ghiscoding/slickgrid-universal/commit/4f9114031ca6236ef45f04b67dcba1a9981035c4))
+
* **editors:** add Column Editor collectionOverride option ([#228](https://github.com/ghiscoding/slickgrid-universal/issues/228)) ([91421fc](https://github.com/ghiscoding/slickgrid-universal/commit/91421fc0154e432874fb2211e430a79032b996b8))
+
* **styling:** add support for Bootstrap 5 ([#226](https://github.com/ghiscoding/slickgrid-universal/issues/226)) ([e35f116](https://github.com/ghiscoding/slickgrid-universal/commit/e35f116efc1989f675ef6e030d80a8a31a444373))
# [0.8.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.7.7...v0.8.0) (2020-12-22)
@@ -1235,6 +1785,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** change moment/lodash imports so it works with ES6 module ([#210](https://github.com/ghiscoding/slickgrid-universal/issues/210)) ([2d25d3b](https://github.com/ghiscoding/slickgrid-universal/commit/2d25d3b99f7be93f2bc69f006fb67a39cf39ce7c))
+
* **core:** use regular imports instead of require to load plugins ([#209](https://github.com/ghiscoding/slickgrid-universal/issues/209)) ([6816696](https://github.com/ghiscoding/slickgrid-universal/commit/6816696c98be0d2dd80c1ff49358bd49ee7caacb))
### Features
@@ -1262,7 +1813,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **components:** don't instantiate composite editor twice ([#207](https://github.com/ghiscoding/slickgrid-universal/issues/207)) ([8548393](https://github.com/ghiscoding/slickgrid-universal/commit/854839358bf276432169447bebefe736de02f57d))
+
* **editors:** fix BS3,BS4 styles & slider value not shown with undefined ([#204](https://github.com/ghiscoding/slickgrid-universal/issues/204)) ([3aca8f9](https://github.com/ghiscoding/slickgrid-universal/commit/3aca8f9053365c1987f6c5abc43f8ce5eca015fb))
+
* **exports:** should be able to change export file name ([#205](https://github.com/ghiscoding/slickgrid-universal/issues/205)) ([9d26213](https://github.com/ghiscoding/slickgrid-universal/commit/9d262134b12da46ef1fea970f092d96ce875ed78))
## [0.7.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.7.1...v0.7.2) (2020-12-17)
@@ -1270,7 +1823,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** range default should be inclusive instead of exclusive ([#203](https://github.com/ghiscoding/slickgrid-universal/issues/203)) ([b7f74ad](https://github.com/ghiscoding/slickgrid-universal/commit/b7f74ad8a1539aed32ac643b4fe395fbdecf4459))
+
* **sorting:** add cellValueCouldBeUndefined in grid option for sorting ([#202](https://github.com/ghiscoding/slickgrid-universal/issues/202)) ([865256e](https://github.com/ghiscoding/slickgrid-universal/commit/865256efe927a5715840963cb2945f16a402789b))
+
* **stylings:** small alignment issue with the slider value elm height ([5a453b8](https://github.com/ghiscoding/slickgrid-universal/commit/5a453b8739c07e07f835e111d7d3ca5d627a0c2f))
## [0.7.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.7.0...v0.7.1) (2020-12-17)
@@ -1292,14 +1847,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** add console error if any of column def id includes dot ([#198](https://github.com/ghiscoding/slickgrid-universal/issues/198)) ([6ee40af](https://github.com/ghiscoding/slickgrid-universal/commit/6ee40af507b066602c39e057349b5ead6e7952f3))
+
* **demo:** changing page should remove unsaved cell styling ([17fa349](https://github.com/ghiscoding/slickgrid-universal/commit/17fa3499e298798fdeccf908feb0f0e5ee40436e))
+
* **stylings:** composite editor styling fixes for BS4 ([#195](https://github.com/ghiscoding/slickgrid-universal/issues/195)) ([305eb90](https://github.com/ghiscoding/slickgrid-universal/commit/305eb90c75e6a4aa076c62b5364b904dc5c6518e))
+
* **stylings:** re-align the svg icons & single/multiple-select icon+text ([#194](https://github.com/ghiscoding/slickgrid-universal/issues/194)) ([b730be7](https://github.com/ghiscoding/slickgrid-universal/commit/b730be7a75b3035c01aa7ca8f48a88df447ad461))
### Features
* **core:** add registerExternalResources for Components/Services ([#196](https://github.com/ghiscoding/slickgrid-universal/issues/196)) ([ee02f1d](https://github.com/ghiscoding/slickgrid-universal/commit/ee02f1d62d1a0601421352e43d17bd8c89e4348c))
+
* **core:** refactor code using the container service everywhere ([#197](https://github.com/ghiscoding/slickgrid-universal/issues/197)) ([96ce9bd](https://github.com/ghiscoding/slickgrid-universal/commit/96ce9bdbf18330e522dad0cbb0eda09c41f6a3df))
+
* **formatters:** add numberPrefix & Suffix to Decimal Formatter ([#193](https://github.com/ghiscoding/slickgrid-universal/issues/193)) ([0e4d30c](https://github.com/ghiscoding/slickgrid-universal/commit/0e4d30c0ee23bc598206fbba4e5ed406e4aeecfe))
## [0.5.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.5.0...v0.5.1) (2020-12-10)
@@ -1311,8 +1871,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **editors:** make sure select editor is defined before reading a prop ([763f981](https://github.com/ghiscoding/slickgrid-universal/commit/763f98111d03652b0ad903ba487a3b8c83a5ef5d))
+
* **editors:** only translate button texts when enableTranslate is true ([b698c6b](https://github.com/ghiscoding/slickgrid-universal/commit/b698c6bd3f13af017c7f3c0113b8407269ba1e0d))
+
* **editors:** Select Editor option to return flat data w/complex object ([#189](https://github.com/ghiscoding/slickgrid-universal/issues/189)) ([4695cd3](https://github.com/ghiscoding/slickgrid-universal/commit/4695cd3b6871dc1ceca4036fd30935eca8011b7e))
+
* **exports:** when cell value is empty object return empty string ([#190](https://github.com/ghiscoding/slickgrid-universal/issues/190)) ([cd34901](https://github.com/ghiscoding/slickgrid-universal/commit/cd349012c82a8bdff113fb9f8ef23ea18c6e3035))
### Features
@@ -1346,6 +1909,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** properly export Enums, Interfaces, Services & Utilities ([#184](https://github.com/ghiscoding/slickgrid-universal/issues/184)) ([0c23398](https://github.com/ghiscoding/slickgrid-universal/commit/0c233984a6e9d718659c119b65a95d6c38d36b0c))
+
* **core:** showing/hiding column shouldn't affect its freezing position ([#185](https://github.com/ghiscoding/slickgrid-universal/issues/185)) ([2a812ed](https://github.com/ghiscoding/slickgrid-universal/commit/2a812edb82c8004ab43df224c67ede228ab72c00))
### Features
@@ -1357,8 +1921,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** don't expose src folder on npm & update few npm package ([#168](https://github.com/ghiscoding/slickgrid-universal/issues/168)) ([3c05938](https://github.com/ghiscoding/slickgrid-universal/commit/3c059381b35bba88ea98d0206692c912c625f227))
+
* **core:** rename i18n to translater & fix few other issues ([#174](https://github.com/ghiscoding/slickgrid-universal/issues/174)) ([34c963a](https://github.com/ghiscoding/slickgrid-universal/commit/34c963a2bcef1b841d3c62ea405a4bc49be98a5c))
+
* **editors:** make sure editor element exist before focusing ([e57235b](https://github.com/ghiscoding/slickgrid-universal/commit/e57235b4339ffa1bee522c245665bb598d963fd1))
+
* **examples:** queued edit cells style should follow page it was edited ([#167](https://github.com/ghiscoding/slickgrid-universal/issues/167)) ([bf72139](https://github.com/ghiscoding/slickgrid-universal/commit/bf7213994151c148e878d703ea21d8f8ffb43ca8))
+
* **extensions:** draggable grouping style change to look better ([#171](https://github.com/ghiscoding/slickgrid-universal/issues/171)) ([d00be88](https://github.com/ghiscoding/slickgrid-universal/commit/d00be8868370f3679555b8f52ef4ad85916c93ac))
+
* **formatters:** date formatters should accept ISO input & output to US ([#172](https://github.com/ghiscoding/slickgrid-universal/issues/172)) ([85ce7cf](https://github.com/ghiscoding/slickgrid-universal/commit/85ce7cf3636d5bb43d3ef18ec6998bb0c423d218))
diff --git a/README.md b/README.md
index acd0493cb..f4caa772a 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
[![codecov](https://codecov.io/gh/ghiscoding/slickgrid-universal/branch/master/graph/badge.svg)](https://codecov.io/gh/ghiscoding/slickgrid-universal)
### Documentation
-📘 [Documentation](https://ghiscoding.gitbook.io/slickgrid-universal/) website powered by GitBook (_for version >=4.x or use the [Wikis](https://github.com/ghiscoding/slickgrid-universal/wiki) for older versions_)
+📘 [Documentation](https://ghiscoding.gitbook.io/slickgrid-universal/) website powered by GitBook for version 4+ (__or use [Wikis](https://github.com/ghiscoding/slickgrid-universal/wiki) for older versions__)
### Live Demo
[Live Demo](https://ghiscoding.github.io/slickgrid-universal/) website
@@ -59,25 +59,25 @@ Slickgrid-Universal has close to **100%** Unit Test Coverage, almost 5,000 Jest
### Available Public Packages
-| Package Name | Version | Description | Changes |
+| Package Name | Version | Size (gzip) | Changes |
| -------------| ------- | ----------- | ------- |
-| [@slickgrid-universal/common](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/common) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/common.svg)](https://www.npmjs.com/package/@slickgrid-universal/common) | commonly used Formatters/Editors/Filters/Services/... | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/CHANGELOG.md) |
-| [@slickgrid-universal/binding](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/binding) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/binding.svg)](https://www.npmjs.com/package/@slickgrid-universal/binding) | basic Binding Engine & Helper | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/binding/CHANGELOG.md) |
-| [@slickgrid-universal/event-pub-sub](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/event-pub-sub) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/event-pub-sub.svg)](https://www.npmjs.com/package/@slickgrid-universal/event-pub-sub) | basic PubSub Service using JS Events | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/event-pub-sub/CHANGELOG.md) |
-| [@slickgrid-universal/composite-editor-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/composite-editor-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/composite-editor-component.svg)](https://www.npmjs.com/package/@slickgrid-universal/composite-editor-component) | Composite Editor Modal Component | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/composite-editor-component/CHANGELOG.md) |
-| [@slickgrid-universal/custom-footer-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/custom-footer-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/custom-footer-component.svg)](https://www.npmjs.com/package/@slickgrid-universal/custom-footer-component) | Custom Footer Component for the grid | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/custom-footer-component/CHANGELOG.md) |
-| [@slickgrid-universal/custom-tooltip-plugin](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/custom-tooltip-plugin) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/custom-tooltip-plugin.svg)](https://www.npmjs.com/package/@slickgrid-universal/custom-tooltip-plugin) | Custom Tooltip (plugin) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/custom-tooltip-plugin/CHANGELOG.md) |
-| [@slickgrid-universal/empty-warning-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/empty-warning-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/empty-warning-component.svg)](https://www.npmjs.com/package/@slickgrid-universal/empty-warning-component) | simple Empty Data Warning Component | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/empty-warning-component/CHANGELOG.md) |
-| [@slickgrid-universal/pagination-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/pagination-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/pagination-component.svg)](https://www.npmjs.com/package/@slickgrid-universal/pagination-component) | simple Pagination Component | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/pagination-component/CHANGELOG.md) |
-| [@slickgrid-universal/excel-export](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/excel-export) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/excel-export.svg)](https://www.npmjs.com/package/@slickgrid-universal/excel-export) | Export to Excel Service (`xls`/`xlsx`) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/excel-export/CHANGELOG.md) |
-| [@slickgrid-universal/text-export](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/text-export) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/text-export.svg)](https://www.npmjs.com/package/@slickgrid-universal/text-export) | Export to Text File Service (`csv`/`txt`) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/text-export/CHANGELOG.md) |
-| [@slickgrid-universal/graphql](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/graphql) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/graphql.svg)](https://www.npmjs.com/package/@slickgrid-universal/graphql) | GraphQL Query Service (Filter/Sort/Paging) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/graphql/CHANGELOG.md) |
-| [@slickgrid-universal/odata](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/odata) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/odata.svg)](https://www.npmjs.com/package/@slickgrid-universal/odata) | OData Query Service (Filter/Sort/Paging) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/odata/CHANGELOG.md) |
-| [@slickgrid-universal/row-detail-view-plugin](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/row-detail-view-plugin) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/row-detail-view-plugin.svg)](https://www.npmjs.com/package/@slickgrid-universal/row-detail-view-plugin) | Row Detail View (plugin) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/row-detail-view-plugin/CHANGELOG.md) |
-| [@slickgrid-universal/rxjs-observable](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/rxjs-observable) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/rxjs-observable.svg)](https://www.npmjs.com/package/@slickgrid-universal/rxjs-observable) | RxJS Observable Service Wrapper | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/rxjs-observable/CHANGELOG.md) |
-| [@slickgrid-universal/utils](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/utils) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/utils.svg)](https://www.npmjs.com/package/@slickgrid-universal/utils) | Common JS Utils | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/utils/CHANGELOG.md)
-| [@slickgrid-universal/vanilla-bundle](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/vanilla-bundle) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/vanilla-bundle.svg)](https://www.npmjs.com/package/@slickgrid-universal/vanilla-bundle) | Vanilla TypeScript/ES6 implementation | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/vanilla-bundle/CHANGELOG.md)
-| [@slickgrid-universal/vanilla-force-bundle](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/vanilla-force-bundle) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/vanilla-force-bundle.svg)](https://www.npmjs.com/package/@slickgrid-universal/vanilla-force-bundle) | Vanilla TypeScript/ES6 for Salesforce implementation | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/vanilla-force-bundle/CHANGELOG.md)
+| [@slickgrid-universal/common](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/common) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/common.svg)](https://www.npmjs.com/package/@slickgrid-universal/common) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/common?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/common) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/CHANGELOG.md) |
+| [@slickgrid-universal/binding](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/binding) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/binding.svg)](https://www.npmjs.com/package/@slickgrid-universal/binding) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/binding?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/binding) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/binding/CHANGELOG.md) |
+| [@slickgrid-universal/event-pub-sub](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/event-pub-sub) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/event-pub-sub.svg)](https://www.npmjs.com/package/@slickgrid-universal/event-pub-sub) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/event-pub-sub?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/event-pub-sub) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/event-pub-sub/CHANGELOG.md) |
+| [@slickgrid-universal/composite-editor-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/composite-editor-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/composite-editor-component.svg)](https://www.npmjs.com/package/@slickgrid-universal/composite-editor-component) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/composite-editor-component?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/composite-editor-component) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/composite-editor-component/CHANGELOG.md) |
+| [@slickgrid-universal/custom-footer-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/custom-footer-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/custom-footer-component.svg)](https://www.npmjs.com/package/@slickgrid-universal/custom-footer-component) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/custom-footer-component?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/custom-footer-component) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/custom-footer-component/CHANGELOG.md) |
+| [@slickgrid-universal/custom-tooltip-plugin](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/custom-tooltip-plugin) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/custom-tooltip-plugin.svg)](https://www.npmjs.com/package/@slickgrid-universal/custom-tooltip-plugin) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/custom-tooltip-plugin?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/custom-tooltip-plugin) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/custom-tooltip-plugin/CHANGELOG.md) |
+| [@slickgrid-universal/empty-warning-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/empty-warning-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/empty-warning-component.svg)](https://www.npmjs.com/package/@slickgrid-universal/empty-warning-component) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/empty-warning-component?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/empty-warning-component) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/empty-warning-component/CHANGELOG.md) |
+| [@slickgrid-universal/pagination-component](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/pagination-component) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/pagination-component.svg)](https://www.npmjs.com/package/@slickgrid-universal/pagination-component) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/pagination-component?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/pagination-component) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/pagination-component/CHANGELOG.md) |
+| [@slickgrid-universal/excel-export](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/excel-export) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/excel-export.svg)](https://www.npmjs.com/package/@slickgrid-universal/excel-export) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/excel-export?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/excel-export) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/excel-export/CHANGELOG.md) |
+| [@slickgrid-universal/text-export](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/text-export) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/text-export.svg)](https://www.npmjs.com/package/@slickgrid-universal/text-export) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/text-export?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/text-export) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/text-export/CHANGELOG.md) |
+| [@slickgrid-universal/graphql](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/graphql) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/graphql.svg)](https://www.npmjs.com/package/@slickgrid-universal/graphql) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/graphql?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/graphql) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/graphql/CHANGELOG.md) |
+| [@slickgrid-universal/odata](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/odata) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/odata.svg)](https://www.npmjs.com/package/@slickgrid-universal/odata) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/odata?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/odata) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/odata/CHANGELOG.md) |
+| [@slickgrid-universal/row-detail-view-plugin](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/row-detail-view-plugin) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/row-detail-view-plugin.svg)](https://www.npmjs.com/package/@slickgrid-universal/row-detail-view-plugin) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/row-detail-view-plugin?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/row-detail-view-plugin) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/row-detail-view-plugin/CHANGELOG.md) |
+| [@slickgrid-universal/rxjs-observable](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/rxjs-observable) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/rxjs-observable.svg)](https://www.npmjs.com/package/@slickgrid-universal/rxjs-observable) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/rxjs-observable?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/rxjs-observable) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/rxjs-observable/CHANGELOG.md) |
+| [@slickgrid-universal/utils](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/utils) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/utils.svg)](https://www.npmjs.com/package/@slickgrid-universal/utils) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/utils?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/utils) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/utils/CHANGELOG.md)
+| [@slickgrid-universal/vanilla-bundle](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/vanilla-bundle) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/vanilla-bundle.svg)](https://www.npmjs.com/package/@slickgrid-universal/vanilla-bundle) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/vanilla-bundle?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/vanilla-bundle) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/vanilla-bundle/CHANGELOG.md)
+| [@slickgrid-universal/vanilla-force-bundle](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/vanilla-force-bundle) | [![npm](https://img.shields.io/npm/v/@slickgrid-universal/vanilla-force-bundle.svg)](https://www.npmjs.com/package/@slickgrid-universal/vanilla-force-bundle) | [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/vanilla-force-bundle?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/vanilla-force-bundle) | [changelog](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/vanilla-force-bundle/CHANGELOG.md)
## Installation
**NOTE:** the installation instructions below are **only** required if you want to contribute to this project, however if you just want to download a quick Slickgrid-Universal demo, then I would suggest to take a look at either [Slickgrid-Universal Vite Demo](https://github.com/ghiscoding/slickgrid-universal-vite-demo) or [Slickgrid-Universal WebPack Demo](https://github.com/ghiscoding/slickgrid-universal-webpack-demo).
diff --git a/docs/TOC.md b/docs/TOC.md
index ffbb77874..f1f8d055d 100644
--- a/docs/TOC.md
+++ b/docs/TOC.md
@@ -6,6 +6,7 @@
* [Quick start](getting-started/quick-start.md)
* [Salesforce (LWC)](getting-started/installation-salesforce.md)
+* [Vanilla Installation](getting-started/installation-vanilla.md)
## Styling
@@ -18,6 +19,7 @@
* [Editors](column-functionalities/Editors.md)
* [new Autocomplete (Kraaden-lib)](column-functionalities/editors/Autocomplete-Editor-(Kraaden-lib).md)
* [Date Picker (flatpickr)](column-functionalities/editors/Date-Editor-(flatpickr).md)
+ * [Date Picker (vanilla-calendar)](column-functionalities/editors/date-editor-(vanilla-calendar).md)
* [LongText (textarea)](column-functionalities/editors/LongText-Editor-(textarea).md)
* [Select Dropdown Editor (single/multiple)](column-functionalities/editors/Select-Dropdown-Editor-(single,multiple).md)
* [Filters](column-functionalities/filters/README.md)
@@ -76,3 +78,4 @@
* [Migration Guide to 2.x](migrations/migration-to-2.x.md)
* [Migration Guide to 3.x](migrations/migration-to-3.x.md)
* [Migration Guide to 4.x](migrations/migration-to-4.x.md)
+* [Migration Guide to 5.x](migrations/migration-to-5.x.md)
diff --git a/docs/column-functionalities/Cell-Menu.md b/docs/column-functionalities/Cell-Menu.md
index 48983d58f..4afffbfd1 100644
--- a/docs/column-functionalities/Cell-Menu.md
+++ b/docs/column-functionalities/Cell-Menu.md
@@ -38,7 +38,7 @@ this.columnDefinitions = [
console.log(args.dataContext, args.column); // action callback.. do something
}
},
- { command: 'help', title: 'HELP', iconCssClass: 'fa fa-question-circle', positionOrder: 62 },
+ { command: 'help', title: 'HELP', iconCssClass: 'mdi mdi-help-circle', positionOrder: 62 },
// you can add sub-menus by adding nested `commandItems`
{
// we can also have multiple nested sub-menus
@@ -74,8 +74,8 @@ this.columnDefinitions = [
cellMenu: {
optionTitle: 'Change Effort Driven Flag', // optional, add title
optionItems: [
- { option: true, title: 'True', iconCssClass: 'fa fa-check-square-o' },
- { option: false, title: 'False', iconCssClass: 'fa fa-square-o' },
+ { option: true, title: 'True', iconCssClass: 'mdi mdi-check-box-outline' },
+ { option: false, title: 'False', iconCssClass: 'mdi mdi-checkbox-blank-outline' },
{ divider: true, command: '', positionOrder: 60 },
],
// subscribe to Context Menu onOptionSelected event (or use the "action" callback on each option)
@@ -153,7 +153,7 @@ this.columnDefinitions = [
{ id: 'action', field: 'action', name: 'Action',
cellMenu: {
menuUsabilityOverride: (args) => {
- const dataContext = args && args.dataContext;
+ const dataContext = args?.dataContext;
return (dataContext.id < 21); // say we want to display the menu only from Task 0 to 20
},
}
@@ -163,24 +163,22 @@ this.columnDefinitions = [
To give another example, with Options this time, we could say that we enable the `n/a` option only when the row is Completed. So we could do it this way
```ts
-this.columnDefinitions = [
- { id: 'action', field: 'action', name: 'Action',
- cellMenu: {
- optionItems: [
- {
- option: 0, title: 'n/a', textCssClass: 'italic',
- // only enable this option when the task is Not Completed
- itemUsabilityOverride: (args) => {
- const dataContext = args && args.dataContext;
- return !dataContext.completed;
- },
- { option: 1, iconCssClass: 'fa fa-star-o yellow', title: 'Low' },
- { option: 2, iconCssClass: 'fa fa-star-half-o orange', title: 'Medium' },
- { option: 3, iconCssClass: 'fa fa-star red', title: 'High' },
- ]
- }
+this.columnDefinitions = [{
+ id: 'action', field: 'action', name: 'Action',
+ cellMenu: {
+ optionItems: [{
+ option: 0, title: 'n/a', textCssClass: 'italic',
+ // only enable this option when the task is Not Completed
+ itemUsabilityOverride: (args) => {
+ const dataContext = args?.dataContext;
+ return !dataContext.completed;
+ },
+ { option: 1, iconCssClass: 'mdi mdi-star-outline yellow', title: 'Low' },
+ { option: 2, iconCssClass: 'mdi mdi-star orange', title: 'Medium' },
+ { option: 3, iconCssClass: 'mdi mdi-star red', title: 'High' },
+ }]
}
-];
+}];
```
### How to add Translations?
@@ -191,9 +189,9 @@ this.columnDefinitions = [
cellMenu: {
optionTitleKey: 'COMMANDS', // optionally pass a title to show over the Options
optionItems: [
- { option: 1, titleKey: 'LOW', iconCssClass: 'fa fa-star-o yellow' },
- { option: 2, titleKey: 'MEDIUM', iconCssClass: 'fa fa-star-half-o orange' },
- { option: 3, titleKey: 'HIGH', iconCssClass: 'fa fa-star red' },
+ { option: 1, titleKey: 'LOW', iconCssClass: 'mdi mdi-star-outline yellow' },
+ { option: 2, titleKey: 'MEDIUM', iconCssClass: 'mdi mdi-star orange' },
+ { option: 3, titleKey: 'HIGH', iconCssClass: 'mdi mdi-star red' },
]
}
}
diff --git a/docs/column-functionalities/Editors.md b/docs/column-functionalities/Editors.md
index 935b4cf96..eec15e57f 100644
--- a/docs/column-functionalities/Editors.md
+++ b/docs/column-functionalities/Editors.md
@@ -108,7 +108,7 @@ this.columnDefinitions = [
];
```
-So to make it more clear, the `saveOutputType` is the format that will be sent to the `onCellChange` event, then the `outputType` is how the date will show up in the date picker (Flatpickr) and finally the `type` is basically the input format (coming from your dataset). Note however that each property are cascading, if 1 property is missing it will go to the next one until 1 is found... for example, on the `onCellChange` if you aren't defining `saveOutputType`, it will try to use `outputType`, if again none is provided it will try to use `type` and finally if none is provided it will use `FieldType.dateIso` as the default.
+So to make it more clear, the `saveOutputType` is the format that will be sent to the `onCellChange` event, then the `outputType` is how the date will show up in the date picker (Vanilla-Calendar) and finally the `type` is basically the input format (coming from your dataset). Note however that each property are cascading, if 1 property is missing it will go to the next one until 1 is found... for example, on the `onCellChange` if you aren't defining `saveOutputType`, it will try to use `outputType`, if again none is provided it will try to use `type` and finally if none is provided it will use `FieldType.dateIso` as the default.
## Perform an action After Inline Edit
#### Recommended way
@@ -201,9 +201,9 @@ Some of the Editors could receive extra options, which is mostly the case for Ed
```ts
this.columnDefinitions = [{
id: 'start', name: 'Start Date', field: 'start',
- editor: {
+ editor: {
model: Editors.date,
- editorOptions: { minDate: 'today' }
+ editorOptions: { range: { min: 'today' } } as VanillaCalendarOption
}
}];
```
@@ -213,10 +213,10 @@ You could also define certain options as a global level (for the entire grid or
```ts
this.gridOptions = {
- defaultEditorOptions: {
+ defaultEditorOptions: {
autocompleter: { debounceWaitMs: 150 }, // typed as AutocompleterOption
- date: { minDate: 'today' },
- longText: { cols: 50, rows: 5 }
+ date: { range: { min: 'today' } },
+ longText: { cols: 50, rows: 5 }
}
}
```
diff --git a/docs/column-functionalities/Formatters.md b/docs/column-functionalities/Formatters.md
index 752267fb3..d6e0ea991 100644
--- a/docs/column-functionalities/Formatters.md
+++ b/docs/column-functionalities/Formatters.md
@@ -13,19 +13,18 @@
### Definition
`Formatters` are functions that can be used to change and format certain column(s) in the grid. Please note that it does not alter the input data, it simply changes the styling by formatting the data differently to the screen (what the user visually see).
-A good example of a `Formatter` could be a column name `isActive` which is a `boolean` field with input data as `True` or `False`. User would prefer to simply see a checkbox as a visual indication representing the `True` flag, for this behavior you can use `Formatters.checkmark` which will use [Font-Awesome](http://fontawesome.io/icons/) icon of `fa-check` when `True` or an empty string when `False`.
+A good example of a `Formatter` could be a column name `isActive` which is a `boolean` field with input data as `True` or `False`. User would prefer to simply see a checkbox as a visual indication representing the `True` flag, for this behavior you can use `Formatters.checkmarkMaterial` which will use optional SVG icons of `mdi-check` when `True` or an empty string when `False`.
For a [UI sample](#ui-sample), scroll down below.
### Provided Formatters
`Slickgrid-Universal` ships with a few `Formatters` by default which helps with common fields, you can see the [entire list here](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/formatters/index.ts#L37).
-> **Note** you might not need a Formatter when a simple CSS style is needed, think about using `cssClass` column property instead.
+> **Note** you might not need a Formatter when a simple CSS style and class might be enough, think about using `cssClass` column property as much as possible since it has much better perf.
#### List of provided `Formatters`
- `arrayObjectToCsv`: Takes an array of complex objects converts it to a comma delimited string.
- `arrayToCsv` : takes an array of text and returns it as CSV string
-- `checkmark` : uses Font-Awesome [(fa-check)](http://fontawesome.io/icon/check/)
- `checkmarkMaterial` use Material Design to display a checkmark icon
- `collection`: Looks up values from the columnDefinition.params.collection property and displays the label in CSV or string format
- `complexObject`: takes a complex object (with a `field` that has a `.` notation) and pull correct value, there are multiple ways to use it
@@ -47,6 +46,7 @@ For a [UI sample](#ui-sample), scroll down below.
- `dateTimeUs` : Takes a Date object and displays it as an US Date+Time format (MM/DD/YYYY HH:mm:ss)
- `dateTimeShortUs`: Takes a Date object and displays it as an US Date+Time (without seconds) format (MM/DD/YYYY HH:mm:ss)
- `dateTimeUsAmPm` : Takes a Date object and displays it as an US Date+Time+(am/pm) format (MM/DD/YYYY hh:mm:ss a)
+- `dateUtc` : Takes a Date object and displays it as a TZ format (YYYY-MM-DDThh:mm:ssZ)
- `decimal`: Display the value as x decimals formatted, defaults to 2 decimals. You can pass "minDecimal" and/or "maxDecimal" to the "params" property.
- `dollar`: Display the value as 2 decimals formatted with dollar sign '$' at the end of of the value.
- `dollarColored`: Display the value as 2 decimals formatted with dollar sign '$' at the end of of the value, change color of text to red/green on negative/positive value
@@ -71,10 +71,12 @@ For a [UI sample](#ui-sample), scroll down below.
- `translateBoolean`: Takes a boolean value, cast it to upperCase string and finally translates it (i18n).
- `tree`: Formatter that must be used when the column is a Tree Data column
-**Note:** The list might not always be up to date, you can refer to the [Formatters export](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/formatters/index.ts#L37) to know exactly which ones are available.
+> **Note:** The list is certainly not up to date (especially for Dates), please refer to the [Formatters export](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/formatters/index.ts#L37) to know exactly which formatters are available.
+
+> **Note** all Date formatters are formatted using [Tempo](https://tempo.formkit.com/#format-tokens). There are also many more Date formats not shown above, simply visit the [formatters.index](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/formatters/formatters.index.ts#L101) to see all available Date/Time formats.
### Usage
-To use any of them, you need to import `Formatters` from `Slickgrid-Universal` and add a `formatter: ...` in your column definitions as shown below:
+To use any of them, you simply need to import `Formatters` from `Slickgrid-Universal` and add a `formatter: Formatters.xyz` (where `xyx` is the name of the built-in formatter) in your column definitions as shown below:
#### TypeSript
```ts
@@ -97,39 +99,7 @@ export class Example {
{ id: '%', name: '% Complete', field: 'percentComplete', formatter: Formatters.percentComplete },
{ id: 'start', name: 'Start', field: 'start', formatter: Formatters.dateIso },
{ id: 'finish', name: 'Finish', field: 'finish', formatter: Formatters.dateIso },
- { id: 'effort-driven', name: 'Effort Driven', field: 'effortDriven', formatter: Formatters.checkmark }
- ];
- }
-}
-```
-
-#### SalesForce (ES6)
-For SalesForce the code is nearly the same, the only difference is to add the `Slicker` prefix, so instead of `Formatters.abc` we need to use `Slicker.Formatters.abc`
-
-```ts
-// ... SF_Slickgrid import
-
-
-export class Example {
- const Slicker = window.Slicker;
-
- columnDefinitions: Column[];
- gridOptions: GridOption;
- dataset: any[];
-
- constructor() {
- // define the grid options & columns and then create the grid itself
- this.defineGrid();
- }
-
- defineGrid() {
- this.columnDefinitions = [
- { id: 'title', name: 'Title', field: 'title' },
- { id: 'duration', name: 'Duration (days)', field: 'duration' },
- { id: '%', name: '% Complete', field: 'percentComplete', formatter: Slicker.Formatters.percentComplete },
- { id: 'start', name: 'Start', field: 'start', formatter: Slicker.Formatters.dateIso },
- { id: 'finish', name: 'Finish', field: 'finish', formatter: Slicker.Formatters.dateIso },
- { id: 'effort-driven', name: 'Effort Driven', field: 'effortDriven', formatter: Slicker.Formatters.checkmark }
+ { id: 'effort-driven', name: 'Effort Driven', field: 'effortDriven', formatter: Formatters.checkmarkMaterial }
];
}
}
@@ -191,11 +161,13 @@ export interface FormatterResultObject {
```
### Example of a Custom Formatter with HTML string
-For example, we will use `Font-Awesome` with a `boolean` as input data, and display a (fire) icon when `True` or a (snowflake) when `False`. This custom formatter is actually display in the [UI sample](#ui-sample) shown below.
+
+For example, we will use our optional SVG icons `.mdi` with a `boolean` as input data, and display a (fire) icon when `True` or a (snowflake) when `False`. This custom formatter is actually display in the [UI sample](#ui-sample) shown below.
+
```ts
// create a custom Formatter with the Formatter type
const myCustomCheckboxFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) =>
- value ? `` : '';
+ value ? `` : '';
```
#### Example with `FormatterResultObject` instead of a string
@@ -203,7 +175,7 @@ Using this object return type will provide the user the same look and feel, it w
```ts
// create a custom Formatter and returning a string and/or an object of type FormatterResultObject
const myCustomCheckboxFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid?: any) =>
- value ? { addClasses: 'fa fa-fire', text: '', tooltip: 'burning fire' } : '';
+ value ? { addClasses: 'mdi mdi-fire', text: '', tooltip: 'burning fire' } : '';
```
### Example of Custom Formatter with Native DOM Element
@@ -212,7 +184,7 @@ Since version 4.x, you can now also return native DOM element instead of an HTML
2. Performance (the reasons are similar to point 1.)
- since it's native it can be appended directly to the grid cell
- when it's an HTML string, it has to do 2 extra steps (which is an overhead process)
- i. sanitize the string (we use [DOMPurify](https://github.com/cure53/DOMPurify) by default)
+ i. sanitize the string (when a sanitizer, for example [DOMPurify](https://github.com/cure53/DOMPurify))
ii. SlickGrid then has to convert it to native element by using `innerHTML` on the grid cell
Demo
diff --git a/docs/column-functionalities/editors/Autocomplete-Editor-(Kraaden-lib).md b/docs/column-functionalities/editors/Autocomplete-Editor-(Kraaden-lib).md
index f669b165a..7af780e4a 100644
--- a/docs/column-functionalities/editors/Autocomplete-Editor-(Kraaden-lib).md
+++ b/docs/column-functionalities/editors/Autocomplete-Editor-(Kraaden-lib).md
@@ -276,11 +276,6 @@ export class GridBasicComponent {
editorOptions: {
showOnFocus: true,
minLength: 1,
- classes: {
- // choose a custom style layout
- // 'ui-autocomplete': 'autocomplete-custom-two-rows',
- 'ui-autocomplete': 'autocomplete-custom-four-corners',
- },
fetch: (searchText, updateCallback) => {
yourAsyncApiCall(searchText) // typically you'll want to return no more than 10 results
.then(result => updateCallback((results.length > 0) ? results : [{ label: 'No match found.', value: '' }]); })
diff --git a/docs/column-functionalities/editors/Date-Editor-(flatpickr).md b/docs/column-functionalities/editors/Date-Editor-(flatpickr).md
index e3b430a1a..743c6e35d 100644
--- a/docs/column-functionalities/editors/Date-Editor-(flatpickr).md
+++ b/docs/column-functionalities/editors/Date-Editor-(flatpickr).md
@@ -41,8 +41,8 @@ You could also define certain options as a global level (for the entire grid or
```ts
this.gridOptions = {
- defaultEditorOptions: {
- date: { minDate: 'today' }, // typed as FlatpickrOption
+ defaultEditorOptions: {
+ date: { range: { min: 'today' } }, // typed as FlatpickrOption
}
}
```
diff --git a/docs/column-functionalities/editors/Select-Dropdown-Editor-(single,multiple).md b/docs/column-functionalities/editors/Select-Dropdown-Editor-(single,multiple).md
index bd7fdd9a0..7e1026e56 100644
--- a/docs/column-functionalities/editors/Select-Dropdown-Editor-(single,multiple).md
+++ b/docs/column-functionalities/editors/Select-Dropdown-Editor-(single,multiple).md
@@ -36,14 +36,21 @@ this.columnDefinitions = [
```
### Editor Options (`MultipleSelectOption` interface)
-All the available options that can be provided as `editorOptions` to your column definitions can be found under this [multipleSelectOption interface](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/multipleSelectOption.interface.ts) and you should cast your `editorOptions` to that interface to make sure that you use only valid options of the `multiple-select.js` library.
+All the available options that can be provided as `editorOptions` to your column definitions via the `MultipleSelectOption` interface of the external library and so you should cast your `editorOptions` to that interface to make sure that you use only valid options of the `Multiple-Select-Vanilla` library.
```ts
-editor: {
- model: Editors.SingleSelect,
- editorOptions: {
- maxHeight: 400
- } as MultipleSelectOption
+import { MultipleSelectOption } from 'multiple-select-vanilla';
+
+prepareGrid() {
+ this.columnDefinitions = [{
+ id: 'isActive', name: 'Active', field: 'isActive',
+ editor: {
+ model: Editors.singleSelect,
+ editorOptions: {
+ maxHeight: 400
+ } as MultipleSelectOption
+ }
+ }];
}
```
@@ -52,7 +59,7 @@ You could also define certain options as a global level (for the entire grid or
```ts
this.gridOptions = {
- defaultEditorOptions: {
+ defaultEditorOptions: {
// Note: that `select` combines both multipleSelect & singleSelect
select: { minHeight: 350 }, // typed as MultipleSelectOption
}
@@ -163,7 +170,7 @@ this.columnDefinitions = [
editor: {
// display checkmark icon when True
enableRenderHtml: true,
- collection: [{ value: '', label: '' }, { value: true, label: 'True', labelPrefix: ` ` }, { value: false, label: 'False' }],
+ collection: [{ value: '', label: '' }, { value: true, label: 'True', labelPrefix: ` ` }, { value: false, label: 'False' }],
model: Editors.singleSelect
}
}
@@ -224,6 +231,3 @@ this.columnDefinitions = [
}
];
```
-
-### Change Default DOMPurify Options (sanitize html)
-If you find that the HTML that you passed is being sanitized and you wish to change it, then you can change the default `sanitizeHtmlOptions` property defined in the Global Grid Options, for more info on how to change these global options, see the `Global Grid Options` and also take a look at the [GitHub - DOMPurify](https://github.com/cure53/DOMPurify#can-i-configure-it) configurations.
diff --git a/docs/column-functionalities/editors/date-editor-(vanilla-calendar).md b/docs/column-functionalities/editors/date-editor-(vanilla-calendar).md
new file mode 100644
index 000000000..9b0e29d1d
--- /dev/null
+++ b/docs/column-functionalities/editors/date-editor-(vanilla-calendar).md
@@ -0,0 +1,72 @@
+##### index
+- [Editor Options](#editor-options)
+- [Custom Validator](#custom-validator)
+- See the [Editors - Wiki](../Editors.md) for more general info about Editors (validators, event handlers, ...)
+
+### Information
+The Date Editor is provided through an external library named [Vanilla-Calendar-Picker](https://github.com/ghiscoding/vanilla-calendar-picker) (a fork of [Vanilla-Calendar-Pro](https://vanilla-calendar.pro)) and all options from that library can be added to your `editorOptions` (see below), so in order to add things like minimum date, disabling dates, ... just review all the [Vanilla-Calendar-Pro](https://vanilla-calendar.pro/docs/reference/additionally/settings) and then add them into `editorOptions`. We use [Tempo](https://tempo.formkit.com/) to parse and format Dates to the chosen format (when `type`, `outputType` and/or `saveType` are provided in your column definition)
+
+> **Note** Also just so you know, `editorOptions` is used by all other editors as well to expose external library like Autocompleter, Multiple-Select, etc...
+
+### Demo
+[Demo Page](https://ghiscoding.github.io/slickgrid-universal/#/example12) | [Demo Component](https://github.com/ghiscoding/slickgrid-universal/blob/master/examples/webpack-demo-vanilla-bundle/src/examples/example12.ts)
+
+### Editor Options
+You can use any of the Vanilla-Calendar [settings](https://vanilla-calendar.pro/docs/reference/additionally/settings) by adding them to `editorOptions` as shown below.
+
+> **Note** for easier implementation, you should import `VanillaCalendarOption` from Slickgrid-Universal common package.
+
+```ts
+import { type VanillaCalendarOption } from '@slickgrid-universal/common';
+
+prepareGrid() {
+ this.columnDefinitions = [
+ {
+ id: 'title', name: 'Title', field: 'title',
+ editor: {
+ model: Editors.date,
+ editorOptions: {
+ range: {
+ max: 'today',
+ disabled: ['2022-08-15', '2022-08-20'],
+ }
+ } as VanillaCalendarOption,
+ },
+ },
+ ];
+}
+```
+
+#### Grid Option `defaultEditorOptions
+You could also define certain options as a global level (for the entire grid or even all grids) by taking advantage of the `defaultEditorOptions` Grid Option. Note that they are set via the editor type as a key name (`autocompleter`, `date`, ...) and then the content is the same as `editorOptions` (also note that each key is already typed with the correct editor option interface), for example
+
+```ts
+this.gridOptions = {
+ defaultEditorOptions: {
+ date: { range: { min: 'today' } }, // typed as VanillaCalendarOption
+ }
+}
+```
+
+### Custom Validator
+You can add a Custom Validator from an external function or inline (inline is shown below and comes from [Example 12](https://ghiscoding.github.io/slickgrid-universal/#/example12))
+```ts
+initializeGrid() {
+ this.columnDefinitions = [
+ {
+ id: 'title', name: 'Title', field: 'title',
+ editor: {
+ model: Editors.date,
+ required: true,
+ validator: (value, args) => {
+ const dataContext = args && args.item;
+ if (dataContext && (dataContext.completed && !value)) {
+ return { valid: false, msg: 'You must provide a "Finish" date when "Completed" is checked.' };
+ }
+ return { valid: true, msg: '' };
+ }
+ },
+ },
+ ];
+}
+```
\ No newline at end of file
diff --git a/docs/column-functionalities/filters/Compound-Filters.md b/docs/column-functionalities/filters/Compound-Filters.md
index 8c5caebd8..bd268a26c 100644
--- a/docs/column-functionalities/filters/Compound-Filters.md
+++ b/docs/column-functionalities/filters/Compound-Filters.md
@@ -3,7 +3,6 @@
- [SASS Styling](#sass-styling)
- [Compound Input Filter](#how-to-use-compoundinput-filter)
- [Compound Date Filter](#how-to-use-compounddate-filter)
- - [Filter Options (`FlatpickrOption` interface)](#filter-options-flatpickroption-interface)
- [Compound Operator List (custom list)](#compound-operator-list-custom-list)
- [Compound Operator Alternate Texts](#compound-operator-alternate-texts)
- [Filter Complex Object](../Input-Filter.md#how-to-filter-complex-objects)
@@ -11,7 +10,7 @@
- [How to avoid filtering when only Operator dropdown is changed?](#how-to-avoid-filtering-when-only-operator-dropdown-is-changed)
### Description
-Compound filters are a combination of 2 elements (Operator Select + Input Filter) used as a filter on a column. This is very useful to make it obvious to the user that there are Operator available and even more useful with a date picker (`Flatpickr`).
+Compound filters are a combination of 2 elements (Operator Select + Input Filter) used as a filter on a column. This is very useful to make it obvious to the user that there are Operator available and even more useful with a date picker (`Vanilla-Calendar`).
### Demo
[Demo Page](https://ghiscoding.github.io/slickgrid-universal/#/example02) / [Demo Component](https://github.com/ghiscoding/slickgrid-universal/blob/master/examples/webpack-demo-vanilla-bundle/src/examples/example02.ts)
@@ -21,11 +20,11 @@ There are multiple types of compound filters available
1. `Filters.compoundInputText` adds an Operator combine to an Input of type `text` (alias to `Filters.compoundInput`).
2. `Filters.compoundInputNumber` adds an Operator combine to an Input of type `number`.
3. `Filters.compoundInputPassword` adds an Operator combine to an Input of type `password.
-4. `Filters.compoundDate` adds an Operator combine to a Date Picker (flatpickr).
+4. `Filters.compoundDate` adds an Operator combine to a Date Picker (Vanilla-Calendar).
5. `Filters.compoundSlider` adds an Operator combine to a Slider Filter.
### SASS Styling
-You can change the `$flatpickr-bgcolor` and any of the `$compound-filter-X` SASS [variables](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/styles/_variables.scss#L660) for styling. For more info on how to use SASS in your project, read the [Wiki - Styling](../../styling/styling.md)
+You can change some of the SASS [variables](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/styles/_variables.scss#L648) for styling. For more info on how to use SASS in your project, read the [Wiki - Styling](../../styling/styling.md)
### How to use CompoundInput Filter
Simply set the flag `filterable` to True and use the filter type `Filters.compoundInput`. Here is an example with a full column definition:
@@ -52,7 +51,7 @@ The column definition `type` will affect the list of Operators shown, for exampl
### How to use CompoundDate Filter
-Again set the column definition flag `filterable: true` and use the filter type `Filters.compoundDate`. Here is an example with a full column definition:
+As any other columns, set the column definition flag `filterable: true` and use the filter type `Filters.compoundDate`. Here is an example with a full column definition:
```ts
// define you columns, in this demo Effort Driven will use a Select Filter
this.columnDefinitions = [
@@ -76,6 +75,8 @@ this.gridOptions = {
};
```
+> **Note** we use [Tempo](https://tempo.formkit.com/) to parse and format Dates to the chosen format via the `type` option when provided in your column definition.
+
#### Dealing with different input/ouput dates (example: UTC)
What if your date input (from your dataset) has a different output on the screen (UI)?
In that case, you will most probably have a Formatter and type representing the input type, we also provided an `outputType` that can be used to deal with that case.
@@ -125,15 +126,15 @@ this.gridOptions = {
};
```
-#### Filter Options (`FlatpickrOption` interface)
-All the available options that can be provided as `filterOptions` to your column definitions can be found under this [FlatpickrOption interface](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/flatpickrOption.interface.ts) and you should cast your `filterOptions` to that interface to make sure that you use only valid options of the [Flatpickr](https://flatpickr.js.org/) library.
+#### Filter Options (`VanillaCalendarOption` interface)
+All the available options that can be provided as `filterOptions` to your column definitions can be found under this [VanillaCalendarOption interface](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/vanillaCalendarOption.interface.ts) and you should cast your `filterOptions` with the expected interface to make sure that you use only valid settings of the [Vanilla-Calendar](https://vanilla-calendar.pro/docs/reference/additionally/settings) library.
```ts
filter: {
model: Filters.compoundDate,
filterOptions: {
- minDate: 'today'
- } as FlatpickrOption
+ range: { min: 'today' }
+ } as VanillaCalendarOption
}
```
@@ -142,10 +143,10 @@ You could also define certain options as a global level (for the entire grid or
```ts
this.gridOptions = {
- defaultFilterOptions: {
+ defaultFilterOptions: {
// Note: that `date`, `select` and `slider` are combining both compound & range filters together
- date: { minDate: 'today' },
- select: { minHeight: 350 }, // typed as MultipleSelectOption
+ date: { range: { min: 'today' } }, // typed as VanillaCalendarOption
+ select: { minHeight: 350 }, // typed as MultipleSelectOption
slider: { sliderStartValue: 10 }
}
}
diff --git a/docs/column-functionalities/filters/Range-Filters.md b/docs/column-functionalities/filters/Range-Filters.md
index 0c1a26d19..0a204da01 100644
--- a/docs/column-functionalities/filters/Range-Filters.md
+++ b/docs/column-functionalities/filters/Range-Filters.md
@@ -4,11 +4,10 @@
- [Using a Slider Range](#using-a-slider-range-filter)
- [Filter Options](#filter-options)
- [Using a Date Range](#using-a-date-range-filter)
- - [Filter Options (`FlatpickrOption` interface)](#filter-options-flatpickroption-interface)
- [Update Filters Dynamically](Input-Filter.md#update-filters-dynamically)
### Introduction
-Range filters allows you to search for a value between 2 min/max values, the 2 most common use case would be to filter between 2 numbers or dates, you can do that with the new Slider & Date Range Filters. The range can also be defined as inclusive (`>= 0 and <= 10`) or exclusive (`> 0 and < 10`), the default is exclusive but you can change that, see below for more info.
+Range filters allows you to search for a value between 2 min/max values, the 2 most common use case would be to filter between 2 numbers or dates, you can do that with the Slider & Date Range Filters. The range can also be defined as inclusive (`>= 0 and <= 10`) or exclusive (`> 0 and < 10`), the default is exclusive but you can change that, see below for more info.
### Using an Inclusive Range (default is Exclusive)
By default all the range filters are with exclusive range, which mean between value `x` and `y` but without including them. If you wish to include the `x` and `y` values, you can change that through the `operator` property.
@@ -123,9 +122,9 @@ You could also define certain options as a global level (for the entire grid or
```ts
this.gridOptions = {
- defaultFilterOptions: {
+ defaultFilterOptions: {
// Note: that `date`, `select` and `slider` are combining both compound & range filters together
- date: { minDate: 'today' },
+ date: { range: { min: 'today' } },
select: { minHeight: 350 }, // typed as MultipleSelectOption
slider: { sliderStartValue: 10 }
}
@@ -133,10 +132,12 @@ this.gridOptions = {
```
### Using a Date Range Filter
-The date range filter allows you to search data between 2 dates (it uses [Flatpickr Range](https://flatpickr.js.org/examples/#range-calendar) feature).
+The date range filter allows you to search data between 2 dates (it uses [Vanilla-Calendar Range](https://vanilla-calendar.pro/) feature).
+
+> **Note** we use [Tempo](https://tempo.formkit.com/) to parse and format Dates to the chosen format via the `type` option when provided in your column definition.
##### Component
-import { Filters, FlatpickrOption, Formatters, GridOption, OperatorType } from '@slickgrid-universal/common';
+import { Filters, Formatters, GridOption, OperatorType, VanillaCalendarOption } from '@slickgrid-universal/common';
```typescript
export class GridBasicComponent {
@@ -148,14 +149,16 @@ export class GridBasicComponent {
// your columns definition
this.columnDefinitions = [
{
- id: 'finish', name: 'Finish', field: 'finish', headerKey: 'FINISH', formatter: Formatters.dateIso, sortable: true, minWidth: 75, width: 120, exportWithFormatter: true,
+ id: 'finish', name: 'Finish', field: 'finish', headerKey: 'FINISH',
+ minWidth: 75, width: 120, exportWithFormatter: true,
+ formatter: Formatters.dateIso, sortable: true,
type: FieldType.date,
filterable: true,
filter: {
model: Filters.dateRange,
- // override any of the Flatpickr options through "filterOptions"
- editorOptions: { minDate: 'today' } as FlatpickrOption
+ // override any of the Vanilla-Calendar options through "filterOptions"
+ editorOptions: { range: { min: 'today' } } as VanillaCalendarOption
}
},
];
@@ -167,14 +170,14 @@ export class GridBasicComponent {
}
```
-##### Filter Options (`FlatpickrOption` interface)
-All the available options that can be provided as `filterOptions` to your column definitions can be found under this [FlatpickrOption interface](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/flatpickrOption.interface.ts) and you should cast your `filterOptions` to that interface to make sure that you use only valid options of the [Flatpickr](https://flatpickr.js.org/) library.
+#### Filter Options (`VanillaCalendarOption` interface)
+All the available options that can be provided as `filterOptions` to your column definitions can be found under this [VanillaCalendarOption interface](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/interfaces/vanillaCalendarOption.interface.ts) and you should cast your `filterOptions` with the expected interface to make sure that you use only valid settings of the [Vanilla-Calendar](https://vanilla-calendar.pro/docs/reference/additionally/settings) library.
```ts
filter: {
- model: Filters.dateRange,
+ model: Filters.compoundDate,
filterOptions: {
- minDate: 'today'
- } as FlatpickrOption
+ range: { min: 'today' }
+ } as VanillaCalendarOption
}
```
diff --git a/docs/column-functionalities/filters/Select-Filter.md b/docs/column-functionalities/filters/Select-Filter.md
index 40872a9a5..aaaa86498 100644
--- a/docs/column-functionalities/filters/Select-Filter.md
+++ b/docs/column-functionalities/filters/Select-Filter.md
@@ -416,17 +416,13 @@ this.columnDefinitions = [
filter: {
// display checkmark icon when True
enableRenderHtml: true,
- collection: [{ value: '', label: '' }, { value: true, label: 'True', labelPrefix: ` ` }, { value: false, label: 'False' }],
+ collection: [{ value: '', label: '' }, { value: true, label: 'True', labelPrefix: ` ` }, { value: false, label: 'False' }],
model: Filters.singleSelect
}
}
];
```
-#### Change Default DOMPurify Options (sanitize html)
-If you find that the HTML that you passed is being sanitized and you wish to change it, then you can change the default `sanitizeHtmlOptions` property defined in the Global Grid Options, for more info on how to change these [global options](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/global-grid-options.ts).
-
-
### Collection Add Blank Entry
In some cases a blank entry at the beginning of the collection could be useful, the most common example for this is to use the first option as a blank entry to tell our Filter to show everything. So for that we can use the `addBlankEntry` flag in `collectionOptions
@@ -554,14 +550,21 @@ this.columnDefinitions = [
```
### Filter Options (`MultipleSelectOption` interface)
-All the available options that can be provided as `filterOptions` to your column definitions can be found under this [multipleSelectOption interface](/ghiscoding/slickgrid-universal/tree/master/packages/common/src/interfaces/multipleSelectOption.interface.ts) and you should cast your `filterOptions` to that interface to make sure that you use only valid options of the `multiple-select.js` library.
+All the available options that can be provided as `filterOptions` to your column definitions via the `MultipleSelectOption` interface of the external library and so you should cast your `filterOptions` to that interface to make sure that you use only valid options of the `Multiple-Select-Vanilla` library.
```ts
-filter: {
- model: Filters.singleSelect,
- filterOptions: {
- maxHeight: 400
- } as MultipleSelectOption
+import { MultipleSelectOption } from 'multiple-select-vanilla';
+
+prepareGrid() {
+ this.columnDefinitions = [{
+ id: 'isActive', name: 'Active', field: 'isActive',
+ filter: {
+ model: Filters.singleSelect,
+ filterOptions: {
+ maxHeight: 400
+ } as MultipleSelectOption
+ }
+ }];
}
```
@@ -570,7 +573,7 @@ You could also define certain options as a global level (for the entire grid or
```ts
this.gridOptions = {
- defaultFilterOptions: {
+ defaultFilterOptions: {
// Note: that `select` combines both multipleSelect & singleSelect
select: { minHeight: 350 }, // typed as MultipleSelectOption
}
@@ -598,53 +601,61 @@ Couple of small options were added to suit SlickGrid-Universal needs, which is w
##### Code
```typescript
-this.columnDefinitions = [
- {
- id: 'isActive', name: 'Is Active', field: 'isActive',
- filterable: true,
- filter: {
- collection: [{ value: '', label: '' }, { value: true, label: 'true' }, { value: false, label: 'false' }],
- model: Filters.singleSelect,
- filterOptions: {
- // add any multiple-select.js options (from original or custom version)
- autoAdjustDropPosition: false, // by default set to True, but you can disable it
- position: 'top'
- } as MultipleSelectOption
+import { MultipleSelectOption } from 'multiple-select-vanilla';
+
+prepareGrid() {
+ this.columnDefinitions = [
+ {
+ id: 'isActive', name: 'Is Active', field: 'isActive',
+ filterable: true,
+ filter: {
+ collection: [{ value: '', label: '' }, { value: true, label: 'true' }, { value: false, label: 'false' }],
+ model: Filters.singleSelect,
+ filterOptions: {
+ // add any multiple-select.js options (from original or custom version)
+ autoAdjustDropPosition: false, // by default set to True, but you can disable it
+ position: 'top'
+ } as MultipleSelectOption
+ }
}
- }
-];
+ ];
+}
```
#### Display shorter selected label text
If we find that our text shown as selected text is too wide, we can choose change that by using `optionLabel` in Custom Structure.
```typescript
-this.columnDefinitions = [
- {
- id: 'isActive', name: 'Is Active', field: 'isActive',
- filterable: true,
- filter: {
- collection: [
- { value: 1, label: '1', suffix: 'day' },
- { value: 2, label: '2', suffix: 'days' },
- { value: 3, label: '3', suffix: 'days' },
- // ...
- ],
- model: Filters.multipleSelect,
- customStructure: {
- label: 'label',
- labelSuffix: 'suffix',
- value: 'value',
- optionLabel: 'value', // use value instead to show "1, 2" instead of "1 day, 2 days"
- },
- filterOptions: {
- // use different label to show as selected text
- // please note the Custom Structure with optionLabel defined
- // or use "useSelectOptionLabelToHtml" to render HTML
- useSelectOptionLabel: true
- } as MultipleSelectOption
+import { MultipleSelectOption } from 'multiple-select-vanilla';
+
+prepareGrid() {
+ this.columnDefinitions = [
+ {
+ id: 'isActive', name: 'Is Active', field: 'isActive',
+ filterable: true,
+ filter: {
+ collection: [
+ { value: 1, label: '1', suffix: 'day' },
+ { value: 2, label: '2', suffix: 'days' },
+ { value: 3, label: '3', suffix: 'days' },
+ // ...
+ ],
+ model: Filters.multipleSelect,
+ customStructure: {
+ label: 'label',
+ labelSuffix: 'suffix',
+ value: 'value',
+ optionLabel: 'value', // use value instead to show "1, 2" instead of "1 day, 2 days"
+ },
+ filterOptions: {
+ // use different label to show as selected text
+ // please note the Custom Structure with optionLabel defined
+ // or use "useSelectOptionLabelToHtml" to render HTML
+ useSelectOptionLabel: true
+ } as MultipleSelectOption
+ }
}
- }
-];
+ ];
+}
```
### Query against another field property
diff --git a/docs/column-functionalities/filters/Styling-Filled-Filters.md b/docs/column-functionalities/filters/Styling-Filled-Filters.md
index 8ac7c970b..895d103f0 100644
--- a/docs/column-functionalities/filters/Styling-Filled-Filters.md
+++ b/docs/column-functionalities/filters/Styling-Filled-Filters.md
@@ -1,55 +1,45 @@
-You can style any (or all) of the Filter(s) when they have value, the lib will automatically add a `filled` CSS class which you can style as your wish. There is no style by default, if you wish to add styling, you will be required to add your own.
+You can style any (or all) of the Filter(s) when they have value, the lib will automatically add a `filled` CSS class which you can style as your wish. There is no style by default, if you wish to add styling, you will be required to add your own.
-## Styled Example
+## Styled Example
![grid_filled_styling](https://user-images.githubusercontent.com/643976/51334569-14306d00-1a4e-11e9-816c-439796eb8a59.png)
## Code example
-For example, the print screen shown earlier was styled using this piece of SASS (`.scss`) code. Also note that the demo adds a Font-Awesome icon which can be used with `font-family: "FontAwesome"` and the relevent unicode character, for example the filter icon is `content: " \f0b0"`. You can basically add a lot of different styling to your populated filters.
+For example, the print screen shown earlier was styled using this piece of SASS (`.scss`) code. You can customize the styling to your liking.
```scss
-$filter-filled-bg-color: darkorange;
-
-.search-filter.filled {
- // color: rgb(189, 104, 1);
- // font-weight: bold;
- background-color: $filter-filled-bg-color;
- .ms-choice {
- // color: rgb(189, 104, 1);
- // font-weight: bold;
- background-color: $filter-filled-bg-color;
- }
-
-
- input, input.flatpickr-input {
- // border: 1px solid darken(rgb(204, 204, 204), 15%) !important;
- // color: rgb(189, 104, 1);
- // font-weight: bold;
- background-color: $filter-filled-bg-color !important;
+$slick-filled-filter-color: $slick-form-control-focus-border-color;
+$slick-filled-filter-border: $slick-form-control-border;
+$slick-filled-filter-box-shadow: $slick-form-control-focus-border-color;
+$slick-filled-filter-font-weight: 400;
+
+.slick-headerrow {
+ input.search-filter.filled,
+ .search-filter.filled input,
+ .search-filter.filled .date-picker input,
+ .search-filter.filled .input-group-addon.slider-value,
+ .search-filter.filled .input-group-addon.slider-range-value,
+ .search-filter.filled .input-group-addon select {
+ color: $slick-filled-filter-color;
+ font-weight: $slick-filled-filter-font-weight;
+ border: $slick-filled-filter-border;
+ box-shadow: $slick-filled-filter-box-shadow;
+ &.input-group-prepend {
+ border-right: 0;
+ }
+ &.input-group-append {
+ border-left: 0;
+ }
}
- /*
- &.ms-parent, .flatpickr > input, .input-group > input {
- border: 1px solid darken(rgb(204, 204, 204), 15%) !important;
- }
- */
-
- div.flatpickr:after, button > div:after, & + span:after, .input-group > span:after {
- font-family: "FontAwesome";
- font-size: 75%;
- content: " \f0b0";
- position: absolute;
- top: 2px;
- right: 5px;
- z-index: 1000;
- color: #ca880f;
- }
-
- .ms-choice > div:after {
- top: -4px;
- right: 16px;
+ .search-filter.filled .input-group-prepend select {
+ border-right: 0;
}
- & + span:after {
- top: 6px;
- right: 10px;
+ .search-filter.filled .ms-choice {
+ box-shadow: $slick-filled-filter-box-shadow;
+ border:$slick-filled-filter-border;
+ span {
+ font-weight: $slick-filled-filter-font-weight;
+ color: $slick-filled-filter-color;
+ }
}
}
```
diff --git a/docs/developer-guides/csp-compliance.md b/docs/developer-guides/csp-compliance.md
index adfb74c39..4c58f2bba 100644
--- a/docs/developer-guides/csp-compliance.md
+++ b/docs/developer-guides/csp-compliance.md
@@ -1,7 +1,20 @@
## CSP Compliance
-The library is now, at least mostly, CSP (Content Security Policy) compliant since `v4.0`, however there are some exceptions to be aware of. When using any html string as template (for example with Custom Formatter returning an html string), you will not be fully compliant unless you return `TrustedHTML`. You can achieve this by using the `sanitizer` method in combo with [DOMPurify](https://github.com/cure53/DOMPurify) to return `TrustedHTML` as shown below and with that in place you should be CSP compliant.
+The library is for the most part CSP (Content Security Policy) compliant since `v4.0` **but** only if you configure the `sanitizer` grid option. We were previously using `DOMPurify` internally in the project (in version <=4.x) but it was made optional in version 5 and higher. The main reason to make it optional was because most users would use `dompurify` but some users who require SSR support would want to use `isomorphic-dompurify`. You could also skip the `sanitizer` configuration, but that is not recommended.
-> **Note** the default sanitizer in Slickgrid-Universal is actually already configured to return `TrustedHTML` but the CSP safe in the DataView is opt-in via `useCSPSafeFilter`
+> **Note** even if the `sanitizer` is optional, we **strongly suggest** that you configure it as a global grid option to avoid possible XSS attacks from your data and also to be CSP compliant. Note that for Salesforce users, you do not have to configure it since Salesforce already use DOMPurify internally.
+
+As mentioned above, the project is mostly CSP compliant, however there are some exceptions to be aware of. When using any html string as template (for example with Custom Formatter returning an html string), you will not be fully compliant unless you return `TrustedHTML`. You can achieve this by using the `sanitizer` method in combo with [DOMPurify](https://github.com/cure53/DOMPurify) to return `TrustedHTML` as shown below and with that in place you should be CSP compliant.
+
+```diff
+// prefer the global grid options if possible
+this.gridOptions = {
+ sanitizer: (dirtyHtml) => DOMPurify.sanitize(dirtyHtml, { ADD_ATTR: ['level'], RETURN_TRUSTED_TYPE: true })
+};
+```
+
+> **Note** If you're wondering about the `ADD_ATTR: ['level']`, well the "level" is a custom attribute used by SlickGrid Grouping/Draggable Grouping to track the grouping level depth and it must be kept.
+
+> **Note** the DataView is not CSP safe by default, it is opt-in via the `useCSPSafeFilter` option.
```typescript
import DOMPurify from 'dompurify';
@@ -15,7 +28,9 @@ this.gridOptions = {
}
this.sgb = new Slicker.GridBundle(gridContainerElm, this.columnDefinitions, this.gridOptions, this.dataset);
```
+
with this code in place, we can use the following CSP meta tag (which is what we use in the lib demo, ref: [index.html](https://github.com/ghiscoding/slickgrid-universal/blob/master/examples/vite-demo-vanilla-bundle/index.html#L8-L14))
+
```html
```
diff --git a/docs/getting-started/installation-vanilla.md b/docs/getting-started/installation-vanilla.md
new file mode 100644
index 000000000..155ce5985
--- /dev/null
+++ b/docs/getting-started/installation-vanilla.md
@@ -0,0 +1,112 @@
+# Quick start
+
+> **NOTE** these instructions are for the latest v5.x and might differ from earlier versions of the lib.
+
+### 1. Install NPM Package
+Install the `Angular-Slickgrid`, and other external packages like `Bootstrap` and `Font-Awesome`
+(Bootstrap, Font-Awesome are optional, you can choose other lib if you wish)
+```bash
+npm install --save @slickgrid-universal/common
+
+# install whichever UI framework you want to use like Bootstrap, Bulma, ...
+npm install bootstrap
+```
+
+### 2. Create a basic grid
+And finally, you are now ready to use it in your project, for example let's create both html/ts files for a basic example.
+
+##### 1. define a grid container in your View
+```html
+
My First Grid
+
+
+
+```
+
+##### 2. configure the Column Definitions, Grid Options and pass a Dataset to the grid
+below we use `mounted`, but it could be totally different dependending on what framework you use (it could be `mounted`, `attached`, `onRender`, ...)
+
+```ts
+import { Column, GridOption, Slicker } from '@slickgrid-universal/common';
+
+export class GridBasicComponent {
+ columnDefinitions: Column[] = [];
+ gridOptions: GridOption = {};
+
+ constructor() {
+ this.prepareGrid();
+ }
+
+ mounted() {
+ const container = document.querySelector(`.grid1`) as HTMLDivElement;
+ this.sgb = new Slicker.GridBundle(container, this.columnDefinitions, this.getData());
+ }
+
+ getData() {
+ // ...
+ }
+
+ prepareGrid() {
+ this.columnDefinitions = [
+ { id: 'title', name: 'Title', field: 'title', sortable: true },
+ { id: 'duration', name: 'Duration (days)', field: 'duration', sortable: true },
+ { id: '%', name: '% Complete', field: 'percentComplete', sortable: true },
+ { id: 'start', name: 'Start', field: 'start' },
+ { id: 'finish', name: 'Finish', field: 'finish' },
+ ];
+
+ this.gridOptions = {
+ enableAutoResize: true,
+ enableSorting: true
+ };
+
+ // fill the dataset with your data (or read it from the DB)
+ this.dataset = [
+ { id: 0, title: 'Task 1', duration: 45, percentComplete: 5, start: '2001-01-01', finish: '2001-01-31' },
+ { id: 1, title: 'Task 2', duration: 33, percentComplete: 34, start: '2001-01-11', finish: '2001-02-04' },
+ ];
+ }
+}
+```
+
+### 3. CSS / SASS Styles
+Load your prefered theme, choose between Bootstrap (default), Material or Salesforce themes. You can also customize them to your taste (either by using SASS or CSS variables).
+
+#### CSS
+Default compiled `css`, you can load it through HTML or import it in your JS code depending on your project.
+
+```html
+# Bootstrap Theme
+
+```
+
+> **Note** to use a different theme, simply replace the theme suffix, for example `"slickgrid-theme-material.css"` for the Material Theme.
+
+#### SASS (scss)
+You could also compile the SASS files with your own customization, for that simply take any of the [_variables.scss](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/styles/_variables.scss) (without the `!default` flag) variable file and make sure to import the Bootstrap Theme afterward. For example, you could modify your `style.scss` with the following changes:
+
+```scss
+/* for example, let's change the mouse hover color */
+$cell-odd-background-color: lightyellow;
+$row-mouse-hover-color: lightgreen;
+
+/* make sure to add the @import the SlickGrid Theme AFTER the variables changes */
+@import '@slickgrid-universal/common/dist/styles/sass/slickgrid-theme-bootstrap.scss';
+```
+
+### 4. Explore the Documentation
+The last step is really to explore all the pages that are available on the documentation website which are often updated. For example a good starter is to look at the following
+- all the `Grid Options` you can take a look at, [Slickgrid-Universal - Grid Options](https://github.com/ghiscoding/angular-slickgrid/blob/master/src/app/modules/angular-slickgrid/models/gridOption.interface.ts) interface
+- [Formatters](../column-functionalities/Formatters.md)
+- [Editors](../column-functionalities/Editors.md)
+- [Filters](../column-functionalities/filters/Select-Filter.md)
+- [Grid Menu](../grid-functionalities/Grid-Menu.md)
+... and much more, just explorer the Documentation through the table of content (on your left)
+
+### 5. Get Started
+The best way to get started is to clone either the [Slickgrid-Universal Vite Demo](https://github.com/ghiscoding/slickgrid-universal-vite-demo) or [Slickgrid-Universal WebPack Demo](https://github.com/ghiscoding/slickgrid-universal-webpack-demo).
+
+##### All Live Demo Examples have links to the actual code
+If you would like to see the code to a particular Example. Just click on the "see code" that is available in every live examples.
+
+... and that should cover it, now let's code!
\ No newline at end of file
diff --git a/docs/getting-started/quick-start.md b/docs/getting-started/quick-start.md
index e5fbfad0f..1175f79b7 100644
--- a/docs/getting-started/quick-start.md
+++ b/docs/getting-started/quick-start.md
@@ -9,8 +9,9 @@ To get started follow any of these instruction Wikis depending on your choice of
| Angular | [Wiki - HOWTO (Step by Step)](https://ghiscoding.gitbook.io/angular-slickgrid/getting-started/quick-start) | [Live Demo](https://ghiscoding.github.io/Angular-Slickgrid/) |
| Aurelia | [Wiki - HOWTO (Step by Step)](https://ghiscoding.gitbook.io/aurelia-slickgrid/getting-started/quick-start) | [Live Demo](https://ghiscoding.github.io/aurelia-slickgrid/) |
| React | [Wiki - HOWTO (Step by Step)](https://ghiscoding.gitbook.io/slickgrid-react/getting-started/quick-start) | [Live Demo](https://ghiscoding.github.io/slickgrid-react/) |
-| Salesforce | Installation | [Print Screen](https://github.com/ghiscoding/slickgrid-universal/wiki#salesforce-demo---print-screen) |
+| Salesforce | [Salesforce Installation](./installation-salesforce.md) | [Print Screen](https://github.com/ghiscoding/slickgrid-universal/wiki#salesforce-demo---print-screen) |
| ---- | | |
+| Vanilla | [Installation (Step by Step)](./installation-vanilla.md) | | | ---- | | |
**General Subjects**
diff --git a/docs/grid-functionalities/Composite-Editor-Modal.md b/docs/grid-functionalities/Composite-Editor-Modal.md
index 19aa2f983..e8b9ec0d7 100644
--- a/docs/grid-functionalities/Composite-Editor-Modal.md
+++ b/docs/grid-functionalities/Composite-Editor-Modal.md
@@ -467,6 +467,7 @@ export class GridExample {
if (columnDef.id === 'completed') {
this.compositeEditorInstance.changeFormEditorOption('percentComplete', 'filter', formValues.completed);
this.compositeEditorInstance.changeFormEditorOption('product', 'minLength', 3);
+ this.compositeEditorInstance.changeFormEditorOption('finish', 'range', { min: 'today' });
}
}
}
@@ -496,9 +497,9 @@ export class GridExample {
// you can also change some editor options
// not all Editors supports this functionality, so far only these Editors are supported: AutoComplete, Date, Single/Multiple Select
if (columnDef.id === 'completed') {
- this.compositeEditorInstance.changeFormEditorOption('percentComplete', 'filter', true); // multiple-select.js, show filter in dropdown
- this.compositeEditorInstance.changeFormEditorOption('product', 'minLength', 3); // autocomplete, change minLength char to type
- this.compositeEditorInstance.changeFormEditorOption('finish', 'minDate', 'today'); // flatpickr date picker, change minDate to today
+ this.compositeEditorInstance.changeFormEditorOption('percentComplete', 'filter', true); // multiple-select.js, show filter in dropdown
+ this.compositeEditorInstance.changeFormEditorOption('product', 'minLength', 3); // autocomplete, change minLength char to type
+ this.compositeEditorInstance.changeFormEditorOption('finish', 'range', { min: 'today' }); // vanilla calendar date picker, change minDate to today
}
}
}
@@ -619,7 +620,7 @@ Disabling field(s) is done through the exact same way that you would do it in th
```ts
handleOnBeforeEditCell(event) {
const eventData = event.detail.eventData;
- const args = event && event.detail && event.detail.args;
+ const args = event?.detail?.args;
const { column, item, grid } = args;
if (column && item) {
@@ -649,13 +650,14 @@ checkItemIsEditable(dataContext: any, columnDef: Column, grid: SlickGrid) {
return isEditable;
}
```
+
#### Disabling Form Inputs but only in Composite Editor
What if you want to disable certain form inputs but only in the Composite Editor, or use different logic in the grid. For that we added an extra `target` (`target` will return either "grid" or "composite") in the returned `args`, so you could apply different logic based on the target being the grid or the composite editor. For example:
```ts
handleOnBeforeEditCell(event) {
const eventData = event.detail.eventData;
- const args = event && event.detail && event.detail.args;
+ const args = event?.detail?.args;
const { column, item, grid, target } = args;
if (column && item) {
diff --git a/docs/grid-functionalities/Context-Menu.md b/docs/grid-functionalities/Context-Menu.md
index 64ca9c170..5e94673e9 100644
--- a/docs/grid-functionalities/Context-Menu.md
+++ b/docs/grid-functionalities/Context-Menu.md
@@ -39,7 +39,7 @@ this.gridOptions = {
console.log(args.dataContext, args.column); // action callback.. do something
}
},
- { command: 'help', title: 'HELP', iconCssClass: 'fa fa-question-circle', positionOrder: 62 },
+ { command: 'help', title: 'HELP', iconCssClass: 'mdi mdi-help-circle', positionOrder: 62 },
// you can add sub-menus by adding nested `commandItems`
{
// we can also have multiple nested sub-menus
@@ -68,14 +68,14 @@ this.gridOptions = {
hideCloseButton: false,
optionTitle: 'Change Effort Driven Flag', // optional, add title
optionItems: [
- { option: true, title: 'True', iconCssClass: 'fa fa-check-square-o' },
- { option: false, title: 'False', iconCssClass: 'fa fa-square-o' },
+ { option: true, title: 'True', iconCssClass: 'mdi mdi-check-box-outline' },
+ { option: false, title: 'False', iconCssClass: 'mdi mdi-checkbox-blank-outline' },
{ divider: true, command: '', positionOrder: 60 },
],
// subscribe to Context Menu onOptionSelected event (or use the "action" callback on each option)
onOptionSelected: (e, args) => {
// change Priority
- const dataContext = args && args.dataContext;
+ const dataContext = args?.dataContext;
if (dataContext && dataContext.hasOwnProperty('priority')) {
dataContext.priority = args.item.option;
this.sgb.gridService.updateItem(dataContext);
@@ -133,7 +133,7 @@ For example, say we want the Context Menu to only be available on the first 20 r
```ts
contextMenu: {
menuUsabilityOverride: (args) => {
- const dataContext = args && args.dataContext;
+ const dataContext = args?.dataContext;
return (dataContext.id < 21); // say we want to display the menu only from Task 0 to 20
},
```
@@ -141,18 +141,17 @@ contextMenu: {
To give another example, with Options this time, we could say that we enable the `n/a` option only when the row is Completed. So we could do it this way
```ts
contextMenu: {
- optionItems: [
- {
+ optionItems: [{
option: 0, title: 'n/a', textCssClass: 'italic',
// only enable this option when the task is Not Completed
itemUsabilityOverride: (args) => {
- const dataContext = args && args.dataContext;
+ const dataContext = args?.dataContext;
return !dataContext.completed;
},
- { option: 1, iconCssClass: 'fa fa-star-o yellow', title: 'Low' },
- { option: 2, iconCssClass: 'fa fa-star-half-o orange', title: 'Medium' },
- { option: 3, iconCssClass: 'fa fa-star red', title: 'High' },
- ]
+ { option: 1, iconCssClass: 'mdi mdi-star-outline yellow', title: 'Low' },
+ { option: 2, iconCssClass: 'mdi mdi-star orange', title: 'Medium' },
+ { option: 3, iconCssClass: 'mdi mdi-star red', title: 'High' },
+ }]
}
```
@@ -161,12 +160,11 @@ It works exactly like the rest of the library when `enableTranslate` is set, all
```ts
contextMenu: {
optionTitleKey: 'COMMANDS', // optionally pass a title to show over the Options
- optionItems: [
- {
- { option: 1, titleKey: 'LOW', iconCssClass: 'fa fa-star-o yellow' },
- { option: 2, titleKey: 'MEDIUM', iconCssClass: 'fa fa-star-half-o orange' },
- { option: 3, titleKey: 'HIGH', iconCssClass: 'fa fa-star red' },
- ]
+ optionItems: [{
+ { option: 1, titleKey: 'LOW', iconCssClass: 'mdi mdi-star-outline yellow' },
+ { option: 2, titleKey: 'MEDIUM', iconCssClass: 'mdi mdi-star orange' },
+ { option: 3, titleKey: 'HIGH', iconCssClass: 'mdi mdi-star red' },
+ }]
}
```
@@ -199,10 +197,10 @@ contextMenu: {
hideExportTextDelimitedCommand: true,
hideMenuOnScroll: true,
hideOptionSection: false,
- iconCopyCellValueCommand: 'fa fa-clone',
- iconExportCsvCommand: 'fa fa-download',
- iconExportExcelCommand: 'fa fa-file-excel-o text-success',
- iconExportTextDelimitedCommand: 'fa fa-download',
+ iconCopyCellValueCommand: 'mdi mdi-content-copy',
+ iconExportCsvCommand: 'mdi mdi-download',
+ iconExportExcelCommand: 'mdi mdi-file-excel-outline text-success',
+ iconExportTextDelimitedCommand: 'mdi mdi-download',
width: 200,
},
```
diff --git a/docs/grid-functionalities/Export-to-Excel.md b/docs/grid-functionalities/Export-to-Excel.md
index eb8e09ae7..e6bbc0bdb 100644
--- a/docs/grid-functionalities/Export-to-Excel.md
+++ b/docs/grid-functionalities/Export-to-Excel.md
@@ -1,7 +1,6 @@
#### index
- [Grid Options](#grid-options)
- [Column Definition & Options](#column-definition-and-options)
-- [Custom Column Width](#custom-column-width)
- [Custom Cell Styling](#custom-cell-styling)
- [Cell Value Parser](#cell-value-parser)
- [Cell Format Auto-Detect Disable](#cell-format-auto-detect-disable)
@@ -59,7 +58,7 @@ initializeGrid() {
- So basically, if `exportWithFormatter` is set to True in the `excelExportOptions` of the Grid Options, but is set to False in the Column Definition, then the result will be False and will not evaluate it's Formatter.
- `exportCustomFormatter` will let you choose a different Formatter when exporting
- For example, you might have `formatter: Formatters.checkmark` but you want to see a boolean translated value, in this case you would define an extra property of `customFormatter: Formatters.translateBoolean`.
-- set `sanitizeDataExport` to remove any HTML/Script code from being export. For example if your value is `True` will export `True` without any HTML (data is sanitized).
+- set `sanitizeDataExport` to remove any HTML/Script code from being export. For example if your value is `True` will export `True` without any HTML (data is sanitized).
- this flag can be used in the Grid Options (all columns) or in a Column Definition (per column).
#### Grid Options
@@ -74,7 +73,7 @@ Inside the column definition there are couple of flags you can set in `excelExpo
- `sheetName` allows you to change the Excel Sheet Name (defaults to "Sheet1")
- `groupingColumnHeaderTitle` The column header title (at A0 in Excel) of the Group by. If nothing is provided it will use "Group By"
- `groupingAggregatorRowText` The default text to display in 1st column of the File Export, which will identify that the current row is a Grouping Aggregator
-- set `sanitizeDataExport` to remove any HTML/Script code from being export. For example if your value is `True` will export `True` without any HTML (data is sanitized).
+- set `sanitizeDataExport` to remove any HTML/Script code from being export. For example if your value is `True` will export `True` without any HTML (data is sanitized).
- this flag can be used in the Grid Options (all columns) or in a Column Definition (per column).
- `customExcelHeader` is a callback method that can be used to provide a custom Header Title to your Excel File
@@ -118,21 +117,6 @@ initializeGrid() {
What we can see from the example, is that it will use all Formatters (when exist) on this grid, except for the last column "Completed" since that column has explicitly defined `exportWithFormatter: false`
-### Custom Column Width
-
-**NOTE** now deprecated, please use [Custom Cell Styling](#custom-cell-styling) instead
-
-You can define a custom Excel column width (the width Excel's own width which is not in pixel). You can define a custom width per column (in your column definitions) and/or for the entire grid (in your grid options).
-
-#### Per Column
-You could set a custom width per column
-```ts
-this.columnDefinitions = [
- { id: 'firstName', name: 'FirstName', exportColumnWidth: 10, },
- // ...
-];
-```
-
#### For the entire Grid
You could also set a custom width for the entire grid export via the `excelExportOptions`
```ts
@@ -238,7 +222,7 @@ If you have lots of data, you might want to show a spinner telling the user that
##### View
```html
-
+
diff --git a/docs/grid-functionalities/Export-to-Text-File.md b/docs/grid-functionalities/Export-to-Text-File.md
index 53c32373c..b32b4e651 100644
--- a/docs/grid-functionalities/Export-to-Text-File.md
+++ b/docs/grid-functionalities/Export-to-Text-File.md
@@ -52,7 +52,7 @@ Inside the column definition there are couple of flags you can set and also some
- `exportCustomFormatter` will let you choose a different Formatter when exporting
- For example, you might have `formatter: Formatters.checkmark` but you want to see a boolean translated value, in this case you would define an extra property of `exportCustomFormatter: Formatters.translateBoolean`.
- you can set `exportCsvForceToKeepAsString` flag, this one will wrap the cell value into double quotes and add an equal sign in the front, this is especially useful on a column that could be turned into an exponential number by Excel. For example, we could have "1E06" and without this flag will become (1.0E06) in Excel, unless we enable the flag which will become `="1E06"` which will keep it as a string, also note that it will be shown as "1E06" but if you click on the cell value, you will see `="1E06"`
-- set `sanitizeDataExport` to remove any HTML/Script code from being export. For example if your value is `True` will export `True` without any HTML (data is sanitized).
+- set `sanitizeDataExport` to remove any HTML/Script code from being export. For example if your value is `True` will export `True` without any HTML (data is sanitized).
- this flag can be used in the Grid Options (all columns) or in a Column Definition (per column).
#### Behaviors
@@ -140,7 +140,7 @@ If you have lots of data, you might want to show a spinner telling the user that
##### View
```html
-
+
diff --git a/docs/grid-functionalities/Grid-Menu.md b/docs/grid-functionalities/Grid-Menu.md
index 4c8b2d30e..fce112f7e 100644
--- a/docs/grid-functionalities/Grid-Menu.md
+++ b/docs/grid-functionalities/Grid-Menu.md
@@ -29,18 +29,18 @@ this.gridOptions = {
gridMenu: {
commandTitle: 'Custom Commands',
columnTitle: 'Columns',
- iconCssClass: 'fa fa-ellipsis-v',
+ iconCssClass: 'mdi mdi-dots-vertical',
menuWidth: 17,
resizeOnShowHeaderRow: true,
commandItems: [
{
- iconCssClass: 'fa fa-filter text-danger',
+ iconCssClass: 'mdi mdi-filter-remove-outline',
title: 'Clear All Filters',
disabled: false,
command: 'clear-filter'
},
{
- iconCssClass: 'fa fa-random',
+ iconCssClass: 'mdi-flip-vertical',
title: 'Toggle Filter Row',
disabled: false,
command: 'toggle-filter'
@@ -110,12 +110,12 @@ You can change any of the default command icon(s) by changing the `icon[X-comman
this.gridOptions = {
enableGridMenu: true,
gridMenu: {
- iconClearAllFiltersCommand: 'fa fa-filter text-danger'
- iconClearAllSortingCommand: 'fa fa-unsorted text-danger',
- iconExportCsvCommand: 'fa fa-download',
- iconExportTextDelimitedCommand: 'fa fa-download',
- iconRefreshDatasetCommand: 'fa fa-refresh',
- iconToggleFilterCommand: 'fa fa-random',
+ iconClearAllFiltersCommand: 'mdi mdi-filter-remove-outline'
+ iconClearAllSortingCommand: 'mdi mdi-sort-variant-off',
+ iconExportCsvCommand: 'mdi mdi-download',
+ iconExportTextDelimitedCommand: 'mdi mdi-download',
+ iconRefreshDatasetCommand: 'mdi mdi-sync',
+ iconToggleFilterCommand: 'mdi-flip-vertical',
},
};
```
diff --git a/docs/grid-functionalities/Tree-Data-Grid.md b/docs/grid-functionalities/Tree-Data-Grid.md
index 4065e6489..34afee089 100644
--- a/docs/grid-functionalities/Tree-Data-Grid.md
+++ b/docs/grid-functionalities/Tree-Data-Grid.md
@@ -349,10 +349,10 @@ this.columnDefinitions = [
if (avgVal !== undefined && sumVal !== undefined) {
// when found Avg & Sum, we'll display both
- return isNaN(sumVal) ? '' : `sum: ${decimalFormatted(sumVal, 0, 2)} MB / avg: ${decimalFormatted(avgVal, 0, 2)} MB(${treeLevel === 0 ? 'total' : 'sub-total'})`;
+ return isNaN(sumVal) ? '' : `sum: ${decimalFormatted(sumVal, 0, 2)} MB / avg: ${decimalFormatted(avgVal, 0, 2)} MB(${treeLevel === 0 ? 'total' : 'sub-total'})`;
} else if (sumVal !== undefined) {
// or when only Sum is aggregated, then just show Sum
- return isNaN(sumVal) ? '' : `sum: ${decimalFormatted(sumVal, 0, 2)} MB(${treeLevel === 0 ? 'total' : 'sub-total'})`;
+ return isNaN(sumVal) ? '' : `sum: ${decimalFormatted(sumVal, 0, 2)} MB(${treeLevel === 0 ? 'total' : 'sub-total'})`;
}
}
// reaching this line means it's a regular dataContext without totals, so regular formatter output will be used
diff --git a/docs/grid-functionalities/frozen-columns-rows.md b/docs/grid-functionalities/frozen-columns-rows.md
index 77e1f2825..f3aba1c33 100644
--- a/docs/grid-functionalities/frozen-columns-rows.md
+++ b/docs/grid-functionalities/frozen-columns-rows.md
@@ -81,7 +81,7 @@ You can change the number of pinned columns/rows and even the pinning of columns
: ${ isFrozenBottom ? 'Bottom' : 'Top' }
diff --git a/docs/grid-functionalities/grouping-aggregators.md b/docs/grid-functionalities/grouping-aggregators.md
index d28fd8c7d..60179aff6 100644
--- a/docs/grid-functionalities/grouping-aggregators.md
+++ b/docs/grid-functionalities/grouping-aggregators.md
@@ -179,21 +179,19 @@ To "Clear all Grouping", "Collapse all Groups" and "Expand all Groups", we can s
```
### Styling (change icons)
-The current icons are Font Awesome chevron (right/down), however if you wish to use +/- icons. You can simply update the SASS variables to use whichever icons (or even Font Family icon) you desire. The SASS variables you can change are
+The current icons are chevron (right/down), however if you wish to use +/- icons. You can simply update the SASS variables to use whichever SVG icon paths. The SASS variables you can change are
```css
-$icon-group-color: $primary-color;
-$icon-group-expanded: "\f107";
-$icon-group-collapsed: "\f105";
-$icon-group-font-size: ($icon-font-size + 2px);
-$icon-group-font-weight: bold;
-$icon-group-margin-right: 2px;
-$icon-group-height: 20px;
-$icon-group-width: 14px;
+$slick-icon-group-color: $primary-color;
+$slick-icon-group-expanded-svg-path: "M19,19V5H5V19H19M19,3A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V5C3,3.89 3.9,3 5,3H19M11,7H13V11H17V13H13V17H11V13H7V11H11V7Z";
+$slick-icon-group-collapsed-svg-path: "M19,19V5H5V19H19M19,3A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V5C3,3.89 3.9,3 5,3H19M17,11V13H7V11H17Z";
+$slick-icon-group-font-size: 20px;
+$slick-icon-group-font-weight: bold;
+$slick-icon-group-margin-right: 2px;
/* Grouping Totals Formatter */
-$group-totals-formatter-color: gray;
-$group-totals-formatter-bgcolor: white;
-$group-totals-formatter-font-size: 14px;
+$slick-group-totals-formatter-color: gray;
+$slick-group-totals-formatter-bgcolor: white;
+$slick-group-totals-formatter-font-size: 14px;
```
For more info on SASS styling and variables, please read the [Wiki - SASS Styling](../styling/styling.md),
\ No newline at end of file
diff --git a/docs/grid-functionalities/header-menu-header-buttons.md b/docs/grid-functionalities/header-menu-header-buttons.md
index 42b15c577..97d6dfe64 100644
--- a/docs/grid-functionalities/header-menu-header-buttons.md
+++ b/docs/grid-functionalities/header-menu-header-buttons.md
@@ -64,9 +64,9 @@ You can change any of the default command icon(s) by changing the `icon[X-comman
this.gridOptions = {
enableHeaderMenu: true,
headerMenu: {
- iconColumnHideCommand: 'fa fa-times'
- iconSortAscCommand: 'fa fa-sort-asc'
- iconSortDescCommand: 'fa fa-sort-desc',
+ iconColumnHideCommand: 'mdi mdi-close'
+ iconSortAscCommand: 'mdi mdi-sort-ascending'
+ iconSortDescCommand: 'mdi mdi-sort-descending',
},
};
```
diff --git a/docs/migrations/migration-to-5.x.md b/docs/migrations/migration-to-5.x.md
new file mode 100644
index 000000000..1e9f56f80
--- /dev/null
+++ b/docs/migrations/migration-to-5.x.md
@@ -0,0 +1,255 @@
+## Version 5 - Better UI and Dark Mode with Pure CSS SVG icons ✨
+This new release brings a lot of changes oriented towards better UI/UX, our SVG icons are now pure CSS and can be colorized like any other text via the native CSS `color` property (which helps a lot to improve the Dark Mode Theme).
+
+Another noticeable UI change is the migration from [Flatpickr](https://flatpickr.js.org/) to [Vanilla-Calendar-Picker](https://github.com/ghiscoding/vanilla-calendar-picker) (which is a fork of [Vanilla-Calendar-Pro](https://vanilla-calendar.pro/) and we'll hopefully drop the fork in the near future if possible), there are multiple reasons to migrate our date picker to another library as shown below. Another change that is mostly internal but is also indirectly connected to the date picker is the migration from MomentJS to [Tempo](https://tempo.formkit.com/) which is modern and is packaged as ESM which is great for Tree Shaking.
+
+##### Flatpickr cons:
+ - barely supported (lots of opened PR but nothing merged for the past 2 years)
+ - not fully ESM ready (it's only partially ESM, for example it is detected as CJS in Angular-Slickgrid and requires an exception in `allowedCommonJsDependencies`)
+ - styling could be a bit more modern (the use of native select/input to change year/month/time is a bit outdated and rudimentary)
+ - date range selection is not very user friendly (UX)
+
+##### Vanilla-Calendar (VC)
+ - pros:
+ - ESM ready
+ - modern styling and also includes Dark Mode theme
+ - date range becomes a lot more easy by displaying a picker with 2 months
+ - cons:
+ - build size is slightly larger but its UI/UX is awesome (especially when chaning month/year)
+ - settings are named differently and are not using flat config (complex object settings) and requires code change
+ - for example Flatpickr `minDate: 'today'` is instead `range: { min: 'today' }` in VC
+ - some settings were missing, like the `'today'` shortcut which is why I forked the VC project
+ - I did open a few PRs on the main project, so the hope is to drop the fork in the future while being a totally transparent change to you when it happens.
+
+With this release, and after 7 years of development as a 1 man show (myself @ghiscoding), I believe that I have achieved all goals and even more than I originally planned to accomplish and with that being said, I am not foreseeing any new major releases on the short term. As a recap, I think that the biggest challenge was the removal of jQuery/jQueryUI and transition to native code, that took 2-3 years to accomplish, and I am of course very proud to have achieved. All dependencies are now also all ESM and the project is CSP compliant.
+
+To summarize, the goal of this new release was mainly to improve UI/UX (mostly for Dark Mode) and also to make it fully ESM ready. Also noteworthy, the project is smaller in size (~100Kb smaller) compared to what it was in v2.x (that was when the user had to install jQuery/jQueryUI separately). So, considering that we're no longer requiring the install of jQuery/jQueryUI, and also considering that these 2 dependencies had a total of well over 200kb. We can safely assume that our project build size is in fact a lot smaller than it was just 2 years ago, that is really nice to know considering that we kept adding features (like Dark Mode and other features) while still decreasing its size over the years :)
+
+#### Major Changes - Quick Summary
+- minimum requirements bump
+ - Node >=v18.x
+ - Bootstrap >=v5.x (or any other UI framework)
+ - SASS >=v1.35 (`dart-sass`)
+ - migrated from Flatpickr to Vanilla-Calendar (visit [Vanilla-Calendar-Pro](https://vanilla-calendar.pro/) for demos and docs)
+ - migrated from MomentJS to [Tempo](https://tempo.formkit.com/) (by the FormKit
+team)
+
+> **Note** for the entire list of tasks & code changes applied in this release, you may want to take a look at the [Roadmap to 5.0](https://github.com/ghiscoding/slickgrid-universal/discussions/1482) Discussion.
+
+For most breaking changes, a quick Search & Replace in your code editor should suffice.
+
+> **Note:** if you come from an earlier version, please make sure to follow each migrations in their respected order (review previous migration guides)
+
+## Changes
+
+### Styling
+
+#### CSS classes `.color-xx` are all removed (use `.text-color-xx` or native `color` instead)
+> **Note** these extra colors are only available in the Material & Salesforce Themes (it is not included in the Bootstrap Theme since Bootstrap have their own coloring utils).
+
+Since the SVG icons are now pure CSS, we can now colorize any of them the same way that we would do for any other text via the `color` CSS property 🌈. For that reason, we no longer need any of the `.color-xx` CSS classes (which were created via CSS [filter](https://developer.mozilla.org/en-US/docs/Web/CSS/filter)). They were useful to override the SVG icon colors (by using CSS `filter`), but since we can now use the regular CSS `color` property, the `color-xx` are no longer necessary and were all removed (just use `text-color-xx` instead or plain CSS `color`s).
+
+```diff
+
+```
+or move the class to the parent container and have both the icon & the text `inherit` the color :)
+```diff
++
+```
+
+#### SASS variables
+A lot of SASS variables were changed, we recommend that you take a look at the [_variables.scss](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/styles/_variables.scss) file to compare them with your SASS overrides and fix any SASS build issues. For example a lot of the ms-select variables and all Flatpickr related variables were deleted (note that Vanilla-Calendar doesn't actually have any variables). Also a lot of the icon related variables were renamed and updated (icons now all have the suffix `-icon-svg-path` for the SVG vector path, you can easily change them with SASS).
+
+> **Note** if you want create your own SVGs icons in pure CSS, you could use the `generateSvgStyle()` SASS function from Slickgrid-Universal [`svg-utilities.scss`](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/styles/svg-utilities.scss) (take a look at the [`slickgrid-icons.scss`](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/styles/slickgrid-icons.scss) for some usage)
+
+#### SASS (dart-sass) `math` polyfills are removed
+When SASS (dart-sass) released their version 1.33 (~3 years ago), it caused a ton of console warnings (and a lot of unhappy users) in projects that were using `/` in their SASS files (for math division) instead of their new `math.div()` function. To avoid seeing all these warnings, I added a temporary polyfill at the time (that piece of code was actually copied from the Bootstrap project). That polyfill patch was put in place about 3 years ago, so I'm assuming that most users have already upgraded their SASS version and already fixed all of these warnings... So, I think it's now safe to remove this polyfill, because like I said earlier, it was really meant to be a temp patch. If you see any warnings coming back, then a suggestion would be to use the SASS CLI `--quiet-upstream` option.
+
+For reference, below is an example of these old Math warnings which were coming up when using the SASS CLI
+
+```sh
+Recommendation: math.div($m, $columns)
+More info and automated migrator: https://sass-lang.com/d/slash-div
+╷
+94 │ margin-right: $m / $columns * 100%
+│ ^^^^^^^^^^^^^^^^^^
+```
+
+#### Font-Awesome references are all removed
+Since this release introduces pure CSS SVG icons, I went ahead and deleted all Font-Awesome references (which were mostly in the Bootstrap Theme). The reason is simple, the built-in icons are now all pure CSS SVG icons (sort, grouping, row detail, row move, row selection). You can also change these icons via SASS (or CSS variables with a bit more work). However, please note that there are a few plugins which use external icons via CSS classes (mostly all menu plugins like Header Menu, Grid Menu, Content Menu, ...) and for that reason **all Styling Themes** now include the Slickgrid-Universal Material icons subset (~200 icons) by default (not just Material & Salesforce but now also the Bootstrap Theme as well). In short, the grid is now using SVG icons by default and Font-Awesome icons will no longer be used internally (you can still use it in your project but it won't be used by the grid itself unless you set them in your grid options).
+
+If you no longer need Font-Awesome, then consider removing it completely
+
+```diff
+# package.json
+{
+ dependencies: {
+- "font-awesome": "^4.7.0"
+ }
+}
+```
+
+What if you don't want to use the [Slickgrid-Universal icons](https://ghiscoding.github.io/slickgrid-universal/#/icons) (`.mdi`) subset and would rather use a different font/SVG library? In that case, I would suggest that you use the "lite" Themes (which do not include the colors & icons subset) and then make sure to update all the menu plugins with the correct CSS classes. For example the global grid options of the Grid Menu is now configured with the following icon classes (notice that we no longer provide any Font-Awesome "fa" icon references in our global grid options). Also note that what is shown below is just 1 of the multiple menu plugins to configure, make sure to review them all (you can review the [global-grid-options.ts](https://github.com/ghiscoding/slickgrid-universal/blob/master/packages/common/src/global-grid-options.ts) file).
+
+```ts
+// default global grid options
+export const GlobalGridOptions = {
+ gridMenu: {
+ iconCssClass: 'mdi mdi-menu',
+ iconClearAllFiltersCommand: 'mdi mdi-filter-remove-outline',
+ iconClearAllSortingCommand: 'mdi mdi-sort-variant-off',
+ iconClearFrozenColumnsCommand: 'mdi mdi-pin-off-outline',
+ iconExportCsvCommand: 'mdi mdi-download',
+ iconExportExcelCommand: 'mdi mdi-file-excel-outline',
+ iconExportTextDelimitedCommand: 'mdi mdi-download',
+ iconRefreshDatasetCommand: 'mdi mdi-sync',
+ iconToggleDarkModeCommand: 'mdi mdi-brightness-4',
+ iconToggleFilterCommand: 'mdi mdi-flip-vertical',
+ iconTogglePreHeaderCommand: 'mdi mdi-flip-vertical',
+ },
+ headerMenu: {
+ // icon...
+ }
+}
+```
+
+and below is a quick snapshot of the file size diff with the "lite" themes (without icons) vs the default themes (with colors & icons subset). However note that the built-in icons are of course always included even in the "lite" themes.
+
+![image](https://github.com/ghiscoding/Angular-Slickgrid/assets/643976/ea7542b9-3c7e-4a6f-ae4d-355138f74188)
+
+### Deprecated code removed/renamed
+##### `getHTMLFromFragment()` removed
+The util `getHTMLFromFragment()` function was removed in favor of `getHtmlStringOutput()`, the new function will auto-detect if it's a DocumentFragment, an HTMLElement or an HTML string and will execute the appropriate action.
+
+##### jQueryUI CSS classes leftovers
+There were a few remaining traces of jQueryUI CSS classes like `.ui-state-default` and other similar classes in the core lib, they were all removed in this release. If you were querying any of them in CSS for styling purposes, you can simply rename them to `.slick-state-*`
+
+```diff
+- .ui-state-default, .ui-state-hover {
++ .slick-state-default, .slick-state-hover {
+}
+```
+
+#### Formatters Cleanup & Removals
+
+Since we now use SVGs everywhere and we got rid of any Font usage (no more Font-Awesome code anywhere), the `checkmark` Formatter no longer has any reason to exist and was removed. If you were using it and still plan to use Font-Awesome in your project, then you'll have to either recreate the Formatter yourself or use alternatives. You could use the `Formatters.icon` or `Formatters.iconBoolean` which require the CSS classes to be provided via `params`. Or as a last alternative, and if you are importing the optional SVG icons `.mdi` subset, then we recommend you simply switch to the `checkmarkMaterial` Formatter.
+
+```diff
+this.columnDefinitions = [
+ {
+ id: 'isActive', name: 'Active', field: 'isActive',
+- formatter: Formatters.checkmark
++ formatter: Formatters.checkmarkMaterial
+ },
+];
+```
+
+or create a Custom Formatter
+
+```ts
+// create a custom Formatter and returning a string and/or an object of type FormatterResultObject
+const myCheckmarkFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {
+ // via native HTML (for CSP safe), you could also use our `createDomElement()` util for 1 liner
+ const iconElm = document.createElement('i');
+ iconElm.className = value ? 'mdi mdi-check' : '';
+ return iconElm;
+
+ // or via simple HTML string
+ return value ? '' : '';
+}
+```
+
+## Column Functionalities
+
+### Native Select Filter (removed)
+I would be very surprised if anyone had ever used the `Filters.select`, which was a native `
`,
excludeFromExport: true,
// customTooltip: {
// formatter: () => `Click to open Cell Menu`, // return empty so it won't show any pre-tooltip
@@ -354,6 +356,7 @@ export default class Example16 {
// Custom Tooltip options can be defined in a Column or Grid Options or a mixed of both (first options found wins)
externalResources: [new SlickCustomTooltip(), new ExcelExportService(), new TextExportService()],
customTooltip: {
+ className: 'grid16-tooltip',
formatter: this.tooltipFormatter.bind(this),
headerFormatter: this.headerFormatter,
headerRowFormatter: this.headerRowFormatter,
@@ -481,7 +484,7 @@ export default class Example16 {
// use a 2nd Formatter to get the percent completion
// any properties provided from the `asyncPost` will end up in the `__params` property (unless a different prop name is provided via `asyncParamsPropName`)
const completionBar = Formatters.percentCompleteBarWithText(row, cell, dataContext.percentComplete, column, dataContext, grid) as HTMLElement;
- const out = `
We only keep a small subset of the Material Design Icons, scroll to the bottom to see which ones are included in the
@@ -16,35 +22,42 @@
Material Design Icons
Icon Utilities
-
+
-
mdi-spin
-
mdi-spin-1s
-
mdi-spin-2s
-
mdi-spin-3s
-
mdi-spin-4s
-
mdi-spin-5s
-
mdi-rotate-45
-
mdi-rotate-90
-
mdi-rotate-135
-
mdi-rotate-180
-
mdi-rotate-220
-
mdi-flip-h
-
mdi-flip-v
+
mdi-spin / mdi-spin-2s
+
mdi-spin-1s
+
mdi-spin-2s
+
mdi-spin-3s
+
mdi-spin-4s
+
mdi-spin-5s
+
mdi-rotate-45
+
mdi-rotate-90
+
mdi-rotate-135
+
mdi-rotate-180
+
mdi-rotate-225
+
mdi-rotate-270
+
mdi-rotate-315
+
mdi-flip-h
+
mdi-flip-v
Icon Sizes
- (from 8px up to 50px)
+ (from 10px up to 50px)
+
+ Note, since icons are now pure CSS you could also use any font size CSS classes (when available) like "font-20px"
+ or you could also change font-size yourself or even simply inherit text font size.
+
+
-
mdi-8px
-
mdi-10px
-
mdi-15px
-
mdi-20px
-
mdi-25px
-
mdi-50px
+
font-10px
+
mdi-15px
+
mdi-22px
+
mdi-25px
+
mdi-38px
+
mdi-50px
@@ -54,7 +67,7 @@
text-bold
text-center
text-left
-
text-right
+
text-right
text-lowercase
text-uppercase
@@ -69,10 +82,10 @@
Padding & Icons Styled as a Button
- (padding from 0px up to 30px)
+ (padding from 0px up to 30px)
- Note, you can use the same pattern with "margin-0px", "padding-0x" and "font-5px"
+ Note, you can use the same pattern with "margin-0px", "padding-0x" and "font-5px"
@@ -102,250 +115,218 @@
-
- Icons Alignments
- (padding from 0px up to 30px)
-
-
-
-
- mdi-v-align-bottom
-
-
-
- mdi-v-align-middle
-
-
- mdi-v-align-sub
-
-
- mdi-v-align-super
-
-
-
- mdi-v-align-text-bottom
-
-
-
- mdi-v-align-text-top
-
-
- mdi-v-align-top
-
-
-
- Icon Colors
+ Icon & Text Colors
-
-
- color-primary
+
+
+ text-color-primary
-
-
- color-primary-light
+
+
+ text-color-primary-light
-
-
- color-primary-dark
+
+
+ text-color-primary-dark
-
-
- color-secondary
+
+
+ text-color-secondary
-
-
- color-secondary-light
+
+
+ text-color-secondary-light
-
-
- color-secondary-dark
+
+
+ text-color-secondary-dark
-
-
- color-success
+
+
+ text-color-success
-
-
- color-success-light
+
+
+ text-color-success-light
-
-
- color-success-dark
+
+
+ text-color-success-dark
-
-
- color-danger
+
+
+ text-color-danger
-
-
- color-danger-light
+
+
+ text-color-danger-light
-
-
- color-danger-dark
+
+
+ text-color-danger-dark
-
-
- color-warning
+
+
+ text-color-warning
-
-
- color-warning-light
+
+
+ text-color-warning-light
-
-
- color-warning-dark
+
+
+ text-color-warning-dark
-
-
- color-info
+
+
+ text-color-info
-
-
- color-info-light
+
+
+ text-color-info-light
-
-
- color-info-dark
+
+
+ text-color-info-dark
-
-
- color-muted
+
+
+ text-color-muted
-
-
- color-muted-light
+
+
+ text-color-muted-light
-
-
- color-muted-dark
+
+
+ text-color-muted-dark
-
-
- color-alt-default
+
+
+ text-color-alt-default
-
-
- color-alt-default-light
+
+
+ text-color-alt-default-light
-
-
- color-alt-default-dark
+
+
+ text-color-alt-default-dark
-
-
- color-alt-warning
+
+
+ text-color-alt-warning
-
-
- color-alt-warning-light
+
+
+ text-color-alt-warning-light
-
-
- color-alt-warning-dark
+
+
+ text-color-alt-warning-dark
-
-
- color-alt-danger
+
+
+ text-color-alt-danger
-
-
- color-alt-danger-light
+
+
+ text-color-alt-danger-light
-
-
- color-alt-danger-dark
+
+
+ text-color-alt-danger-dark
-
-
- color-alt-success
+
+
+ text-color-alt-success
-
-
- color-alt-success-light
+
+
+ text-color-alt-success-light
-
-
- color-alt-success-dark
+
+
+ text-color-alt-success-dark
-
-
- color-se-primary
+
+
+ text-color-se-primary
-
-
- color-se-link
+
+
+ text-color-se-link
-
-
- color-se-link-dark
+
+
+ text-color-se-link-dark
-
-
- color-se-danger
+
+
+ text-color-se-danger
-
-
- color-se-secondary-light
+
+
+ text-color-se-secondary-light
-
-
- color-se-secondary
+
+
+ text-color-se-secondary
-
-
- color-se-warning
+
+
+ text-color-se-warning
-
-
- color-se-warning-light
+
+
+ text-color-se-warning-light
-
-
- color-sf-highlight
+
+
+ text-color-sf-highlight
-
-
- color-sf-primary
+
+
+ text-color-sf-primary
-
-
- color-sf-primary-dark
+
+
+ text-color-sf-primary-dark
-
-
- color-dark
+
+
+ text-color-dark
-
-
- color-body
+
+
+ text-color-body
-
-
- color-disabled
+
+
+ text-color-disabled
-
-
- color-disabled-dark
+
+
+ text-color-disabled-dark
-
-
- color-light
+
+
+ text-color-light
-
-
- color-white
+
+
+ text-color-white
Icons currently available in the lib
-
+
\ No newline at end of file
diff --git a/examples/vite-demo-vanilla-bundle/src/examples/icons.scss b/examples/vite-demo-vanilla-bundle/src/examples/icons.scss
index 5ca991db5..ee539d95e 100644
--- a/examples/vite-demo-vanilla-bundle/src/examples/icons.scss
+++ b/examples/vite-demo-vanilla-bundle/src/examples/icons.scss
@@ -17,4 +17,16 @@
}
.bg-gray {
background-color: #3F3E3E;
+}
+.icon-box {
+ display: flex;
+ align-items: center;
+}
+.button-style {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+.mr-5px {
+ margin-right: 5px;
}
\ No newline at end of file
diff --git a/examples/vite-demo-vanilla-bundle/src/examples/icons.ts b/examples/vite-demo-vanilla-bundle/src/examples/icons.ts
index d4f617f75..2abded044 100644
--- a/examples/vite-demo-vanilla-bundle/src/examples/icons.ts
+++ b/examples/vite-demo-vanilla-bundle/src/examples/icons.ts
@@ -1,6 +1,8 @@
import './icons.scss';
export default class Icons {
+ private _darkMode = false;
+
attached() {
const iconContainerElm = document.querySelector(`.icons-container`) as HTMLDivElement;
const iconCounter = document.querySelector(`.icon-counter`) as HTMLDivElement;
@@ -10,14 +12,18 @@ export default class Icons {
icons.forEach((icon) => {
const iconDivElm = document.createElement('div');
- iconDivElm.className = 'slick-col-medium-2';
- iconDivElm.style.paddingBottom = '5px';
+ iconDivElm.className = 'slick-col-medium-2 icon-box';
+ iconDivElm.style.marginBottom = '5px';
const iconElm = document.createElement('span');
iconElm.className = icon.replace(/\./gi, ' ');
- iconElm.classList.add('mdi-24px');
+ if (icon.includes('mdi-change-record-type')) {
+ iconElm.classList.add('mdi-20px');
+ } else {
+ iconElm.classList.add('mdi-24px');
+ }
iconElm.title = icon.replace('.mdi.', '');
- iconElm.style.marginRight = '2px';
+ iconElm.style.marginRight = '5px';
iconDivElm.appendChild(iconElm);
const iconNameElm = document.createElement('span');
@@ -28,6 +34,22 @@ export default class Icons {
});
}
+ dispose() {
+ document.querySelector('.demo-container')?.classList.remove('dark-mode');
+ document.body.setAttribute('data-theme', 'light');
+ }
+
+ toggleDarkMode() {
+ this._darkMode = !this._darkMode;
+ if (this._darkMode) {
+ document.body.setAttribute('data-theme', 'dark');
+ document.querySelector('.demo-container')?.classList.add('dark-mode');
+ } else {
+ document.body.setAttribute('data-theme', 'light');
+ document.querySelector('.demo-container')?.classList.remove('dark-mode');
+ }
+ }
+
getIcons() {
return [
'.mdi.mdi-account',
@@ -59,6 +81,7 @@ export default class Icons {
'.mdi.mdi-arrow-expand',
'.mdi.mdi-arrow-expand-horizontal',
'.mdi.mdi-arrow-split-vertical',
+ '.mdi.mdi-book-open-blank-variant-outline',
'.mdi.mdi-brightness-4',
'.mdi.mdi-calendar',
'.mdi.mdi-calendar-check',
@@ -204,6 +227,7 @@ export default class Icons {
'.mdi.mdi-snowflake',
'.mdi.mdi-sort-ascending',
'.mdi.mdi-sort-descending',
+ '.mdi.mdi-sort-variant-off',
'.mdi.mdi-sort-variant-remove',
'.mdi.mdi-square-edit-outline',
'.mdi.mdi-star',
diff --git a/examples/vite-demo-vanilla-bundle/src/main.ts b/examples/vite-demo-vanilla-bundle/src/main.ts
index 4ae989561..3e0a57dea 100644
--- a/examples/vite-demo-vanilla-bundle/src/main.ts
+++ b/examples/vite-demo-vanilla-bundle/src/main.ts
@@ -1,15 +1,9 @@
-// import all CSS required by Slickgrid-Universal
-import 'flatpickr/dist/flatpickr.min.css';
-import './styles.scss';
-
import { Renderer } from './renderer';
import * as SlickerModule from '@slickgrid-universal/vanilla-bundle';
import { App } from './app';
import AppView from './app.html?raw';
import { TranslateService } from './translate.service';
-
-// load necessary Flatpickr Locale(s), but make sure it's imported AFTER the SlickerModule import
-import 'flatpickr/dist/l10n/fr';
+import './styles.scss';
class Main {
app!: App;
diff --git a/examples/vite-demo-vanilla-bundle/src/material-styles.scss b/examples/vite-demo-vanilla-bundle/src/material-styles.scss
index d3f5f9879..81d72ab35 100644
--- a/examples/vite-demo-vanilla-bundle/src/material-styles.scss
+++ b/examples/vite-demo-vanilla-bundle/src/material-styles.scss
@@ -3,8 +3,11 @@
// @import '@slickgrid-universal/common/dist/styles/sass/slickgrid-theme-material.scss';
:root {
- body.material-theme {
+ body.material-theme,
+ body.material-theme .icon-checkbox-container {
+ $dark-primary-color: #66bb6a;
$slick-primary-color: #009530;
+ --text-color-primary: #009530;
--slick-primary-color: #009530;
--slick-header-menu-display: inline-block;
--slick-compound-filter-operator-select-border: 1px solid #00c840;
@@ -39,24 +42,22 @@
--slick-header-font-size: 12px;
--slick-filled-filter-font-weight: normal;
--slick-icon-sort-color: var(--slick-primary-color);
- --slick-icon-sort-asc: url('data:image/svg+xml,');
- --slick-icon-sort-desc: url('data:image/svg+xml,');
- --slick-icon-sort-font-size: 18px;
- --slick-icon-sort-width: 18px;
- --slick-icon-sort-position-right: 14px;
- --slick-checkbox-selector-size: 22px;
- --slick-checkbox-selector-icon-width: 22px;
- --slick-checkbox-selector-checked-color: var(--slick-primary-color);
- --slick-checkbox-selector-color: var(--slick-primary-color);
- --slick-checkbox-selector-icon-border: none;
- --slick-checkbox-selector-icon-bg-color: transparent;
- --slick-checkbox-selector-icon-checked: url('data:image/svg+xml,');
- --slick-checkbox-selector-icon-unchecked: url('data:image/svg+xml,');
+ --slick-column-picker-icon-color: #009530;
+ --slick-compound-filter-text-color: #009530;
+ --slick-checkbox-icon-color: var(--slick-primary-color);
+ --slick-checkbox-icon-border: none;
+ --slick-checkbox-icon-width: 22px;
+ --slick-checkbox-icon-bg-color: transparent;
+ --slick-checkbox-icon-container-bg-color: transparent;
+ --slick-checkbox-icon-unchecked-color-visibility: visible;
+ --slick-checkbox-icon-container-size: 1rem;
+ --slick-checkbox-icon-font-size: 28px;
+ --slick-checkbox-icon-container-size: 1.4rem;
+ --slick-checkbox-opacity-hover: 0.9;
+ --slick-checkbox-size: 22px;
+ --slick-checkbox-unchecked-opacity: 1;
--slick-icon-group-color: var(--slick-primary-color);
- --slick-icon-group-collapsed: url('data:image/svg+xml,');
- --slick-icon-group-expanded: url('data:image/svg+xml,');
- --slick-icon-group-width: 22px;
-
+ --slick-pagination-icon-color: #009530;
--slick-slider-filter-thumb-border: 2px solid rgba(0, 149, 48, .68);
--slick-slider-filter-thumb-active-bg-color: #fff;
--slick-slider-filter-thumb-active-color: rgba(#02bf3e, .88);
@@ -74,22 +75,24 @@
--slick-multiselect-ok-button-text-color: #009530;
--slick-multiselect-ok-button-text-hover-color: #00a736;
--slick-multiselect-select-all-text-color: #007c28;
- --slick-column-picker-checkbox-icon-checked: url('data:image/svg+xml,');
- --slick-column-picker-checkbox-icon-unchecked: var(--slick-column-picker-checkbox-icon-checked);
- --slick-multiselect-icon-unchecked: url('data:image/svg+xml,');
--ms-checkbox-color: var(--slick-primary-color);
--slick-multiselect-icon-color: var(--slick-primary-color);
- --slick-multiselect-icon-radio-checked: url('data:image/svg+xml,');
- --slick-multiselect-icon-radio-unchecked: url('data:image/svg+xml,');
- .color-primary {
- filter: url("data:image/svg+xml;utf8, #recolor");
+ .icon-checkbox-container {
+ --slick-checkbox-icon-container-bg-color: transparent;
+ --slick-checkbox-unchecked-opacity: 0.9;
+ .mdi-icon-check {
+ --slick-checkbox-icon-checked-svg: url('data:image/svg+xml;utf8,%3Csvg viewBox="0 0 24 24" display="inline-block" height="1em" width="1em" vertical-align="text-bottom" xmlns="http://www.w3.org/2000/svg" %3E%3Cpath fill="currentColor" d="M10,17L5,12L6.41,10.58L10,14.17L17.59,6.58L19,8M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z"/%3E%3C/svg%3E') !important;
+ }
+ .mdi-icon-uncheck {
+ --slick-checkbox-icon-unchecked-svg: url('data:image/svg+xml;utf8,%3Csvg viewBox="0 0 24 24" display="inline-block" height="1em" width="1em" vertical-align="text-bottom" xmlns="http://www.w3.org/2000/svg" %3E%3Cpath fill="currentColor" d="M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M19,5V19H5V5H19Z"/%3E%3C/svg%3E') !important;
+ }
}
.slick-headerrow {
input.search-filter.filled,
.search-filter.filled input,
- .search-filter.filled input.flatpickr-input,
+ .search-filter.filled input.date-picker,
.search-filter.filled .input-group-addon.slider-value,
.search-filter.filled .input-group-addon.slider-range-value,
.search-filter.filled .input-group-addon select {
@@ -118,12 +121,19 @@
.ms-dark-mode,
.ms-drop.ms-dark-mode,
.slick-dark-mode .ms-dark-mode,
+ .slick-dark-mode .icon-checkbox-container,
+ .ms-dark-mode .icon-checkbox-container,
.slick-dark-mode {
--slick-base-dark-menu-bg-color: #212121;
--slick-primary-color: #66bb6a;
- --slick-button-primary-bg-color: var(--slick-primary-color);
+ --slick-button-primary-bg-color:#66bb6a;
+ --slick-cell-active-box-shadow: inset 0 0 0 1px #aaaaaa;
--slick-cell-box-shadow: none;
- --slick-column-picker-checkbox-color: #49a54e;
+ --slick-checkbox-icon-color: #66bb6a;
+ --slick-checkbox-icon-height: 22px;
+ --slick-checkbox-icon-bg-color: transparent;
+ --slick-checkbox-icon-border: none;
+ --slick-column-picker-icon-color: #66bb6a;
--slick-compound-filter-text-color: #66bb6a;
--slick-compound-filter-operator-select-border: 1px solid #66bb6a;
--slick-header-filter-row-border-bottom: 1px solid #505050;
@@ -134,17 +144,13 @@
--slick-pane-top-border-top: 1px solid #505050;
--slick-filled-filter-color: #66bb6a;
--slick-highlight-color: #49a54e;
- --slick-pagination-icon-color: #49a54e;
- --slick-checkbox-selector-checked-color: #66bb6a;
+ --slick-icon-sort-color: #66bb6a;
+ --slick-grid-menu-icon-btn-color: #bbb;
+ --slick-pagination-icon-color: #66bb6a;
--slick-row-mouse-hover-box-shadow: none;
--slick-row-mouse-hover-color: #505050;
--slick-row-selected-color: #474747;
- --slick-checkbox-selector-opacity: 1;
- --slick-checkbox-selector-icon-height: 22px;
- --slick-checkbox-selector-icon-bg-color: transparent;
- --slick-checkbox-selector-icon-border: none;
- --slick-multiselect-icon-radio-color: var(--slick-primary-color);
- --ms-checkbox-color: var(--slick-primary-color);
+ --ms-checkbox-color: #66bb6a;
--ms-checkbox-hover-color: #{lighten(#49a54e, 13%)};
--ms-ok-button-text-color: #66bb6a;
--ms-ok-button-text-hover-color: #{lighten(#66bb6a, 5%)};
@@ -157,10 +163,18 @@
}
input.search-filter.filled,
.search-filter.filled input,
- .search-filter.filled input.flatpickr-input {
+ .search-filter.filled .date-picker input {
color: var(--slick-text-color);
}
}
}
}
+
+ body.material-theme .ms-dark-mode,
+ body.material-theme .ms-drop.ms-dark-mode,
+ body.material-theme .slick-dark-mode .ms-dark-mode,
+ body.material-theme .slick-dark-mode,
+ body.material-theme .dark-mode .text-color-primary {
+ --slick-primary-color: #66bb6a;
+ }
}
diff --git a/examples/vite-demo-vanilla-bundle/src/styles.scss b/examples/vite-demo-vanilla-bundle/src/styles.scss
index cff379557..012ce46ac 100644
--- a/examples/vite-demo-vanilla-bundle/src/styles.scss
+++ b/examples/vite-demo-vanilla-bundle/src/styles.scss
@@ -9,6 +9,17 @@ $slick-link-color: #006DCC;
@import './bulma.scss';
+:root {
+ .ms-dark-mode,
+ .ms-drop.ms-dark-mode,
+ .slick-dark-mode .ms-dark-mode,
+ .slick-dark-mode,
+ .dark-mode .text-color-primary {
+ --slick-primary-color: #66b8ff;
+ --text-color-primary: #66b8ff;
+ }
+}
+
$navbar-height: 52px;
body {
height: calc(100vh - $navbar-height);
@@ -34,9 +45,9 @@ body {
}
.demo-container.dark-mode {
background-color: #33393e;
- color: #dddddd;
+ color: #f0f0f0;
h3 {
- color: #dddddd;
+ color: #e4e4e4;
}
.subtitle {
color: #cbcbcb;
@@ -85,8 +96,20 @@ input.is-narrow {
width: 35px;
margin-top: -1px;
}
+.d-inline-flex {
+ display: inline-flex;
+}
+.align-items-center {
+ align-items: center;
+}
+.columns:not(:last-child) {
+ margin-bottom: calc(1.5rem - 0.9rem);
+}
+.gap-5px {
+ gap: 5px;
+}
.text-green {
- color: green;
+ color: #009e00;
}
.text-violet {
color: #659bff;
@@ -97,9 +120,12 @@ input.is-narrow {
.text-red {
color: red;
}
-.d-inline-flex {
- display: inline-flex;
+.flex {
+ display: flex !important;
}
-.columns:not(:last-child) {
- margin-bottom: calc(1.5rem - 0.9rem);
+.align-center {
+ align-items: center;
+}
+.justify-center {
+ justify-content: center;
}
\ No newline at end of file
diff --git a/examples/vite-demo-vanilla-bundle/vite.config.mts b/examples/vite-demo-vanilla-bundle/vite.config.mts
index 3bfc9b9ea..e9d9d53be 100644
--- a/examples/vite-demo-vanilla-bundle/vite.config.mts
+++ b/examples/vite-demo-vanilla-bundle/vite.config.mts
@@ -10,11 +10,6 @@ export default defineConfig(() => {
chunkSizeWarningLimit: 6000,
emptyOutDir: true,
outDir: '../../website',
- rollupOptions: {
- external: [
- './node_modules/flatpickr/dist/l10n/fr',
- ],
- },
},
preview: {
port: 8888
diff --git a/lerna.json b/lerna.json
index 713424684..78ccdda00 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,6 +1,6 @@
{
"$schema": "node_modules/@lerna-lite/cli/schemas/lerna-schema.json",
- "version": "4.7.0",
+ "version": "5.0.0-beta.3",
"npmClient": "pnpm",
"loglevel": "info",
"command": {
@@ -20,6 +20,7 @@
"syncWorkspaceLock": true
}
},
+ "changelogPreset": "conventional-changelog-conventionalcommits",
"packages": [
"examples/*",
"packages/*"
diff --git a/package.json b/package.json
index 87584bc96..24d4ae41e 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
"preview:publish": "lerna publish from-package --dry-run --yes",
"preview:version": "lerna version --dry-run --yes",
"preview:roll-new-release": "pnpm bundle && pnpm new-version --dry-run && pnpm new-publish --dry-run",
+ "beta-release": "lerna publish 5.0.0-beta.2 --dist-tag beta",
"new-version": "lerna version",
"new-publish": "lerna publish from-package",
"roll-new-release": "pnpm bundle && pnpm new-version && pnpm new-publish",
@@ -58,6 +59,7 @@
"@4tw/cypress-drag-drop": "^2.2.5",
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
+ "@formkit/tempo": "^0.1.1",
"@jest/types": "^29.6.3",
"@lerna-lite/cli": "^3.3.3",
"@lerna-lite/publish": "^3.3.3",
@@ -65,6 +67,7 @@
"@lerna-lite/watch": "^3.3.3",
"@types/jest": "^29.5.12",
"@types/node": "^20.12.11",
+ "conventional-changelog-conventionalcommits": "^7.0.2",
"cross-env": "^7.0.3",
"cypress": "^13.9.0",
"cypress-real-events": "^1.12.0",
@@ -74,7 +77,6 @@
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jest": "^28.5.0",
"eslint-plugin-n": "^17.5.1",
- "flatpickr": "^4.6.13",
"husky": "^9.0.11",
"jest": "^29.7.0",
"jest-cli": "^29.7.0",
@@ -82,7 +84,6 @@
"jest-extended": "^4.0.2",
"jsdom": "^24.0.0",
"jsdom-global": "^3.0.2",
- "moment-mini": "^2.29.4",
"npm-run-all2": "^6.1.2",
"pnpm": "^8.15.8",
"rimraf": "^5.0.5",
diff --git a/packages/binding/CHANGELOG.md b/packages/binding/CHANGELOG.md
index 6fe9a4079..c2bfdeb1f 100644
--- a/packages/binding/CHANGELOG.md
+++ b/packages/binding/CHANGELOG.md
@@ -4,6 +4,20 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [5.0.0-beta.3](https://github.com/ghiscoding/slickgrid-universal/compare/v5.0.0-beta.2...v5.0.0-beta.3) (2024-05-09)
+
+**Note:** Version bump only for package @slickgrid-universal/binding
+
+## [5.0.0-beta.2](https://github.com/ghiscoding/slickgrid-universal/compare/v4.7.0...v5.0.0-beta.2) (2024-05-07)
+
+### ⚠ BREAKING CHANGES
+
+* **common:** migrate from Flatpickr to Vanilla-Calendar (#1466)
+
+### Features
+
+* **common:** migrate from Flatpickr to Vanilla-Calendar ([#1466](https://github.com/ghiscoding/slickgrid-universal/issues/1466)) ([fb6e950](https://github.com/ghiscoding/slickgrid-universal/commit/fb6e950f429b4abd868fca86d9c304580a745b1c)) - by @ghiscoding
+
# [4.7.0](https://github.com/ghiscoding/slickgrid-universal/compare/v4.6.3...v4.7.0) (2024-04-20)
**Note:** Version bump only for package @slickgrid-universal/binding
@@ -141,6 +155,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** package exports prop had invalid ESM import link ([#892](https://github.com/ghiscoding/slickgrid-universal/issues/892)) ([7f95f69](https://github.com/ghiscoding/slickgrid-universal/commit/7f95f698447f8178cb7ceec416c35f4957fddbe9)) - by @ghiscoding
+
* **deps:** update dependency dompurify to v3 ([#907](https://github.com/ghiscoding/slickgrid-universal/issues/907)) ([66c8b4d](https://github.com/ghiscoding/slickgrid-universal/commit/66c8b4d602d88d733070b2189468bf1b6508d7eb)) - by @renovate-bot
# [2.4.0](https://github.com/ghiscoding/slickgrid-universal/compare/v2.3.0...v2.4.0) (2023-02-04)
diff --git a/packages/binding/README.md b/packages/binding/README.md
index 6a26d9488..bae5f2a55 100644
--- a/packages/binding/README.md
+++ b/packages/binding/README.md
@@ -3,6 +3,7 @@
[![lerna--lite](https://img.shields.io/badge/maintained%20with-lerna--lite-e137ff)](https://github.com/ghiscoding/lerna-lite)
[![npm](https://img.shields.io/npm/v/@slickgrid-universal/binding.svg)](https://www.npmjs.com/package/@slickgrid-universal/binding)
[![npm](https://img.shields.io/npm/dy/@slickgrid-universal/binding)](https://www.npmjs.com/package/@slickgrid-universal/binding)
+[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/binding?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/binding)
[![Actions Status](https://github.com/ghiscoding/slickgrid-universal/workflows/CI%20Build/badge.svg)](https://github.com/ghiscoding/slickgrid-universal/actions)
[![Cypress.io](https://img.shields.io/badge/tested%20with-Cypress-04C38E.svg)](https://www.cypress.io/)
diff --git a/packages/binding/package.json b/packages/binding/package.json
index 089e7e1af..13cf5beab 100644
--- a/packages/binding/package.json
+++ b/packages/binding/package.json
@@ -1,6 +1,6 @@
{
"name": "@slickgrid-universal/binding",
- "version": "4.7.0",
+ "version": "5.0.0-beta.3",
"description": "Simple Vanilla Implementation of a Binding Engine & Helper to add properties/events 2 way bindings",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
diff --git a/packages/binding/src/bindingEvent.service.ts b/packages/binding/src/bindingEvent.service.ts
index 3e7450d04..c85217a95 100644
--- a/packages/binding/src/bindingEvent.service.ts
+++ b/packages/binding/src/bindingEvent.service.ts
@@ -18,7 +18,7 @@ export class BindingEventService {
}
/** Bind an event listener to any element */
- bind(elementOrElements: Element | NodeListOf | Window, eventNameOrNames: string | string[], listener: EventListenerOrEventListenerObject, listenerOptions?: boolean | AddEventListenerOptions, groupName = '') {
+ bind(elementOrElements: Document | Element | NodeListOf | Window, eventNameOrNames: string | string[], listener: EventListenerOrEventListenerObject, listenerOptions?: boolean | AddEventListenerOptions, groupName = '') {
// convert to array for looping in next task
const eventNames = (Array.isArray(eventNameOrNames)) ? eventNameOrNames : [eventNameOrNames];
diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md
index 176aed85d..fcb4655f9 100644
--- a/packages/common/CHANGELOG.md
+++ b/packages/common/CHANGELOG.md
@@ -4,19 +4,76 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [5.0.0-beta.3](https://github.com/ghiscoding/slickgrid-universal/compare/v5.0.0-beta.2...v5.0.0-beta.3) (2024-05-09)
+
+### Bug Fixes
+
+* **common:** consider target size when auto-position picker/modal ([#1517](https://github.com/ghiscoding/slickgrid-universal/issues/1517)) ([e3a70b8](https://github.com/ghiscoding/slickgrid-universal/commit/e3a70b810d04c963f48454b78053c1bd45f96ebf)) - by @ghiscoding
+* **common:** Select Editor should always close with Escape key ([#1512](https://github.com/ghiscoding/slickgrid-universal/issues/1512)) ([e37bb28](https://github.com/ghiscoding/slickgrid-universal/commit/e37bb281ee83c25e9c4e15930e06bf9a044c65e9)) - by @ghiscoding
+* **core:** tweak setupColumnSort() to fix exception with hidden col ([#1509](https://github.com/ghiscoding/slickgrid-universal/issues/1509)) ([94b836a](https://github.com/ghiscoding/slickgrid-universal/commit/94b836a025ecb19b72f439079382280740b51027)) - by @ghiscoding
+* **editors:** body click or Escape key should cancel Select Editor ([#1513](https://github.com/ghiscoding/slickgrid-universal/issues/1513)) ([3d765a9](https://github.com/ghiscoding/slickgrid-universal/commit/3d765a9d282b684c38c550a1e5736cb1b2132f8e)) - by @ghiscoding
+* make some more cleanup with now optional DOMPurify ([#1508](https://github.com/ghiscoding/slickgrid-universal/issues/1508)) ([7fafbcc](https://github.com/ghiscoding/slickgrid-universal/commit/7fafbcc21fccfcd83d3ab103f313398c9d4b82e2)) - by @ghiscoding
+* **plugins:** clicking a grid cell should close any open menu ([#1515](https://github.com/ghiscoding/slickgrid-universal/issues/1515)) ([383792d](https://github.com/ghiscoding/slickgrid-universal/commit/383792d389e56239d62874842a50ec838f0bd3e9)) - by @ghiscoding
+* **styling:** improve UI & fix small issues found after testing upstream ([#1510](https://github.com/ghiscoding/slickgrid-universal/issues/1510)) ([a4ef70f](https://github.com/ghiscoding/slickgrid-universal/commit/a4ef70f70953c13f7abb0075586439931f18af74)) - by @ghiscoding
+* **tooltip:** only show tooltip that has value ([#1511](https://github.com/ghiscoding/slickgrid-universal/issues/1511)) ([2ff15da](https://github.com/ghiscoding/slickgrid-universal/commit/2ff15da4a21cd98b63f251b9b248454658dac698)) - by @ghiscoding
+
+## [5.0.0-beta.2](https://github.com/ghiscoding/slickgrid-universal/compare/v4.7.0...v5.0.0-beta.2) (2024-05-07)
+
+### ⚠ BREAKING CHANGES
+
+* migrate from Moment to Tempo (#1507)
+* **common:** make DOMPurify as optional sanitizer grid option (#1503)
+* **styling:** delete "bare" Themes but keep "lite" & add to Bootstrap (#1493)
+* **common:** migrate from `moment` to `moment-tiny` (#1456)
+* **filters:** remove native `Filters.select` (#1485)
+* **styling:** delete `checkmarkFormatter` and any Font-Awesome related (#1484)
+* **common:** migrate from Flatpickr to Vanilla-Calendar (#1466)
+* **styling:** remove SASS `math.div` polyfill (#1483)
+* **styling:** convert SVG icons to pure CSS (#1474)
+
+### Features
+
+* **common:** make DOMPurify as optional sanitizer grid option ([#1503](https://github.com/ghiscoding/slickgrid-universal/issues/1503)) ([0aa0859](https://github.com/ghiscoding/slickgrid-universal/commit/0aa085955f81303c0193fbdcd36ff220263814e3)) - by @ghiscoding
+* **common:** migrate from `moment` to `moment-tiny` ([#1456](https://github.com/ghiscoding/slickgrid-universal/issues/1456)) ([90690f4](https://github.com/ghiscoding/slickgrid-universal/commit/90690f4b6a4c8f8a7a221ddc1df69077384f48a9)) - by @ghiscoding
+* **common:** migrate from Flatpickr to Vanilla-Calendar ([#1466](https://github.com/ghiscoding/slickgrid-universal/issues/1466)) ([fb6e950](https://github.com/ghiscoding/slickgrid-universal/commit/fb6e950f429b4abd868fca86d9c304580a745b1c)) - by @ghiscoding
+* **filters:** remove native `Filters.select` ([#1485](https://github.com/ghiscoding/slickgrid-universal/issues/1485)) ([fae4c4a](https://github.com/ghiscoding/slickgrid-universal/commit/fae4c4a199409cec40ebb2703b6ae6d0d14e4af7)) - by @ghiscoding
+* migrate from Moment to Tempo ([#1507](https://github.com/ghiscoding/slickgrid-universal/issues/1507)) ([adef47f](https://github.com/ghiscoding/slickgrid-universal/commit/adef47f21a0e32bd32ec4efce931770dc252d3b5)) - by @ghiscoding
+* **styling:** convert SVG icons to pure CSS ([#1474](https://github.com/ghiscoding/slickgrid-universal/issues/1474)) ([70cda8a](https://github.com/ghiscoding/slickgrid-universal/commit/70cda8aa9304ac8ea4bab06390dc1b4c4423df2e)) - by @ghiscoding
+* **styling:** delete "bare" Themes but keep "lite" & add to Bootstrap ([#1493](https://github.com/ghiscoding/slickgrid-universal/issues/1493)) ([ca5ac06](https://github.com/ghiscoding/slickgrid-universal/commit/ca5ac0663c1670f9e9af1f88d6f6c85e9e064359)) - by @ghiscoding
+* **styling:** delete `checkmarkFormatter` and any Font-Awesome related ([#1484](https://github.com/ghiscoding/slickgrid-universal/issues/1484)) ([2de3fe2](https://github.com/ghiscoding/slickgrid-universal/commit/2de3fe2d07a14225a31fbc77e72c47895de664d6)) - by @ghiscoding
+* **styling:** remove SASS `math.div` polyfill ([#1483](https://github.com/ghiscoding/slickgrid-universal/issues/1483)) ([12661a3](https://github.com/ghiscoding/slickgrid-universal/commit/12661a3ff13ea844f6e16028216e1ed8808ee4d9)) - by @ghiscoding
+
+### Bug Fixes
+
+* **core:** col name from HTML shouldn't disappear in picker, fixes [#1475](https://github.com/ghiscoding/slickgrid-universal/issues/1475) ([#1476](https://github.com/ghiscoding/slickgrid-universal/issues/1476)) ([15a590b](https://github.com/ghiscoding/slickgrid-universal/commit/15a590b2e52f8864aeccc38f9a708c0453b6e4a6)) - by @ghiscoding
+* **editor:** autocomplete should only save empty when val is null ([#1500](https://github.com/ghiscoding/slickgrid-universal/issues/1500)) ([8de1340](https://github.com/ghiscoding/slickgrid-universal/commit/8de13402d244cb3aa2fcdb4af62e05b06f6cb27c)) - by @ghiscoding
+* **editor:** input editor should call save on focusout or blur of input ([#1497](https://github.com/ghiscoding/slickgrid-universal/issues/1497)) ([ccd344e](https://github.com/ghiscoding/slickgrid-universal/commit/ccd344ecd2e6abcff1d7b9f5e7d7fe85a4c20fdd)) - by @ghiscoding
+* **editor:** new Date Editor input clear button wasn't working ([#1487](https://github.com/ghiscoding/slickgrid-universal/issues/1487)) ([4ac34ee](https://github.com/ghiscoding/slickgrid-universal/commit/4ac34ee6d95398c77f10f89b0ad4c3168765b6a0)) - by @ghiscoding
+* **styling:** couple of small alignment issues when using flex ([#1496](https://github.com/ghiscoding/slickgrid-universal/issues/1496)) ([2188242](https://github.com/ghiscoding/slickgrid-universal/commit/21882420eb9c31b7922038fa45f373d42e2fb35f)) - by @ghiscoding
+* **styling:** empty warning should separate icon & text ([#1491](https://github.com/ghiscoding/slickgrid-universal/issues/1491)) ([240cbd3](https://github.com/ghiscoding/slickgrid-universal/commit/240cbd3b5a8cfb6a6cab563bc43d705332d59beb)) - by @ghiscoding
+* **styling:** properly import Vanilla-Calendar CSS and only once ([#1492](https://github.com/ghiscoding/slickgrid-universal/issues/1492)) ([75dce74](https://github.com/ghiscoding/slickgrid-universal/commit/75dce746659796f7d1c21e5ebcfd0418588df4c0)) - by @ghiscoding
+* **styling:** Row Move icon shouldn't show extra dot ([69f7bfc](https://github.com/ghiscoding/slickgrid-universal/commit/69f7bfcb7eb078815f5edb6d84d53c0905df27a1)) - by @ghiscoding-SE
+* **tooltip:** don't sanitize empty text, fixes empty tooltip being shown ([#1495](https://github.com/ghiscoding/slickgrid-universal/issues/1495)) ([dcc693b](https://github.com/ghiscoding/slickgrid-universal/commit/dcc693b26677873b93ccb770ff8ef9a514085341)) - by @ghiscoding
+* tweak setupColumnSort() to fix exception when col no longer exists ([#1477](https://github.com/ghiscoding/slickgrid-universal/issues/1477)) ([094d760](https://github.com/ghiscoding/slickgrid-universal/commit/094d7602d7170b2f395985ce5635041bb2b803d2)) - by @ghiscoding
+
# [4.7.0](https://github.com/ghiscoding/slickgrid-universal/compare/v4.6.3...v4.7.0) (2024-04-20)
### Bug Fixes
* **common:** don't try to strip tags on object input to calc cell width ([#1453](https://github.com/ghiscoding/slickgrid-universal/issues/1453)) ([5ab671b](https://github.com/ghiscoding/slickgrid-universal/commit/5ab671bee805f7b7d9b139e9bf7a14b31b5aea56)) - by @ghiscoding
+
* **common:** switch back to `autocompleter` with ESM build ([#1450](https://github.com/ghiscoding/slickgrid-universal/issues/1450)) ([ad66a12](https://github.com/ghiscoding/slickgrid-universal/commit/ad66a121b4a6b7718009948d873ceb8f5c66a32c)) - by @ghiscoding
+
* **core:** Editor.keyCaptureList is an array of numbers ([#1458](https://github.com/ghiscoding/slickgrid-universal/issues/1458)) ([62a686e](https://github.com/ghiscoding/slickgrid-universal/commit/62a686e7db4dc4ef65d0c426c8623dc8f1e3f9d9)) - by @ghiscoding
+
* **styling:** improve button & text colors for Dark Mode ([9414ab4](https://github.com/ghiscoding/slickgrid-universal/commit/9414ab4e24482d080f3113d32d96fe635856a871)) - by @ghiscoding-SE
### Features
* **common:** add global `defaultEditorOptions` & `defaultFilterOptions` ([#1470](https://github.com/ghiscoding/slickgrid-universal/issues/1470)) ([0462f17](https://github.com/ghiscoding/slickgrid-universal/commit/0462f17b215d5c1b88e1a9fe482877ed733486b3)) - by @ghiscoding
+
* **core:** add `getFilterArgs()` to `SlickDataView` ([#1457](https://github.com/ghiscoding/slickgrid-universal/issues/1457)) ([7563126](https://github.com/ghiscoding/slickgrid-universal/commit/7563126cfbf792fc86a494850e5a3bad7d8991f7)) - by @ghiscoding
+
* notify onValidationError on paste if validation failed ([#1462](https://github.com/ghiscoding/slickgrid-universal/issues/1462)) ([38b465c](https://github.com/ghiscoding/slickgrid-universal/commit/38b465cb8ebcdd6012b939677a4367c2dce010e9)) - by @zewa666
## [4.6.1](https://github.com/ghiscoding/slickgrid-universal/compare/v4.6.0...v4.6.1) (2024-03-31)
@@ -24,11 +81,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** move DOMPurify/SortableJS [@types](https://github.com/types) as dependencies ([51eaec7](https://github.com/ghiscoding/slickgrid-universal/commit/51eaec756120c93f0fbb9ed58b5784025b808e59)) - by @ghiscoding
+
* **common:** switch to `autocompleter-es` to get ESM build ([#1449](https://github.com/ghiscoding/slickgrid-universal/issues/1449)) ([aa59334](https://github.com/ghiscoding/slickgrid-universal/commit/aa59334d280d76078bc9cf36e66daa0bd4c6fac1)) - by @ghiscoding
+
* improve Dark Mode styling for icons barely visible in dark ([16b1a6e](https://github.com/ghiscoding/slickgrid-universal/commit/16b1a6e52bec83ed25bca077fe2ea30b5966f3ab)) - by @ghiscoding
+
* **pubsub:** externalize PubSub event to SlickEventData to stop bubbling ([#1444](https://github.com/ghiscoding/slickgrid-universal/issues/1444)) ([973d0ab](https://github.com/ghiscoding/slickgrid-universal/commit/973d0abb0a4df050ad68a6c7e6493bf7ae4abd52)) - by @ghiscoding
+
* revisit package `exports` to pass "are the types wrong" ([#1440](https://github.com/ghiscoding/slickgrid-universal/issues/1440)) ([20229f7](https://github.com/ghiscoding/slickgrid-universal/commit/20229f78adef51078f99fce3f5a46ac88280a048)) - by @ghiscoding
+
* **styling:** missing/too many borders compound filters w/group addon ([#1446](https://github.com/ghiscoding/slickgrid-universal/issues/1446)) ([863933f](https://github.com/ghiscoding/slickgrid-universal/commit/863933f8cd1988f5ae1b387839a99532cd58d92d)) - by @ghiscoding
+
* **tooltip:** allow multiple tooltips per grid cell ([#1448](https://github.com/ghiscoding/slickgrid-universal/issues/1448)) ([061c4a0](https://github.com/ghiscoding/slickgrid-universal/commit/061c4a087484238f7285eb27a1c238ac75972f19)) - by @ghiscoding
# [4.6.0](https://github.com/ghiscoding/slickgrid-universal/compare/v4.5.0...v4.6.0) (2024-03-23)
@@ -36,21 +99,33 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* `column.editor` and `gridOptions.editorFactory` type changed ([#1428](https://github.com/ghiscoding/slickgrid-universal/issues/1428)) ([bf8c5b9](https://github.com/ghiscoding/slickgrid-universal/commit/bf8c5b95aca22bced0d926d6ac118c9fa0e61411)) - by @ghiscoding
+
* **build:** add ESLint-TS rules to enforce `type` imports and exports ([#1432](https://github.com/ghiscoding/slickgrid-universal/issues/1432)) ([cce4693](https://github.com/ghiscoding/slickgrid-universal/commit/cce4693556e01d7f664fbe832ae4e7fd5776dc6b)) - by @ghiscoding
+
* **common:** add missing Filter `model` Type of `FilterConstructor` ([#1430](https://github.com/ghiscoding/slickgrid-universal/issues/1430)) ([3f3e952](https://github.com/ghiscoding/slickgrid-universal/commit/3f3e952b20b41dda5bf2cd1648c6d6f02e7c7943)) - by @ghiscoding
+
* **common:** bump ms-select to fix compatibility problem in Salesforce ([#1425](https://github.com/ghiscoding/slickgrid-universal/issues/1425)) ([d3d2d39](https://github.com/ghiscoding/slickgrid-universal/commit/d3d2d390a8a1b17d0cd3699ddebfea855fdc5f77)) - by @ghiscoding
+
* **common:** Select All checkbox shouldn't disappear w/Dark Mode toggle ([#1421](https://github.com/ghiscoding/slickgrid-universal/issues/1421)) ([5fab179](https://github.com/ghiscoding/slickgrid-universal/commit/5fab1792cfdf24172bd46556b6fe5513c93d19d1)) - by @ghiscoding
+
* Join type ([#1427](https://github.com/ghiscoding/slickgrid-universal/issues/1427)) ([21c76cc](https://github.com/ghiscoding/slickgrid-universal/commit/21c76cc9d921ad34516bd38070afd791ff55de56)) - by @zewa666
+
* **styling:** add border & box-shadow to Flatpickr in Dark Mode ([fdbb6ae](https://github.com/ghiscoding/slickgrid-universal/commit/fdbb6ae9de7069968af747240a9b2ad74b0c8184)) - by @ghiscoding
+
* **styling:** add missing orange border for Salesforce modified inputs ([e830dd3](https://github.com/ghiscoding/slickgrid-universal/commit/e830dd3df4c6c0176ac88304247571f5ef05d4ef)) - by @ghiscoding
+
* **styling:** add more visual cue for column picker uncheck row select ([b4712e9](https://github.com/ghiscoding/slickgrid-universal/commit/b4712e9a8c03b60457d9033f11affb7364231de2)) - by @ghiscoding
+
* **styling:** don't add filled border all side for group-addon btn ([30be835](https://github.com/ghiscoding/slickgrid-universal/commit/30be8353101157a00440dba0357f88879bd3acda)) - by @ghiscoding-SE
+
* **styling:** small Composite Editor fixes for Dark Mode ([#1417](https://github.com/ghiscoding/slickgrid-universal/issues/1417)) ([7e00087](https://github.com/ghiscoding/slickgrid-universal/commit/7e000877a85059e23d3aa4c00c04d0e4e1e0abc1)) - by @ghiscoding
### Features
* **common:** add optional "Toggle Dark Mode" in Grid Menu ([#1418](https://github.com/ghiscoding/slickgrid-universal/issues/1418)) ([990c1df](https://github.com/ghiscoding/slickgrid-universal/commit/990c1df2a39a6b5098c991b16f43c5679daf4bb5)) - by @ghiscoding
+
* **core:** rename SG `editorClass` & deprecate `internalColumnEditor` ([#1429](https://github.com/ghiscoding/slickgrid-universal/issues/1429)) ([409115c](https://github.com/ghiscoding/slickgrid-universal/commit/409115cecb132556e88abf6e281f4fcb52414d71)) - by @ghiscoding
+
* upgrade to ms-select-vanilla v3.x ([#1439](https://github.com/ghiscoding/slickgrid-universal/issues/1439)) ([8f2378e](https://github.com/ghiscoding/slickgrid-universal/commit/8f2378e6cfed3489ce487fe84947bdabd04e31d2)) - by @ghiscoding
# [4.5.0](https://github.com/ghiscoding/slickgrid-universal/compare/v4.4.1...v4.5.0) (2024-03-05)
@@ -58,22 +133,35 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* auto-resize not just grid but also headers for Salesforce tabs ([#1395](https://github.com/ghiscoding/slickgrid-universal/issues/1395)) ([6180461](https://github.com/ghiscoding/slickgrid-universal/commit/6180461b543cb7d4cc14d1504cb0db7d35990164)) - by @ghiscoding
+
* **common:** switch to `isomorphic-dompurify` for SSR support ([#1413](https://github.com/ghiscoding/slickgrid-universal/issues/1413)) ([b619453](https://github.com/ghiscoding/slickgrid-universal/commit/b619453fd9825500f2d9589e31bdcf5e17ac412d)), closes [/github.com/ghiscoding/Angular-Slickgrid/discussions/838#discussioncomment-8574215](https://github.com//github.com/ghiscoding/Angular-Slickgrid/discussions/838/issues/discussioncomment-8574215) - by @ghiscoding
+
* **core:** add extra checks for some objects to be a bit more strict ([#1404](https://github.com/ghiscoding/slickgrid-universal/issues/1404)) ([8b95c50](https://github.com/ghiscoding/slickgrid-universal/commit/8b95c505ed2409cde7b790f97b4fbc0d666ca459)) - by @ghiscoding
+
* **plugin:** the RowMove plugin cell should be selectable ([#1408](https://github.com/ghiscoding/slickgrid-universal/issues/1408)) ([8c01a13](https://github.com/ghiscoding/slickgrid-universal/commit/8c01a1361898fe3f3b6cfdba3239f93f2e8acec9)) - by @ghiscoding
+
* **styling:** add full width to grid container ([#1409](https://github.com/ghiscoding/slickgrid-universal/issues/1409)) ([eedc162](https://github.com/ghiscoding/slickgrid-universal/commit/eedc162e243b3c0bbf450bd404b199f5ee511926)) - by @ghiscoding
+
* **styling:** add menu shadow & increase contrast for Dark Mode ([bff2da0](https://github.com/ghiscoding/slickgrid-universal/commit/bff2da0dd027103c30fa86635b9e45460b10e700)) - by @ghiscoding
+
* **styling:** ms-select filter should use same color as other filters ([#1396](https://github.com/ghiscoding/slickgrid-universal/issues/1396)) ([a30d590](https://github.com/ghiscoding/slickgrid-universal/commit/a30d59066419d2c3324718f1d5497e8e89ebf749)) - by @ghiscoding
+
* **styling:** ms-select highlight bg-color same as nav highlight ([fe77341](https://github.com/ghiscoding/slickgrid-universal/commit/fe77341645f72be6c03a8e210dc08e6d0ef131d4)) - by @ghiscoding-SE
+
* **styling:** properly align flexbox ms-select icon+text vertically ([#1397](https://github.com/ghiscoding/slickgrid-universal/issues/1397)) ([e744d02](https://github.com/ghiscoding/slickgrid-universal/commit/e744d0256d25ba6ad5d538b827460828b6e0666f)) - by @ghiscoding
+
* **styling:** remove header menu open class for Dark Mode ([6a2e7e1](https://github.com/ghiscoding/slickgrid-universal/commit/6a2e7e13a18921c2b70caeb2690298173310aece)) - by @ghiscoding
+
* **styling:** tweak Composite Editor form disabled buttons style ([5052ba1](https://github.com/ghiscoding/slickgrid-universal/commit/5052ba19858ff2bced69f0846e00bbb36c9d0fde)) - by @ghiscoding
### Features
* **common:** upgrade `multiple-select-vanilla` to v2 ([#1401](https://github.com/ghiscoding/slickgrid-universal/issues/1401)) ([d6bb1d7](https://github.com/ghiscoding/slickgrid-universal/commit/d6bb1d7ef76100268456b2ab499c496a78debdd8)) - by @ghiscoding
+
* **deps:** simplify package TS Types exports ([#1402](https://github.com/ghiscoding/slickgrid-universal/issues/1402)) ([19bac52](https://github.com/ghiscoding/slickgrid-universal/commit/19bac52e5fcb8e523a26ab1f6564f0b6a2b93ef4)) - by @ghiscoding
+
* **editor:** add `onRendered` lifecycle callback option ([#1410](https://github.com/ghiscoding/slickgrid-universal/issues/1410)) ([9d348d6](https://github.com/ghiscoding/slickgrid-universal/commit/9d348d6e4b693e23a2959917e02a7bcfa55a0c90)) - by @ghiscoding
+
* **styling:** add Dark Mode grid option ([#1407](https://github.com/ghiscoding/slickgrid-universal/issues/1407)) ([855151b](https://github.com/ghiscoding/slickgrid-universal/commit/855151b9f47a5238e3069f8c85ba4ed8a5bf9bb6)) - by @ghiscoding
## [4.4.1](https://github.com/ghiscoding/slickgrid-universal/compare/v4.3.1...v4.4.1) (2024-02-13)
@@ -81,8 +169,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** replace `any` types by valid types ([#1378](https://github.com/ghiscoding/slickgrid-universal/issues/1378)) ([02c4bc1](https://github.com/ghiscoding/slickgrid-universal/commit/02c4bc15e0da31c055c0fac9eecb7c4a17df3eb7)) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#1381](https://github.com/ghiscoding/slickgrid-universal/issues/1381)) ([2562352](https://github.com/ghiscoding/slickgrid-universal/commit/25623527d05dd713123e1031b682f0a80cca37de)) - by @renovate-bot
+
* mouse cell selection with active editor ([#1382](https://github.com/ghiscoding/slickgrid-universal/issues/1382)) ([17549b8](https://github.com/ghiscoding/slickgrid-universal/commit/17549b89933b10688fe8d186ab18ab4c8b7e9f87)) - by @zewa666
+
* **publish:** do not npm publish `tsconfig.tsbuildinfo` ([#1373](https://github.com/ghiscoding/slickgrid-universal/issues/1373)) ([9223338](https://github.com/ghiscoding/slickgrid-universal/commit/922333843852ae861015e4bbec053d4937222aa2)) - by @ghiscoding
### Features
@@ -94,8 +185,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** replace `any` types by valid types ([#1378](https://github.com/ghiscoding/slickgrid-universal/issues/1378)) ([02c4bc1](https://github.com/ghiscoding/slickgrid-universal/commit/02c4bc15e0da31c055c0fac9eecb7c4a17df3eb7)) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#1381](https://github.com/ghiscoding/slickgrid-universal/issues/1381)) ([2562352](https://github.com/ghiscoding/slickgrid-universal/commit/25623527d05dd713123e1031b682f0a80cca37de)) - by @renovate-bot
+
* mouse cell selection with active editor ([#1382](https://github.com/ghiscoding/slickgrid-universal/issues/1382)) ([17549b8](https://github.com/ghiscoding/slickgrid-universal/commit/17549b89933b10688fe8d186ab18ab4c8b7e9f87)) - by @zewa666
+
* **publish:** do not npm publish `tsconfig.tsbuildinfo` ([#1373](https://github.com/ghiscoding/slickgrid-universal/issues/1373)) ([9223338](https://github.com/ghiscoding/slickgrid-universal/commit/922333843852ae861015e4bbec053d4937222aa2)) - by @ghiscoding
### Features
@@ -107,13 +201,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** frozen grid w/hidden column should remove from DOM ([#1372](https://github.com/ghiscoding/slickgrid-universal/issues/1372)) ([2c1346e](https://github.com/ghiscoding/slickgrid-universal/commit/2c1346e53e0e5cba57c949f7b70d2b20d3dc1d22)) - by @ghiscoding
+
* **styling:** remove different bg-color on unorderable column ([#1358](https://github.com/ghiscoding/slickgrid-universal/issues/1358)) ([91426d1](https://github.com/ghiscoding/slickgrid-universal/commit/91426d1f6801680a5c40b3b900ab1a64cd771277)) - by @ghiscoding
### Performance Improvements
* **core:** convert `for..in` to `Object.keys().forEach` for better perf ([#1370](https://github.com/ghiscoding/slickgrid-universal/issues/1370)) ([29111a9](https://github.com/ghiscoding/slickgrid-universal/commit/29111a94756c34a2e01f2431c14b7ed806349a94)) - by @ghiscoding
+
* decrease calls to setItems & grid invalidate ([#1363](https://github.com/ghiscoding/slickgrid-universal/issues/1363)) ([cab6898](https://github.com/ghiscoding/slickgrid-universal/commit/cab68989ebd53178dfcee5ed293379dc8932a72f)) - by @ghiscoding
+
* **plugins:** decrease number of calls to translate all extensions only once ([#1359](https://github.com/ghiscoding/slickgrid-universal/issues/1359)) ([3e002f1](https://github.com/ghiscoding/slickgrid-universal/commit/3e002f15a06abd06893783e0667798f5ff8893cf)) - by @ghiscoding
+
* **plugins:** Row Base Editing tooltip title should be translated only once ([#1360](https://github.com/ghiscoding/slickgrid-universal/issues/1360)) ([ef4e8f9](https://github.com/ghiscoding/slickgrid-universal/commit/ef4e8f9f4bf491d670986c6dac8531274aaaa46b)) - by @ghiscoding
# [4.3.0](https://github.com/ghiscoding/slickgrid-universal/compare/v4.2.0...v4.3.0) (2024-01-20)
@@ -121,30 +219,51 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* `getCellFromPoint()` should return row/cell -1 outside grid canvas ([#1325](https://github.com/ghiscoding/slickgrid-universal/issues/1325)) ([b483e62](https://github.com/ghiscoding/slickgrid-universal/commit/b483e62fc3931f836c77677db67557adb2ca4edd)) - by @ghiscoding
+
* add grid & cell `role` for screen ready accessibility ([#1337](https://github.com/ghiscoding/slickgrid-universal/issues/1337)) ([7309fa8](https://github.com/ghiscoding/slickgrid-universal/commit/7309fa8de4fc00f930e68af090010d91080b6213)) - by @ghiscoding
+
* **core:** allow extra spaces in `headerCssClass` & other `cssClass` ([#1303](https://github.com/ghiscoding/slickgrid-universal/issues/1303)) ([59ebaa6](https://github.com/ghiscoding/slickgrid-universal/commit/59ebaa65b6882ed3274a3185f457ecef4b2c5b51)) - by @ghiscoding
+
* **core:** allow extra spaces to be striped to any css classes ([#1352](https://github.com/ghiscoding/slickgrid-universal/issues/1352)) ([e5e29c0](https://github.com/ghiscoding/slickgrid-universal/commit/e5e29c063a9e018c2148685cfea5fc43c89426b9)) - by @ghiscoding
+
* **core:** column resize handle could throw when invalid elm ([#1344](https://github.com/ghiscoding/slickgrid-universal/issues/1344)) ([41f6058](https://github.com/ghiscoding/slickgrid-universal/commit/41f60583831b7284cba56f2af9cfe45b4a09d617)) - by @ghiscoding
+
* **core:** DataView `inlineFilters` should allow ES6 arrow functions ([#1304](https://github.com/ghiscoding/slickgrid-universal/issues/1304)) ([25b9a10](https://github.com/ghiscoding/slickgrid-universal/commit/25b9a10fdd14585f1b303361b2814e860c6e7031)) - by @ghiscoding
+
* **core:** don't show column header empty title tooltip ([#1317](https://github.com/ghiscoding/slickgrid-universal/issues/1317)) ([8b20407](https://github.com/ghiscoding/slickgrid-universal/commit/8b2040754f1810191fb26f0a5a91a19eae13ebfd)) - by @ghiscoding
+
* **core:** EventHandler subscribed event should be SlickEventData type ([#1327](https://github.com/ghiscoding/slickgrid-universal/issues/1327)) ([2573310](https://github.com/ghiscoding/slickgrid-universal/commit/25733102dbcefcbacc2ce5d6f4c07bd9d1cce6a1)) - by @ghiscoding
+
* **core:** remove editor keydown keyCaptureList duplicate code ([#1322](https://github.com/ghiscoding/slickgrid-universal/issues/1322)) ([c5f6b85](https://github.com/ghiscoding/slickgrid-universal/commit/c5f6b8575513aa6eb0215a47a0365fdab0059c3e)) - by @ghiscoding
+
* **core:** SlickEvent handler event should be type of ArgType ([#1328](https://github.com/ghiscoding/slickgrid-universal/issues/1328)) ([a9cb8ee](https://github.com/ghiscoding/slickgrid-universal/commit/a9cb8ee3f1a5da4249851e5b701b027b3f72ad26)), closes [#1327](https://github.com/ghiscoding/slickgrid-universal/issues/1327) - by @ghiscoding
+
* Editors/Filters should create SlickEventData with event arg ([#1326](https://github.com/ghiscoding/slickgrid-universal/issues/1326)) ([e008902](https://github.com/ghiscoding/slickgrid-universal/commit/e008902e6d85a7a424ed8c9e32786490daac66ce)) - by @ghiscoding
+
* **plugin:** CustomDataView for CellSelectionModel & SlickCustomTooltip ([#1306](https://github.com/ghiscoding/slickgrid-universal/issues/1306)) ([3bdd300](https://github.com/ghiscoding/slickgrid-universal/commit/3bdd30038b93af2db1f2f4a8b7df72ca6a06a06e)) - by @ghiscoding
+
* regression with `onSelectedRowsChanged` not receiving correct `caller` prop ([#1341](https://github.com/ghiscoding/slickgrid-universal/issues/1341)) ([03cad4a](https://github.com/ghiscoding/slickgrid-universal/commit/03cad4a34bf13a8e1342306f9210525f5025321f)) - by @ghiscoding
+
* SlickEmptyWarningComponent should accept native HTML for CSP safe ([#1333](https://github.com/ghiscoding/slickgrid-universal/issues/1333)) ([4740f96](https://github.com/ghiscoding/slickgrid-universal/commit/4740f961813666cbae918cb4940e7c2ec57bec2d)) - by @ghiscoding
+
* when `onDragInit` return false it should stop ([#1340](https://github.com/ghiscoding/slickgrid-universal/issues/1340)) ([d9c714c](https://github.com/ghiscoding/slickgrid-universal/commit/d9c714c042739d5cbdbe51b876f16a3152d200e6)), closes [#1339](https://github.com/ghiscoding/slickgrid-universal/issues/1339) - by @ghiscoding
+
* when `onResizeStart` return false it should stop ([#1339](https://github.com/ghiscoding/slickgrid-universal/issues/1339)) ([5a3bd1c](https://github.com/ghiscoding/slickgrid-universal/commit/5a3bd1c0c6a19294fe6578766d6b2d56ac8e2cac)) - by @ghiscoding
### Features
* add `name` option to CheckboxSelectColumn plugin on columDef ([#1331](https://github.com/ghiscoding/slickgrid-universal/issues/1331)) ([abe344b](https://github.com/ghiscoding/slickgrid-universal/commit/abe344b025b385630077bfb63d5534a88b3b7d71)) - by @ghiscoding
+
* add `onBeforePasteCell` event to excel copy buffer ([#1298](https://github.com/ghiscoding/slickgrid-universal/issues/1298)) ([22037ca](https://github.com/ghiscoding/slickgrid-universal/commit/22037ca7918fc4bfb55bb4bf619cd280b564a351)) - by @zewa666
+
* add column `reorderable` option to optionally lock a column ([#1357](https://github.com/ghiscoding/slickgrid-universal/issues/1357)) ([44f6c08](https://github.com/ghiscoding/slickgrid-universal/commit/44f6c085f009ec41bec711aa14ae7fbb3fcbc156)) - by @ghiscoding
+
* convert CheckSelectColumn plugin to native HTML for CSP safe code ([#1332](https://github.com/ghiscoding/slickgrid-universal/issues/1332)) ([2b9216d](https://github.com/ghiscoding/slickgrid-universal/commit/2b9216df3e1796ffb4081127cdaa9011e4d48b23)) - by @ghiscoding
+
* **core:** expose all SlickEvent via internal PubSub Service ([#1311](https://github.com/ghiscoding/slickgrid-universal/issues/1311)) ([f56edef](https://github.com/ghiscoding/slickgrid-universal/commit/f56edef91b76ab044134ddf36d67599e6d80f39c)) - by @ghiscoding
+
* **editor:** auto commit before save; add `onBeforeEditMode` callback ([#1353](https://github.com/ghiscoding/slickgrid-universal/issues/1353)) ([f33bf52](https://github.com/ghiscoding/slickgrid-universal/commit/f33bf5202e0db30121bf52ce184555f6524dde85)) - by @zewa666
+
* **plugin:** new Row Based Editor ([#1323](https://github.com/ghiscoding/slickgrid-universal/issues/1323)) ([64d464c](https://github.com/ghiscoding/slickgrid-universal/commit/64d464c2094c014024ddeaf49bd4f6ec898b1c25)) - by @zewa666
### Performance Improvements
@@ -156,17 +275,25 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* `updateColumns()` should be public use with column hidden ([#1288](https://github.com/ghiscoding/slickgrid-universal/issues/1288)) ([211180b](https://github.com/ghiscoding/slickgrid-universal/commit/211180b8c1f32250e6fc7a559baaa203154473e0)) - by @ghiscoding
+
* applyDefaults use provided grid options before applying defaults ([#1283](https://github.com/ghiscoding/slickgrid-universal/issues/1283)) ([7fc772f](https://github.com/ghiscoding/slickgrid-universal/commit/7fc772fb80a80e0eafa900fc688667d12e1f9429)) - by @ghiscoding
+
* **core:** `SlickGroupItemMetadataProvider` should implements `SlickPlugin` ([#1294](https://github.com/ghiscoding/slickgrid-universal/issues/1294)) ([5aac2b6](https://github.com/ghiscoding/slickgrid-universal/commit/5aac2b6a37cdd21938fa54769b72ce317562e45d)) - by @ghiscoding
+
* **core:** add missing option to control row highlight duration after CRUD ([#1278](https://github.com/ghiscoding/slickgrid-universal/issues/1278)) ([8240c8c](https://github.com/ghiscoding/slickgrid-universal/commit/8240c8c9710f4e5d902ec9961f6a721ae0f84f7f)) - by @ghiscoding
+
* GroupingGetterFunction should be allowed to return arbitrary value ([#1296](https://github.com/ghiscoding/slickgrid-universal/issues/1296)) ([3807116](https://github.com/ghiscoding/slickgrid-universal/commit/38071168e0fe5eea7d5e1ee117fae98c09057a4c)) - by @ghiscoding
+
* **RowDetail:** sort change should collapse all Row Detail ([#1284](https://github.com/ghiscoding/slickgrid-universal/issues/1284)) ([21f6031](https://github.com/ghiscoding/slickgrid-universal/commit/21f60310a402dd12c80bf4553588c6cd777a131a)) - by @ghiscoding
+
* use correct argument type on `setData()` ([#1287](https://github.com/ghiscoding/slickgrid-universal/issues/1287)) ([0b0b86c](https://github.com/ghiscoding/slickgrid-universal/commit/0b0b86c2325ea2a11b74d8fe8debeb02e23bb014)) - by @ghiscoding
### Features
* (re)add option to cancel Row Detail opening ([#1286](https://github.com/ghiscoding/slickgrid-universal/issues/1286)) ([f08925c](https://github.com/ghiscoding/slickgrid-universal/commit/f08925c50c1dd18448a04a55c8303736e3cc2289)) - by @ghiscoding
+
* datasetIdPropertyName respected in newRowCreator ([#1279](https://github.com/ghiscoding/slickgrid-universal/issues/1279)) ([9d60a9d](https://github.com/ghiscoding/slickgrid-universal/commit/9d60a9d82e605ae2351822c66ff8757349b906cf)) - by @zewa666
+
* make DataView Grouping `compileAccumulatorLoop` CSP safe ([#1295](https://github.com/ghiscoding/slickgrid-universal/issues/1295)) ([af82208](https://github.com/ghiscoding/slickgrid-universal/commit/af8220881b2791be2cc3f6605eda3955428094c7)) - by @ghiscoding
### Performance Improvements
@@ -182,6 +309,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Features
* **core:** add `rowHighlightCssClass` & `highlightRow()` to SlickGrid ([#1272](https://github.com/ghiscoding/slickgrid-universal/issues/1272)) ([31c38ad](https://github.com/ghiscoding/slickgrid-universal/commit/31c38ad4d0a2e5c07ad92964fee303b31a192b59)) - by @ghiscoding
+
* **utils:** replace slick-core extend utils with `node-extend` ([#1277](https://github.com/ghiscoding/slickgrid-universal/issues/1277)) ([3439118](https://github.com/ghiscoding/slickgrid-universal/commit/3439118da344cd852a1b1af5bd83c4b894213464)) - by @ghiscoding
## [4.0.3](https://github.com/ghiscoding/slickgrid-universal/compare/v4.0.2...v4.0.3) (2023-12-16)
@@ -209,6 +337,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** SlickEventHandler handler args should have Types ([#1261](https://github.com/ghiscoding/slickgrid-universal/issues/1261)) ([a33129b](https://github.com/ghiscoding/slickgrid-universal/commit/a33129b0ce1443443e7dcebb3562ffd538b6a731)) - by @ghiscoding
+
* regression, Row Detail no longer displayed after CSP safe code ([#1259](https://github.com/ghiscoding/slickgrid-universal/issues/1259)) ([a35f0a4](https://github.com/ghiscoding/slickgrid-universal/commit/a35f0a488775e8ccb68ec8fe0ece9abc47c358f4)) - by @ghiscoding
# [4.0.0-alpha.0](https://github.com/ghiscoding/slickgrid-universal/compare/v3.7.1...v4.0.0-alpha.0) (2023-12-09)
@@ -216,21 +345,33 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* `setActiveCellInternal()` should not throw when cell/row undefined ([dbe6413](https://github.com/ghiscoding/slickgrid-universal/commit/dbe64132294bc88f5dc13ac23a6f6f84ac5e1ffd)) - by @ghiscoding
+
* change dynamic html string w/CSP safe code to fix scroll ([#1210](https://github.com/ghiscoding/slickgrid-universal/issues/1210)) ([cd03907](https://github.com/ghiscoding/slickgrid-universal/commit/cd03907b20468190db7f84f3ae24fbd531e4f6e4)) - by @ghiscoding
+
* Draggable shouldn't trigger dragEnd without first dragging ([#1211](https://github.com/ghiscoding/slickgrid-universal/issues/1211)) ([47cb36e](https://github.com/ghiscoding/slickgrid-universal/commit/47cb36e78995f70933807aa33ba3afa0fecf491e)) - by @ghiscoding
+
* escape glob pattern for SASS copy to work in CI ([0590b24](https://github.com/ghiscoding/slickgrid-universal/commit/0590b24bf2ac140ba69149bd55cbff95b3493112)) - by @ghiscoding-SE
+
* only allow row drag on cell w/`dnd` or `cell-reorder`, fix [#937](https://github.com/ghiscoding/slickgrid-universal/issues/937) ([6a2ab55](https://github.com/ghiscoding/slickgrid-universal/commit/6a2ab550a253a4a1f35e4e81a120fa9247ce753b)), closes [#897](https://github.com/ghiscoding/slickgrid-universal/issues/897) - by @ghiscoding-SE
+
* remove CellRange, SlickRange, SlickGroup, ... unused interfaces ([#1219](https://github.com/ghiscoding/slickgrid-universal/issues/1219)) ([a4cc469](https://github.com/ghiscoding/slickgrid-universal/commit/a4cc469e9c21c5ed851bfbaafdc6b580e7389272)) - by @ghiscoding
+
* the `devMode` should be `false` or an object with other options ([ac57992](https://github.com/ghiscoding/slickgrid-universal/commit/ac57992abd821cdd6fec823464944dadfa1e7b2c)) - by @ghiscoding-SE
+
* the `devMode` should be `false` or an object with other options ([ad2285a](https://github.com/ghiscoding/slickgrid-universal/commit/ad2285a3890442b28dfc7c668ab1b1376e17d3df)) - by @ghiscoding-SE
+
* try adding sort icon on non `sortable` column shouldn't throw ([4791fc8](https://github.com/ghiscoding/slickgrid-universal/commit/4791fc89078d9f3212d034fb1d5e43b8bbfffc5d)) - by @ghiscoding-SE
### Features
* convert GroupItemMetadataProvider Formatter to native HTML for CSP ([#1215](https://github.com/ghiscoding/slickgrid-universal/issues/1215)) ([d723856](https://github.com/ghiscoding/slickgrid-universal/commit/d723856777329f2e40fe3a12d3c59e33afd0e3a8)) - by @ghiscoding
+
* introduce devMode to support nodejs based unit testing ([#1251](https://github.com/ghiscoding/slickgrid-universal/issues/1251)) ([596737d](https://github.com/ghiscoding/slickgrid-universal/commit/596737d52a2ec8c42320152342144ff32191ebfd)) - by @ghiscoding
+
* remove unnecessary Formatters, replace by `cssClass` ([#1225](https://github.com/ghiscoding/slickgrid-universal/issues/1225)) ([de26496](https://github.com/ghiscoding/slickgrid-universal/commit/de26496aa5dc462869a4a1ff966b32baf86e188b)) - by @ghiscoding
+
* rewrite all Formatters as native HTML elements ([#1229](https://github.com/ghiscoding/slickgrid-universal/issues/1229)) ([5cb4dd5](https://github.com/ghiscoding/slickgrid-universal/commit/5cb4dd5757adc401ed4e6deab0e41bcd08a827a3)) - by @ghiscoding
+
* use PubSub Service singleton to subscribe to any SlickEvent ([#1248](https://github.com/ghiscoding/slickgrid-universal/issues/1248)) ([388bd11](https://github.com/ghiscoding/slickgrid-universal/commit/388bd115c1a15f853da8ac943a6e5e3574630438)) - by @ghiscoding
### Performance Improvements
@@ -242,6 +383,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* the `devMode` should be `false` or an object with other options ([ad2285a](https://github.com/ghiscoding/slickgrid-universal/commit/ad2285a3890442b28dfc7c668ab1b1376e17d3df)) - by @ghiscoding-SE
+
* use !important on CSS text utils ([7fdbeb6](https://github.com/ghiscoding/slickgrid-universal/commit/7fdbeb6c46201ae80d6e71e2df7016735b771bf2)) - by @ghiscoding
## [3.7.1](https://github.com/ghiscoding/slickgrid-universal/compare/v3.7.0...v3.7.1) (2023-12-08)
@@ -255,8 +397,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* cell selection range with key combos were incorrect ([#1244](https://github.com/ghiscoding/slickgrid-universal/issues/1244)) ([79d86fe](https://github.com/ghiscoding/slickgrid-universal/commit/79d86fea99258ccf82a5d3d8c684410623e6753b)) - by @ghiscoding
+
* DraggableGrouping & Select Filter `collectionAsync` mem leaks ([#1247](https://github.com/ghiscoding/slickgrid-universal/issues/1247)) ([7dcf53a](https://github.com/ghiscoding/slickgrid-universal/commit/7dcf53ac4d7873c75e82e01c2b4a806f88d8ff39)) - by @ghiscoding
+
* **formatters:** show console error on invalid multiple formatters ([#1227](https://github.com/ghiscoding/slickgrid-universal/issues/1227)) ([fd69ac0](https://github.com/ghiscoding/slickgrid-universal/commit/fd69ac01c68496d4e7d5dd2f06186fba961016d9)) - by @ghiscoding
+
* registered external resouces should keep singleton ref ([#1242](https://github.com/ghiscoding/slickgrid-universal/issues/1242)) ([adf2054](https://github.com/ghiscoding/slickgrid-universal/commit/adf2054bdc8ef7701e6fab78e685d49b8424da29)) - by @ghiscoding
### Features
@@ -274,6 +419,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** ms-select-vanilla requires `@types/trusted-types` dep ([#1190](https://github.com/ghiscoding/slickgrid-universal/issues/1190)) ([284a379](https://github.com/ghiscoding/slickgrid-universal/commit/284a3791027423d0d7f45a950e0a3b8a8a684612)) - by @ghiscoding
+
* improve build & types exports for all targets, Node, CJS/ESM ([#1188](https://github.com/ghiscoding/slickgrid-universal/issues/1188)) ([980fd68](https://github.com/ghiscoding/slickgrid-universal/commit/980fd68f6ce9564bb1fcac5f6ee68fd35f839e8f)) - by @ghiscoding
# [3.5.0](https://github.com/ghiscoding/slickgrid-universal/compare/v3.4.2...v3.5.0) (2023-11-10)
@@ -281,13 +427,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** SlickCellRangeSelector shouldn't stop editor event bubbling ([#1183](https://github.com/ghiscoding/slickgrid-universal/issues/1183)) ([7bb9d25](https://github.com/ghiscoding/slickgrid-universal/commit/7bb9d25c40c3f7f53be57c45917802e5f426c599)) - by @ghiscoding
+
* **graphql:** deprecate `isWithCursor` in favor of simpler `useCursor` ([#1187](https://github.com/ghiscoding/slickgrid-universal/issues/1187)) ([7b3590f](https://github.com/ghiscoding/slickgrid-universal/commit/7b3590f323ea2fe3d3f312674205fc94485213fa)) - by @ghiscoding
+
* **pagination:** should recreate pagination on cursor based changed ([#1175](https://github.com/ghiscoding/slickgrid-universal/issues/1175)) ([c7836aa](https://github.com/ghiscoding/slickgrid-universal/commit/c7836aae4a4ea0892791acc79a7bcb338ddb2038)) - by @ghiscoding
+
* **styles:** menu command with & without icons aren't aligned ([#1180](https://github.com/ghiscoding/slickgrid-universal/issues/1180)) ([35f040d](https://github.com/ghiscoding/slickgrid-universal/commit/35f040dbd1f2d384aadbfbe351dd0e55f8d34c68)) - by @ghiscoding
### Features
* **common:** add `compoundOperatorAltTexts` grid option ([#1181](https://github.com/ghiscoding/slickgrid-universal/issues/1181)) ([dc0aa5e](https://github.com/ghiscoding/slickgrid-universal/commit/dc0aa5e28351af989e9dd691916af909e3a5fdf5)) - by @ghiscoding
+
* Graphql verbatim search terms ([#1174](https://github.com/ghiscoding/slickgrid-universal/issues/1174)) ([eadc5ef](https://github.com/ghiscoding/slickgrid-universal/commit/eadc5ef636e8bf331d89f37be4596e7cc534b974)) - by @Harsgalt86
## [3.4.2](https://github.com/ghiscoding/slickgrid-universal/compare/v3.4.1...v3.4.2) (2023-11-02)
@@ -305,28 +455,47 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** `unbindAll` with a group name should remove all tagged ones ([#1152](https://github.com/ghiscoding/slickgrid-universal/issues/1152)) ([5014354](https://github.com/ghiscoding/slickgrid-universal/commit/5014354803d4561409c0f9622ad8bc5093d494cf)), closes [#1150](https://github.com/ghiscoding/slickgrid-universal/issues/1150) - by @ghiscoding
+
* **common:** calling `bind` with multiple events should add group name ([#1157](https://github.com/ghiscoding/slickgrid-universal/issues/1157)) ([9023b54](https://github.com/ghiscoding/slickgrid-universal/commit/9023b54146b72c0305128484f9fd6f9d1ac47b48)), closes [#1150](https://github.com/ghiscoding/slickgrid-universal/issues/1150) - by @ghiscoding
+
* **common:** clicking Menu close button should only close current menu ([#1160](https://github.com/ghiscoding/slickgrid-universal/issues/1160)) ([b524ef1](https://github.com/ghiscoding/slickgrid-universal/commit/b524ef1af6c662bc4ebcd87ad95aa99dd077a119)) - by @ghiscoding
+
* **common:** context menu should close when clicking another cell ([#1163](https://github.com/ghiscoding/slickgrid-universal/issues/1163)) ([bd132c5](https://github.com/ghiscoding/slickgrid-universal/commit/bd132c52a082147c2366b2fade124e145834902f)) - by @ghiscoding
+
* **common:** disable throwWhenFrozenNotAllViewable w/frozen grids ([#1149](https://github.com/ghiscoding/slickgrid-universal/issues/1149)) ([9a06875](https://github.com/ghiscoding/slickgrid-universal/commit/9a06875d8654c47d97aaaa0fd5191c1bfeae7288)) - by @ghiscoding
+
* **common:** make sure destroy is a function before calling it ([#1148](https://github.com/ghiscoding/slickgrid-universal/issues/1148)) ([dba9606](https://github.com/ghiscoding/slickgrid-universal/commit/dba96060666a929eb616bcacb492f6f5f3f56106)) - by @ghiscoding
+
* **common:** mouseover disabled sub-menu shouldn't open it ([#1167](https://github.com/ghiscoding/slickgrid-universal/issues/1167)) ([550f103](https://github.com/ghiscoding/slickgrid-universal/commit/550f1031ca2c56649ed630ab753d757a3fb799fa)) - by @ghiscoding
+
* **common:** replace `innerHTML: '×'` with `textContent: '×'` ([#1156](https://github.com/ghiscoding/slickgrid-universal/issues/1156)) ([e8b2cfb](https://github.com/ghiscoding/slickgrid-universal/commit/e8b2cfb4b3d182de429ba367d1c83b873670fabc)) - by @ghiscoding
+
* **common:** rollback event capture causing multiple calls ([#1168](https://github.com/ghiscoding/slickgrid-universal/issues/1168)) ([90876c9](https://github.com/ghiscoding/slickgrid-universal/commit/90876c9a57f291271a3510541e4a24a4ef86413c)) - by @ghiscoding
+
* deprecate HeaderMenu `items` in favor of `commandItems` ([#1159](https://github.com/ghiscoding/slickgrid-universal/issues/1159)) ([2b26d6d](https://github.com/ghiscoding/slickgrid-universal/commit/2b26d6da1232f4ad4a7d0db8ad077b3b2e3c6bd7)) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#1138](https://github.com/ghiscoding/slickgrid-universal/issues/1138)) ([82a602e](https://github.com/ghiscoding/slickgrid-universal/commit/82a602e8c3c25a45979d3e3bbf4766d1bae33f80)) - by @renovate-bot
+
* **gridMenu:** remove GridMenu from DOM after closing it ([#1169](https://github.com/ghiscoding/slickgrid-universal/issues/1169)) ([87b242f](https://github.com/ghiscoding/slickgrid-universal/commit/87b242fdebd6d8ce838842458e192a6e90de3d80)) - by @ghiscoding
+
* move `innerHTML` as separate assignment to improve CSP trusted types ([#1162](https://github.com/ghiscoding/slickgrid-universal/issues/1162)) ([9c6a002](https://github.com/ghiscoding/slickgrid-universal/commit/9c6a002666f16b1096d3f928900ad412a4124233)) - by @ghiscoding
### Features
* add `subMenuOpenByEvent` option to open sub-menus via mouseover ([#1161](https://github.com/ghiscoding/slickgrid-universal/issues/1161)) ([609f88b](https://github.com/ghiscoding/slickgrid-universal/commit/609f88b2b80515a540bd7ae1c8366b57bd288dbc)) - by @ghiscoding
+
* add sub-menu(s) to CellMenu & ContextMenu plugins ([#1141](https://github.com/ghiscoding/slickgrid-universal/issues/1141)) ([bd18af1](https://github.com/ghiscoding/slickgrid-universal/commit/bd18af1ee960f9417cb7625ff8c3fb5d9567d16e)) - by @ghiscoding
+
* add sub-menu(s) to GridMenu plugin ([#1151](https://github.com/ghiscoding/slickgrid-universal/issues/1151)) ([5178310](https://github.com/ghiscoding/slickgrid-universal/commit/5178310c0247d5524300841aac7aea7c4f3df733)) - by @ghiscoding
+
* add sub-menu(s) to HeaderMenu plugin ([#1158](https://github.com/ghiscoding/slickgrid-universal/issues/1158)) ([eeab42e](https://github.com/ghiscoding/slickgrid-universal/commit/eeab42e270e53341a8572ab55ed758276a4d30d6)) - by @ghiscoding
+
* add support for grid inside Shadow DOM ([#1166](https://github.com/ghiscoding/slickgrid-universal/issues/1166)) ([f7b8c46](https://github.com/ghiscoding/slickgrid-universal/commit/f7b8c46593c71b7114ac85610c12ad6187e3f6de)) - by @ghiscoding
+
* **common:** add group name to `bind` and `unbindAll` methods ([#1150](https://github.com/ghiscoding/slickgrid-universal/issues/1150)) ([6c3b90e](https://github.com/ghiscoding/slickgrid-universal/commit/6c3b90e774906621d5b1584a2372ba633d2366ff)) - by @ghiscoding
+
* **common:** create ColumnPicker dynamically every time ([#1165](https://github.com/ghiscoding/slickgrid-universal/issues/1165)) ([7e8d80e](https://github.com/ghiscoding/slickgrid-universal/commit/7e8d80e807176ba2064cbb71d06fb53995aae06c)) - by @ghiscoding
+
* **graphql:** add optional cursor pagination to GraphQL backend service ([#1153](https://github.com/ghiscoding/slickgrid-universal/issues/1153)) ([29579b2](https://github.com/ghiscoding/slickgrid-universal/commit/29579b23ab1e531b3323cbf10eb9e9882e244b8f)) - by @Harsgalt86
## [3.3.2](https://github.com/ghiscoding/slickgrid-universal/compare/v3.3.1...v3.3.2) (2023-10-06)
@@ -348,7 +517,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** update dependency multiple-select-vanilla to ^0.4.10 ([#1098](https://github.com/ghiscoding/slickgrid-universal/issues/1098)) ([ab97b9d](https://github.com/ghiscoding/slickgrid-universal/commit/ab97b9df3205f1a55f69f3722d276c8c71d8fd29)) - by @renovate-bot
+
* **GridService:** clear any opened highlight timers before disposing ([#1116](https://github.com/ghiscoding/slickgrid-universal/issues/1116)) ([c6a0957](https://github.com/ghiscoding/slickgrid-universal/commit/c6a095702a672e14b442e71be492942c07d6f1e6)) - by @ghiscoding
+
* **resizer:** resize without container ([#1117](https://github.com/ghiscoding/slickgrid-universal/issues/1117)) ([9013522](https://github.com/ghiscoding/slickgrid-universal/commit/90135223130dacfdd376b56d4cf49437328b08ae)) - by @zewa666
## [3.2.1](https://github.com/ghiscoding/slickgrid-universal/compare/v3.2.0...v3.2.1) (2023-09-05)
@@ -362,14 +533,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Features
* **export:** add `autoDetectCellFormat` flag to Excel Export Options ([#1083](https://github.com/ghiscoding/slickgrid-universal/issues/1083)) ([839b09a](https://github.com/ghiscoding/slickgrid-universal/commit/839b09a10ceba889bc96a7f229f58412a6d5649c)) - by @ghiscoding
+
* **TreeData:** add auto-recalc feature for Tree Totals w/Aggregators ([#1084](https://github.com/ghiscoding/slickgrid-universal/issues/1084)) ([e884c03](https://github.com/ghiscoding/slickgrid-universal/commit/e884c0356595c161b746ca370efa4bd74088c458)) - by @ghiscoding
+
* **TreeData:** add optional Aggregators to Tree Data grids ([#1074](https://github.com/ghiscoding/slickgrid-universal/issues/1074)) ([6af5fd1](https://github.com/ghiscoding/slickgrid-universal/commit/6af5fd17b582834b24655b06c34c634a99c93c6e)) - by @ghiscoding
### Bug Fixes
* **common:** Sort Service could throw on 3rd with undefined columnId ([#1059](https://github.com/ghiscoding/slickgrid-universal/issues/1059)) ([1141230](https://github.com/ghiscoding/slickgrid-universal/commit/114123040a6b69d40f928955627121189a6feb75)) - by @ghiscoding
+
* copying multiple times only kept last undo CellExternalCopyManager ([#1075](https://github.com/ghiscoding/slickgrid-universal/issues/1075)) ([e3beee2](https://github.com/ghiscoding/slickgrid-universal/commit/e3beee208fcd223e911d2d88a15b9d2950267eda)) - by @ghiscoding
+
* **deps:** update dependency autocompleter to v9 ([#1051](https://github.com/ghiscoding/slickgrid-universal/issues/1051)) ([0e05f2a](https://github.com/ghiscoding/slickgrid-universal/commit/0e05f2a4c9f3c9640a3982b7cfa04ea71cfaab96)) - by @renovate-bot
+
* **TreeData:** auto-recalc should update totals for collapsed items too ([#1086](https://github.com/ghiscoding/slickgrid-universal/issues/1086)) ([25d39f2](https://github.com/ghiscoding/slickgrid-universal/commit/25d39f277093990f150ec4aa471c079eab73e4b1)) - by @ghiscoding
## [3.1.0](https://github.com/ghiscoding/slickgrid-universal/compare/v3.0.1...v3.1.0) (2023-07-20)
@@ -381,6 +557,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** update dependency dompurify to ^3.0.5 ([#1030](https://github.com/ghiscoding/slickgrid-universal/issues/1030)) ([728bc58](https://github.com/ghiscoding/slickgrid-universal/commit/728bc58b6844544479695f29984221c9ea099936)) - by @renovate-bot
+
* **plugins:** RowMoveManager shouldn't add cssClass when not usable ([#1044](https://github.com/ghiscoding/slickgrid-universal/issues/1044)) ([f25eeec](https://github.com/ghiscoding/slickgrid-universal/commit/f25eeec7a277d4b915d1423f12e688ad8ac98e7c)) - by @ghiscoding
## [3.0.1](https://github.com/ghiscoding/slickgrid-universal/compare/v3.0.0...v3.0.1) (2023-07-01)
@@ -388,11 +565,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** Select Filter/Editor regular text shouldn't be html encoded ([#1011](https://github.com/ghiscoding/slickgrid-universal/issues/1011)) ([c203a2c](https://github.com/ghiscoding/slickgrid-universal/commit/c203a2ce4d4e5cf6dfb0e05a25f5fd6b0c4cbe4d)), closes [#976](https://github.com/ghiscoding/slickgrid-universal/issues/976) - by @ghiscoding
+
* **deps:** update all non-major dependencies ([#1016](https://github.com/ghiscoding/slickgrid-universal/issues/1016)) ([c34ed84](https://github.com/ghiscoding/slickgrid-universal/commit/c34ed84c8c5aa20876c70b6350f711e16fe6b965)) - by @renovate-bot
+
* **deps:** update dependency autocompleter to ^8.0.4 ([#996](https://github.com/ghiscoding/slickgrid-universal/issues/996)) ([3adf3a1](https://github.com/ghiscoding/slickgrid-universal/commit/3adf3a1a4cf960963ce1447617b3f34b68b6ff4d)) - by @renovate-bot
+
* **deps:** update dependency slickgrid to ^4.0.1 ([#1017](https://github.com/ghiscoding/slickgrid-universal/issues/1017)) ([2750816](https://github.com/ghiscoding/slickgrid-universal/commit/2750816b7b669a820362934daa9bbfd5d60f3ac5)) - by @renovate-bot
+
* **GridState:** calling `getAssociatedGridColumns` should extend column ([#1014](https://github.com/ghiscoding/slickgrid-universal/issues/1014)) ([77cec0c](https://github.com/ghiscoding/slickgrid-universal/commit/77cec0cd052ec3145d73a7a16d0c7f5c663e3901)) - by @ghiscoding
+
* **GridState:** calling getAssociatedGridColumns should extend column (part2) ([#1015](https://github.com/ghiscoding/slickgrid-universal/issues/1015)) ([3ea1d02](https://github.com/ghiscoding/slickgrid-universal/commit/3ea1d0289ba260325a2592fda42fecce10499525)) - by @ghiscoding
+
* **grouping:** DraggableGrouping could throw when leaving page ([#1019](https://github.com/ghiscoding/slickgrid-universal/issues/1019)) ([c233a9c](https://github.com/ghiscoding/slickgrid-universal/commit/c233a9c5db1fc06395e75f1bc5bb34ea3431ba1f)) - by @ghiscoding
## [3.0.0](https://github.com/ghiscoding/slickgrid-universal/compare/v2.6.4...v3.0.0) (2023-05-29)
@@ -414,11 +597,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### ⚠ BREAKING CHANGES
* drop jQuery requirement (#962)
+
* **common:** migrate to multiple-select-vanilla (#919)
### Features
* **common:** migrate to multiple-select-vanilla ([#919](https://github.com/ghiscoding/slickgrid-universal/issues/919)) ([bc74207](https://github.com/ghiscoding/slickgrid-universal/commit/bc74207e9b2ec46209e87b126e1fcff596c162af)) - by @ghiscoding
+
* drop jQuery requirement ([#962](https://github.com/ghiscoding/slickgrid-universal/issues/962)) ([3da21da](https://github.com/ghiscoding/slickgrid-universal/commit/3da21daacc391a0fb309fcddd78442642c5269f6)) - by @ghiscoding
## [2.6.4](https://github.com/ghiscoding/slickgrid-universal/compare/v2.6.3...v2.6.4) (2023-05-20)
@@ -426,8 +611,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** add better aria accessibility missing on menus and checkboxes ([#968](https://github.com/ghiscoding/slickgrid-universal/issues/968)) ([8041c11](https://github.com/ghiscoding/slickgrid-universal/commit/8041c1189afd7460bbcc0226c49086878c3b5f90)) - by @ghiscoding
+
* **core:** set `wheel` event listener to passive for better perf ([#971](https://github.com/ghiscoding/slickgrid-universal/issues/971)) ([e4417e8](https://github.com/ghiscoding/slickgrid-universal/commit/e4417e865f6fdf4bcb27eebfc476d959a16d47ea)) - by @ghiscoding
+
* **export:** fix negative number exports to Excel ([#977](https://github.com/ghiscoding/slickgrid-universal/issues/977)) ([edf5721](https://github.com/ghiscoding/slickgrid-universal/commit/edf5721007ce0745fc81f3f0261fb7e25340cbc1)) - by @ghiscoding
+
* SlickDraggableGrouping should hide group elms when dragging ([#965](https://github.com/ghiscoding/slickgrid-universal/issues/965)) ([6601998](https://github.com/ghiscoding/slickgrid-universal/commit/660199896df040a34f8947acf81a5d720d11a8c4)) - by @ghiscoding
## [2.6.3](https://github.com/ghiscoding/slickgrid-universal/compare/v2.6.2...v2.6.3) (2023-03-23)
@@ -463,12 +651,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **autocomplete:** Autocomplete drop container should take content width ([#897](https://github.com/ghiscoding/slickgrid-universal/issues/897)) ([9690a38](https://github.com/ghiscoding/slickgrid-universal/commit/9690a38f678ca6f0632b847aebfe93e5b7f0bc12)) - by @ghiscoding
+
* **build:** package exports prop had invalid ESM import link ([#892](https://github.com/ghiscoding/slickgrid-universal/issues/892)) ([7f95f69](https://github.com/ghiscoding/slickgrid-universal/commit/7f95f698447f8178cb7ceec416c35f4957fddbe9)) - by @ghiscoding
+
* **common:** Excel copy cell ranges shouldn't lose its cell focus ([#901](https://github.com/ghiscoding/slickgrid-universal/issues/901)) ([1dc8b76](https://github.com/ghiscoding/slickgrid-universal/commit/1dc8b762b4fc8070eec003161fdc9c4ebf60afd2)) - by @ghiscoding
+
* **deps:** update dependency autocompleter to v8 ([#895](https://github.com/ghiscoding/slickgrid-universal/issues/895)) ([7df225d](https://github.com/ghiscoding/slickgrid-universal/commit/7df225d844ec5629800373da59aeed44eee04e1b)) - by @renovate-bot
+
* **deps:** update dependency dompurify to v3 ([#907](https://github.com/ghiscoding/slickgrid-universal/issues/907)) ([66c8b4d](https://github.com/ghiscoding/slickgrid-universal/commit/66c8b4d602d88d733070b2189468bf1b6508d7eb)) - by @renovate-bot
+
* **editor:** comparing select editor value against `['']` isn't valid ([#909](https://github.com/ghiscoding/slickgrid-universal/issues/909)) ([d93fd5f](https://github.com/ghiscoding/slickgrid-universal/commit/d93fd5f163e393c47fad8c8d285a5788b3834adf)) - by @ghiscoding
+
* **export:** Excel export auto-detect number with Formatters.multiple ([#902](https://github.com/ghiscoding/slickgrid-universal/issues/902)) ([be33a68](https://github.com/ghiscoding/slickgrid-universal/commit/be33a68cadbdaed0c60b00bdcd123f3a4797fb8a)) - by @ghiscoding
+
* **RowDetail:** Row Detail extension should work with editable grid ([#896](https://github.com/ghiscoding/slickgrid-universal/issues/896)) ([99677f0](https://github.com/ghiscoding/slickgrid-universal/commit/99677f08b9cb383a2b64540700e501c7bdfe9f72)) - by @ghiscoding
### Features
@@ -496,6 +691,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **filters:** provide flag to disable special chars input filter parsing ([#873](https://github.com/ghiscoding/slickgrid-universal/issues/873)) ([7e35dae](https://github.com/ghiscoding/slickgrid-universal/commit/7e35dae2258c191e76dbdf01ac654f4a54b5b547)), closes [/stackoverflow.com/questions/75155658/in-angular-slickgrid-the-records-with-special-characters-are-not-gett/75160978#75160978](https://github.com//stackoverflow.com/questions/75155658/in-angular-slickgrid-the-records-with-special-characters-are-not-gett/75160978/issues/75160978) - by @ghiscoding
+
* **styling:** do not remove ul>li bullet on html root, fixes [#868](https://github.com/ghiscoding/slickgrid-universal/issues/868) ([#872](https://github.com/ghiscoding/slickgrid-universal/issues/872)) ([59fa0ba](https://github.com/ghiscoding/slickgrid-universal/commit/59fa0badad181172bf37a31ecf4ef0f44ee47e8d)) - by @ghiscoding
## [2.2.2](https://github.com/ghiscoding/slickgrid-universal/compare/v2.2.1...v2.2.2) (2022-12-24)
@@ -515,18 +711,27 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **editors:** Autocomplete list should be using same width as cell width ([#846](https://github.com/ghiscoding/slickgrid-universal/issues/846)) ([0055f8a](https://github.com/ghiscoding/slickgrid-universal/commit/0055f8a925f7ec6e381c9b9b05dccdb405b7a420)) - by @ghiscoding
+
* **export:** create custom Excel cell format with Formatters.decimal ([#844](https://github.com/ghiscoding/slickgrid-universal/issues/844)) ([a7a626c](https://github.com/ghiscoding/slickgrid-universal/commit/a7a626ccaaa510d084979d38d9a6b5a439f24e6d)) - by @ghiscoding
+
* **exports:** Date should always export w/Formatter unless false ([#856](https://github.com/ghiscoding/slickgrid-universal/issues/856)) ([1b249e8](https://github.com/ghiscoding/slickgrid-universal/commit/1b249e88e3033ff4c432346ae32ce3183537237b)) - by @ghiscoding
+
* **formatters:** add all missing Date Formatters ([#855](https://github.com/ghiscoding/slickgrid-universal/issues/855)) ([9d29e59](https://github.com/ghiscoding/slickgrid-universal/commit/9d29e59818ae4e7d3cac692f0479e0147cc2ba8d)) - by @ghiscoding
+
* **formatters:** Date Formatter should work with Date object ([#854](https://github.com/ghiscoding/slickgrid-universal/issues/854)) ([30b80e2](https://github.com/ghiscoding/slickgrid-universal/commit/30b80e27b209dbafda25963864116d980650a648)) - by @ghiscoding
+
* **styling:** Grid Menu & Col Picker overflow in Firefox ([#845](https://github.com/ghiscoding/slickgrid-universal/issues/845)) ([9b0aef7](https://github.com/ghiscoding/slickgrid-universal/commit/9b0aef74d569c73e18d64e29034d777315c19cf8)) - by @ghiscoding
### Features
* **exports:** add Excel auto-detect format by field types & formatters ([#848](https://github.com/ghiscoding/slickgrid-universal/issues/848)) ([27a18c4](https://github.com/ghiscoding/slickgrid-universal/commit/27a18c416e71a2a1f418d5c2c850fd331262bf7f)) - by @ghiscoding
+
* **exports:** add Excel custom cell (column) styling ([#851](https://github.com/ghiscoding/slickgrid-universal/issues/851)) ([dd92d44](https://github.com/ghiscoding/slickgrid-universal/commit/dd92d44e0ac27c94a72c98af314cfa23f525f94c)) - by @ghiscoding
+
* **exports:** add optional Excel export parser callback functions ([#852](https://github.com/ghiscoding/slickgrid-universal/issues/852)) ([975da5b](https://github.com/ghiscoding/slickgrid-universal/commit/975da5b1d87ac287c1240e7ec88be4760e22ca74)) - by @ghiscoding
+
* **exports:** add optional file MIME type to Excel export service ([#849](https://github.com/ghiscoding/slickgrid-universal/issues/849)) ([05402e5](https://github.com/ghiscoding/slickgrid-universal/commit/05402e5b3a4cec9306ed21a495cc89c31b3816d8)) - by @ghiscoding
+
* **formatters:** add Currency Formatter and GroupTotalFormatter ([#850](https://github.com/ghiscoding/slickgrid-universal/issues/850)) ([ad373ab](https://github.com/ghiscoding/slickgrid-universal/commit/ad373abd84468367d43bf4fa0feccb99ae22821c)) - by @ghiscoding
## [2.1.3](https://github.com/ghiscoding/slickgrid-universal/compare/v2.1.2...v2.1.3) (2022-12-08)
@@ -534,7 +739,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** Date Sorting was shuffling other lines with same dates ([#831](https://github.com/ghiscoding/slickgrid-universal/issues/831)) ([db34213](https://github.com/ghiscoding/slickgrid-universal/commit/db34213bc8594ae12a6fd241f9fb6d6bfd1b8334)) - by @ghiscoding
+
* **common:** Resizer Service should only resize grid not its container ([#833](https://github.com/ghiscoding/slickgrid-universal/issues/833)) ([7d21233](https://github.com/ghiscoding/slickgrid-universal/commit/7d21233deb16a1bda99799fe54401a8b9410197a)) - by @ghiscoding
+
* Fix for page being cleared when using copy and paste with selectEditor ([#836](https://github.com/ghiscoding/slickgrid-universal/pull/836)) ([f1cadb33](https://github.com/ghiscoding/slickgrid-universal/commit/f1cadb33d99bcd98bc3c79221fbe55a5b1d72cfd)) - by @austinsimpson
## [2.1.2](https://github.com/ghiscoding/slickgrid-universal/compare/v2.1.1...v2.1.2) (2022-12-02)
@@ -542,10 +749,15 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **addons:** do not add special columns twice (like Row Selection) ([#822](https://github.com/ghiscoding/slickgrid-universal/issues/822)) ([a80d6f8](https://github.com/ghiscoding/slickgrid-universal/commit/a80d6f8f2cae674e0a870eb9c450de991cd84837)) - by @ghiscoding
+
* **addons:** onGroupChanged callback should be executed with Draggable ([#826](https://github.com/ghiscoding/slickgrid-universal/issues/826)) ([35c2631](https://github.com/ghiscoding/slickgrid-universal/commit/35c2631feb00a5b2efe6903e9bfdfe5c95df318e)) - by @ghiscoding
+
* **common:** remove unused console log ([593928a](https://github.com/ghiscoding/slickgrid-universal/commit/593928af8a7e92ecf2a8c67e4cff4c8e5da58468)) - by @ghiscoding
+
* **core:** grid service `resetGrid` method wasn't always resetting ([#829](https://github.com/ghiscoding/slickgrid-universal/issues/829)) ([1ffc382](https://github.com/ghiscoding/slickgrid-universal/commit/1ffc38265006e8b6e584e6de8f6c4fe53c2e2bf8)) - by @ghiscoding
+
* **styling:** editor clear button should always be centered ([3e9f330](https://github.com/ghiscoding/slickgrid-universal/commit/3e9f3304dc2b02450e859af27af254fee1fbd650)) - by @ghiscoding
+
* **styling:** focused compound input box-shadow css ([2c50c47](https://github.com/ghiscoding/slickgrid-universal/commit/2c50c47a76556ae4a6f842c483800d5af90637fc)) - by @ghiscoding
## [2.1.1](https://github.com/ghiscoding/slickgrid-universal/compare/v2.1.0...v2.1.1) (2022-11-19)
@@ -559,32 +771,51 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** upgrading to TypeScript 4.9 brought new build issue ([#816](https://github.com/ghiscoding/slickgrid-universal/issues/816)) ([4d46d8a](https://github.com/ghiscoding/slickgrid-universal/commit/4d46d8ab251bd78671140f82cb143b973e5422b3)) - by @ghiscoding
+
* **common:** changing Slider value(s) should update Tooltip instantly ([#800](https://github.com/ghiscoding/slickgrid-universal/issues/800)) ([9c6be27](https://github.com/ghiscoding/slickgrid-universal/commit/9c6be271a956876edaa03be7bf4bda9821840910)) - by @ghiscoding
+
* **common:** Slider Range should update both number addons ([#803](https://github.com/ghiscoding/slickgrid-universal/issues/803)) ([3cfd84e](https://github.com/ghiscoding/slickgrid-universal/commit/3cfd84e7ec4e45cf6a4896dc6143da1fecb0402c)) - by @ghiscoding
+
* **deps:** update dependency autocompleter to v7 ([#804](https://github.com/ghiscoding/slickgrid-universal/issues/804)) ([c298646](https://github.com/ghiscoding/slickgrid-universal/commit/c298646fca64059ca3a59a370f870ad4b3a573da)) - by @renovate-bot
+
* **deps:** update dependency dompurify to ^2.4.1 ([#806](https://github.com/ghiscoding/slickgrid-universal/issues/806)) ([a33d8fb](https://github.com/ghiscoding/slickgrid-universal/commit/a33d8fbf3e48bfa29b9173f9263620e61608fffb)) - by @renovate-bot
+
* **editors:** disable browser autofill on the Editors.autocompleter ([#776](https://github.com/ghiscoding/slickgrid-universal/issues/776)) ([fd2cf53](https://github.com/ghiscoding/slickgrid-universal/commit/fd2cf535c0bd941203951c665bb3da00f4a4677e)) - by @ghiscoding
+
* **editors:** Slider editor track not showing after Slider filter change ([#792](https://github.com/ghiscoding/slickgrid-universal/issues/792)) ([2ad02d2](https://github.com/ghiscoding/slickgrid-universal/commit/2ad02d22cfbb2187df62f0ec19b26f828fec57a6)) - by @ghiscoding
+
* **filters:** changing Slider value should update tooltip value ([#788](https://github.com/ghiscoding/slickgrid-universal/issues/788)) ([509a31d](https://github.com/ghiscoding/slickgrid-universal/commit/509a31d5630689c6c91cc2cef4e87b8dea72a243)) - by @ghiscoding
+
* **filters:** Slider default operator should be greater or equal (>=) ([#793](https://github.com/ghiscoding/slickgrid-universal/issues/793)) ([b895864](https://github.com/ghiscoding/slickgrid-universal/commit/b895864bc39a415622ac9f2a4b79565aa3d89179)) - by @ghiscoding
+
* **styling:** new Slider not flexed correctly ([#799](https://github.com/ghiscoding/slickgrid-universal/issues/799)) ([83a86d0](https://github.com/ghiscoding/slickgrid-universal/commit/83a86d0575a47ed3a11ede31af2a8a3a8186fb9d)) - by @ghiscoding
### Features
* **addon:** add group by sorting to SlickDraggableGrouping ([#814](https://github.com/ghiscoding/slickgrid-universal/issues/814)) ([962a756](https://github.com/ghiscoding/slickgrid-universal/commit/962a756fb17476221867c977752e28bd1d74f6db)) - by @ghiscoding
+
* **common:** add "targetSelector" to onFilterChanged & Grid State ([#813](https://github.com/ghiscoding/slickgrid-universal/issues/813)) ([a25791a](https://github.com/ghiscoding/slickgrid-universal/commit/a25791a5d11b73fd88d80ef8a6f788b27d7390ec)) - by @ghiscoding
+
* **common:** use editorOptions/filterOptions instead of params ([#798](https://github.com/ghiscoding/slickgrid-universal/issues/798)) ([a3c8b6e](https://github.com/ghiscoding/slickgrid-universal/commit/a3c8b6e48dbe3db7eb154837f15ce10780923b32)) - by @ghiscoding
+
* **filters:** add "target" prop to `onBeforeSearchChange` ([#796](https://github.com/ghiscoding/slickgrid-universal/issues/796)) ([c4606fd](https://github.com/ghiscoding/slickgrid-universal/commit/c4606fde3cf206f81ab5f83d150cf3ce29cbfe75)) - by @ghiscoding
+
* **filters:** add back Slider Range filter in pure JS ([#784](https://github.com/ghiscoding/slickgrid-universal/issues/784)) ([b84525c](https://github.com/ghiscoding/slickgrid-universal/commit/b84525c3c087582854e30b386a1015f6ce3156b4)) - by @ghiscoding
+
* **filters:** add grid option `skipCompoundOperatorFilterWithNullInput` ([#794](https://github.com/ghiscoding/slickgrid-universal/issues/794)) ([617c88d](https://github.com/ghiscoding/slickgrid-universal/commit/617c88d7432c35b8ac0c0f40066a2f55a58b6d35)) - by @ghiscoding
+
* **filters:** add Slider filter track filled track color ([#795](https://github.com/ghiscoding/slickgrid-universal/issues/795)) ([5fbd9c9](https://github.com/ghiscoding/slickgrid-universal/commit/5fbd9c9036844e7e88a99fea6a4d1e1f0fd2377a)) - by @ghiscoding
+
* **plugins:** sync column definitions to user after plugin adds column ([#781](https://github.com/ghiscoding/slickgrid-universal/issues/781)) ([0755b65](https://github.com/ghiscoding/slickgrid-universal/commit/0755b655b7be5911345334e094544a14c3698b51)) - by @ghiscoding
+
* **tooltip:** add a new "center" position option to SlickCustomTooltip ([#787](https://github.com/ghiscoding/slickgrid-universal/issues/787)) ([b019de5](https://github.com/ghiscoding/slickgrid-universal/commit/b019de50244836a984314ea6e6f5cee639551438)) - by @ghiscoding
### Performance Improvements
* **filters:** merge all date range & compound filters into one class ([#812](https://github.com/ghiscoding/slickgrid-universal/issues/812)) ([ca9adfa](https://github.com/ghiscoding/slickgrid-universal/commit/ca9adfae84ca8fd57b61548b1222ade5a8b9c498)) - by @ghiscoding
+
* **filters:** merge all input & compound filters into one class ([#809](https://github.com/ghiscoding/slickgrid-universal/issues/809)) ([6d08f4d](https://github.com/ghiscoding/slickgrid-universal/commit/6d08f4dc9fc471b316f375d77fa8ae1805dc9b83)) - by @ghiscoding
+
* **filters:** merge all Slider filters into one class ([#791](https://github.com/ghiscoding/slickgrid-universal/issues/791)) ([fc4304b](https://github.com/ghiscoding/slickgrid-universal/commit/fc4304b3dd47ac10df65f5b8dda9d8ce5aad8ed9)) - by @ghiscoding
# [2.0.0](https://github.com/ghiscoding/slickgrid-universal/compare/v1.4.0...v2.0.0) (2022-10-17)
@@ -592,6 +823,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** update all non-major dependencies ([#769](https://github.com/ghiscoding/slickgrid-universal/issues/769)) ([4e05a4b](https://github.com/ghiscoding/slickgrid-universal/commit/4e05a4b977c760511fc90903c0f62673859bd65f)) - by @renovate-bot
+
* **styling:** fix some styling issues with input groups and Firefox ([#750](https://github.com/ghiscoding/slickgrid-universal/issues/750)) ([1aa849e](https://github.com/ghiscoding/slickgrid-universal/commit/1aa849ea81461dc9bbd7b3bc05a092bb14c88be2)) - by @ghiscoding
### Features
@@ -603,6 +835,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** update all non-major dependencies ([#769](https://github.com/ghiscoding/slickgrid-universal/issues/769)) ([4e05a4b](https://github.com/ghiscoding/slickgrid-universal/commit/4e05a4b977c760511fc90903c0f62673859bd65f)) - by @renovate-bot
+
* **styling:** fix some styling issues with input groups and Firefox ([#750](https://github.com/ghiscoding/slickgrid-universal/issues/750)) ([1aa849e](https://github.com/ghiscoding/slickgrid-universal/commit/1aa849ea81461dc9bbd7b3bc05a092bb14c88be2)) - by @ghiscoding
### Features
@@ -614,12 +847,15 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **common:** duplicate translation namespace prefix, fixes [#738](https://github.com/ghiscoding/slickgrid-universal/issues/738) ([#739](https://github.com/ghiscoding/slickgrid-universal/issues/739)) ([ed6b0cc](https://github.com/ghiscoding/slickgrid-universal/commit/ed6b0cc4f664e27830357ac45d523d0571c94bce)) - by @someusersomeuser
+
* **deps:** update all non-major dependencies ([#740](https://github.com/ghiscoding/slickgrid-universal/issues/740)) ([c8acb65](https://github.com/ghiscoding/slickgrid-universal/commit/c8acb6542a768b2a2b4e0ea0e1f71533d7077927)) - by @renovate-bot
+
* **filters:** fetch API isn't always an instance of Response ([#746](https://github.com/ghiscoding/slickgrid-universal/issues/746)) ([11be5c2](https://github.com/ghiscoding/slickgrid-universal/commit/11be5c2f9554c8fad2b984864ec7180698d02d19)), closes [#744](https://github.com/ghiscoding/slickgrid-universal/issues/744) - by @ghiscoding
### Features
* **common:** remove jquery-ui-dist from deps, use jquery-ui only ([#733](https://github.com/ghiscoding/slickgrid-universal/issues/733)) ([b89d1f1](https://github.com/ghiscoding/slickgrid-universal/commit/b89d1f169bfde21d8a46520aed580c12db5f668f)) - by @ghiscoding
+
* **common:** update title prop on change event for Slider Filter/Editor ([#743](https://github.com/ghiscoding/slickgrid-universal/issues/743)) ([0ca6f3f](https://github.com/ghiscoding/slickgrid-universal/commit/0ca6f3f4d8894d4bb9459cabca9a3492e7cca0ad)) - by @ghiscoding
## [1.3.7](https://github.com/ghiscoding/slickgrid-universal/compare/v1.3.6...v1.3.7) (2022-08-02)
@@ -651,6 +887,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **composite:** selected row count always 0 on mass-selected ([#712](https://github.com/ghiscoding/slickgrid-universal/issues/712)) ([ec42dc7](https://github.com/ghiscoding/slickgrid-universal/commit/ec42dc753fbf8c84040e252f328e51ea4a98cedf))
+
* **deps:** update all non-major dependencies ([230291c](https://github.com/ghiscoding/slickgrid-universal/commit/230291c94506fdd12e7f843a3d7f324922ef97f6))
# [1.3.0](https://github.com/ghiscoding/slickgrid-universal/compare/v1.2.6...v1.3.0) (2022-06-18)
@@ -658,6 +895,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **deps:** add missing dependencies in child package ([97d0230](https://github.com/ghiscoding/slickgrid-universal/commit/97d02306899e583779c3b6d5b219b2798a5f9cfd))
+
* **deps:** update all non-major dependencies ([5097cea](https://github.com/ghiscoding/slickgrid-universal/commit/5097ceae88c0ea212e0aa6ea2a5b1020368f3216))
### Features
@@ -687,8 +925,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **editors:** select editor should call save only once ([d111c2f](https://github.com/ghiscoding/slickgrid-universal/commit/d111c2f7799151236c6053d7a5288d1fdd530550))
+
* **resizer:** use default resize when resizeByContent has no data ([8499b61](https://github.com/ghiscoding/slickgrid-universal/commit/8499b61b5cc6365af0035d254a9487c79b74bd7f))
+
* **selections:** selected rows doesn't update when hidden column shown ([0d1cf29](https://github.com/ghiscoding/slickgrid-universal/commit/0d1cf294e8ae944672a9c9a2cece1de553c2f973)), closes [#661](https://github.com/ghiscoding/slickgrid-universal/issues/661)
+
* **styling:** add pointer cursor on ms-filter, avoid Bootstrap override ([11e1e12](https://github.com/ghiscoding/slickgrid-universal/commit/11e1e12115896e73096e10b34575e4e8ebe5b819))
## [1.2.1](https://github.com/ghiscoding/slickgrid-universal/compare/v1.2.0...v1.2.1) (2022-01-18)
@@ -702,28 +943,47 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **demo:** latest change with Filter container breaks other demos ([129cc78](https://github.com/ghiscoding/slickgrid-universal/commit/129cc78ac34ad632f2a265d49a631e04b119250b))
+
* **filter:** add the "filled" class for styling purposes ([ea7974a](https://github.com/ghiscoding/slickgrid-universal/commit/ea7974a9a7d54150c16d22ccb8008c692faf6132))
+
* **filter:** add the "filled" class for styling purposes - better code ([4a650cd](https://github.com/ghiscoding/slickgrid-universal/commit/4a650cd269852ab20088b274939e89b2cfc96ec8))
+
* **filter:** add the "filled" class for styling purposes - ajust code format ([abe481e](https://github.com/ghiscoding/slickgrid-universal/commit/abe481e0cd11bfe204399814c1be0eeb66d3f91a))
+
* **filter:** add the "filled" class for styling purposes - ajust format ([fc8c899](https://github.com/ghiscoding/slickgrid-universal/commit/fc8c8992381b001d6ada449352d7b66c6ca08e00))
+
* **filter:** update multiple-select to fix select filtering ([63dcd08](https://github.com/ghiscoding/slickgrid-universal/commit/63dcd0873026fb8ba036ca52ba31f583d6ad136f)), closes [#865](https://github.com/ghiscoding/slickgrid-universal/issues/865)
+
* **plugins:** Draggable Grouping Toggle All should follow `collapsed` ([7fedfa1](https://github.com/ghiscoding/slickgrid-universal/commit/7fedfa1129e12a3bf665efe0bd9160b6a7a1b6a9))
+
* **services:** unsubscribe shouldn't remove when poping out of array ([e841da9](https://github.com/ghiscoding/slickgrid-universal/commit/e841da9df7a23bf7b789e4a13803488ab479ff15))
### Features
* **binding:** make Binding Service a little smarter ([98a7661](https://github.com/ghiscoding/slickgrid-universal/commit/98a766173638246b6a17e31812929a9bba1eb52b))
+
* **composite:** add new `validateMassUpdateChange` callback & bug fixes ([#603](https://github.com/ghiscoding/slickgrid-universal/issues/603)) ([2c1559b](https://github.com/ghiscoding/slickgrid-universal/commit/2c1559b7a3b0b1a642a664e59a025ce78a747946))
+
* **demo:** add new Example to demo Real-time Market Trading ([e50434a](https://github.com/ghiscoding/slickgrid-universal/commit/e50434ac3dab98644e23266c81d09b3789ea7de4))
+
* **filters:** change-filter-element-Container ([31c6e54](https://github.com/ghiscoding/slickgrid-universal/commit/31c6e54a3b2e0d135d8407c74b7bfa329a85e0c5))
+
* **filters:** change-filter-element-Container ([d455d27](https://github.com/ghiscoding/slickgrid-universal/commit/d455d2781f19fc9865600b6123f679ab3526cf04))
+
* **filters:** change-filter-element-Container ([704c52a](https://github.com/ghiscoding/slickgrid-universal/commit/704c52a1d5dec9fedbe837ceca41b96a0d673061))
+
* **filters:** change-filter-element-Container-ajust-code-format ([efb0189](https://github.com/ghiscoding/slickgrid-universal/commit/efb0189b0ce357b07025e2f9f29717a41128ab6b))
+
* **filters:** change-filter-element-Container-ajust-test ([268ccb4](https://github.com/ghiscoding/slickgrid-universal/commit/268ccb4d6be916959f2eadd87d7c506dff1df472))
+
* **filters:** change-filter-element-Container-test ([61e29c5](https://github.com/ghiscoding/slickgrid-universal/commit/61e29c5851487f7470e6f631c890c346f07ed242))
+
* **plugins:** Apply auto scroll when dragging on RowMoveManager plugin ([1c14a4f](https://github.com/ghiscoding/slickgrid-universal/commit/1c14a4fd06693425be52e91f405d1c8739699627)), closes [#662](https://github.com/ghiscoding/slickgrid-universal/issues/662)
+
* **selection:** auto-scroll the viewport when dragging with selection ([ecd9c57](https://github.com/ghiscoding/slickgrid-universal/commit/ecd9c57bd6c1315e2358722785a87582ec939f85)), closes [#656](https://github.com/ghiscoding/slickgrid-universal/issues/656)
+
* **services:** add `skipError` to CRUD methods in Grid Service ([869ed87](https://github.com/ghiscoding/slickgrid-universal/commit/869ed87bfa4e60d089138bcba1da5f4bb120e73b))
+
* **services:** add extra features to EventPubSub Service ([9bd02b5](https://github.com/ghiscoding/slickgrid-universal/commit/9bd02b5d92bcf6aaf89a828c4e6496a24e795c53))
# [1.1.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.19.2...v1.1.0) (2021-12-11)
@@ -731,50 +991,91 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** add DOM purify optional default import to fix rollup builds ([73bc3c0](https://github.com/ghiscoding/slickgrid-universal/commit/73bc3c0756cf6d28b292f0162afffc06412a126e))
+
* **build:** DOMPurify import fix for all framework ([c551d0c](https://github.com/ghiscoding/slickgrid-universal/commit/c551d0c64d4c7325578acf4feb5d22132c7d7f91))
+
* **comp:** replace `prepend` not supported in IE/Salesforce ([13bd9a4](https://github.com/ghiscoding/slickgrid-universal/commit/13bd9a4f8c4fdaedccc65db7100527be0e84eb00))
+
* **context:** remove fixed width on ContextMenu use auto instead ([403679b](https://github.com/ghiscoding/slickgrid-universal/commit/403679be5ca8547b53ed2525a4017923302afae7))
+
* **context:** strip hidden special chars on context menu Copy command ([5d81644](https://github.com/ghiscoding/slickgrid-universal/commit/5d81644a194b66e7fb5efc550a08962d8087f0e3))
+
* **context:** strip hidden special chars on context menu Copy command ([f94ca83](https://github.com/ghiscoding/slickgrid-universal/commit/f94ca834b1fdee94e4e44bdc3d245956a4437de6))
+
* **filters:** remove Filters from DOM after header row gets destroyed ([3f08162](https://github.com/ghiscoding/slickgrid-universal/commit/3f08162cd8b5fbb407c77b6dc441e60239ba5788))
+
* **locales:** add missing text & remove global config texts fix Locales ([655a872](https://github.com/ghiscoding/slickgrid-universal/commit/655a872d7160ab53530f8e2fdc575817af782b5d))
+
* **plugin:** Copy command from Context Menu should work with numbers ([9d36491](https://github.com/ghiscoding/slickgrid-universal/commit/9d36491c407beb0fdc53588ffc6264306fab607a))
+
* **plugin:** providing usability override via grid option should work ([6446a10](https://github.com/ghiscoding/slickgrid-universal/commit/6446a1061d7d0126cfe655518b7179d93356aa83)), closes [#555](https://github.com/ghiscoding/slickgrid-universal/issues/555)
+
* **plugins:** remove invalid export for build to work ([9353022](https://github.com/ghiscoding/slickgrid-universal/commit/9353022593ba9b16e34a8b3dd3ad62bc5b5e7569))
+
* **styling:** better support of auto width on drop menu ([8a48dd2](https://github.com/ghiscoding/slickgrid-universal/commit/8a48dd2a224c757534a631e88a4864e151496438))
+
* **styling:** Grid Menu Title not aligned correctly with Bootstrap ([e2b991f](https://github.com/ghiscoding/slickgrid-universal/commit/e2b991fb05b8ca94e5a0e3986aabaefc7bc245fb))
+
* **styling:** slightly off Autocomplete position ([cd03f67](https://github.com/ghiscoding/slickgrid-universal/commit/cd03f67f50db301cfe74a1e20efd998102bcf3bf))
+
* **styling:** tweak & fix all styling with Salesforce & other frameworks ([86dbb76](https://github.com/ghiscoding/slickgrid-universal/commit/86dbb76b439a99773a3fe6fd154440eacb20d510))
+
* **tree:** reset to initial tree sort when calling "Clear all Sorting" ([8bd3f4f](https://github.com/ghiscoding/slickgrid-universal/commit/8bd3f4f68247681f8eb57e7aabd59b636face7e7))
+
* **treeGrid:** Bug in onCellClick event ([42155af](https://github.com/ghiscoding/slickgrid-universal/commit/42155af12b0808fc95d5f1c00fcec9bfaef64c44))
+
* apply fixes & refactoring after testing in Aurelia-Slickgrid ([038fa3f](https://github.com/ghiscoding/slickgrid-universal/commit/038fa3f56f202465f2b40af57e8acf752fe31f60))
+
* switch normal/frozen should always show Grid Menu on far right ([6bef090](https://github.com/ghiscoding/slickgrid-universal/commit/6bef0901652a2bdbf661cf5a0fc0d9a7c325a44a))
+
* translation wasn't working with context menu ([889e443](https://github.com/ghiscoding/slickgrid-universal/commit/889e44387279c7834944600417c0c2da11b7991f))
### Features
* **controls:** add `minHeight` option to ColumnPicker/GridMenu ([cfcfc85](https://github.com/ghiscoding/slickgrid-universal/commit/cfcfc8588b854530425f2bea19e8aa7c5256d059))
+
* **controls:** convert and add ColumnPicker into Slickgrid-Universal ([1f937b9](https://github.com/ghiscoding/slickgrid-universal/commit/1f937b9a3abe43cf1a2bb1f52ba625c34431e328))
+
* **controls:** move external Grid Menu into Slickgrid-Universal ([40adff4](https://github.com/ghiscoding/slickgrid-universal/commit/40adff49c2a74769823dfbed3d32b239608e2a59))
+
* **core:** add TS utility to infer extension instance by name ([3f4f65f](https://github.com/ghiscoding/slickgrid-universal/commit/3f4f65fb1c4f01cddca0e356a0a770b575a7384a))
+
* **plugins:** add all Cell Range/Selection plugins into Universal ([3b4ddca](https://github.com/ghiscoding/slickgrid-universal/commit/3b4ddcaff6e2e8db5804b995ff2282f306cc1a7a))
+
* **plugins:** add extra callback methods to checkbox selector ([#570](https://github.com/ghiscoding/slickgrid-universal/issues/570)) ([a9245f9](https://github.com/ghiscoding/slickgrid-universal/commit/a9245f920397bab0ef5105404babe8443654785c))
+
* **plugins:** add Row Detail plugin final code & tests ([045ea6d](https://github.com/ghiscoding/slickgrid-universal/commit/045ea6d0e49e55163edcbe1ec6e796f51349667b))
+
* **plugins:** make it possible to use both Header Button/Menu together ([965bd58](https://github.com/ghiscoding/slickgrid-universal/commit/965bd588aeba7528031f309020bdfd3c611ebeab))
+
* **plugins:** move Checkbox and Row Selection plugins to universal ([06f0ab1](https://github.com/ghiscoding/slickgrid-universal/commit/06f0ab155a2f0ee06681d3e94780397c5e4f9f67))
+
* **plugins:** move external Cell Menu into Slickgrid-Universal ([6f34c10](https://github.com/ghiscoding/slickgrid-universal/commit/6f34c10b9a8522ae430e13c9519083451bf71ebf))
+
* **plugins:** move external cell related plugins to universal ([11e15d8](https://github.com/ghiscoding/slickgrid-universal/commit/11e15d88360b7b30ca7ab94624a7928201f15945))
+
* **plugins:** move external Context Menu into Slickgrid-Universal ([2170bb4](https://github.com/ghiscoding/slickgrid-universal/commit/2170bb4e3f02ef6f45ad13a1c59730047942651e))
+
* **plugins:** move external Draggable Grouping into Slickgrid-Universal ([8e6eb48](https://github.com/ghiscoding/slickgrid-universal/commit/8e6eb4881741313b7d582d2e3d17ffef582ecb35))
+
* **plugins:** move external GroupItemMetataProvider into Universal ([8f18c7d](https://github.com/ghiscoding/slickgrid-universal/commit/8f18c7d3d616e4cd72eb5478d544ec241c53154f))
+
* **plugins:** move external Header Button into Slickgrid-Universal ([69711ad](https://github.com/ghiscoding/slickgrid-universal/commit/69711aded5aa835091789800214f82cd7c72753e))
+
* **plugins:** move external Header Menu into Slickgrid-Universal ([aeba480](https://github.com/ghiscoding/slickgrid-universal/commit/aeba4801fdb5cba3976984f5c591be8c1ad97e4b))
+
* **plugins:** move Row Detail View plugin to universal ([9700ff4](https://github.com/ghiscoding/slickgrid-universal/commit/9700ff49132e9408b808f916f634976d80e12579))
+
* **plugins:** move Row Detail View plugin to universal ([fb327a6](https://github.com/ghiscoding/slickgrid-universal/commit/fb327a6abe85b86683572cde2a550de43a01f9e1))
+
* **plugins:** move Row Move Manager plugin to universal ([b19b2ed](https://github.com/ghiscoding/slickgrid-universal/commit/b19b2ed2da669662fbbdcf9fdefac243132909b2))
+
* **plugins:** replace AutoTooltips Extension by plugin ([80df14d](https://github.com/ghiscoding/slickgrid-universal/commit/80df14da9b66e9e1b8314e5adb1b96890cc7baa1))
+
* **plugins:** show bullet when command menu icon missing ([cbe580a](https://github.com/ghiscoding/slickgrid-universal/commit/cbe580a97313b7b90e287586b4a6420f0a983f20))
+
* **selection:** add `caller` property to `onSelectedRowsChanged` event ([cc5f4ae](https://github.com/ghiscoding/slickgrid-universal/commit/cc5f4aec7334b6d001bde55dacf83722c3b2763b))
+
* **utils:** replace ext lib `assign-deep` by local `deepMerge` util ([2f56bd3](https://github.com/ghiscoding/slickgrid-universal/commit/2f56bd3571d9c5fb689a09d21cfb3813f5b70e89))
## [0.19.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.19.1...v0.19.2) (2021-11-19)
@@ -782,8 +1083,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** add DOM purify optional default import to fix rollup builds ([3bd335d](https://github.com/ghiscoding/slickgrid-universal/commit/3bd335dd62d0829c1581ca0fde560c93dcd84458))
+
* **resizer:** use autosize width when total width smaller than viewport ([555fb0c](https://github.com/ghiscoding/slickgrid-universal/commit/555fb0cb793c111de837ffe6e9f212fcbf5ed701))
+
* **translation:** add new UNFREEZE_COLUMNS to fix translation ([0010861](https://github.com/ghiscoding/slickgrid-universal/commit/001086165434f619f1e90f664e2185b77fb6a92e))
+
* **translation:** add new UNFREEZE_COLUMNS to fix translation ([22ed231](https://github.com/ghiscoding/slickgrid-universal/commit/22ed2313c45587f2ebdb279c9e47df881c6f83d6))
## [0.19.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.19.0...v0.19.1) (2021-11-15)
@@ -791,8 +1095,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **context:** strin hidden special chars on context menu Copy command ([221c05d](https://github.com/ghiscoding/slickgrid-universal/commit/221c05d8d6345d090074c92e423071888e4a2686))
+
* **context:** when copying use opacity 0 on temp element ([3f0896f](https://github.com/ghiscoding/slickgrid-universal/commit/3f0896fab30aa5a3da278912f00272ce434b8c15))
+
* **subscriptions:** unsubscribe every subcriptions while disposing comp ([bf0dcd4](https://github.com/ghiscoding/slickgrid-universal/commit/bf0dcd4963171b703f07e705aac7230402c84dbf))
+
* **tree:** reset to initial tree sort when calling "Clear all Sorting" ([984e3a7](https://github.com/ghiscoding/slickgrid-universal/commit/984e3a7bf0bf734f035514d32d44c6164c6fdab1))
# [0.19.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.18.0...v0.19.0) (2021-10-28)
@@ -800,17 +1107,25 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* make it work with AutoTooltip and extra option to skip it ([2f7e4c5](https://github.com/ghiscoding/slickgrid-universal/commit/2f7e4c502471c236a76510905ddbf07f653ea5d8))
+
* **frozen:** calling `setPinning` with empty object/null should clear it ([48b11f7](https://github.com/ghiscoding/slickgrid-universal/commit/48b11f74f2ce6541b6e6e03bf7fe194e5be96d0e))
+
* **style:** remove unnecessary css source map ([4e6fc08](https://github.com/ghiscoding/slickgrid-universal/commit/4e6fc085abe19389d28bf7a8cea3f83859582bdc))
+
* **styling:** cleanup CSS files to ship smaller bundle ([69b18bf](https://github.com/ghiscoding/slickgrid-universal/commit/69b18bf3505fc5538de878b7dbf33104faa8b11a))
+
* **tree:** Grid State should have Tree Data initial sort ([b24ce40](https://github.com/ghiscoding/slickgrid-universal/commit/b24ce4032ea671aa6de6d8e2bb8b045359fd897b))
+
* **tree:** use previous state when refreshing dataset afterward ([0982474](https://github.com/ghiscoding/slickgrid-universal/commit/09824741be404d3d05ccff4417f243c4b1c5c113))
### Features
* **plugin:** add row move shadown item while moving/dragging row ([c665ec8](https://github.com/ghiscoding/slickgrid-universal/commit/c665ec88be859feeea89e5ab8826f2b0a57c5cfb))
+
* add async process to use with Promise/Observable ([7350a6d](https://github.com/ghiscoding/slickgrid-universal/commit/7350a6d06ef5bb8495a05e22421f9b7b5a4270cb))
+
* add auto-position depending on available space ([82d6134](https://github.com/ghiscoding/slickgrid-universal/commit/82d6134003900ca8e345bd02a35e3830476638e3))
+
* **plugin:** create new Custom Tooltip plugin ([4c8c4f6](https://github.com/ghiscoding/slickgrid-universal/commit/4c8c4f62423665bc2e1dcf0675b1300607397b6a))
# [0.18.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.17.0...v0.18.0) (2021-09-29)
@@ -818,18 +1133,27 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **context:** Copy Cell via Context Menu shouldn't include Tree symbols ([f710084](https://github.com/ghiscoding/slickgrid-universal/commit/f710084c06cd47d900daccd389de131209e19163))
+
* **filters:** css "filled" class on filters should also work w/Grid View ([e8edae7](https://github.com/ghiscoding/slickgrid-universal/commit/e8edae79bcd5c28438203e269d26f107e26c4ae5))
+
* **resizer:** clear pending resizeGrid on dispose ([07ed6a0](https://github.com/ghiscoding/slickgrid-universal/commit/07ed6a0390f235341b116d981aa4ee84719b029b))
+
* **resizer:** only bind autoresize when enabled ([ca894c0](https://github.com/ghiscoding/slickgrid-universal/commit/ca894c0a83b5762a42b703f28fc59bdb38e01944))
+
* **styling:** List bullets shouldn't show in any frameworks, fixes [#487](https://github.com/ghiscoding/slickgrid-universal/issues/487) ([53ea537](https://github.com/ghiscoding/slickgrid-universal/commit/53ea5379c6109383630362717b980a1dbe099681))
+
* **tree:** when Tree Data is filtered then Sort, footer count is invalid ([4f5fc44](https://github.com/ghiscoding/slickgrid-universal/commit/4f5fc443fbc7a0ab3cbe46722fc6bd85fd4b1594))
### Features
* **context:** expose 3 events for Tree/Grouping clear/collapse/expand ([317f3ad](https://github.com/ghiscoding/slickgrid-universal/commit/317f3ad443f8ac81c7cacacaec6d38553bec147b))
+
* **Resizer:** add useResizeObserver option ([bb33cdd](https://github.com/ghiscoding/slickgrid-universal/commit/bb33cdd716834913846ab2fcf74a84f8424acf92))
+
* **sorts:** option to ignore accent while sorting text ([1b4fe81](https://github.com/ghiscoding/slickgrid-universal/commit/1b4fe81d613b780aefcc0ba3e7b16c20eaebd0aa))
+
* **styling:** increase highlight of filters that are filled w/values ([8f93534](https://github.com/ghiscoding/slickgrid-universal/commit/8f9353418190ee3e11aca65d1a57fa4204331011))
+
* **tree:** new `excludeChildrenWhenFilteringTree` set as new default ([47df943](https://github.com/ghiscoding/slickgrid-universal/commit/47df943414f383a47062a7ad9245700a1bd8a24e))
# [0.17.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.16.2...v0.17.0) (2021-09-09)
@@ -837,25 +1161,41 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **filters:** IN_CONTAINS should be sanitized when used with html ([961d8fd](https://github.com/ghiscoding/slickgrid-universal/commit/961d8fd7ea6f915dd8f0749d0329219b82923fea))
+
* **filters:** remove Filters from DOM after header row gets destroyed ([b08d4ba](https://github.com/ghiscoding/slickgrid-universal/commit/b08d4ba070ec9d9d131d6830e4625e6ef950ac09))
+
* **grouping:** Draggable Grouping should clear preheader when called ([37811a5](https://github.com/ghiscoding/slickgrid-universal/commit/37811a51d2af04e78aedc88ff5d8eae8a622ac40))
+
* **resizer:** regression introduced by [#462](https://github.com/ghiscoding/slickgrid-universal/issues/462) for the grid resize in SF ([f34d8b9](https://github.com/ghiscoding/slickgrid-universal/commit/f34d8b9678c7ee9e76534a7f7ffdf2c4d7f9f772))
+
* **resizer:** resizer not always triggered in SF and show broken UI ([89fc62e](https://github.com/ghiscoding/slickgrid-universal/commit/89fc62eff7fac8b5cf43b3b6acd7590ed84288f6))
+
* **state:** don't use previous columns ref when getting current cols ([f312c60](https://github.com/ghiscoding/slickgrid-universal/commit/f312c60349d5bc95527ec93cb752f449d1c761f7))
+
* **styling:** add ms-select placeholder bg-color to fix Bootstrap 5 ([2c34d12](https://github.com/ghiscoding/slickgrid-universal/commit/2c34d1229c14bd36bd034062cc7eb7a7cbe1bf5c))
+
* **styling:** add ms-select placeholder bg-color to fix Bootstrap 5 ([5d6454e](https://github.com/ghiscoding/slickgrid-universal/commit/5d6454e9f175b8694f372a7e26492ae573eb918f))
### Features
* **aggregators:** add better TS typing for all Aggregators ([1518d6a](https://github.com/ghiscoding/slickgrid-universal/commit/1518d6aef194f184390316f8421f51d23a1d470a))
+
* **backend:** add cancellable onBeforeSearchChange & revert on error ([b26a53d](https://github.com/ghiscoding/slickgrid-universal/commit/b26a53d2e1fc7172c8c054b9c27ab1b3a2d3dff6))
+
* **backend:** add cancellable onBeforeSort & revert sort on error ([958f823](https://github.com/ghiscoding/slickgrid-universal/commit/958f823a6bffedc2c146c7c68d49a29419812995))
+
* **backend:** add cancellable Pagination change & revert on error ([7a8d903](https://github.com/ghiscoding/slickgrid-universal/commit/7a8d9038f230ba433f2773c02992a211a322ebd4))
+
* **composite:** move SlickGrid Composite Editor factory into universal ([c813cea](https://github.com/ghiscoding/slickgrid-universal/commit/c813ceac1ed6535963df15e7933a444de3a8790a))
+
* **editors:** add Ctrl+S combo to enhance LongText (textarea) Editor ([5116bbd](https://github.com/ghiscoding/slickgrid-universal/commit/5116bbd9e837a3bbd9835b10b2167edf3561cd3d))
+
* **filters:** option to ignore accent while filtering text, closes [#470](https://github.com/ghiscoding/slickgrid-universal/issues/470) ([cba9a4e](https://github.com/ghiscoding/slickgrid-universal/commit/cba9a4e4d12b6dfaaec06af5edf4c629b2943feb))
+
* **sanitize:** make sure any string sent to innerHtml are sanitized ([fe55046](https://github.com/ghiscoding/slickgrid-universal/commit/fe550461d27d01cb5c54d93812db82fa7213f96b))
+
* **styling:** only show header menu caret when hovering ([41e7856](https://github.com/ghiscoding/slickgrid-universal/commit/41e7856f9483f7228d1455f2e3810ae58a5f5c8d))
+
* **tree:** add `dynamicallyToggledItemState` method to toggle parent(s) ([26369f9](https://github.com/ghiscoding/slickgrid-universal/commit/26369f9b6c9e81ad5705f580896ab28cf362d090))
## [0.16.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.16.1...v0.16.2) (2021-07-23)
@@ -863,6 +1203,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **formatters:** Complex Object Formatter shouldn't throw with null data ([3421465](https://github.com/ghiscoding/slickgrid-universal/commit/342146557c16b560b5b8ef0f0e47f971179bc765))
+
* **tree:** exclude the correct type from interface argument ([af51784](https://github.com/ghiscoding/slickgrid-universal/commit/af51784aa3471dcc88c567f4c3762ab7590184f6))
## [0.16.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.16.0...v0.16.1) (2021-07-16)
@@ -876,7 +1217,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **filter:** refreshTreeDataFilters only when Tree is enabled ([07c70d5](https://github.com/ghiscoding/slickgrid-universal/commit/07c70d5d17dab464cefb1046c72abbd41da4c834))
+
* **filters:** always find locale even without TranslaterService ([c4b17c4](https://github.com/ghiscoding/slickgrid-universal/commit/c4b17c4f51ba6f80b907dab0fd0493a8b0944908))
+
* **styling:** remove css variable on width causing UX problem ([df69f9c](https://github.com/ghiscoding/slickgrid-universal/commit/df69f9c33604187f91adaf5bb8b43b6abd624d32))
### Features
@@ -884,7 +1227,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
* **aria:** add aria-label to all Editors/Filters & other html templates ([1a4f8f7](https://github.com/ghiscoding/slickgrid-universal/commit/1a4f8f7873d76b7da5a7d38debed598d3d395c10))
* make constructor arguments as readonly ([a4588ea](https://github.com/ghiscoding/slickgrid-universal/commit/a4588ea5722ae44b647b8c0d02cf8e2a60ff5963))
+
* **services:** make everything extendable by using `protected` ([ecbb93a](https://github.com/ghiscoding/slickgrid-universal/commit/ecbb93a56abba39dd050bbd6019b86694495edd1))
+
* **styling:** add support for CSS Variables ([674dd1a](https://github.com/ghiscoding/slickgrid-universal/commit/674dd1a064d4d42af1d5841ac87ba8ea35a26b2f))
# [0.15.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.14.1...v0.15.0) (2021-07-06)
@@ -892,48 +1237,87 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **addon:** providing columnIndexPosition should always work ([42c8cff](https://github.com/ghiscoding/slickgrid-universal/commit/42c8cff7dd6cf9103149445969be289710549590))
+
* **demo:** we should be able to move row(s) and keep selections ([d5669a1](https://github.com/ghiscoding/slickgrid-universal/commit/d5669a1d9c07680540d084dad6e1ef06faca0357))
+
* **editors:** longText Editor (textarea) was scrolling to page bottom ([a4e37a0](https://github.com/ghiscoding/slickgrid-universal/commit/a4e37a0baf329a100f72fe12c35af67fa072829a))
+
* **editors:** select dropdown value is undefined it shouldn't call save ([015294b](https://github.com/ghiscoding/slickgrid-universal/commit/015294b86e431e8109ce540dda7856b7e9e27575))
+
* **filters:** filtering with IN_CONTAINS should also work with spaces ([ab54724](https://github.com/ghiscoding/slickgrid-universal/commit/ab5472437b94fe81270f809ab6fd00f204c688b8))
+
* **frozen:** in some occasion column pinning changes column positions ([70cb74e](https://github.com/ghiscoding/slickgrid-universal/commit/70cb74ef1119a60b37d438130d4a463a87a8939a))
+
* **menu:** toggle filter bar could be out of sync w/horizontal scroll ([ab7f589](https://github.com/ghiscoding/slickgrid-universal/commit/ab7f58929b10d1b250765b707363aedd9f9d7866))
+
* **pagination:** should be able to toggle Pagination ([c0367c2](https://github.com/ghiscoding/slickgrid-universal/commit/c0367c24da2ccb3558e1b27f8e70a81d84201479))
+
* **plugin:** row move shouldn't go further when onBefore returns false ([e9bfb5c](https://github.com/ghiscoding/slickgrid-universal/commit/e9bfb5ceba6a18a020b8b34f72abba6e3d13d8b8))
+
* **resizer:** few fixes & adjustments after trying in SF ([32e80ec](https://github.com/ghiscoding/slickgrid-universal/commit/32e80ecdbc5072c1619593d101289a3c1ea92b3a))
+
* **services:** toggle pagination was not displaying all row selection ([e51ccb4](https://github.com/ghiscoding/slickgrid-universal/commit/e51ccb4352bf3a578159b8b63f0a6caf891c382a))
+
* **state:** changeColumnsArrangement should work w/columnIndexPosition ([7c1e9d3](https://github.com/ghiscoding/slickgrid-universal/commit/7c1e9d3d243988d6d99a9696b0afbe8f62ac45b4))
+
* **state:** Grid View/Columns dynamically should work w/row move ([a7cf1df](https://github.com/ghiscoding/slickgrid-universal/commit/a7cf1dfb73c770908aadf01fd67680c985449f9d))
+
* **state:** Grid View/Columns dynamically should work w/row selection ([865944f](https://github.com/ghiscoding/slickgrid-universal/commit/865944f5d6aadc0c05c7f83db7c11a569a33118f))
+
* **styling:** address latest dart-sass math division deprecation warning ([b7317d8](https://github.com/ghiscoding/slickgrid-universal/commit/b7317d8fa619b35fb65789e12b268d65ff65968c))
+
* **styling:** header title should show ellipsis if too long ([607e14d](https://github.com/ghiscoding/slickgrid-universal/commit/607e14d7fffa4f9854eff5103e1a1a0881664286))
+
* **tree:** using `initiallyCollapsed` change internal toggled state ([380f2f9](https://github.com/ghiscoding/slickgrid-universal/commit/380f2f903d9908e2bed5b3f44d04e28e5d5b9c63))
+
* initial grid state should also include toggled presets ([f1fe39f](https://github.com/ghiscoding/slickgrid-universal/commit/f1fe39f5d68487e815be7fd3d7ca5a6fd4cba7c6))
+
* **tree:** calling updateItems should not lose the Tree collapsing icon ([45b9622](https://github.com/ghiscoding/slickgrid-universal/commit/45b96225dd5a676b6a85bbb2c8146137eb95b33f))
+
* option labels weren't showing correctly after running Cypress tests ([10d4339](https://github.com/ghiscoding/slickgrid-universal/commit/10d4339da70cce4977707a6a19a79cceb4bf87df))
+
* provide input type directly in constructor before init() is called ([e89c3bd](https://github.com/ghiscoding/slickgrid-universal/commit/e89c3bd3da66e4b16342cefe1eedd5df96363e45))
### Features
* **components:** extract Custom Footer to be an external component ([1794c27](https://github.com/ghiscoding/slickgrid-universal/commit/1794c27d7669c172f606d709d3360bc5d2f77798))
+
* **editors:** convert jQuery to native element on slider editor ([3181cf0](https://github.com/ghiscoding/slickgrid-universal/commit/3181cf069d9f3bc85dc0d13ceeb9623d21ae8eff))
+
* **editors:** replace jQuery with native element on date editor ([062f1f9](https://github.com/ghiscoding/slickgrid-universal/commit/062f1f9713c8f236c30b4d631b601b24b56a530d))
+
* **editors:** use class inheritance to extend main input editor ([ad3e696](https://github.com/ghiscoding/slickgrid-universal/commit/ad3e6965d4cd4295086401de26b5d3aad13a7650))
+
* **filters:** build multiple-select options from native dom elements ([aa548a9](https://github.com/ghiscoding/slickgrid-universal/commit/aa548a9bc05da0d4d5233a2633ae3055fd9f7178))
+
* **filters:** convert jQuery to native element on more filters ([b46eb5e](https://github.com/ghiscoding/slickgrid-universal/commit/b46eb5ebdb177e7d0d6c93cb6df541cedc7eb5d1))
+
* **filters:** convert jQuery to native elements on multiple filters ([3a80996](https://github.com/ghiscoding/slickgrid-universal/commit/3a80996bec96e465d23a30387af707289f4089e3))
+
* **footer:** add option to customize right footer text ([2ea41cc](https://github.com/ghiscoding/slickgrid-universal/commit/2ea41cc8ab38ebc5d5276c90de33b57247c4476f))
+
* **formatters:** add Bootstrap Dropdown Formatter ([5ba9423](https://github.com/ghiscoding/slickgrid-universal/commit/5ba9423200e60460c22f05253901707ef7055782))
+
* **services:** convert jQuery to native elements ([4da0a20](https://github.com/ghiscoding/slickgrid-universal/commit/4da0a201aaa866447a0c76e3b9c16503e2ed6af9))
+
* **services:** decouple the EventPubSubService to separate package ([9f51665](https://github.com/ghiscoding/slickgrid-universal/commit/9f516655e9ce5f06e0cfeabc43536834dc38c70b))
+
* **services:** move Resizer Service w/common services folder for reuse ([d127ac7](https://github.com/ghiscoding/slickgrid-universal/commit/d127ac797ee787ea7785e8ae9f4c0bcaed786afd))
+
* **styling:** add a new `color-disabled-dark` ([55c3062](https://github.com/ghiscoding/slickgrid-universal/commit/55c30621241ec5da7a2e19879265c4e15a6ad907))
+
* **styling:** add a new `color-disabled` ([7151198](https://github.com/ghiscoding/slickgrid-universal/commit/7151198dd393c0bc93151cc4dc9c3295917b6b3e))
+
* **styling:** add extra material icons & new color ([4205b66](https://github.com/ghiscoding/slickgrid-universal/commit/4205b664e80af691c72d5520e4778ad4cd7d94b3))
+
* **tree:** add `getItemCount` method with optional tree level ([b3f8f94](https://github.com/ghiscoding/slickgrid-universal/commit/b3f8f9484e7ea352b2ed264c6a27e1e091eaf918))
+
* **tree:** add Tree Collapse Grid State/Preset ([998b01a](https://github.com/ghiscoding/slickgrid-universal/commit/998b01a2f10ccee5636f616921dd86b35a4feaec))
+
* **tree:** add ways to reapply Tree Collapse previous state ([3702ed3](https://github.com/ghiscoding/slickgrid-universal/commit/3702ed32629f84397349147c978ca650043c45eb))
+
* add new Input Password Editor which uses common inputEditor ([87e547c](https://github.com/ghiscoding/slickgrid-universal/commit/87e547c0dbccc106a1109c3902ac2027fbd52138))
+
* convert jQuery to native element on few more filters ([7d5e1e8](https://github.com/ghiscoding/slickgrid-universal/commit/7d5e1e859a0331699d6fb07d2d35797d7274d1df))
## [0.14.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.14.0...v0.14.1) (2021-05-22)
@@ -947,37 +1331,65 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **backend:** able to preset filters on hidden columns & all queried ([c610979](https://github.com/ghiscoding/slickgrid-universal/commit/c610979c54170c069b97a71864d95d0363d75e80))
+
* **editors:** select editor inline blur save before destroy ([0e591b1](https://github.com/ghiscoding/slickgrid-universal/commit/0e591b1812fc1c733c03f7afcf81dee7a3e4b107))
+
* **frozen:** rollback previous commit since the issue was found in SlickGrid (core) ([780bcd7](https://github.com/ghiscoding/slickgrid-universal/commit/780bcd7bfae35e26cd84c9a6d220e2dab9eca3b4))
+
* **resizer:** remove delay to call resize by content to avoid flickering ([961efe6](https://github.com/ghiscoding/slickgrid-universal/commit/961efe6fe7ad721e8196c76ed4c35205830b6b83))
+
* **services:** fix couple of issues found with custom grid views ([db06736](https://github.com/ghiscoding/slickgrid-universal/commit/db0673688b2b6e6dde8f25af9551bf6c27174a44))
+
* **sorting:** multi-column sort shouldn't work when option is disabled ([bfc8651](https://github.com/ghiscoding/slickgrid-universal/commit/bfc865128de0a9e4c21ff0dc8b564c15c88dea93))
+
* **styling:** center horizontally checkbox selector in column header ([bb5aebc](https://github.com/ghiscoding/slickgrid-universal/commit/bb5aebc355a22e19b0071bfe993bbeb0e1090265))
+
* **tree:** Tree Data export should also include correct indentation ([f1e06c1](https://github.com/ghiscoding/slickgrid-universal/commit/f1e06c11f9eaa9ee778d319bfbaba20bb9abfcc9))
+
* add item should work in the demo even with filter preset ([d9c97eb](https://github.com/ghiscoding/slickgrid-universal/commit/d9c97ebb587184e94439f6fde1ec8c8a739e7bfa))
+
* add item to flat and/or tree should both work ([1b19028](https://github.com/ghiscoding/slickgrid-universal/commit/1b19028c9d58a31597906e371f439b094bca7ff0))
+
* adding optional tree level property should be used when sorting ([a3598c5](https://github.com/ghiscoding/slickgrid-universal/commit/a3598c519a875585498cc828b5a0e76e95890795))
+
* addItem from grid service should work with tree data ([8b468f0](https://github.com/ghiscoding/slickgrid-universal/commit/8b468f055144b001378395546519d1801e046a0a))
+
* export to file/excel should also have tree indentation ([8c4c2b8](https://github.com/ghiscoding/slickgrid-universal/commit/8c4c2b8d30bb78e927f0a28bb0f7bef81e95d789))
+
* Grid Service addItem should invalidate hierarchical dataset itself ([066e894](https://github.com/ghiscoding/slickgrid-universal/commit/066e894271603562b10e014c4febfb18626e54f0))
+
* previous commit caused issue with composite editor ([13c2a49](https://github.com/ghiscoding/slickgrid-universal/commit/13c2a49916282c1888ae23c1720a617755341e0f))
+
* return all onBeforeX events in delayed promise to fix spinner ([bb36d1a](https://github.com/ghiscoding/slickgrid-universal/commit/bb36d1af114031eb973cf9993bdb9be1dd050de3))
+
* **formatters:** Tree Data use nullish coallescing w/optional chaining ([f6cf14c](https://github.com/ghiscoding/slickgrid-universal/commit/f6cf14c06518d47742ee17d82a22a39af490c9e7))
+
* **styling:** add a better search filter magnify glass icon as placeholder ([5464824](https://github.com/ghiscoding/slickgrid-universal/commit/5464824f3719ebddb303ee1b82161638d870a288))
+
* **tree:** couple of issues found in Tree Data, fixes [#307](https://github.com/ghiscoding/slickgrid-universal/issues/307) ([e684d1a](https://github.com/ghiscoding/slickgrid-universal/commit/e684d1af1c078a8861c3c94fe5486cbe68d57b85))
### Features
* **addon:** provide grid menu labels for all built-in commands ([44c72d3](https://github.com/ghiscoding/slickgrid-universal/commit/44c72d3ca0b8a88e6ae5022a25b11c4d41fd2897))
+
* **editors:** add `compositeEditorFormOrder` option ([03f2d66](https://github.com/ghiscoding/slickgrid-universal/commit/03f2d662a69d71edf4b61cdda862fb4eef0f9b47))
+
* **editors:** add ways to preload date without closing date picker ([3088038](https://github.com/ghiscoding/slickgrid-universal/commit/30880380584b281c756e0ad437031631e6f607e0))
+
* **resizer:** add `resizeByContentOnlyOnFirstLoad` grid option ([ffe7dc4](https://github.com/ghiscoding/slickgrid-universal/commit/ffe7dc4c2a7ae778c8e731fd7637b154c10035f0))
+
* **resizer:** add single Column Resize by Content dblClick & headerMenu ([683389f](https://github.com/ghiscoding/slickgrid-universal/commit/683389fcc343ac5c0378a9e34b7f11dda97fc719))
+
* **styling:** add new marker material icons for project ([9b386fa](https://github.com/ghiscoding/slickgrid-universal/commit/9b386fa3e6af8e76cf4beb5aa0b5322db2f270af))
+
* add `titleFormatter` to Tree Data ([8bf32ca](https://github.com/ghiscoding/slickgrid-universal/commit/8bf32caa08a6c5a28c7114cb8abe33a5ed9bc4cb))
+
* add few pubsub events to help with big dataset ([360c62c](https://github.com/ghiscoding/slickgrid-universal/commit/360c62cb0979792dddef8fab39383266c0d855e3))
+
* add optional child value prefix to Tree Formatter ([9da9662](https://github.com/ghiscoding/slickgrid-universal/commit/9da966298120686929ab3dd2f276574d7f6c8c7e))
+
* **tree:** improve Tree Data speed considerably ([5487798](https://github.com/ghiscoding/slickgrid-universal/commit/548779801d06cc9ae7e319e72d351c8a868ed79f))
+
* **editors:** replace jQuery with native elements ([d6e8f4e](https://github.com/ghiscoding/slickgrid-universal/commit/d6e8f4e59823673df290b179d7ee277e3d7bb1af))
# [0.13.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.12.0...v0.13.0) (2021-04-27)
@@ -985,20 +1397,31 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **editors:** Composite Editor modal compo should work w/complex objects ([#298](https://github.com/ghiscoding/slickgrid-universal/issues/298)) ([721a6c5](https://github.com/ghiscoding/slickgrid-universal/commit/721a6c5627369cfc89710705384995f8aba3a178))
+
* **exports:** grid with colspan should be export accordingly ([#311](https://github.com/ghiscoding/slickgrid-universal/issues/311)) ([e899fbb](https://github.com/ghiscoding/slickgrid-universal/commit/e899fbba3daa41261dcaa57b0555e37e9bdfafb4))
+
* **observables:** http cancellable Subject should be unsubscribed ([cbc951b](https://github.com/ghiscoding/slickgrid-universal/commit/cbc951bcf5891658f55981e88887f41b4fb5d5c4))
+
* **selection:** full row selection should be selected w/show hidden row ([f76e30c](https://github.com/ghiscoding/slickgrid-universal/commit/f76e30cdca476c947089d88069bd21e42639ba7e))
### Features
* **editors:** add `onBeforeOpen` optional callback to Composite Editor ([#306](https://github.com/ghiscoding/slickgrid-universal/issues/306)) ([a642482](https://github.com/ghiscoding/slickgrid-universal/commit/a642482254009115366ca4992e2e60647f8ae9b0))
+
* **editors:** add `target` to `onBeforeEditCell` w/called by composite ([#301](https://github.com/ghiscoding/slickgrid-universal/issues/301)) ([7440ff5](https://github.com/ghiscoding/slickgrid-universal/commit/7440ff58988acd7abd1ce249b1ceb72556cceb1d))
+
* **filters:** add option to filter empty values for select filter ([#310](https://github.com/ghiscoding/slickgrid-universal/issues/310)) ([c58a92a](https://github.com/ghiscoding/slickgrid-universal/commit/c58a92a8e2b29ea216211e3561d5567c43f0376a))
+
* **filters:** option to add custom compound operator list ([3e8d2cb](https://github.com/ghiscoding/slickgrid-universal/commit/3e8d2cbcea6181e3ce3157798f003a8479d11011))
+
* **footer:** add row selection count to the footer component ([8ba146c](https://github.com/ghiscoding/slickgrid-universal/commit/8ba146cd4cbdccdb61f3441918065fad4561ff84))
+
* **resize:** add column resize by cell content ([#309](https://github.com/ghiscoding/slickgrid-universal/issues/309)) ([515a072](https://github.com/ghiscoding/slickgrid-universal/commit/515a072b3a16d3aca0f48e62c968ae89a1510669))
+
* **services:** remove deprecated hideColumnByIndex form Grid Service ([#312](https://github.com/ghiscoding/slickgrid-universal/issues/312)) ([b00c64d](https://github.com/ghiscoding/slickgrid-universal/commit/b00c64d8f88d4560c677f667a84d95ba30e96399))
+
* **styling:** switch from node-sass to dart-sass (sass) ([81f8d9f](https://github.com/ghiscoding/slickgrid-universal/commit/81f8d9fbd1381b4c877eeeb4992bdcc90c1cd677))
+
* **typing:** add missing item metadata interface ([#299](https://github.com/ghiscoding/slickgrid-universal/issues/299)) ([7cf0a21](https://github.com/ghiscoding/slickgrid-universal/commit/7cf0a2185c73dcb7748a193ba2272bb7af699266))
# [0.12.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.11.2...v0.12.0) (2021-03-24)
@@ -1006,26 +1429,43 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **editors:** show all editors as 100% height in their cell container ([#277](https://github.com/ghiscoding/slickgrid-universal/issues/277)) ([3f49aea](https://github.com/ghiscoding/slickgrid-universal/commit/3f49aeabd6016c705d4d6b809345fe1ac948cfc5))
+
* **filters:** rollback a change made in PR [#288](https://github.com/ghiscoding/slickgrid-universal/issues/288) causing preset issues ([18ffc0c](https://github.com/ghiscoding/slickgrid-universal/commit/18ffc0c8285e4e2306bc60817fba357734a65b61))
+
* **filters:** SearchTerms shouldn't come back after calling clearFilters ([04f3d12](https://github.com/ghiscoding/slickgrid-universal/commit/04f3d1267de493b9dc1e922dca3b433b9cb34fde))
+
* **filters:** string <> should be Not Contains instead of Not Equal ([#276](https://github.com/ghiscoding/slickgrid-universal/issues/276)) ([960884d](https://github.com/ghiscoding/slickgrid-universal/commit/960884ddf58b1e87ad5ef71e3713f8836e6190c0))
+
* **firefox:** add all missing SVG color filter classes for Firefox/SF ([#296](https://github.com/ghiscoding/slickgrid-universal/issues/296)) ([a07ebdf](https://github.com/ghiscoding/slickgrid-universal/commit/a07ebdfbd2c2197c28102efe1f4a685ea61185e1))
+
* **pinning:** reordering cols position freezing cols shouldn't affect ([#275](https://github.com/ghiscoding/slickgrid-universal/issues/275)) ([a30665d](https://github.com/ghiscoding/slickgrid-universal/commit/a30665d54da583c47b1f533002173af99e9ab20d))
+
* **plugin:** Grid Menu Clear Frozen Cols shouldn't change cols positions ([#291](https://github.com/ghiscoding/slickgrid-universal/issues/291)) ([4fdab08](https://github.com/ghiscoding/slickgrid-universal/commit/4fdab08357d12349b6402e3007f4ab399d9a2140))
+
* **presets:** Filter & Sorting presets & Footer metrics issues ([#285](https://github.com/ghiscoding/slickgrid-universal/issues/285)) ([3174c86](https://github.com/ghiscoding/slickgrid-universal/commit/3174c86e011b4927510b99a348e8019adb4baa00))
+
* **presets:** Multiple Select Filter Grid Presets values should be shown ([dd1f231](https://github.com/ghiscoding/slickgrid-universal/commit/dd1f231850819bde455e24d743b9e1637767ecb3))
+
* **resizer:** allow gridHeight/gridWidth to be passed as string ([#284](https://github.com/ghiscoding/slickgrid-universal/issues/284)) ([20bda50](https://github.com/ghiscoding/slickgrid-universal/commit/20bda50bf3ab647ae4ee3d7ffe0c9c8b58e8f187)), closes [#534](https://github.com/ghiscoding/slickgrid-universal/issues/534)
+
* **sorting:** add some unit tests that were previously commented out ([#290](https://github.com/ghiscoding/slickgrid-universal/issues/290)) ([2a91fa6](https://github.com/ghiscoding/slickgrid-universal/commit/2a91fa6f672650bb525a4ba1774d02c5ac435c5b))
### Features
* **editors:** add `onSelect` callback to Autocomplete Editor ([#286](https://github.com/ghiscoding/slickgrid-universal/issues/286)) ([2d106d4](https://github.com/ghiscoding/slickgrid-universal/commit/2d106d4df0a259d36bee3d910320706ddb7e8580))
+
* **filters:** add new IN_COLLECTION operator to allow searching cell value as Array ([#282](https://github.com/ghiscoding/slickgrid-universal/issues/282)) ([ecce93c](https://github.com/ghiscoding/slickgrid-universal/commit/ecce93c92b7424522ad2af0d7d82963a3a56ca97))
+
* **filters:** add optional `filterTypingDebounce` for filters w/keyup ([#289](https://github.com/ghiscoding/slickgrid-universal/issues/289)) ([3aecc89](https://github.com/ghiscoding/slickgrid-universal/commit/3aecc899ebd78d9597cc4ed4919c0a8dd26673a8))
+
* **filters:** add optional `filterTypingDebounce` for keyboard filters ([#283](https://github.com/ghiscoding/slickgrid-universal/issues/283)) ([bb7dcd3](https://github.com/ghiscoding/slickgrid-universal/commit/bb7dcd3a9e28f45c7339e2f30685220b7a152507))
+
* **filters:** add possibility to filter by text range like "a..e" ([#279](https://github.com/ghiscoding/slickgrid-universal/issues/279)) ([e44145d](https://github.com/ghiscoding/slickgrid-universal/commit/e44145d897da570bf6ea15b156c7961ce96ce6f0))
+
* **filters:** display operator into input text filter from Grid Presets ([#288](https://github.com/ghiscoding/slickgrid-universal/issues/288)) ([3fad4fe](https://github.com/ghiscoding/slickgrid-universal/commit/3fad4fe9ef3bec290dabb860d7ea4baf8f182a4a))
+
* **resources:** add RxJS support into Slickgrid-Universal via external package ([#280](https://github.com/ghiscoding/slickgrid-universal/issues/280)) ([c10fc33](https://github.com/ghiscoding/slickgrid-universal/commit/c10fc339019c04ec0f7c4357ccdb3949a2358460))
+
* **state:** add Pinning (frozen) to Grid State & Presets ([#292](https://github.com/ghiscoding/slickgrid-universal/issues/292)) ([ba703d8](https://github.com/ghiscoding/slickgrid-universal/commit/ba703d8353a243ffed4d40804c0f977119424f6c))
## [0.11.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.11.1...v0.11.2) (2021-02-27)
@@ -1045,19 +1485,29 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** enable tsconfig strict mode tsconfig ([#269](https://github.com/ghiscoding/slickgrid-universal/issues/269)) ([095fc71](https://github.com/ghiscoding/slickgrid-universal/commit/095fc71052c1f4e776544781da5fe762cfa16238))
+
* **filters:** don't use indexOf NOT_IN_CONTAINS ([#262](https://github.com/ghiscoding/slickgrid-universal/issues/262)) ([310be30](https://github.com/ghiscoding/slickgrid-universal/commit/310be30efb653151a75dde0a14b1ed3f9946b333))
+
* **filters:** use defaultFilterOperator in range when none provided ([#271](https://github.com/ghiscoding/slickgrid-universal/issues/271)) ([993675f](https://github.com/ghiscoding/slickgrid-universal/commit/993675f6b0d76e76010d5cadc6696134a73dad66))
+
* **helpers:** should be able to highlight first row (0) ([#268](https://github.com/ghiscoding/slickgrid-universal/issues/268)) ([a58be17](https://github.com/ghiscoding/slickgrid-universal/commit/a58be17959e28ab9a1280c3d7d7c8df9db02587e)), closes [#527](https://github.com/ghiscoding/slickgrid-universal/issues/527)
+
* **plugin:** recreate header menu when adding column dynamically ([#257](https://github.com/ghiscoding/slickgrid-universal/issues/257)) ([16c4984](https://github.com/ghiscoding/slickgrid-universal/commit/16c49845c5d3388502811c15f0a23daa1a01f850))
### Features
* **demo:** add Example 13 Header Button Plugin ([f345cd1](https://github.com/ghiscoding/slickgrid-universal/commit/f345cd18b89f849f3f873538c214d3ac24ff12f8))
+
* **editors:** add a Clear (X) button to the Autocomplete Editor ([#270](https://github.com/ghiscoding/slickgrid-universal/issues/270)) ([ffbd188](https://github.com/ghiscoding/slickgrid-universal/commit/ffbd188534992c31848691154517deb64694f3b2))
+
* **filters:** add updateSingleFilter for a single external filter ([#265](https://github.com/ghiscoding/slickgrid-universal/issues/265)) ([20564a3](https://github.com/ghiscoding/slickgrid-universal/commit/20564a3096948626beada698460b72374a18ca7c))
+
* **perf:** huge filtering speed improvements ([a101ed1](https://github.com/ghiscoding/slickgrid-universal/commit/a101ed1b62c2fbfec2712f64e08192a4852bce9d))
+
* **perf:** improve date sorting speed ([258da22](https://github.com/ghiscoding/slickgrid-universal/commit/258da2238bba3693eada058f9405012f68af150b))
+
* **perf:** improve date sorting speed ([#259](https://github.com/ghiscoding/slickgrid-universal/issues/259)) ([a52f4fc](https://github.com/ghiscoding/slickgrid-universal/commit/a52f4fcee1627ac5906388f8dcf4b7fe3f5c4aa7))
+
* **services:** add bulk transactions in Grid Service CRUD methods ([#256](https://github.com/ghiscoding/slickgrid-universal/issues/256)) ([03385d9](https://github.com/ghiscoding/slickgrid-universal/commit/03385d9ac58cb3ce7501a409394706c0cb4f4d29))
## [0.10.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.10.1...v0.10.2) (2021-01-28)
@@ -1077,20 +1527,31 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** fix types index.d.ts url ([a76b3a3](https://github.com/ghiscoding/slickgrid-universal/commit/a76b3a3d97a6d211ec2e7e8d9060fd8dd0719f58))
+
* **editors:** add blank disabled fields in Composite Editor form values ([#233](https://github.com/ghiscoding/slickgrid-universal/issues/233)) ([b634902](https://github.com/ghiscoding/slickgrid-universal/commit/b6349029b705991b7ac2d1df99f5b330fe69ef36))
+
* **editors:** fix clear date & blank disabled field w/Composite Editor ([#235](https://github.com/ghiscoding/slickgrid-universal/issues/235)) ([9aac97d](https://github.com/ghiscoding/slickgrid-universal/commit/9aac97d2d433c809facc8d7092467780d55ca01a))
+
* **filters:** Grid State filters should always include an operator ([#238](https://github.com/ghiscoding/slickgrid-universal/issues/238)) ([f64ed37](https://github.com/ghiscoding/slickgrid-universal/commit/f64ed37f7ffe01346c8f68d4bd170ffdce54839d))
+
* **frozen:** hiding multiple columns when using pinning gets out of sync ([#243](https://github.com/ghiscoding/slickgrid-universal/issues/243)) ([b255220](https://github.com/ghiscoding/slickgrid-universal/commit/b255220ec37dbdc9df4f3ecccb4397656cf9f2a6))
+
* **lint:** add eslint as a pre task when bundling & fix linting errors ([#246](https://github.com/ghiscoding/slickgrid-universal/issues/246)) ([6f7ccd8](https://github.com/ghiscoding/slickgrid-universal/commit/6f7ccd8ee4cc5e005034965a2c2dcc0499f06a73))
+
* **pinning:** recalculate frozen idx properly when column shown changes ([#241](https://github.com/ghiscoding/slickgrid-universal/issues/241)) ([3b55972](https://github.com/ghiscoding/slickgrid-universal/commit/3b559726acdff96970c68c10c8d256d0403d6c4f))
+
* **plugins:** add missing Row Detail filtering code ([#239](https://github.com/ghiscoding/slickgrid-universal/issues/239)) ([d9cad63](https://github.com/ghiscoding/slickgrid-universal/commit/d9cad635840650d2b2dd91444ffa0121147f4140))
### Features
* **editors:** add Clone functionality to Composite Editor ([#236](https://github.com/ghiscoding/slickgrid-universal/issues/236)) ([df545e4](https://github.com/ghiscoding/slickgrid-universal/commit/df545e4ec64271307b1979feb5e786f449433639))
+
* **editors:** change all private keyword to protected for extensability ([#247](https://github.com/ghiscoding/slickgrid-universal/issues/247)) ([089b6cb](https://github.com/ghiscoding/slickgrid-universal/commit/089b6cbbdd6284d94f765fdad08642e0d0d81ff0))
+
* **filters:** change all private keyword to protected for extensability ([#245](https://github.com/ghiscoding/slickgrid-universal/issues/245)) ([52cc702](https://github.com/ghiscoding/slickgrid-universal/commit/52cc7022c4b847566d89e91a80c423373538a15a))
+
* **formatters:** add grid option to auto add custom editor formatter ([#248](https://github.com/ghiscoding/slickgrid-universal/issues/248)) ([db77d46](https://github.com/ghiscoding/slickgrid-universal/commit/db77d464ee37eda573351e89d4c5acc9b5648649))
+
* add nameCompositeEditor override to be used by Composite Editor ([fcdb2e9](https://github.com/ghiscoding/slickgrid-universal/commit/fcdb2e92ed736b09e947cdbcf39ee157afc4acab))
# [0.9.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.8.0...v0.9.0) (2021-01-06)
@@ -1102,8 +1563,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Features
* **build:** upgrade to WebPack 5 ([#225](https://github.com/ghiscoding/slickgrid-universal/issues/225)) ([c6b3ad3](https://github.com/ghiscoding/slickgrid-universal/commit/c6b3ad3eb6fb64306bfd8bd300fcc1e86b27e5a6))
+
* **ci:** replace CircleCI with GitHub Actions ([#211](https://github.com/ghiscoding/slickgrid-universal/issues/211)) ([4f91140](https://github.com/ghiscoding/slickgrid-universal/commit/4f9114031ca6236ef45f04b67dcba1a9981035c4))
+
* **editors:** add Column Editor collectionOverride option ([#228](https://github.com/ghiscoding/slickgrid-universal/issues/228)) ([91421fc](https://github.com/ghiscoding/slickgrid-universal/commit/91421fc0154e432874fb2211e430a79032b996b8))
+
* **styling:** add support for Bootstrap 5 ([#226](https://github.com/ghiscoding/slickgrid-universal/issues/226)) ([e35f116](https://github.com/ghiscoding/slickgrid-universal/commit/e35f116efc1989f675ef6e030d80a8a31a444373))
# [0.8.0](https://github.com/ghiscoding/slickgrid-universal/compare/v0.7.7...v0.8.0) (2020-12-22)
@@ -1111,6 +1575,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** change moment/lodash imports so it works with ES6 module ([#210](https://github.com/ghiscoding/slickgrid-universal/issues/210)) ([2d25d3b](https://github.com/ghiscoding/slickgrid-universal/commit/2d25d3b99f7be93f2bc69f006fb67a39cf39ce7c))
+
* **core:** use regular imports instead of require to load plugins ([#209](https://github.com/ghiscoding/slickgrid-universal/issues/209)) ([6816696](https://github.com/ghiscoding/slickgrid-universal/commit/6816696c98be0d2dd80c1ff49358bd49ee7caacb))
### Features
@@ -1138,6 +1603,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **editors:** fix BS3,BS4 styles & slider value not shown with undefined ([#204](https://github.com/ghiscoding/slickgrid-universal/issues/204)) ([3aca8f9](https://github.com/ghiscoding/slickgrid-universal/commit/3aca8f9053365c1987f6c5abc43f8ce5eca015fb))
+
* **exports:** should be able to change export file name ([#205](https://github.com/ghiscoding/slickgrid-universal/issues/205)) ([9d26213](https://github.com/ghiscoding/slickgrid-universal/commit/9d262134b12da46ef1fea970f092d96ce875ed78))
## [0.7.2](https://github.com/ghiscoding/slickgrid-universal/compare/v0.7.1...v0.7.2) (2020-12-17)
@@ -1145,7 +1611,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** range default should be inclusive instead of exclusive ([#203](https://github.com/ghiscoding/slickgrid-universal/issues/203)) ([b7f74ad](https://github.com/ghiscoding/slickgrid-universal/commit/b7f74ad8a1539aed32ac643b4fe395fbdecf4459))
+
* **sorting:** add cellValueCouldBeUndefined in grid option for sorting ([#202](https://github.com/ghiscoding/slickgrid-universal/issues/202)) ([865256e](https://github.com/ghiscoding/slickgrid-universal/commit/865256efe927a5715840963cb2945f16a402789b))
+
* **stylings:** small alignment issue with the slider value elm height ([5a453b8](https://github.com/ghiscoding/slickgrid-universal/commit/5a453b8739c07e07f835e111d7d3ca5d627a0c2f))
## [0.7.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.7.0...v0.7.1) (2020-12-17)
@@ -1167,13 +1635,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** add console error if any of column def id includes dot ([#198](https://github.com/ghiscoding/slickgrid-universal/issues/198)) ([6ee40af](https://github.com/ghiscoding/slickgrid-universal/commit/6ee40af507b066602c39e057349b5ead6e7952f3))
+
* **stylings:** composite editor styling fixes for BS4 ([#195](https://github.com/ghiscoding/slickgrid-universal/issues/195)) ([305eb90](https://github.com/ghiscoding/slickgrid-universal/commit/305eb90c75e6a4aa076c62b5364b904dc5c6518e))
+
* **stylings:** re-align the svg icons & single/multiple-select icon+text ([#194](https://github.com/ghiscoding/slickgrid-universal/issues/194)) ([b730be7](https://github.com/ghiscoding/slickgrid-universal/commit/b730be7a75b3035c01aa7ca8f48a88df447ad461))
### Features
* **core:** add registerExternalResources for Components/Services ([#196](https://github.com/ghiscoding/slickgrid-universal/issues/196)) ([ee02f1d](https://github.com/ghiscoding/slickgrid-universal/commit/ee02f1d62d1a0601421352e43d17bd8c89e4348c))
+
* **core:** refactor code using the container service everywhere ([#197](https://github.com/ghiscoding/slickgrid-universal/issues/197)) ([96ce9bd](https://github.com/ghiscoding/slickgrid-universal/commit/96ce9bdbf18330e522dad0cbb0eda09c41f6a3df))
+
* **formatters:** add numberPrefix & Suffix to Decimal Formatter ([#193](https://github.com/ghiscoding/slickgrid-universal/issues/193)) ([0e4d30c](https://github.com/ghiscoding/slickgrid-universal/commit/0e4d30c0ee23bc598206fbba4e5ed406e4aeecfe))
## [0.5.1](https://github.com/ghiscoding/slickgrid-universal/compare/v0.5.0...v0.5.1) (2020-12-10)
@@ -1185,8 +1657,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **editors:** make sure select editor is defined before reading a prop ([763f981](https://github.com/ghiscoding/slickgrid-universal/commit/763f98111d03652b0ad903ba487a3b8c83a5ef5d))
+
* **editors:** only translate button texts when enableTranslate is true ([b698c6b](https://github.com/ghiscoding/slickgrid-universal/commit/b698c6bd3f13af017c7f3c0113b8407269ba1e0d))
+
* **editors:** Select Editor option to return flat data w/complex object ([#189](https://github.com/ghiscoding/slickgrid-universal/issues/189)) ([4695cd3](https://github.com/ghiscoding/slickgrid-universal/commit/4695cd3b6871dc1ceca4036fd30935eca8011b7e))
+
* **exports:** when cell value is empty object return empty string ([#190](https://github.com/ghiscoding/slickgrid-universal/issues/190)) ([cd34901](https://github.com/ghiscoding/slickgrid-universal/commit/cd349012c82a8bdff113fb9f8ef23ea18c6e3035))
### Features
@@ -1208,6 +1683,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** properly export Enums, Interfaces, Services & Utilities ([#184](https://github.com/ghiscoding/slickgrid-universal/issues/184)) ([0c23398](https://github.com/ghiscoding/slickgrid-universal/commit/0c233984a6e9d718659c119b65a95d6c38d36b0c))
+
* **core:** showing/hiding column shouldn't affect its freezing position ([#185](https://github.com/ghiscoding/slickgrid-universal/issues/185)) ([2a812ed](https://github.com/ghiscoding/slickgrid-universal/commit/2a812edb82c8004ab43df224c67ede228ab72c00))
### Features
@@ -1219,9 +1695,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** don't expose src folder on npm & update few npm package ([#168](https://github.com/ghiscoding/slickgrid-universal/issues/168)) ([3c05938](https://github.com/ghiscoding/slickgrid-universal/commit/3c059381b35bba88ea98d0206692c912c625f227))
+
* **core:** rename i18n to translater & fix few other issues ([#174](https://github.com/ghiscoding/slickgrid-universal/issues/174)) ([34c963a](https://github.com/ghiscoding/slickgrid-universal/commit/34c963a2bcef1b841d3c62ea405a4bc49be98a5c))
+
* **editors:** make sure editor element exist before focusing ([e57235b](https://github.com/ghiscoding/slickgrid-universal/commit/e57235b4339ffa1bee522c245665bb598d963fd1))
+
* **extensions:** draggable grouping style change to look better ([#171](https://github.com/ghiscoding/slickgrid-universal/issues/171)) ([d00be88](https://github.com/ghiscoding/slickgrid-universal/commit/d00be8868370f3679555b8f52ef4ad85916c93ac))
+
* **formatters:** date formatters should accept ISO input & output to US ([#172](https://github.com/ghiscoding/slickgrid-universal/issues/172)) ([85ce7cf](https://github.com/ghiscoding/slickgrid-universal/commit/85ce7cf3636d5bb43d3ef18ec6998bb0c423d218))
## [0.2.13](https://github.com/ghiscoding/slickgrid-universal/compare/@slickgrid-universal/common@0.2.12...@slickgrid-universal/common@0.2.13) (2020-11-26)
@@ -1281,6 +1761,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** don't expose src folder on npm & update few npm package ([#168](https://github.com/ghiscoding/slickgrid-universal/issues/168)) ([3c05938](https://github.com/ghiscoding/slickgrid-universal/commit/3c059381b35bba88ea98d0206692c912c625f227))
+
* **editors:** make sure editor element exist before focusing ([e57235b](https://github.com/ghiscoding/slickgrid-universal/commit/e57235b4339ffa1bee522c245665bb598d963fd1))
# [0.2.0](https://github.com/ghiscoding/slickgrid-universal/compare/@slickgrid-universal/common@0.1.0...@slickgrid-universal/common@0.2.0) (2020-11-20)
@@ -1288,48 +1769,87 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **core:** clear dataset when disposing and fix few unsubscribed events to avoid leak ([#156](https://github.com/ghiscoding/slickgrid-universal/issues/156)) ([78c80b4](https://github.com/ghiscoding/slickgrid-universal/commit/78c80b43ca04fd4fff68791556f9d4ab37f06caa))
+
* **core:** empty warning message should work with multiple grids ([#158](https://github.com/ghiscoding/slickgrid-universal/issues/158)) ([9e7c023](https://github.com/ghiscoding/slickgrid-universal/commit/9e7c023f7d33313400f4e55ddffd838d290b83dd))
+
* **core:** fix some problems found with AutoComplete ([#74](https://github.com/ghiscoding/slickgrid-universal/issues/74)) ([00fb478](https://github.com/ghiscoding/slickgrid-universal/commit/00fb478263db832ec31d940ed19417d9fcbae04a))
+
* **core:** Flatpickr is not destroyed properly & leaks detached elements ([#154](https://github.com/ghiscoding/slickgrid-universal/issues/154)) ([9633d4a](https://github.com/ghiscoding/slickgrid-universal/commit/9633d4a090c23ff4792cb614360afc58e76d74c3))
+
* **core:** header columns grouping misbehave after hiding column ([#164](https://github.com/ghiscoding/slickgrid-universal/issues/164)) ([6b8232b](https://github.com/ghiscoding/slickgrid-universal/commit/6b8232b3b98d1b75412bebd6b4528ee5dea71d7a))
+
* **core:** mem leaks w/orphan DOM elements when disposing ([#153](https://github.com/ghiscoding/slickgrid-universal/issues/153)) ([faba5a6](https://github.com/ghiscoding/slickgrid-universal/commit/faba5a6652fa2cf5e78f64b6b2e27bf9b85936ba))
+
* **core:** properly remove event listeners when disposing ([#163](https://github.com/ghiscoding/slickgrid-universal/issues/163)) ([ecfb9a7](https://github.com/ghiscoding/slickgrid-universal/commit/ecfb9a7c623010504a7a2d312ffef185f16cec9e))
+
* **editor:** SingleSelect Editor should show pick false value ([#75](https://github.com/ghiscoding/slickgrid-universal/issues/75)) ([fdb2c84](https://github.com/ghiscoding/slickgrid-universal/commit/fdb2c8433d443dd8f4fdd86f714354424cfb9ea3))
+
* **editors:** autocomplete editor spinner aligned right in mass update ([#162](https://github.com/ghiscoding/slickgrid-universal/issues/162)) ([6ae5189](https://github.com/ghiscoding/slickgrid-universal/commit/6ae51897979d80f5639fb095406e83e182649252))
+
* **filters:** disregard time when filtering date only format ([#134](https://github.com/ghiscoding/slickgrid-universal/issues/134)) ([7bd2d19](https://github.com/ghiscoding/slickgrid-universal/commit/7bd2d1964de2e809d8b08c737231eec31d146fae))
+
* **pinning:** put back vertical scroll on grid after removing freezing ([75a47a6](https://github.com/ghiscoding/slickgrid-universal/commit/75a47a607d463854c1b51fe5a330d629c79ac2e2))
+
* **select:** make a collection array copy to avoid change by ref ([#135](https://github.com/ghiscoding/slickgrid-universal/issues/135)) ([3237133](https://github.com/ghiscoding/slickgrid-universal/commit/323713382f1565ff8617ede08fdc8ed31ac3a594))
+
* **styling:** support other unit of measure in SASS ([5b9adec](https://github.com/ghiscoding/slickgrid-universal/commit/5b9adec6d11230a870337f1adaac1b0f9e157438))
+
* **styling:** SVG icon colors aren't showing up in SF with Firefox ([#131](https://github.com/ghiscoding/slickgrid-universal/issues/131)) ([2ed3cf5](https://github.com/ghiscoding/slickgrid-universal/commit/2ed3cf50358139374d4deeaedb5a8fdb7db27b98))
+
* **translations:** HeaderMenu & Date Filters not translating ([#58](https://github.com/ghiscoding/slickgrid-universal/issues/58)) ([9416c4d](https://github.com/ghiscoding/slickgrid-universal/commit/9416c4d2642894c5660473419623cee9bebcac4b))
### Features
* **autocomplete:** add much more functionalities to the AutoComplete ([#69](https://github.com/ghiscoding/slickgrid-universal/issues/69)) ([93c3d0a](https://github.com/ghiscoding/slickgrid-universal/commit/93c3d0a9b8d5a30c7a933f95a4333937c95305a3))
+
* **core:** add "Empty Data" warning message when grid is empty ([#155](https://github.com/ghiscoding/slickgrid-universal/issues/155)) ([13875b4](https://github.com/ghiscoding/slickgrid-universal/commit/13875b455d60f44918d8524aa803374773276e90))
+
* **core:** add custom entry to Select Editor/Filter collections ([#133](https://github.com/ghiscoding/slickgrid-universal/issues/133)) ([66effcf](https://github.com/ghiscoding/slickgrid-universal/commit/66effcfddd8b5a9d78a1d1ab679ca2721067e4be))
+
* **core:** add ESLint npm script and add to prebuild script ([#151](https://github.com/ghiscoding/slickgrid-universal/issues/151)) ([4064876](https://github.com/ghiscoding/slickgrid-universal/commit/40648760a33628f0ba85653f5fc99d8250b9a7a2))
+
* **core:** add loading spinner to AutoComplete Editor/Filter ([#65](https://github.com/ghiscoding/slickgrid-universal/issues/65)) ([4ecd2bd](https://github.com/ghiscoding/slickgrid-universal/commit/4ecd2bd305f2fd2b509e48cf1c7166b666228be3))
+
* **core:** rewrite "Empty Data" warning component to be in the canvas ([#157](https://github.com/ghiscoding/slickgrid-universal/issues/157)) ([78e2132](https://github.com/ghiscoding/slickgrid-universal/commit/78e213222d6058e1d1d768094801be42dbf4fb05))
+
* **core:** update few npm packages ([#123](https://github.com/ghiscoding/slickgrid-universal/issues/123)) ([1c25b87](https://github.com/ghiscoding/slickgrid-universal/commit/1c25b87fdd738616879298baeb52074e30e9bf14))
+
* **core:** update lib to latest jQuery version 3.5.1 ([#56](https://github.com/ghiscoding/slickgrid-universal/issues/56)) ([1af66d5](https://github.com/ghiscoding/slickgrid-universal/commit/1af66d5142bb5bc17cc84c819f9f273874af285c)), closes [#42](https://github.com/ghiscoding/slickgrid-universal/issues/42)
+
* **core:** update to latest SlickGrid version and update npm packages ([#140](https://github.com/ghiscoding/slickgrid-universal/issues/140)) ([d73a44e](https://github.com/ghiscoding/slickgrid-universal/commit/d73a44e338025da45e990a8a522fb0b9aa1c5279))
+
* **core:** use barel export everywhere ([#57](https://github.com/ghiscoding/slickgrid-universal/issues/57)) ([d068fc5](https://github.com/ghiscoding/slickgrid-universal/commit/d068fc577566a44217f543f7486be0cc4edc5f69))
+
* **editor:** add Composite Editor modal dialog ([#76](https://github.com/ghiscoding/slickgrid-universal/issues/76)) ([bba0b80](https://github.com/ghiscoding/slickgrid-universal/commit/bba0b804301195a166f87be610ee85fe77d4a134))
+
* **editors:** add changeEditorOption to all Editors which supports it ([#142](https://github.com/ghiscoding/slickgrid-universal/issues/142)) ([97b1003](https://github.com/ghiscoding/slickgrid-universal/commit/97b1003f80a72859ae9fc4b4a0ade12e8ec373a5))
+
* **editors:** add way to change or disable Composite Editor form input ([#139](https://github.com/ghiscoding/slickgrid-universal/issues/139)) ([2a5280f](https://github.com/ghiscoding/slickgrid-universal/commit/2a5280f216b2929c018f4019169db039361f2985))
+
* **editors:** disable editor when collectionAsync, re-enable after ([#132](https://github.com/ghiscoding/slickgrid-universal/issues/132)) ([75b10de](https://github.com/ghiscoding/slickgrid-universal/commit/75b10de91adecfaab6627e677abe7f5ce91d8769))
+
* **examples:** add mass update feat to Example 11 ([#31](https://github.com/ghiscoding/slickgrid-universal/issues/31)) ([84e9817](https://github.com/ghiscoding/slickgrid-universal/commit/84e98175686160dfc243435496ac65a757ec30aa))
+
* **filters:** add Pre-Defined & Custom Filters saved in Local Storage ([#143](https://github.com/ghiscoding/slickgrid-universal/issues/143)) ([dea71ab](https://github.com/ghiscoding/slickgrid-universal/commit/dea71ababb4b06520b06f7e12f4acbd86051110a))
+
* **formatters:** add AlignRight Formatter & alias AlignCenter=>Center ([#161](https://github.com/ghiscoding/slickgrid-universal/issues/161)) ([831580d](https://github.com/ghiscoding/slickgrid-universal/commit/831580d5234114d9510a578a71f608cbb3eda3ec))
+
* **icons:** add more Material icons ([9f9377b](https://github.com/ghiscoding/slickgrid-universal/commit/9f9377b2768c0ad6c091731be36125ea73e2ad46))
+
* **icons:** add some more material icons ([#124](https://github.com/ghiscoding/slickgrid-universal/issues/124)) ([b90fe2d](https://github.com/ghiscoding/slickgrid-universal/commit/b90fe2d231c1005ad137a7f0fbae8f6fb928cb79))
+
* **plugins:** add "hidden" to all controls/plugins with menu items ([#128](https://github.com/ghiscoding/slickgrid-universal/issues/128)) ([99202de](https://github.com/ghiscoding/slickgrid-universal/commit/99202deb7b452b7ac8d67d4b98545901cf99005e))
+
* **services:** add 2x new methods hideColumnById or ..byIds ([#160](https://github.com/ghiscoding/slickgrid-universal/issues/160)) ([d396653](https://github.com/ghiscoding/slickgrid-universal/commit/d3966530fab48ee72fab138b8caf97c4eb73ec91))
+
* **services:** add Toggle Filtering/Sorting & Hide Column methods ([#126](https://github.com/ghiscoding/slickgrid-universal/issues/126)) ([08fe2e1](https://github.com/ghiscoding/slickgrid-universal/commit/08fe2e19c5778941050e42ca207d55dc27564ba8))
+
* **styling:** add frozen on all possible elements with SASS variables ([#138](https://github.com/ghiscoding/slickgrid-universal/issues/138)) ([c61da91](https://github.com/ghiscoding/slickgrid-universal/commit/c61da911c449949570f54343724bc80523f77bcb)), closes [#537](https://github.com/ghiscoding/slickgrid-universal/issues/537)
+
* **styling:** add Pagination button height sass variable ([#136](https://github.com/ghiscoding/slickgrid-universal/issues/136)) ([43deeee](https://github.com/ghiscoding/slickgrid-universal/commit/43deeee99aee1887a62ec4238f68dce9e37fca69))
+
* **styling:** find way to add colors to SVGs used by the lib ([#73](https://github.com/ghiscoding/slickgrid-universal/issues/73)) ([8a07c16](https://github.com/ghiscoding/slickgrid-universal/commit/8a07c16ec3238533ab16fb22f8b748168cd5f18c))
+
* **tests:** add more Cypress E2E tests for grouping ([#125](https://github.com/ghiscoding/slickgrid-universal/issues/125)) ([814dec0](https://github.com/ghiscoding/slickgrid-universal/commit/814dec0dbad7cf59e98654a732dbf6d46de37a1a))
# [0.1.0](https://github.com/ghiscoding/slickgrid-universal/compare/@slickgrid-universal/common@0.0.2...@slickgrid-universal/common@0.1.0) (2020-07-28)
@@ -1337,108 +1857,209 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* **build:** vscode chrome debugger + webpack prod build should both work ([e148090](https://github.com/ghiscoding/slickgrid-universal/commit/e148090b967119c911c5da2fc7cb2cfdf4c3de39))
+
* **components:** add "cssText" option to both Footer/Pagination ([abd4fcd](https://github.com/ghiscoding/slickgrid-universal/commit/abd4fcd6ea6c990e1192afaca450dd6b7847e590))
+
* **components:** both Footer/Pagination should always be 100% width ([#27](https://github.com/ghiscoding/slickgrid-universal/issues/27)) ([e587ef5](https://github.com/ghiscoding/slickgrid-universal/commit/e587ef5084d469c6342c84c5c2f6a0dc65ae4493))
+
* **context:** change copy cell command to make it work in SF ([#8](https://github.com/ghiscoding/slickgrid-universal/issues/8)) ([c0b8ad9](https://github.com/ghiscoding/slickgrid-universal/commit/c0b8ad943dbd6baf08f41c36d6d266382b758206))
+
* **core:** add missing use of custom datasetIdPropertyName ([917f044](https://github.com/ghiscoding/slickgrid-universal/commit/917f044b1489b19917b15bd146a2d40f8924ea23))
+
* **debug:** chrome debugger with webpack & TS breakpoints ([6c3ab52](https://github.com/ghiscoding/slickgrid-universal/commit/6c3ab521be42265edd33d30002f342493f12c54b))
+
* **editor:** disregard Flatpickr error on Date Editor ([e7d7ba5](https://github.com/ghiscoding/slickgrid-universal/commit/e7d7ba57c6a68309aafb0c2082b4e642194067f3))
+
* **editor:** disregard Flatpickr error on Date Editor and fix output format ([140c48e](https://github.com/ghiscoding/slickgrid-universal/commit/140c48e7fe18eea76d59b44bb6625d3cb89aaf55))
+
* **editor:** float validator min/max values should be inclusive ([3e193aa](https://github.com/ghiscoding/slickgrid-universal/commit/3e193aabd8bdf515d53da938c19bc931b29c8438))
+
* **editor:** float validator should accept decimal even without 0 suffix ([87808ce](https://github.com/ghiscoding/slickgrid-universal/commit/87808ce1f0c10e4dd070518b78e35e986580de30))
+
* **editor:** number validators should be ok with null value on init ([1aadc86](https://github.com/ghiscoding/slickgrid-universal/commit/1aadc86787d88de8e18a193853e40ee88e795f93))
+
* **editor:** shouldn't call cell changed when cell value is undefined ([d5796a1](https://github.com/ghiscoding/slickgrid-universal/commit/d5796a1c3d45d5592c56dc9001231b2943f56cc0))
+
* **editors:** add saveOutputType to finally have proper save format ([#17](https://github.com/ghiscoding/slickgrid-universal/issues/17)) ([ebfd715](https://github.com/ghiscoding/slickgrid-universal/commit/ebfd71582642abe136317dbef8cedee68d472aa7))
+
* **editors:** Editors should work with undefined item properties ([#25](https://github.com/ghiscoding/slickgrid-universal/issues/25)) ([9bc6f5a](https://github.com/ghiscoding/slickgrid-universal/commit/9bc6f5ad617d7144d8787d4afcfe3b888966dcb7))
+
* **editors:** invalid date should trigger onvalidationerror ([#19](https://github.com/ghiscoding/slickgrid-universal/issues/19)) ([041087e](https://github.com/ghiscoding/slickgrid-universal/commit/041087ea928b9c53ef118a198b6837a028933b7a))
+
* **editors:** make sure appendChild exist before using it to add Editor ([90d4a67](https://github.com/ghiscoding/slickgrid-universal/commit/90d4a670824eb979fc2813d0d42a5803dacd3739))
+
* **filter:** recreate filter when toggling header row ([e839464](https://github.com/ghiscoding/slickgrid-universal/commit/e839464fa5dbb1db274ebda69daf3f71808f0c93))
+
* **filter:** string filter should also work when using Contains ([fc54f9a](https://github.com/ghiscoding/slickgrid-universal/commit/fc54f9a03b974e000cde4ea4a18ddb261572f003))
+
* **filter:** when entering filter operator it shouldn't do any filtering ([81c465b](https://github.com/ghiscoding/slickgrid-universal/commit/81c465b61ca4c0883c4c4308a5b154ef7410039e))
+
* **formatter:** add possibility to parse a date formatter as a UTC date ([e72bcad](https://github.com/ghiscoding/slickgrid-universal/commit/e72bcadae652bb00cb8b51f92ff2b2cf67de37a4))
+
* **formatters:** decimalSeparator & thousandSeparator work tgt ([62de7c2](https://github.com/ghiscoding/slickgrid-universal/commit/62de7c2713c140ef757d821d7538a965ea625b7e))
+
* **header:** re-create header grouping title after changing picker cols ([872c780](https://github.com/ghiscoding/slickgrid-universal/commit/872c7808d27cae30c414d1e3769728aa083910e7))
+
* **menu:** context menu to copy cell with queryFieldNameGetterFn ([#21](https://github.com/ghiscoding/slickgrid-universal/issues/21)) ([53c50f9](https://github.com/ghiscoding/slickgrid-universal/commit/53c50f9d716725330681d3617082b1fa33f90c12))
+
* **pagination:** get pagination working in SF as well ([#24](https://github.com/ghiscoding/slickgrid-universal/issues/24)) ([1132f2e](https://github.com/ghiscoding/slickgrid-universal/commit/1132f2edec251e2f65cce860ebfa57dbe35cf852))
+
* **picker:** add missing pre-header title grouping extractor ([fa3148b](https://github.com/ghiscoding/slickgrid-universal/commit/fa3148bd90487cad6bcd01b782ab27570336f741))
+
* **resize:** add a patch to fix autoresize on Chrome ([02faae4](https://github.com/ghiscoding/slickgrid-universal/commit/02faae44118dd5adbda57a5363567a84c84e7cb2))
+
* **sanitizer:** add optional grid option sanitizer anywhere possible ([#9](https://github.com/ghiscoding/slickgrid-universal/issues/9)) ([a6c7997](https://github.com/ghiscoding/slickgrid-universal/commit/a6c7997d75d27cc14892de4460dea28b529b392e))
+
* **select:** revert to jQuery 3.4.1 since latest version seems ([e839a5e](https://github.com/ghiscoding/slickgrid-universal/commit/e839a5e0f8ef8ab21a341ee2e2961c5a07736805))
+
* **sort:** header menu sorting should include columnId property ([2c5d2e0](https://github.com/ghiscoding/slickgrid-universal/commit/2c5d2e0547179f4cbe8f491a83af5202ba3410f9))
+
* **sort:** header menu sorting should include columnId property ([666a831](https://github.com/ghiscoding/slickgrid-universal/commit/666a83166ec21062bba9be287d65a242f7b52a1a))
+
* **styling:** cell menu is re-position incorrectly below the grid ([6fd3552](https://github.com/ghiscoding/slickgrid-universal/commit/6fd3552b568faef252e77b0446f2ab08d2a6ccde))
+
* **styling:** cell/context menus get re-position below the grid ([7db862a](https://github.com/ghiscoding/slickgrid-universal/commit/7db862ad6d7a939d1a285141068e2095c3295541))
+
* **styling:** sass variable should be interpolate before using calc ([42e7e3d](https://github.com/ghiscoding/slickgrid-universal/commit/42e7e3d51e6750f11a17f11d259fe97851505385))
+
* **tests:** fix failing unit test ([f19745d](https://github.com/ghiscoding/slickgrid-universal/commit/f19745d91d264d3da450a674b9ca9c78bf157294))
+
* **types:** fix TS type warnings ([d22ee64](https://github.com/ghiscoding/slickgrid-universal/commit/d22ee64dfaabae5b0e497ade62192b1c5595e0c3))
### Features
* **backend:** add OData & GraphQL packages ([#2](https://github.com/ghiscoding/slickgrid-universal/issues/2)) ([53cf08b](https://github.com/ghiscoding/slickgrid-universal/commit/53cf08bff2eea18e677770f70eedef1bda9aefcc))
+
* **browser:** add browserslist for packages who uses it ([fc69908](https://github.com/ghiscoding/slickgrid-universal/commit/fc69908a4eccfaedeb1835eb9d00719e7926065f))
+
* **build:** add correct TS types to all packages ([5ab0833](https://github.com/ghiscoding/slickgrid-universal/commit/5ab0833e07b89504ac603c3d356d2a6bdb0dfee2))
+
* **build:** tweak build to use tsc and test with sf lwc ([e4964b3](https://github.com/ghiscoding/slickgrid-universal/commit/e4964b34513e828d5cc9f2b278d794d892895277))
+
* **colspan:** add Header Grouping & Column Span example ([b9a155d](https://github.com/ghiscoding/slickgrid-universal/commit/b9a155dcf58c9a7c984ea1b6426883af0ae2f9ca))
+
* **core:** add `collectionAsync` option for both the Editors & Filters ([#16](https://github.com/ghiscoding/slickgrid-universal/issues/16)) ([f9488ab](https://github.com/ghiscoding/slickgrid-universal/commit/f9488ab350421be771f356b1775559a8e0d8e0c0))
+
* **core:** add Translation into demo with fetch locale from json file ([#23](https://github.com/ghiscoding/slickgrid-universal/issues/23)) ([b5608e9](https://github.com/ghiscoding/slickgrid-universal/commit/b5608e958f659b839a8460ffee4a555c66774893))
+
* **core:** dynamically add/remove columns ([#13](https://github.com/ghiscoding/slickgrid-universal/issues/13)) ([959097c](https://github.com/ghiscoding/slickgrid-universal/commit/959097cf8363330c7166d0844048cfde57a5cabc))
+
* **core:** expose all Extensions in new getter prop & fix draggable ([#29](https://github.com/ghiscoding/slickgrid-universal/issues/29)) ([07257b2](https://github.com/ghiscoding/slickgrid-universal/commit/07257b2564d86cbfad4f69bb4e910e04d7df5688))
+
* **core:** expose all services, slickgrid, dataview instances ([a33e387](https://github.com/ghiscoding/slickgrid-universal/commit/a33e3876b1134f6839aac10a67193448997ae7c5))
+
* **core:** use DataView transactions with multiple item changes ([#14](https://github.com/ghiscoding/slickgrid-universal/issues/14)) ([8cbd03a](https://github.com/ghiscoding/slickgrid-universal/commit/8cbd03a678bc6a2a89495685cc781b12946ec404))
+
* **demo:** add prod build for github page sample ([13eb721](https://github.com/ghiscoding/slickgrid-universal/commit/13eb721f88114461e1dda70eeba0461b69a89f46))
+
* **editor:** add more Editors ([f08864d](https://github.com/ghiscoding/slickgrid-universal/commit/f08864d0d583d01dece58570ea5bf8d1a195cdc9))
+
* **editor:** add operatorConditionalType (inclusive or exclusive) ([e300b31](https://github.com/ghiscoding/slickgrid-universal/commit/e300b313ae0d04ad2ec65f932e243d2b4150eca3))
+
* **editor:** add readonly option to DualInput Editor ([4217c41](https://github.com/ghiscoding/slickgrid-universal/commit/4217c411304d6056a6de6489351497418b72d9e6))
+
* **editor:** fully working dual input editor ([773fb49](https://github.com/ghiscoding/slickgrid-universal/commit/773fb49c1dbb6876bf8c2d2c53a1f823a84dd655))
+
* **editor:** start working on a Compound Editor ([49107c1](https://github.com/ghiscoding/slickgrid-universal/commit/49107c14ca841edf7c279e9a0ffe334f1d5dc71a))
+
* **editor:** tweak Dual Input Editor and add full unit tests ([c48e321](https://github.com/ghiscoding/slickgrid-universal/commit/c48e32189db48ced3c68e3427c64583db2d8d1d7))
+
* **editors:** add Autocomplete Editor ([011df55](https://github.com/ghiscoding/slickgrid-universal/commit/011df552c48defb32e81a1552e8b4e38f25be028))
+
* **editors:** add combo input editor poc code ([5918c73](https://github.com/ghiscoding/slickgrid-universal/commit/5918c73ea82e13183e8a6c14021f38ddf0f2b0fd))
+
* **editors:** add min/max length options to text editors ([#30](https://github.com/ghiscoding/slickgrid-universal/issues/30)) ([318c70c](https://github.com/ghiscoding/slickgrid-universal/commit/318c70ccbf0f071e328457d6290b6b1e078a1564))
+
* **editors:** add missing Date Editor ([c897c7c](https://github.com/ghiscoding/slickgrid-universal/commit/c897c7c426c179282766bba3345f4b44317aee44))
+
* **editors:** add more Editors and rewrite some in vanilla JS ([9308d4b](https://github.com/ghiscoding/slickgrid-universal/commit/9308d4b78a77a86a4b86fd10fb1de34746276a9e))
+
* **editors:** add more Editors and update all npm packages ([14b10a1](https://github.com/ghiscoding/slickgrid-universal/commit/14b10a17642b2c7f889f90b58dd3fef084e983b9))
+
* **editors:** extract most of the Editor Validators into separate files ([a9a45e6](https://github.com/ghiscoding/slickgrid-universal/commit/a9a45e6f2ce3536f9be846ef932337f174569897))
+
* **examples:** add more Tree View with checkbox selector code ([7d7c644](https://github.com/ghiscoding/slickgrid-universal/commit/7d7c644b0ecc8c3b61dd706d37d31edd0cf92fca))
+
* **examples:** add new sample to showcase queued editing ([#28](https://github.com/ghiscoding/slickgrid-universal/issues/28)) ([3b8fec6](https://github.com/ghiscoding/slickgrid-universal/commit/3b8fec6e890fc0b8dc9754495c1022d898740b3e))
+
* **extension:** add latest slickgrid with RowMove improvements ([c10fffd](https://github.com/ghiscoding/slickgrid-universal/commit/c10fffdb2bd8a8ce0221e570cf0bfb4cf03c7c29))
+
* **extensions:** add more Extensions and all their unit tests ([30af496](https://github.com/ghiscoding/slickgrid-universal/commit/30af496c48233ff84ce548648994398db068dbcb))
+
* **filter:** add Filter Service, Filter Conditions and few unit tests ([2baed7f](https://github.com/ghiscoding/slickgrid-universal/commit/2baed7fa0c31d73437b3d08d2d48c91b05602ff9))
+
* **filter:** refactor Filter Service by adding a debounce fn ([#7](https://github.com/ghiscoding/slickgrid-universal/issues/7)) ([3ba243c](https://github.com/ghiscoding/slickgrid-universal/commit/3ba243ce3b4ade48531ca323a12b465b5ad0b091))
+
* **filters:** add Autocomplete Filter ([82bda77](https://github.com/ghiscoding/slickgrid-universal/commit/82bda776c9cb72c9d44aca24ecf289c839e6e24f))
+
* **filters:** add few Filters and their unit tests ([c7e5897](https://github.com/ghiscoding/slickgrid-universal/commit/c7e5897d2e2af93339ea28a2fabc5263015d7d2c))
+
* **filters:** add few more Filters ([76b4177](https://github.com/ghiscoding/slickgrid-universal/commit/76b41771bd55e846ee67c9100b0de29ddb0a9276))
+
* **filters:** add missing Date Filters ([76c66a3](https://github.com/ghiscoding/slickgrid-universal/commit/76c66a3ec2da4b1ff1b296851f46bf58967adc18))
+
* **footer:** add Custom Footer ([0d3e1da](https://github.com/ghiscoding/slickgrid-universal/commit/0d3e1dabf29c4bc354df598a3b166030f61769fc))
+
* **footer:** add Custom Footer component ([#5](https://github.com/ghiscoding/slickgrid-universal/issues/5)) ([59d0ba8](https://github.com/ghiscoding/slickgrid-universal/commit/59d0ba8921c2e0886b0c34705ac5a74f35ab4e43))
+
* **grouping:** add missing Grouping interface properties ([7c83fd0](https://github.com/ghiscoding/slickgrid-universal/commit/7c83fd09acff960b86f62a0bd0c1f4b654b25f9c))
+
* **grouping:** add more Grouping & Aggregators code ([8c20808](https://github.com/ghiscoding/slickgrid-universal/commit/8c20808d9a8b0a6166f4fb8fe013d33ae57a223c))
+
* **package:** add new Excel Export package ([808785e](https://github.com/ghiscoding/slickgrid-universal/commit/808785e0ea9508f817453211d8ed808398aa9c01))
+
* **package:** add new Export (csv, txt) package ([d6adc5c](https://github.com/ghiscoding/slickgrid-universal/commit/d6adc5ce7aa466fde3c1e1377bd47c9a6cd8b53b))
+
* **pinning:** add "Freezen Columns" to header menu ([#4](https://github.com/ghiscoding/slickgrid-universal/issues/4)) ([1c7d49f](https://github.com/ghiscoding/slickgrid-universal/commit/1c7d49f838a8cadb093dfbdf81c215ed250fbe14))
+
* **presets:** add missing row selections preset option ([#11](https://github.com/ghiscoding/slickgrid-universal/issues/11)) ([e0a729c](https://github.com/ghiscoding/slickgrid-universal/commit/e0a729cfbbe7aa75a18301b4db994ac9d3330f10))
+
* **query:** add queryFieldNameGetterFn callback know which field to use ([6d8955c](https://github.com/ghiscoding/slickgrid-universal/commit/6d8955c1933a88683c2284d9162e43248bc578a2))
+
* **service:** add GridEvent Service to the lib ([4a4bf6f](https://github.com/ghiscoding/slickgrid-universal/commit/4a4bf6f86ebdb6cbf911d838714440cceee4e07f))
+
* **services:** add Pagination & Grid State Services ([c15e6e6](https://github.com/ghiscoding/slickgrid-universal/commit/c15e6e63edce6f07751f3380229e9e1777c43d84))
+
* **services:** add registerServices in Grid Options ([#1](https://github.com/ghiscoding/slickgrid-universal/issues/1)) ([e7c2e91](https://github.com/ghiscoding/slickgrid-universal/commit/e7c2e91842eac2044ccdd82673bfade20b24ab4f))
+
* **sort:** add valueCouldBeUndefined column flag to help sorting ([6d2b6a6](https://github.com/ghiscoding/slickgrid-universal/commit/6d2b6a6b7521511470c27c17ce65784258a87868))
+
* **sorting:** header menu clear sort, reset sorting when nothing left ([032886b](https://github.com/ghiscoding/slickgrid-universal/commit/032886bf6da9e3d711a17d23481c47ccf81af353))
+
* **style:** tweak Editors styling and add Sort icon hint on hover ([aba4182](https://github.com/ghiscoding/slickgrid-universal/commit/aba41826659844519da1ef170f0b3641a0d91af0))
+
* **styling:** add a Salesforce theme ([3b62101](https://github.com/ghiscoding/slickgrid-universal/commit/3b62101413dc3eb4eeb5df7772db3b885d7ae7c5))
+
* **styling:** add css autoprefixer ([2e89c28](https://github.com/ghiscoding/slickgrid-universal/commit/2e89c287ea0ed5a508f2e977cae21ecc35ed414d))
+
* **styling:** add edit icon when hovering editable cell with SF Theme ([eef4403](https://github.com/ghiscoding/slickgrid-universal/commit/eef4403b8e9168ff119eb97ca5c663101104abae))
+
* **styling:** add material design icons to npm & scss instead of html ([9e9a1ca](https://github.com/ghiscoding/slickgrid-universal/commit/9e9a1ca7794eb807494bfbd837aa7e17ad4b42b2))
+
* **styling:** add more material design stylings ([680788b](https://github.com/ghiscoding/slickgrid-universal/commit/680788b9b456c6d87875234d9f2c033cfbb7e18f))
+
* **styling:** material theme, replace all built-in Font char to SVG ([ed25d6a](https://github.com/ghiscoding/slickgrid-universal/commit/ed25d6ae4848b614c84da111ff894eedb5be6400))
+
* **styling:** salesforce theme, replace all built-in Font char to SVG ([1c5f341](https://github.com/ghiscoding/slickgrid-universal/commit/1c5f3414d8bafea7cb393033c9753aef4ad66b2f))
+
* **styling:** update Material Design font and some material styling ([c7ecbf9](https://github.com/ghiscoding/slickgrid-universal/commit/c7ecbf91b000e0758df04f87f49c35c1293f0abe))
+
* **tests:** add export abstract classes and add few more unit tests ([13a1bca](https://github.com/ghiscoding/slickgrid-universal/commit/13a1bcac7c21666f2b006f3488036175b29b1b3d))
+
* **tests:** add Jest to lib root and add few more unit tests ([5811c96](https://github.com/ghiscoding/slickgrid-universal/commit/5811c96568c5255376ea6b97b132f4f0fded0647))
+
* **tests:** add more Jest unit tests & commands ([d4da547](https://github.com/ghiscoding/slickgrid-universal/commit/d4da547aaae797767140d73289d7f50874fdd09e))
+
* **tests:** add queryFieldNameGetterFn callback unit tests ([6426793](https://github.com/ghiscoding/slickgrid-universal/commit/64267931dd6ad5506c52da2b19854d2a56d2104f))
+
* **tests:** rename to slick-vanilla-grid-bundle and add unit tests ([#12](https://github.com/ghiscoding/slickgrid-universal/issues/12)) ([006c302](https://github.com/ghiscoding/slickgrid-universal/commit/006c30251ea1d473e5d1ae54d20c050fccf0e6a4))
+
* **translate:** add namespace prefix + separator grid option ([90b1b2e](https://github.com/ghiscoding/slickgrid-universal/commit/90b1b2ec0c1a55d23ebcc47b6a88d972c9bbcdb7))
+
* **tree:** add Collapse/Expand All comands in context menu ([0b58d5e](https://github.com/ghiscoding/slickgrid-universal/commit/0b58d5e3727541fa088a1eeb9e49bb55f367b7c5))
+
* **tree:** add Tree Data multi-column Filtering support ([f9b4863](https://github.com/ghiscoding/slickgrid-universal/commit/f9b4863810da47138be7f83222ee49d87b4e20c0))
+
* **tree:** fixed recursive methods to sort hierarchical array ([6bc2915](https://github.com/ghiscoding/slickgrid-universal/commit/6bc29158395e6f3c9e3fbf87358d3ecb5fb12b75))
+
* **tree:** get a functional Tree View example working with add item ([c07cdb5](https://github.com/ghiscoding/slickgrid-universal/commit/c07cdb545106fd845a105a28014daabaa2860137))
diff --git a/packages/common/README.md b/packages/common/README.md
index 53901ca1f..c3d9624d7 100644
--- a/packages/common/README.md
+++ b/packages/common/README.md
@@ -3,6 +3,7 @@
[![lerna--lite](https://img.shields.io/badge/maintained%20with-lerna--lite-e137ff)](https://github.com/ghiscoding/lerna-lite)
[![npm](https://img.shields.io/npm/v/@slickgrid-universal/common.svg)](https://www.npmjs.com/package/@slickgrid-universal/common)
[![npm](https://img.shields.io/npm/dy/@slickgrid-universal/common)](https://www.npmjs.com/package/@slickgrid-universal/common)
+[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@slickgrid-universal/common?color=success&label=gzip)](https://bundlephobia.com/result?p=@slickgrid-universal/common)
[![Actions Status](https://github.com/ghiscoding/slickgrid-universal/actions/workflows/main.yml/badge.svg)](https://github.com/ghiscoding/slickgrid-universal/actions)
[![Cypress.io](https://img.shields.io/badge/tested%20with-Cypress-04C38E.svg)](https://www.cypress.io/)
diff --git a/packages/common/package.json b/packages/common/package.json
index 6357ab611..a999e2e5c 100644
--- a/packages/common/package.json
+++ b/packages/common/package.json
@@ -1,6 +1,6 @@
{
"name": "@slickgrid-universal/common",
- "version": "4.7.0",
+ "version": "5.0.0-beta.3",
"description": "SlickGrid-Universal Common Code",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
@@ -46,11 +46,10 @@
"bundle:esm": "tsc --project tsconfig.bundle.json --outDir dist/esm --module esnext --target es2021",
"bundle:types": "tsc --emitDeclarationOnly --declarationMap --outDir dist/types",
"sass-build-task:scss-compile:bootstrap": "sass src/styles/slickgrid-theme-bootstrap.scss dist/styles/css/slickgrid-theme-bootstrap.css --style=compressed --quiet-deps --no-source-map --load-path=node_modules",
+ "sass-build-task:scss-compile:bootstrap-lite": "sass src/styles/slickgrid-theme-bootstrap.lite.scss dist/styles/css/slickgrid-theme-bootstrap.lite.css --style=compressed --quiet-deps --no-source-map --load-path=node_modules",
"sass-build-task:scss-compile:material": "sass src/styles/slickgrid-theme-material.scss dist/styles/css/slickgrid-theme-material.css --style=compressed --quiet-deps --no-source-map --load-path=node_modules",
- "sass-build-task:scss-compile:material-bare": "sass src/styles/slickgrid-theme-material.bare.scss dist/styles/css/slickgrid-theme-material.bare.css --style=compressed --quiet-deps --no-source-map --load-path=node_modules",
"sass-build-task:scss-compile:material-lite": "sass src/styles/slickgrid-theme-material.lite.scss dist/styles/css/slickgrid-theme-material.lite.css --style=compressed --quiet-deps --no-source-map --load-path=node_modules",
"sass-build-task:scss-compile:salesforce": "sass src/styles/slickgrid-theme-salesforce.scss dist/styles/css/slickgrid-theme-salesforce.css --style=compressed --quiet-deps --no-source-map --load-path=node_modules",
- "sass-build-task:scss-compile:salesforce-bare": "sass src/styles/slickgrid-theme-salesforce.bare.scss dist/styles/css/slickgrid-theme-salesforce.bare.css --style=compressed --quiet-deps --no-source-map --load-path=node_modules",
"sass-build-task:scss-compile:salesforce-lite": "sass src/styles/slickgrid-theme-salesforce.lite.scss dist/styles/css/slickgrid-theme-salesforce.lite.css --style=compressed --quiet-deps --no-source-map --load-path=node_modules",
"sass:build": "run-p sass-build-task:scss-compile:*",
"postsass:build": "postcss --no-map --use cssnano --use autoprefixer --dir dist/styles/css dist/styles/css --style=compressed --quiet-deps --no-source-map",
@@ -67,20 +66,18 @@
"not dead"
],
"dependencies": {
+ "@formkit/tempo": "^0.1.1",
"@slickgrid-universal/binding": "workspace:~",
"@slickgrid-universal/event-pub-sub": "workspace:~",
"@slickgrid-universal/utils": "workspace:~",
- "@types/dompurify": "^3.0.5",
"@types/sortablejs": "^1.15.8",
"autocompleter": "^9.2.1",
"dequal": "^2.0.3",
"excel-builder-vanilla": "3.0.1",
- "flatpickr": "^4.6.13",
- "isomorphic-dompurify": "^2.9.0",
- "moment-mini": "^2.29.4",
"multiple-select-vanilla": "^3.2.0",
"sortablejs": "^1.15.2",
- "un-flatten-tree": "^2.0.12"
+ "un-flatten-tree": "^2.0.12",
+ "vanilla-calendar-picker": "^2.11.5"
},
"devDependencies": {
"autoprefixer": "^10.4.19",
diff --git a/packages/common/src/commonEditorFilter/commonEditorFilterUtils.ts b/packages/common/src/commonEditorFilter/commonEditorFilterUtils.ts
index 9133e6780..b433620e2 100644
--- a/packages/common/src/commonEditorFilter/commonEditorFilterUtils.ts
+++ b/packages/common/src/commonEditorFilter/commonEditorFilterUtils.ts
@@ -1,6 +1,10 @@
+import { format } from '@formkit/tempo';
import type { AutocompleteItem } from 'autocompleter';
+import type { IOptions } from 'vanilla-calendar-picker';
-import type { AutocompleterOption } from '../interfaces/index';
+import type { AutocompleterOption, Column, ColumnEditor, ColumnFilter } from '../interfaces/index';
+import { FieldType } from '../enums';
+import { formatDateByFieldType, mapTempoDateFormatWithFieldType, tryParseDate } from '../services/dateUtils';
/**
* add loading class ".slick-autocomplete-loading" to the Kraaden Autocomplete input element
@@ -27,4 +31,32 @@ export function addAutocompleteLoadingByOverridingFetch format(p, isoFormat)).join(':')],
+ month: pickerDates[0].getMonth(),
+ year: pickerDates[0].getFullYear(),
+ time: inputFormat === 'ISO8601' || (inputFormat || '').toLowerCase().includes('h') ? format(pickerDates[0], 'HH:mm') : undefined,
+ };
+ }
+ dateInputElm.value = initialDates.length ? pickerDates.map(p => formatDateByFieldType(p, undefined, outputFieldType)).join(' — ') : '';
+ }
}
\ No newline at end of file
diff --git a/packages/common/src/core/__tests__/slickDataView.spec.ts b/packages/common/src/core/__tests__/slickDataView.spec.ts
index daf3f0b76..08ed55718 100644
--- a/packages/common/src/core/__tests__/slickDataView.spec.ts
+++ b/packages/common/src/core/__tests__/slickDataView.spec.ts
@@ -3,7 +3,6 @@ import { SortDirectionNumber } from '../../enums';
import { GridOption, Grouping } from '../../interfaces';
import { SortComparers } from '../../sortComparers';
import { SlickDataView } from '../slickDataview';
-import 'flatpickr';
import { SlickGrid } from '../slickGrid';
import { SlickRowSelectionModel } from '../../extensions/slickRowSelectionModel';
import { SlickEventData } from '../slickCore';
diff --git a/packages/common/src/core/__tests__/slickGrid.spec.ts b/packages/common/src/core/__tests__/slickGrid.spec.ts
index 9ba598086..7b59a9293 100644
--- a/packages/common/src/core/__tests__/slickGrid.spec.ts
+++ b/packages/common/src/core/__tests__/slickGrid.spec.ts
@@ -811,16 +811,6 @@ describe('SlickGrid core file', () => {
expect(divElm.outerHTML).toBe('
only text kept
');
});
- it('should be able to supply differnt sanitizer options to use with DOMPurify before applying html code', () => {
- const divElm = document.createElement('div');
- const htmlStr = 'only text kept';
-
- grid = new SlickGrid('#myGrid', dv, columns, defaultOptions);
- grid.applyHtmlCode(divElm, htmlStr, { sanitizerOptions: { ALLOW_ARIA_ATTR: false } });
-
- expect(divElm.outerHTML).toBe('
only text kept
');
- });
-
it('should expect HTML string to be kept as a string and not be converted (but html escaped) when "enableHtmlRendering" grid option is disabled', () => {
const divElm = document.createElement('div');
const htmlStr = 'only text kept';
diff --git a/packages/common/src/core/slickGrid.ts b/packages/common/src/core/slickGrid.ts
index 111f67634..c7f0926a0 100644
--- a/packages/common/src/core/slickGrid.ts
+++ b/packages/common/src/core/slickGrid.ts
@@ -1,5 +1,4 @@
import Sortable, { type SortableEvent } from 'sortablejs';
-import DOMPurify from 'isomorphic-dompurify';
import { BindingEventService } from '@slickgrid-universal/binding';
import {
classNameToList,
@@ -588,22 +587,17 @@ export class SlickGrid = Column, O e
return; // same result, just skip it
}
- let sanitizedText = val;
- if (typeof sanitizedText === 'number' || typeof sanitizedText === 'boolean') {
- target.textContent = String(sanitizedText);
+ if (typeof val === 'number' || typeof val === 'boolean') {
+ target.textContent = String(val);
} else {
- if (typeof this._options?.sanitizer === 'function') {
- sanitizedText = this._options.sanitizer(val as string);
- } else if (typeof DOMPurify?.sanitize === 'function') {
- const purifyOptions = (options?.sanitizerOptions ?? this._options.sanitizerOptions ?? { ADD_ATTR: ['level'], RETURN_TRUSTED_TYPE: true }) as DOMPurify.Config;
- sanitizedText = DOMPurify.sanitize(val as string, purifyOptions) as unknown as string;
- }
+ const sanitizedText = this.sanitizeHtmlString(val);
- // apply HTML when enableHtmlRendering is enabled but make sure we do have a value (without a value, it will simply use `textContent` to clear text content)
+ // apply HTML when enableHtmlRendering is enabled
+ // but make sure we do have a value (without a value, it will simply use `textContent` to clear text content)
if (this._options.enableHtmlRendering && sanitizedText) {
- target.innerHTML = sanitizedText;
+ target.innerHTML = sanitizedText as unknown as string;
} else {
- target.textContent = sanitizedText;
+ target.textContent = sanitizedText as unknown as string;
}
}
}
@@ -645,7 +639,7 @@ export class SlickGrid = Column, O e
this._container.style.overflow = 'hidden';
this._container.style.outline = String(0);
this._container.classList.add(this.uid);
- this._container.classList.add('ui-widget');
+ this._container.classList.add('slick-widget');
this._container.setAttribute('role', 'grid');
const containerStyles = window.getComputedStyle(this._container);
@@ -664,12 +658,12 @@ export class SlickGrid = Column, O e
this._paneBottomR = createDomElement('div', { className: 'slick-pane slick-pane-bottom slick-pane-right', tabIndex: 0 }, this._container);
if (this._options.createPreHeaderPanel) {
- this._preHeaderPanelScroller = createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderL);
+ this._preHeaderPanelScroller = createDomElement('div', { className: 'slick-preheader-panel slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderL);
this._preHeaderPanelScroller.appendChild(document.createElement('div'));
this._preHeaderPanel = createDomElement('div', null, this._preHeaderPanelScroller);
this._preHeaderPanelSpacer = createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScroller);
- this._preHeaderPanelScrollerR = createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderR);
+ this._preHeaderPanelScrollerR = createDomElement('div', { className: 'slick-preheader-panel slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderR);
this._preHeaderPanelR = createDomElement('div', null, this._preHeaderPanelScrollerR);
this._preHeaderPanelSpacerR = createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScrollerR);
@@ -680,8 +674,8 @@ export class SlickGrid = Column, O e
}
// Append the header scroller containers
- this._headerScrollerL = createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-left' }, this._paneHeaderL);
- this._headerScrollerR = createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-right' }, this._paneHeaderR);
+ this._headerScrollerL = createDomElement('div', { className: 'slick-header slick-state-default slick-header-left' }, this._paneHeaderL);
+ this._headerScrollerR = createDomElement('div', { className: 'slick-header slick-state-default slick-header-right' }, this._paneHeaderR);
// Cache the header scroller containers
this._headerScroller.push(this._headerScrollerL);
@@ -694,8 +688,8 @@ export class SlickGrid = Column, O e
// Cache the header columns
this._headers = [this._headerL, this._headerR];
- this._headerRowScrollerL = createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopL);
- this._headerRowScrollerR = createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopR);
+ this._headerRowScrollerL = createDomElement('div', { className: 'slick-headerrow slick-state-default' }, this._paneTopL);
+ this._headerRowScrollerR = createDomElement('div', { className: 'slick-headerrow slick-state-default' }, this._paneTopR);
this._headerRowScroller = [this._headerRowScrollerL, this._headerRowScrollerR];
@@ -708,8 +702,8 @@ export class SlickGrid = Column, O e
this._headerRows = [this._headerRowL, this._headerRowR];
// Append the top panel scroller
- this._topPanelScrollerL = createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopL);
- this._topPanelScrollerR = createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopR);
+ this._topPanelScrollerL = createDomElement('div', { className: 'slick-top-panel-scroller slick-state-default' }, this._paneTopL);
+ this._topPanelScrollerR = createDomElement('div', { className: 'slick-top-panel-scroller slick-state-default' }, this._paneTopR);
this._topPanelScrollers = [this._topPanelScrollerL, this._topPanelScrollerR];
@@ -782,8 +776,8 @@ export class SlickGrid = Column, O e
// footer Row
if (this._options.createFooterRow) {
- this._footerRowScrollerR = createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopR);
- this._footerRowScrollerL = createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopL);
+ this._footerRowScrollerR = createDomElement('div', { className: 'slick-footerrow slick-state-default' }, this._paneTopR);
+ this._footerRowScrollerL = createDomElement('div', { className: 'slick-footerrow slick-state-default' }, this._paneTopL);
this._footerRowScroller = [this._footerRowScrollerL, this._footerRowScrollerR];
@@ -1349,7 +1343,7 @@ export class SlickGrid = Column, O e
* @param {string | HTMLElement | DocumentFragment} [title] New column name.
* @param {String} [toolTip] New column tooltip.
*/
- updateColumnHeader(columnId: number | string, title?: string | HTMLElement | DocumentFragment, toolTip?: string) {
+ updateColumnHeader(columnId: number | string, title?: string | HTMLElement | DocumentFragment, toolTip?: string): HTMLElement | void {
if (this.initialized) {
const idx = this.getColumnIndex(columnId);
if (!isDefined(idx)) {
@@ -1383,6 +1377,8 @@ export class SlickGrid = Column, O e
grid: this
});
}
+
+ return header;
}
}
@@ -1502,7 +1498,7 @@ export class SlickGrid = Column, O e
continue;
}
- const footerRowCell = createDomElement('div', { className: `ui-state-default slick-state-default slick-footerrow-column l${i} r${i}` }, this.hasFrozenColumns() && (i > this._options.frozenColumn!) ? this._footerRowR : this._footerRowL);
+ const footerRowCell = createDomElement('div', { className: `slick-state-default slick-footerrow-column l${i} r${i}` }, this.hasFrozenColumns() && (i > this._options.frozenColumn!) ? this._footerRowR : this._footerRowL);
const className = this.hasFrozenColumns() && i <= this._options.frozenColumn! ? 'frozen' : null;
if (className) {
footerRowCell.classList.add(className);
@@ -1520,11 +1516,11 @@ export class SlickGrid = Column, O e
}
protected handleHeaderMouseHoverOn(e: Event | SlickEventData) {
- (e as any)?.target.classList.add('ui-state-hover', 'slick-state-hover');
+ (e as any)?.target.classList.add('slick-state-hover');
}
protected handleHeaderMouseHoverOff(e: Event | SlickEventData) {
- (e as any)?.target.classList.remove('ui-state-hover', 'slick-state-hover');
+ (e as any)?.target.classList.remove('slick-state-hover');
}
protected createColumnHeaders() {
@@ -1606,7 +1602,7 @@ export class SlickGrid = Column, O e
const headerTarget = this.hasFrozenColumns() ? ((i <= this._options.frozenColumn!) ? this._headerL : this._headerR) : this._headerL;
const headerRowTarget = this.hasFrozenColumns() ? ((i <= this._options.frozenColumn!) ? this._headerRowL : this._headerRowR) : this._headerRowL;
- const header = createDomElement('div', { id: `${this.uid + m.id}`, dataset: { id: String(m.id) }, role: 'columnheader', className: 'ui-state-default slick-state-default slick-header-column' }, headerTarget);
+ const header = createDomElement('div', { id: `${this.uid + m.id}`, dataset: { id: String(m.id) }, role: 'columnheader', className: 'slick-state-default slick-header-column' }, headerTarget);
if (m.toolTip) {
header.title = m.toolTip;
}
@@ -1662,7 +1658,7 @@ export class SlickGrid = Column, O e
});
if (this._options.showHeaderRow) {
- const headerRowCell = createDomElement('div', { className: `ui-state-default slick-state-default slick-headerrow-column l${i} r${i}` }, headerRowTarget);
+ const headerRowCell = createDomElement('div', { className: `slick-state-default slick-headerrow-column l${i} r${i}` }, headerRowTarget);
const frozenClasses = this.hasFrozenColumns() && i <= this._options.frozenColumn! ? 'frozen' : null;
if (frozenClasses) {
headerRowCell.classList.add(frozenClasses);
@@ -1683,7 +1679,7 @@ export class SlickGrid = Column, O e
}
if (this._options.createFooterRow && this._options.showFooterRow) {
const footerRowTarget = this.hasFrozenColumns() ? ((i <= this._options.frozenColumn!) ? this._footerRow[0] : this._footerRow[1]) : this._footerRow[0];
- const footerRowCell = createDomElement('div', { className: `ui-state-default slick-state-default slick-footerrow-column l${i} r${i}` }, footerRowTarget);
+ const footerRowCell = createDomElement('div', { className: `slick-state-default slick-footerrow-column l${i} r${i}` }, footerRowTarget);
Utils.storage.put(footerRowCell, 'column', m);
this.triggerEvent(this.onFooterRowCellRendered, {
@@ -1785,7 +1781,7 @@ export class SlickGrid = Column, O e
previousSortColumns,
sortCols: this.sortColumns.map((col) => {
const tempCol = this.columns[this.getColumnIndex(col.columnId)];
- return !tempCol ? null : { columnId: tempCol.id, sortCol: tempCol, sortAsc: col.sortAsc };
+ return (!tempCol || tempCol.hidden) ? null : { columnId: tempCol.id, sortCol: tempCol, sortAsc: col.sortAsc };
}).filter((el) => el)
};
}
@@ -2329,7 +2325,7 @@ export class SlickGrid = Column, O e
this.headerColumnWidthDiff = this.headerColumnHeightDiff = 0;
this.cellWidthDiff = this.cellHeightDiff = 0;
- let el = createDomElement('div', { className: 'ui-state-default slick-state-default slick-header-column', style: { visibility: 'hidden' }, textContent: '-' }, header);
+ let el = createDomElement('div', { className: 'slick-state-default slick-header-column', style: { visibility: 'hidden' }, textContent: '-' }, header);
let style = getComputedStyle(el);
if (style.boxSizing !== 'border-box') {
h.forEach((val) => this.headerColumnWidthDiff += Utils.toFloat(style[val as any]));
@@ -3308,7 +3304,7 @@ export class SlickGrid = Column, O e
const frozenRowOffset = this.getFrozenRowOffset(row);
- const rowDiv = createDomElement('div', { className: `ui-widget-content ${rowCss}`, role: 'row', style: { top: `${this.getRowTop(row) - frozenRowOffset}px` } });
+ const rowDiv = createDomElement('div', { className: `slick-widget-content ${rowCss}`, role: 'row', style: { top: `${this.getRowTop(row) - frozenRowOffset}px` } });
let rowDivR: HTMLElement | undefined;
divArrayL.push(rowDiv);
@@ -6299,12 +6295,15 @@ export class SlickGrid = Column, O e
}
}
- /** html sanitizer to avoid scripting attack */
- sanitizeHtmlString(dirtyHtml: string) {
- if (!this._options.sanitizer || typeof dirtyHtml !== 'string') {
- return dirtyHtml;
+ /**
+ * Sanitize possible dirty html string (remove any potential XSS code like scripts and others) when provided via `sanitizer` grid option.
+ * The logic will only call the sanitizer if it exists and is a defined string, anything else will be skipped (number, boolean, TrustedHTML will all be skipped)
+ * @param {*} dirtyHtml: dirty html string
+ */
+ sanitizeHtmlString(dirtyHtml: unknown): T {
+ if (typeof this._options?.sanitizer !== 'function' || !dirtyHtml || typeof dirtyHtml !== 'string') {
+ return dirtyHtml as T;
}
-
- return this._options.sanitizer(dirtyHtml);
+ return this._options.sanitizer(dirtyHtml) as T;
}
}
\ No newline at end of file
diff --git a/packages/common/src/editors/__tests__/autocompleterEditor.spec.ts b/packages/common/src/editors/__tests__/autocompleterEditor.spec.ts
index efb7d67ec..7bd9fd8c3 100644
--- a/packages/common/src/editors/__tests__/autocompleterEditor.spec.ts
+++ b/packages/common/src/editors/__tests__/autocompleterEditor.spec.ts
@@ -3,7 +3,7 @@ import 'jest-extended';
import { Editors } from '../index';
import { AutocompleterEditor } from '../autocompleterEditor';
import { FieldType } from '../../enums/index';
-import { AutocompleterOption, Column, ColumnEditor, Editor, EditorArguments, GridOption } from '../../interfaces/index';
+import { AutocompleterOption, Column, Editor, EditorArguments, GridOption } from '../../interfaces/index';
import { TranslateServiceStub } from '../../../../../test/translateServiceStub';
import { SlickDataView, SlickEvent, type SlickGrid } from '../../core/index';
@@ -38,6 +38,7 @@ const gridStub = {
render: jest.fn(),
onBeforeEditCell: new SlickEvent(),
onCompositeEditorChange: new SlickEvent(),
+ sanitizeHtmlString: (str) => str,
} as unknown as SlickGrid;
describe('AutocompleterEditor', () => {
@@ -745,7 +746,7 @@ describe('AutocompleterEditor', () => {
editor = new AutocompleterEditor(editorArguments);
const clearSpy = jest.spyOn(editor, 'clear');
- const clearBtnElm = divContainer.querySelector('.btn.icon-clear') as HTMLButtonElement;
+ const clearBtnElm = divContainer.querySelector('.btn.btn-clear') as HTMLButtonElement;
clearBtnElm.dispatchEvent(new Event('click'));
expect(clearSpy).toHaveBeenCalled();
diff --git a/packages/common/src/editors/__tests__/dateEditor.spec.ts b/packages/common/src/editors/__tests__/dateEditor.spec.ts
index 033fb2b51..622f3d670 100644
--- a/packages/common/src/editors/__tests__/dateEditor.spec.ts
+++ b/packages/common/src/editors/__tests__/dateEditor.spec.ts
@@ -1,17 +1,13 @@
-import moment from 'moment-mini';
+import { format } from '@formkit/tempo';
+import { VanillaCalendar } from 'vanilla-calendar-picker';
import { Editors } from '../index';
import { DateEditor } from '../dateEditor';
import { FieldType } from '../../enums/index';
-import { Column, ColumnEditor, Editor, EditorArguments, GridOption } from '../../interfaces/index';
+import { Column, Editor, EditorArguments, GridOption } from '../../interfaces/index';
import { TranslateServiceStub } from '../../../../../test/translateServiceStub';
import { SlickEvent, type SlickDataView, type SlickGrid } from '../../core/index';
-const containerId = 'demo-container';
-
-// define a
container to simulate the grid container
-const template = ``;
-
const dataViewStub = {
refresh: jest.fn(),
} as unknown as SlickDataView;
@@ -38,8 +34,30 @@ const gridStub = {
render: jest.fn(),
onBeforeEditCell: new SlickEvent(),
onCompositeEditorChange: new SlickEvent(),
+ sanitizeHtmlString: (str) => str,
} as unknown as SlickGrid;
+const gridId = 'grid1';
+const gridUid = 'slickgrid_124343';
+const template =
+ `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
`;
+
+jest.useFakeTimers();
+
describe('DateEditor', () => {
let translateService: TranslateServiceStub;
let divContainer: HTMLDivElement;
@@ -108,18 +126,17 @@ describe('DateEditor', () => {
expect(editorCount).toBe(1);
});
- it('should initialize the editor and expect to focus on the element after a small delay', (done) => {
+ it('should initialize the editor and expect to focus on the element after a small delay', () => {
const focusSpy = jest.spyOn(editor, 'focus');
- const showSpy = jest.spyOn(editor, 'focus');
+ const showSpy = jest.spyOn(editor, 'show');
editor = new DateEditor(editorArguments);
const editorCount = divContainer.querySelectorAll('input.editor-text.editor-startDate').length;
- setTimeout(() => {
- expect(editorCount).toBe(1);
- expect(focusSpy).toHaveBeenCalled();
- expect(showSpy).toHaveBeenCalled();
- done();
- }, 51);
+ jest.runAllTimers();
+
+ expect(editorCount).toBe(1);
+ expect(focusSpy).toHaveBeenCalled();
+ expect(showSpy).toHaveBeenCalled();
});
it('should have a placeholder when defined in its column definition', () => {
@@ -153,16 +170,22 @@ describe('DateEditor', () => {
expect(editor.columnEditor).toEqual(mockColumn.editor);
});
- it('should call "setValue" and expect the DOM element value to be the same string when calling "getValue"', () => {
+ it('should call "setValue" and expect the DOM element value to be the same string when calling "getValue"', async () => {
editor = new DateEditor(editorArguments);
- editor.setValue('2001-01-02T11:02:02.000Z');
- expect(editor.getValue()).toBe('2001-01-02T11:02:02.000Z');
+ jest.runAllTimers();
+
+ editor.setValue('2001-01-02T11:02:00.000Z');
+
+ expect(editor.getValue()).toBe('2001-01-02T11:02:00.000Z');
});
it('should call "setValue" with value & apply value flag and expect the DOM element to have same value and also expect the value to be applied to the item object', () => {
mockColumn.type = FieldType.dateIso;
editor = new DateEditor(editorArguments);
+
+ jest.runAllTimers();
+
editor.setValue('2001-01-02', true);
expect(editor.getValue()).toBe('2001-01-02');
@@ -172,17 +195,19 @@ describe('DateEditor', () => {
it('should define an item datacontext containing a string as cell value and expect this value to be loaded in the editor when calling "loadValue"', () => {
mockItemData = { id: 1, startDate: '2001-01-02T11:02:02.000Z', isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
- const editorElm = editor.editorDomElement;
- expect(editor.getValue()).toBe('2001-01-02T11:02:02.000Z');
- expect(editorElm.defaultValue).toBe('2001-01-02T11:02:02.000Z');
+ expect(editor.getValue()).toBe('2001-01-02');
});
it('should hide the DOM element when the "hide" method is called', () => {
editor = new DateEditor(editorArguments);
- const spy = jest.spyOn(editor.flatInstance, 'close');
- const calendarElm = document.body.querySelector('.flatpickr-calendar');
+
+ jest.runAllTimers();
+
+ const spy = jest.spyOn(editor.calendarInstance!, 'hide');
+ const calendarElm = document.body.querySelector('.vanilla-calendar');
editor.hide();
expect(calendarElm).toBeTruthy();
@@ -191,100 +216,108 @@ describe('DateEditor', () => {
it('should show the DOM element when the "show" method is called', () => {
editor = new DateEditor(editorArguments);
- const spy = jest.spyOn(editor.flatInstance, 'open');
- const calendarElm = document.body.querySelector('.flatpickr-calendar');
- editor.show();
- editor.focus();
- expect(gridStub.focus).toHaveBeenCalled();
- expect(calendarElm).toBeTruthy();
- expect(spy).toHaveBeenCalled();
- });
+ jest.runAllTimers();
- it('should enable Dark Mode and expect ".slick-dark-mode" CSS class to be found on parent element', () => {
- gridOptionMock.darkMode = true;
- editor = new DateEditor(editorArguments);
- const spy = jest.spyOn(editor.flatInstance, 'open');
- const calendarElm = document.body.querySelector('.flatpickr-calendar');
+ const spy = jest.spyOn(editor.calendarInstance!, 'show');
+ const calendarElm = document.body.querySelector('.vanilla-calendar');
editor.show();
editor.focus();
expect(gridStub.focus).toHaveBeenCalled();
- expect(calendarElm?.classList.contains('slick-dark-mode')).toBeTruthy();
+ expect(calendarElm).toBeTruthy();
expect(spy).toHaveBeenCalled();
});
- it('should call the "changeEditorOption" method and expect new option to be merged with the previous Editor options and also expect to call Flatpickr "set" method', () => {
+ it('should call the "changeEditorOption" method and expect new option to be merged with the previous Editor options', () => {
editor = new DateEditor(editorArguments);
- const spy = jest.spyOn(editor.flatInstance, 'set');
- const calendarElm = document.body.querySelector('.flatpickr-calendar');
- editor.changeEditorOption('minDate', 'today');
+ const calendarElm = document.body.querySelector('.vanilla-calendar');
+ editor.changeEditorOption('range', { disablePast: true });
+ editor.changeEditorOption('selected', { dates: ['2001-02-04'], month: 2 });
expect(calendarElm).toBeTruthy();
- expect(spy).toHaveBeenCalledWith('minDate', 'today');
+ expect(editor.pickerOptions.settings?.range?.disablePast).toBeTruthy();
+ expect(editor.pickerOptions.settings?.selected).toEqual({ dates: ['2001-02-04'], month: 2 });
+
+ editor.changeEditorOption('range', { edgesOnly: true });
+ editor.changeEditorOption('selected', { dates: ['2020-03-10', 'today'] });
+
+ expect(editor.pickerOptions.settings?.range).toEqual({ disablePast: true, edgesOnly: true });
+ expect(editor.pickerOptions.settings?.selected).toEqual({ dates: ['2020-03-10', 'today'], month: 2 });
});
describe('isValueChanged method', () => {
it('should return True when date is changed in the picker', () => {
- // change to allow input value only for testing purposes & use the regular flatpickr input to test that one too
- mockColumn.editor!.editorOptions = { allowInput: true, altInput: false };
+ const dateMock = '2024-04-02';
mockItemData = { id: 1, startDate: '2001-01-02T11:02:02.000Z', isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
+
editor.loadValue(mockItemData);
editor.focus();
- const editorInputElm = divContainer.querySelector('.flatpickr input') as HTMLInputElement;
+ const editorInputElm = editor.editorDomElement;
editorInputElm.value = '2024-04-02T16:02:02.239Z';
- editorInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
+ editor.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [dateMock], selectedHours: 11, selectedMinutes: 2 } as unknown as VanillaCalendar);
+ editor.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [dateMock], selectedHours: 11, selectedMinutes: 2, hide: jest.fn() } as unknown as VanillaCalendar);
expect(editor.isValueChanged()).toBe(true);
expect(editor.isValueTouched()).toBe(true);
});
it('should return True when date is reset by the clear date button', () => {
- // change to allow input value only for testing purposes & use the regular flatpickr input to test that one too
- mockColumn.editor!.editorOptions = { allowInput: true, altInput: false };
mockItemData = { id: 1, startDate: '2001-01-02T11:02:02.000Z', isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
+
editor.loadValue(mockItemData);
editor.focus();
- const clearBtnElm = divContainer.querySelector('.btn.icon-clear') as HTMLInputElement;
- const editorInputElm = divContainer.querySelector('.flatpickr input') as HTMLInputElement;
+ const clearBtnElm = divContainer.querySelector('.btn-clear') as HTMLInputElement;
+ const editorInputElm = divContainer.querySelector('input.date-picker') as HTMLInputElement;
clearBtnElm.click();
- editorInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
+ editor.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [] } as unknown as VanillaCalendar);
+ editor.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [], hide: jest.fn() } as unknown as VanillaCalendar);
+ expect(editor.calendarInstance?.settings.selected.dates).toEqual([]);
expect(editorInputElm.value).toBe('');
expect(editor.isValueChanged()).toBe(true);
expect(editor.isValueTouched()).toBe(true);
});
it('should also return True when date is reset by the clear date button even if the previous date was empty', () => {
- // change to allow input value only for testing purposes & use the regular flatpickr input to test that one too
- mockColumn.editor!.editorOptions = { allowInput: true, altInput: false };
mockItemData = { id: 1, startDate: '', isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
+
editor.loadValue(mockItemData);
editor.focus();
- const clearBtnElm = divContainer.querySelector('.btn.icon-clear') as HTMLInputElement;
- const editorInputElm = divContainer.querySelector('.flatpickr input') as HTMLInputElement;
+ const clearBtnElm = divContainer.querySelector('.btn-clear') as HTMLInputElement;
+ const editorInputElm = divContainer.querySelector('input.date-picker') as HTMLInputElement;
+ editor.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [] } as unknown as VanillaCalendar);
+ editor.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [], hide: jest.fn() } as unknown as VanillaCalendar);
clearBtnElm.click();
expect(editorInputElm.value).toBe('');
+ expect(editor.calendarInstance?.settings.selected.dates).toEqual([]);
expect(editor.isValueChanged()).toBe(true);
expect(editor.isValueTouched()).toBe(true);
});
it('should return False when date in the picker is the same as the current date', () => {
- mockItemData = { id: 1, startDate: '2001-01-02T11:02:02.000Z', isActive: true };
- mockColumn.editor!.editorOptions = { allowInput: true }; // change to allow input value only for testing purposes
+ mockItemData = { id: 1, startDate: '2001-01-02', isActive: true };
+ mockColumn.type = FieldType.dateIso;
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
+
editor.loadValue(mockItemData);
- const editorInputElm = divContainer.querySelector('input.flatpickr-alt-input') as HTMLInputElement;
- editorInputElm.value = '2001-01-02T11:02:02.000Z';
- editorInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
+
+ const editorInputElm = divContainer.querySelector('input.date-picker') as HTMLInputElement;
+ editorInputElm.value = '2001-01-02';
+ editor.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: ['2001-01-02'] } as unknown as VanillaCalendar);
+ editor.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: ['2001-01-02'], hide: jest.fn() } as unknown as VanillaCalendar);
expect(editor.isValueChanged()).toBe(false);
expect(editor.isValueTouched()).toBe(true);
@@ -293,13 +326,16 @@ describe('DateEditor', () => {
it('should return False when input date is invalid', () => {
mockItemData = { id: 1, startDate: '1900-02-32', isActive: true };
mockColumn.type = FieldType.dateUs;
- mockColumn.editor!.editorOptions = { allowInput: true }; // change to allow input value only for testing purposes
+ const dateMock = '1900-02-32';
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
+
editor.loadValue(mockItemData);
- const editorInputElm = divContainer.querySelector('input.flatpickr-alt-input') as HTMLInputElement;
- editorInputElm.value = '1900-02-32';
- editorInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
+ const editorInputElm = divContainer.querySelector('input.date-picker') as HTMLInputElement;
+ editorInputElm.value = dateMock;
+ editor.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [dateMock] } as unknown as VanillaCalendar);
+ editor.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [dateMock], hide: jest.fn() } as unknown as VanillaCalendar);
expect(editor.isValueChanged()).toBe(false);
expect(editor.isValueTouched()).toBe(true);
@@ -314,25 +350,27 @@ describe('DateEditor', () => {
const newDate = new Date(Date.UTC(2001, 0, 2, 16, 2, 2, 0));
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.applyValue(mockItemData, newDate);
// @ts-ignore:2349
- expect(mockItemData).toEqual({ id: 1, startDate: moment(newDate).format('YYYY-MM-DD'), isActive: true });
+ expect(mockItemData).toEqual({ id: 1, startDate: format(newDate, 'YYYY-MM-DD'), isActive: true });
});
it('should apply the value to the startDate property with "outputType" format with a field having dot notation (complex object) that passes validation', () => {
mockColumn.editor!.validator = null as any;
mockColumn.type = FieldType.date;
- mockColumn.outputType = FieldType.dateTimeIsoAmPm;
+ mockColumn.outputType = FieldType.dateTimeShortEuro;
mockColumn.field = 'employee.startDate';
mockItemData = { id: 1, employee: { startDate: '2001-04-05T11:33:42.000Z' }, isActive: true };
- const newDate = new Date(Date.UTC(2001, 0, 2, 16, 2, 2, 0));
+ const newDate = new Date(Date.UTC(2001, 10, 23, 16, 2, 2, 0));
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.applyValue(mockItemData, newDate);
// @ts-ignore:2349
- expect(mockItemData).toEqual({ id: 1, employee: { startDate: moment(newDate).format('YYYY-MM-DD hh:mm:ss a') }, isActive: true });
+ expect(mockItemData).toEqual({ id: 1, employee: { startDate: format(newDate, 'D/M/YYYY HH:mm') }, isActive: true });
});
it('should apply the value to the startDate property with output format defined by "saveOutputType" when it passes validation', () => {
@@ -343,10 +381,11 @@ describe('DateEditor', () => {
const newDate = new Date(Date.UTC(2001, 0, 2, 16, 2, 2, 0));
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.applyValue(mockItemData, newDate);
// @ts-ignore:2349
- expect(mockItemData).toEqual({ id: 1, startDate: moment(newDate).format('YYYY-MM-DD hh:mm:ss a'), isActive: true });
+ expect(mockItemData).toEqual({ id: 1, startDate: format(newDate, 'YYYY-MM-DD hh:mm:ss a', 'en-US'), isActive: true });
});
it('should return item data with an empty string in its value when it fails the custom validation', () => {
@@ -359,6 +398,7 @@ describe('DateEditor', () => {
mockItemData = { id: 1, startDate: '2001-04-05T11:33:42.000Z', isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.applyValue(mockItemData, '2001-01-02T16:02:02.000+05:00');
expect(mockItemData).toEqual({ id: 1, startDate: '', isActive: true });
@@ -371,6 +411,7 @@ describe('DateEditor', () => {
mockItemData = { id: 1, startDate: '2001-01-02T16:02:02.000+05:00', isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
const output = editor.serializeValue();
@@ -381,6 +422,7 @@ describe('DateEditor', () => {
mockItemData = { id: 1, startDate: '', isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
const output = editor.serializeValue();
@@ -391,6 +433,7 @@ describe('DateEditor', () => {
mockItemData = { id: 1, startDate: null, isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
const output = editor.serializeValue();
@@ -403,6 +446,7 @@ describe('DateEditor', () => {
mockItemData = { id: 1, employee: { startDate: '2001-01-02T16:02:02.000+05:00' }, isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
const output = editor.serializeValue();
@@ -421,6 +465,7 @@ describe('DateEditor', () => {
const spy = jest.spyOn(gridStub.getEditorLock(), 'commitCurrentEdit');
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
editor.setValue('2022-03-02T16:02:02.000+05:00');
editor.save();
@@ -434,6 +479,7 @@ describe('DateEditor', () => {
const spy = jest.spyOn(editorArguments, 'commitChanges');
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
editor.setValue('2022-03-02T16:02:02.000+05:00');
editor.save();
@@ -448,24 +494,27 @@ describe('DateEditor', () => {
const spy = jest.spyOn(gridStub.getEditorLock(), 'commitCurrentEdit');
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
editor.save();
expect(spy).not.toHaveBeenCalled();
});
- it('should not throw any error when date is invalid when lower than required "minDate" defined in the "editorOptions" and "autoCommitEdit" is enabled', () => {
- // change to allow input value only for testing purposes & use the regular flatpickr input to test that one too
- mockColumn.editor!.editorOptions = { minDate: 'today', altInput: true };
+ it('should not throw any error when date is lower than required "minDate" defined in the "editorOptions" and "autoCommitEdit" is enabled', () => {
+ mockColumn.editor!.editorOptions = { range: { min: 'today' } };
mockItemData = { id: 1, startDate: '500-01-02T11:02:02.000Z', isActive: true };
gridOptionMock.autoCommitEdit = true;
gridOptionMock.autoEdit = true;
gridOptionMock.editable = true;
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
- editor.flatInstance.toggle();
- const editorInputElm = divContainer.querySelector('.flatpickr input') as HTMLInputElement;
+ editor.calendarInstance?.show();
+ const editorInputElm = divContainer.querySelector('input.date-picker') as HTMLInputElement;
+ editor.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [] } as unknown as VanillaCalendar);
+ editor.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [], hide: jest.fn() } as unknown as VanillaCalendar);
expect(editor.pickerOptions).toBeTruthy();
expect(editorInputElm.value).toBe('');
@@ -473,9 +522,9 @@ describe('DateEditor', () => {
});
it('should not throw any error when date is invalid when lower than required "minDate" defined in the global default editorOptions and "autoCommitEdit" is enabled', () => {
- // change to allow input value only for testing purposes & use the regular flatpickr input to test that one too
+ // change to allow input value only for testing purposes & use the regular date picker input to test that one too
gridOptionMock.defaultEditorOptions = {
- date: { minDate: 'today', altInput: true }
+ date: { range: { min: 'today' } }
};
mockItemData = { id: 1, startDate: '500-01-02T11:02:02.000Z', isActive: true };
gridOptionMock.autoCommitEdit = true;
@@ -483,9 +532,12 @@ describe('DateEditor', () => {
gridOptionMock.editable = true;
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
- editor.flatInstance.toggle();
- const editorInputElm = divContainer.querySelector('.flatpickr input') as HTMLInputElement;
+ editor.calendarInstance?.show();
+ const editorInputElm = divContainer.querySelector('input.date-picker') as HTMLInputElement;
+ editor.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [] } as unknown as VanillaCalendar);
+ editor.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [], hide: jest.fn() } as unknown as VanillaCalendar);
expect(editor.pickerOptions).toBeTruthy();
expect(editorInputElm.value).toBe('');
@@ -497,6 +549,7 @@ describe('DateEditor', () => {
it('should return False when field is required and field is empty', () => {
mockColumn.editor!.required = true;
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
const validation = editor.validate(null, '');
expect(validation).toEqual({ valid: false, msg: 'Field is required' });
@@ -505,6 +558,7 @@ describe('DateEditor', () => {
it('should return True when field is required and input is a valid input value', () => {
mockColumn.editor!.required = true;
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
const validation = editor.validate(null, 'text');
expect(validation).toEqual({ valid: true, msg: null });
@@ -512,36 +566,20 @@ describe('DateEditor', () => {
});
describe('with different locale', () => {
- it('should display a console warning when locale is not previously imported', (done) => {
- const consoleSpy = jest.spyOn(global.console, 'warn').mockReturnValue();
-
- gridOptionMock.translater = translateService;
-
- translateService.use('zz-yy'); // will be trimmed to 2 chars "zz"
- editor = new DateEditor(editorArguments);
- setTimeout(() => {
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(`[Slickgrid-Universal] Flatpickr missing locale imports (zz), will revert to English as the default locale.`));
- done();
- });
- });
-
it('should display text in new locale', async () => {
- await (await import('flatpickr/dist/l10n/fr')).French;
gridOptionMock.translater = translateService;
translateService.use('fr');
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
- const spy = jest.spyOn(editor.flatInstance, 'open');
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
- const selectonOptionElms = calendarElm.querySelectorAll(' .flatpickr-monthDropdown-months option');
-
- editor.show();
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
+ const monthElm = calendarElm.querySelector('.vanilla-calendar-month') as HTMLButtonElement;
expect(calendarElm).toBeTruthy();
- expect(selectonOptionElms.length).toBe(12);
- expect(selectonOptionElms[0].textContent).toBe('janvier');
- expect(spy).toHaveBeenCalled();
+ expect(monthElm).toBeTruthy();
+ expect(editor.calendarInstance?.settings.lang).toBe('fr');
+ // expect(monthElm.textContent).toBe('janvier');
});
});
});
@@ -566,6 +604,7 @@ describe('DateEditor', () => {
} as any);
mockColumn.type = FieldType.dateIso;
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.setValue('2001-01-02', true);
expect(editor.getValue()).toContain('2001-01-02');
@@ -583,6 +622,7 @@ describe('DateEditor', () => {
} as any);
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
const disableSpy = jest.spyOn(editor, 'disable');
editor.show();
@@ -602,6 +642,7 @@ describe('DateEditor', () => {
} as any);
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
const disableSpy = jest.spyOn(editor, 'disable');
editor.show();
@@ -613,8 +654,8 @@ describe('DateEditor', () => {
formValues: { startDate: '' }, editors: {}, triggeredBy: 'user',
}, expect.anything());
expect(disableSpy).toHaveBeenCalledWith(true);
- expect(editor.flatInstance._input.disabled).toEqual(true);
- expect(editor.flatInstance._input.value).toEqual('');
+ expect(editor.calendarInstance?.HTMLInputElement?.disabled).toEqual(true);
+ expect(editor.calendarInstance?.HTMLInputElement?.value).toEqual('');
});
it('should call "show" and expect the DOM element to become disabled and empty when "onBeforeEditCell" returns false and also expect "onBeforeComposite" to not be called because the value is blank', () => {
@@ -631,6 +672,7 @@ describe('DateEditor', () => {
};
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
const disableSpy = jest.spyOn(editor, 'disable');
editor.show();
@@ -639,8 +681,8 @@ describe('DateEditor', () => {
expect(onBeforeEditSpy).toHaveBeenCalledWith({ ...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub, target: 'composite', compositeEditorOptions: editorArguments.compositeEditorOptions });
expect(onCompositeEditorSpy).not.toHaveBeenCalled();
expect(disableSpy).toHaveBeenCalledWith(true);
- expect(editor.flatInstance._input.disabled).toEqual(true);
- expect(editor.flatInstance._input.value).toEqual('');
+ expect(editor.calendarInstance?.HTMLInputElement?.disabled).toEqual(true);
+ expect(editor.calendarInstance?.HTMLInputElement?.value).toEqual('');
});
it('should call "disable" method and expect the DOM element to become disabled and have an empty formValues be passed in the onCompositeEditorChange event', () => {
@@ -654,6 +696,7 @@ describe('DateEditor', () => {
};
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue({ ...mockItemData, startDate: '2020-01-01' });
editor.show();
editor.disable();
@@ -663,13 +706,13 @@ describe('DateEditor', () => {
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: {}, editors: {}, triggeredBy: 'user',
}, expect.anything());
- expect(editor.flatInstance._input.disabled).toEqual(true);
- expect(editor.flatInstance._input.value).toEqual('');
+ expect(editor.calendarInstance?.HTMLInputElement?.disabled).toEqual(true);
+ expect(editor.calendarInstance?.HTMLInputElement?.value).toEqual('');
});
it('should expect "onCompositeEditorChange" to have been triggered with the new value showing up in its "formValues" object', () => {
const activeCellMock = { row: 0, cell: 0 };
- mockColumn.editor!.editorOptions = { allowInput: true, altInput: false };
+ const dateMock = '2001-01-02';
mockColumn.type = FieldType.dateIso;
const getCellSpy = jest.spyOn(gridStub, 'getActiveCell').mockReturnValue(activeCellMock);
const onBeforeEditSpy = jest.spyOn(gridStub.onBeforeEditCell, 'notify').mockReturnValue({
@@ -679,20 +722,22 @@ describe('DateEditor', () => {
getReturnValue: () => false
} as any);
gridOptionMock.autoCommitEdit = true;
- mockItemData = { id: 1, startDate: '2001-01-02', isActive: true };
+ mockItemData = { id: 1, startDate: dateMock, isActive: true };
editor = new DateEditor(editorArguments);
+ jest.runAllTimers();
editor.loadValue(mockItemData);
editor.focus();
- const editorInputElm = divContainer.querySelector('.flatpickr input') as HTMLInputElement;
- editorInputElm.value = '2001-01-02';
- editorInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
+ const editorInputElm = divContainer.querySelector('input.date-picker') as HTMLInputElement;
+ editorInputElm.value = dateMock;
+ editor.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [dateMock] } as unknown as VanillaCalendar);
+ editor.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: editorInputElm, selectedDates: [dateMock], hide: jest.fn() } as unknown as VanillaCalendar);
expect(getCellSpy).toHaveBeenCalled();
expect(onBeforeEditSpy).toHaveBeenCalledWith({ ...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub, target: 'composite', compositeEditorOptions: editorArguments.compositeEditorOptions });
expect(onCompositeEditorSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
- formValues: { startDate: '2001-01-02' }, editors: {}, triggeredBy: 'user',
+ formValues: { startDate: dateMock }, editors: {}, triggeredBy: 'user',
}, expect.anything());
});
});
diff --git a/packages/common/src/editors/__tests__/floatEditor.spec.ts b/packages/common/src/editors/__tests__/floatEditor.spec.ts
index a0b655538..24936def2 100644
--- a/packages/common/src/editors/__tests__/floatEditor.spec.ts
+++ b/packages/common/src/editors/__tests__/floatEditor.spec.ts
@@ -101,7 +101,7 @@ describe('FloatEditor', () => {
editor = new FloatEditor(editorArguments);
const editorElm = divContainer.querySelector('input.editor-text.editor-price') as HTMLInputElement;
- expect(editorElm.ariaLabel).toBe('Price Number Editor');
+ expect(editorElm.ariaLabel).toBe('Price Input Editor');
});
it('should initialize the editor and focus on the element after a small delay', () => {
diff --git a/packages/common/src/editors/__tests__/inputEditor.spec.ts b/packages/common/src/editors/__tests__/inputEditor.spec.ts
index 1b592357f..52bc4d6df 100644
--- a/packages/common/src/editors/__tests__/inputEditor.spec.ts
+++ b/packages/common/src/editors/__tests__/inputEditor.spec.ts
@@ -390,6 +390,24 @@ describe('InputEditor (TextEditor)', () => {
expect(spyCommit).toHaveBeenCalled();
expect(spySave).toHaveBeenCalled();
});
+
+ it('should call "getEditorLock" and "save" methods when "hasAutoCommitEdit" is enabled and the event "blur" is triggered', () => {
+ mockItemData = { id: 1, title: 'task', isActive: true };
+ gridOptionMock.autoCommitEdit = true;
+ const spyCommit = jest.spyOn(gridStub.getEditorLock(), 'commitCurrentEdit');
+
+ editor = new InputEditor(editorArguments, 'text');
+ editor.loadValue(mockItemData);
+ editor.setValue('task 21');
+ const spySave = jest.spyOn(editor, 'save');
+ const editorElm = editor.editorDomElement;
+
+ editorElm.dispatchEvent(new (window.window as any).Event('blur'));
+ jest.runAllTimers(); // fast-forward timer
+
+ expect(spyCommit).toHaveBeenCalled();
+ expect(spySave).toHaveBeenCalled();
+ });
});
describe('validate method', () => {
diff --git a/packages/common/src/editors/__tests__/integerEditor.spec.ts b/packages/common/src/editors/__tests__/integerEditor.spec.ts
index 3a98aa326..2d81e32cc 100644
--- a/packages/common/src/editors/__tests__/integerEditor.spec.ts
+++ b/packages/common/src/editors/__tests__/integerEditor.spec.ts
@@ -101,7 +101,7 @@ describe('IntegerEditor', () => {
editor = new IntegerEditor(editorArguments);
const editorElm = divContainer.querySelector('input.editor-text.editor-price') as HTMLInputElement;
- expect(editorElm.ariaLabel).toBe('Price Slider Editor');
+ expect(editorElm.ariaLabel).toBe('Price Input Editor');
});
it('should initialize the editor and focus on the element after a small delay', () => {
diff --git a/packages/common/src/editors/__tests__/multipleSelectEditor.spec.ts b/packages/common/src/editors/__tests__/multipleSelectEditor.spec.ts
index 2c2efaa12..242246506 100644
--- a/packages/common/src/editors/__tests__/multipleSelectEditor.spec.ts
+++ b/packages/common/src/editors/__tests__/multipleSelectEditor.spec.ts
@@ -89,11 +89,11 @@ describe('MultipleSelectEditor', () => {
gridOptionMock.translater = translateService;
editor = new MultipleSelectEditor(editorArguments, 0);
const editorCount = document.body.querySelectorAll('select.ms-filter.editor-gender').length;
- const spy = jest.spyOn(editor, 'show');
+
jest.runAllTimers(); // fast-forward timer
- expect(spy).toHaveBeenCalled();
expect(editorCount).toBe(1);
+ expect(editor.msInstance?.getOptions().isOpen).toBeTruthy();
});
it('should call "setValue" with a single string and expect the string to be returned as an array when calling "getValue"', () => {
diff --git a/packages/common/src/editors/__tests__/selectEditor.spec.ts b/packages/common/src/editors/__tests__/selectEditor.spec.ts
index 5e622622d..3562cbf5c 100644
--- a/packages/common/src/editors/__tests__/selectEditor.spec.ts
+++ b/packages/common/src/editors/__tests__/selectEditor.spec.ts
@@ -41,6 +41,7 @@ const gridStub = {
render: jest.fn(),
onBeforeEditCell: new SlickEvent(),
onCompositeEditorChange: new SlickEvent(),
+ sanitizeHtmlString: (str) => str,
} as unknown as SlickGrid;
describe('SelectEditor', () => {
@@ -630,6 +631,38 @@ describe('SelectEditor', () => {
expect(saveSpy).toHaveBeenCalledWith(false);
});
+ it('should cancel changes when Escape key is pressed and should not call "save()"', () => {
+ mockItemData = { id: 1, gender: 'male', isActive: true };
+ gridOptionMock.autoCommitEdit = false;
+
+ editor = new SelectEditor(editorArguments, true);
+ const cancelSpy = jest.spyOn(editor, 'cancel');
+ const saveSpy = jest.spyOn(editor, 'save');
+
+ editor.loadValue(mockItemData);
+ editor.msInstance?.close('key.escape');
+ editor.destroy();
+
+ expect(cancelSpy).toHaveBeenCalled();
+ expect(saveSpy).not.toHaveBeenCalled();
+ });
+
+ it('should not "save()" when clicking ouside the select on body', () => {
+ mockItemData = { id: 1, gender: 'male', isActive: true };
+ gridOptionMock.autoCommitEdit = false;
+
+ editor = new SelectEditor(editorArguments, true);
+ const cancelSpy = jest.spyOn(editor, 'cancel');
+ const saveSpy = jest.spyOn(editor, 'save');
+
+ editor.loadValue(mockItemData);
+ editor.msInstance?.close('body.click');
+ editor.destroy();
+
+ expect(cancelSpy).not.toHaveBeenCalled();
+ expect(saveSpy).not.toHaveBeenCalled();
+ });
+
it('should not call "commitCurrentEdit" when "hasAutoCommitEdit" is disabled', () => {
mockItemData = { id: 1, gender: 'male', isActive: true };
gridOptionMock.autoCommitEdit = false;
@@ -840,7 +873,7 @@ describe('SelectEditor', () => {
it('should create the multi-select editor with a default search term and have the HTML rendered when "enableRenderHtml" is set', () => {
mockColumn.editor = {
enableRenderHtml: true,
- collection: [{ value: true, label: 'True', labelPrefix: ` ` }, { value: false, label: 'False' }],
+ collection: [{ value: true, label: 'True', labelPrefix: ` ` }, { value: false, label: 'False' }],
customStructure: {
value: 'isEffort',
label: 'label',
@@ -854,41 +887,13 @@ describe('SelectEditor', () => {
editorBtnElm.click();
expect(editorListElm.length).toBe(2);
- expect(editorListElm[0].innerHTML).toBe(' True');
- });
-
- it('should create the multi-select editor with a default search term and have the HTML rendered and sanitized when "enableRenderHtml" is set and has ` }, { isEffort: false, label: 'False' }],
- collectionOptions: {
- separatorBetweenTextLabels: ': ',
- includePrefixSuffixToSelectedValues: true,
- },
- customStructure: {
- value: 'isEffort',
- label: 'label',
- labelPrefix: 'labelPrefix',
- },
- };
- mockItemData = { id: 1, gender: 'male', isEffort: false };
-
- editor = new SelectEditor(editorArguments, true, 0);
- editor.loadValue(mockItemData);
- editor.setValue([false]);
- const editorBtnElm = divContainer.querySelector('.ms-parent.ms-filter.editor-gender button.ms-choice') as HTMLButtonElement;
- const editorListElm = divContainer.querySelectorAll(`[data-name=editor-gender].ms-drop ul>li span`);
- editorBtnElm.click();
-
- expect(editor.getValue()).toEqual(['']);
- expect(editorListElm.length).toBe(2);
- expect(editorListElm[0].innerHTML).toBe(' : True');
+ expect(editorListElm[0].innerHTML).toBe(' True');
});
- it('should create the multi-select editor with a default search term and have the HTML rendered and sanitized when using a custom "sanitizer" and "enableRenderHtml" flag is set and has ` }, { isEffort: false, label: 'False' }],
+ collection: [{ isEffort: true, label: 'True', labelPrefix: ` ` }, { isEffort: false, label: 'False' }],
collectionOptions: {
separatorBetweenTextLabels: ': ',
includePrefixSuffixToSelectedValues: true,
@@ -900,7 +905,6 @@ describe('SelectEditor', () => {
},
};
mockItemData = { id: 1, gender: 'male', isEffort: false };
- gridOptionMock.sanitizer = (dirtyHtml) => dirtyHtml.replace(/( ` }, { isEffort: false, label: 'False' }],
+ collection: [{ isEffort: true, label: 'True', labelPrefix: ` ` }, { isEffort: false, label: 'False' }],
collectionOptions: {
separatorBetweenTextLabels: ': ',
includePrefixSuffixToSelectedValues: true,
@@ -281,9 +282,9 @@ describe('SingleSelectEditor', () => {
editorListElm[0].click();
expect(editorBtnElm).toBeTruthy();
- expect(editor.getValue()).toEqual(` : true`);
+ expect(editor.getValue()).toEqual(` : true`);
expect(editorListElm.length).toBe(2);
- expect(editorListElm[0].innerHTML).toBe(' : True');
+ expect(editorListElm[0].innerHTML).toBe(' : True');
});
});
});
diff --git a/packages/common/src/editors/autocompleterEditor.ts b/packages/common/src/editors/autocompleterEditor.ts
index 69b73fed8..91025a790 100644
--- a/packages/common/src/editors/autocompleterEditor.ts
+++ b/packages/common/src/editors/autocompleterEditor.ts
@@ -22,7 +22,6 @@ import type {
} from '../interfaces/index';
import { textValidator } from '../editorValidators/textValidator';
import { addAutocompleteLoadingByOverridingFetch } from '../commonEditorFilter';
-import { sanitizeTextByAvailableSanitizer, } from '../services/domUtilities';
import { findOrDefault, getDescendantProperty, } from '../services/utilities';
import type { TranslaterService } from '../services/translater.service';
import { SlickEventData, type SlickGrid } from '../core/index';
@@ -516,7 +515,7 @@ export class AutocompleterEditor implements Ed
// sanitize any unauthorized html tags like script and others
// for the remaining allowed tags we'll permit all attributes
- const sanitizedText = sanitizeTextByAvailableSanitizer(this.gridOptions, finalText) || '';
+ const sanitizedText = this.grid.sanitizeHtmlString(finalText) || '';
const div = document.createElement('div');
div[isRenderHtmlEnabled ? 'innerHTML' : 'textContent'] = sanitizedText;
@@ -530,7 +529,8 @@ export class AutocompleterEditor implements Ed
this._editorInputGroupElm = createDomElement('div', { className: 'autocomplete-container input-group' });
const closeButtonGroupElm = createDomElement('span', { className: 'input-group-btn input-group-append', dataset: { clear: '' } });
- this._clearButtonElm = createDomElement('button', { type: 'button', className: 'btn btn-default icon-clear' });
+ this._clearButtonElm = createDomElement('button', { type: 'button', className: 'btn btn-default btn-clear' });
+ this._clearButtonElm.appendChild(createDomElement('i', { className: 'icon-clear' }));
this._inputElm = createDomElement(
'input',
{
@@ -553,7 +553,7 @@ export class AutocompleterEditor implements Ed
}
this._bindEventService.bind(this._inputElm, 'focus', () => this._inputElm?.select());
- this._bindEventService.bind(this._inputElm, 'keydown', ((event: KeyboardEvent) => {
+ this._bindEventService.bind(this._inputElm, 'keydown', ((event: KeyboardEvent & { target: HTMLInputElement; }) => {
this._lastInputKeyEvent = event;
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
event.stopImmediatePropagation();
@@ -561,10 +561,8 @@ export class AutocompleterEditor implements Ed
// in case the user wants to save even an empty value,
// we need to subscribe to the onKeyDown event for that use case and clear the current value
- if (this.columnEditor.alwaysSaveOnEnterKey) {
- if (event.key === 'Enter') {
- this._currentValue = null;
- }
+ if (event.key === 'Enter' && event.target.value === '' && this.columnEditor.alwaysSaveOnEnterKey) {
+ this._currentValue = null;
}
}) as EventListener);
diff --git a/packages/common/src/editors/dateEditor.ts b/packages/common/src/editors/dateEditor.ts
index 0d52581c8..48a548188 100644
--- a/packages/common/src/editors/dateEditor.ts
+++ b/packages/common/src/editors/dateEditor.ts
@@ -1,10 +1,7 @@
import { BindingEventService } from '@slickgrid-universal/binding';
-import { createDomElement, destroyAllElementProps, emptyElement, setDeepValue } from '@slickgrid-universal/utils';
-import flatpickr from 'flatpickr';
-import type { BaseOptions as FlatpickrBaseOptions } from 'flatpickr/dist/types/options';
-import type { Instance as FlatpickrInstance } from 'flatpickr/dist/types/instance';
-import * as moment_ from 'moment-mini';
-const moment = (moment_ as any)['default'] || moment_;
+import { createDomElement, emptyElement, extend, setDeepValue } from '@slickgrid-universal/utils';
+import { parse } from '@formkit/tempo';
+import { VanillaCalendar, type IOptions } from 'vanilla-calendar-picker';
import { Constants } from './../constants';
import { FieldType } from '../enums/index';
@@ -16,30 +13,31 @@ import type {
EditorArguments,
EditorValidator,
EditorValidationResult,
- FlatpickrOption,
GridOption,
+ VanillaCalendarOption,
} from './../interfaces/index';
-import { getDescendantProperty, mapFlatpickrDateFormatWithFieldType, mapMomentDateFormatWithFieldType, } from './../services/utilities';
+import { getDescendantProperty, } from './../services/utilities';
import type { TranslaterService } from '../services/translater.service';
import { SlickEventData, type SlickGrid } from '../core/index';
+import { setPickerDates } from '../commonEditorFilter';
+import { formatDateByFieldType, mapTempoDateFormatWithFieldType } from '../services/dateUtils';
/*
- * An example of a date picker editor using Flatpickr
- * https://chmln.github.io/flatpickr
+ * An example of a date picker editor using Vanilla-Calendar-Picker
*/
export class DateEditor implements Editor {
protected _bindEventService: BindingEventService;
protected _clearButtonElm!: HTMLButtonElement;
protected _editorInputGroupElm!: HTMLDivElement;
protected _inputElm!: HTMLInputElement;
- protected _inputWithDataElm!: HTMLInputElement | null;
protected _isValueTouched = false;
+ protected _lastClickIsDate = false;
protected _lastTriggeredByClearDate = false;
protected _originalDate?: string;
- protected _pickerMergedOptions!: FlatpickrOption;
-
- flatInstance!: FlatpickrInstance;
+ protected _pickerMergedOptions!: IOptions;
+ calendarInstance?: VanillaCalendar;
defaultDate?: string;
+ hasTimePicker = false;
/** is the Editor disabled? */
disabled = false;
@@ -86,8 +84,8 @@ export class DateEditor implements Editor {
return this._inputElm;
}
- /** Get Flatpickr options passed to the editor by the user */
- get editorOptions(): FlatpickrOption {
+ /** Get options passed to the editor by the user */
+ get editorOptions(): IOptions {
return { ...this.gridOptions.defaultEditorOptions?.date, ...this.columnEditor?.editorOptions };
}
@@ -95,7 +93,7 @@ export class DateEditor implements Editor {
return this.gridOptions.autoCommitEdit ?? false;
}
- get pickerOptions(): FlatpickrOption {
+ get pickerOptions(): IOptions {
return this._pickerMergedOptions;
}
@@ -104,112 +102,151 @@ export class DateEditor implements Editor {
return this.columnEditor?.validator ?? this.columnDef?.validator;
}
- init(): void {
+ async init() {
if (this.args && this.columnDef) {
const compositeEditorOptions = this.args.compositeEditorOptions;
const columnId = this.columnDef?.id ?? '';
- const gridOptions = (this.args.grid.getOptions() || {}) as GridOption;
- this.defaultDate = (this.args.item) ? this.args.item[this.columnDef.field] : null;
- const inputFormat = mapFlatpickrDateFormatWithFieldType(this.columnEditor.type || this.columnDef.type || FieldType.dateUtc);
- const outputFormat = mapFlatpickrDateFormatWithFieldType(this.columnDef.outputType || this.columnEditor.type || this.columnDef.type || FieldType.dateUtc);
- let currentLocale = this._translaterService?.getCurrentLanguage?.() || gridOptions.locale || 'en';
- if (currentLocale.length > 2) {
- currentLocale = currentLocale.substring(0, 2);
+ const gridOptions: GridOption = this.args.grid.getOptions() || {};
+ this.defaultDate = this.args.item?.[this.columnDef.field];
+ const outputFieldType = this.columnDef.outputType || this.columnEditor.type || this.columnDef.type || FieldType.dateUtc;
+ const outputFormat = mapTempoDateFormatWithFieldType(outputFieldType);
+ const currentLocale = this._translaterService?.getCurrentLanguage?.() || gridOptions.locale || 'en';
+
+ // add the time picker when format is UTC (TZ - ISO8601) or has the 'h' (meaning hours)
+ if (outputFormat && (outputFormat === 'ISO8601' || outputFormat.toLowerCase().includes('h'))) {
+ this.hasTimePicker = true;
}
-
- const pickerOptions: FlatpickrOption = {
- defaultDate: this.defaultDate as string,
- altInput: true,
- altFormat: outputFormat,
- dateFormat: inputFormat,
- closeOnSelect: true,
- wrap: true,
- locale: currentLocale,
- onChange: () => this.handleOnDateChange(),
- errorHandler: (error: Error) => {
- if (error.toString().includes('invalid locale')) {
- console.warn(`[Slickgrid-Universal] Flatpickr missing locale imports (${currentLocale}), will revert to English as the default locale.
- See Flatpickr Localization for more info, for example if we want to use French, then we can import it with: import 'flatpickr/dist/l10n/fr';`);
+ const pickerFormat = mapTempoDateFormatWithFieldType(this.hasTimePicker ? FieldType.dateTimeIsoAM_PM : FieldType.dateIso);
+
+ const pickerOptions: IOptions = {
+ input: true,
+ jumpToSelectedDate: true,
+ sanitizer: (dirtyHtml) => this.grid.sanitizeHtmlString(dirtyHtml),
+ toggleSelected: false,
+ actions: {
+ clickDay: () => {
+ this._lastClickIsDate = true;
+ },
+ changeToInput: (_e, self) => {
+ if (self.HTMLInputElement) {
+ let selectedDate = '';
+ if (self.selectedDates[0]) {
+ selectedDate = self.selectedDates[0];
+ self.HTMLInputElement.value = formatDateByFieldType(self.selectedDates[0], undefined, outputFieldType);
+ } else {
+ self.HTMLInputElement.value = '';
+ }
+
+ if (selectedDate && this.hasTimePicker) {
+ const tempoDate = parse(selectedDate, pickerFormat);
+ tempoDate.setHours(+(self.selectedHours || 0));
+ tempoDate.setMinutes(+(self.selectedMinutes || 0));
+ self.HTMLInputElement.value = formatDateByFieldType(tempoDate, undefined, outputFieldType);
+ }
+
+ if (this._lastClickIsDate) {
+ this.handleOnDateChange();
+ self.hide();
+ }
+ }
}
- // for any other error do nothing
- // Flatpickr is a little too sensitive and will throw an error when provided date is lower than minDate so just disregard the error completely
- }
+ },
+ settings: {
+ lang: currentLocale,
+ iso8601: false,
+ visibility: {
+ theme: this.gridOptions?.darkMode ? 'dark' : 'light',
+ positionToInput: 'auto',
+ weekend: false,
+ },
+ },
};
- // merge options with optional user's custom options
- this._pickerMergedOptions = { ...pickerOptions, ...(this.editorOptions as FlatpickrOption) };
- const inputCssClasses = `.editor-text.editor-${columnId}.form-control`;
- if (this._pickerMergedOptions.altInput) {
- this._pickerMergedOptions.altInputClass = 'flatpickr-alt-input form-control';
+ // add the time picker when format includes time (hours/minutes)
+ if (this.hasTimePicker) {
+ pickerOptions.settings!.selection = {
+ time: 24
+ };
}
- this._editorInputGroupElm = createDomElement('div', { className: 'flatpickr input-group' });
+ // merge options with optional user's custom options
+ this._pickerMergedOptions = extend(true, {}, pickerOptions, { settings: this.editorOptions, type: 'default' });
+
+ const inputCssClasses = `.editor-text.date-picker.editor-${columnId}.form-control.input-group-editor`;
+ this._editorInputGroupElm = createDomElement('div', { className: 'vanilla-picker input-group' });
const closeButtonGroupElm = createDomElement('span', { className: 'input-group-btn input-group-append', dataset: { clear: '' } });
- this._clearButtonElm = createDomElement('button', { type: 'button', className: 'btn btn-default icon-clear' });
+ this._clearButtonElm = createDomElement('button', { type: 'button', className: 'btn btn-default btn-clear' });
+ this._clearButtonElm.appendChild(createDomElement('i', { className: 'icon-clear' }));
this._inputElm = createDomElement(
'input',
{
placeholder: this.columnEditor?.placeholder ?? '',
title: this.columnEditor && this.columnEditor.title || '',
className: inputCssClasses.replace(/\./g, ' '),
- dataset: { input: '', defaultdate: this.defaultDate }
+ dataset: { input: '', defaultdate: this.defaultDate },
+ readOnly: true,
},
this._editorInputGroupElm
);
+ this.args.container.appendChild(this._editorInputGroupElm);
+
// show clear date button (unless user specifically doesn't want it)
- if (!(this.editorOptions as FlatpickrOption)?.hideClearButton) {
+ if (!(this.columnEditor.editorOptions as any)?.hideClearButton) {
closeButtonGroupElm.appendChild(this._clearButtonElm);
this._editorInputGroupElm.appendChild(closeButtonGroupElm);
- this._bindEventService.bind(this._clearButtonElm, 'click', () => this._lastTriggeredByClearDate = true);
+ this._bindEventService.bind(this._clearButtonElm, 'click', () => {
+ this.clear();
+ this.handleOnDateChange();
+ });
}
- this.args.container.appendChild(this._editorInputGroupElm);
- this.flatInstance = flatpickr(this._editorInputGroupElm, this._pickerMergedOptions as unknown as Partial);
-
- // add dark mode CSS class when enabled
- if (this.gridOptions?.darkMode) {
- this.flatInstance.calendarContainer.classList.add('slick-dark-mode');
- }
-
- // when we're using an alternate input to display data, we'll consider this input as the one to do the focus later on
- // else just use the top one
- this._inputWithDataElm = (this._pickerMergedOptions?.altInput) ? document.querySelector(`${inputCssClasses}.flatpickr-alt-input`) : this._inputElm;
-
- if (!compositeEditorOptions) {
- setTimeout(() => {
+ setTimeout(() => {
+ this.calendarInstance = new VanillaCalendar(this._inputElm, this._pickerMergedOptions);
+ this.calendarInstance.init();
+ if (!compositeEditorOptions) {
this.show();
this.focus();
- }, 50);
- }
+ }
+ if (this.calendarInstance) {
+ setPickerDates(this._inputElm, this.calendarInstance, this.defaultDate, this.columnDef, this.columnEditor);
+ this.calendarInstance.update({
+ dates: true,
+ month: true,
+ year: true,
+ time: true,
+ });
+ }
+ });
}
}
destroy() {
this.hide();
this._bindEventService.unbindAll();
+ this.calendarInstance?.destroy();
- if (typeof this.flatInstance?.destroy === 'function') {
- this.flatInstance.destroy();
- if (this.flatInstance?.element) {
- setTimeout(() => destroyAllElementProps(this.flatInstance));
- }
- }
emptyElement(this._editorInputGroupElm);
- emptyElement(this._inputWithDataElm);
emptyElement(this._inputElm);
- this._editorInputGroupElm?.remove?.();
- this._inputWithDataElm?.remove?.();
- this._inputElm?.remove?.();
+ this._editorInputGroupElm?.remove();
+ this._inputElm?.remove();
+ }
+
+ clear() {
+ this._lastTriggeredByClearDate = true;
+ if (this.calendarInstance) {
+ this.calendarInstance.settings.selected.dates = [];
+ this._inputElm.value = '';
+ }
}
disable(isDisabled = true) {
const prevIsDisabled = this.disabled;
this.disabled = isDisabled;
- if (this.flatInstance?._input) {
+ if (this._inputElm) {
if (isDisabled) {
- this.flatInstance._input.setAttribute('disabled', 'disabled');
+ this._inputElm.setAttribute('disabled', 'disabled');
this._clearButtonElm.disabled = true;
// clear picker when it's newly disabled and not empty
@@ -218,7 +255,7 @@ export class DateEditor implements Editor {
this.reset('', true, true);
}
} else {
- this.flatInstance._input.removeAttribute('disabled');
+ this._inputElm.removeAttribute('disabled');
this._clearButtonElm.disabled = false;
}
}
@@ -227,16 +264,15 @@ export class DateEditor implements Editor {
/**
* Dynamically change an Editor option, this is especially useful with Composite Editor
* since this is the only way to change option after the Editor is created (for example dynamically change "minDate" or another Editor)
- * @param {string} optionName - Flatpickr option name
- * @param {newValue} newValue - Flatpickr new option value
+ * @param {string} optionName
+ * @param {newValue} newValue
*/
- changeEditorOption(optionName: keyof FlatpickrBaseOptions, newValue: any) {
+ changeEditorOption>(optionName: T, newValue: K) {
if (!this.columnEditor.editorOptions) {
this.columnEditor.editorOptions = {};
}
this.columnEditor.editorOptions[optionName] = newValue;
- this._pickerMergedOptions = { ...this._pickerMergedOptions, [optionName]: newValue };
- this.flatInstance.set(optionName, newValue);
+ this._pickerMergedOptions = extend(true, {}, this._pickerMergedOptions, { settings: { [optionName]: newValue } });
}
focus() {
@@ -245,22 +281,16 @@ export class DateEditor implements Editor {
this.show();
this._inputElm?.focus();
- if (this._inputWithDataElm?.focus) {
- this._inputWithDataElm.focus();
- this._inputWithDataElm.select();
- }
}
hide() {
- if (this.flatInstance && typeof this.flatInstance.close === 'function') {
- this.flatInstance.close();
- }
+ this.calendarInstance?.hide();
}
show() {
const isCompositeEditor = !!this.args?.compositeEditorOptions;
- if (!isCompositeEditor && this.flatInstance && typeof this.flatInstance.open === 'function' && this.flatInstance._input) {
- this.flatInstance.open();
+ if (!isCompositeEditor && this.calendarInstance) {
+ this.calendarInstance.show();
} else if (isCompositeEditor) {
// when it's a Composite Editor, we'll check if the Editor is editable (by checking onBeforeEditCell) and if not Editable we'll disable the Editor
this.applyInputUsabilityState();
@@ -272,7 +302,9 @@ export class DateEditor implements Editor {
}
setValue(val: string, isApplyingValue = false, triggerOnCompositeEditorChange = true) {
- this.flatInstance.setDate(val);
+ if (this.calendarInstance) {
+ setPickerDates(this._inputElm, this.calendarInstance, val, this.columnDef, this.columnEditor);
+ }
if (isApplyingValue) {
this.applyValue(this.args.item, this.serializeValue());
@@ -286,21 +318,21 @@ export class DateEditor implements Editor {
}
applyValue(item: any, state: any) {
- const fieldName = this.columnDef && this.columnDef.field;
- if (fieldName !== undefined) {
- const outputTypeFormat = mapMomentDateFormatWithFieldType((this.columnDef && (this.columnDef.outputType || this.columnEditor.type || this.columnDef.type)) || FieldType.dateUtc);
- const saveTypeFormat = mapMomentDateFormatWithFieldType((this.columnDef && (this.columnDef.saveOutputType || this.columnDef.outputType || this.columnEditor.type || this.columnDef.type)) || FieldType.dateUtc);
- const isComplexObject = fieldName?.indexOf('.') > 0; // is the field a complex object, "address.streetNumber"
+ const fieldName = this.columnDef?.field;
+ if (this.columnDef && fieldName !== undefined) {
+ const saveFieldType = this.columnDef.saveOutputType || this.columnDef.outputType || this.columnEditor.type || this.columnDef.type || FieldType.dateUtc;
+ const outputFieldType = this.columnDef.outputType || this.columnEditor.type || this.columnDef.type || FieldType.dateUtc;
+ const isComplexObject = fieldName.indexOf('.') > 0; // is the field a complex object, "address.streetNumber"
// validate the value before applying it (if not valid we'll set an empty string)
const validation = this.validate(null, state);
- const newValue = (state && validation && validation.valid) ? moment(state, outputTypeFormat).format(saveTypeFormat) : '';
+ const newValue = (state && validation?.valid) ? formatDateByFieldType(state, outputFieldType, saveFieldType) : '';
// set the new value to the item datacontext
if (isComplexObject) {
// when it's a complex object, user could override the object path (where the editable object is located)
// else we use the path provided in the Field Column Definition
- const objectPath = this.columnEditor?.complexObjectPath ?? fieldName ?? '';
+ const objectPath = this.columnEditor?.complexObjectPath ?? fieldName;
setDeepValue(item, objectPath, newValue);
} else {
item[fieldName] = newValue;
@@ -309,15 +341,12 @@ export class DateEditor implements Editor {
}
isValueChanged(): boolean {
- const elmValue = this._inputElm.value;
- const inputFormat = mapMomentDateFormatWithFieldType(this.columnEditor.type || this.columnDef?.type || FieldType.dateIso);
- const outputTypeFormat = mapMomentDateFormatWithFieldType((this.columnDef && (this.columnDef.outputType || this.columnEditor.type || this.columnDef.type)) || FieldType.dateUtc);
- const elmDateStr = elmValue ? moment(elmValue, inputFormat, false).format(outputTypeFormat) : '';
- const orgDateStr = this._originalDate ? moment(this._originalDate, inputFormat, false).format(outputTypeFormat) : '';
- if (elmDateStr === 'Invalid date' || orgDateStr === 'Invalid date') {
- return false;
+ let isChanged = false;
+ const elmDateStr = this.getValue();
+
+ if (this.columnDef) {
+ isChanged = this._lastTriggeredByClearDate || (!(elmDateStr === '' && this._originalDate === '')) && (elmDateStr !== this._originalDate);
}
- const isChanged = this._lastTriggeredByClearDate || (!(elmDateStr === '' && orgDateStr === '')) && (elmDateStr !== orgDateStr);
return isChanged;
}
@@ -327,15 +356,17 @@ export class DateEditor implements Editor {
}
loadValue(item: any) {
- const fieldName = this.columnDef && this.columnDef.field;
+ const fieldName = this.columnDef?.field;
- if (item && fieldName !== undefined) {
+ if (item && this.columnDef && fieldName !== undefined) {
// is the field a complex object, "address.streetNumber"
const isComplexObject = fieldName?.indexOf('.') > 0;
- const value = (isComplexObject) ? getDescendantProperty(item, fieldName) : item[fieldName];
+ const value = isComplexObject ? getDescendantProperty(item, fieldName) : item[fieldName];
+ const inputFieldType = this.columnEditor.type || this.columnDef?.type || FieldType.dateIso;
+ const outputFieldType = this.columnDef.outputType || this.columnEditor.type || this.columnDef.type || FieldType.dateIso;
- this._originalDate = value;
- this.flatInstance.setDate(value);
+ this._originalDate = formatDateByFieldType(value, inputFieldType, outputFieldType);
+ this._inputElm.value = this._originalDate;
}
}
@@ -345,11 +376,12 @@ export class DateEditor implements Editor {
*/
reset(value?: string, triggerCompositeEventWhenExist = true, clearByDisableCommand = false) {
const inputValue = value ?? this._originalDate ?? '';
- if (this.flatInstance) {
+ if (this.calendarInstance) {
this._originalDate = inputValue;
- this.flatInstance.setDate(inputValue);
+ this.calendarInstance.settings.selected.dates = [inputValue];
if (!inputValue) {
- this.flatInstance.clear();
+ this.calendarInstance.settings.selected.dates = [];
+ this._inputElm.value = '';
}
}
this._isValueTouched = false;
@@ -363,7 +395,7 @@ export class DateEditor implements Editor {
save() {
const validation = this.validate();
- const isValid = (validation && validation.valid) || false;
+ const isValid = validation?.valid ?? false;
if (this.hasAutoCommitEdit && isValid) {
// do not use args.commitChanges() as this sets the focus to the next row.
@@ -375,22 +407,17 @@ export class DateEditor implements Editor {
}
serializeValue() {
- const domValue: string = this._inputElm.value;
-
+ const domValue = this.getValue();
if (!domValue) {
return '';
}
- const inputFormat = mapMomentDateFormatWithFieldType(this.columnEditor.type || this.columnDef?.type || FieldType.dateIso);
- const outputTypeFormat = mapMomentDateFormatWithFieldType((this.columnDef && (this.columnDef.outputType || this.columnEditor.type || this.columnDef.type)) || FieldType.dateIso);
- const value = moment(domValue, inputFormat, false).format(outputTypeFormat);
-
- return value;
+ return domValue;
}
validate(_targetElm?: any, inputValue?: any): EditorValidationResult {
const isRequired = this.args?.compositeEditorOptions ? false : this.columnEditor.required;
- const elmValue = (inputValue !== undefined) ? inputValue : this._inputElm?.value;
+ const elmValue = inputValue ?? this._inputElm?.value;
const errorMsg = this.columnEditor.errorMessage;
// when using Composite Editor, we also want to recheck if the field if disabled/enabled since it might change depending on other inputs on the composite form
@@ -430,9 +457,8 @@ export class DateEditor implements Editor {
protected handleOnDateChange() {
this._isValueTouched = true;
- const currentFlatpickrOptions = this.flatInstance?.config ?? this._pickerMergedOptions;
- if (this.args && currentFlatpickrOptions?.closeOnSelect) {
+ if (this.args) {
const compositeEditorOptions = this.args.compositeEditorOptions;
if (compositeEditorOptions) {
this.handleChangeOnCompositeEditor(compositeEditorOptions);
diff --git a/packages/common/src/editors/editors.index.ts b/packages/common/src/editors/editors.index.ts
index 1e4cee0be..3ea7648f3 100644
--- a/packages/common/src/editors/editors.index.ts
+++ b/packages/common/src/editors/editors.index.ts
@@ -18,7 +18,7 @@ export const Editors = {
/** Checkbox Editor (uses native checkbox DOM element) */
checkbox: CheckboxEditor,
- /** Date Picker Editor (which uses 3rd party lib "flatpickr") */
+ /** Date Picker Editor (which uses 3rd party lib "vanilla-calendar-picker") */
date: DateEditor,
/** Dual Input Editor, default input type is text but it could be (integer/float/number/password/text) */
diff --git a/packages/common/src/editors/floatEditor.ts b/packages/common/src/editors/floatEditor.ts
index 8dde76ff7..55665b7aa 100644
--- a/packages/common/src/editors/floatEditor.ts
+++ b/packages/common/src/editors/floatEditor.ts
@@ -1,83 +1,13 @@
-import { createDomElement, toSentenceCase } from '@slickgrid-universal/utils';
-
import type { EditorArguments, EditorValidationResult } from '../interfaces/index';
import { floatValidator } from '../editorValidators/floatValidator';
import { InputEditor } from './inputEditor';
import { getDescendantProperty } from '../services/utilities';
-const DEFAULT_DECIMAL_PLACES = 0;
-
export class FloatEditor extends InputEditor {
constructor(protected readonly args: EditorArguments) {
super(args, 'number');
}
- /** Initialize the Editor */
- init() {
- if (this.columnDef && this.columnEditor && this.args) {
- const columnId = this.columnDef?.id ?? '';
- const compositeEditorOptions = this.args.compositeEditorOptions;
-
- this._input = createDomElement('input', {
- type: 'number', autocomplete: 'off', ariaAutoComplete: 'none',
- ariaLabel: this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Number Editor`,
- className: `editor-text editor-${columnId}`,
- placeholder: this.columnEditor?.placeholder ?? '',
- title: this.columnEditor?.title ?? '',
- step: `${(this.columnEditor.valueStep !== undefined) ? this.columnEditor.valueStep : this.getInputDecimalSteps()}`,
- });
- const cellContainer = this.args.container;
- if (cellContainer && typeof cellContainer.appendChild === 'function') {
- cellContainer.appendChild(this._input);
- }
-
- this._bindEventService.bind(this._input, 'focus', () => this._input?.select());
- this._bindEventService.bind(this._input, 'keydown', ((event: KeyboardEvent) => {
- this._lastInputKeyEvent = event;
- if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
- event.stopImmediatePropagation();
- }
- }) as EventListener);
-
- // the lib does not get the focus out event for some reason
- // so register it here
- if (this.hasAutoCommitEdit && !compositeEditorOptions) {
- this._bindEventService.bind(this._input, 'focusout', () => {
- this._isValueTouched = true;
- this.save();
- });
- }
-
- if (compositeEditorOptions) {
- this._bindEventService.bind(this._input, ['input', 'paste'], this.handleOnInputChange.bind(this) as EventListener);
- this._bindEventService.bind(this._input, 'wheel', this.handleOnMouseWheel.bind(this) as EventListener, { passive: true });
- }
- }
- }
-
- getDecimalPlaces(): number {
- // returns the number of fixed decimal places or null
- let rtn = this.columnEditor?.decimal ?? this.columnEditor?.params?.decimalPlaces ?? undefined;
-
- if (rtn === undefined) {
- rtn = DEFAULT_DECIMAL_PLACES;
- }
- return (!rtn && rtn !== 0 ? null : rtn);
- }
-
- getInputDecimalSteps(): string {
- const decimals = this.getDecimalPlaces();
- let zeroString = '';
- for (let i = 1; i < decimals; i++) {
- zeroString += '0';
- }
-
- if (decimals > 0) {
- return `0.${zeroString}1`;
- }
- return '1';
- }
-
loadValue(item: any) {
const fieldName = this.columnDef && this.columnDef.field;
@@ -137,17 +67,4 @@ export class FloatEditor extends InputEditor {
validator: this.validator,
});
}
-
- // --
- // protected functions
- // ------------------
-
- /** When the input value changes (this will cover the input spinner arrows on the right) */
- protected handleOnMouseWheel(event: KeyboardEvent) {
- this._isValueTouched = true;
- const compositeEditorOptions = this.args.compositeEditorOptions;
- if (compositeEditorOptions) {
- this.handleChangeOnCompositeEditor(event, compositeEditorOptions);
- }
- }
}
\ No newline at end of file
diff --git a/packages/common/src/editors/inputEditor.ts b/packages/common/src/editors/inputEditor.ts
index dec519f7d..55c42969d 100644
--- a/packages/common/src/editors/inputEditor.ts
+++ b/packages/common/src/editors/inputEditor.ts
@@ -15,6 +15,8 @@ import { getDescendantProperty } from '../services/utilities';
import { textValidator } from '../editorValidators/textValidator';
import { SlickEventData, type SlickGrid } from '../core/index';
+const DEFAULT_DECIMAL_PLACES = 0;
+
/*
* An example of a 'detached' editor.
* KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.
@@ -92,13 +94,18 @@ export class InputEditor implements Editor {
const compositeEditorOptions = this.args.compositeEditorOptions;
this._input = createDomElement('input', {
- type: this._inputType || 'text',
- autocomplete: 'off', ariaAutoComplete: 'none',
+ type: this._inputType || 'text', autocomplete: 'off', ariaAutoComplete: 'none',
ariaLabel: this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Input Editor`,
+ className: `editor-text editor-${columnId}`,
placeholder: this.columnEditor?.placeholder ?? '',
title: this.columnEditor?.title ?? '',
- className: `editor-text editor-${columnId}`,
});
+
+ // add "step" attribute when editor type is integer/float
+ if (this.inputType === 'number') {
+ this._input.step = `${(this.columnEditor.valueStep !== undefined) ? this.columnEditor.valueStep : this.getInputDecimalSteps()}`;
+ }
+
const cellContainer = this.args.container;
if (cellContainer && typeof cellContainer.appendChild === 'function') {
cellContainer.appendChild(this._input);
@@ -113,10 +120,9 @@ export class InputEditor implements Editor {
}
}) as EventListener);
- // the lib does not get the focus out event for some reason
- // so register it here
+ // listen to focusout or blur to automatically call a save
if (this.hasAutoCommitEdit && !compositeEditorOptions) {
- this._bindEventService.bind(this._input, 'focusout', () => {
+ this._bindEventService.bind(this._input, ['focusout', 'blur'], () => {
this._isValueTouched = true;
this.save();
});
@@ -124,6 +130,11 @@ export class InputEditor implements Editor {
if (compositeEditorOptions) {
this._bindEventService.bind(this._input, ['input', 'paste'], this.handleOnInputChange.bind(this) as EventListener);
+
+ // add an extra mousewheel listener when editor type is integer/float
+ if (this.inputType === 'number') {
+ this._bindEventService.bind(this._input, 'wheel', this.handleOnMouseWheel.bind(this) as EventListener, { passive: true });
+ }
}
}
@@ -157,6 +168,30 @@ export class InputEditor implements Editor {
this._input?.focus();
}
+ getDecimalPlaces(): number {
+ // returns the number of fixed decimal places or null
+ let rtn = this.columnEditor?.decimal ?? this.columnEditor?.params?.decimalPlaces ?? undefined;
+
+ if (rtn === undefined) {
+ rtn = DEFAULT_DECIMAL_PLACES;
+ }
+ return (!rtn && rtn !== 0 ? null : rtn);
+ }
+
+ /** when editor is a float input editor, we'll want to know how many decimals to show */
+ getInputDecimalSteps(): string {
+ const decimals = this.getDecimalPlaces();
+ let zeroString = '';
+ for (let i = 1; i < decimals; i++) {
+ zeroString += '0';
+ }
+
+ if (decimals > 0) {
+ return `0.${zeroString}1`;
+ }
+ return '1';
+ }
+
show() {
const isCompositeEditor = !!this.args?.compositeEditorOptions;
if (isCompositeEditor) {
@@ -338,4 +373,13 @@ export class InputEditor implements Editor {
this._timer = setTimeout(() => this.handleChangeOnCompositeEditor(event, compositeEditorOptions), typingDelay);
}
}
+
+ /** When the input value changes (this will cover the input spinner arrows on the right) */
+ protected handleOnMouseWheel(event: KeyboardEvent) {
+ this._isValueTouched = true;
+ const compositeEditorOptions = this.args.compositeEditorOptions;
+ if (compositeEditorOptions) {
+ this.handleChangeOnCompositeEditor(event, compositeEditorOptions);
+ }
+ }
}
diff --git a/packages/common/src/editors/integerEditor.ts b/packages/common/src/editors/integerEditor.ts
index 1ae1ccdec..d6752d60c 100644
--- a/packages/common/src/editors/integerEditor.ts
+++ b/packages/common/src/editors/integerEditor.ts
@@ -1,5 +1,3 @@
-import { createDomElement, toSentenceCase } from '@slickgrid-universal/utils';
-
import type { EditorArguments, EditorValidationResult } from '../interfaces/index';
import { integerValidator } from '../editorValidators/integerValidator';
import { InputEditor } from './inputEditor';
@@ -10,49 +8,6 @@ export class IntegerEditor extends InputEditor {
super(args, 'number');
}
- /** Initialize the Editor */
- init() {
- if (this.columnDef && this.columnEditor && this.args) {
- const columnId = this.columnDef?.id ?? '';
- const compositeEditorOptions = this.args.compositeEditorOptions;
-
- this._input = createDomElement('input', {
- type: 'number', autocomplete: 'off', ariaAutoComplete: 'none',
- ariaLabel: this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Slider Editor`,
- placeholder: this.columnEditor?.placeholder ?? '',
- title: this.columnEditor?.title ?? '',
- step: `${(this.columnEditor.valueStep !== undefined) ? this.columnEditor.valueStep : '1'}`,
- className: `editor-text editor-${columnId}`,
- });
- const cellContainer = this.args.container;
- if (cellContainer && typeof cellContainer.appendChild === 'function') {
- cellContainer.appendChild(this._input);
- }
-
- this._bindEventService.bind(this._input, 'focus', () => this._input?.select());
- this._bindEventService.bind(this._input, 'keydown', ((event: KeyboardEvent) => {
- this._lastInputKeyEvent = event;
- if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
- event.stopImmediatePropagation();
- }
- }) as EventListener);
-
- // the lib does not get the focus out event for some reason
- // so register it here
- if (this.hasAutoCommitEdit && !compositeEditorOptions) {
- this._bindEventService.bind(this._input, 'focusout', () => {
- this._isValueTouched = true;
- this.save();
- });
- }
-
- if (compositeEditorOptions) {
- this._bindEventService.bind(this._input, ['input', 'paste'], this.handleOnInputChange.bind(this) as EventListener);
- this._bindEventService.bind(this._input, 'wheel', this.handleOnMouseWheel.bind(this) as EventListener, { passive: true });
- }
- }
- }
-
loadValue(item: any) {
const fieldName = this.columnDef && this.columnDef.field;
diff --git a/packages/common/src/editors/longTextEditor.ts b/packages/common/src/editors/longTextEditor.ts
index 5ceaeb00e..2ca203515 100644
--- a/packages/common/src/editors/longTextEditor.ts
+++ b/packages/common/src/editors/longTextEditor.ts
@@ -52,14 +52,14 @@ export class LongTextEditor implements Editor {
throw new Error('[Slickgrid-Universal] Something is wrong with this grid, an Editor must always have valid arguments.');
}
this.grid = args.grid;
- this.gridOptions = args.grid && args.grid.getOptions() as GridOption;
+ this.gridOptions = args.grid?.getOptions() as GridOption;
const options = this.gridOptions || this.args.column.params || {};
if (options?.translater) {
this._translater = options.translater;
}
// get locales provided by user in forRoot or else use default English locales via the Constants
- this._locales = this.gridOptions && this.gridOptions.locales || Constants.locales;
+ this._locales = this.gridOptions?.locales || Constants.locales;
this._bindEventService = new BindingEventService();
this.init();
@@ -258,7 +258,7 @@ export class LongTextEditor implements Editor {
// validate the value before applying it (if not valid we'll set an empty string)
const validation = this.validate(undefined, state);
- const newValue = (validation && validation.valid) ? state : '';
+ const newValue = validation?.valid ? state : '';
// set the new value to the item datacontext
if (isComplexObject) {
@@ -409,24 +409,24 @@ export class LongTextEditor implements Editor {
this.disable(isCellEditable === false);
}
- protected handleKeyDown(event: KeyboardEvent) {
- const key = event.key;
+ protected handleKeyDown(e: KeyboardEvent) {
+ const key = e.key;
this._isValueTouched = true;
if (!this.args.compositeEditorOptions) {
- if ((key === 'Enter' && event.ctrlKey) || (event.ctrlKey && event.key.toUpperCase() === 'S')) {
- event.preventDefault();
+ if ((key === 'Enter' && e.ctrlKey) || (e.ctrlKey && e.key.toUpperCase() === 'S')) {
+ e.preventDefault();
this.save();
} else if (key === 'Escape') {
- event.preventDefault();
+ e.preventDefault();
this.cancel();
- } else if (key === 'Tab' && event.shiftKey) {
- event.preventDefault();
+ } else if (key === 'Tab' && e.shiftKey) {
+ e.preventDefault();
if (this.args && this.grid) {
this.grid.navigatePrev();
}
} else if (key === 'Tab') {
- event.preventDefault();
+ e.preventDefault();
if (this.args && this.grid) {
this.grid.navigateNext();
}
diff --git a/packages/common/src/editors/selectEditor.ts b/packages/common/src/editors/selectEditor.ts
index 621adf1f5..76b960349 100644
--- a/packages/common/src/editors/selectEditor.ts
+++ b/packages/common/src/editors/selectEditor.ts
@@ -19,7 +19,7 @@ import type {
Locale,
SelectOption,
} from './../interfaces/index';
-import { buildMsSelectCollectionList, CollectionService, findOrDefault, sanitizeTextByAvailableSanitizer, type TranslaterService } from '../services/index';
+import { buildMsSelectCollectionList, CollectionService, findOrDefault, type TranslaterService } from '../services/index';
import { getDescendantProperty, getTranslationPrefix, } from '../services/utilities';
import { SlickEventData, type SlickGrid } from '../core/index';
@@ -120,11 +120,18 @@ export class SelectEditor implements Editor {
single: true,
singleRadio: true,
renderOptionLabelAsHtml: this.columnEditor?.enableRenderHtml ?? false,
- sanitizer: (dirtyHtml: string) => sanitizeTextByAvailableSanitizer(this.gridOptions, dirtyHtml),
+ sanitizer: (dirtyHtml: string) => this.grid.sanitizeHtmlString(dirtyHtml),
onClick: () => this._isValueTouched = true,
onCheckAll: () => this._isValueTouched = true,
onUncheckAll: () => this._isValueTouched = true,
- onClose: () => {
+ onClose: (reason) => {
+ if (reason === 'key.escape' || reason === 'body.click' || (!this.hasAutoCommitEdit && !this.isValueChanged())) {
+ if (reason === 'key.escape') {
+ this.cancel();
+ }
+ return;
+ }
+
if (compositeEditorOptions) {
this.handleChangeOnCompositeEditor(compositeEditorOptions);
} else {
@@ -364,6 +371,12 @@ export class SelectEditor implements Editor {
}
}
+ cancel() {
+ if (this.args?.cancelChanges) {
+ this.args.cancelChanges();
+ }
+ }
+
hide() {
if (this._msInstance) {
this._msInstance.close();
@@ -754,7 +767,7 @@ export class SelectEditor implements Editor {
this._msInstance = multipleSelect(selectElement, this.editorElmOptions) as MultipleSelectInstance;
this.editorElm = this._msInstance.getParentElement();
if (!this.isCompositeEditor) {
- this.delayOpening >= 0 ? setTimeout(() => this.show()) : this.show();
+ this.show(this.delayOpening);
}
}
diff --git a/packages/common/src/extensions/__tests__/slickCellExcelCopyManager.spec.ts b/packages/common/src/extensions/__tests__/slickCellExcelCopyManager.spec.ts
index 283a25993..c05ab7c26 100644
--- a/packages/common/src/extensions/__tests__/slickCellExcelCopyManager.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickCellExcelCopyManager.spec.ts
@@ -6,8 +6,6 @@ import { SlickCellExternalCopyManager } from '../slickCellExternalCopyManager';
import { SlickEvent, SlickEventData, SlickGrid, SlickRange } from '../../core/index';
import { Editors } from '../../editors';
-jest.mock('flatpickr', () => { });
-
const getEditorLockMock = {
isActive: jest.fn(),
commitCurrentEdit: jest.fn(),
@@ -364,7 +362,7 @@ describe('CellExcelCopyManager', () => {
(gridStub.getCellEditor as jest.Mock).mockReturnValue({});
(gridStub.getActiveCell as jest.Mock).mockReturnValue({ row: 6, cell: 6 });
- const output = plugin.addonOptions!.dataItemColumnValueExtractor!({ firstName: 'John', lastName: 'Doe' }, { id: 'firstName', field: 'firstName', exportWithFormatter: true, editor: { model: Editors.text }, formatter: myBoldFormatter}, 6, 6);
+ const output = plugin.addonOptions!.dataItemColumnValueExtractor!({ firstName: 'John', lastName: 'Doe' }, { id: 'firstName', field: 'firstName', exportWithFormatter: true, editor: { model: Editors.text }, formatter: myBoldFormatter }, 6, 6);
expect(output).toBeNull();
});
diff --git a/packages/common/src/extensions/__tests__/slickCellExternalCopyManager.spec.ts b/packages/common/src/extensions/__tests__/slickCellExternalCopyManager.spec.ts
index 5a990b7d3..26ef2e661 100644
--- a/packages/common/src/extensions/__tests__/slickCellExternalCopyManager.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickCellExternalCopyManager.spec.ts
@@ -8,8 +8,6 @@ import { InputEditor } from '../../editors/inputEditor';
import { SlickEvent, SlickEventData, SlickGrid, SlickRange } from '../../core/index';
import { BasePubSubService } from '@slickgrid-universal/event-pub-sub';
-jest.mock('flatpickr', () => { });
-
const pubSubServiceStub = {
publish: jest.fn(),
subscribe: jest.fn(),
diff --git a/packages/common/src/extensions/__tests__/slickCellMenu.plugin.spec.ts b/packages/common/src/extensions/__tests__/slickCellMenu.plugin.spec.ts
index 2e2a90d58..26013358c 100644
--- a/packages/common/src/extensions/__tests__/slickCellMenu.plugin.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickCellMenu.plugin.spec.ts
@@ -96,7 +96,7 @@ const commandItemsMock = [
{ command: 'command3', title: 'Command 3', positionOrder: 70, },
{ command: 'command4', title: 'Command 4', positionOrder: 71, },
{
- command: 'more-sub-commands', title: 'More Sub Commands', subMenuTitle: 'Sub Command Title 2', subMenuTitleCssClass: 'color-warning', commandItems: [
+ command: 'more-sub-commands', title: 'More Sub Commands', subMenuTitle: 'Sub Command Title 2', subMenuTitleCssClass: 'text-color-warning', commandItems: [
{ command: 'command5', title: 'Command 5', positionOrder: 72, },
]
}
@@ -655,7 +655,7 @@ describe('CellMenu Plugin', () => {
expect(commandList2Elm.querySelectorAll('.slick-menu-item').length).toBe(3);
expect(commandContentElm2.textContent).toBe('Sub Commands');
expect(subMenuTitleElm.textContent).toBe('Sub Command Title 2');
- expect(subMenuTitleElm.className).toBe('slick-menu-title color-warning');
+ expect(subMenuTitleElm.className).toBe('slick-menu-title text-color-warning');
expect(commandChevronElm.className).toBe('sub-item-chevron mdi mdi-chevron-right');
expect(subCommand3Elm.textContent).toContain('Command 3');
expect(subCommand5Elm.textContent).toContain('Command 5');
@@ -706,7 +706,7 @@ describe('CellMenu Plugin', () => {
expect(commandList2Elm.querySelectorAll('.slick-menu-item').length).toBe(3);
expect(commandContentElm2.textContent).toBe('Sub Commands');
expect(subMenuTitleElm.textContent).toBe('Sub Command Title 2');
- expect(subMenuTitleElm.className).toBe('slick-menu-title color-warning');
+ expect(subMenuTitleElm.className).toBe('slick-menu-title text-color-warning');
expect(commandChevronElm.className).toBe('sub-item-chevron mdi mdi-chevron-right');
expect(subCommand3Elm.textContent).toContain('Command 3');
expect(subCommand5Elm.textContent).toContain('Command 5');
diff --git a/packages/common/src/extensions/__tests__/slickCellRangeDecorator.spec.ts b/packages/common/src/extensions/__tests__/slickCellRangeDecorator.spec.ts
index f9b47724a..834184574 100644
--- a/packages/common/src/extensions/__tests__/slickCellRangeDecorator.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickCellRangeDecorator.spec.ts
@@ -4,8 +4,6 @@ import type { GridOption } from '../../interfaces/index';
import { SlickCellRangeDecorator } from '../slickCellRangeDecorator';
import { SlickGrid } from '../../core';
-jest.mock('flatpickr', () => { });
-
const gridStub = {
getActiveCell: jest.fn(),
getActiveCanvasNode: jest.fn(),
diff --git a/packages/common/src/extensions/__tests__/slickCellRangeSelector.spec.ts b/packages/common/src/extensions/__tests__/slickCellRangeSelector.spec.ts
index 33e2ed70b..01d36033d 100644
--- a/packages/common/src/extensions/__tests__/slickCellRangeSelector.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickCellRangeSelector.spec.ts
@@ -6,7 +6,6 @@ import { SlickEvent, SlickGrid } from '../../core/index';
import { BasePubSubService } from '@slickgrid-universal/event-pub-sub';
const GRID_UID = 'slickgrid_12345';
-jest.mock('flatpickr', () => { });
const addVanillaEventPropagation = function (event) {
Object.defineProperty(event, 'isPropagationStopped', { writable: true, configurable: true, value: jest.fn() });
diff --git a/packages/common/src/extensions/__tests__/slickCellSelectionModel.spec.ts b/packages/common/src/extensions/__tests__/slickCellSelectionModel.spec.ts
index 5a1a2c733..5785a92de 100644
--- a/packages/common/src/extensions/__tests__/slickCellSelectionModel.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickCellSelectionModel.spec.ts
@@ -9,7 +9,6 @@ import { BasePubSubService } from '@slickgrid-universal/event-pub-sub';
const GRID_UID = 'slickgrid_12345';
const NB_ITEMS = 200;
const CALCULATED_PAGE_ROW_COUNT = 23; // pageRowCount with our mocked sizes is 23 => ((600 - 17) / 25)
-jest.mock('flatpickr', () => { });
const addVanillaEventPropagation = function (event, commandKeys: string[] = [], keyName = '') {
Object.defineProperty(event, 'isPropagationStopped', { writable: true, configurable: true, value: jest.fn() });
diff --git a/packages/common/src/extensions/__tests__/slickCheckboxSelectColumn.spec.ts b/packages/common/src/extensions/__tests__/slickCheckboxSelectColumn.spec.ts
index 6cf0e7e54..df2d02b38 100644
--- a/packages/common/src/extensions/__tests__/slickCheckboxSelectColumn.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickCheckboxSelectColumn.spec.ts
@@ -295,13 +295,13 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
plugin.init(gridStub);
gridStub.onHeaderRowCellRendered.notify({ column: { id: '_checkbox_selector', field: '_checkbox_selector' }, node: nodeElm, grid: gridStub });
plugin.setOptions({ hideInColumnTitleRow: true, hideInFilterHeaderRow: false, hideSelectAllCheckbox: false, });
- let filterSelectAll = plugin.headerRowNode!.querySelector(`#filter-checkbox-selectall-container`) as HTMLSpanElement;
+ let filterSelectAll = plugin.headerRowNode!.querySelector('#filter-checkbox-selectall-container') as HTMLSpanElement;
expect(plugin).toBeTruthy();
expect(updateColHeaderSpy).toHaveBeenCalledWith('_checkbox_selector', '', '');
expect(filterSelectAll.style.display).toEqual('flex');
- filterSelectAll = plugin.headerRowNode!.querySelector(`#filter-checkbox-selectall-container`) as HTMLSpanElement;
+ filterSelectAll = plugin.headerRowNode!.querySelector('#filter-checkbox-selectall-container') as HTMLSpanElement;
plugin.hideSelectAllFromColumnHeaderFilterRow();
expect(filterSelectAll.style.display).toEqual('none');
});
@@ -424,10 +424,11 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
resizable: false,
sortable: false,
width: 30,
+ maxWidth: 30,
name: expect.any(DocumentFragment),
formatter: expect.toBeFunction(),
});
- expect(nameHtmlOutput).toBe(``);
+ expect(nameHtmlOutput).toBe(``);
});
it('should create the plugin and add the Toggle All checkbox in the filter header row and expect toggle all to work when clicked', () => {
@@ -439,7 +440,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
plugin.init(gridStub);
gridStub.onHeaderRowCellRendered.notify({ column: { id: '_checkbox_selector', field: '_checkbox_selector' }, node: nodeElm, grid: gridStub });
- const checkboxContainerElm = nodeElm.querySelector('span#filter-checkbox-selectall-container') as HTMLDivElement;
+ const checkboxContainerElm = nodeElm.querySelector('div.icon-checkbox-container') as HTMLDivElement;
const inputCheckboxElm = checkboxContainerElm.querySelector('input[type=checkbox]') as HTMLDivElement;
inputCheckboxElm.dispatchEvent(new Event('click', { bubbles: true, cancelable: true }));
@@ -464,6 +465,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
sortable: false,
toolTip: 'Select/Deselect All',
width: 30,
+ maxWidth: 30,
};
plugin.create(mockColumns, { checkboxSelector: { columnId: 'chk-id' } });
@@ -475,7 +477,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
});
expect(plugin).toBeTruthy();
expect(mockColumns[0]).toEqual(expect.objectContaining({ ...checkboxColumnMock, formatter: expect.toBeFunction() }));
- expect(nameHtmlOutput).toBe(``);
+ expect(nameHtmlOutput).toBe(``);
});
@@ -501,8 +503,9 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
sortable: false,
toolTip: 'Select/Deselect All',
width: 30,
+ maxWidth: 30,
});
- expect(nameHtmlOutput).toBe(``);
+ expect(nameHtmlOutput).toBe(``);
});
it('should add a "name" and "hideSelectAllCheckbox: true" and call the "create" method and expect plugin to be created with a column name and without a checkbox', () => {
@@ -527,6 +530,7 @@ describe('SlickCheckboxSelectColumn Plugin', () => {
sortable: false,
toolTip: '',
width: 30,
+ maxWidth: 30,
});
});
diff --git a/packages/common/src/extensions/__tests__/slickColumnPicker.spec.ts b/packages/common/src/extensions/__tests__/slickColumnPicker.spec.ts
index bdfe27f55..651270920 100644
--- a/packages/common/src/extensions/__tests__/slickColumnPicker.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickColumnPicker.spec.ts
@@ -21,6 +21,7 @@ const gridStub = {
setColumns: jest.fn(),
setOptions: jest.fn(),
setSelectedRows: jest.fn(),
+ onClick: new SlickEvent(),
onColumnsReordered: new SlickEvent(),
onHeaderContextMenu: new SlickEvent(),
} as unknown as SlickGrid;
@@ -147,10 +148,15 @@ describe('ColumnPickerControl', () => {
gridStub.onHeaderContextMenu.notify({ column: columnsMock[1], grid: gridStub }, eventData as any, gridStub);
control.menuElement!.querySelector('input[type="checkbox"]')!.dispatchEvent(new Event('click', { bubbles: true }));
- expect(handlerSpy).toHaveBeenCalledTimes(2);
+ expect(handlerSpy).toHaveBeenCalledTimes(3);
expect(readjustSpy).toHaveBeenCalledWith(0, columnsMock, columnsMock);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
+
+ // cell click should close it
+ gridStub.onClick.notify({ row: 1, cell: 2, grid: gridStub }, eventData as any, gridStub);
+
+ expect(control.menuElement).toBeFalsy();
});
it('should query an input checkbox change event and expect "headerColumnValueExtractor" method to be called when defined', () => {
@@ -166,11 +172,11 @@ describe('ColumnPickerControl', () => {
control.menuElement!.querySelector('input[type="checkbox"]')!.dispatchEvent(new Event('click', { bubbles: true }));
const liElmList = control.menuElement!.querySelectorAll('li');
- expect(handlerSpy).toHaveBeenCalledTimes(2);
+ expect(handlerSpy).toHaveBeenCalledTimes(3);
expect(readjustSpy).toHaveBeenCalledWith(0, columnsMock, columnsMock);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
- expect(liElmList[2].textContent).toBe('Billing - Field 3')
+ expect(liElmList[2].textContent).toBe('Billing - Field 3');
});
it('should open the column picker via "onHeaderContextMenu" and expect "Forcefit" to be checked when "hideForceFitButton" is false', () => {
@@ -187,11 +193,11 @@ describe('ColumnPickerControl', () => {
const inputForcefitElm = control.menuElement!.querySelector('#slickgrid_124343-colpicker-forcefit') as HTMLInputElement;
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-colpicker-forcefit]') as HTMLDivElement;
- expect(handlerSpy).toHaveBeenCalledTimes(2);
+ expect(handlerSpy).toHaveBeenCalledTimes(3);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
expect(inputForcefitElm.checked).toBeTruthy();
- expect(inputForcefitElm.dataset.option).toBe('autoresize')
+ expect(inputForcefitElm.dataset.option).toBe('autoresize');
expect(labelSyncElm.textContent).toBe('Force fit columns');
});
@@ -209,7 +215,7 @@ describe('ColumnPickerControl', () => {
const inputSyncElm = control.menuElement!.querySelector('#slickgrid_124343-colpicker-syncresize') as HTMLInputElement;
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-colpicker-syncresize]') as HTMLDivElement;
- expect(handlerSpy).toHaveBeenCalledTimes(2);
+ expect(handlerSpy).toHaveBeenCalledTimes(3);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
expect(inputSyncElm.checked).toBeTruthy();
@@ -238,7 +244,7 @@ describe('ColumnPickerControl', () => {
visibleColumns: columnsMock,
grid: gridStub,
};
- expect(handlerSpy).toHaveBeenCalledTimes(2);
+ expect(handlerSpy).toHaveBeenCalledTimes(3);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
expect(onColChangedMock).toBeCalledWith(expect.anything(), expectedCallbackArgs);
@@ -262,7 +268,7 @@ describe('ColumnPickerControl', () => {
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-colpicker-forcefit]') as HTMLDivElement;
inputForcefitElm.dispatchEvent(new Event('click', { bubbles: true }));
- expect(handlerSpy).toHaveBeenCalledTimes(2);
+ expect(handlerSpy).toHaveBeenCalledTimes(3);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(inputForcefitElm.checked).toBeTruthy();
expect(inputForcefitElm.dataset.option).toBe('autoresize');
@@ -288,7 +294,7 @@ describe('ColumnPickerControl', () => {
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-colpicker-syncresize]') as HTMLDivElement;
inputSyncElm.dispatchEvent(new Event('click', { bubbles: true }));
- expect(handlerSpy).toHaveBeenCalledTimes(2);
+ expect(handlerSpy).toHaveBeenCalledTimes(3);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(inputSyncElm.checked).toBeTruthy();
expect(inputSyncElm.dataset.option).toBe('syncresize');
@@ -334,7 +340,7 @@ describe('ColumnPickerControl', () => {
control.menuElement!.querySelector('input[type="checkbox"]')!.dispatchEvent(new Event('click', { bubbles: true }));
const col4 = control.menuElement!.querySelector('li.hidden input[data-columnid=field4]');
- expect(handlerSpy).toHaveBeenCalledTimes(2);
+ expect(handlerSpy).toHaveBeenCalledTimes(3);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
expect(control.columns).toEqual(columnsMock);
@@ -362,7 +368,7 @@ describe('ColumnPickerControl', () => {
const labelForcefitElm = control.menuElement!.querySelector('label[for=slickgrid_124343-colpicker-forcefit]') as HTMLDivElement;
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-colpicker-syncresize]') as HTMLDivElement;
- expect(handlerSpy).toHaveBeenCalledTimes(2);
+ expect(handlerSpy).toHaveBeenCalledTimes(3);
expect(labelForcefitElm.textContent).toBe('Ajustement forcé des colonnes');
expect(labelSyncElm.textContent).toBe('Redimension synchrone');
expect(utilitySpy).toHaveBeenCalled();
diff --git a/packages/common/src/extensions/__tests__/slickContextMenu.spec.ts b/packages/common/src/extensions/__tests__/slickContextMenu.spec.ts
index d8b711a98..f594f0657 100644
--- a/packages/common/src/extensions/__tests__/slickContextMenu.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickContextMenu.spec.ts
@@ -1,12 +1,11 @@
import { BasePubSubService } from '@slickgrid-universal/event-pub-sub';
import { deepCopy } from '@slickgrid-universal/utils';
-import { type SlickDataView, SlickEvent, SlickEventData, SlickGrid } from '../../core/index';
+import { type SlickDataView, SlickEvent, SlickEventData, SlickGrid } from '../../core/index';
import { DelimiterType, FileType } from '../../enums/index';
import type { ContextMenu, Column, ElementPosition, GridOption, MenuCommandItem, MenuOptionItem, Formatter } from '../../interfaces/index';
import { BackendUtilityService, ExcelExportService, SharedService, TextExportService, TreeDataService, } from '../../services/index';
import { ExtensionUtility } from '../../extensions/extensionUtility';
-import { Formatters } from '../../formatters';
import { TranslateServiceStub } from '../../../../../test/translateServiceStub';
import { SlickContextMenu } from '../slickContextMenu';
@@ -26,7 +25,7 @@ const commandItemsMock = [
{ command: 'command3', title: 'Command 3', positionOrder: 70, },
{ command: 'command4', title: 'Command 4', positionOrder: 71, },
{
- command: 'more-sub-commands', title: 'More Sub Commands', subMenuTitle: 'Sub Command Title 2', subMenuTitleCssClass: 'color-warning', commandItems: [
+ command: 'more-sub-commands', title: 'More Sub Commands', subMenuTitle: 'Sub Command Title 2', subMenuTitleCssClass: 'text-color-warning', commandItems: [
{ command: 'command5', title: 'Command 5', positionOrder: 72, },
]
}
@@ -281,6 +280,12 @@ describe('ContextMenu Plugin', () => {
expect(contextMenuElm).toBeTruthy();
expect(contextMenuElm.classList.contains('slick-dark-mode')).toBeTruthy();
+
+ // cell click should close it
+ gridStub.onClick.notify({ row: 1, cell: 2, grid: gridStub }, eventData as any, gridStub);
+ contextMenuElm = document.body.querySelector('.slick-context-menu.slickgrid12345') as HTMLDivElement;
+
+ expect(contextMenuElm).toBeNull();
});
it('should "autoAlignSide" and expect menu to aligned left with a calculate offset when showing menu', () => {
@@ -703,7 +708,7 @@ describe('ContextMenu Plugin', () => {
expect(commandList2Elm.querySelectorAll('.slick-menu-item').length).toBe(3);
expect(commandContentElm2.textContent).toBe('Sub Commands');
expect(subMenuTitleElm.textContent).toBe('Sub Command Title 2');
- expect(subMenuTitleElm.className).toBe('slick-menu-title color-warning');
+ expect(subMenuTitleElm.className).toBe('slick-menu-title text-color-warning');
expect(commandChevronElm.className).toBe('sub-item-chevron mdi mdi-chevron-right');
expect(subCommand3Elm.textContent).toContain('Command 3');
expect(subCommand5Elm.textContent).toContain('Command 5');
@@ -832,7 +837,7 @@ describe('ContextMenu Plugin', () => {
expect(closeBtnElm).toBeTruthy();
expect(commandListElm.querySelectorAll('.slick-menu-item').length).toBe(1);
expect(commandItemElm1.classList.contains('slick-menu-item-disabled')).toBeFalsy();
- expect(commandIconElm1.classList.contains('fa-clone')).toBeTruthy();
+ expect(commandIconElm1.classList.contains('mdi-content-copy')).toBeTruthy();
expect(commandLabelElm1.textContent).toBe('Copy');
commandItemElm1.dispatchEvent(new CustomEvent('click'));
diff --git a/packages/common/src/extensions/__tests__/slickDraggableGrouping.spec.ts b/packages/common/src/extensions/__tests__/slickDraggableGrouping.spec.ts
index 3e8273fbd..bff30f9d8 100644
--- a/packages/common/src/extensions/__tests__/slickDraggableGrouping.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickDraggableGrouping.spec.ts
@@ -54,7 +54,7 @@ const gridOptionsMock = {
enableDraggableGrouping: true,
draggableGrouping: {
hideToggleAllButton: false,
- deleteIconCssClass: 'mdi mdi-close color-danger',
+ deleteIconCssClass: 'mdi mdi-close text-color-danger',
},
showHeaderRow: false,
showTopPanel: false,
@@ -329,7 +329,7 @@ describe('Draggable Grouping Plugin', () => {
it('should execute the "onEnd" callback of Sortable and expect sortable to be cancelled', () => {
plugin.init(gridStub, { ...addonOptions });
- plugin.setAddonOptions({ deleteIconCssClass: 'mdi mdi-close color-danger' });
+ plugin.setAddonOptions({ deleteIconCssClass: 'mdi mdi-close text-color-danger' });
const fn = plugin.setupColumnReorder(gridStub, mockHeaderLeftDiv1, {}, setColumnsSpy, setColumnResizeSpy, mockColumns, getColumnIndexSpy, GRID_UID, triggerSpy);
fn.sortableLeftInstance!.options.onStart!({} as any);
@@ -346,7 +346,7 @@ describe('Draggable Grouping Plugin', () => {
it('should clear grouping and expect placeholder to be displayed when calling "onEnd" callback', () => {
plugin.init(gridStub, { ...addonOptions });
- plugin.setAddonOptions({ deleteIconCssClass: 'mdi mdi-close color-danger' });
+ plugin.setAddonOptions({ deleteIconCssClass: 'mdi mdi-close text-color-danger' });
const fn = plugin.setupColumnReorder(gridStub, mockHeaderLeftDiv1, {}, setColumnsSpy, setColumnResizeSpy, mockColumns, getColumnIndexSpy, GRID_UID, triggerSpy);
fn.sortableLeftInstance!.options.onStart!({} as any);
@@ -382,7 +382,7 @@ describe('Draggable Grouping Plugin', () => {
it('should drag over dropzone and expect hover css class be added and removed when dragging outside of dropzone', () => {
plugin.init(gridStub, { ...addonOptions });
- plugin.setAddonOptions({ deleteIconCssClass: 'mdi mdi-close color-danger' });
+ plugin.setAddonOptions({ deleteIconCssClass: 'mdi mdi-close text-color-danger' });
const fn = plugin.setupColumnReorder(gridStub, mockHeaderLeftDiv1, {}, setColumnsSpy, setColumnResizeSpy, mockColumns, getColumnIndexSpy, GRID_UID, triggerSpy);
fn.sortableLeftInstance!.options.onStart!({} as any);
@@ -704,7 +704,7 @@ describe('Draggable Grouping Plugin', () => {
it('should execute the "onEnd" callback of Sortable and expect sortable to be cancelled', () => {
plugin.init(gridStub, { ...addonOptions });
- plugin.setAddonOptions({ deleteIconCssClass: 'mdi mdi-close color-danger' });
+ plugin.setAddonOptions({ deleteIconCssClass: 'mdi mdi-close text-color-danger' });
const fn = plugin.setupColumnReorder(gridStub, [mockHeaderLeftDiv1, mockHeaderLeftDiv2], {}, setColumnsSpy, setColumnResizeSpy, mockColumns, getColumnIndexSpy, GRID_UID, triggerSpy);
jest.spyOn(fn.sortableLeftInstance, 'toArray').mockReturnValue(['firstName', 'lastName', 'age']);
jest.spyOn(fn.sortableRightInstance, 'toArray').mockReturnValue(['gender']);
diff --git a/packages/common/src/extensions/__tests__/slickGridMenu.spec.ts b/packages/common/src/extensions/__tests__/slickGridMenu.spec.ts
index e7e41d699..578374ef6 100644
--- a/packages/common/src/extensions/__tests__/slickGridMenu.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickGridMenu.spec.ts
@@ -9,8 +9,6 @@ import { type SlickDataView, SlickEvent, SlickEventData, SlickGrid } from '../..
import { TranslateServiceStub } from '../../../../../test/translateServiceStub';
import { ExtensionUtility } from '../../extensions/extensionUtility';
-jest.mock('flatpickr', () => { });
-
const gridId = 'grid1';
const gridUid = 'slickgrid_124343';
const containerId = 'demo-container';
@@ -64,6 +62,7 @@ const gridStub = {
setOptions: jest.fn(),
scrollColumnIntoView: jest.fn(),
onBeforeDestroy: new SlickEvent(),
+ onClick: new SlickEvent(),
onColumnsReordered: new SlickEvent(),
onSetOptions: new SlickEvent(),
} as unknown as SlickGrid;
@@ -265,10 +264,15 @@ describe('GridMenuControl', () => {
buttonElm.dispatchEvent(new Event('click', { bubbles: true, cancelable: true, composed: false }));
control.menuElement!.querySelector('input[type="checkbox"]')!.dispatchEvent(new Event('click', { bubbles: true }));
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(readjustSpy).toHaveBeenCalledWith(0, columnsMock, columnsMock);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
+
+ // cell click should close it
+ gridStub.onClick.notify({ row: 1, cell: 2, grid: gridStub }, eventData as any, gridStub);
+
+ expect(control.menuElement).toBeFalsy();
});
it('should query an input checkbox change event and expect "readjustFrozenColumnIndexWhenNeeded" method to be called when the grid is detected to be a frozen grid', () => {
@@ -284,7 +288,7 @@ describe('GridMenuControl', () => {
buttonElm.dispatchEvent(new Event('click', { bubbles: true, cancelable: true, composed: false }));
control.menuElement!.querySelector('input[type="checkbox"]')!.dispatchEvent(new Event('click', { bubbles: true }));
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(readjustSpy).toHaveBeenCalledWith(0, columnsMock, columnsMock);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
@@ -317,7 +321,7 @@ describe('GridMenuControl', () => {
control.menuElement!.querySelector('input[type="checkbox"]')!.dispatchEvent(new Event('click', { bubbles: true }));
const liElmList = control.menuElement!.querySelectorAll('li');
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(readjustSpy).toHaveBeenCalledWith(0, columnsMock, columnsMock);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
@@ -339,7 +343,7 @@ describe('GridMenuControl', () => {
control.menuElement!.querySelector('input[type="checkbox"]')!.dispatchEvent(new Event('click', { bubbles: true }));
const liElmList = control.menuElement!.querySelectorAll('li');
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(readjustSpy).toHaveBeenCalledWith(0, columnsMock, columnsMock);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
@@ -381,7 +385,7 @@ describe('GridMenuControl', () => {
const repositionSpy = jest.spyOn(control, 'repositionMenu');
control.init();
- const spanEvent = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false })
+ const spanEvent = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false });
const spanBtnElm = document.createElement('span');
const buttonElm = document.createElement('button');
spanBtnElm.textContent = 'Grid Menu';
@@ -400,7 +404,7 @@ describe('GridMenuControl', () => {
const repositionSpy = jest.spyOn(control, 'repositionMenu');
control.init();
- const spanEvent = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false })
+ const spanEvent = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false });
const spanBtnElm = document.createElement('span');
const buttonElm = document.createElement('button');
spanBtnElm.textContent = 'Grid Menu';
@@ -429,11 +433,11 @@ describe('GridMenuControl', () => {
const inputForcefitElm = control.menuElement!.querySelector('#slickgrid_124343-gridmenu-colpicker-forcefit') as HTMLInputElement;
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-gridmenu-colpicker-forcefit]') as HTMLLabelElement;
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
expect(inputForcefitElm.checked).toBeTruthy();
- expect(inputForcefitElm.dataset.option).toBe('autoresize')
+ expect(inputForcefitElm.dataset.option).toBe('autoresize');
expect(labelSyncElm.textContent).toBe('Force fit columns');
});
@@ -452,7 +456,7 @@ describe('GridMenuControl', () => {
const inputSyncElm = control.menuElement!.querySelector('#slickgrid_124343-gridmenu-colpicker-syncresize') as HTMLInputElement;
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-gridmenu-colpicker-syncresize]') as HTMLLabelElement;
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
expect(inputSyncElm.checked).toBeTruthy();
@@ -482,7 +486,7 @@ describe('GridMenuControl', () => {
visibleColumns: columnsMock,
grid: gridStub,
};
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
expect(onColChangedMock).toBeCalledWith(expect.anything(), expectedCallbackArgs);
@@ -507,7 +511,7 @@ describe('GridMenuControl', () => {
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-gridmenu-colpicker-forcefit]') as HTMLLabelElement;
inputForcefitElm.dispatchEvent(new Event('click', { bubbles: true }));
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(inputForcefitElm.checked).toBeTruthy();
expect(inputForcefitElm.dataset.option).toBe('autoresize');
@@ -534,7 +538,7 @@ describe('GridMenuControl', () => {
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-gridmenu-colpicker-syncresize]') as HTMLLabelElement;
inputSyncElm.dispatchEvent(new Event('click', { bubbles: true }));
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(inputSyncElm.checked).toBeTruthy();
expect(inputSyncElm.dataset.option).toBe('syncresize');
@@ -913,7 +917,7 @@ describe('GridMenuControl', () => {
{ command: 'command3', title: 'Command 3', positionOrder: 70, },
{ command: 'command4', title: 'Command 4', positionOrder: 71, },
{
- command: 'more-sub-commands', title: 'More Sub Commands', subMenuTitle: 'Sub Command Title 2', subMenuTitleCssClass: 'color-warning', commandItems: [
+ command: 'more-sub-commands', title: 'More Sub Commands', subMenuTitle: 'Sub Command Title 2', subMenuTitleCssClass: 'text-color-warning', commandItems: [
{ command: 'command5', title: 'Command 5', positionOrder: 72, },
]
}
@@ -963,7 +967,7 @@ describe('GridMenuControl', () => {
expect(commandList2Elm.querySelectorAll('.slick-menu-item').length).toBe(3);
expect(commandContentElm2.textContent).toBe('Sub Commands');
expect(subMenuTitleElm.textContent).toBe('Sub Command Title 2');
- expect(subMenuTitleElm.className).toBe('slick-menu-title color-warning');
+ expect(subMenuTitleElm.className).toBe('slick-menu-title text-color-warning');
expect(commandChevronElm.className).toBe('sub-item-chevron mdi mdi-chevron-right');
expect(subCommand3Elm.textContent).toContain('Command 3');
expect(subCommand5Elm.textContent).toContain('Command 5');
@@ -1019,7 +1023,7 @@ describe('GridMenuControl', () => {
expect(commandList2Elm.querySelectorAll('.slick-menu-item').length).toBe(3);
expect(commandContentElm2.textContent).toBe('Sub Commands');
expect(subMenuTitleElm.textContent).toBe('Sub Command Title 2');
- expect(subMenuTitleElm.className).toBe('slick-menu-title color-warning');
+ expect(subMenuTitleElm.className).toBe('slick-menu-title text-color-warning');
expect(commandChevronElm.className).toBe('sub-item-chevron mdi mdi-chevron-right');
expect(subCommand3Elm.textContent).toContain('Command 3');
expect(subCommand5Elm.textContent).toContain('Command 5');
@@ -1053,7 +1057,7 @@ describe('GridMenuControl', () => {
const gridMenu2Elm = document.body.querySelector('.slick-grid-menu.slick-menu-level-1') as HTMLDivElement;
Object.defineProperty(gridMenu2Elm, 'clientHeight', { writable: true, configurable: true, value: 320 });
- const divEvent = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false })
+ const divEvent = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false });
const subMenuElm = document.createElement('div');
const menuItem = document.createElement('div');
menuItem.className = 'slick-menu-item';
@@ -1094,7 +1098,7 @@ describe('GridMenuControl', () => {
control.columns = columnsMock;
control.init();
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-times', titleKey: 'CLEAR_PINNING', title: 'Dégeler les colonnes/rangées', disabled: false, command: 'clear-pinning', positionOrder: 52 },
+ { iconCssClass: 'mdi mdi-pin-off-outline', titleKey: 'CLEAR_PINNING', title: 'Dégeler les colonnes/rangées', disabled: false, command: 'clear-pinning', positionOrder: 52 },
]);
});
@@ -1106,9 +1110,9 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-filter text-danger', titleKey: 'CLEAR_ALL_FILTERS', title: 'Supprimer tous les filtres', disabled: false, command: 'clear-filter', positionOrder: 50 },
- { iconCssClass: 'fa fa-random', titleKey: 'TOGGLE_FILTER_ROW', title: 'Basculer la ligne des filtres', disabled: false, command: 'toggle-filter', positionOrder: 53 },
- { iconCssClass: 'fa fa-refresh', titleKey: 'REFRESH_DATASET', title: 'Rafraîchir les données', disabled: false, command: 'refresh-dataset', positionOrder: 58 }
+ { iconCssClass: 'mdi mdi-filter-remove-outline', titleKey: 'CLEAR_ALL_FILTERS', title: 'Supprimer tous les filtres', disabled: false, command: 'clear-filter', positionOrder: 50 },
+ { iconCssClass: 'mdi mdi-flip-vertical', titleKey: 'TOGGLE_FILTER_ROW', title: 'Basculer la ligne des filtres', disabled: false, command: 'toggle-filter', positionOrder: 53 },
+ { iconCssClass: 'mdi mdi-sync', titleKey: 'REFRESH_DATASET', title: 'Rafraîchir les données', disabled: false, command: 'refresh-dataset', positionOrder: 58 }
]);
});
@@ -1124,7 +1128,7 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-filter text-danger', titleKey: 'CLEAR_ALL_FILTERS', title: 'Supprimer tous les filtres', disabled: false, command: 'clear-filter', positionOrder: 50 }
+ { iconCssClass: 'mdi mdi-filter-remove-outline', titleKey: 'CLEAR_ALL_FILTERS', title: 'Supprimer tous les filtres', disabled: false, command: 'clear-filter', positionOrder: 50 }
]);
});
@@ -1140,7 +1144,7 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-random', titleKey: 'TOGGLE_FILTER_ROW', title: 'Basculer la ligne des filtres', disabled: false, command: 'toggle-filter', positionOrder: 53 },
+ { iconCssClass: 'mdi mdi-flip-vertical', titleKey: 'TOGGLE_FILTER_ROW', title: 'Basculer la ligne des filtres', disabled: false, command: 'toggle-filter', positionOrder: 53 },
]);
});
@@ -1157,7 +1161,7 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-random', titleKey: 'TOGGLE_DARK_MODE', title: 'Basculer le mode clair/sombre', disabled: false, command: 'toggle-dark-mode', positionOrder: 54 },
+ { iconCssClass: 'mdi mdi-brightness-4', titleKey: 'TOGGLE_DARK_MODE', title: 'Basculer le mode clair/sombre', disabled: false, command: 'toggle-dark-mode', positionOrder: 54 },
]);
});
@@ -1173,7 +1177,7 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-refresh', titleKey: 'REFRESH_DATASET', title: 'Rafraîchir les données', disabled: false, command: 'refresh-dataset', positionOrder: 58 }
+ { iconCssClass: 'mdi mdi-sync', titleKey: 'REFRESH_DATASET', title: 'Rafraîchir les données', disabled: false, command: 'refresh-dataset', positionOrder: 58 }
]);
});
@@ -1185,7 +1189,7 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-random', titleKey: 'TOGGLE_PRE_HEADER_ROW', title: 'Basculer la ligne de pré-en-tête', disabled: false, command: 'toggle-preheader', positionOrder: 53 }
+ { iconCssClass: 'mdi mdi-flip-vertical', titleKey: 'TOGGLE_PRE_HEADER_ROW', title: 'Basculer la ligne de pré-en-tête', disabled: false, command: 'toggle-preheader', positionOrder: 53 }
]);
});
@@ -1211,7 +1215,7 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-unsorted text-danger', titleKey: 'CLEAR_ALL_SORTING', title: 'Supprimer tous les tris', disabled: false, command: 'clear-sorting', positionOrder: 51 }
+ { iconCssClass: 'mdi mdi-sort-variant-off', titleKey: 'CLEAR_ALL_SORTING', title: 'Supprimer tous les tris', disabled: false, command: 'clear-sorting', positionOrder: 51 }
]);
});
@@ -1241,7 +1245,7 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-download', titleKey: 'EXPORT_TO_CSV', title: 'Exporter en format CSV', disabled: false, command: 'export-csv', positionOrder: 55 }
+ { iconCssClass: 'mdi mdi-download', titleKey: 'EXPORT_TO_CSV', title: 'Exporter en format CSV', disabled: false, command: 'export-csv', positionOrder: 55 }
]);
});
@@ -1271,7 +1275,7 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-file-excel-o text-success', titleKey: 'EXPORT_TO_EXCEL', title: 'Exporter vers Excel', disabled: false, command: 'export-excel', positionOrder: 56 }
+ { iconCssClass: 'mdi mdi-file-excel-outline text-success', titleKey: 'EXPORT_TO_EXCEL', title: 'Exporter vers Excel', disabled: false, command: 'export-excel', positionOrder: 56 }
]);
});
@@ -1287,7 +1291,7 @@ describe('GridMenuControl', () => {
control.init();
control.init(); // calling 2x register to make sure it doesn't duplicate commands
expect(SharedService.prototype.gridOptions.gridMenu!.commandItems).toEqual([
- { iconCssClass: 'fa fa-download', titleKey: 'EXPORT_TO_TAB_DELIMITED', title: 'Exporter en format texte (délimité par tabulation)', disabled: false, command: 'export-text-delimited', positionOrder: 57 }
+ { iconCssClass: 'mdi mdi-download', titleKey: 'EXPORT_TO_TAB_DELIMITED', title: 'Exporter en format texte (délimité par tabulation)', disabled: false, command: 'export-text-delimited', positionOrder: 57 }
]);
});
@@ -1574,7 +1578,7 @@ describe('GridMenuControl', () => {
gridStub.onColumnsReordered.notify({ impactedColumns: columnsUnorderedMock, grid: gridStub }, eventData as any, gridStub);
control.menuElement!.querySelector('input[type="checkbox"]')!.dispatchEvent(new Event('click', { bubbles: true }));
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(control.getAllColumns()).toEqual(columnsMock);
expect(control.getVisibleColumns()).toEqual(columnsMock);
expect(control.columns).toEqual(columnsMock);
@@ -1616,7 +1620,7 @@ describe('GridMenuControl', () => {
const labelForcefitElm = control.menuElement!.querySelector('label[for=slickgrid_124343-gridmenu-colpicker-forcefit]') as HTMLLabelElement;
const labelSyncElm = control.menuElement!.querySelector('label[for=slickgrid_124343-gridmenu-colpicker-syncresize]') as HTMLLabelElement;
- expect(handlerSpy).toHaveBeenCalledTimes(3);
+ expect(handlerSpy).toHaveBeenCalledTimes(4);
expect(labelForcefitElm.textContent).toBe('Ajustement forcé des colonnes');
expect(labelSyncElm.textContent).toBe('Redimension synchrone');
expect(utilitySpy).toHaveBeenCalled();
diff --git a/packages/common/src/extensions/__tests__/slickHeaderButtons.spec.ts b/packages/common/src/extensions/__tests__/slickHeaderButtons.spec.ts
index 9dc5ae00f..a50e5a1a4 100644
--- a/packages/common/src/extensions/__tests__/slickHeaderButtons.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickHeaderButtons.spec.ts
@@ -98,7 +98,7 @@ describe('HeaderButton Plugin', () => {
plugin.init();
plugin.addonOptions = {
buttonCssClass: 'some-class'
- }
+ };
expect(plugin.addonOptions).toEqual({
buttonCssClass: 'some-class',
diff --git a/packages/common/src/extensions/__tests__/slickHeaderMenu.spec.ts b/packages/common/src/extensions/__tests__/slickHeaderMenu.spec.ts
index e42fa336a..0fb51e20a 100644
--- a/packages/common/src/extensions/__tests__/slickHeaderMenu.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickHeaderMenu.spec.ts
@@ -59,6 +59,7 @@ const gridStub = {
updateColumnHeader: jest.fn(),
onBeforeSetColumns: new SlickEvent(),
onBeforeHeaderCellDestroy: new SlickEvent(),
+ onClick: new SlickEvent(),
onHeaderCellRendered: new SlickEvent(),
onHeaderMouseEnter: new SlickEvent(),
onMouseEnter: new SlickEvent(),
@@ -605,7 +606,7 @@ describe('HeaderMenu Plugin', () => {
{ command: 'command3', title: 'Command 3', positionOrder: 70, },
{ command: 'command4', title: 'Command 4', positionOrder: 71, },
{
- command: 'more-sub-commands', title: 'More Sub Commands', subMenuTitle: 'Sub Command Title 2', subMenuTitleCssClass: 'color-warning', commandItems: [
+ command: 'more-sub-commands', title: 'More Sub Commands', subMenuTitle: 'Sub Command Title 2', subMenuTitleCssClass: 'text-color-warning', commandItems: [
{ command: 'command5', title: 'Command 5', positionOrder: 72, },
]
}
@@ -661,7 +662,7 @@ describe('HeaderMenu Plugin', () => {
expect(commandList2Elm.querySelectorAll('.slick-menu-item').length).toBe(3);
expect(commandContentElm2.textContent).toBe('Sub Commands');
expect(subMenuTitleElm.textContent).toBe('Sub Command Title 2');
- expect(subMenuTitleElm.className).toBe('slick-menu-title color-warning');
+ expect(subMenuTitleElm.className).toBe('slick-menu-title text-color-warning');
expect(commandChevronElm.className).toBe('sub-item-chevron');
expect(subCommand3Elm.textContent).toContain('Command 3');
expect(subCommand5Elm.textContent).toContain('Command 5');
@@ -717,7 +718,7 @@ describe('HeaderMenu Plugin', () => {
expect(commandList2Elm.querySelectorAll('.slick-menu-item').length).toBe(3);
expect(commandContentElm2.textContent).toBe('Sub Commands');
expect(subMenuTitleElm.textContent).toBe('Sub Command Title 2');
- expect(subMenuTitleElm.className).toBe('slick-menu-title color-warning');
+ expect(subMenuTitleElm.className).toBe('slick-menu-title text-color-warning');
expect(commandChevronElm.className).toBe('sub-item-chevron mdi mdi-chevron-right');
expect(subCommand3Elm.textContent).toContain('Command 3');
expect(subCommand5Elm.textContent).toContain('Command 5');
@@ -735,6 +736,7 @@ describe('HeaderMenu Plugin', () => {
});
it('should create a Grid Menu item with commands sub-menu commandItems and expect sub-menu to be positioned on top (dropup)', () => {
+ const hideMenuSpy = jest.spyOn(plugin, 'hideMenu');
const onCommandMock = jest.fn();
Object.defineProperty(document.documentElement, 'clientWidth', { writable: true, configurable: true, value: 50 });
jest.spyOn(gridStub, 'getColumns').mockReturnValueOnce(columnsMock);
@@ -751,7 +753,7 @@ describe('HeaderMenu Plugin', () => {
const subCommands1Elm = commandList1Elm.querySelector('[data-command="sub-commands"]') as HTMLDivElement;
Object.defineProperty(headerMenu1Elm, 'clientHeight', { writable: true, configurable: true, value: 77 });
Object.defineProperty(headerMenu1Elm, 'clientWidth', { writable: true, configurable: true, value: 225 });
- const divEvent1 = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false })
+ const divEvent1 = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false });
Object.defineProperty(divEvent1, 'target', { writable: true, configurable: true, value: headerButtonElm });
subCommands1Elm!.dispatchEvent(new Event('click'));
@@ -759,7 +761,7 @@ describe('HeaderMenu Plugin', () => {
const headerMenu2Elm = document.body.querySelector('.slick-header-menu.slick-menu-level-1') as HTMLDivElement;
Object.defineProperty(headerMenu2Elm, 'clientHeight', { writable: true, configurable: true, value: 320 });
- const divEvent = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false })
+ const divEvent = new MouseEvent('click', { bubbles: true, cancelable: true, composed: false });
const subMenuElm = document.createElement('div');
const menuItem = document.createElement('div');
menuItem.className = 'slick-menu-item';
@@ -775,6 +777,11 @@ describe('HeaderMenu Plugin', () => {
expect(headerMenu2Elm2.classList.contains('dropup')).toBeTruthy();
expect(headerMenu2Elm2.classList.contains('dropdown')).toBeFalsy();
+
+ // cell click should close it
+ gridStub.onClick.notify({ row: 1, cell: 2, grid: gridStub }, eventData as any, gridStub);
+
+ expect(hideMenuSpy).toHaveBeenCalled();
});
});
@@ -813,7 +820,7 @@ describe('HeaderMenu Plugin', () => {
const commandDivElm = gridContainerDiv.querySelector('[data-command="freeze-columns"]') as HTMLDivElement;
expect((originalColumnDefinitions[1] as any).header!.menu!.commandItems!).toEqual([
- { iconCssClass: 'fa fa-thumb-tack', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
+ { iconCssClass: 'mdi mdi-pin-outline', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
{ divider: true, command: '', positionOrder: 49 },
]);
expect(commandDivElm).toBeFalsy();
@@ -834,12 +841,12 @@ describe('HeaderMenu Plugin', () => {
headerButtonElm.dispatchEvent(new Event('click', { bubbles: true, cancelable: true, composed: false }));
const clearFilterSpy = jest.spyOn(filterServiceStub, 'clearFilterByColumnId');
- const headerMenuExpected = [{ iconCssClass: 'fa fa-filter', title: 'Remove Filter', titleKey: 'REMOVE_FILTER', command: 'clear-filter', positionOrder: 53 }];
+ const headerMenuExpected = [{ iconCssClass: 'mdi mdi-filter-remove-outline', title: 'Remove Filter', titleKey: 'REMOVE_FILTER', command: 'clear-filter', positionOrder: 53 }];
const commandDivElm = gridContainerDiv.querySelector('[data-command="clear-filter"]') as HTMLDivElement;
const commandIconElm = commandDivElm.querySelector('.slick-menu-icon') as HTMLDivElement;
const commandLabelElm = commandDivElm.querySelector('.slick-menu-content') as HTMLDivElement;
expect(columnsMock[1].header!.menu!.commandItems!).toEqual(headerMenuExpected);
- expect(commandIconElm.classList.contains('fa-filter')).toBeTruthy();
+ expect(commandIconElm.classList.contains('mdi-filter-remove-outline')).toBeTruthy();
expect(commandLabelElm.textContent).toBe('Remove Filter');
const clickEvent = new Event('click');
@@ -870,15 +877,15 @@ describe('HeaderMenu Plugin', () => {
const pubSubSpy = jest.spyOn(pubSubServiceStub, 'publish');
const headerMenuExpected = [
- { iconCssClass: 'fa fa-arrows-h', title: 'Resize by Content', titleKey: 'COLUMN_RESIZE_BY_CONTENT', command: 'column-resize-by-content', positionOrder: 48 },
+ { iconCssClass: 'mdi mdi-arrow-expand-horizontal', title: 'Resize by Content', titleKey: 'COLUMN_RESIZE_BY_CONTENT', command: 'column-resize-by-content', positionOrder: 48 },
{ divider: true, command: '', positionOrder: 49 },
- { iconCssClass: 'fa fa-times', title: 'Hide Column', titleKey: 'HIDE_COLUMN', command: 'hide-column', positionOrder: 55 }
+ { iconCssClass: 'mdi mdi-close', title: 'Hide Column', titleKey: 'HIDE_COLUMN', command: 'hide-column', positionOrder: 55 }
];
const commandDivElm = gridContainerDiv.querySelector('[data-command="column-resize-by-content"]') as HTMLDivElement;
const commandIconElm = commandDivElm.querySelector('.slick-menu-icon') as HTMLDivElement;
const commandLabelElm = commandDivElm.querySelector('.slick-menu-content') as HTMLDivElement;
expect(columnsMock[1].header!.menu!.commandItems!).toEqual(headerMenuExpected);
- expect(commandIconElm.classList.contains('fa-arrows-h')).toBeTruthy();
+ expect(commandIconElm.classList.contains('mdi-arrow-expand-horizontal')).toBeTruthy();
expect(commandLabelElm.textContent).toBe('Resize by Content');
const clickEvent = new Event('click');
@@ -904,15 +911,15 @@ describe('HeaderMenu Plugin', () => {
const autosizeSpy = jest.spyOn(gridStub, 'autosizeColumns');
const headerMenuExpected = [
- { iconCssClass: 'fa fa-thumb-tack', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
+ { iconCssClass: 'mdi mdi-pin-outline', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
{ divider: true, command: '', positionOrder: 49 },
- { iconCssClass: 'fa fa-times', title: 'Hide Column', titleKey: 'HIDE_COLUMN', command: 'hide-column', positionOrder: 55 }
+ { iconCssClass: 'mdi mdi-close', title: 'Hide Column', titleKey: 'HIDE_COLUMN', command: 'hide-column', positionOrder: 55 }
];
const commandDivElm = gridContainerDiv.querySelector('[data-command="hide-column"]') as HTMLDivElement;
const commandIconElm = commandDivElm.querySelector('.slick-menu-icon') as HTMLDivElement;
const commandLabelElm = commandDivElm.querySelector('.slick-menu-content') as HTMLDivElement;
expect(columnsMock[1].header!.menu!.commandItems!).toEqual(headerMenuExpected);
- expect(commandIconElm.classList.contains('fa-times')).toBeTruthy();
+ expect(commandIconElm.classList.contains('mdi-close')).toBeTruthy();
expect(commandLabelElm.textContent).toBe('Hide Column');
commandDivElm.dispatchEvent(new Event('click'));
@@ -933,12 +940,12 @@ describe('HeaderMenu Plugin', () => {
headerButtonElm.dispatchEvent(new Event('click', { bubbles: true, cancelable: true, composed: false }));
const clearFilterSpy = jest.spyOn(filterServiceStub, 'clearFilterByColumnId');
- const headerMenuExpected = [{ iconCssClass: 'fa fa-filter', title: 'Remove Filter', titleKey: 'REMOVE_FILTER', command: 'clear-filter', positionOrder: 53 }];
+ const headerMenuExpected = [{ iconCssClass: 'mdi mdi-filter-remove-outline', title: 'Remove Filter', titleKey: 'REMOVE_FILTER', command: 'clear-filter', positionOrder: 53 }];
const commandDivElm = gridContainerDiv.querySelector('[data-command="clear-filter"]') as HTMLDivElement;
const commandIconElm = commandDivElm.querySelector('.slick-menu-icon') as HTMLDivElement;
const commandLabelElm = commandDivElm.querySelector('.slick-menu-content') as HTMLDivElement;
expect(columnsMock[1].header!.menu!.commandItems!).toEqual(headerMenuExpected);
- expect(commandIconElm.classList.contains('fa-filter')).toBeTruthy();
+ expect(commandIconElm.classList.contains('mdi-filter-remove-outline')).toBeTruthy();
expect(commandLabelElm.textContent).toBe('Remove Filter');
const clickEvent = new Event('click');
@@ -964,21 +971,21 @@ describe('HeaderMenu Plugin', () => {
const commandIconElm = commandDivElm.querySelector('.slick-menu-icon') as HTMLDivElement;
const commandLabelElm = commandDivElm.querySelector('.slick-menu-content') as HTMLDivElement;
expect(columnsMock[1].header!.menu!.commandItems!).toEqual([
- { iconCssClass: 'fa fa-sort-asc', title: 'Sort Ascending', titleKey: 'SORT_ASCENDING', command: 'sort-asc', positionOrder: 50 },
- { iconCssClass: 'fa fa-sort-desc', title: 'Sort Descending', titleKey: 'SORT_DESCENDING', command: 'sort-desc', positionOrder: 51 },
+ { iconCssClass: 'mdi mdi-sort-ascending', title: 'Sort Ascending', titleKey: 'SORT_ASCENDING', command: 'sort-asc', positionOrder: 50 },
+ { iconCssClass: 'mdi mdi-sort-descending', title: 'Sort Descending', titleKey: 'SORT_DESCENDING', command: 'sort-desc', positionOrder: 51 },
{ divider: true, command: '', positionOrder: 52 },
- { iconCssClass: 'fa fa-unsorted', title: 'Remove Sort', titleKey: 'REMOVE_SORT', command: 'clear-sort', positionOrder: 54 },
+ { iconCssClass: 'mdi mdi-sort-variant-off', title: 'Remove Sort', titleKey: 'REMOVE_SORT', command: 'clear-sort', positionOrder: 54 },
]);
- expect(commandIconElm.classList.contains('fa-unsorted')).toBeTruthy();
+ expect(commandIconElm.classList.contains('mdi-sort-variant-off')).toBeTruthy();
expect(commandLabelElm.textContent).toBe('Remove Sort');
translateService.use('fr');
plugin.translateHeaderMenu();
expect(columnsMock[1].header!.menu!.commandItems!).toEqual([
- { iconCssClass: 'fa fa-sort-asc', title: 'Trier par ordre croissant', titleKey: 'SORT_ASCENDING', command: 'sort-asc', positionOrder: 50 },
- { iconCssClass: 'fa fa-sort-desc', title: 'Trier par ordre décroissant', titleKey: 'SORT_DESCENDING', command: 'sort-desc', positionOrder: 51 },
+ { iconCssClass: 'mdi mdi-sort-ascending', title: 'Trier par ordre croissant', titleKey: 'SORT_ASCENDING', command: 'sort-asc', positionOrder: 50 },
+ { iconCssClass: 'mdi mdi-sort-descending', title: 'Trier par ordre décroissant', titleKey: 'SORT_DESCENDING', command: 'sort-desc', positionOrder: 51 },
{ divider: true, command: '', positionOrder: 52 },
- { iconCssClass: 'fa fa-unsorted', title: 'Supprimer le tri', titleKey: 'REMOVE_SORT', command: 'clear-sort', positionOrder: 54 },
+ { iconCssClass: 'mdi mdi-sort-variant-off', title: 'Supprimer le tri', titleKey: 'REMOVE_SORT', command: 'clear-sort', positionOrder: 54 },
]);
const clickEvent = new Event('click');
@@ -1005,16 +1012,16 @@ describe('HeaderMenu Plugin', () => {
const commandIconElm = commandDivElm.querySelector('.slick-menu-icon') as HTMLDivElement;
const commandLabelElm = commandDivElm.querySelector('.slick-menu-content') as HTMLDivElement;
expect(columnsMock[1].header!.menu!.commandItems!).toEqual([
- { iconCssClass: 'fa fa-thumb-tack', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
+ { iconCssClass: 'mdi mdi-pin-outline', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
{ divider: true, command: '', positionOrder: 49 },
]);
- expect(commandIconElm.classList.contains('fa-thumb-tack')).toBeTruthy();
+ expect(commandIconElm.classList.contains('mdi-pin-outline')).toBeTruthy();
expect(commandLabelElm.textContent).toBe('Freeze Columns');
translateService.use('fr');
plugin.translateHeaderMenu();
expect(columnsMock[1].header!.menu!.commandItems!).toEqual([
- { iconCssClass: 'fa fa-thumb-tack', title: 'Geler les colonnes', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
+ { iconCssClass: 'mdi mdi-pin-outline', title: 'Geler les colonnes', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
{ divider: true, command: '', positionOrder: 49 },
]);
@@ -1038,7 +1045,7 @@ describe('HeaderMenu Plugin', () => {
const commandDivElm = gridContainerDiv.querySelector('[data-command="freeze-columns"]') as HTMLDivElement;
expect(columnsMock[2].header!.menu!.commandItems!).toEqual([
- { iconCssClass: 'fa fa-thumb-tack', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
+ { iconCssClass: 'mdi mdi-pin-outline', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
{ divider: true, command: '', positionOrder: 49 },
]);
@@ -1066,7 +1073,7 @@ describe('HeaderMenu Plugin', () => {
const commandDivElm = gridContainerDiv.querySelector('[data-command="freeze-columns"]') as HTMLDivElement;
expect((originalColumnDefinitions[1] as any).header!.menu!.commandItems!).toEqual([
- { iconCssClass: 'fa fa-thumb-tack', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
+ { iconCssClass: 'mdi mdi-pin-outline', title: 'Freeze Columns', titleKey: 'FREEZE_COLUMNS', command: 'freeze-columns', positionOrder: 47 },
{ divider: true, command: '', positionOrder: 49 },
]);
@@ -1093,10 +1100,10 @@ describe('HeaderMenu Plugin', () => {
const commandDivElm = gridContainerDiv.querySelector('[data-command="sort-asc"]') as HTMLDivElement;
expect(columnsMock[1].header!.menu!.commandItems!).toEqual([
- { iconCssClass: 'fa fa-sort-asc', title: 'Sort Ascending', titleKey: 'SORT_ASCENDING', command: 'sort-asc', positionOrder: 50 },
- { iconCssClass: 'fa fa-sort-desc', title: 'Sort Descending', titleKey: 'SORT_DESCENDING', command: 'sort-desc', positionOrder: 51 },
+ { iconCssClass: 'mdi mdi-sort-ascending', title: 'Sort Ascending', titleKey: 'SORT_ASCENDING', command: 'sort-asc', positionOrder: 50 },
+ { iconCssClass: 'mdi mdi-sort-descending', title: 'Sort Descending', titleKey: 'SORT_DESCENDING', command: 'sort-desc', positionOrder: 51 },
{ divider: true, command: '', positionOrder: 52 },
- { iconCssClass: 'fa fa-unsorted', title: 'Remove Sort', titleKey: 'REMOVE_SORT', command: 'clear-sort', positionOrder: 54 },
+ { iconCssClass: 'mdi mdi-sort-variant-off', title: 'Remove Sort', titleKey: 'REMOVE_SORT', command: 'clear-sort', positionOrder: 54 },
]);
const clickEvent = new Event('click');
@@ -1125,10 +1132,10 @@ describe('HeaderMenu Plugin', () => {
const commandDivElm = gridContainerDiv.querySelector('[data-command="sort-desc"]') as HTMLDivElement;
expect(columnsMock[1].header!.menu!.commandItems!).toEqual([
- { iconCssClass: 'fa fa-sort-asc', title: 'Sort Ascending', titleKey: 'SORT_ASCENDING', command: 'sort-asc', positionOrder: 50 },
- { iconCssClass: 'fa fa-sort-desc', title: 'Sort Descending', titleKey: 'SORT_DESCENDING', command: 'sort-desc', positionOrder: 51 },
+ { iconCssClass: 'mdi mdi-sort-ascending', title: 'Sort Ascending', titleKey: 'SORT_ASCENDING', command: 'sort-asc', positionOrder: 50 },
+ { iconCssClass: 'mdi mdi-sort-descending', title: 'Sort Descending', titleKey: 'SORT_DESCENDING', command: 'sort-desc', positionOrder: 51 },
{ divider: true, command: '', positionOrder: 52 },
- { iconCssClass: 'fa fa-unsorted', title: 'Remove Sort', titleKey: 'REMOVE_SORT', command: 'clear-sort', positionOrder: 54 },
+ { iconCssClass: 'mdi mdi-sort-variant-off', title: 'Remove Sort', titleKey: 'REMOVE_SORT', command: 'clear-sort', positionOrder: 54 },
]);
const clickEvent = new Event('click');
diff --git a/packages/common/src/extensions/__tests__/slickRowMoveManager.spec.ts b/packages/common/src/extensions/__tests__/slickRowMoveManager.spec.ts
index 93d89312f..0e008f5b4 100644
--- a/packages/common/src/extensions/__tests__/slickRowMoveManager.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickRowMoveManager.spec.ts
@@ -6,7 +6,6 @@ import { SlickRowMoveManager } from '../slickRowMoveManager';
import { SlickEvent, SlickGrid } from '../../core/index';
const GRID_UID = 'slickgrid_12345';
-jest.mock('flatpickr', () => { });
const addVanillaEventPropagation = function (event, target?: HTMLElement) {
Object.defineProperty(event, 'isPropagationStopped', { writable: true, configurable: true, value: jest.fn() });
@@ -230,7 +229,7 @@ describe('SlickRowMoveManager Plugin', () => {
const output = plugin.getColumnDefinition().formatter!(0, 0, null, { id: '_move', field: '' } as Column, { firstName: 'John', lastName: 'Doe', age: 33 }, gridStub);
expect(plugin).toBeTruthy();
- expect(output).toEqual({ addClasses: 'cell-reorder dnd slick-row-move-column', html: iconElm });
+ expect(output).toEqual({ addClasses: 'cell-reorder dnd', html: iconElm });
});
it('should process the "checkboxSelectionFormatter" and expect necessary Formatter to return regular formatter when usabilityOverride is not a function', () => {
@@ -242,7 +241,7 @@ describe('SlickRowMoveManager Plugin', () => {
const output = plugin.getColumnDefinition().formatter!(0, 0, null, { id: '_move', field: '' } as Column, { firstName: 'John', lastName: 'Doe', age: 33 }, gridStub);
expect(plugin).toBeTruthy();
- expect(output).toEqual({ addClasses: 'cell-reorder dnd slick-row-move-column', html: iconElm });
+ expect(output).toEqual({ addClasses: 'cell-reorder dnd', html: iconElm });
});
it('should create the plugin and trigger "dragInit" event and expect "stopImmediatePropagation" to be called', () => {
diff --git a/packages/common/src/extensions/__tests__/slickRowSelectionModel.spec.ts b/packages/common/src/extensions/__tests__/slickRowSelectionModel.spec.ts
index 602c4cb2f..4f83bfc0c 100644
--- a/packages/common/src/extensions/__tests__/slickRowSelectionModel.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickRowSelectionModel.spec.ts
@@ -7,7 +7,6 @@ import { SlickRowSelectionModel } from '../slickRowSelectionModel';
import { BasePubSubService } from '@slickgrid-universal/event-pub-sub';
const GRID_UID = 'slickgrid_12345';
-jest.mock('flatpickr', () => { });
const addVanillaEventPropagation = function (event, commandKey = '', keyName = '') {
Object.defineProperty(event, 'isPropagationStopped', { writable: true, configurable: true, value: jest.fn() });
diff --git a/packages/common/src/extensions/extensionCommonUtils.ts b/packages/common/src/extensions/extensionCommonUtils.ts
index c6911d83a..a31158d28 100644
--- a/packages/common/src/extensions/extensionCommonUtils.ts
+++ b/packages/common/src/extensions/extensionCommonUtils.ts
@@ -5,6 +5,9 @@ import type { Column, ColumnPickerOption, DOMEvent, GridMenuOption } from '../in
import { SlickColumnPicker } from './slickColumnPicker';
import { SlickGridMenu } from './slickGridMenu';
+const PICKER_CHECK_ICON = 'mdi-icon-picker-check';
+const PICKER_UNCHECK_ICON = 'mdi-icon-picker-uncheck';
+
/** Create a Close button element and add it to the Menu element */
export function addCloseButtomElement(this: SlickColumnPicker | SlickGridMenu, menuElm: HTMLDivElement) {
const context: any = this;
@@ -37,28 +40,28 @@ export function addColumnTitleElementWhenDefined(this: SlickColumnPicker | Slick
export function handleColumnPickerItemClick(this: SlickColumnPicker | SlickGridMenu, event: DOMEvent) {
const context: any = this;
const controlType = context instanceof SlickColumnPicker ? 'columnPicker' : 'gridMenu';
+ const iconContainerElm = event.target?.closest('.icon-checkbox-container') as HTMLDivElement;
+ const iconElm = iconContainerElm?.querySelector('.mdi');
+ const isChecked = !!(event.target.checked);
+ event.target.ariaChecked = String(isChecked);
+ togglePickerCheckbox(iconElm, isChecked);
if (event.target.dataset.option === 'autoresize') {
// when calling setOptions, it will resize with ALL Columns (even the hidden ones)
// we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after
const previousVisibleColumns = context.getVisibleColumns();
- event.target.ariaChecked = String(event.target.checked);
- const isChecked = event.target.checked;
context.grid.setOptions({ forceFitColumns: isChecked });
context.grid.setColumns(previousVisibleColumns);
return;
}
if (event.target.dataset.option === 'syncresize') {
- event.target.ariaChecked = String(event.target.checked);
- context.grid.setOptions({ syncColumnCellResize: !!(event.target.checked) });
+ context.grid.setOptions({ syncColumnCellResize: isChecked });
return;
}
if (event.target.type === 'checkbox') {
context._areVisibleColumnDifferent = true;
- event.target.ariaChecked = String(event.target.checked);
- const isChecked = event.target.checked;
const columnId = event.target.dataset.columnid || '';
const visibleColumns: Column[] = [];
context._columnCheckboxes.forEach((columnCheckbox: HTMLInputElement, idx: number) => {
@@ -69,6 +72,7 @@ export function handleColumnPickerItemClick(this: SlickColumnPicker | SlickGridM
if (!visibleColumns.length) {
event.target.checked = true;
+ togglePickerCheckbox(iconElm, true);
return;
}
@@ -114,6 +118,32 @@ export function handleColumnPickerItemClick(this: SlickColumnPicker | SlickGridM
}
}
+function togglePickerCheckbox(iconElm: HTMLDivElement | null, checked = false) {
+ if (iconElm) {
+ iconElm.className = `mdi ${checked ? PICKER_CHECK_ICON : PICKER_UNCHECK_ICON}`;
+ }
+}
+
+function generatePickerCheckbox(columnLiElm: HTMLLIElement, inputId: string, inputData: any, checked = false) {
+ const labelElm = createDomElement('label', { className: 'checkbox-picker-label', htmlFor: inputId });
+ const divElm = createDomElement('div', { className: 'icon-checkbox-container' });
+ const inputElm = createDomElement('input', { id: inputId, type: 'checkbox', dataset: inputData });
+ const colInputDivElm = createDomElement('div', { className: `mdi ${checked ? PICKER_CHECK_ICON : PICKER_UNCHECK_ICON}` });
+ const labelSpanElm = createDomElement('span', { className: 'checkbox-label' });
+ divElm.appendChild(inputElm);
+ divElm.appendChild(colInputDivElm);
+ labelElm.appendChild(divElm);
+ labelElm.appendChild(labelSpanElm);
+ columnLiElm.appendChild(labelElm);
+
+ if (checked) {
+ inputElm.ariaChecked = 'true';
+ inputElm.checked = true;
+ }
+
+ return { inputElm, labelElm, labelSpanElm };
+}
+
export function populateColumnPicker(this: SlickColumnPicker | SlickGridMenu, addonOptions: ColumnPickerOption | GridMenuOption) {
const context: any = this;
const menuPrefix = context instanceof SlickGridMenu ? 'gridmenu-' : '';
@@ -125,24 +155,15 @@ export function populateColumnPicker(this: SlickColumnPicker | SlickGridMenu, ad
columnLiElm.className = 'hidden';
}
- const colInputElm = createDomElement('input', {
- type: 'checkbox', id: `${context._gridUid}-${menuPrefix}colpicker-${columnId}`,
- dataset: { columnid: `${columnId}` }
- });
- const colIndex = context.grid.getColumnIndex(columnId);
- if (colIndex >= 0) {
- colInputElm.ariaChecked = 'true';
- colInputElm.checked = true;
- }
- columnLiElm.appendChild(colInputElm);
- context._columnCheckboxes.push(colInputElm);
+ const inputId = `${context._gridUid}-${menuPrefix}colpicker-${columnId}`;
+ const isChecked = context.grid.getColumnIndex(columnId) >= 0;
+ const { inputElm, labelElm, labelSpanElm } = generatePickerCheckbox(columnLiElm, inputId, { columnid: `${columnId}` }, isChecked);
+ context._columnCheckboxes.push(inputElm);
const headerColumnValueExtractorFn = typeof addonOptions?.headerColumnValueExtractor === 'function' ? addonOptions.headerColumnValueExtractor : context._defaults.headerColumnValueExtractor;
const columnLabel = headerColumnValueExtractorFn!(column, context.gridOptions);
- const labelElm = document.createElement('label');
- labelElm.htmlFor = `${context._gridUid}-${menuPrefix}colpicker-${columnId}`;
- this.grid.applyHtmlCode(labelElm, columnLabel);
+ this.grid.applyHtmlCode(labelSpanElm, columnLabel);
columnLiElm.appendChild(labelElm);
context._listElm.appendChild(columnLiElm);
}
@@ -153,39 +174,17 @@ export function populateColumnPicker(this: SlickColumnPicker | SlickGridMenu, ad
if (!(addonOptions?.hideForceFitButton)) {
const fitLiElm = document.createElement('li');
- fitLiElm.appendChild(
- createDomElement('input', {
- type: 'checkbox', id: `${context._gridUid}-${menuPrefix}colpicker-forcefit`,
- ariaChecked: String(context.gridOptions.forceFitColumns),
- checked: context.gridOptions.forceFitColumns,
- dataset: { option: 'autoresize' }
- })
- );
- fitLiElm.appendChild(
- createDomElement('label', {
- htmlFor: `${context._gridUid}-${menuPrefix}colpicker-forcefit`,
- textContent: addonOptions?.forceFitTitle ?? '',
- })
- );
+ const inputId = `${context._gridUid}-${menuPrefix}colpicker-forcefit`;
+ const { labelSpanElm } = generatePickerCheckbox(fitLiElm, inputId, { option: 'autoresize' }, context.gridOptions.forceFitColumns);
+ labelSpanElm.textContent = addonOptions?.forceFitTitle ?? '';
context._listElm.appendChild(fitLiElm);
}
if (!(addonOptions?.hideSyncResizeButton)) {
const syncLiElm = document.createElement('li');
- syncLiElm.appendChild(
- createDomElement('input', {
- type: 'checkbox', id: `${context._gridUid}-${menuPrefix}colpicker-syncresize`,
- ariaChecked: String(context.gridOptions.syncColumnCellResize),
- checked: context.gridOptions.syncColumnCellResize,
- dataset: { option: 'syncresize' }
- })
- );
- syncLiElm.appendChild(
- createDomElement('label', {
- htmlFor: `${context._gridUid}-${menuPrefix}colpicker-syncresize`,
- textContent: addonOptions?.syncResizeTitle ?? ''
- })
- );
+ const inputId = `${context._gridUid}-${menuPrefix}colpicker-syncresize`;
+ const { labelSpanElm } = generatePickerCheckbox(syncLiElm, inputId, { option: 'syncresize' }, context.gridOptions.forceFitColumns);
+ labelSpanElm.textContent = addonOptions?.syncResizeTitle ?? '';
context._listElm.appendChild(syncLiElm);
}
}
diff --git a/packages/common/src/extensions/slickCheckboxSelectColumn.ts b/packages/common/src/extensions/slickCheckboxSelectColumn.ts
index f3543dacf..fc3cd1dcf 100644
--- a/packages/common/src/extensions/slickCheckboxSelectColumn.ts
+++ b/packages/common/src/extensions/slickCheckboxSelectColumn.ts
@@ -9,6 +9,9 @@ import type { SelectionModel } from '../enums/index';
export interface RowLookup { [row: number]: boolean; }
+const CHECK_ICON = 'mdi-icon-check';
+const UNCHECK_ICON = 'mdi-icon-uncheck';
+
export class SlickCheckboxSelectColumn {
pluginName: 'CheckboxSelectColumn' = 'CheckboxSelectColumn' as const;
protected _defaults = {
@@ -219,12 +222,16 @@ export class SlickCheckboxSelectColumn {
*/
createCheckboxElement(inputId: string, checked = false) {
const fragmentElm = new DocumentFragment();
- fragmentElm.appendChild(
+ const labelElm = createDomElement('label', { className: 'checkbox-selector-label', htmlFor: inputId });
+ const divElm = createDomElement('div', { className: 'icon-checkbox-container' });
+ divElm.appendChild(
createDomElement('input', { id: inputId, type: 'checkbox', checked, ariaChecked: String(checked) })
);
- fragmentElm.appendChild(
- createDomElement('label', { htmlFor: inputId })
+ divElm.appendChild(
+ createDomElement('div', { className: `mdi ${checked ? CHECK_ICON : UNCHECK_ICON}` })
);
+ labelElm.appendChild(divElm);
+ fragmentElm.appendChild(labelElm);
return fragmentElm;
}
@@ -250,6 +257,7 @@ export class SlickCheckboxSelectColumn {
reorderable: this._addonOptions.reorderable,
sortable: false,
width: this._addonOptions.width || 30,
+ maxWidth: this._addonOptions.width || 30,
formatter: this.checkboxSelectionFormatter.bind(this),
} as Column;
}
@@ -287,7 +295,7 @@ export class SlickCheckboxSelectColumn {
// user can optionally execute a callback defined in its grid options prior to toggling the row
const previousSelectedRows = this._grid.getSelectedRows();
- if (this._addonOptions.onRowToggleStart) {
+ if (typeof this._addonOptions.onRowToggleStart === 'function') {
this._addonOptions.onRowToggleStart(event, { row, previousSelectedRows });
}
@@ -320,18 +328,22 @@ export class SlickCheckboxSelectColumn {
if (args.column.field === (this._addonOptions.field || '_checkbox_selector')) {
emptyElement(args.node);
- //
- const spanElm = createDomElement('span', { id: 'filter-checkbox-selectall-container', ariaChecked: 'false' });
- spanElm.appendChild(
- createDomElement('input', { type: 'checkbox', id: `header-filter-selector${this._selectAll_UID}` })
+ const inputId = `header-filter-selector${this._selectAll_UID}`;
+ const labelElm = createDomElement('label', { id: 'filter-checkbox-selectall-container', htmlFor: inputId });
+ const divElm = createDomElement('div', { className: 'icon-checkbox-container' });
+ divElm.appendChild(
+ createDomElement('input', { id: inputId, type: 'checkbox', ariaChecked: 'false' })
);
- spanElm.appendChild(
- createDomElement('label', { htmlFor: `header-filter-selector${this._selectAll_UID}` })
+ divElm.appendChild(
+ createDomElement('div', { className: 'mdi mdi-icon-uncheck' })
);
- args.node.appendChild(spanElm);
+
+ labelElm.appendChild(divElm);
+ args.node.appendChild(labelElm);
this._headerRowNode = args.node;
+ this._headerRowNode.classList.add('checkbox-header');
- this._bindEventService.bind(spanElm, 'click', ((e: DOMMouseOrTouchEvent) => this.handleHeaderClick(e, args)) as EventListener);
+ this._bindEventService.bind(labelElm, 'click', ((e: DOMMouseOrTouchEvent) => this.handleHeaderClick(e, args)) as EventListener);
}
});
}
@@ -392,10 +404,14 @@ export class SlickCheckboxSelectColumn {
}
if (!this._addonOptions.hideInFilterHeaderRow) {
const selectAllElm = this.headerRowNode?.querySelector(`#header-filter-selector${this._selectAll_UID}`);
+ const selectAllIconElm = this.headerRowNode?.querySelector('.icon-checkbox-container .mdi');
if (selectAllElm) {
selectAllElm.ariaChecked = String(this._isSelectAllChecked);
selectAllElm.checked = this._isSelectAllChecked;
}
+ if (selectAllIconElm) {
+ selectAllIconElm.className = `mdi ${this._isSelectAllChecked ? CHECK_ICON : UNCHECK_ICON}`;
+ }
}
}
@@ -562,10 +578,11 @@ export class SlickCheckboxSelectColumn {
}
protected renderSelectAllCheckbox(isSelectAllChecked: boolean) {
- this._grid.updateColumnHeader(
+ const colHeaderElm = this._grid.updateColumnHeader(
this._addonOptions.columnId || '',
this.createCheckboxElement(`header-selector${this._selectAll_UID}`, !!isSelectAllChecked),
this._addonOptions.toolTip
);
+ colHeaderElm?.classList.add('header-checkbox-selectall');
}
}
\ No newline at end of file
diff --git a/packages/common/src/extensions/slickColumnPicker.ts b/packages/common/src/extensions/slickColumnPicker.ts
index fbdc4b3e3..0fd5a410d 100644
--- a/packages/common/src/extensions/slickColumnPicker.ts
+++ b/packages/common/src/extensions/slickColumnPicker.ts
@@ -101,6 +101,7 @@ export class SlickColumnPicker {
this._eventHandler.subscribe(this.grid.onHeaderContextMenu, this.handleHeaderContextMenu.bind(this));
this._eventHandler.subscribe(this.grid.onColumnsReordered, updateColumnPickerOrder.bind(this));
+ this._eventHandler.subscribe(this.grid.onClick, this.disposeMenu.bind(this));
// Hide the menu on outside click.
this._bindEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener, undefined, 'body');
diff --git a/packages/common/src/extensions/slickContextMenu.ts b/packages/common/src/extensions/slickContextMenu.ts
index 2049d997f..8100d5b96 100644
--- a/packages/common/src/extensions/slickContextMenu.ts
+++ b/packages/common/src/extensions/slickContextMenu.ts
@@ -75,6 +75,7 @@ export class SlickContextMenu extends MenuFromCellBaseClass {
this.sortMenuItems();
this._eventHandler.subscribe(this.grid.onContextMenu, this.handleOnContextMenu.bind(this));
+ this._eventHandler.subscribe(this.grid.onClick, this.hideMenu.bind(this));
if (this._addonOptions.hideMenuOnScroll) {
this._eventHandler.subscribe(this.grid.onScroll, this.closeMenu.bind(this));
@@ -169,7 +170,7 @@ export class SlickContextMenu extends MenuFromCellBaseClass {
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
menuCommandItems.push(
{
- iconCssClass: contextMenu.iconCopyCellValueCommand || 'fa fa-clone',
+ iconCssClass: contextMenu.iconCopyCellValueCommand || 'mdi mdi-content-copy',
titleKey: `${translationPrefix}COPY`,
disabled: false,
command: commandName,
@@ -202,7 +203,7 @@ export class SlickContextMenu extends MenuFromCellBaseClass {
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
menuCommandItems.push(
{
- iconCssClass: contextMenu.iconExportCsvCommand || 'fa fa-download',
+ iconCssClass: contextMenu.iconExportCsvCommand || 'mdi mdi-download',
titleKey: `${translationPrefix}EXPORT_TO_CSV`,
disabled: false,
command: commandName,
@@ -230,7 +231,7 @@ export class SlickContextMenu extends MenuFromCellBaseClass {
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
menuCommandItems.push(
{
- iconCssClass: contextMenu.iconExportExcelCommand || 'fa fa-file-excel-o text-success',
+ iconCssClass: contextMenu.iconExportExcelCommand || 'mdi mdi-file-excel-outline text-success',
titleKey: `${translationPrefix}EXPORT_TO_EXCEL`,
disabled: false,
command: commandName,
@@ -255,7 +256,7 @@ export class SlickContextMenu extends MenuFromCellBaseClass {
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
menuCommandItems.push(
{
- iconCssClass: contextMenu.iconExportTextDelimitedCommand || 'fa fa-download',
+ iconCssClass: contextMenu.iconExportTextDelimitedCommand || 'mdi mdi-download',
titleKey: `${translationPrefix}EXPORT_TO_TAB_DELIMITED`,
disabled: false,
command: commandName,
@@ -290,7 +291,7 @@ export class SlickContextMenu extends MenuFromCellBaseClass {
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
menuCommandItems.push(
{
- iconCssClass: contextMenu.iconClearGroupingCommand || 'fa fa-times',
+ iconCssClass: contextMenu.iconClearGroupingCommand || 'mdi mdi-close',
titleKey: `${translationPrefix}CLEAR_ALL_GROUPING`,
disabled: false,
command: commandName,
@@ -315,7 +316,7 @@ export class SlickContextMenu extends MenuFromCellBaseClass {
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
menuCommandItems.push(
{
- iconCssClass: contextMenu.iconCollapseAllGroupsCommand || 'fa fa-compress',
+ iconCssClass: contextMenu.iconCollapseAllGroupsCommand || 'mdi mdi-arrow-collapse',
titleKey: `${translationPrefix}COLLAPSE_ALL_GROUPS`,
disabled: false,
command: commandName,
@@ -347,7 +348,7 @@ export class SlickContextMenu extends MenuFromCellBaseClass {
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
menuCommandItems.push(
{
- iconCssClass: contextMenu.iconExpandAllGroupsCommand || 'fa fa-expand',
+ iconCssClass: contextMenu.iconExpandAllGroupsCommand || 'mdi mdi-arrow-expand',
titleKey: `${translationPrefix}EXPAND_ALL_GROUPS`,
disabled: false,
command: commandName,
diff --git a/packages/common/src/extensions/slickDraggableGrouping.ts b/packages/common/src/extensions/slickDraggableGrouping.ts
index 7b6568fa8..1782910ad 100644
--- a/packages/common/src/extensions/slickDraggableGrouping.ts
+++ b/packages/common/src/extensions/slickDraggableGrouping.ts
@@ -320,7 +320,7 @@ export class SlickDraggableGrouping {
draggablePlaceholderElm.style.display = 'none';
}
if (groupTogglerElm) {
- groupTogglerElm.style.display = 'inline-block';
+ groupTogglerElm.style.display = 'inline-flex';
}
}
@@ -488,7 +488,7 @@ export class SlickDraggableGrouping {
// show the "Toggle All" when feature is enabled
if (this._groupToggler && this.columnsGroupBy.length > 0) {
- this._groupToggler.style.display = 'inline-block';
+ this._groupToggler.style.display = 'inline-flex';
}
}
}
diff --git a/packages/common/src/extensions/slickGridMenu.ts b/packages/common/src/extensions/slickGridMenu.ts
index 9dbd8d55c..71dfd7b08 100644
--- a/packages/common/src/extensions/slickGridMenu.ts
+++ b/packages/common/src/extensions/slickGridMenu.ts
@@ -114,6 +114,7 @@ export class SlickGridMenu extends MenuBaseClass {
initEventHandlers() {
// when grid columns are reordered then we also need to update/resync our picker column in the same order
this._eventHandler.subscribe(this.grid.onColumnsReordered, updateColumnPickerOrder.bind(this));
+ this._eventHandler.subscribe(this.grid.onClick, (e) => this.hideMenu(e as any));
// subscribe to the grid, when it's destroyed, we should also destroy the Grid Menu
this._eventHandler.subscribe(this.grid.onBeforeDestroy, this.dispose.bind(this));
@@ -570,7 +571,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'clear-pinning';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconClearFrozenColumnsCommand || 'fa fa-times',
+ iconCssClass: this._addonOptions.iconClearFrozenColumnsCommand || 'mdi mdi-pin-off-outline',
titleKey: `${translationPrefix}${commandLabels?.clearFrozenColumnsCommandKey ?? 'CLEAR_PINNING'}`,
disabled: false,
command: commandName,
@@ -585,7 +586,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'clear-filter';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconClearAllFiltersCommand || 'fa fa-filter text-danger',
+ iconCssClass: this._addonOptions.iconClearAllFiltersCommand || 'mdi mdi-filter-remove-outline',
titleKey: `${translationPrefix}${commandLabels?.clearAllFiltersCommandKey ?? 'CLEAR_ALL_FILTERS'}`,
disabled: false,
command: commandName,
@@ -599,7 +600,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'toggle-filter';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconToggleFilterCommand || 'fa fa-random',
+ iconCssClass: this._addonOptions.iconToggleFilterCommand || 'mdi mdi-flip-vertical',
titleKey: `${translationPrefix}${commandLabels?.toggleFilterCommandKey ?? 'TOGGLE_FILTER_ROW'}`,
disabled: false,
command: commandName,
@@ -613,7 +614,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'refresh-dataset';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconRefreshDatasetCommand || 'fa fa-refresh',
+ iconCssClass: this._addonOptions.iconRefreshDatasetCommand || 'mdi mdi-sync',
titleKey: `${translationPrefix}${commandLabels?.refreshDatasetCommandKey ?? 'REFRESH_DATASET'}`,
disabled: false,
command: commandName,
@@ -628,7 +629,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'toggle-dark-mode';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconToggleDarkModeCommand || 'fa fa-random',
+ iconCssClass: this._addonOptions.iconToggleDarkModeCommand || 'mdi mdi-brightness-4',
titleKey: `${translationPrefix}${commandLabels?.toggleDarkModeCommandKey ?? 'TOGGLE_DARK_MODE'}`,
disabled: false,
command: commandName,
@@ -643,7 +644,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'toggle-preheader';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconTogglePreHeaderCommand || 'fa fa-random',
+ iconCssClass: this._addonOptions.iconTogglePreHeaderCommand || 'mdi mdi-flip-vertical',
titleKey: `${translationPrefix}${commandLabels?.togglePreHeaderCommandKey ?? 'TOGGLE_PRE_HEADER_ROW'}`,
disabled: false,
command: commandName,
@@ -659,7 +660,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'clear-sorting';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconClearAllSortingCommand || 'fa fa-unsorted text-danger',
+ iconCssClass: this._addonOptions.iconClearAllSortingCommand || 'mdi mdi-sort-variant-off',
titleKey: `${translationPrefix}${commandLabels?.clearAllSortingCommandKey ?? 'CLEAR_ALL_SORTING'}`,
disabled: false,
command: commandName,
@@ -674,7 +675,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'export-csv';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconExportCsvCommand || 'fa fa-download',
+ iconCssClass: this._addonOptions.iconExportCsvCommand || 'mdi mdi-download',
titleKey: `${translationPrefix}${commandLabels?.exportCsvCommandKey ?? 'EXPORT_TO_CSV'}`,
disabled: false,
command: commandName,
@@ -688,7 +689,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'export-excel';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconExportExcelCommand || 'fa fa-file-excel-o text-success',
+ iconCssClass: this._addonOptions.iconExportExcelCommand || 'mdi mdi-file-excel-outline text-success',
titleKey: `${translationPrefix}${commandLabels?.exportExcelCommandKey ?? 'EXPORT_TO_EXCEL'}`,
disabled: false,
command: commandName,
@@ -702,7 +703,7 @@ export class SlickGridMenu extends MenuBaseClass {
const commandName = 'export-text-delimited';
if (!originalCommandItems.some(item => item !== 'divider' && item.hasOwnProperty('command') && item.command === commandName)) {
gridMenuCommandItems.push({
- iconCssClass: this._addonOptions.iconExportTextDelimitedCommand || 'fa fa-download',
+ iconCssClass: this._addonOptions.iconExportTextDelimitedCommand || 'mdi mdi-download',
titleKey: `${translationPrefix}${commandLabels?.exportTextDelimitedCommandKey ?? 'EXPORT_TO_TAB_DELIMITED'}`,
disabled: false,
command: commandName,
@@ -830,7 +831,7 @@ export class SlickGridMenu extends MenuBaseClass {
columnTitle: this.extensionUtility.getPickerTitleOutputString('columnTitle', 'gridMenu'),
forceFitTitle: this.extensionUtility.getPickerTitleOutputString('forceFitTitle', 'gridMenu'),
syncResizeTitle: this.extensionUtility.getPickerTitleOutputString('syncResizeTitle', 'gridMenu'),
- iconCssClass: 'fa fa-bars',
+ iconCssClass: 'mdi mdi-menu',
menuWidth: 18,
commandItems: [],
hideClearAllFiltersCommand: false,
diff --git a/packages/common/src/extensions/slickHeaderMenu.ts b/packages/common/src/extensions/slickHeaderMenu.ts
index 3a5b5ec81..f5e57643f 100644
--- a/packages/common/src/extensions/slickHeaderMenu.ts
+++ b/packages/common/src/extensions/slickHeaderMenu.ts
@@ -79,6 +79,7 @@ export class SlickHeaderMenu extends MenuBaseClass {
});
this._eventHandler.subscribe(this.grid.onHeaderCellRendered, this.handleHeaderCellRendered.bind(this));
this._eventHandler.subscribe(this.grid.onBeforeHeaderCellDestroy, this.handleBeforeHeaderCellDestroy.bind(this));
+ this._eventHandler.subscribe(this.grid.onClick, this.hideMenu.bind(this));
// force the grid to re-render the header after the events are hooked up.
this.grid.setColumns(this.grid.getColumns());
@@ -357,7 +358,7 @@ export class SlickHeaderMenu extends MenuBaseClass {
hasFrozenOrResizeCommand = true;
if (!columnHeaderMenuItems.some(item => item !== 'divider' && item?.command === 'freeze-columns')) {
columnHeaderMenuItems.push({
- iconCssClass: headerMenuOptions.iconFreezeColumns || 'fa fa-thumb-tack',
+ iconCssClass: headerMenuOptions.iconFreezeColumns || 'mdi mdi-pin-outline',
titleKey: `${translationPrefix}FREEZE_COLUMNS`,
command: 'freeze-columns',
positionOrder: 47
@@ -370,7 +371,7 @@ export class SlickHeaderMenu extends MenuBaseClass {
hasFrozenOrResizeCommand = true;
if (!columnHeaderMenuItems.some(item => item !== 'divider' && item?.command === 'column-resize-by-content')) {
columnHeaderMenuItems.push({
- iconCssClass: headerMenuOptions.iconColumnResizeByContentCommand || 'fa fa-arrows-h',
+ iconCssClass: headerMenuOptions.iconColumnResizeByContentCommand || 'mdi mdi-arrow-expand-horizontal',
titleKey: `${translationPrefix}COLUMN_RESIZE_BY_CONTENT`,
command: 'column-resize-by-content',
positionOrder: 48
@@ -387,7 +388,7 @@ export class SlickHeaderMenu extends MenuBaseClass {
if (gridOptions.enableSorting && columnDef.sortable && headerMenuOptions && !headerMenuOptions.hideSortCommands) {
if (!columnHeaderMenuItems.some(item => item !== 'divider' && item?.command === 'sort-asc')) {
columnHeaderMenuItems.push({
- iconCssClass: headerMenuOptions.iconSortAscCommand || 'fa fa-sort-asc',
+ iconCssClass: headerMenuOptions.iconSortAscCommand || 'mdi mdi-sort-ascending',
titleKey: `${translationPrefix}SORT_ASCENDING`,
command: 'sort-asc',
positionOrder: 50
@@ -395,7 +396,7 @@ export class SlickHeaderMenu extends MenuBaseClass {
}
if (!columnHeaderMenuItems.some(item => item !== 'divider' && item?.command === 'sort-desc')) {
columnHeaderMenuItems.push({
- iconCssClass: headerMenuOptions.iconSortDescCommand || 'fa fa-sort-desc',
+ iconCssClass: headerMenuOptions.iconSortDescCommand || 'mdi mdi-sort-descending',
titleKey: `${translationPrefix}SORT_DESCENDING`,
command: 'sort-desc',
positionOrder: 51
@@ -409,7 +410,7 @@ export class SlickHeaderMenu extends MenuBaseClass {
if (!headerMenuOptions.hideClearSortCommand && !columnHeaderMenuItems.some(item => item !== 'divider' && item?.command === 'clear-sort')) {
columnHeaderMenuItems.push({
- iconCssClass: headerMenuOptions.iconClearSortCommand || 'fa fa-unsorted',
+ iconCssClass: headerMenuOptions.iconClearSortCommand || 'mdi mdi-sort-variant-off',
titleKey: `${translationPrefix}REMOVE_SORT`,
command: 'clear-sort',
positionOrder: 54
@@ -421,7 +422,7 @@ export class SlickHeaderMenu extends MenuBaseClass {
if (gridOptions.enableFiltering && columnDef.filterable && headerMenuOptions && !headerMenuOptions.hideFilterCommand) {
if (!headerMenuOptions.hideClearFilterCommand && !columnHeaderMenuItems.some(item => item !== 'divider' && item?.command === 'clear-filter')) {
columnHeaderMenuItems.push({
- iconCssClass: headerMenuOptions.iconClearFilterCommand || 'fa fa-filter',
+ iconCssClass: headerMenuOptions.iconClearFilterCommand || 'mdi mdi-filter-remove-outline',
titleKey: `${translationPrefix}REMOVE_FILTER`,
command: 'clear-filter',
positionOrder: 53
@@ -432,7 +433,7 @@ export class SlickHeaderMenu extends MenuBaseClass {
// Hide Column Command
if (headerMenuOptions && !headerMenuOptions.hideColumnHideCommand && !columnHeaderMenuItems.some(item => item !== 'divider' && item?.command === 'hide-column')) {
columnHeaderMenuItems.push({
- iconCssClass: headerMenuOptions.iconColumnHideCommand || 'fa fa-times',
+ iconCssClass: headerMenuOptions.iconColumnHideCommand || 'mdi mdi-close',
titleKey: `${translationPrefix}HIDE_COLUMN`,
command: 'hide-column',
positionOrder: 55
diff --git a/packages/common/src/extensions/slickRowBasedEdit.ts b/packages/common/src/extensions/slickRowBasedEdit.ts
index 29d9afbd9..7a5765bec 100644
--- a/packages/common/src/extensions/slickRowBasedEdit.ts
+++ b/packages/common/src/extensions/slickRowBasedEdit.ts
@@ -439,7 +439,7 @@ export class SlickRowBasedEdit {
.appendChild(
createDomElement('span', {
className:
- options.rowBasedEditOptions?.actionButtons?.iconEditButtonClassName || 'mdi mdi-table-edit color-primary',
+ options.rowBasedEditOptions?.actionButtons?.iconEditButtonClassName || 'mdi mdi-table-edit text-color-primary',
})
);
actionFragment
@@ -455,7 +455,7 @@ export class SlickRowBasedEdit {
.appendChild(
createDomElement('span', {
className:
- options.rowBasedEditOptions?.actionButtons?.iconDeleteButtonClassName || 'mdi mdi-close color-danger',
+ options.rowBasedEditOptions?.actionButtons?.iconDeleteButtonClassName || 'mdi mdi-close text-color-danger',
})
);
actionFragment
@@ -471,7 +471,7 @@ export class SlickRowBasedEdit {
.appendChild(
createDomElement('span', {
className:
- options.rowBasedEditOptions?.actionButtons?.iconUpdateButtonClassName || 'mdi mdi-check-bold color-success',
+ options.rowBasedEditOptions?.actionButtons?.iconUpdateButtonClassName || 'mdi mdi-check-bold text-color-success',
})
);
actionFragment
@@ -487,7 +487,7 @@ export class SlickRowBasedEdit {
.appendChild(
createDomElement('span', {
className:
- options.rowBasedEditOptions?.actionButtons?.iconCancelButtonClassName || 'mdi mdi-cancel color-danger',
+ options.rowBasedEditOptions?.actionButtons?.iconCancelButtonClassName || 'mdi mdi-cancel text-color-danger',
})
);
diff --git a/packages/common/src/extensions/slickRowMoveManager.ts b/packages/common/src/extensions/slickRowMoveManager.ts
index e989d252e..7bdd91c17 100644
--- a/packages/common/src/extensions/slickRowMoveManager.ts
+++ b/packages/common/src/extensions/slickRowMoveManager.ts
@@ -320,7 +320,7 @@ export class SlickRowMoveManager {
return '';
} else {
return {
- addClasses: `cell-reorder dnd ${this._addonOptions.cssClass || ''}`,
+ addClasses: `cell-reorder dnd`,
html: createDomElement('div', { className: this._addonOptions.cssClass || '' }),
};
}
diff --git a/packages/common/src/filter-conditions/__tests__/dateEuroShortFilterCondition.spec.ts b/packages/common/src/filter-conditions/__tests__/dateEuroShortFilterCondition.spec.ts
index f8b7e49cc..0d8d5c4b3 100644
--- a/packages/common/src/filter-conditions/__tests__/dateEuroShortFilterCondition.spec.ts
+++ b/packages/common/src/filter-conditions/__tests__/dateEuroShortFilterCondition.spec.ts
@@ -74,38 +74,77 @@ describe('dateEuroShortFilterCondition method', () => {
expect(output).toBe(false);
});
- it('should return True when input value is in the range of search terms', () => {
- const searchTerms = ['01/12/93..31/12/93'];
- const options = { dataKey: '', operator: 'EQ', cellValue: '25/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
- const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
- expect(output).toBe(true);
- });
+ describe('without zero padding dates', () => {
+ it('should return True when input value is in the range of search terms with short US dates and without zero padding', () => {
+ const searchTerms = ['1/12/93..31/12/93'];
+ const options = { dataKey: '', operator: 'EQ', cellValue: '25/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(true);
+ });
- it('should return False when input value is not in the range of search terms', () => {
- const searchTerms = ['01/12/93..31/12/93'];
- const options = { dataKey: '', operator: 'EQ', cellValue: '25/11/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
- const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
- expect(output).toBe(false);
- });
+ it('should return False when input value is not in the range of search terms with short US dates and without zero padding', () => {
+ const searchTerms = ['1/12/93..31/12/93'];
+ const options = { dataKey: '', operator: 'EQ', cellValue: '25/11/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(false);
+ });
- it('should return True when input value equals the search terms min inclusive value and operator is set to "rangeInclusive"', () => {
- const searchTerms = ['01/12/93..31/12/93'];
- const options = { dataKey: '', operator: 'RangeInclusive', cellValue: '01/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
- const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
- expect(output).toBe(true);
- });
+ it('should return True when input value equals the search terms min inclusive value and operator is set to "rangeInclusive"', () => {
+ const searchTerms = ['1/12/93..31/12/93'];
+ const options = { dataKey: '', operator: 'RangeInclusive', cellValue: '1/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(true);
+ });
- it('should return False when input value equals the search terms min inclusive value and operator is set to "RangeExclusive"', () => {
- const searchTerms = ['01/12/93..31/12/93'];
- const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '01/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
- const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
- expect(output).toBe(false);
+ it('should return False when input value equals the search terms min inclusive value and operator is set to "RangeExclusive"', () => {
+ const searchTerms = ['1/12/93..31/12/93'];
+ const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '1/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(false);
+ });
+
+ it('should return False when any of the 2 search term value is not a valid date', () => {
+ const searchTerms = ['1/12/93..60/12/93'];
+ const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '05/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(false);
+ });
});
- it('should return False when any of the 2 search term value is not a valid date', () => {
- const searchTerms = ['01/12/93..60/12/93'];
- const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '05/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
- const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
- expect(output).toBe(false);
+ describe('zero padding dates', () => {
+ it('should return True when input value is in the range of search terms', () => {
+ const searchTerms = ['01/12/93..31/12/93'];
+ const options = { dataKey: '', operator: 'EQ', cellValue: '25/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(true);
+ });
+
+ it('should return False when input value is not in the range of search terms', () => {
+ const searchTerms = ['01/12/93..31/12/93'];
+ const options = { dataKey: '', operator: 'EQ', cellValue: '25/11/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(false);
+ });
+
+ it('should return True when input value equals the search terms min inclusive value and operator is set to "rangeInclusive"', () => {
+ const searchTerms = ['01/12/93..31/12/93'];
+ const options = { dataKey: '', operator: 'RangeInclusive', cellValue: '1/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(true);
+ });
+
+ it('should return False when input value equals the search terms min inclusive value and operator is set to "RangeExclusive"', () => {
+ const searchTerms = ['01/12/93..31/12/93'];
+ const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '1/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(false);
+ });
+
+ it('should return False when any of the 2 search term value is not a valid date', () => {
+ const searchTerms = ['01/12/93..60/12/93'];
+ const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '05/12/93', fieldType: FieldType.dateEuroShort, searchTerms } as FilterConditionOption;
+ const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateEuroShort));
+ expect(output).toBe(false);
+ });
});
});
diff --git a/packages/common/src/filter-conditions/__tests__/dateUsShortFilterCondition.spec.ts b/packages/common/src/filter-conditions/__tests__/dateUsShortFilterCondition.spec.ts
index ad6149193..deaa413d4 100644
--- a/packages/common/src/filter-conditions/__tests__/dateUsShortFilterCondition.spec.ts
+++ b/packages/common/src/filter-conditions/__tests__/dateUsShortFilterCondition.spec.ts
@@ -40,14 +40,14 @@ describe('dateUsShortFilterCondition method', () => {
});
it('should return False when cell value is not the same value as the searchTerm', () => {
- const searchTerms = ['03/03/2003'];
+ const searchTerms = ['3/3/2003'];
const options = { dataKey: '', operator: 'EQ', fieldType: FieldType.dateUsShort, cellValue: '12/25/93', searchTerms } as FilterConditionOption;
const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateUsShort));
expect(output).toBe(false);
});
it('should return False even when the cell value is found in the searchTerms since it only compares first term', () => {
- const searchTerms = ['03/14/03', '12/25/93'];
+ const searchTerms = ['3/14/03', '12/25/93'];
const options = { dataKey: '', operator: 'EQ', fieldType: FieldType.dateUsShort, cellValue: '12/25/93', searchTerms } as FilterConditionOption;
const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateUsShort));
expect(output).toBe(false);
@@ -82,36 +82,36 @@ describe('dateUsShortFilterCondition method', () => {
});
it('should return True when input value is in the range of search terms', () => {
- const searchTerms = ['12/01/93..12/31/93'];
+ const searchTerms = ['12/1/93..12/31/93'];
const options = { dataKey: '', operator: 'EQ', cellValue: '12/25/93', fieldType: FieldType.dateUsShort, searchTerms } as FilterConditionOption;
const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateUsShort));
expect(output).toBe(true);
});
it('should return False when input value is not in the range of search terms', () => {
- const searchTerms = ['12/01/93..12/31/93'];
+ const searchTerms = ['12/1/93..12/31/93'];
const options = { dataKey: '', operator: 'EQ', cellValue: '11/25/93', fieldType: FieldType.dateUsShort, searchTerms } as FilterConditionOption;
const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateUsShort));
expect(output).toBe(false);
});
it('should return True when input value equals the search terms min inclusive value and operator is set to "rangeInclusive"', () => {
- const searchTerms = ['12/01/93..12/31/93'];
- const options = { dataKey: '', operator: 'RangeInclusive', cellValue: '12/01/93', fieldType: FieldType.dateUsShort, searchTerms } as FilterConditionOption;
+ const searchTerms = ['12/1/93..12/31/93'];
+ const options = { dataKey: '', operator: 'RangeInclusive', cellValue: '12/1/93', fieldType: FieldType.dateUsShort, searchTerms } as FilterConditionOption;
const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateUsShort));
expect(output).toBe(true);
});
it('should return False when input value equals the search terms min inclusive value and operator is set to "RangeExclusive"', () => {
- const searchTerms = ['12/01/93..12/31/93'];
- const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '12/01/93', fieldType: FieldType.dateUsShort, searchTerms } as FilterConditionOption;
+ const searchTerms = ['12/1/93..12/31/93'];
+ const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '12/1/93', fieldType: FieldType.dateUsShort, searchTerms } as FilterConditionOption;
const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateUsShort));
expect(output).toBe(false);
});
it('should return False when any of the 2 search term value is not a valid date', () => {
- const searchTerms = ['12/01/93..12/60/93'];
- const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '12/05/93', fieldType: FieldType.dateUsShort, searchTerms } as FilterConditionOption;
+ const searchTerms = ['12/1/93..12/60/93'];
+ const options = { dataKey: '', operator: 'RangeExclusive', cellValue: '12/5/93', fieldType: FieldType.dateUsShort, searchTerms } as FilterConditionOption;
const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateUsShort));
expect(output).toBe(false);
});
diff --git a/packages/common/src/filter-conditions/__tests__/filterConditionProcesses.spec.ts b/packages/common/src/filter-conditions/__tests__/filterConditionProcesses.spec.ts
index cd0e6d7b7..b838316b3 100644
--- a/packages/common/src/filter-conditions/__tests__/filterConditionProcesses.spec.ts
+++ b/packages/common/src/filter-conditions/__tests__/filterConditionProcesses.spec.ts
@@ -1,5 +1,3 @@
-import moment from 'moment-mini';
-
import { getParsedSearchTermsByFieldType } from '../filterConditionProcesses';
describe('getParsedSearchTermsByFieldType method', () => {
@@ -13,15 +11,6 @@ describe('getParsedSearchTermsByFieldType method', () => {
expect(result2).toEqual(true);
});
- it('should get a moment date object when parsing any date type', () => {
- const inputDate = '2001-03-03T10:11:22.456Z';
- const result = getParsedSearchTermsByFieldType([inputDate], 'dateUtc');
-
- expect(result![0]).toBeObject();
- expect(moment.isMoment(result![0])).toBeTrue();
- expect(result![0].format('YYYY-MM-DD')).toBe('2001-03-03');
- });
-
it('should get parsed result as a number array when providing an array of searchTerms that are string of numbers', () => {
const input1 = ['0'];
const input2 = ['0', 12];
diff --git a/packages/common/src/filter-conditions/dateFilterCondition.ts b/packages/common/src/filter-conditions/dateFilterCondition.ts
index 7a04a1299..89892605a 100644
--- a/packages/common/src/filter-conditions/dateFilterCondition.ts
+++ b/packages/common/src/filter-conditions/dateFilterCondition.ts
@@ -1,29 +1,31 @@
-import moment from 'moment-mini';
+import { dayStart } from '@formkit/tempo';
import { FieldType, OperatorType, type SearchTerm } from '../enums/index';
import type { FilterConditionOption } from '../interfaces/index';
-import { mapMomentDateFormatWithFieldType } from '../services/utilities';
import { testFilterCondition } from './filterUtilities';
+import { mapTempoDateFormatWithFieldType, tryParseDate } from '../services';
/**
* Execute Date filter condition check on each cell and use correct date format depending on it's field type (or filterSearchType when that is provided)
*/
-export function executeDateFilterCondition(options: FilterConditionOption, parsedSearchDates: any[]): boolean {
+export function executeDateFilterCondition(options: FilterConditionOption, parsedSearchDates: Array): boolean {
const filterSearchType = options && (options.filterSearchType || options.fieldType) || FieldType.dateIso;
- const FORMAT = mapMomentDateFormatWithFieldType(filterSearchType);
+ const FORMAT = mapTempoDateFormatWithFieldType(filterSearchType);
const [searchDate1, searchDate2] = parsedSearchDates;
- // cell value in moment format
- const dateCell = moment(options.cellValue, FORMAT, true);
+ // cell value in Date format
+ const dateCell = tryParseDate(options.cellValue, FORMAT, true);
// return when cell value is not a valid date
- if ((!searchDate1 && !searchDate2) || !dateCell.isValid()) {
+ if ((!searchDate1 && !searchDate2) || !dateCell) {
return false;
}
// when comparing with Dates only (without time), we need to disregard the time portion, we can do so by setting our time to start at midnight
// ref, see https://stackoverflow.com/a/19699447/1212166
- const dateCellTimestamp = FORMAT.toLowerCase().includes('h') ? dateCell.valueOf() : dateCell.clone().startOf('day').valueOf();
+ const dateCellTimestamp = FORMAT === 'ISO8601' || FORMAT.toLowerCase().includes('h')
+ ? dateCell.valueOf()
+ : dayStart(new Date(dateCell)).valueOf();
// having 2 search dates, we assume that it's a date range filtering and we'll compare against both dates
if (searchDate1 && searchDate2) {
@@ -38,18 +40,20 @@ export function executeDateFilterCondition(options: FilterConditionOption, parse
}
// comparing against a single search date
- const dateSearchTimestamp1 = FORMAT.toLowerCase().includes('h') ? searchDate1.valueOf() : searchDate1.clone().startOf('day').valueOf();
+ const dateSearchTimestamp1 = FORMAT === 'ISO8601' || FORMAT.toLowerCase().includes('h')
+ ? searchDate1.valueOf()
+ : dayStart(new Date(searchDate1)).valueOf();
return testFilterCondition(options.operator || '==', dateCellTimestamp, dateSearchTimestamp1);
}
/**
- * From our search filter value(s), get the parsed value(s), they are parsed as Moment object(s).
+ * From our search filter value(s), get the parsed value(s), they are parsed as Date objects.
* This is called only once per filter before running the actual filter condition check on each cell
*/
export function getFilterParsedDates(inputSearchTerms: SearchTerm[] | undefined, inputFilterSearchType: typeof FieldType[keyof typeof FieldType]): SearchTerm[] {
const searchTerms = Array.isArray(inputSearchTerms) && inputSearchTerms || [];
const filterSearchType = inputFilterSearchType || FieldType.dateIso;
- const FORMAT = mapMomentDateFormatWithFieldType(filterSearchType);
+ const FORMAT = mapTempoDateFormatWithFieldType(filterSearchType);
const parsedSearchValues: any[] = [];
@@ -57,18 +61,18 @@ export function getFilterParsedDates(inputSearchTerms: SearchTerm[] | undefined,
const searchValues = (searchTerms.length === 2) ? searchTerms : (searchTerms[0] as string).split('..');
const searchValue1 = (Array.isArray(searchValues) && searchValues[0] || '') as Date | string;
const searchValue2 = (Array.isArray(searchValues) && searchValues[1] || '') as Date | string;
- const searchDate1 = moment(searchValue1, FORMAT, true);
- const searchDate2 = moment(searchValue2, FORMAT, true);
+ const searchDate1 = tryParseDate(searchValue1, FORMAT, true);
+ const searchDate2 = tryParseDate(searchValue2, FORMAT, true);
// return if any of the 2 values are invalid dates
- if (!searchDate1.isValid() || !searchDate2.isValid()) {
+ if (!searchDate1 || !searchDate2) {
return [];
}
parsedSearchValues.push(searchDate1, searchDate2);
} else {
// return if the search term is an invalid date
- const searchDate1 = moment(searchTerms[0] as Date | string, FORMAT, true);
- if (!searchDate1.isValid()) {
+ const searchDate1 = tryParseDate(searchTerms[0] as Date | string, FORMAT, true);
+ if (!searchDate1) {
return [];
}
parsedSearchValues.push(searchDate1);
diff --git a/packages/common/src/filter-conditions/filterConditionProcesses.ts b/packages/common/src/filter-conditions/filterConditionProcesses.ts
index ffae472c1..95b1bd3d2 100644
--- a/packages/common/src/filter-conditions/filterConditionProcesses.ts
+++ b/packages/common/src/filter-conditions/filterConditionProcesses.ts
@@ -44,7 +44,7 @@ export const executeFilterConditionTest: FilterCondition = ((options: FilterCond
}) as FilterCondition;
/**
- * From our search filter value(s), get their parsed value(s), for example a "dateIso" filter will be parsed as Moment object.
+ * From our search filter value(s), get their parsed value(s), for example a "dateIso" filter will be parsed as Date object.
* Then later when we execute the filtering checks, we won't need to re-parse all search value(s) again and again.
* So this is called only once, for each search filter that is, prior to running the actual filter condition checks on each cell afterward.
*/
diff --git a/packages/common/src/filters/__tests__/autocompleterFilter.spec.ts b/packages/common/src/filters/__tests__/autocompleterFilter.spec.ts
index 1e81d0444..5efd7f03d 100644
--- a/packages/common/src/filters/__tests__/autocompleterFilter.spec.ts
+++ b/packages/common/src/filters/__tests__/autocompleterFilter.spec.ts
@@ -28,6 +28,7 @@ const gridStub = {
getColumns: jest.fn(),
getHeaderRowColumn: jest.fn(),
render: jest.fn(),
+ sanitizeHtmlString: (str) => str,
} as unknown as SlickGrid;
describe('AutocompleterFilter', () => {
@@ -309,7 +310,7 @@ describe('AutocompleterFilter', () => {
jest.runAllTimers(); // fast-forward timer
- expect(filter.filterDomElement.classList.contains('slick-autocomplete-loading')).toBeTrue();
+ expect(filter.filterDomElement.classList.contains('slick-autocomplete-loading')).toBe(true);
expect(callbackMock).toHaveBeenCalledWith('female');
expect(renderSpy).toHaveBeenCalledTimes(1);
});
diff --git a/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts b/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts
index 4e473abfd..7c03a7901 100644
--- a/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts
+++ b/packages/common/src/filters/__tests__/compoundDateFilter.spec.ts
@@ -1,10 +1,14 @@
import 'jest-extended';
+import { format } from '@formkit/tempo';
+import { VanillaCalendar } from 'vanilla-calendar-picker';
+
import { Filters } from '../filters.index';
import { FieldType, OperatorType } from '../../enums/index';
import { Column, FilterArguments, GridOption } from '../../interfaces/index';
import { CompoundDateFilter } from '../compoundDateFilter';
import { TranslateServiceStub } from '../../../../../test/translateServiceStub';
import { SlickGrid } from '../../core/index';
+import { mapTempoDateFormatWithFieldType } from '../../services/dateUtils';
const containerId = 'demo-container';
@@ -26,8 +30,11 @@ const gridStub = {
getColumns: jest.fn(),
getHeaderRowColumn: jest.fn(),
render: jest.fn(),
+ sanitizeHtmlString: (str) => str,
} as unknown as SlickGrid;
+jest.useFakeTimers();
+
describe('CompoundDateFilter', () => {
let divContainer: HTMLDivElement;
let filter: CompoundDateFilter;
@@ -83,15 +90,17 @@ describe('CompoundDateFilter', () => {
mockColumn.filter!.placeholder = testValue;
filter.init(filterArguments);
- const filterElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
+ const filterElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
expect(filterElm.placeholder).toBe(testValue);
});
it('should hide the DOM element when the "hide" method is called', () => {
filter.init(filterArguments);
- const spy = jest.spyOn(filter.flatInstance, 'close');
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
+ const spy = jest.spyOn(filter.calendarInstance!, 'hide');
+ const inputElm = document.body.querySelector('input.date-picker') as HTMLInputElement;
+ inputElm.dispatchEvent(new MouseEvent('click'));
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
filter.hide();
expect(calendarElm).toBeTruthy();
@@ -100,44 +109,37 @@ describe('CompoundDateFilter', () => {
it('should show the DOM element when the "show" method is called', () => {
filter.init(filterArguments);
- const spy = jest.spyOn(filter.flatInstance, 'open');
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
+ const spy = jest.spyOn(filter.calendarInstance!, 'show');
filter.show();
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
expect(calendarElm).toBeTruthy();
expect(spy).toHaveBeenCalled();
});
- it('should enable Dark Mode and expect ".slick-dark-mode" CSS class to be found on parent element', () => {
- jest.spyOn(gridStub, 'getOptions').mockReturnValue({
- ...gridOptionMock, darkMode: true
- });
-
- filter.init(filterArguments);
- const spy = jest.spyOn(filter.flatInstance, 'open');
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
- filter.show();
-
- expect(calendarElm.classList.contains('slick-dark-mode')).toBeTruthy();
- expect(spy).toHaveBeenCalled();
- });
-
- it('should be able to retrieve default flatpickr options through the Getter', () => {
+ it('should be able to retrieve default picker options through the Getter', () => {
filter.init(filterArguments);
- expect(filter.flatInstance).toBeTruthy();
- expect(filter.flatpickrOptions).toEqual({
- altFormat: 'Y-m-d',
- altInput: true,
- closeOnSelect: true,
- dateFormat: 'Y-m-d',
- defaultDate: '',
- errorHandler: expect.toBeFunction(),
- locale: 'en',
- mode: 'single',
- onChange: expect.anything(),
- theme: 'light',
- wrap: true,
+ expect(filter.calendarInstance).toBeTruthy();
+ expect(filter.pickerOptions).toEqual({
+ actions: {
+ changeToInput: expect.any(Function),
+ clickDay: expect.any(Function),
+ },
+ input: true,
+ jumpToSelectedDate: true,
+ sanitizer: expect.any(Function),
+ toggleSelected: false,
+ settings: {
+ iso8601: false,
+ lang: 'en',
+ visibility: {
+ positionToInput: 'auto',
+ theme: 'light',
+ weekend: false,
+ },
+ },
+ type: 'default'
});
});
@@ -167,14 +169,14 @@ describe('CompoundDateFilter', () => {
});
it('should trigger input change event and expect the callback to be called with the date provided in the input', () => {
- mockColumn.filter!.filterOptions = { allowInput: true }; // change to allow input value only for testing purposes
mockColumn.filter!.operator = '>';
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
filterInputElm.value = '2001-01-02T16:02:02.239Z';
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2001-01-02'], hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2001-01-02'], hide: jest.fn() } as unknown as VanillaCalendar);
const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
@@ -183,15 +185,29 @@ describe('CompoundDateFilter', () => {
});
});
+ it('should trigger input change event with empty value and still expect the callback to be called with the date provided in the input', () => {
+ mockColumn.filter!.operator = '>';
+
+ filter.init(filterArguments);
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ filterInputElm.value = '2001-01-02T16:02:02.239Z';
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: [], hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: [], hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
+
+ expect(filterFilledElms.length).toBe(0);
+ expect(filterInputElm.value).toBe('');
+ });
+
it('should pass a different operator then trigger an input change event and expect the callback to be called with the date provided in the input', () => {
- mockColumn.filter!.filterOptions = { allowInput: true }; // change to allow input value only for testing purposes
mockColumn.filter!.operator = '>';
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
filterInputElm.value = '2001-01-02T16:02:02.239Z';
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2001-01-02'], hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2001-01-02'], hide: jest.fn() } as unknown as VanillaCalendar);
const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
@@ -199,12 +215,11 @@ describe('CompoundDateFilter', () => {
});
it('should change operator dropdown without a date entered and not expect the callback to be called', () => {
- mockColumn.filter!.filterOptions = { allowInput: true }; // change to allow input value only for testing purposes
mockColumn.filter!.operator = '>';
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
const filterSelectElm = divContainer.querySelector('.search-filter.filter-finish select') as HTMLInputElement;
filterInputElm.value = undefined as any;
filterSelectElm.value = '<=';
@@ -214,13 +229,12 @@ describe('CompoundDateFilter', () => {
});
it('should change operator dropdown without a date entered and expect the callback to be called when "skipCompoundOperatorFilterWithNullInput" is defined as False', () => {
- mockColumn.filter!.filterOptions = { allowInput: true }; // change to allow input value only for testing purposes
mockColumn.filter!.operator = '>';
mockColumn.filter!.skipCompoundOperatorFilterWithNullInput = false;
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
const filterSelectElm = divContainer.querySelector('.search-filter.filter-finish select') as HTMLInputElement;
filterInputElm.value = undefined as any;
filterSelectElm.value = '<=';
@@ -229,24 +243,111 @@ describe('CompoundDateFilter', () => {
expect(spyCallback).toHaveBeenCalled();
});
- it('should create the input filter with a default search term when passed as a filter argument', () => {
+ it('should hide picker when pressing Escape key', () => {
+ const hideSpy = jest.spyOn(filter, 'hide');
+
+ filter.init(filterArguments);
+ filter.show();
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
+
+ expect(calendarElm).toBeTruthy();
+
+ calendarElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { key: 'Escape', bubbles: true, cancelable: true }));
+ expect(hideSpy).toHaveBeenCalled();
+ });
+
+ it('should hide picker when pressing Tab key', () => {
+ const hideSpy = jest.spyOn(filter, 'hide');
+
+ filter.init(filterArguments);
+ filter.show();
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
+
+ expect(calendarElm).toBeTruthy();
+
+ calendarElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { key: 'Tab', bubbles: true, cancelable: true }));
+ expect(hideSpy).toHaveBeenCalled();
+ });
+
+ it('should clear picker when pressing Backspace key', () => {
+ filterArguments.searchTerms = ['2000-01-01'];
+ mockColumn.filter!.operator = '<=';
+ const clearSpy = jest.spyOn(filter, 'clear');
+
+ filter.init(filterArguments);
+ filter.show();
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
+
+ expect(calendarElm).toBeTruthy();
+ expect(filterInputElm.value).toBe('2000-01-01');
+
+ filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { key: 'Backspace', bubbles: true, cancelable: true }));
+ expect(clearSpy).toHaveBeenCalled();
+ expect(filterInputElm.value).toBe('');
+ });
+
+ it('should create the input filter with a default search terms when passed as a filter argument', () => {
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
mockColumn.filter!.operator = '<=';
+ mockColumn.type = FieldType.dateUtc;
+ mockColumn.outputType = FieldType.dateUtc;
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
filterInputElm.focus();
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2000-01-01T05:00:00.000Z'], hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2000-01-01T05:00:00.000Z'], hide: jest.fn() } as unknown as VanillaCalendar);
const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- expect(filter.currentDateOrDates).toBe('2000-01-01T05:00:00.000Z');
- expect(filterInputElm.value).toBe('2000-01-01');
+ expect(filter.currentDateOrDates![0].toISOString()).toBe('2000-01-01T05:00:00.000Z');
+ expect(filterInputElm.value).toBe('2000-01-01T05:00:00.000Z');
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01T05:00:00.000Z'], shouldTriggerQuery: true });
});
+ it('should create the input filter with a default input dates when passed as a filter options', () => {
+ mockColumn.filter!.operator = '<=';
+ mockColumn.filter!.filterOptions = {
+ selected: { dates: ['2001-01-02'] }
+ };
+ const spyCallback = jest.spyOn(filterArguments, 'callback');
+
+ filter.init(filterArguments);
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+
+ filterInputElm.focus();
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2000-01-02'], hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
+
+ expect(filterFilledElms.length).toBe(1);
+ expect(format(filter.currentDateOrDates![0], mapTempoDateFormatWithFieldType(FieldType.dateTimeIso))).toBe('2000-01-02 00:00:00');
+ expect(filterInputElm.value).toBe('2000-01-02');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-02'], shouldTriggerQuery: true });
+ });
+
+ it('should have a value with date & time in the picker when "enableTime" option is set as a global default filter option and we trigger a change', () => {
+ gridOptionMock.defaultFilterOptions = {
+ date: { selected: { dates: ['2001-01-02'] } }
+ };
+ mockColumn.filter!.operator = '<=';
+ const spyCallback = jest.spyOn(filterArguments, 'callback');
+
+ filter.init(filterArguments);
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+
+ filterInputElm.focus();
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2000-01-02'], hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
+
+ expect(filterFilledElms.length).toBe(1);
+ expect(format(filter.currentDateOrDates![0], mapTempoDateFormatWithFieldType(FieldType.dateTimeIso))).toBe('2000-01-02 00:00:00');
+ expect(filterInputElm.value).toBe('2000-01-02');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-02'], shouldTriggerQuery: true });
+ });
+
it('should trigger an operator change event and expect the callback to be called with the searchTerms and operator defined', () => {
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
mockColumn.filter!.operator = '>';
@@ -267,67 +368,45 @@ describe('CompoundDateFilter', () => {
const mockDate = '2001-01-02T16:02:02.239Z';
filter.init(filterArguments);
filter.setValues(mockDate);
- let filledInputElm = divContainer.querySelector('.search-filter.filter-finish .filled') as HTMLInputElement;
+ let filledInputElm = divContainer.querySelector('.search-filter.filter-finish.filled') as HTMLInputElement;
expect(filter.currentDateOrDates).toEqual(mockDate);
expect(filledInputElm).toBeTruthy();
filter.setValues('');
- filledInputElm = divContainer.querySelector('.search-filter.filter-finish .filled') as HTMLInputElement;
+ filledInputElm = divContainer.querySelector('.search-filter.filter-finish.filled') as HTMLInputElement;
expect(filledInputElm).toBeFalsy();
});
it('should work with different locale when locale is changed', async () => {
- await (await import('flatpickr/dist/l10n/fr')).French;
-
translateService.use('fr');
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
mockColumn.filter!.operator = '<=';
+ mockColumn.type = FieldType.dateUtc;
+ mockColumn.outputType = FieldType.dateUtc;
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
- const selectonOptionElms = calendarElm.querySelectorAll(' .flatpickr-monthDropdown-months option');
+ filter.show();
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
+ const monthElm = calendarElm.querySelector('.vanilla-calendar-month') as HTMLButtonElement;
filter.show();
filterInputElm.focus();
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
+
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2000-01-01T05:00:00.000Z'], hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2000-01-01T05:00:00.000Z'], hide: jest.fn() } as unknown as VanillaCalendar);
const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- expect(filter.currentDateOrDates).toBe('2000-01-01T05:00:00.000Z');
- expect(filterInputElm.value).toBe('2000-01-01');
+ expect(filter.currentDateOrDates![0].toISOString()).toBe('2000-01-01T05:00:00.000Z');
+ expect(filterInputElm.value).toBe('2000-01-01T05:00:00.000Z');
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01T05:00:00.000Z'], shouldTriggerQuery: true });
expect(calendarElm).toBeTruthy();
- expect(selectonOptionElms.length).toBe(12);
- expect(selectonOptionElms[0].textContent).toBe('janvier');
- });
-
- it('should display a console warning when locale is not previously imported', (done) => {
- const consoleSpy = jest.spyOn(global.console, 'warn').mockReturnValue();
-
- translateService.use('zz-yy'); // will be trimmed to 2 chars "zz"
- filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
- mockColumn.filter!.operator = '<=';
-
- filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
- const selectonOptionElms = calendarElm.querySelectorAll(' .flatpickr-monthDropdown-months option');
-
- filter.show();
-
- filterInputElm.focus();
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
-
- setTimeout(() => {
- expect(selectonOptionElms.length).toBe(12);
- expect(selectonOptionElms[0].textContent).toBe('January');
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(`[Slickgrid-Universal] Flatpickr missing locale imports (zz), will revert to English as the default locale.`));
- done();
- });
+ expect(monthElm).toBeTruthy();
+ // expect(monthElm.textContent).toBe('janvier');
});
it('should trigger a callback with the clear filter set when calling the "clear" method', () => {
@@ -335,13 +414,14 @@ describe('CompoundDateFilter', () => {
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
+ filter.show();
filter.clear();
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
expect(filterInputElm.value).toBe('');
expect(filterFilledElms.length).toBe(0);
- expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, clearFilterTriggered: true, shouldTriggerQuery: true });
+ expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, clearFilterTriggered: true, shouldTriggerQuery: true });
});
it('should trigger a callback with the clear filter but without querying when when calling the "clear" method with False as argument', () => {
@@ -350,71 +430,48 @@ describe('CompoundDateFilter', () => {
filter.init(filterArguments);
filter.clear(false);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
expect(filterInputElm.value).toBe('');
expect(filterFilledElms.length).toBe(0);
- expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, clearFilterTriggered: true, shouldTriggerQuery: false });
+ expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, clearFilterTriggered: true, shouldTriggerQuery: false });
});
it('should have a value with date & time in the picker when "enableTime" option is set and we trigger a change', () => {
- mockColumn.filter!.filterOptions = { enableTime: true, allowInput: true }; // change to allow input value only for testing purposes
- mockColumn.outputType = FieldType.dateTimeIsoAmPm;
+ mockColumn.outputType = FieldType.dateTimeShortEuro;
mockColumn.filter!.operator = '>';
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
- filterInputElm.value = '2001-01-02T16:02:02.000+05:00';
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ filterInputElm.value = '2001-01-02T16:02:00.000Z';
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2001-01-02'], hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2001-01-02'], selectedHours: 16, selectedMinutes: 2, hide: jest.fn() } as unknown as VanillaCalendar);
const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- // expect(filter.currentDateOrDates.toISOString()).toBe('2001-01-02T21:02:02.000Z');
- expect(filterInputElm.value).toBe('2001-01-02 4:02:02 PM');
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), {
- columnDef: mockColumn, operator: '>', searchTerms: ['2001-01-02'], shouldTriggerQuery: true
- });
- });
-
- it('should have a value with date & time in the picker when "enableTime" option is set as a global default filter option and we trigger a change', () => {
- gridOptionMock.defaultFilterOptions = {
- date: { enableTime: true, allowInput: true }
- };
- mockColumn.outputType = FieldType.dateTimeIsoAmPm;
- mockColumn.filter!.operator = '>';
- const spyCallback = jest.spyOn(filterArguments, 'callback');
-
- filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
- filterInputElm.value = '2001-01-02T16:02:02.000+05:00';
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
- const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
-
- expect(filterFilledElms.length).toBe(1);
- // expect(filter.currentDateOrDates.toISOString()).toBe('2001-01-02T21:02:02.000Z');
- expect(filterInputElm.value).toBe('2001-01-02 4:02:02 PM');
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), {
- columnDef: mockColumn, operator: '>', searchTerms: ['2001-01-02'], shouldTriggerQuery: true
- });
+ expect(filterInputElm.value).toBe('2/1/2001 16:02');
+ expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '>', searchTerms: ['2001-01-02'], shouldTriggerQuery: true });
});
it('should have a value with date & time in the picker when using no "outputType" which will default to UTC date', () => {
+ mockColumn.type = FieldType.dateUtc;
mockColumn.outputType = null as any;
- filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
+ filterArguments.searchTerms = ['2000-01-01T05:00'];
mockColumn.filter!.operator = '<=';
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.search-filter.filter-finish .flatpickr input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
filterInputElm.focus();
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2000-01-01'], hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: ['2000-01-01'], hide: jest.fn() } as unknown as VanillaCalendar);
const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- expect(filter.currentDateOrDates).toBe('2000-01-01T05:00:00.000Z');
+ expect(filter.currentDateOrDates![0].toISOString()).toBe('2000-01-01T05:00:00.000Z');
expect(filterInputElm.value).toBe('2000-01-01T05:00:00.000Z');
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01T05:00:00.000Z'], shouldTriggerQuery: true });
});
diff --git a/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts b/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts
index ddc728a8b..4035d0ec2 100644
--- a/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts
+++ b/packages/common/src/filters/__tests__/dateRangeFilter.spec.ts
@@ -1,4 +1,6 @@
import 'jest-extended';
+import { VanillaCalendar } from 'vanilla-calendar-picker';
+
import { FieldType } from '../../enums/index';
import { Column, FilterArguments, GridOption } from '../../interfaces/index';
import { Filters } from '../filters.index';
@@ -21,6 +23,7 @@ const gridStub = {
getColumns: jest.fn(),
getHeaderRowColumn: jest.fn(),
render: jest.fn(),
+ sanitizeHtmlString: (str) => str,
} as unknown as SlickGrid;
describe('DateRangeFilter', () => {
@@ -39,7 +42,7 @@ describe('DateRangeFilter', () => {
document.body.appendChild(divContainer);
spyGetHeaderRow = jest.spyOn(gridStub, 'getHeaderRowColumn').mockReturnValue(divContainer);
- mockColumn = { id: 'finish', field: 'finish', filterable: true, filter: { model: Filters.dateRange, operator: 'RangeInclusive' } };
+ mockColumn = { id: 'finish', field: 'finish', type: FieldType.dateIso, filterable: true, filter: { model: Filters.dateRange, operator: 'RangeInclusive' } };
filterArguments = {
grid: gridStub,
columnDef: mockColumn,
@@ -64,7 +67,7 @@ describe('DateRangeFilter', () => {
it('should initialize the filter', () => {
filter.init(filterArguments);
- const filterCount = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish').length;
+ const filterCount = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish').length;
expect(spyGetHeaderRow).toHaveBeenCalled();
expect(filterCount).toBe(1);
@@ -75,15 +78,17 @@ describe('DateRangeFilter', () => {
mockColumn.filter!.placeholder = testValue;
filter.init(filterArguments);
- const filterElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input') as HTMLInputElement;
+ const filterElm = divContainer.querySelector('.date-picker.search-filter.filter-finish input') as HTMLInputElement;
expect(filterElm.placeholder).toBe(testValue);
});
it('should hide the DOM element when the "hide" method is called', () => {
filter.init(filterArguments);
- const spy = jest.spyOn(filter.flatInstance, 'close');
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
+ const spy = jest.spyOn(filter.calendarInstance!, 'hide');
+ const inputElm = document.body.querySelector('input.date-picker') as HTMLInputElement;
+ inputElm.dispatchEvent(new MouseEvent('click'));
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
filter.hide();
expect(calendarElm).toBeTruthy();
@@ -92,31 +97,42 @@ describe('DateRangeFilter', () => {
it('should show the DOM element when the "show" method is called', () => {
filter.init(filterArguments);
- const spy = jest.spyOn(filter.flatInstance, 'open');
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
+ const spy = jest.spyOn(filter.calendarInstance!, 'show');
filter.show();
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
expect(calendarElm).toBeTruthy();
expect(spy).toHaveBeenCalled();
});
- it('should be able to retrieve default flatpickr options through the Getter', () => {
+ it('should be able to retrieve default date picker options through the Getter', () => {
filter.init(filterArguments);
- expect(filter.flatInstance).toBeTruthy();
- expect(filter.flatpickrOptions).toEqual({
- altFormat: 'Z',
- altInput: true,
- closeOnSelect: true,
- dateFormat: 'Y-m-d',
- defaultDate: [],
- enableTime: true,
- errorHandler: expect.toBeFunction(),
- locale: 'en',
- mode: 'range',
- onChange: expect.anything(),
- theme: 'light',
- wrap: true,
+ expect(filter.calendarInstance).toBeTruthy();
+ expect(filter.pickerOptions).toEqual({
+ actions: {
+ changeToInput: expect.any(Function),
+ clickDay: expect.any(Function),
+ },
+ input: true,
+ jumpMonths: 2,
+ jumpToSelectedDate: true,
+ months: 2,
+ sanitizer: expect.any(Function),
+ settings: {
+ iso8601: false,
+ lang: 'en',
+ range: { edgesOnly: true },
+ selection: { day: 'multiple-ranged', },
+ visibility: {
+ daysOutside: false,
+ positionToInput: 'auto',
+ theme: 'light',
+ weekend: false,
+ },
+ },
+ toggleSelected: false,
+ type: 'multiple'
});
});
@@ -135,73 +151,92 @@ describe('DateRangeFilter', () => {
});
it('should trigger input change event and expect the callback to be called with the date provided in the input', () => {
- mockColumn.filter!.filterOptions = { allowInput: true }; // change to allow input value only for testing purposes
mockColumn.filter!.operator = 'RangeInclusive';
const spyCallback = jest.spyOn(filterArguments, 'callback');
+ const selectedDates = ['2001-01-02', '2001-01-13'];
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
- filterInputElm.value = '2001-01-02T16:02:02.239Z to 2001-01-31T16:02:02.239Z';
- filterInputElm.dispatchEvent(new CustomEvent('change'));
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ const filterInputElm = divContainer.querySelector('div.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2001-01-02', '2001-01-31'], shouldTriggerQuery: true });
+ expect(filterInputElm.value).toBe('2001-01-02 — 2001-01-13');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2001-01-02', '2001-01-13'], shouldTriggerQuery: true });
+ });
+
+ it('should trigger input change event with empty value and still expect the callback to be called with the date provided in the input', () => {
+ mockColumn.filter!.operator = 'RangeInclusive';
+
+ filter.init(filterArguments);
+ const filterInputElm = divContainer.querySelector('.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ filterInputElm.value = '2001-01-02T16:02:02.239Z';
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates: [], hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new Event('click'), { HTMLInputElement: filterInputElm, selectedDates: [], hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.form-group.search-filter.filter-finish.filled');
+
+ expect(filterFilledElms.length).toBe(0);
+ expect(filterInputElm.value).toBe('');
});
it('should pass a different operator then trigger an input change event and expect the callback to be called with the date provided in the input', () => {
- mockColumn.filter!.filterOptions = { allowInput: true, enableTime: false }; // change to allow input value only for testing purposes
mockColumn.filter!.operator = 'RangeExclusive';
const spyCallback = jest.spyOn(filterArguments, 'callback');
+ const selectedDates = ['2001-01-02', '2001-01-13'];
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
- filterInputElm.value = '2001-01-02T16:02:02.239Z to 2001-01-31T16:02:02.239Z';
- filterInputElm.dispatchEvent(new CustomEvent('change'));
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ const filterInputElm = divContainer.querySelector('.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'RangeExclusive', searchTerms: ['2001-01-02', '2001-01-31'], shouldTriggerQuery: true });
+ expect(filterInputElm.value).toBe('2001-01-02 — 2001-01-13');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, operator: 'RangeExclusive', searchTerms: ['2001-01-02', '2001-01-13'], shouldTriggerQuery: true });
});
- it('should create the input filter with a default search term when passed as a filter argument', () => {
- filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z'];
+ it('should create the input filter with a default search terms when passed as a filter argument', () => {
+ const selectedDates = ['2001-01-02', '2001-01-13'];
+ filterArguments.searchTerms = ['2001-01-02', '2001-01-13'];
mockColumn.filter!.operator = 'RangeInclusive';
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
filterInputElm.focus();
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- expect(filterInputElm.value).toBe('2000-01-01T05:00:00.000Z to 2000-01-31T05:00:00.000Z');
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2000-01-01', '2000-01-31'], shouldTriggerQuery: true });
+ expect(filterInputElm.value).toBe('2001-01-02 — 2001-01-13');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2001-01-02', '2001-01-13'], shouldTriggerQuery: true });
});
it('should create the input filter with a default search term when passed as a filter argument with 2 dots (..) notation', () => {
- filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z..2000-01-31T05:00:00.000Z'];
+ const selectedDates = ['2001-01-01', '2001-01-02', '2001-01-03'];
+ filterArguments.searchTerms = ['2001-01-01..2001-01-03'];
mockColumn.filter!.operator = 'RangeInclusive';
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
filterInputElm.focus();
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- expect(filterInputElm.value).toBe('2000-01-01T05:00:00.000Z to 2000-01-31T05:00:00.000Z');
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2000-01-01', '2000-01-31'], shouldTriggerQuery: true });
+ expect(filterInputElm.value).toBe('2001-01-01 — 2001-01-03');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2001-01-01', '2001-01-03'], shouldTriggerQuery: true });
});
it('should be able to call "setValues" and set empty values and the picker input to not have the "filled" css class', () => {
- const mockDates = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z'];
+ const mockDates = ['2001-01-02T05:00:00.000Z', '2001-01-13T05:00:00.000Z'];
filter.init(filterArguments);
filter.setValues(mockDates);
let filledInputElm = divContainer.querySelector('.search-filter.filter-finish.filled') as HTMLInputElement;
@@ -215,65 +250,41 @@ describe('DateRangeFilter', () => {
});
it('should work with different locale when locale is changed', async () => {
- await (await import('flatpickr/dist/l10n/fr')).French;
-
translateService.use('fr');
- filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z'];
+ const selectedDates = ['2001-01-01', '2001-01-02', '2001-01-03'];
+ filterArguments.searchTerms = ['2001-01-01', '2001-01-03'];
mockColumn.filter!.operator = 'RangeInclusive';
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
- const selectonOptionElms = calendarElm.querySelectorAll(' .flatpickr-monthDropdown-months option');
+ filter.show();
+ const filterInputElm = divContainer.querySelector('.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ const calendarElm = document.body.querySelector('.vanilla-calendar') as HTMLDivElement;
+ const monthElm = calendarElm.querySelector('.vanilla-calendar-month') as HTMLButtonElement;
filter.show();
filterInputElm.focus();
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- expect(filterInputElm.value).toBe('2000-01-01T05:00:00.000Z au 2000-01-31T05:00:00.000Z');
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2000-01-01', '2000-01-31'], shouldTriggerQuery: true });
+ expect(filterInputElm.value).toBe('2001-01-01 — 2001-01-03');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2001-01-01', '2001-01-03'], shouldTriggerQuery: true });
expect(calendarElm).toBeTruthy();
- expect(selectonOptionElms.length).toBe(12);
- expect(selectonOptionElms[0].textContent).toBe('janvier');
- });
-
- it('should display a console warning when locale is not previously imported', (done) => {
- const consoleSpy = jest.spyOn(global.console, 'warn').mockReturnValue();
-
- translateService.use('zz-yy'); // will be trimmed to 2 chars "zz"
- filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z'];
- mockColumn.filter!.operator = 'RangeInclusive';
-
- filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
- const calendarElm = document.body.querySelector('.flatpickr-calendar') as HTMLDivElement;
- const selectonOptionElms = calendarElm.querySelectorAll(' .flatpickr-monthDropdown-months option');
-
- filter.show();
-
- filterInputElm.focus();
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
-
- setTimeout(() => {
- expect(selectonOptionElms.length).toBe(12);
- expect(selectonOptionElms[0].textContent).toBe('January');
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(`[Slickgrid-Universal] Flatpickr missing locale imports (zz), will revert to English as the default locale.`));
- done();
- });
+ expect(monthElm).toBeTruthy();
+ // expect(monthElm.textContent).toBe('janvier');
});
it('should trigger a callback with the clear filter set when calling the "clear" method', () => {
- filterArguments.searchTerms = ['2000-01-01', '2000-01-31'];
+ filterArguments.searchTerms = ['2001-01-01', '2001-01-03'];
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
filter.clear();
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ const filterInputElm = divContainer.querySelector('.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterInputElm.value).toBe('');
expect(filterFilledElms.length).toBe(0);
@@ -281,13 +292,13 @@ describe('DateRangeFilter', () => {
});
it('should trigger a callback with the clear filter but without querying when when calling the "clear" method with False as argument', () => {
- filterArguments.searchTerms = ['2000-01-01', '2000-01-31'];
+ filterArguments.searchTerms = ['2001-01-01', '2001-01-31'];
const spyCallback = jest.spyOn(filterArguments, 'callback');
filter.init(filterArguments);
filter.clear(false);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ const filterInputElm = divContainer.querySelector('.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterInputElm.value).toBe('');
expect(filterFilledElms.length).toBe(0);
@@ -295,44 +306,47 @@ describe('DateRangeFilter', () => {
});
it('should have a value with date & time in the picker when "enableTime" option is set and we trigger a change', () => {
- mockColumn.filter!.filterOptions = { enableTime: true, allowInput: true }; // change to allow input value only for testing purposes
mockColumn.outputType = FieldType.dateTimeIsoAmPm;
mockColumn.filter!.operator = '>';
const spyCallback = jest.spyOn(filterArguments, 'callback');
+ const selectedDates = ['2001-01-02', '2001-01-13'];
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
- filterInputElm.value = '2000-01-01T05:00:00.000+05:00 to 2000-01-31T05:00:00.000+05:00';
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ const filterInputElm = divContainer.querySelector('.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ filterInputElm.value = '2001-01-02 — 2001-01-13';
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- // expect(filter.currentDateOrDates.map((date) => date.toISOString())).toEqual(['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z']);
- expect(filterInputElm.value).toBe('2000-01-01 5:00:00 AM to 2000-01-31 5:00:00 AM');
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), {
- columnDef: mockColumn, operator: '>', searchTerms: ['2000-01-01 05:00:00 am', '2000-01-31 05:00:00 am'], shouldTriggerQuery: true
+ // expect(filter.currentDateOrDates.map((date) => date.toISOString())).toEqual(['2001-01-01T05:00:00.000Z', '2001-01-31T05:00:00.000Z']);
+ expect(filterInputElm.value).toBe('2001-01-02 12:00:00 am — 2001-01-13 12:00:00 am');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, {
+ columnDef: mockColumn, operator: '>', searchTerms: ['2001-01-02', '2001-01-13'], shouldTriggerQuery: true
});
});
it('should have a value with date & time in the picker when "enableTime" option is set as a global default filter option and we trigger a change', () => {
gridOptionMock.defaultFilterOptions = {
- date: { enableTime: true, allowInput: true }
};
mockColumn.outputType = FieldType.dateTimeIsoAmPm;
mockColumn.filter!.operator = '>';
const spyCallback = jest.spyOn(filterArguments, 'callback');
+ const selectedDates = ['2001-01-02', '2001-01-13'];
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.input') as HTMLInputElement;
- filterInputElm.value = '2000-01-01T05:00:00.000+05:00 to 2000-01-31T05:00:00.000+05:00';
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ const filterInputElm = divContainer.querySelector('div.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
+ filterInputElm.value = '2001-01-02 — 2001-01-13';
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
// expect(filter.currentDateOrDates.map((date) => date.toISOString())).toEqual(['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z']);
- expect(filterInputElm.value).toBe('2000-01-01 5:00:00 AM to 2000-01-31 5:00:00 AM');
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), {
- columnDef: mockColumn, operator: '>', searchTerms: ['2000-01-01 05:00:00 am', '2000-01-31 05:00:00 am'], shouldTriggerQuery: true
+ expect(filterInputElm.value).toBe('2001-01-02 12:00:00 am — 2001-01-13 12:00:00 am');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, {
+ columnDef: mockColumn, operator: '>', searchTerms: ['2001-01-02', '2001-01-13'], shouldTriggerQuery: true
});
});
@@ -341,17 +355,19 @@ describe('DateRangeFilter', () => {
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z'];
mockColumn.filter!.operator = '<=';
const spyCallback = jest.spyOn(filterArguments, 'callback');
+ const selectedDates = ['2001-01-02', '2001-01-13'];
filter.init(filterArguments);
- const filterInputElm = divContainer.querySelector('.flatpickr.search-filter.filter-finish input.flatpickr-input') as HTMLInputElement;
+ const filterInputElm = divContainer.querySelector('div.date-picker.search-filter.filter-finish input.date-picker') as HTMLInputElement;
filterInputElm.focus();
- filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));
- const filterFilledElms = divContainer.querySelectorAll('.flatpickr.search-filter.filter-finish.filled');
+ filterInputElm.value = '2001-01-02 — 2001-01-13';
+ filter.calendarInstance!.actions!.changeToInput!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ filter.calendarInstance!.actions!.clickDay!(new MouseEvent('click'), { HTMLInputElement: filterInputElm, selectedDates, hide: jest.fn() } as unknown as VanillaCalendar);
+ const filterFilledElms = divContainer.querySelectorAll('.date-picker.search-filter.filter-finish.filled');
expect(filterFilledElms.length).toBe(1);
- expect(filter.currentDateOrDates).toEqual(['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z']);
- expect(filterInputElm.value).toBe('2000-01-01 to 2000-01-31');
- expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01', '2000-01-31'], shouldTriggerQuery: true });
+ expect(filterInputElm.value).toBe('2001-01-02 — 2001-01-13');
+ expect(spyCallback).toHaveBeenCalledWith(undefined, { columnDef: mockColumn, operator: '<=', searchTerms: ['2001-01-02', '2001-01-13'], shouldTriggerQuery: true });
});
});
diff --git a/packages/common/src/filters/__tests__/nativeSelectFilter.spec.ts b/packages/common/src/filters/__tests__/nativeSelectFilter.spec.ts
deleted file mode 100644
index 5f936f839..000000000
--- a/packages/common/src/filters/__tests__/nativeSelectFilter.spec.ts
+++ /dev/null
@@ -1,420 +0,0 @@
-import { Column, FilterArguments, GridOption } from '../../interfaces/index';
-import { Filters } from '../filters.index';
-import { NativeSelectFilter } from '../nativeSelectFilter';
-import { TranslateServiceStub } from '../../../../../test/translateServiceStub';
-import { SlickGrid } from '../../core/index';
-
-jest.useFakeTimers();
-
-const containerId = 'demo-container';
-
-// define a