Skip to content

Commit

Permalink
fix(ld-input): type file not dispatching in safari
Browse files Browse the repository at this point in the history
  • Loading branch information
borisdiakur committed Feb 1, 2023
1 parent 30e4cff commit 3c0e990
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 18 deletions.
78 changes: 62 additions & 16 deletions src/liquid/components/ld-input/ld-input.css
@@ -1,3 +1,7 @@
:host > input [type='file'] {
pointer-events: none; /* important for Safari */
}

:host,
.ld-input {
--ld-input-padding-x-sm: 0.5rem;
Expand Down Expand Up @@ -66,18 +70,30 @@
box-shadow: inset 0 0 0 var(--ld-sp-2) var(--ld-input-border-col);
}

:where(input) {
margin: 0; /* margin reset for Safari */
}

::slotted(*),
> :where(:not(input):not(textarea)) {
user-select: none;
}

::slotted(:not(ld-button):not(.ld-button)[slot='start']),
> :where(:not(input):not(textarea):not(ld-button):not(.ld-button):not([slot='end']):first-child) {
> :where(
:not(input):not(textarea):not(ld-button):not(.ld-button):not(
[slot='end']
):first-child
) {
margin-left: var(--ld-input-padding-x-md);
}

::slotted(:not(ld-button):not(.ld-button)[slot='end']),
> :where(:not(input):not(textarea):not(ld-button):not(.ld-button):not([slot='start']):last-child) {
> :where(
:not(input):not(textarea):not(ld-button):not(.ld-button):not(
[slot='start']
):last-child
) {
margin-right: var(--ld-input-padding-x-md);
}

Expand All @@ -89,10 +105,6 @@
&[type='file'] {
opacity: 0;

&:not(:disabled):not([aria-disabled='true']) {
cursor: pointer;
}

&::-webkit-file-upload-button {
display: none;
}
Expand Down Expand Up @@ -251,12 +263,20 @@
min-height: var(--ld-input-min-height-sm);

::slotted(:not(ld-button):not(.ld-button)[slot='start']),
> :where(:not(input):not(textarea):not(ld-button):not(.ld-button):not([slot='end']):first-child) {
> :where(
:not(input):not(textarea):not(ld-button):not(.ld-button):not(
[slot='end']
):first-child
) {
margin-left: var(--ld-input-padding-x-sm);
}

::slotted(:not(ld-button):not(.ld-button)[slot='end']),
> :where(:not(input):not(textarea):not(ld-button):not(.ld-button):not([slot='start']):last-child) {
> :where(
:not(input):not(textarea):not(ld-button):not(.ld-button):not(
[slot='start']
):last-child
) {
margin-right: var(--ld-input-padding-x-sm);
}

Expand Down Expand Up @@ -303,12 +323,20 @@
min-height: var(--ld-input-min-height-lg);

::slotted(:not(ld-button):not(.ld-button)[slot='start']),
> :where(:not(input):not(textarea):not(ld-button):not(.ld-button):not([slot='end']):first-child) {
> :where(
:not(input):not(textarea):not(ld-button):not(.ld-button):not(
[slot='end']
):first-child
) {
margin-left: var(--ld-input-padding-x-lg);
}

::slotted(:not(ld-button):not(.ld-button)[slot='end']),
> :where(:not(input):not(textarea):not(ld-button):not(.ld-button):not([slot='start']):last-child) {
> :where(
:not(input):not(textarea):not(ld-button):not(.ld-button):not(
[slot='start']
):last-child
) {
margin-right: var(--ld-input-padding-x-lg);
}

Expand Down Expand Up @@ -357,8 +385,14 @@
}

@media (hover: hover) {
:host(:not(.ld-input--invalid):not([aria-disabled='true']):not(.ld-input--disabled):hover:not(:focus-within)),
.ld-input:not(.ld-input--invalid):not([aria-disabled='true']):not(.ld-input--disabled):hover:not(:focus-within) {
:host(
:not(.ld-input--invalid):not([aria-disabled='true']):not(
.ld-input--disabled
):hover:not(:focus-within)
),
.ld-input:not(.ld-input--invalid):not([aria-disabled='true']):not(
.ld-input--disabled
):hover:not(:focus-within) {
&::before {
box-shadow: inset 0 0 0 var(--ld-sp-2) var(--ld-input-border-col-hover);
}
Expand All @@ -382,8 +416,14 @@
background-color: var(--ld-input-bg-col-invalid-focus);
}

:host(.ld-input--invalid:not(.ld-input--disabled):not([aria-disabled='true']):where(:not(:focus))),
.ld-input--invalid:not(.ld-input--disabled):not([aria-disabled='true']):where(:not(:focus)) {
:host(
.ld-input--invalid:not(.ld-input--disabled):not(
[aria-disabled='true']
):where(:not(:focus))
),
.ld-input--invalid:not(.ld-input--disabled):not([aria-disabled='true']):where(
:not(:focus)
) {
background-color: var(--ld-input-bg-col-invalid);
color: var(--ld-input-text-col-invalid);
}
Expand Down Expand Up @@ -416,8 +456,14 @@
}
}

:host(.ld-input--invalid:not(.ld-input--disabled):not([aria-disabled='true']):focus-within),
.ld-input--invalid:not(.ld-input--disabled):not([aria-disabled='true']):focus-within {
:host(
.ld-input--invalid:not(.ld-input--disabled):not(
[aria-disabled='true']
):focus-within
),
.ld-input--invalid:not(.ld-input--disabled):not(
[aria-disabled='true']
):focus-within {
background-color: var(--ld-input-bg-col-invalid-focus);

> input,
Expand Down
5 changes: 4 additions & 1 deletion src/liquid/components/ld-input/ld-input.tsx
Expand Up @@ -248,6 +248,7 @@ export class LdInput implements InnerFocusable, ClonesAttributes {
this.attributesObserver = cloneAttributes.call(this, [
'multiline',
'autocomplete',
'value',
])

const outerForm = this.el.closest('form')
Expand Down Expand Up @@ -295,7 +296,9 @@ export class LdInput implements InnerFocusable, ClonesAttributes {
}

private handleClick = (ev: MouseEvent) => {
const target = ev.target as HTMLElement
const target = (
'composedPath' in ev ? ev.composedPath()[0] : ev['target']
) as HTMLElement
if (
this.el.hasAttribute('disabled') ||
this.el.getAttribute('aria-disabled') === 'true'
Expand Down
6 changes: 5 additions & 1 deletion src/liquid/components/ld-input/readme.md
Expand Up @@ -216,7 +216,11 @@ Triggerts associated keyboard in supporting browsers and devices with dynamic ke
### Type file

{% example %}
<ld-input placeholder="Your profile image" type="file"></ld-input>
<ld-input placeholder="Your profile image" type="file" accept="image/png, image/jpeg"></ld-input>

<!-- React component -->

<LdInput placeholder="Your profile image" type="file" accept="image/png, image/jpeg" />
{% endexample %}

### Type number
Expand Down
22 changes: 22 additions & 0 deletions src/liquid/components/ld-input/test/ld-input.spec.ts
Expand Up @@ -220,6 +220,28 @@ describe('ld-input', () => {
expect(dispatchSpy).toHaveBeenCalledWith(
expect.objectContaining({ bubbles: false })
)
expect(dispatchSpy).toHaveBeenCalledTimes(1)
})

it('does not forward click to input if the input is the event target', async () => {
const { root } = await newSpecPage({
components: [LdInput],
html: `<ld-input />`,
})
const input = root.shadowRoot.querySelector('input')

input.focus = jest.fn()
const dispatchSpy = jest.spyOn(input, 'dispatchEvent')

const ev = {
type: 'click',
bubbles: true,
composed: true,
composedPath: () => [input],
} as unknown as MouseEvent
root.dispatchEvent(ev)

expect(dispatchSpy).not.toHaveBeenCalled()
})

it('forwards click to input (multiline)', async () => {
Expand Down

1 comment on commit 3c0e990

@vercel
Copy link

@vercel vercel bot commented on 3c0e990 Feb 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

liquid – ./

liquid-uxsd.vercel.app
liquid-oxygen.vercel.app
liquid-git-main-uxsd.vercel.app

Please sign in to comment.