diff --git a/packages/checkbox-group/README.md b/packages/checkbox-group/README.md
index 5584c8c29..0cd5d842b 100644
--- a/packages/checkbox-group/README.md
+++ b/packages/checkbox-group/README.md
@@ -11,6 +11,7 @@ Its purpose is to provide a way for users to check **multiple** options amongst
import { html } from '@lion/core';
import { Required, Validator } from '@lion/form-core';
import './lion-checkbox-group.js';
+import './lion-checkbox-indeterminate.js';
import './lion-checkbox.js';
export default {
@@ -166,3 +167,17 @@ export const event = () => html`
Selected scientists: N/A
`;
```
+
+### Indeterminate
+
+```js preview-story
+export const indeterminate = () => html`
+
+
+
+
+
+
+
+`;
+```
diff --git a/packages/checkbox-group/index.js b/packages/checkbox-group/index.js
index 6f20e3181..c07ad86a5 100644
--- a/packages/checkbox-group/index.js
+++ b/packages/checkbox-group/index.js
@@ -1,2 +1,3 @@
export { LionCheckboxGroup } from './src/LionCheckboxGroup.js';
+export { LionCheckboxIndeterminate } from './src/LionCheckboxIndeterminate.js';
export { LionCheckbox } from './src/LionCheckbox.js';
diff --git a/packages/checkbox-group/lion-checkbox-indeterminate.js b/packages/checkbox-group/lion-checkbox-indeterminate.js
new file mode 100644
index 000000000..37b65d36b
--- /dev/null
+++ b/packages/checkbox-group/lion-checkbox-indeterminate.js
@@ -0,0 +1,3 @@
+import { LionCheckboxIndeterminate } from './src/LionCheckboxIndeterminate.js';
+
+customElements.define('lion-checkbox-indeterminate', LionCheckboxIndeterminate);
diff --git a/packages/checkbox-group/package.json b/packages/checkbox-group/package.json
index 044b29017..8e6bfa78d 100644
--- a/packages/checkbox-group/package.json
+++ b/packages/checkbox-group/package.json
@@ -31,7 +31,8 @@
},
"sideEffects": [
"lion-checkbox.js",
- "lion-checkbox-group.js"
+ "lion-checkbox-group.js",
+ "lion-checkbox-indeterminate.js"
],
"dependencies": {
"@lion/core": "0.13.8",
diff --git a/packages/checkbox-group/src/LionCheckboxIndeterminate.js b/packages/checkbox-group/src/LionCheckboxIndeterminate.js
new file mode 100644
index 000000000..a164ec8c4
--- /dev/null
+++ b/packages/checkbox-group/src/LionCheckboxIndeterminate.js
@@ -0,0 +1,91 @@
+import { LionCheckbox } from './LionCheckbox.js';
+
+export class LionCheckboxIndeterminate extends LionCheckbox {
+ static get properties() {
+ return {
+ /**
+ * Indeterminate state of the checkbox
+ */
+ indeterminate: {
+ type: Boolean,
+ reflect: true,
+ },
+ };
+ }
+
+ get _checkboxGroupNode() {
+ return /** @type {import('./LionCheckboxGroup').LionCheckboxGroup} */ (this.parentElement);
+ }
+
+ get _subCheckboxes() {
+ return this._checkboxGroupNode.formElements.filter(checkbox => checkbox !== this);
+ }
+
+ _parentModelValueChanged() {
+ const checkedElements = this._subCheckboxes.filter(checkbox => checkbox.checked);
+ switch (this._subCheckboxes.length - checkedElements.length) {
+ // all checked
+ case 0:
+ this.indeterminate = false;
+ this.checked = true;
+ break;
+ // none checked
+ case this._subCheckboxes.length:
+ this.indeterminate = false;
+ this.checked = false;
+ break;
+ default:
+ this.indeterminate = true;
+ }
+ }
+
+ _ownModelValueChanged(ev) {
+ if (ev.target === this) {
+ this._subCheckboxes.forEach(checkbox => {
+ // eslint-disable-next-line no-param-reassign
+ checkbox.checked = this.checked;
+ });
+ }
+ }
+
+ constructor() {
+ super();
+ this.indeterminate = false;
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ this._checkboxGroupNode.addEventListener(
+ 'model-value-changed',
+ this._parentModelValueChanged.bind(this),
+ );
+ this.addEventListener('model-value-changed', this._ownModelValueChanged);
+ }
+
+ /** @param {import('lit-element').PropertyValues } changedProperties */
+ updated(changedProperties) {
+ super.updated(changedProperties);
+ if (changedProperties.has('indeterminate')) {
+ this._inputNode.indeterminate = this.indeterminate;
+ }
+ }
+
+ /**
+ * @override
+ * clicking on indeterminate status will set the status as checked
+ */
+ __toggleChecked() {
+ if (this.disabled) {
+ return;
+ }
+
+ // always turn off indeterminate
+ // and set checked to true
+ if (this.indeterminate) {
+ this.indeterminate = false;
+ this.checked = true;
+ } else {
+ this.checked = !this.checked;
+ }
+ }
+}