@streamscloud/embeddable 15.0.2 → 15.1.0-1770736445096

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.
Files changed (69) hide show
  1. package/dist/ads/ad-card/cmp.ad-card.svelte +15 -21
  2. package/dist/ads/ad-card/cmp.ad-card.svelte.d.ts +0 -5
  3. package/dist/core/theme/brand-colors.svelte.d.ts +33 -0
  4. package/dist/core/theme/brand-colors.svelte.js +26 -0
  5. package/dist/core/theme/index.d.ts +3 -2
  6. package/dist/core/theme/index.js +1 -1
  7. package/dist/external-api/data-providers/internal-media-center-data-provider.svelte.js +2 -5
  8. package/dist/media-center/config/types.d.ts +0 -3
  9. package/dist/media-center/media-center/cmp.media-center-proxy.svelte +2 -9
  10. package/dist/media-center/media-center/footer/media-center-footer.svelte +1 -1
  11. package/dist/media-center/media-center/handlers/media-center-settings-handler.svelte.d.ts +1 -11
  12. package/dist/media-center/media-center/handlers/media-center-settings-handler.svelte.js +3 -14
  13. package/dist/media-center/media-center/header/media-center-header.svelte +8 -27
  14. package/dist/media-center/media-center/media-center-context.svelte.d.ts +0 -2
  15. package/dist/media-center/media-center/media-center-context.svelte.js +0 -3
  16. package/dist/media-center/media-center/menu/menu.svelte +2 -9
  17. package/dist/media-center/media-center/moments/cmp.moments-circle.svelte +1 -9
  18. package/dist/posts/attachments/cmp.attachments.svelte +6 -3
  19. package/dist/posts/attachments/cmp.attachments.svelte.d.ts +0 -6
  20. package/dist/posts/controls/post-actions-generator.svelte.js +3 -4
  21. package/dist/posts/post-viewer/cmp.post-viewer.svelte +5 -7
  22. package/dist/posts/post-viewer/cmp.post-viewer.svelte.d.ts +0 -4
  23. package/dist/posts/post-viewer/media/post-media.svelte +1 -6
  24. package/dist/posts/posts-player/posts-player-proxy.svelte +2 -10
  25. package/dist/posts/posts-player/posts-player-view.svelte +5 -13
  26. package/dist/posts/posts-player/types.d.ts +0 -3
  27. package/dist/products/product-card/cmp.product-card.svelte +4 -17
  28. package/dist/products/product-card/cmp.product-card.svelte.d.ts +0 -5
  29. package/dist/streams/controls/stream-actions-generator.svelte.js +3 -4
  30. package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte +1 -2
  31. package/dist/streams/layout/element-views/cmp.short-video-stream-element.svelte.d.ts +0 -4
  32. package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte +4 -6
  33. package/dist/streams/stream-page-viewer/cmp.stream-page-viewer.svelte.d.ts +0 -4
  34. package/dist/streams/streams-player/streams-player-proxy.svelte +2 -10
  35. package/dist/streams/streams-player/streams-player-view.svelte +5 -17
  36. package/dist/streams/streams-player/types.d.ts +0 -3
  37. package/dist/ui/button/resources/button-theme.svelte +5 -22
  38. package/dist/ui/icon/cmp.icon.svelte +0 -4
  39. package/dist/ui/player/button/{cmp.mobile-player-buttons-group.svelte → cmp.mobile-player-buttons.svelte} +10 -17
  40. package/dist/ui/player/button/cmp.player-buttons.svelte +127 -0
  41. package/dist/ui/player/button/{cmp.player-buttons-group.svelte.d.ts → cmp.player-buttons.svelte.d.ts} +1 -2
  42. package/dist/ui/player/button/cmp.responsive-player-buttons.svelte +32 -0
  43. package/dist/ui/player/button/{cmp.responsive-player-buttons-group.svelte.d.ts → cmp.responsive-player-buttons.svelte.d.ts} +1 -3
  44. package/dist/ui/player/button/index.d.ts +3 -4
  45. package/dist/ui/player/button/index.js +3 -4
  46. package/dist/ui/player/button/types.d.ts +1 -0
  47. package/dist/ui/player/player/cmp.player.svelte +1 -1
  48. package/dist/ui/player/player/controls-and-attachments.svelte +13 -26
  49. package/dist/ui/player/player/overview-panel.svelte +3 -9
  50. package/dist/ui/player/player/overview-panel.svelte.d.ts +10 -33
  51. package/dist/ui/player/player/player-config.svelte.d.ts +0 -1
  52. package/dist/ui/player/player/player-config.svelte.js +0 -3
  53. package/dist/ui/player/player/player-settings.svelte.d.ts +0 -5
  54. package/dist/ui/player/player/player-settings.svelte.js +0 -12
  55. package/dist/ui/shadow-dom/cmp.shadow-root.svelte +79 -62
  56. package/dist/ui/shadow-dom/cmp.shadow-root.svelte.d.ts +2 -1
  57. package/dist/ui/shadow-dom/colors.scss +53 -55
  58. package/package.json +1 -1
  59. package/dist/core/theme/theme-store.svelte.d.ts +0 -6
  60. package/dist/core/theme/theme-store.svelte.js +0 -10
  61. package/dist/ui/player/button/cmp.player-button.svelte +0 -74
  62. package/dist/ui/player/button/cmp.player-button.svelte.d.ts +0 -16
  63. package/dist/ui/player/button/cmp.player-buttons-group.svelte +0 -86
  64. package/dist/ui/player/button/cmp.responsive-player-buttons-group.svelte +0 -53
  65. package/dist/ui/player/colors/index.d.ts +0 -1
  66. package/dist/ui/player/colors/index.js +0 -1
  67. package/dist/ui/player/colors/player-colors.d.ts +0 -25
  68. package/dist/ui/player/colors/player-colors.js +0 -24
  69. /package/dist/ui/player/button/{cmp.mobile-player-buttons-group.svelte.d.ts → cmp.mobile-player-buttons.svelte.d.ts} +0 -0
