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 58daab5 commit bbf9a29
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 44 deletions.
109 changes: 80 additions & 29 deletions src/liquid/components/ld-toggle/ld-toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,44 @@ export class LdToggle implements InnerFocusable {
private hiddenInput: HTMLInputElement
private hasIcons: boolean

/** Size of the toggle. */
@Prop() size?: 'sm' | 'lg'
/** Alternative disabled state that keeps element focusable */
@Prop() ariaDisabled: string

/** Disabled state of the toggle. */
/** Hint for form autofill feature. */
@Prop({ mutable: true, reflect: true }) autocomplete?: string

/** Automatically focus the form control when the page is loaded. */
@Prop() autofocus?: boolean

/** The input value. */
@Prop({ mutable: true, reflect: true }) checked: boolean

/** Disabled state of the checkbox. */
@Prop() disabled: boolean

/** Associates the control with a form element. */
@Prop() form?: string

/** 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

/** The input value. */
@Prop() value: string
/** The value is not editable. */
@Prop() readonly?: boolean

/** Alternative disabled state that keeps element focusable */
@Prop() ariaDisabled: string
/** Set this property to `true` in order to mark the checkbox as required. */
@Prop() required: boolean

/** The input value. */
@Prop({ mutable: true, reflect: true }) checked: boolean
/** Size of the toggle. */
@Prop() size?: 'sm' | 'lg'

/** Set this property to `true` in order to mark the toggle as required. */
@Prop() required: boolean
/** The input value. */
@Prop() value: string

/**
* Sets focus on the toggle
Expand All @@ -57,21 +75,39 @@ export class LdToggle implements InnerFocusable {
@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)
}

if (this.hiddenInput) {
if (!this.name) {
this.hiddenInput.remove()
this.hiddenInput = undefined
return
}

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

if (this.name) {
this.hiddenInput.name = this.name
} else {
this.hiddenInput.removeAttribute('name')
}

if (this.value) {
this.hiddenInput.value = this.value
} else {
this.hiddenInput.removeAttribute('value')
}

if (this.form) {
this.hiddenInput.setAttribute('form', this.form)
} else if (this.hiddenInput.getAttribute('form')) {
if (outerForm) {
this.hiddenInput.removeAttribute('form')
} else {
this.hiddenInput.remove()
this.hiddenInput = undefined
}
}
}
}

Expand Down Expand Up @@ -102,24 +138,39 @@ export class LdToggle implements InnerFocusable {
!!this.el.querySelector('[slot="icon-start"]') ||
!!this.el.querySelector('[slot="icon-end"]')

if (this.el.closest('form')) {
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
const outerForm = this.el.closest('form')

if (outerForm && !this.autocomplete) {
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.value) {
this.hiddenInput.value = this.value
if (this.form) {
this.hiddenInput.setAttribute('form', this.form)
}

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

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

this.el.appendChild(this.hiddenInput)
componentDidLoad() {
if (this.autofocus) {
this.focusInner()
}
}

Expand Down
28 changes: 17 additions & 11 deletions src/liquid/components/ld-toggle/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,17 +435,23 @@ Please refer to the [ld-label](components/ld-label/) docs for more information o

## Properties

| Property | Attribute | Description | Type | Default |
| -------------- | --------------- | -------------------------------------------------------------------- | ------------------ | ----------- |
| `ariaDisabled` | `aria-disabled` | Alternative disabled state that keeps element focusable | `string` | `undefined` |
| `checked` | `checked` | The input value. | `boolean` | `undefined` |
| `disabled` | `disabled` | Disabled state of the toggle. | `boolean` | `undefined` |
| `key` | `key` | for tracking the node's identity when working with lists | `string \| number` | `undefined` |
| `name` | `name` | Used to specify the name of the control. | `string` | `undefined` |
| `ref` | `ref` | reference to component | `any` | `undefined` |
| `required` | `required` | Set this property to `true` in order to mark the toggle as required. | `boolean` | `undefined` |
| `size` | `size` | Size of the toggle. | `"lg" \| "sm"` | `undefined` |
| `value` | `value` | The input value. | `string` | `undefined` |
| Property | Attribute | Description | Type | Default |
| -------------- | --------------- | ------------------------------------------------------------------------------ | ------------------ | ----------- |
| `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` |
| `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` |
| `required` | `required` | Set this property to `true` in order to mark the checkbox as required. | `boolean` | `undefined` |
| `size` | `size` | Size of the toggle. | `"lg" \| "sm"` | `undefined` |
| `value` | `value` | The input value. | `string` | `undefined` |


## Methods
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ld-toggle creates hidden input field, if inside a form 1`] = `
<ld-toggle class="ld-toggle">
<ld-toggle class="ld-toggle" name="example">
<mock:shadow-root>
<input part="input focusable" type="checkbox">
<span class="ld-toggle__knob" part="knob"></span>
</mock:shadow-root>
<input type="checkbox" style="visibility: hidden; position: absolute; pointer-events: none;">
<input name="example" type="checkbox" style="visibility: hidden; position: absolute; pointer-events: none;">
</ld-toggle>
`;
Expand Down
20 changes: 18 additions & 2 deletions src/liquid/components/ld-toggle/test/ld-toggle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ describe('ld-toggle', () => {
it('creates hidden input field, if inside a form', async () => {
const { root } = await newSpecPage({
components: [LdToggle],
html: `<form><ld-toggle /></form>`,
html: `<form><ld-toggle name="example" /></form>`,
})
expect(root).toMatchSnapshot()
})
Expand Down Expand Up @@ -170,7 +170,12 @@ describe('ld-toggle', () => {
ldToggle.removeAttribute('name')
await waitForChanges()

expect(ldToggle.querySelector('input').getAttribute('name')).toEqual(null)
expect(ldToggle.querySelector('input')).toEqual(null)

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

expect(ldToggle.querySelector('input')).toHaveProperty('name', 'test')

ldToggle.dispatchEvent(new Event('click'))
await waitForChanges()
Expand All @@ -192,4 +197,15 @@ describe('ld-toggle', () => {

expect(ldToggle.querySelector('input').getAttribute('value')).toEqual(null)
})

it('uses hidden input field with referenced form', async () => {
const { root, waitForChanges } = await newSpecPage({
components: [LdToggle],
html: '<ld-toggle name="example" form="yolo" />',
})
const ldToggle = root
await waitForChanges()

expect(ldToggle.querySelector('input')).toHaveProperty('name', 'example')
})
})

0 comments on commit bbf9a29

Please sign in to comment.