@furystack/shades 14.0.0 → 15.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/esm/compile-route.d.ts +5 -0
- package/esm/compile-route.d.ts.map +1 -1
- package/esm/compile-route.js +5 -0
- package/esm/compile-route.js.map +1 -1
- package/esm/component-factory.spec.d.ts.map +1 -1
- package/esm/component-factory.spec.js +2 -2
- package/esm/component-factory.spec.js.map +1 -1
- package/esm/components/nested-hooks.js +2 -2
- package/esm/components/nested-hooks.js.map +1 -1
- package/esm/components/nested-hooks.spec.js +14 -14
- package/esm/components/nested-hooks.spec.js.map +1 -1
- package/esm/components/nested-navigate.js +1 -1
- package/esm/components/nested-navigate.js.map +1 -1
- package/esm/components/nested-navigate.spec.js +16 -16
- package/esm/components/nested-navigate.spec.js.map +1 -1
- package/esm/components/nested-replace.js +1 -1
- package/esm/components/nested-replace.js.map +1 -1
- package/esm/components/nested-replace.spec.js +6 -6
- package/esm/components/nested-replace.spec.js.map +1 -1
- package/esm/components/nested-route-link.js +1 -1
- package/esm/components/nested-route-link.js.map +1 -1
- package/esm/components/nested-route-link.spec.js +8 -8
- package/esm/components/nested-route-link.spec.js.map +1 -1
- package/esm/components/nested-router.js +3 -3
- package/esm/components/nested-router.js.map +1 -1
- package/esm/components/nested-router.spec.js +24 -24
- package/esm/components/nested-router.spec.js.map +1 -1
- package/esm/css-generator.d.ts +9 -26
- package/esm/css-generator.d.ts.map +1 -1
- package/esm/css-generator.js +9 -26
- package/esm/css-generator.js.map +1 -1
- package/esm/css-generator.spec.js.map +1 -1
- package/esm/models/css-object.d.ts +3 -5
- package/esm/models/css-object.d.ts.map +1 -1
- package/esm/models/render-options.d.ts +16 -20
- package/esm/models/render-options.d.ts.map +1 -1
- package/esm/models/shade-component.d.ts +6 -4
- package/esm/models/shade-component.d.ts.map +1 -1
- package/esm/models/shade-component.js +3 -3
- package/esm/models/shade-component.js.map +1 -1
- package/esm/services/location-service.d.ts +39 -42
- package/esm/services/location-service.d.ts.map +1 -1
- package/esm/services/location-service.js +115 -134
- package/esm/services/location-service.js.map +1 -1
- package/esm/services/location-service.spec.js +32 -30
- package/esm/services/location-service.spec.js.map +1 -1
- package/esm/services/route-match-service.d.ts +3 -2
- package/esm/services/route-match-service.d.ts.map +1 -1
- package/esm/services/route-match-service.js +13 -22
- package/esm/services/route-match-service.js.map +1 -1
- package/esm/services/route-match-service.spec.js +40 -51
- package/esm/services/route-match-service.spec.js.map +1 -1
- package/esm/services/route-meta-utils.js.map +1 -1
- package/esm/services/route-meta-utils.spec.js +3 -3
- package/esm/services/route-meta-utils.spec.js.map +1 -1
- package/esm/services/screen-service.d.ts +13 -72
- package/esm/services/screen-service.d.ts.map +1 -1
- package/esm/services/screen-service.js +45 -137
- package/esm/services/screen-service.js.map +1 -1
- package/esm/services/screen-service.spec.js +19 -18
- package/esm/services/screen-service.spec.js.map +1 -1
- package/esm/services/spatial-navigation-service.d.ts +17 -39
- package/esm/services/spatial-navigation-service.d.ts.map +1 -1
- package/esm/services/spatial-navigation-service.js +280 -313
- package/esm/services/spatial-navigation-service.js.map +1 -1
- package/esm/services/spatial-navigation-service.spec.js +163 -158
- package/esm/services/spatial-navigation-service.spec.js.map +1 -1
- package/esm/shade-component.d.ts +14 -17
- package/esm/shade-component.d.ts.map +1 -1
- package/esm/shade-component.js +14 -17
- package/esm/shade-component.js.map +1 -1
- package/esm/shade.d.ts +18 -15
- package/esm/shade.d.ts.map +1 -1
- package/esm/shade.js +22 -32
- package/esm/shade.js.map +1 -1
- package/esm/style-manager.d.ts +8 -22
- package/esm/style-manager.d.ts.map +1 -1
- package/esm/style-manager.js +8 -22
- package/esm/style-manager.js.map +1 -1
- package/esm/styled-shade.d.ts +4 -7
- package/esm/styled-shade.d.ts.map +1 -1
- package/esm/styled-shade.js +4 -4
- package/esm/styled-shade.js.map +1 -1
- package/esm/view-transition.d.ts +10 -22
- package/esm/view-transition.d.ts.map +1 -1
- package/esm/view-transition.js +10 -22
- package/esm/view-transition.js.map +1 -1
- package/esm/vnode.js.map +1 -1
- package/esm/vnode.spec.js.map +1 -1
- package/package.json +9 -8
- package/src/compile-route.ts +5 -0
- package/src/component-factory.spec.tsx +3 -2
- package/src/components/nested-hooks.spec.ts +14 -14
- package/src/components/nested-hooks.ts +2 -2
- package/src/components/nested-navigate.spec.ts +17 -16
- package/src/components/nested-navigate.ts +1 -1
- package/src/components/nested-replace.spec.ts +7 -6
- package/src/components/nested-replace.ts +1 -1
- package/src/components/nested-route-link.spec.tsx +8 -8
- package/src/components/nested-route-link.tsx +1 -1
- package/src/components/nested-router.spec.tsx +24 -24
- package/src/components/nested-router.tsx +5 -5
- package/src/css-generator.spec.ts +1 -1
- package/src/css-generator.ts +9 -26
- package/src/models/css-object.ts +3 -5
- package/src/models/render-options.ts +17 -20
- package/src/models/shade-component.ts +6 -4
- package/src/services/location-service.spec.ts +35 -31
- package/src/services/location-service.tsx +156 -122
- package/src/services/route-match-service.spec.ts +41 -32
- package/src/services/route-match-service.ts +17 -8
- package/src/services/route-meta-utils.spec.ts +3 -3
- package/src/services/route-meta-utils.ts +1 -1
- package/src/services/screen-service.spec.ts +21 -20
- package/src/services/screen-service.ts +65 -110
- package/src/services/spatial-navigation-service.spec.ts +165 -160
- package/src/services/spatial-navigation-service.ts +299 -287
- package/src/shade-component.ts +14 -17
- package/src/shade.ts +31 -41
- package/src/style-manager.ts +9 -22
- package/src/styled-shade.ts +5 -8
- package/src/view-transition.ts +10 -22
- package/src/vnode.spec.ts +3 -3
- package/src/vnode.ts +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Token } from '@furystack/inject'
|
|
2
|
+
import { defineService } from '@furystack/inject'
|
|
2
3
|
import { ObservableValue } from '@furystack/utils'
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -19,134 +20,88 @@ export type Breakpoint = { name: ScreenSize; minSize: number; maxSize?: number }
|
|
|
19
20
|
/**
|
|
20
21
|
* Service for detecting and subscribing to screen size and orientation changes.
|
|
21
22
|
*
|
|
22
|
-
* This service provides reactive observables for responsive design decisions.
|
|
23
23
|
* Use `screenSize.atLeast[size]` to check if the viewport is at least a certain size.
|
|
24
24
|
*
|
|
25
25
|
* **Breakpoint Thresholds:**
|
|
26
|
-
* - `xs`: 0px+
|
|
27
|
-
* - `sm`: 600px+
|
|
28
|
-
* - `md`: 960px+
|
|
29
|
-
* - `lg`: 1280px+
|
|
30
|
-
* - `xl`: 1920px+
|
|
26
|
+
* - `xs`: 0px+
|
|
27
|
+
* - `sm`: 600px+
|
|
28
|
+
* - `md`: 960px+
|
|
29
|
+
* - `lg`: 1280px+
|
|
30
|
+
* - `xl`: 1920px+
|
|
31
31
|
*
|
|
32
32
|
* @example
|
|
33
33
|
* ```typescript
|
|
34
|
-
* const screenService = injector.
|
|
34
|
+
* const screenService = injector.get(ScreenService)
|
|
35
35
|
*
|
|
36
|
-
* // Check if screen is at least medium size
|
|
37
36
|
* if (screenService.screenSize.atLeast.md.getValue()) {
|
|
38
|
-
* //
|
|
37
|
+
* // Desktop layout
|
|
39
38
|
* }
|
|
40
39
|
*
|
|
41
|
-
* // Subscribe to size changes for responsive behavior
|
|
42
40
|
* screenService.screenSize.atLeast.md.subscribe((isAtLeastMd) => {
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* } else {
|
|
46
|
-
* console.log('Mobile view');
|
|
47
|
-
* }
|
|
48
|
-
* });
|
|
49
|
-
*
|
|
50
|
-
* // Get current breakpoint by checking from largest to smallest
|
|
51
|
-
* const getCurrentBreakpoint = (): ScreenSize => {
|
|
52
|
-
* if (screenService.screenSize.atLeast.xl.getValue()) return 'xl';
|
|
53
|
-
* if (screenService.screenSize.atLeast.lg.getValue()) return 'lg';
|
|
54
|
-
* if (screenService.screenSize.atLeast.md.getValue()) return 'md';
|
|
55
|
-
* if (screenService.screenSize.atLeast.sm.getValue()) return 'sm';
|
|
56
|
-
* return 'xs';
|
|
57
|
-
* };
|
|
58
|
-
*
|
|
59
|
-
* // Subscribe to orientation changes
|
|
60
|
-
* screenService.orientation.subscribe((orientation) => {
|
|
61
|
-
* console.log(`Screen is now in ${orientation} mode`);
|
|
62
|
-
* });
|
|
41
|
+
* // react to breakpoint changes
|
|
42
|
+
* })
|
|
63
43
|
* ```
|
|
64
44
|
*/
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* The definitions of the breakpoint thresholds in pixels.
|
|
71
|
-
* Each breakpoint represents the minimum width for that size category.
|
|
72
|
-
*/
|
|
73
|
-
public readonly breakpoints: { [K in ScreenSize]: { minSize: number } } = {
|
|
74
|
-
xl: { minSize: 1920 },
|
|
75
|
-
lg: { minSize: 1280 },
|
|
76
|
-
md: { minSize: 960 },
|
|
77
|
-
sm: { minSize: 600 },
|
|
78
|
-
xs: { minSize: 0 },
|
|
45
|
+
export interface ScreenService {
|
|
46
|
+
readonly breakpoints: { [K in ScreenSize]: { minSize: number } }
|
|
47
|
+
readonly screenSize: {
|
|
48
|
+
atLeast: { [K in ScreenSize]: ObservableValue<boolean> }
|
|
79
49
|
}
|
|
50
|
+
readonly orientation: ObservableValue<'landscape' | 'portrait'>
|
|
51
|
+
}
|
|
80
52
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Object.values(this.screenSize.atLeast).forEach((observable) => {
|
|
88
|
-
observable[Symbol.dispose]()
|
|
89
|
-
})
|
|
90
|
-
}
|
|
53
|
+
export const ScreenService: Token<ScreenService, 'singleton'> = defineService({
|
|
54
|
+
name: '@furystack/shades/ScreenService',
|
|
55
|
+
lifetime: 'singleton',
|
|
56
|
+
factory: ({ onDispose }) => {
|
|
57
|
+
const getOrientation = (): 'landscape' | 'portrait' =>
|
|
58
|
+
window.matchMedia?.('(orientation:landscape').matches ? 'landscape' : 'portrait'
|
|
91
59
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
* ```typescript
|
|
100
|
-
* // Hide sidebar on small screens
|
|
101
|
-
* screenService.screenSize.atLeast.md.subscribe((isAtLeastMd) => {
|
|
102
|
-
* sidebarVisible.setValue(isAtLeastMd);
|
|
103
|
-
* });
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
|
-
public readonly screenSize: {
|
|
107
|
-
atLeast: { [K in ScreenSize]: ObservableValue<boolean> }
|
|
108
|
-
} = {
|
|
109
|
-
atLeast: {
|
|
110
|
-
xs: new ObservableValue<boolean>(this.screenSizeAtLeast('xs')),
|
|
111
|
-
sm: new ObservableValue<boolean>(this.screenSizeAtLeast('sm')),
|
|
112
|
-
md: new ObservableValue<boolean>(this.screenSizeAtLeast('md')),
|
|
113
|
-
lg: new ObservableValue<boolean>(this.screenSizeAtLeast('lg')),
|
|
114
|
-
xl: new ObservableValue<boolean>(this.screenSizeAtLeast('xl')),
|
|
115
|
-
},
|
|
116
|
-
}
|
|
60
|
+
const breakpoints: { [K in ScreenSize]: { minSize: number } } = {
|
|
61
|
+
xl: { minSize: 1920 },
|
|
62
|
+
lg: { minSize: 1280 },
|
|
63
|
+
md: { minSize: 960 },
|
|
64
|
+
sm: { minSize: 600 },
|
|
65
|
+
xs: { minSize: 0 },
|
|
66
|
+
}
|
|
117
67
|
|
|
118
|
-
|
|
119
|
-
return window.innerWidth >= this.breakpoints[size].minSize
|
|
120
|
-
}
|
|
68
|
+
const screenSizeAtLeast = (size: ScreenSize): boolean => window.innerWidth >= breakpoints[size].minSize
|
|
121
69
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
* if (orientation === 'landscape') {
|
|
130
|
-
* // Adjust layout for landscape mode
|
|
131
|
-
* }
|
|
132
|
-
* });
|
|
133
|
-
* ```
|
|
134
|
-
*/
|
|
135
|
-
public orientation = new ObservableValue<'landscape' | 'portrait'>(this.getOrientation())
|
|
70
|
+
const atLeast: { [K in ScreenSize]: ObservableValue<boolean> } = {
|
|
71
|
+
xs: new ObservableValue<boolean>(screenSizeAtLeast('xs')),
|
|
72
|
+
sm: new ObservableValue<boolean>(screenSizeAtLeast('sm')),
|
|
73
|
+
md: new ObservableValue<boolean>(screenSizeAtLeast('md')),
|
|
74
|
+
lg: new ObservableValue<boolean>(screenSizeAtLeast('lg')),
|
|
75
|
+
xl: new ObservableValue<boolean>(screenSizeAtLeast('xl')),
|
|
76
|
+
}
|
|
136
77
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
78
|
+
const orientation = new ObservableValue<'landscape' | 'portrait'>(getOrientation())
|
|
79
|
+
|
|
80
|
+
const refreshValues = (): void => {
|
|
81
|
+
orientation.setValue(getOrientation())
|
|
82
|
+
for (const size of ScreenSizes) {
|
|
83
|
+
atLeast[size].setValue(screenSizeAtLeast(size))
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const onResizeListener = (): void => {
|
|
88
|
+
refreshValues()
|
|
89
|
+
}
|
|
140
90
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
91
|
+
window.addEventListener('resize', onResizeListener)
|
|
92
|
+
refreshValues()
|
|
93
|
+
|
|
94
|
+
onDispose(() => {
|
|
95
|
+
window.removeEventListener('resize', onResizeListener)
|
|
96
|
+
// eslint-disable-next-line furystack/prefer-using-wrapper -- Disposal is deferred to the injector's onDispose hook.
|
|
97
|
+
orientation[Symbol.dispose]()
|
|
98
|
+
Object.values(atLeast).forEach((observable) => observable[Symbol.dispose]())
|
|
145
99
|
})
|
|
146
|
-
}
|
|
147
100
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
101
|
+
return {
|
|
102
|
+
breakpoints,
|
|
103
|
+
screenSize: { atLeast },
|
|
104
|
+
orientation,
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
})
|