Skip to content

Commit 10053e9

Browse files
Merge pull request #446 from lightning-js/dev
Release 1.36.0
2 parents bf48245 + 11166be commit 10053e9

File tree

11 files changed

+70
-27
lines changed

11 files changed

+70
-27
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## v1.36.0
4+
5+
_11 Aug 2025_
6+
7+
- Added `passFocus` option to route options to prevent focus being passed to page navigated to
8+
- Added missing type definitions for Route options
9+
- Fixed sidebar in docs
10+
- Added debug log messages to Announcer
11+
- Added `remove()` function as (preferred) alias for announcer `message.cancel()`
12+
- Fixed issue with removing a messages causing an interrupt of current message being read out
13+
314
## v1.35.5
415

516
_06 Aug 2025_

docs/_sidebar.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@
3333
- [Language](/plugins/language.md)
3434
- [Theme](/plugins/theme.md)
3535
- [Global App State](/plugins/global_app_state.md)
36+
- [Storage](/plugins/storage.md)
3637
- Performance
3738
- [Lazy loading]('/performance/lazy-loading.md')

docs/plugins/text-to-speech-announcer.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ In some cases you may not want to clear the entire queue, but instead cancel out
7979

8080
Imagine an App with a row of tiles, it's possible that before the title of the role is being spoken out, the user already navigates through the tiles within the row. Traditionally you'd use the focus event to speak out info about each tile (i.e. adding tot the queue). You don't want all previously focused tiles to still be announced, but would still want the category of the row to be announced, making clearing the queue not required.
8181

82-
The `speak()`-method return a Promise that also contains a `cancel()` function. When called, it will cancel that specific message and remove it from the queue before it can be spoken out.
82+
The `speak()`-method return a Promise that also contains a `remove()` function. When called, it will remove it from the queue before it can be spoken out.
8383

8484
Additionally if you want to _interrupt_ a specific messages as it's being spoken out as well and go straight to the next message in the queue (i.e. the newly focused item, for example). You can use the `stop()` message that is returned on the Promise returned by the `speak()`-method.
8585

@@ -100,8 +100,8 @@ Blits.Component('MyTile', {
100100
unfocus() {
101101
// when unfocused interrupt the message if it's already being spoken out
102102
this.message.stop()
103-
// and cancel the message to remove it from the queue
104-
this.message.cancel()
103+
// and remove the message from the queue
104+
this.message.remove()
105105
}
106106
}
107107
})
@@ -117,4 +117,4 @@ Alternatively the announcer can be enabled or disabled run time by using one of
117117

118118
- `this.$announcer.enable()` - activates the announcer
119119
- `this.$announcer.disable()` - deactivates the announcer
120-
- `this.$announcer.disable(true/false)` - turns the announcer or on off
120+
- `this.$announcer.disable(true/false)` - turns the announcer on or off

docs/router/basics.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ export default Blits.Component('Poster', {
9696

9797
Whenever you navigate to a new page, the URL hash will automatically be updated. Unless specified otherwise, navigating to a new page, will add that route to the history stack. The `back` input action is automatically wired up to navigate back down the history stack.
9898

99+
By default, every time you navigate to a new route, the application focus will be automatically passed to the newly loaded page. If you instead want to maintain the current focus (for example in a widget that sits above your RouterView), you can use `passFocus: false` as part of the router options.
100+
99101
## Deeplinking
100102

101103
The Router plugin has support for deeplinking. When the App is loaded with a URL hash (i.e. `#/pages/settings/network`), the router will try to match that hash to a defined route. This means that your app can be deep linked into, by simply providing the correct URL hash.

docs/sidebar.json

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,6 @@
112112
}
113113
]
114114
},
115-
{
116-
"text": "Performance",
117-
"items": [
118-
{
119-
"text": "Lazy Loading",
120-
"link": "/performance/lazy-loading"
121-
}
122-
]
123-
},
124115
{
125116
"text": "Router",
126117
"items": [
@@ -156,6 +147,10 @@
156147
{
157148
"text": "Global App State",
158149
"link": "/plugins/global_app_state"
150+
},
151+
{
152+
"text": "Storage",
153+
"link": "/plugins/storage"
159154
}
160155
]
161156
},

