@streamscloud/kit 0.54.0 → 0.55.0
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/dist/core/data-loaders/cursor-data-loader-with-search.svelte.d.ts +1 -0
- package/dist/core/data-loaders/cursor-data-loader-with-search.svelte.js +3 -0
- package/dist/core/data-loaders/cursor-data-loader.svelte.d.ts +1 -0
- package/dist/core/data-loaders/cursor-data-loader.svelte.js +3 -0
- package/dist/core/data-loaders/data-loader.d.ts +2 -0
- package/dist/core/data-loaders/page-data-loader.svelte.d.ts +1 -0
- package/dist/core/data-loaders/page-data-loader.svelte.js +3 -0
- package/dist/ui/player/buttons/cmp.mobile-player-buttons.svelte +30 -6
- package/dist/ui/player/buttons/cmp.mobile-player-buttons.svelte.d.ts +13 -4
- package/dist/ui/player/buttons/cmp.player-buttons.svelte +71 -20
- package/dist/ui/player/buttons/cmp.player-buttons.svelte.d.ts +12 -2
- package/dist/ui/player/buttons/cmp.responsive-player-buttons.svelte +12 -8
- package/dist/ui/player/buttons/cmp.responsive-player-buttons.svelte.d.ts +16 -6
- package/dist/ui/player/buttons/index.d.ts +1 -1
- package/dist/ui/player/buttons/player-buttons-localization.d.ts +3 -0
- package/dist/ui/player/buttons/player-buttons-localization.js +12 -0
- package/dist/ui/player/buttons/player-context-menu.svelte +20 -0
- package/dist/ui/player/buttons/player-context-menu.svelte.d.ts +9 -0
- package/dist/ui/player/buttons/types.d.ts +6 -0
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@ export declare class CursorDataLoaderWithSearch<T> implements IDataLoader<T> {
|
|
|
15
15
|
});
|
|
16
16
|
get searchString(): string;
|
|
17
17
|
get loading(): boolean;
|
|
18
|
+
get initialLoading(): boolean;
|
|
18
19
|
loadMore: () => Promise<T[]>;
|
|
19
20
|
reset(): Promise<void>;
|
|
20
21
|
updateSearchString: (searchString: string | null) => void;
|
|
@@ -11,6 +11,7 @@ export declare class CursorDataLoader<T> implements IDataLoader<T> {
|
|
|
11
11
|
loadPage: (continuationToken: ContinuationToken) => Promise<CursorResult<T> | null>;
|
|
12
12
|
});
|
|
13
13
|
get loading(): boolean;
|
|
14
|
+
get initialLoading(): boolean;
|
|
14
15
|
loadMore: () => Promise<T[]>;
|
|
15
16
|
reset(): Promise<void>;
|
|
16
17
|
private runLoad;
|
|
@@ -1,28 +1,42 @@
|
|
|
1
1
|
<script lang="ts">import { IconSlot } from '../../icon';
|
|
2
|
-
|
|
2
|
+
import PlayerContextMenu from './player-context-menu.svelte';
|
|
3
|
+
let { actions, contextActions = [], contextPosition = 'left-end' } = $props();
|
|
3
4
|
</script>
|
|
4
5
|
|
|
5
6
|
<div class="mobile-player-buttons">
|
|
6
|
-
{#each actions as action (
|
|
7
|
+
{#each actions as action, index (index)}
|
|
7
8
|
<button type="button" class="mobile-player-buttons__action" disabled={action.disabled} onclick={action.callback}>
|
|
8
9
|
<span class="mobile-player-buttons__action-icon">
|
|
9
10
|
<IconSlot icon={action.icon} />
|
|
10
11
|
</span>
|
|
11
12
|
</button>
|
|
12
13
|
{/each}
|
|
14
|
+
{#if contextActions.length}
|
|
15
|
+
<div class="mobile-player-buttons__action mobile-player-buttons__action--menu">
|
|
16
|
+
<PlayerContextMenu actions={contextActions} position={contextPosition} />
|
|
17
|
+
</div>
|
|
18
|
+
{/if}
|
|
13
19
|
</div>
|
|
14
20
|
|
|
15
21
|
<!--
|
|
16
22
|
@component
|
|
17
23
|
A vertically stacked column of player action buttons optimized for mobile touch targets.
|
|
24
|
+
`contextActions` appends an overflow-menu cell below the buttons.
|
|
18
25
|
|
|
19
|
-
###
|
|
20
|
-
|
|
|
26
|
+
### CSS Custom Properties
|
|
27
|
+
| Property | Description | Default |
|
|
21
28
|
|---|---|---|
|
|
22
|
-
| `
|
|
29
|
+
| `--sc-kit--player-button--color--inactive` | Overflow menu panel background | 60% opacity of `black` |
|
|
30
|
+
| `--sc-kit--player-button--menu--border-color` | Overflow menu panel border | `white` at 15% |
|
|
31
|
+
| `--sc-kit--player-button--menu--item--color` | Overflow menu row text / icon color | `--sc-kit--color--text--on-accent` |
|
|
32
|
+
| `--sc-kit--player-button--menu--item--background--hover` | Overflow menu row hover background | `white` at 12% |
|
|
23
33
|
-->
|
|
24
34
|
|
|
25
35
|
<style>.mobile-player-buttons {
|
|
36
|
+
--_player-button--color--inactive: var(--sc-kit--player-button--color--inactive, rgb(0 0 0 / 60%));
|
|
37
|
+
--_player-button--menu--border-color: var(--sc-kit--player-button--menu--border-color, rgb(255 255 255 / 15%));
|
|
38
|
+
--_player-button--menu--item-color: var(--sc-kit--player-button--menu--item--color, var(--sc-kit--color--text--on-accent));
|
|
39
|
+
--_player-button--menu--item-background-hover: var(--sc-kit--player-button--menu--item--background--hover, rgb(255 255 255 / 12%));
|
|
26
40
|
cursor: pointer;
|
|
27
41
|
display: flex;
|
|
28
42
|
flex-direction: column;
|
|
@@ -30,10 +44,11 @@ A vertically stacked column of player action buttons optimized for mobile touch
|
|
|
30
44
|
pointer-events: auto;
|
|
31
45
|
}
|
|
32
46
|
.mobile-player-buttons__action {
|
|
47
|
+
--_player-button--cell-padding: var(--sc-kit--space--4);
|
|
33
48
|
display: flex;
|
|
34
49
|
justify-content: center;
|
|
35
50
|
align-items: center;
|
|
36
|
-
padding: var(--
|
|
51
|
+
padding: var(--_player-button--cell-padding);
|
|
37
52
|
--sc-kit--icon--color: var(--sc-kit--color--text--on-accent);
|
|
38
53
|
--sc-kit--icon--size: 2rem;
|
|
39
54
|
--sc-kit--icon--filter: drop-shadow(1px 1px 0 rgba(0, 0, 0, 0.2));
|
|
@@ -42,6 +57,15 @@ A vertically stacked column of player action buttons optimized for mobile touch
|
|
|
42
57
|
opacity: 0.5;
|
|
43
58
|
cursor: default;
|
|
44
59
|
}
|
|
60
|
+
.mobile-player-buttons__action--menu {
|
|
61
|
+
padding: 0;
|
|
62
|
+
min-block-size: calc(var(--sc-kit--icon--size) + 2 * var(--_player-button--cell-padding));
|
|
63
|
+
min-inline-size: calc(var(--sc-kit--icon--size) + 2 * var(--_player-button--cell-padding));
|
|
64
|
+
--sc-kit--popover--content--background: var(--_player-button--color--inactive);
|
|
65
|
+
--sc-kit--popover--content--border-color: var(--_player-button--menu--border-color);
|
|
66
|
+
--sc-kit--popover-item--color: var(--_player-button--menu--item-color);
|
|
67
|
+
--sc-kit--popover-item--background--hover: var(--_player-button--menu--item-background-hover);
|
|
68
|
+
}
|
|
45
69
|
.mobile-player-buttons__action-icon {
|
|
46
70
|
display: block;
|
|
47
71
|
}</style>
|
|
@@ -1,14 +1,23 @@
|
|
|
1
|
-
import type { PlayerButtonDef } from './types';
|
|
1
|
+
import type { PlayerButtonDef, PlayerContextActionDef } from './types';
|
|
2
|
+
import type { Placement } from '@floating-ui/dom';
|
|
2
3
|
type Props = {
|
|
3
4
|
actions: PlayerButtonDef[];
|
|
5
|
+
/** Rows of an overflow menu rendered as the final cell — an ellipsis trigger opening a popover. Empty ⇒ no menu cell. @default [] */
|
|
6
|
+
contextActions?: PlayerContextActionDef[];
|
|
7
|
+
/** Floating UI placement of the overflow menu panel @default 'left-end' */
|
|
8
|
+
contextPosition?: Placement;
|
|
4
9
|
};
|
|
5
10
|
/**
|
|
6
11
|
* A vertically stacked column of player action buttons optimized for mobile touch targets.
|
|
12
|
+
* `contextActions` appends an overflow-menu cell below the buttons.
|
|
7
13
|
*
|
|
8
|
-
* ###
|
|
9
|
-
* |
|
|
14
|
+
* ### CSS Custom Properties
|
|
15
|
+
* | Property | Description | Default |
|
|
10
16
|
* |---|---|---|
|
|
11
|
-
* | `
|
|
17
|
+
* | `--sc-kit--player-button--color--inactive` | Overflow menu panel background | 60% opacity of `black` |
|
|
18
|
+
* | `--sc-kit--player-button--menu--border-color` | Overflow menu panel border | `white` at 15% |
|
|
19
|
+
* | `--sc-kit--player-button--menu--item--color` | Overflow menu row text / icon color | `--sc-kit--color--text--on-accent` |
|
|
20
|
+
* | `--sc-kit--player-button--menu--item--background--hover` | Overflow menu row hover background | `white` at 12% |
|
|
12
21
|
*/
|
|
13
22
|
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
14
23
|
type Cmp = ReturnType<typeof Cmp>;
|
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
<script lang="ts">import { IconSlot } from '../../icon';
|
|
2
|
-
|
|
2
|
+
import PlayerContextMenu from './player-context-menu.svelte';
|
|
3
|
+
let { actions, contextActions = [], contextPosition = 'left-end', scaleEffect = false, zoom = 1 } = $props();
|
|
4
|
+
const hasMenu = $derived(contextActions.length > 0);
|
|
5
|
+
const cellCount = $derived(actions.length + (hasMenu ? 1 : 0));
|
|
3
6
|
</script>
|
|
4
7
|
|
|
5
|
-
{#if
|
|
6
|
-
{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{
|
|
8
|
+
{#if cellCount === 1}
|
|
9
|
+
{#if hasMenu}
|
|
10
|
+
<div class="player-button player-button--menu" style:zoom={zoom}>
|
|
11
|
+
<PlayerContextMenu actions={contextActions} position={contextPosition} />
|
|
12
|
+
</div>
|
|
13
|
+
{:else}
|
|
14
|
+
{@const action = actions[0]}
|
|
15
|
+
<button
|
|
16
|
+
type="button"
|
|
17
|
+
class="player-button"
|
|
18
|
+
style:zoom={zoom}
|
|
19
|
+
class:player-button--scale-effect={scaleEffect}
|
|
20
|
+
disabled={action.disabled}
|
|
21
|
+
onclick={action.callback}>
|
|
22
|
+
<span class="player-button__icon">
|
|
23
|
+
<IconSlot icon={action.icon} />
|
|
24
|
+
</span>
|
|
25
|
+
</button>
|
|
26
|
+
{/if}
|
|
27
|
+
{:else if cellCount > 1}
|
|
19
28
|
<div class="player-buttons" style:zoom={zoom}>
|
|
20
|
-
{#each actions as action (
|
|
29
|
+
{#each actions as action, index (index)}
|
|
21
30
|
<button
|
|
22
31
|
type="button"
|
|
23
32
|
class="player-buttons__action"
|
|
@@ -29,26 +38,40 @@ let { actions, scaleEffect = false, zoom = 1 } = $props();
|
|
|
29
38
|
</span>
|
|
30
39
|
</button>
|
|
31
40
|
{/each}
|
|
41
|
+
{#if hasMenu}
|
|
42
|
+
<div class="player-buttons__action player-buttons__action--menu">
|
|
43
|
+
<PlayerContextMenu actions={contextActions} position={contextPosition} />
|
|
44
|
+
</div>
|
|
45
|
+
{/if}
|
|
32
46
|
</div>
|
|
33
47
|
{/if}
|
|
34
48
|
|
|
35
49
|
<!--
|
|
36
50
|
@component
|
|
37
51
|
Desktop player action buttons — renders a single circular button or a vertically stacked pill for multiple actions.
|
|
52
|
+
`contextActions` adds an overflow-menu cell as the last item; it counts towards the single / pill split, so one
|
|
53
|
+
action plus a menu renders as a two-cell pill.
|
|
38
54
|
|
|
39
55
|
### CSS Custom Properties
|
|
40
56
|
| Property | Description | Default |
|
|
41
57
|
|---|---|---|
|
|
42
58
|
| `--sc-kit--player-button--color` | Button background at full opacity | `dark-500` / `black` at 95% |
|
|
43
|
-
| `--sc-kit--player-button--color--inactive` | Button background at rest | 60% opacity of `--color` |
|
|
59
|
+
| `--sc-kit--player-button--color--inactive` | Button background at rest — the overflow menu panel takes the same value | 60% opacity of `--color` |
|
|
60
|
+
| `--sc-kit--player-button--menu--border-color` | Overflow menu panel border | `white` at 15% |
|
|
61
|
+
| `--sc-kit--player-button--menu--item--color` | Overflow menu row text / icon color | `--sc-kit--color--text--on-accent` |
|
|
62
|
+
| `--sc-kit--player-button--menu--item--background--hover` | Overflow menu row hover background | `white` at 12% |
|
|
44
63
|
-->
|
|
45
64
|
|
|
46
65
|
<style>.player-button {
|
|
47
66
|
--_player-button--color: var(--sc-kit--player-button--color, rgb(0 0 0 / 95%));
|
|
48
67
|
--_player-button--color--inactive: var(--sc-kit--player-button--color--inactive, rgb(0 0 0 / 60%));
|
|
68
|
+
--_player-button--menu--border-color: var(--sc-kit--player-button--menu--border-color, rgb(255 255 255 / 15%));
|
|
69
|
+
--_player-button--menu--item-color: var(--sc-kit--player-button--menu--item--color, var(--sc-kit--color--text--on-accent));
|
|
70
|
+
--_player-button--menu--item-background-hover: var(--sc-kit--player-button--menu--item--background--hover, rgb(255 255 255 / 12%));
|
|
49
71
|
--_player-button--icon-scale: 1;
|
|
72
|
+
--_player-button--cell-padding: 0.625rem;
|
|
50
73
|
pointer-events: auto;
|
|
51
|
-
padding:
|
|
74
|
+
padding: var(--_player-button--cell-padding);
|
|
52
75
|
display: flex;
|
|
53
76
|
justify-content: center;
|
|
54
77
|
align-items: center;
|
|
@@ -69,6 +92,18 @@ Desktop player action buttons — renders a single circular button or a vertical
|
|
|
69
92
|
.player-button--scale-effect:hover:not(:disabled) {
|
|
70
93
|
--_player-button--icon-scale: 1.2;
|
|
71
94
|
}
|
|
95
|
+
.player-button--menu {
|
|
96
|
+
padding: 0;
|
|
97
|
+
min-block-size: calc(var(--sc-kit--icon--size) + 2 * var(--_player-button--cell-padding));
|
|
98
|
+
min-inline-size: calc(var(--sc-kit--icon--size) + 2 * var(--_player-button--cell-padding));
|
|
99
|
+
--sc-kit--popover--content--background: var(--_player-button--color--inactive);
|
|
100
|
+
--sc-kit--popover--content--border-color: var(--_player-button--menu--border-color);
|
|
101
|
+
--sc-kit--popover-item--color: var(--_player-button--menu--item-color);
|
|
102
|
+
--sc-kit--popover-item--background--hover: var(--_player-button--menu--item-background-hover);
|
|
103
|
+
}
|
|
104
|
+
.player-button--menu:hover:not(:disabled) {
|
|
105
|
+
background-color: var(--_player-button--color--inactive);
|
|
106
|
+
}
|
|
72
107
|
.player-button__icon {
|
|
73
108
|
display: block;
|
|
74
109
|
transform: scale(var(--_player-button--icon-scale));
|
|
@@ -79,7 +114,7 @@ Desktop player action buttons — renders a single circular button or a vertical
|
|
|
79
114
|
}
|
|
80
115
|
@container (width < 576px) {
|
|
81
116
|
.player-button {
|
|
82
|
-
padding: 0.5rem;
|
|
117
|
+
--_player-button--cell-padding: 0.5rem;
|
|
83
118
|
--sc-kit--icon--size: 1.5rem;
|
|
84
119
|
}
|
|
85
120
|
}
|
|
@@ -87,6 +122,9 @@ Desktop player action buttons — renders a single circular button or a vertical
|
|
|
87
122
|
.player-buttons {
|
|
88
123
|
--_player-button--color: var(--sc-kit--player-button--color, rgb(0 0 0 / 95%));
|
|
89
124
|
--_player-button--color--inactive: var(--sc-kit--player-button--color--inactive, rgb(0 0 0 / 60%));
|
|
125
|
+
--_player-button--menu--border-color: var(--sc-kit--player-button--menu--border-color, rgb(255 255 255 / 15%));
|
|
126
|
+
--_player-button--menu--item-color: var(--sc-kit--player-button--menu--item--color, var(--sc-kit--color--text--on-accent));
|
|
127
|
+
--_player-button--menu--item-background-hover: var(--sc-kit--player-button--menu--item--background--hover, rgb(255 255 255 / 12%));
|
|
90
128
|
cursor: pointer;
|
|
91
129
|
display: flex;
|
|
92
130
|
flex-direction: column;
|
|
@@ -98,10 +136,11 @@ Desktop player action buttons — renders a single circular button or a vertical
|
|
|
98
136
|
}
|
|
99
137
|
.player-buttons__action {
|
|
100
138
|
--_player-button--icon-scale: 1;
|
|
139
|
+
--_player-button--cell-padding: 0.5625rem;
|
|
101
140
|
display: flex;
|
|
102
141
|
justify-content: center;
|
|
103
142
|
align-items: center;
|
|
104
|
-
padding:
|
|
143
|
+
padding: var(--_player-button--cell-padding);
|
|
105
144
|
border-radius: 1.25rem;
|
|
106
145
|
color: var(--sc-kit--color--text--on-accent);
|
|
107
146
|
--sc-kit--icon--color: var(--sc-kit--color--text--on-accent);
|
|
@@ -119,6 +158,18 @@ Desktop player action buttons — renders a single circular button or a vertical
|
|
|
119
158
|
--_player-button--icon-scale: 1.2;
|
|
120
159
|
background-color: transparent;
|
|
121
160
|
}
|
|
161
|
+
.player-buttons__action--menu {
|
|
162
|
+
padding: 0;
|
|
163
|
+
min-block-size: calc(var(--sc-kit--icon--size) + 2 * var(--_player-button--cell-padding));
|
|
164
|
+
min-inline-size: calc(var(--sc-kit--icon--size) + 2 * var(--_player-button--cell-padding));
|
|
165
|
+
--sc-kit--popover--content--background: var(--_player-button--color--inactive);
|
|
166
|
+
--sc-kit--popover--content--border-color: var(--_player-button--menu--border-color);
|
|
167
|
+
--sc-kit--popover-item--color: var(--_player-button--menu--item-color);
|
|
168
|
+
--sc-kit--popover-item--background--hover: var(--_player-button--menu--item-background-hover);
|
|
169
|
+
}
|
|
170
|
+
.player-buttons__action--menu:hover:not(:disabled) {
|
|
171
|
+
background-color: transparent;
|
|
172
|
+
}
|
|
122
173
|
.player-buttons__action-icon {
|
|
123
174
|
display: block;
|
|
124
175
|
transform: scale(var(--_player-button--icon-scale));
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import type { PlayerButtonDef } from './types';
|
|
1
|
+
import type { PlayerButtonDef, PlayerContextActionDef } from './types';
|
|
2
|
+
import type { Placement } from '@floating-ui/dom';
|
|
2
3
|
type Props = {
|
|
3
4
|
/** Array of button definitions (icon, callback, disabled state) */
|
|
4
5
|
actions: PlayerButtonDef[];
|
|
6
|
+
/** Rows of an overflow menu rendered as the final cell — an ellipsis trigger opening a popover. Empty ⇒ no menu cell. @default [] */
|
|
7
|
+
contextActions?: PlayerContextActionDef[];
|
|
8
|
+
/** Floating UI placement of the overflow menu panel @default 'left-end' */
|
|
9
|
+
contextPosition?: Placement;
|
|
5
10
|
/** Scale the icon on hover */
|
|
6
11
|
scaleEffect?: boolean;
|
|
7
12
|
/** CSS zoom level applied to the button container @default 1 */
|
|
@@ -9,12 +14,17 @@ type Props = {
|
|
|
9
14
|
};
|
|
10
15
|
/**
|
|
11
16
|
* Desktop player action buttons — renders a single circular button or a vertically stacked pill for multiple actions.
|
|
17
|
+
* `contextActions` adds an overflow-menu cell as the last item; it counts towards the single / pill split, so one
|
|
18
|
+
* action plus a menu renders as a two-cell pill.
|
|
12
19
|
*
|
|
13
20
|
* ### CSS Custom Properties
|
|
14
21
|
* | Property | Description | Default |
|
|
15
22
|
* |---|---|---|
|
|
16
23
|
* | `--sc-kit--player-button--color` | Button background at full opacity | `dark-500` / `black` at 95% |
|
|
17
|
-
* | `--sc-kit--player-button--color--inactive` | Button background at rest | 60% opacity of `--color` |
|
|
24
|
+
* | `--sc-kit--player-button--color--inactive` | Button background at rest — the overflow menu panel takes the same value | 60% opacity of `--color` |
|
|
25
|
+
* | `--sc-kit--player-button--menu--border-color` | Overflow menu panel border | `white` at 15% |
|
|
26
|
+
* | `--sc-kit--player-button--menu--item--color` | Overflow menu row text / icon color | `--sc-kit--color--text--on-accent` |
|
|
27
|
+
* | `--sc-kit--player-button--menu--item--background--hover` | Overflow menu row hover background | `white` at 12% |
|
|
18
28
|
*/
|
|
19
29
|
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
20
30
|
type Cmp = ReturnType<typeof Cmp>;
|
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
<script lang="ts">import { default as MobilePlayerButtons } from './cmp.mobile-player-buttons.svelte';
|
|
2
2
|
import { default as PlayerButtons } from './cmp.player-buttons.svelte';
|
|
3
|
-
let { scaleEffect = false, actions } = $props();
|
|
3
|
+
let { scaleEffect = false, actions, contextActions = [], contextPosition = 'left-end' } = $props();
|
|
4
4
|
</script>
|
|
5
5
|
|
|
6
6
|
<div class="desktop-controls">
|
|
7
|
-
<PlayerButtons actions={actions} scaleEffect={scaleEffect} />
|
|
7
|
+
<PlayerButtons actions={actions} contextActions={contextActions} contextPosition={contextPosition} scaleEffect={scaleEffect} />
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
10
|
<div class="mobile-controls">
|
|
11
|
-
<MobilePlayerButtons actions={actions} />
|
|
11
|
+
<MobilePlayerButtons actions={actions} contextActions={contextActions} contextPosition={contextPosition} />
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
14
|
<!--
|
|
15
15
|
@component
|
|
16
16
|
Renders `PlayerButtons` on desktop and `MobilePlayerButtons` on mobile, switching via container query.
|
|
17
|
+
Both branches stay mounted, so `contextActions` builds a menu in each; only the visible one is reachable.
|
|
17
18
|
|
|
18
|
-
###
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
19
|
+
### CSS Custom Properties
|
|
20
|
+
| Property | Description | Default |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| `--sc-kit--player-button--color` | Button background at full opacity (desktop only — the mobile column paints no button background) | `black` at 95% |
|
|
23
|
+
| `--sc-kit--player-button--color--inactive` | Button background at rest — the overflow menu panel takes the same value | 60% opacity of `--color` |
|
|
24
|
+
| `--sc-kit--player-button--menu--border-color` | Overflow menu panel border | `white` at 15% |
|
|
25
|
+
| `--sc-kit--player-button--menu--item--color` | Overflow menu row text / icon color | `--sc-kit--color--text--on-accent` |
|
|
26
|
+
| `--sc-kit--player-button--menu--item--background--hover` | Overflow menu row hover background | `white` at 12% |
|
|
23
27
|
-->
|
|
24
28
|
|
|
25
29
|
<style>.desktop-controls {
|
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import type { PlayerButtonDef } from './types';
|
|
1
|
+
import type { PlayerButtonDef, PlayerContextActionDef } from './types';
|
|
2
|
+
import type { Placement } from '@floating-ui/dom';
|
|
2
3
|
type Props = {
|
|
3
4
|
actions: PlayerButtonDef[];
|
|
5
|
+
/** Rows of an overflow menu rendered as the final cell — an ellipsis trigger opening a popover. Empty ⇒ no menu cell. @default [] */
|
|
6
|
+
contextActions?: PlayerContextActionDef[];
|
|
7
|
+
/** Floating UI placement of the overflow menu panel @default 'left-end' */
|
|
8
|
+
contextPosition?: Placement;
|
|
9
|
+
/** Scale the icon on hover (desktop only) */
|
|
4
10
|
scaleEffect?: boolean;
|
|
5
11
|
};
|
|
6
12
|
/**
|
|
7
13
|
* Renders `PlayerButtons` on desktop and `MobilePlayerButtons` on mobile, switching via container query.
|
|
14
|
+
* Both branches stay mounted, so `contextActions` builds a menu in each; only the visible one is reachable.
|
|
8
15
|
*
|
|
9
|
-
* ###
|
|
10
|
-
* |
|
|
11
|
-
*
|
|
12
|
-
* | `
|
|
13
|
-
* | `
|
|
16
|
+
* ### CSS Custom Properties
|
|
17
|
+
* | Property | Description | Default |
|
|
18
|
+
* |---|---|---|
|
|
19
|
+
* | `--sc-kit--player-button--color` | Button background at full opacity (desktop only — the mobile column paints no button background) | `black` at 95% |
|
|
20
|
+
* | `--sc-kit--player-button--color--inactive` | Button background at rest — the overflow menu panel takes the same value | 60% opacity of `--color` |
|
|
21
|
+
* | `--sc-kit--player-button--menu--border-color` | Overflow menu panel border | `white` at 15% |
|
|
22
|
+
* | `--sc-kit--player-button--menu--item--color` | Overflow menu row text / icon color | `--sc-kit--color--text--on-accent` |
|
|
23
|
+
* | `--sc-kit--player-button--menu--item--background--hover` | Overflow menu row hover background | `white` at 12% |
|
|
14
24
|
*/
|
|
15
25
|
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
16
26
|
type Cmp = ReturnType<typeof Cmp>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as MobilePlayerButtons } from './cmp.mobile-player-buttons.svelte';
|
|
2
2
|
export { default as PlayerButtons } from './cmp.player-buttons.svelte';
|
|
3
3
|
export { default as ResponsivePlayerButtons } from './cmp.responsive-player-buttons.svelte';
|
|
4
|
-
export type { PlayerButtonDef } from './types';
|
|
4
|
+
export type { PlayerButtonDef, PlayerContextActionDef } from './types';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AppLocale } from '../../../core/locale';
|
|
2
|
+
const loc = {
|
|
3
|
+
moreActions: {
|
|
4
|
+
en: 'More actions',
|
|
5
|
+
no: 'Flere handlinger'
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
export class PlayerButtonsLocalization {
|
|
9
|
+
get moreActions() {
|
|
10
|
+
return loc.moreActions[AppLocale.current];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">import { IconSlot } from '../../icon';
|
|
2
|
+
import { IconText } from '../../icon-text';
|
|
3
|
+
import { Popover, PopoverItem } from '../../popover';
|
|
4
|
+
import { PlayerButtonsLocalization } from './player-buttons-localization';
|
|
5
|
+
import IconMoreVertical from '@fluentui/svg-icons/icons/more_vertical_28_regular.svg?raw';
|
|
6
|
+
let { actions, position = 'left-end' } = $props();
|
|
7
|
+
const localization = new PlayerButtonsLocalization();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<Popover position={position} fixedPosition fillContainer aria-label={localization.moreActions}>
|
|
11
|
+
{#snippet trigger()}
|
|
12
|
+
<IconSlot icon={IconMoreVertical} />
|
|
13
|
+
{/snippet}
|
|
14
|
+
|
|
15
|
+
{#each actions as action (action.label)}
|
|
16
|
+
<PopoverItem disabled={action.disabled} on={{ click: action.callback }}>
|
|
17
|
+
<IconText icon={action.icon} size="sm">{action.label}</IconText>
|
|
18
|
+
</PopoverItem>
|
|
19
|
+
{/each}
|
|
20
|
+
</Popover>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PlayerContextActionDef } from './types';
|
|
2
|
+
import type { Placement } from '@floating-ui/dom';
|
|
3
|
+
type Props = {
|
|
4
|
+
actions: PlayerContextActionDef[];
|
|
5
|
+
position?: Placement;
|
|
6
|
+
};
|
|
7
|
+
declare const PlayerContextMenu: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type PlayerContextMenu = ReturnType<typeof PlayerContextMenu>;
|
|
9
|
+
export default PlayerContextMenu;
|