feat(range): expose label wrapper as shadow part (#28601)

This commit is contained in:
Liam DeBeasi
2023-11-30 10:36:21 -05:00
committed by GitHub
parent 1c1b567279
commit 52ed2bf637
7 changed files with 48 additions and 7 deletions

View File

@ -1077,6 +1077,7 @@ ion-range,css-prop,--pin-color
ion-range,part,bar
ion-range,part,bar-active
ion-range,part,knob
ion-range,part,label
ion-range,part,pin
ion-range,part,tick
ion-range,part,tick-active

21
core/setupJest.js Normal file
View File

@ -0,0 +1,21 @@
expect.extend({
toHaveShadowPart(received, part) {
if (typeof part !== 'string') {
throw new Error('expected toHaveShadowPart to be called with a string of the CSS shadow part name');
}
if (received.shadowRoot === null) {
throw new Error('expected toHaveShadowPart to be called on an element with a shadow root');
}
const shadowPart = received.shadowRoot.querySelector(`[part="${part}"]`);
const pass = shadowPart !== null;
const message = `expected ${received.tagName.toLowerCase()} to have shadow part "${part}"`;
return {
pass,
message: () => message,
};
},
});

View File

@ -216,13 +216,6 @@
*/
max-width: 200px;
/**
* This ensures that double tapping this text
* clicks the <label> and focuses the range
* when a screen reader is enabled.
*/
pointer-events: none;
text-overflow: ellipsis;
white-space: nowrap;

View File

@ -37,6 +37,7 @@ import type {
* @part knob - The handle that is used to drag the range.
* @part bar - The inactive part of the bar.
* @part bar-active - The active part of the bar.
* @part label - The label text describing the range.
*/
@Component({
tag: 'ion-range',
@ -675,6 +676,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
'label-text-wrapper': true,
'label-text-wrapper-hidden': !hasLabel,
}}
part="label"
>
{label !== undefined ? <div class="label-text">{label}</div> : <slot name="label"></slot>}
</div>

View File

@ -229,4 +229,22 @@ describe('range: item adjustments', () => {
expect(range.classList.contains('range-item-start-adjustment')).toBe(false);
expect(range.classList.contains('range-item-end-adjustment')).toBe(false);
});
describe('shadow parts', () => {
it('should have shadow parts', async () => {
const page = await newSpecPage({
components: [Range],
html: `<ion-range pin="true" snaps="true" value="50" label="Label"></ion-range>`,
});
const range = page.body.querySelector('ion-range')!;
expect(range).toHaveShadowPart('label');
expect(range).toHaveShadowPart('pin');
expect(range).toHaveShadowPart('knob');
expect(range).toHaveShadowPart('bar');
expect(range).toHaveShadowPart('bar-active');
expect(range).toHaveShadowPart('tick');
expect(range).toHaveShadowPart('tick-active');
});
});
});

5
core/src/jest.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
declare namespace jest {
interface Matchers<R> {
toHaveShadowPart(part: string): R;
}
}

View File

@ -252,6 +252,7 @@ export const config: Config = {
"@utils/test": ["<rootDir>/src/utils/test/utils"],
"@utils/logging": ["<rootDir>/src/utils/logging"],
},
setupFilesAfterEnv: ['./setupJest.js']
},
preamble: '(C) Ionic http://ionicframework.com - MIT License',
globalScript: 'src/global/ionic-global.ts',