Skip to content

Commit

Permalink
fix(ld-toggle): prop forwarding
Browse files Browse the repository at this point in the history
  • Loading branch information
borisdiakur authored and renet committed Dec 2, 2021
1 parent 572e711 commit eb3d168
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 40 deletions.
55 changes: 27 additions & 28 deletions src/liquid/components/ld-toggle/ld-toggle.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component, Element, h, Host, Method, Prop, Watch } from '@stencil/core'
import { getClassNames } from '../../utils/getClassNames'
import { cloneAttributes } from '../../utils/cloneAttributes'

/**
* @virtualProp ref - reference to component
Expand All @@ -17,6 +18,7 @@ import { getClassNames } from '../../utils/getClassNames'
})
export class LdToggle implements InnerFocusable {
@Element() el: HTMLElement

private input: HTMLInputElement
private hiddenInput: HTMLInputElement
private hasIcons: boolean
Expand All @@ -30,7 +32,7 @@ export class LdToggle implements InnerFocusable {
/** Automatically focus the form control when the page is loaded. */
@Prop() autofocus?: boolean

/** The input value. */
/** Indicates whether the toggle is "on". */
@Prop({ mutable: true, reflect: true }) checked: boolean

/** Disabled state of the checkbox. */
Expand All @@ -42,9 +44,6 @@ export class LdToggle implements InnerFocusable {
/** Set this property to `true` in order to mark the checkbox visually as invalid. */
@Prop() invalid: boolean

/** Value of the id attribute of the `<datalist>` of autocomplete options. */
@Prop() list?: string

/** Used to specify the name of the control. */
@Prop() name: string

Expand Down Expand Up @@ -72,13 +71,11 @@ export class LdToggle implements InnerFocusable {

@Watch('checked')
@Watch('name')
@Watch('required')
@Watch('value')
updateHiddenInput() {
const outerForm = this.el.closest('form')
if (!this.hiddenInput && this.name && (outerForm || this.form)) {
this.hiddenInput = document.createElement('input')
this.el.appendChild(this.hiddenInput)
this.createHiddenInput()
}

if (this.hiddenInput) {
Expand All @@ -90,7 +87,6 @@ export class LdToggle implements InnerFocusable {

this.hiddenInput.name = this.name
this.hiddenInput.checked = this.checked
this.hiddenInput.required = this.required

if (this.value) {
this.hiddenInput.value = this.value
Expand All @@ -111,6 +107,15 @@ export class LdToggle implements InnerFocusable {
}
}

private createHiddenInput() {
this.hiddenInput = document.createElement('input')
this.hiddenInput.type = 'checkbox'
this.hiddenInput.style.visibility = 'hidden'
this.hiddenInput.style.position = 'absolute'
this.hiddenInput.style.pointerEvents = 'none'
this.el.appendChild(this.hiddenInput)
}

private handleBlur = (ev: FocusEvent) => {
setTimeout(() => {
this.el.dispatchEvent(ev)
Expand Down Expand Up @@ -144,27 +149,20 @@ export class LdToggle implements InnerFocusable {
this.autocomplete = outerForm.getAttribute('autocomplete')
}

if (outerForm || this.form) {
if (this.name) {
this.hiddenInput = document.createElement('input')
this.hiddenInput.required = this.required
this.hiddenInput.type = 'checkbox'
this.hiddenInput.style.visibility = 'hidden'
this.hiddenInput.style.position = 'absolute'
this.hiddenInput.style.pointerEvents = 'none'
this.hiddenInput.checked = this.checked
this.hiddenInput.name = this.name

if (this.form) {
this.hiddenInput.setAttribute('form', this.form)
}
if (this.name && (outerForm || this.form)) {
this.createHiddenInput()
this.hiddenInput.checked = this.checked
this.hiddenInput.name = this.name

if (this.value) {
this.hiddenInput.value = this.value
}
if (this.form) {
this.hiddenInput.setAttribute('form', this.form)
}

this.el.appendChild(this.hiddenInput)
if (this.value) {
this.hiddenInput.value = this.value
}

this.el.appendChild(this.hiddenInput)
}
}

Expand All @@ -186,14 +184,15 @@ export class LdToggle implements InnerFocusable {
>
<input
aria-disabled={this.ariaDisabled}
checked={this.checked}
disabled={this.disabled}
onBlur={this.handleBlur}
onFocus={this.handleFocus}
part="input focusable"
ref={(ref) => (this.input = ref)}
required={this.required}
type="checkbox"
{...cloneAttributes(this.el, ['autocomplete', 'size'])}
checked={this.checked}
disabled={this.disabled}
/>
<span class="ld-toggle__knob" part="knob" />
{this.hasIcons && (
Expand Down
4 changes: 1 addition & 3 deletions src/liquid/components/ld-toggle/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,12 +440,11 @@ Please refer to the [ld-label](components/ld-label/) docs for more information o
| `ariaDisabled` | `aria-disabled` | Alternative disabled state that keeps element focusable | `string` | `undefined` |
| `autocomplete` | `autocomplete` | Hint for form autofill feature. | `string` | `undefined` |
| `autofocus` | `autofocus` | Automatically focus the form control when the page is loaded. | `boolean` | `undefined` |
| `checked` | `checked` | The input value. | `boolean` | `undefined` |
| `checked` | `checked` | Indicates whether the toggle is "on". | `boolean` | `undefined` |
| `disabled` | `disabled` | Disabled state of the checkbox. | `boolean` | `undefined` |
| `form` | `form` | Associates the control with a form element. | `string` | `undefined` |
| `invalid` | `invalid` | Set this property to `true` in order to mark the checkbox visually as invalid. | `boolean` | `undefined` |
| `key` | `key` | for tracking the node's identity when working with lists | `string \| number` | `undefined` |
| `list` | `list` | Value of the id attribute of the `<datalist>` of autocomplete options. | `string` | `undefined` |
| `name` | `name` | Used to specify the name of the control. | `string` | `undefined` |
| `readonly` | `readonly` | The value is not editable. | `boolean` | `undefined` |
| `ref` | `ref` | reference to component | `any` | `undefined` |
Expand All @@ -471,7 +470,6 @@ Type: `Promise<void>`

| Part | Description |
| ---------------------- | ------------------------- |
| `"focusable"` | |
| `"icon-wrapper"` | Both wrappers of icons |
| `"icon-wrapper-end"` | Wrapper of the end icon |
| `"icon-wrapper-start"` | Wrapper of the start icon |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`ld-toggle creates hidden input field, if inside a form 1`] = `
<ld-toggle class="ld-toggle" name="example">
<mock:shadow-root>
<input part="input focusable" type="checkbox">
<input name="example" part="input focusable" type="checkbox">
<span class="ld-toggle__knob" part="knob"></span>
</mock:shadow-root>
<input name="example" type="checkbox" style="visibility: hidden; position: absolute; pointer-events: none;">
Expand Down
10 changes: 2 additions & 8 deletions src/liquid/components/ld-toggle/test/ld-toggle.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { newSpecPage } from '@stencil/core/testing'
jest.mock('../../../utils/cloneAttributes')
import { LdIcon } from '../../ld-icon/ld-icon'
import { LdToggle } from '../ld-toggle'

Expand Down Expand Up @@ -144,10 +145,9 @@ describe('ld-toggle', () => {
it('sets initial state on hidden input', async () => {
const { root } = await newSpecPage({
components: [LdToggle],
html: `<form><ld-toggle name="example" checked required /></form>`,
html: `<form><ld-toggle name="example" checked /></form>`,
})
expect(root.querySelector('input')).toHaveProperty('name', 'example')
expect(root.querySelector('input')).toHaveProperty('required', true)
})

it('updates hidden input field', async () => {
Expand All @@ -160,7 +160,6 @@ describe('ld-toggle', () => {

expect(ldToggle.querySelector('input')).toHaveProperty('name', 'example')
expect(ldToggle.querySelector('input')).toHaveProperty('checked', false)
expect(ldToggle.querySelector('input')).toHaveProperty('required', false)

ldToggle.setAttribute('name', 'test')
await waitForChanges()
Expand All @@ -182,11 +181,6 @@ describe('ld-toggle', () => {

expect(ldToggle.querySelector('input')).toHaveProperty('checked', true)

ldToggle.setAttribute('required', '')
await waitForChanges()

expect(ldToggle.querySelector('input')).toHaveProperty('required', true)

ldToggle.setAttribute('value', 'test')
await waitForChanges()

Expand Down

0 comments on commit eb3d168

Please sign in to comment.