index.d.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,30 @@ declare module '@lightningjs/blits' {
187187

188188
// todo: specify valid route options
189189
export interface RouteOptions {
190-
[key: string]: any
190+
/**
191+
* Whether the page navigation should be added to the history stack
192+
* used when navigating back using `this.$router.back()`
193+
*
194+
* @default true
195+
*/
196+
inHistory?: Boolean
197+
/**
198+
* Whether the page should be kept alive when navigating away. Can be useful
199+
* for a homepage where the state should be fully retained when navigating back
200+
* from a details page
201+
*
202+
* @default false
203+
*/
204+
keepAlive?: Boolean
205+
/**
206+
* Whether the focus should be delegated to the page that's being navigated to.
207+
* Can be useful when navigating to a new page from a widget / menu overlaying the
208+
* RouterView, where the widget should maintain the focus (instead of the new page, which
209+
* is the default behaviour)
210+
*
211+
* @default true
212+
*/
213+
passFocus?: Boolean
191214
}
192215

193216
export interface Router {
@@ -628,7 +651,7 @@ declare module '@lightningjs/blits' {
628651
/**
629652
* Extra route options
630653
*/
631-
options?: object // todo: specify which options are available,
654+
options?: RouteOptions
632655
/**
633656
* Message to be announced when visiting the route (often used for accessibility purposes)
634657
*

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lightningjs/blits",
3-
"version": "1.35.5",
3+
"version": "1.36.0",
44
"description": "Blits: The Lightning 3 App Development Framework",
55
"bin": "bin/index.js",
66
"exports": {

src/announcer/announcer.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* SPDX-License-Identifier: Apache-2.0
1616
*/
1717

18+
import { Log } from '../lib/log.js'
1819
import speechSynthesis from './speechSynthesis.js'
1920

2021
let active = false
@@ -28,6 +29,7 @@ const noopAnnouncement = {
2829
then() {},
2930
done() {},
3031
cancel() {},
32+
remove() {},
3133
stop() {},
3234
}
3335

@@ -66,11 +68,11 @@ const addToQueue = (message, politeness, delay = false) => {
6668
resolveFn = resolve
6769
})
6870

69-
// augment the promise with a cancel function
70-
done.cancel = () => {
71+
// augment the promise with a cancel / remove function
72+
done.remove = done.cancel = () => {
7173
const index = queue.findIndex((item) => item.id === id)
7274
if (index !== -1) queue.splice(index, 1)
73-
isProcessing = false
75+
Log.debug(`Announcer - removed from queue: "${message}" (id: ${id})`)
7476
resolveFn('canceled')
7577
}
7678

@@ -92,6 +94,8 @@ const addToQueue = (message, politeness, delay = false) => {
9294
queue.push({ delay, resolveFn, id })
9395
}
9496

97+
Log.debug(`Announcer - added to queue: "${message}" (id: ${id})`)
98+
9599
setTimeout(() => {
96100
processQueue()
97101
}, 100)
@@ -118,17 +122,22 @@ const processQueue = async () => {
118122
if (debounce !== null) clearTimeout(debounce)
119123
// add some easing when speaking the messages to reduce stuttering
120124
debounce = setTimeout(() => {
125+
Log.debug(`Announcer - speaking: "${message}" (id: ${id})`)
126+
121127
speechSynthesis
122-
.speak({ message })
128+
.speak({ message, id })
123129
.then(() => {
124-
isProcessing = false
130+
Log.debug(`Announcer - finished speaking: "${message}" (id: ${id})`)
131+
125132
currentId = null
133+
isProcessing = false
126134
resolveFn('finished')
127135
processQueue()
128136
})
129137
.catch((e) => {
130-
isProcessing = false
131138
currentId = null
139+
isProcessing = false
140+
Log.debug(`Announcer - error ("${e.error}") while speaking: "${message}" (id: ${id})`)
132141
resolveFn(e.error)
133142
processQueue()
134143
})

src/announcer/speechSynthesis.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const initialize = () => {
6464

6565
const speak = (options) => {
6666
const utterance = new SpeechSynthesisUtterance(options.message)
67-
const id = Date.now() + Math.random() // Unique ID for tracking
67+
const id = options.id
6868
utterance.lang = options.lang || defaultUtteranceProps.lang
6969
utterance.pitch = options.pitch || defaultUtteranceProps.pitch
7070
utterance.rate = options.rate || defaultUtteranceProps.rate

0 commit comments

Comments
 (0)