Merge branch 'main' of github.com:github/typing-effect-element into hazukitenki/main
This commit is contained in:
Коммит
7f3abaec95
10
README.md
10
README.md
|
@ -21,6 +21,16 @@ import '@github/typing-effect-element'
|
|||
</typing-effect>
|
||||
```
|
||||
|
||||
## Accessibility
|
||||
|
||||
This component detects whether `prefers-reduced-motion` is set on the window:
|
||||
|
||||
```js
|
||||
window.matchMedia('(prefers-reduced-motion)').matches === true
|
||||
```
|
||||
|
||||
If this evaluates to true, any content lines provided will be appended immediately rather than being typed out with a delay.
|
||||
|
||||
## Browser support
|
||||
|
||||
Browsers without native [custom element support][support] require a [polyfill][].
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = function(config) {
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
frameworks: ['mocha', 'chai'],
|
||||
files: [
|
||||
|
|
22
src/index.ts
22
src/index.ts
|
@ -39,7 +39,14 @@ class TypingEffectElement extends HTMLElement {
|
|||
}
|
||||
}
|
||||
|
||||
get prefersReducedMotion(): boolean {
|
||||
return window.matchMedia('(prefers-reduced-motion)').matches
|
||||
}
|
||||
|
||||
get characterDelay(): number {
|
||||
if (this.prefersReducedMotion) {
|
||||
return 0
|
||||
}
|
||||
return Math.max(0, Math.min(Math.floor(Number(this.getAttribute('data-character-delay'))), 2_147_483_647)) || 40
|
||||
}
|
||||
|
||||
|
@ -51,6 +58,9 @@ class TypingEffectElement extends HTMLElement {
|
|||
}
|
||||
|
||||
get lineDelay(): number {
|
||||
if (this.prefersReducedMotion) {
|
||||
return 0
|
||||
}
|
||||
return Math.max(0, Math.min(Math.floor(Number(this.getAttribute('data-line-delay'))), 2_147_483_647)) || 40
|
||||
}
|
||||
|
||||
|
@ -82,12 +92,16 @@ async function typeLines(
|
|||
lineDelay: number
|
||||
): Promise<void> {
|
||||
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
||||
for (const character of lines[lineIndex].split('')) {
|
||||
await wait(characterDelay)
|
||||
contentElement.innerHTML += character
|
||||
if (characterDelay === 0) {
|
||||
contentElement.append(lines[lineIndex])
|
||||
} else {
|
||||
for (const character of lines[lineIndex].split('')) {
|
||||
await wait(characterDelay)
|
||||
contentElement.innerHTML += character
|
||||
}
|
||||
}
|
||||
|
||||
await wait(lineDelay)
|
||||
if (lineDelay !== 0) await wait(lineDelay)
|
||||
if (lineIndex < lines.length - 1) contentElement.append(document.createElement('br'))
|
||||
}
|
||||
}
|
||||
|
|
41
test/test.js
41
test/test.js
|
@ -68,6 +68,21 @@ describe('typing-effect', function () {
|
|||
})
|
||||
|
||||
describe('delay attributes', function () {
|
||||
let realMatchMedia
|
||||
before(() => {
|
||||
realMatchMedia = window.matchMedia
|
||||
window.matchMedia = mediaString => {
|
||||
if (mediaString === '(prefers-reduced-motion)') {
|
||||
return {matches: false}
|
||||
}
|
||||
return realMatchMedia(mediaString)
|
||||
}
|
||||
})
|
||||
|
||||
after(() => {
|
||||
window.matchMedia = realMatchMedia
|
||||
})
|
||||
|
||||
it('uses defaults when no delays specified', function () {
|
||||
const typingEffectElement = document.createElement('typing-effect')
|
||||
document.body.append(typingEffectElement)
|
||||
|
@ -89,6 +104,32 @@ describe('typing-effect', function () {
|
|||
assert.equal(typingEffectElement.lineDelay, lineDelay)
|
||||
})
|
||||
})
|
||||
|
||||
describe('a11y considerations', function () {
|
||||
let realMatchMedia
|
||||
before(() => {
|
||||
realMatchMedia = window.matchMedia
|
||||
window.matchMedia = mediaString => {
|
||||
if (mediaString === '(prefers-reduced-motion)') {
|
||||
return {matches: true}
|
||||
}
|
||||
return realMatchMedia(mediaString)
|
||||
}
|
||||
})
|
||||
|
||||
after(() => {
|
||||
window.matchMedia = realMatchMedia
|
||||
})
|
||||
|
||||
it('sets delay to 0 when media query matches (prefers-reduced-motion)', function () {
|
||||
const typingEffectElement = document.createElement('typing-effect')
|
||||
document.body.append(typingEffectElement)
|
||||
|
||||
assert.equal(window.matchMedia('(prefers-reduced-motion)').matches, true)
|
||||
assert.equal(typingEffectElement.characterDelay, 0)
|
||||
assert.equal(typingEffectElement.lineDelay, 0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function once(element, eventName) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче