@@ -15,8 +15,6 @@ import {when} from 'lit/directives/when.js';
1515import { ARIAMixinStrict } from '../../aria/aria.js' ;
1616import { requestUpdateOnAriaChange } from '../../aria/delegate.js' ;
1717import { dispatchActivationClick , isActivationClick , redispatchEvent } from '../../controller/events.js' ;
18- import { FormController , getFormValue } from '../../controller/form-controller.js' ;
19- import { stringConverter } from '../../controller/string-converter.js' ;
2018import { ripple } from '../../ripple/directive.js' ;
2119import { MdRipple } from '../../ripple/ripple.js' ;
2220
@@ -28,15 +26,13 @@ export class Checkbox extends LitElement {
2826 requestUpdateOnAriaChange ( this ) ;
2927 }
3028
31- /**
32- * @nocollapse
33- */
29+ /** @nocollapse */
3430 static formAssociated = true ;
3531
3632 /**
3733 * Whether or not the checkbox is selected.
3834 */
39- @property ( { type : Boolean , reflect : true } ) checked = false ;
35+ @property ( { type : Boolean } ) checked = false ;
4036
4137 /**
4238 * Whether or not the checkbox is disabled.
@@ -46,14 +42,14 @@ export class Checkbox extends LitElement {
4642 /**
4743 * Whether or not the checkbox is invalid.
4844 */
49- @property ( { type : Boolean , reflect : true } ) error = false ;
45+ @property ( { type : Boolean } ) error = false ;
5046
5147 /**
5248 * Whether or not the checkbox is indeterminate.
5349 *
5450 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#indeterminate_state_checkboxes
5551 */
56- @property ( { type : Boolean , reflect : true } ) indeterminate = false ;
52+ @property ( { type : Boolean } ) indeterminate = false ;
5753
5854 /**
5955 * The value of the checkbox that is submitted with a form when selected.
@@ -65,13 +61,25 @@ export class Checkbox extends LitElement {
6561 /**
6662 * The HTML name to use in form submission.
6763 */
68- @property ( { reflect : true , converter : stringConverter } ) name = '' ;
64+ get name ( ) {
65+ return this . getAttribute ( 'name' ) ?? '' ;
66+ }
67+ set name ( name : string ) {
68+ this . setAttribute ( 'name' , name ) ;
69+ }
6970
7071 /**
7172 * The associated form element with which this element's value will submit.
7273 */
7374 get form ( ) {
74- return this . closest ( 'form' ) ;
75+ return this . internals . form ;
76+ }
77+
78+ /**
79+ * The labels this element is associated with.
80+ */
81+ get labels ( ) {
82+ return this . internals . labels ;
7583 }
7684
7785 @state ( ) private prevChecked = false ;
@@ -80,10 +88,11 @@ export class Checkbox extends LitElement {
8088 @queryAsync ( 'md-ripple' ) private readonly ripple ! : Promise < MdRipple | null > ;
8189 @query ( 'input' ) private readonly input ! : HTMLInputElement | null ;
8290 @state ( ) private showRipple = false ;
91+ private readonly internals =
92+ ( this as HTMLElement /* needed for closure */ ) . attachInternals ( ) ;
8393
8494 constructor ( ) {
8595 super ( ) ;
86- this . addController ( new FormController ( this ) ) ;
8796 if ( ! isServer ) {
8897 this . addEventListener ( 'click' , ( event : MouseEvent ) => {
8998 if ( ! isActivationClick ( event ) ) {
@@ -99,10 +108,6 @@ export class Checkbox extends LitElement {
99108 this . input ?. focus ( ) ;
100109 }
101110
102- [ getFormValue ] ( ) {
103- return this . checked ? this . value : null ;
104- }
105-
106111 protected override update ( changed : PropertyValues < Checkbox > ) {
107112 if ( changed . has ( 'checked' ) || changed . has ( 'disabled' ) ||
108113 changed . has ( 'indeterminate' ) ) {
@@ -112,6 +117,9 @@ export class Checkbox extends LitElement {
112117 changed . get ( 'indeterminate' ) ?? this . indeterminate ;
113118 }
114119
120+ const shouldAddFormValue = this . checked && ! this . indeterminate ;
121+ const state = String ( this . checked ) ;
122+ this . internals . setFormValue ( shouldAddFormValue ? this . value : null , state ) ;
115123 super . update ( changed ) ;
116124 }
117125
@@ -176,4 +184,16 @@ export class Checkbox extends LitElement {
176184 private readonly renderRipple = ( ) => { // bind to this
177185 return html `< md-ripple ?disabled =${ this . disabled } unbounded > </ md-ripple > ` ;
178186 } ;
187+
188+ /** @private */
189+ formResetCallback ( ) {
190+ // The checked property does not reflect, so the original attribute set by
191+ // the user is used to determine the default value.
192+ this . checked = this . hasAttribute ( 'checked' ) ;
193+ }
194+
195+ /** @private */
196+ formStateRestoreCallback ( state : string ) {
197+ this . checked = state === 'true' ;
198+ }
179199}
0 commit comments