@@ -11,16 +11,15 @@ import { initBufferFromProvider } from '../../ui/player/providers/service';
11
11
  import IconDelete from '@fluentui/svg-icons/icons/delete_32_regular.svg?raw';
12
12
  import IconEdit from '@fluentui/svg-icons/icons/edit_32_regular.svg?raw';
13
13
  import { untrack } from 'svelte';
14
- import { SvelteMap } from 'svelte/reactivity';
15
14
  let { dataProvider, socialInteractionsHandler, sharingHandler, playerSettings, analyticsHandler, managementActions, closeOrchestrator, on } = $props();
16
15
  let buffer = $state.raw(null);
17
- let mappedPostsCache = new SvelteMap();
16
+ let mappedPostsCache = {};
18
17
  $effect(() => {
19
18
  void dataProvider;
20
19
  untrack(() => {
21
20
  contentPlayerConfig.playerBuffer = null;
22
21
  buffer = null;
23
- mappedPostsCache = new SvelteMap();
22
+ mappedPostsCache = {};
24
23
  initBuffer(dataProvider);
25
24
  });
26
25
  });
@@ -92,11 +91,11 @@ const onAdImpression = (id) => {
92
91
  analyticsHandler?.trackAdImpression(id);
93
92
  };
94
93
  const itemAsPostModel = (item) => {
95
- if (mappedPostsCache.has(item.id)) {
96
- return mappedPostsCache.get(item.id);
94
+ if (mappedPostsCache[item.id]) {
95
+ return mappedPostsCache[item.id];
97
96
  }
98
97
  const postModel = new PostModel(item);
99
- mappedPostsCache.set(item.id, postModel);
98
+ mappedPostsCache[item.id] = postModel;
100
99
  return postModel;
101
100
  };
102
101
  const currentItemActions = $derived.by(() => {
@@ -141,12 +140,6 @@ const currentItemActions = $derived.by(() => {
141
140
 
142
141
  <PostAttachments
143
142
  model={postModel}
144
- colors={{
145
- background: contentPlayerConfig.playerColors.cardBackground,
146
- price: contentPlayerConfig.playerColors.price,
147
- salePrice: contentPlayerConfig.playerColors.salePrice,
148
- buttonBackground: contentPlayerConfig.playerColors.cardButton
149
- }}
150
143
  trackingParams={false}
151
144
  locale={contentPlayerConfig.settings.locale}
152
145
  on={{
@@ -165,7 +158,6 @@ const currentItemActions = $derived.by(() => {
165
158
  {@const handler = postActionsGenerator.getPostActionsHandler(postModel)}
166
159
  <PostViewer
167
160
  model={postModel}
168
- controlsColors={{ active: contentPlayerConfig.playerColors.button, inactive: contentPlayerConfig.playerColors.buttonInactive }}
169
161
  controlActions={handler.actions}
170
162
  trackingParams={false}
171
163
  enableAttachments={contentPlayerConfig.uiManager.showAttachmentsOverlay}
@@ -1,11 +1,9 @@
1
1
  import type { PostType } from '../../core/enums';
2
2
  import type { Locale } from '../../core/locale';
3
- import type { ThemeValue } from '../../core/theme';
4
3
  import type { IPostModel } from '..';
5
4
  import type { IPostSharingHandler } from '../sharing';
6
5
  import type { IPostSocialInteractionsHandler } from '../social-interactions';
7
6
  import type { ICloseOrchestrator } from '../../ui/player/close-orchestrator';
8
- import type { PlayerColors } from '../../ui/player/colors';
9
7
  import type { IPlayerBuffer, IPlayerDataProvider } from '../../ui/player/providers';
10
8
  export interface IPostAnalyticsHandler {
11
9
  trackPostOpened: (postType: PostType, postId: string) => void;
@@ -38,7 +36,6 @@ export type PostsPlayerProps = {
38
36
  export type PostPlayerSettings = {
39
37
  locale?: Locale;
40
38
  showStreamsCloudWatermark?: boolean;
41
- playerColors?: Record<ThemeValue, PlayerColors>;
42
39
  };
43
40
  export type PostManagementActions = {
44
41
  editPost: ((id: string) => void) | null;
@@ -4,7 +4,7 @@ import { Image } from '../../ui/image';
4
4
  import { LineClamp } from '../../ui/line-clamp';
5
5
  import { ProportionalContainer } from '../../ui/proportional-container';
6
6
  import { ProductCardLocalization } from './product-card-localization';
7
- let { product, colors, includeBeforeNowPrefix, trackingParams, inert = false, locale, on } = $props();
7
+ let { product, includeBeforeNowPrefix, trackingParams, inert = false, locale, on } = $props();
8
8
  const localization = $derived(new ProductCardLocalization(locale));
9
9
  const shortDescriptionPresented = $derived(product.shortDescription && product.shortDescription.length > 0);
10
10
  const trackImpression = (node) => {
@@ -36,22 +36,9 @@ const onProductClicked = (event) => {
36
36
  window.open(enrichedLink, '_blank', 'noopener noreferrer');
37
37
  }
38
38
  };
39
- const styles = $derived.by(() => {
40
- const values = [];
41
- if (colors?.background) {
42
- values.push(`--product-card--background-color: ${colors.background}`);
43
- }
44
- if (colors?.price) {
45
- values.push(`--product-card--price-color: ${colors.price}`);
46
- }
47
- if (colors?.salePrice) {
48
- values.push(`--product-card--sale-price-color: ${colors.salePrice}`);
49
- }
50
- return values.join(';');
51
- });
52
39
  </script>
53
40
 
54
- <div class="product-card" inert={inert} use:trackImpression style={styles}>
41
+ <div class="product-card" inert={inert} use:trackImpression>
55
42
  <ProportionalContainer ratio={1}>
56
43
  <Image src={product.image} />
57
44
  </ProportionalContainer>
@@ -102,8 +89,8 @@ const styles = $derived.by(() => {
102
89
  .product-card {
103
90
  --_product-card--aspect-ratio: var(--product-card--aspect-ratio, 10/16);
104
91
  --_product-card--border-radius: var(--product-card--border-radius, 0.5rem);
105
- --_product-card--background-color: var(--product-card--background-color, rgb(from var(--sc-mc-color--bg-card) r g b/90%));
106
- --_product-card--border-color: var(--product-card--background-color, var(--sc-mc-color--border-card));
92
+ --_product-card--background-color: var(--product-card--background-color, rgb(from light-dark(#ffffff, #000000) r g b / 90%));
93
+ --_product-card--border-color: var(--product-card--border-color, light-dark(#f2f2f2, #000000));
107
94
  --_product-card--price-color: var(--product-card--price-color, inherit);
108
95
  --_product-card--sale-price-color: var(--product-card--sale-price-color, inherit);
109
96
  --product-price-color: var(--_product-card--price-color);
@@ -3,11 +3,6 @@ import { type TrackingParams } from '../../marketing-tracking';
3
3
  import type { ProductCardModel } from './types';
4
4
  type Props = {
5
5
  product: ProductCardModel;
6
- colors: {
7
- background?: string | null;
8
- price?: string | null;
9
- salePrice?: string | null;
10
- };
11
6
  locale: Locale;
12
7
  includeBeforeNowPrefix?: boolean;
13
8
  inert?: boolean;
@@ -1,11 +1,10 @@
1
1
  import { PostActionsHandler } from '../../posts/controls';
2
2
  import IconShare from '@fluentui/svg-icons/icons/share_48_regular.svg?raw';
3
- import { SvelteMap } from 'svelte/reactivity';
4
3
  export class StreamActionsGenerator {
5
4
  postSocialInteractionsHandler;
6
5
  sharingHandler;
7
6
  callbacks;
8
- handlers = new SvelteMap();
7
+ handlers = {};
9
8
  constructor(init) {
10
9
  this.postSocialInteractionsHandler = init.postSocialInteractionsHandler ?? null;
11
10
  this.sharingHandler = init.sharingHandler ?? null;
@@ -13,7 +12,7 @@ export class StreamActionsGenerator {
13
12
  }
14
13
  getPostActionsHandler = (data) => {
15
14
  const { model, streamId, streamPageId } = data;
16
- let handler = this.handlers.get(streamPageId);
15
+ let handler = this.handlers[streamPageId];
17
16
  if (!handler) {
18
17
  handler = new PostActionsHandler({
19
18
  post: model,
@@ -23,7 +22,7 @@ export class StreamActionsGenerator {
23
22
  shareClicked: this.sharingHandler ? () => this.sharingHandler?.share(streamId) : undefined
24
23
  }
25
24
  });
26
- this.handlers.set(streamPageId, handler);
25
+ this.handlers[streamPageId] = handler;
27
26
  }
28
27
  return handler;
29
28
  };
@@ -2,13 +2,12 @@
2
2
  import { PostViewer } from '../../../posts/post-viewer';
3
3
  import { ShortVideoStreamElementLocalization } from './short-video-stream-element-localization';
4
4
  import { mapToPostModel } from '../models';
5
- let { data, trackingParams, locale, controlsColors = null, on } = $props();
5
+ let { data, trackingParams, locale, on } = $props();
6
6
  const localization = $derived(new ShortVideoStreamElementLocalization(locale));
7
7
  </script>
8
8
 
9
9
  <PostViewer
10
10
  model={new PostModel(mapToPostModel(data))}
11
- controlsColors={controlsColors}
12
11
  trackingParams={trackingParams ? { streamId: trackingParams.streamId, campaignId: trackingParams.campaignId } : false}
13
12
  autoplay={false}
14
13
  enableControls={false}
@@ -5,10 +5,6 @@ type Props = {
5
5
  data: StreamLayoutShortVideoModel;
6
6
  trackingParams: StreamTrackingParams;
7
7
  locale: Locale;
8
- controlsColors?: {
9
- active: string | null;
10
- inactive: string | null;
11
- } | null;
12
8
  on?: {
13
9
  progress?: (progress: number) => void;
14
10
  };
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">import { StreamLayoutSlot, StreamPageLayout, StreamLayoutSlotContent } from '../layout';
2
- import { ResponsivePlayerButtonsGroup } from '../../ui/player/button';
2
+ import { ResponsivePlayerButtons } from '../../ui/player/button';
3
3
  import { StreamPageViewerLocalization } from './stream-page-viewer-localization';
4
4
  let { page, trackingParams, overlayControls, locale, on, overlay } = $props();
5
5
  const localization = $derived(new StreamPageViewerLocalization(locale));
@@ -15,11 +15,7 @@ const localization = $derived(new StreamPageViewerLocalization(locale));
15
15
  {#snippet controls()}
16
16
  {#if overlayControls?.enabled && overlayControls.actions.length}
17
17
  <div class="controls-panel">
18
- <ResponsivePlayerButtonsGroup
19
- actions={overlayControls.actions}
20
- activeColor={overlayControls.colors?.active ?? null}
21
- backgroundColor={overlayControls.colors?.inactive ?? null}
22
- scaleEffect={true} />
18
+ <ResponsivePlayerButtons actions={overlayControls.actions} scaleEffect={true} />
23
19
  </div>
24
20
  {/if}
25
21
  {/snippet}
@@ -38,6 +34,8 @@ const localization = $derived(new StreamPageViewerLocalization(locale));
38
34
  }
39
35
  }
40
36
  .controls-panel {
37
+ --player-button--color: var(--sc-player--button);
38
+ --player-button--color--inactive: var(--sc-player--button-inactive);
41
39
  position: absolute;
42
40
  left: auto;
43
41
  right: 0;
@@ -9,10 +9,6 @@ type Props = {
9
9
  locale: Locale;
10
10
  overlayControls?: {
11
11
  enabled: boolean;
12
- colors: {
13
- active: string | null;
14
- inactive: string | null;
15
- } | null;
16
12
  actions: PlayerButtonDef[];
17
13
  };
18
14
  on?: {
@@ -1,22 +1,14 @@
1
- <script lang="ts">import { Theme } from '../../core/theme';
2
- import {} from '../../ui/player/close-orchestrator';
1
+ <script lang="ts">import {} from '../../ui/player/close-orchestrator';
3
2
  import { ShadowRoot } from '../../ui/shadow-dom';
4
3
  import { default as StreamsPlayerView } from './streams-player-view.svelte';
5
- import { untrack } from 'svelte';
6
4
  let { dataProvider, postSocialInteractionsHandler, sharingHandler, amplificationParameters, closeOrchestrator, playerSettings, analyticsHandler, on } = $props();
7
5
  let backgroundImageUrl = $state(null);
8
6
  const handleBackgroundImagedLoaded = (url) => {
9
7
  backgroundImageUrl = url;
10
8
  };
11
- $effect(() => {
12
- void playerSettings?.theme;
13
- untrack(() => {
14
- Theme.set(playerSettings?.theme ?? 'dark');
15
- });
16
- });
17
9
  </script>
18
10
 
19
- <ShadowRoot backgroundDisabled={playerSettings?.disableBackground === true} backgroundImageUrl={backgroundImageUrl}>
11
+ <ShadowRoot theme={playerSettings?.theme ?? 'dark'} backgroundDisabled={playerSettings?.disableBackground === true} backgroundImageUrl={backgroundImageUrl}>
20
12
  <StreamsPlayerView
21
13
  dataProvider={{ type: 'provider', provider: dataProvider }}
22
14
  postSocialInteractionsHandler={postSocialInteractionsHandler}
@@ -14,11 +14,10 @@ import { StreamsPlayerBuffer } from './streams-player-buffer.svelte';
14
14
  import IconDelete from '@fluentui/svg-icons/icons/delete_32_regular.svg?raw';
15
15
  import IconEdit from '@fluentui/svg-icons/icons/edit_32_regular.svg?raw';
16
16
  import { untrack } from 'svelte';
17
- import { SvelteMap } from 'svelte/reactivity';
18
17
  let { dataProvider, analyticsHandler, postSocialInteractionsHandler, sharingHandler, amplificationParameters, managementActions, playerSettings, closeOrchestrator, on } = $props();
19
18
  const localization = $derived(new StreamPlayerLocalization(playerSettings?.locale ?? 'en'));
20
19
  let currentStreamModel = $state(null);
21
- let mappedPostsCache = new SvelteMap();
20
+ let mappedPostsCache = {};
22
21
  let activePageId = $derived.by(() => buffer?.current?.id ?? '');
23
22
  let buffer = $state(null);
24
23
  let totalEngagementTimeSeconds = 0;
@@ -40,7 +39,7 @@ $effect(() => {
40
39
  untrack(() => {
41
40
  buffer = null;
42
41
  contentPlayerConfig.playerBuffer = null;
43
- mappedPostsCache = new SvelteMap();
42
+ mappedPostsCache = {};
44
43
  initPlayerBuffer(dataProvider);
45
44
  });
46
45
  return () => { };
@@ -112,11 +111,11 @@ const itemAsPostModel = (item) => {
112
111
  if (item.type !== 'short-video' || !item.shortVideo) {
113
112
  return null;
114
113
  }
115
- if (mappedPostsCache.has(item.shortVideo.id)) {
116
- return mappedPostsCache.get(item.shortVideo.id);
114
+ if (mappedPostsCache[item.shortVideo.id]) {
115
+ return mappedPostsCache[item.shortVideo.id];
117
116
  }
118
117
  const postModel = new PostModel(mapToPostModel(item.shortVideo));
119
- mappedPostsCache.set(item.shortVideo.id, postModel);
118
+ mappedPostsCache[item.shortVideo.id] = postModel;
120
119
  return postModel;
121
120
  };
122
121
  const handleChangePage = (index) => {
@@ -312,12 +311,6 @@ const stopActivityTracking = () => {
312
311
  {#if postModel}
313
312
  <PostAttachments
314
313
  model={postModel}
315
- colors={{
316
- background: contentPlayerConfig.playerColors.cardBackground,
317
- price: contentPlayerConfig.playerColors.price,
318
- salePrice: contentPlayerConfig.playerColors.salePrice,
319
- buttonBackground: contentPlayerConfig.playerColors.cardButton
320
- }}
321
314
  trackingParams={trackingParams}
322
315
  locale={contentPlayerConfig.settings.locale}
323
316
  on={{
@@ -360,10 +353,6 @@ const stopActivityTracking = () => {
360
353
  locale={localization.locale}
361
354
  overlayControls={{
362
355
  enabled: contentPlayerConfig.uiManager.showControlsOverlay,
363
- colors: {
364
- active: contentPlayerConfig.playerColors.button,
365
- inactive: contentPlayerConfig.playerColors.buttonInactive
366
- },
367
356
  actions: buffer?.activeChunk
368
357
  ? streamActionsGenerator.getGeneralStreamPageActions({ streamId: buffer.activeChunk.model.id, streamPageId: item.id })
369
358
  : []
@@ -386,7 +375,6 @@ const stopActivityTracking = () => {
386
375
  : null}
387
376
  <PostViewer
388
377
  model={postModel}
389
- controlsColors={{ active: contentPlayerConfig.playerColors.button, inactive: contentPlayerConfig.playerColors.buttonInactive }}
390
378
  trackingParams={trackingParams}
391
379
  enableAttachments={contentPlayerConfig.uiManager.showAttachmentsOverlay}
392
380
  enableControls={contentPlayerConfig.uiManager.showControlsOverlay}
@@ -1,10 +1,8 @@
1
1
  import type { Locale } from '../../core/locale';
2
- import type { ThemeValue } from '../../core/theme';
3
2
  import type { IPostSocialInteractionsHandler } from '../../posts/social-interactions';
4
3
  import type { IStreamSharingHandler } from '../sharing';
5
4
  import type { StreamPageViewerModel } from '../stream-page-viewer';
6
5
  import type { ICloseOrchestrator } from '../../ui/player/close-orchestrator';
7
- import type { PlayerColors } from '../../ui/player/colors';
8
6
  import type { StreamsPlayerBuffer } from './streams-player-buffer.svelte';
9
7
  export type StreamPlayerModel = {
10
8
  id: string;
@@ -47,7 +45,6 @@ export type StreamsPlayerProps = {
47
45
  export type StreamsPlayerSettings = {
48
46
  locale?: Locale;
49
47
  showStreamsCloudWatermark?: boolean;
50
- playerColors?: Record<ThemeValue, PlayerColors>;
51
48
  overlayMinOffsetTop?: number;
52
49
  };
53
50
  export type StreamAmplificationParameters = {
@@ -23,33 +23,16 @@ let { style = undefined, size = ButtonSize.Standard, children } = $props();
23
23
  {@render children()}
24
24
  </div>
25
25
 
26
- <style>@keyframes fadeIn {
27
- 0% {
28
- opacity: 1;
29
- }
30
- 50% {
31
- opacity: 0.4;
32
- }
33
- 100% {
34
- opacity: 1;
35
- }
36
- }
37
- .button-theme {
26
+ <style>.button-theme {
38
27
  display: contents;
39
28
  }
40
29
  .button-theme--standard {
41
30
  --button--font--color: var(--sc-mc-color--text-primary);
42
31
  --button--background: var(--sc-mc-color--bg-button);
43
- --button--background--hover: #f9fafb;
44
- --button--background--active: #f2f2f3;
45
- --button--background--disabled: #f2f2f3;
46
- --button--border: 1px solid #e5e7eb;
47
- }
48
- :global([data-theme='dark']) .button-theme--standard {
49
- --button--background--hover: #1f2937;
50
- --button--background--active: #374151;
51
- --button--background--disabled: #374151;
52
- --button--border: 1px solid #4b5563;
32
+ --button--background--hover: light-dark(#f9fafb, #1f2937);
33
+ --button--background--active: light-dark(#f2f2f3, #374151);
34
+ --button--background--disabled: light-dark(#f2f2f3, #374151);
35
+ --button--border: 1px solid light-dark(#e5e7eb, #4b5563);
53
36
  }
54
37
  .button-theme {
55
38
  /*Size*/
@@ -72,8 +72,4 @@ let { src, color = null } = $props();
72
72
  .icon :global(path) {
73
73
  stroke: var(--_icon--stroke-color, var(--_icon--color));
74
74
  stroke-width: var(--_icon--stroke-width);
75
- }
76
- :global([data-theme='dark']) .icon :global(path) {
77
- stroke: var(--_icon--stroke-color, var(--_icon--color));
78
- stroke-width: var(--_icon--stroke-width);
79
75
  }</style>
@@ -2,35 +2,24 @@
2
2
  let { actions } = $props();
3
3
  </script>
4
4
 
5
- <div class="mobile-player-buttons-group">
5
+ <div class="mobile-player-buttons">
6
6
  {#each actions as action (action.icon)}
7
- <button type="button" class="mobile-player-buttons-group__action" onclick={action.callback}>
8
- <span class="mobile-player-buttons-group__action-icon">
7
+ <button type="button" class="mobile-player-buttons__action" disabled={action.disabled} onclick={action.callback}>
8
+ <span class="mobile-player-buttons__action-icon">
9
9
  <Icon src={action.icon} color={action.iconColor} />
10
10
  </span>
11
11
  </button>
12
12
  {/each}
13
13
  </div>
14
14
 
15
- <style>@keyframes fadeIn {
16
- 0% {
17
- opacity: 1;
18
- }
19
- 50% {
20
- opacity: 0.4;
21
- }
22
- 100% {
23
- opacity: 1;
24
- }
25
- }
26
- .mobile-player-buttons-group {
15
+ <style>.mobile-player-buttons {
27
16
  cursor: pointer;
28
17
  display: flex;
29
18
  flex-direction: column;
30
19
  justify-content: center;
31
20
  pointer-events: auto;
32
21
  }
33
- .mobile-player-buttons-group__action {
22
+ .mobile-player-buttons__action {
34
23
  display: flex;
35
24
  justify-content: center;
36
25
  align-items: center;
@@ -39,6 +28,10 @@ let { actions } = $props();
39
28
  --icon--size: 2rem;
40
29
  --icon--filter: var(--sc-mc-color--icon-overlay-shadow);
41
30
  }
42
- .mobile-player-buttons-group__action-icon {
31
+ .mobile-player-buttons__action:disabled {
32
+ opacity: 0.5;
33
+ cursor: default;
34
+ }
35
+ .mobile-player-buttons__action-icon {
43
36
  display: block;
44
37
  }</style>
@@ -0,0 +1,127 @@
1
+ <script lang="ts">import { Icon } from '../../icon';
2
+ let { actions, scaleEffect = false, zoom = 1 } = $props();
3
+ </script>
4
+
5
+ {#if actions.length === 1}
6
+ {@const action = actions[0]}
7
+ <button
8
+ type="button"
9
+ class="player-button"
10
+ style:zoom={zoom}
11
+ class:player-button--scale-effect={scaleEffect}
12
+ disabled={action.disabled}
13
+ onclick={action.callback}>
14
+ <span class="player-button__icon">
15
+ <Icon src={action.icon} color={action.iconColor} />
16
+ </span>
17
+ </button>
18
+ {:else if actions.length > 1}
19
+ <div class="player-buttons" style:zoom={zoom}>
20
+ {#each actions as action (action.icon)}
21
+ <button
22
+ type="button"
23
+ class="player-buttons__action"
24
+ class:player-buttons__action--scale-effect={scaleEffect}
25
+ disabled={action.disabled}
26
+ onclick={action.callback}>
27
+ <span class="player-buttons__action-icon">
28
+ <Icon src={action.icon} color={action.iconColor} />
29
+ </span>
30
+ </button>
31
+ {/each}
32
+ </div>
33
+ {/if}
34
+
35
+ <style>.player-button {
36
+ --_player-button--color: var(--player-button--color, rgb(from light-dark(#272727, #000000) r g b / 95%));
37
+ --_player-button--color--inactive: var(--player-button--color--inactive, rgb(from var(--_player-button--color) r g b / 60%));
38
+ --_player-button--icon-scale: 1;
39
+ pointer-events: auto;
40
+ padding: 0.625rem;
41
+ display: flex;
42
+ justify-content: center;
43
+ align-items: center;
44
+ background-color: var(--_player-button--color--inactive);
45
+ transition: background-color 0.5s;
46
+ border-radius: 50%;
47
+ color: var(--sc-mc-color--text-white);
48
+ --icon--color: var(--sc-mc-color--icon-overlay);
49
+ --icon--size: 1.75rem;
50
+ }
51
+ .player-button:hover:not(:disabled) {
52
+ background-color: var(--_player-button--color);
53
+ }
54
+ .player-button:disabled {
55
+ opacity: 0.5;
56
+ cursor: default;
57
+ }
58
+ .player-button--scale-effect:hover:not(:disabled) {
59
+ --_player-button--icon-scale: 1.2;
60
+ }
61
+ .player-button__icon {
62
+ display: block;
63
+ transform: scale(var(--_player-button--icon-scale));
64
+ transition: 0.3s;
65
+ }
66
+ .player-button {
67
+ /* Set 'container-type: inline-size;' to reference container*/
68
+ }
69
+ @container (width < 576px) {
70
+ .player-button {
71
+ padding: 0.5rem;
72
+ --icon--size: 1.5rem;
73
+ }
74
+ }
75
+
76
+ .player-buttons {
77
+ --_player-button--color: var(--player-button--color, rgb(from light-dark(#272727, #000000) r g b / 95%));
78
+ --_player-button--color--inactive: var(--player-button--color--inactive, rgb(from var(--_player-button--color) r g b / 60%));
79
+ cursor: pointer;
80
+ display: flex;
81
+ flex-direction: column;
82
+ justify-content: center;
83
+ border-radius: 1.25rem;
84
+ background: var(--_player-button--color--inactive);
85
+ padding: 0.4375rem 0.0625rem;
86
+ pointer-events: auto;
87
+ }
88
+ .player-buttons__action {
89
+ --_player-button--icon-scale: 1;
90
+ display: flex;
91
+ justify-content: center;
92
+ align-items: center;
93
+ padding: 0.5625rem;
94
+ border-radius: 1.25rem;
95
+ color: var(--sc-mc-color--text-white);
96
+ --icon--color: var(--sc-mc-color--icon-overlay);
97
+ --icon--size: 1.75rem;
98
+ transition: background-color 0.5s;
99
+ }
100
+ .player-buttons__action:hover:not(:disabled) {
101
+ background-color: var(--_player-button--color);
102
+ }
103
+ .player-buttons__action:disabled {
104
+ opacity: 0.5;
105
+ cursor: default;
106
+ }
107
+ .player-buttons__action--scale-effect:hover:not(:disabled) {
108
+ --_player-button--icon-scale: 1.2;
109
+ background-color: transparent;
110
+ }
111
+ .player-buttons__action-icon {
112
+ display: block;
113
+ transform: scale(var(--_player-button--icon-scale));
114
+ transition: 0.3s;
115
+ }
116
+ .player-buttons {
117
+ /* Set 'container-type: inline-size;' to reference container*/
118
+ }
119
+ @container (width < 576px) {
120
+ .player-buttons {
121
+ border-radius: 0.9375rem;
122
+ padding: 0.25rem 0.0625rem;
123
+ }
124
+ .player-buttons__action {
125
+ --icon--size: 1.5rem;
126
+ }
127
+ }</style>
@@ -1,9 +1,8 @@
1
1
  import type { PlayerButtonDef } from './types';
2
2
  type Props = {
3
- activeColor: string | null;
4
- backgroundColor: string | null;
5
3
  actions: PlayerButtonDef[];
6
4
  scaleEffect?: boolean;
5
+ zoom?: number;
7
6
  };
8
7
  declare const Cmp: import("svelte").Component<Props, {}, "">;
9
8
  type Cmp = ReturnType<typeof Cmp>;
@@ -0,0 +1,32 @@
1
+ <script lang="ts">import { default as MobilePlayerButtons } from './cmp.mobile-player-buttons.svelte';
2
+ import { default as PlayerButtons } from './cmp.player-buttons.svelte';
3
+ let { scaleEffect = false, actions } = $props();
4
+ </script>
5
+
6
+ <div class="desktop-controls">
7
+ <PlayerButtons actions={actions} scaleEffect={scaleEffect} />
8
+ </div>
9
+
10
+ <div class="mobile-controls">
11
+ <MobilePlayerButtons actions={actions} />
12
+ </div>
13
+
14
+ <style>.desktop-controls {
15
+ display: contents;
16
+ /* Set 'container-type: inline-size;' to reference container*/
17
+ }
18
+ @container (width < 576px) {
19
+ .desktop-controls {
20
+ display: none;
21
+ }
22
+ }
23
+
24
+ .mobile-controls {
25
+ display: none;
26
+ /* Set 'container-type: inline-size;' to reference container*/
27
+ }
28
+ @container (width < 576px) {
29
+ .mobile-controls {
30
+ display: contents;
31
+ }
32
+ }</style>
@@ -1,7 +1,5 @@
1
- import { type PlayerButtonDef } from './';
1
+ import type { PlayerButtonDef } from './types';
2
2
  type Props = {
3
- activeColor: string | null;
4
- backgroundColor: string | null;
5
3
  actions: PlayerButtonDef[];
6
4
  scaleEffect?: boolean;
7
5
  };
@@ -1,5 +1,4 @@
1
- export { default as PlayerButton } from './cmp.player-button.svelte';
2
- export { default as PlayerButtonsGroup } from './cmp.player-buttons-group.svelte';
3
- export { default as MobilePlayerButtonsGroup } from './cmp.mobile-player-buttons-group.svelte';
4
- export { default as ResponsivePlayerButtonsGroup } from './cmp.responsive-player-buttons-group.svelte';
1
+ export { default as PlayerButtons } from './cmp.player-buttons.svelte';
2
+ export { default as MobilePlayerButtons } from './cmp.mobile-player-buttons.svelte';
3
+ export { default as ResponsivePlayerButtons } from './cmp.responsive-player-buttons.svelte';
5
4
  export type { PlayerButtonDef } from './types';
@@ -1,4 +1,3 @@
1
- export { default as PlayerButton } from './cmp.player-button.svelte';
2
- export { default as PlayerButtonsGroup } from './cmp.player-buttons-group.svelte';
3
- export { default as MobilePlayerButtonsGroup } from './cmp.mobile-player-buttons-group.svelte';
4
- export { default as ResponsivePlayerButtonsGroup } from './cmp.responsive-player-buttons-group.svelte';
1
+ export { default as PlayerButtons } from './cmp.player-buttons.svelte';
2
+ export { default as MobilePlayerButtons } from './cmp.mobile-player-buttons.svelte';
3
+ export { default as ResponsivePlayerButtons } from './cmp.responsive-player-buttons.svelte';
@@ -3,4 +3,5 @@ export type PlayerButtonDef = {
3
3
  icon: string;
4
4
  iconColor?: IconColor;
5
5
  callback: () => void;
6
+ disabled?: boolean;
6
7
  };