mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-06 14:19:17 +08:00
feat(input, textarea): dir is inherited to native form control (#30102)
Issue number: resolves #30193 resolves #29577 Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
18e26acb01
commit
504fb6a25f
@ -338,10 +338,26 @@ export class Input implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dir is a globally enumerated attribute.
|
||||||
|
* As a result, creating these as properties
|
||||||
|
* can have unintended side effects. Instead, we
|
||||||
|
* listen for attribute changes and inherit them
|
||||||
|
* to the inner `<input>` element.
|
||||||
|
*/
|
||||||
|
@Watch('dir')
|
||||||
|
onDirChanged(newValue: string) {
|
||||||
|
this.inheritedAttributes = {
|
||||||
|
...this.inheritedAttributes,
|
||||||
|
dir: newValue,
|
||||||
|
};
|
||||||
|
forceUpdate(this);
|
||||||
|
}
|
||||||
|
|
||||||
componentWillLoad() {
|
componentWillLoad() {
|
||||||
this.inheritedAttributes = {
|
this.inheritedAttributes = {
|
||||||
...inheritAriaAttributes(this.el),
|
...inheritAriaAttributes(this.el),
|
||||||
...inheritAttributes(this.el, ['tabindex', 'title', 'data-form-type']),
|
...inheritAttributes(this.el, ['tabindex', 'title', 'data-form-type', 'dir']),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,24 @@ describe('input: rendering', () => {
|
|||||||
const bottomContent = page.body.querySelector('ion-input .input-bottom');
|
const bottomContent = page.body.querySelector('ion-input .input-bottom');
|
||||||
expect(bottomContent).toBe(null);
|
expect(bottomContent).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should inherit watched attributes', async () => {
|
||||||
|
const page = await newSpecPage({
|
||||||
|
components: [Input],
|
||||||
|
html: '<ion-input label="Input" dir="ltr"></ion-input>',
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputEl = page.body.querySelector('ion-input')!;
|
||||||
|
const nativeEl = inputEl.querySelector('input')!;
|
||||||
|
|
||||||
|
expect(nativeEl.getAttribute('dir')).toBe('ltr');
|
||||||
|
|
||||||
|
inputEl.setAttribute('dir', 'rtl');
|
||||||
|
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
expect(nativeEl.getAttribute('dir')).toBe('rtl');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -14,6 +14,24 @@ it('should inherit attributes', async () => {
|
|||||||
expect(nativeEl.getAttribute('data-form-type')).toBe('password');
|
expect(nativeEl.getAttribute('data-form-type')).toBe('password');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should inherit watched attributes', async () => {
|
||||||
|
const page = await newSpecPage({
|
||||||
|
components: [Textarea],
|
||||||
|
html: '<ion-textarea dir="ltr"></ion-textarea>',
|
||||||
|
});
|
||||||
|
|
||||||
|
const textareaEl = page.body.querySelector('ion-textarea')!;
|
||||||
|
const nativeEl = textareaEl.querySelector('textarea')!;
|
||||||
|
|
||||||
|
expect(nativeEl.getAttribute('dir')).toBe('ltr');
|
||||||
|
|
||||||
|
textareaEl.setAttribute('dir', 'rtl');
|
||||||
|
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
expect(nativeEl.getAttribute('dir')).toBe('rtl');
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Textarea uses emulated slots, so the internal
|
* Textarea uses emulated slots, so the internal
|
||||||
* behavior will not exactly match IonSelect's slots.
|
* behavior will not exactly match IonSelect's slots.
|
||||||
|
|||||||
@ -261,6 +261,22 @@ export class Textarea implements ComponentInterface {
|
|||||||
this.runAutoGrow();
|
this.runAutoGrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dir is a globally enumerated attribute.
|
||||||
|
* As a result, creating these as properties
|
||||||
|
* can have unintended side effects. Instead, we
|
||||||
|
* listen for attribute changes and inherit them
|
||||||
|
* to the inner `<textarea>` element.
|
||||||
|
*/
|
||||||
|
@Watch('dir')
|
||||||
|
onDirChanged(newValue: string) {
|
||||||
|
this.inheritedAttributes = {
|
||||||
|
...this.inheritedAttributes,
|
||||||
|
dir: newValue,
|
||||||
|
};
|
||||||
|
forceUpdate(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `ionChange` event is fired when the user modifies the textarea's value.
|
* The `ionChange` event is fired when the user modifies the textarea's value.
|
||||||
* Unlike the `ionInput` event, the `ionChange` event is fired when
|
* Unlike the `ionInput` event, the `ionChange` event is fired when
|
||||||
@ -331,7 +347,7 @@ export class Textarea implements ComponentInterface {
|
|||||||
componentWillLoad() {
|
componentWillLoad() {
|
||||||
this.inheritedAttributes = {
|
this.inheritedAttributes = {
|
||||||
...inheritAriaAttributes(this.el),
|
...inheritAriaAttributes(this.el),
|
||||||
...inheritAttributes(this.el, ['data-form-type', 'title', 'tabindex']),
|
...inheritAttributes(this.el, ['data-form-type', 'title', 'tabindex', 'dir']),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user