@streamscloud/embeddable 16.0.7-1772051881364 → 16.0.7-1772096232639
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/articles/article/article-layout.svelte +1 -1
- package/dist/articles/article/article-section.svelte +2 -2
- package/dist/articles/article/cmp.article.svelte +3 -3
- package/dist/articles/article/cmp.facts-container.svelte.d.ts +7 -0
- package/dist/articles/article/fields/article-field.svelte +8 -8
- package/dist/articles/article/fields/image-field.svelte +1 -1
- package/dist/articles/article/fields/media-field.svelte +1 -1
- package/dist/articles/article/fields/media-gallery-field.svelte +1 -1
- package/dist/articles/article/fields/text-field.svelte +1 -1
- package/dist/articles/article/fields/video-field.svelte +1 -1
- package/dist/articles/article/index.d.ts +1 -0
- package/dist/articles/article/index.js +1 -0
- package/dist/core/graphql.d.ts +4 -1
- package/dist/core/graphql.js +3 -3
- package/dist/external-api/article/cmp.embed-article.svelte +97 -0
- package/dist/external-api/article/cmp.embed-article.svelte.d.ts +42 -0
- package/dist/external-api/article/index.d.ts +1 -0
- package/dist/external-api/article/index.js +1 -0
- package/dist/external-api/article/operations.generated.d.ts +104 -0
- package/dist/external-api/article/operations.generated.js +262 -0
- package/dist/external-api/article/operations.graphql +99 -0
- package/dist/external-api/data-providers/internal-media-center-data-provider.svelte.js +1 -1
- package/dist/external-api/data-providers/internal-short-video-player-items-provider.js +1 -1
- package/dist/external-api/data-providers/internal-streams-player-data-provider.js +1 -1
- package/dist/external-api/index.d.ts +2 -1
- package/dist/external-api/index.js +2 -1
- package/package.json +1 -5
- package/dist/articles/article/facts-container.svelte.d.ts +0 -7
- package/dist/articles/article-viewer/article-viewer-host-settings.svelte.d.ts +0 -14
- package/dist/articles/article-viewer/article-viewer-host-settings.svelte.js +0 -11
- package/dist/articles/article-viewer/article-viewer-proxy.svelte +0 -9
- package/dist/articles/article-viewer/article-viewer-proxy.svelte.d.ts +0 -10
- package/dist/articles/article-viewer/article-viewer-view.svelte +0 -85
- package/dist/articles/article-viewer/article-viewer-view.svelte.d.ts +0 -9
- package/dist/articles/article-viewer/cmp.article-viewer.svelte +0 -34
- package/dist/articles/article-viewer/cmp.article-viewer.svelte.d.ts +0 -12
- package/dist/articles/article-viewer/index.d.ts +0 -43
- package/dist/articles/article-viewer/index.js +0 -60
- package/dist/articles/article-viewer/types.d.ts +0 -12
- package/dist/articles/article-viewer/types.js +0 -1
- /package/dist/articles/article/{facts-container.svelte → cmp.facts-container.svelte} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script lang="ts">import ArticleField from './fields/article-field.svelte';
|
|
1
|
+
<script lang="ts">import { default as ArticleField } from './fields/article-field.svelte';
|
|
2
2
|
import { fieldIsFilled } from './helpers';
|
|
3
3
|
import { generatePaddingsCssVar } from './styles-transformer';
|
|
4
4
|
let { layout, metadata } = $props();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<script lang="ts">import ArticleLayout from './article-layout.svelte';
|
|
2
|
-
import FactsContainer from './facts-container.svelte';
|
|
1
|
+
<script lang="ts">import { default as ArticleLayout } from './article-layout.svelte';
|
|
2
|
+
import { default as FactsContainer } from './cmp.facts-container.svelte';
|
|
3
3
|
import { layoutIsFilled } from './helpers';
|
|
4
4
|
import { generatePaddingsCssVar } from './styles-transformer';
|
|
5
5
|
import { HtmlHelper } from '@streamscloud/kit/core/utils';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script lang="ts">import ArticleSection from './article-section.svelte';
|
|
1
|
+
<script lang="ts">import { default as ArticleSection } from './article-section.svelte';
|
|
2
2
|
import { sectionIsFilled } from './helpers';
|
|
3
3
|
let { sections, metadata } = $props();
|
|
4
4
|
const filledSections = $derived(sections.filter(sectionIsFilled));
|
|
@@ -15,8 +15,8 @@ const fieldMetadata = $derived({ displayDate: metadata.displayDate });
|
|
|
15
15
|
|
|
16
16
|
<style>.article-container {
|
|
17
17
|
--_article--min-height: var(--article--min-height, 0);
|
|
18
|
-
--_article--background: var(--article--background, light-dark(#ffffff, #
|
|
19
|
-
--_article--text-color: var(--article--text-color);
|
|
18
|
+
--_article--background: var(--article--background, light-dark(#ffffff, #1e1e1e));
|
|
19
|
+
--_article--text-color: var(--article--text-color, light-dark(#000000, #ffffff));
|
|
20
20
|
container-type: inline-size;
|
|
21
21
|
min-height: var(--_article--min-height);
|
|
22
22
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<script lang="ts">import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
1
|
+
<script lang="ts">import { generateMarginsCssVar } from '../styles-transformer';
|
|
2
|
+
import { default as BylineField } from './byline-field.svelte';
|
|
3
|
+
import { default as ImageField } from './image-field.svelte';
|
|
4
|
+
import { default as MediaField } from './media-field.svelte';
|
|
5
|
+
import { default as MediaGalleryField } from './media-gallery-field.svelte';
|
|
6
|
+
import { default as RichTextField } from './rich-text-field.svelte';
|
|
7
|
+
import { default as TextField } from './text-field.svelte';
|
|
8
|
+
import { default as VideoField } from './video-field.svelte';
|
|
9
9
|
let { field, metadata } = $props();
|
|
10
10
|
const styles = $derived.by(() => {
|
|
11
11
|
const mobileStyles = generateMarginsCssVar({ styles: field.styles, mobileView: true });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">import { MediaItemView } from '../../../ui/media-items/media-item-view';
|
|
2
|
-
import AltText from './alt-text.svelte';
|
|
2
|
+
import { default as AltText } from './alt-text.svelte';
|
|
3
3
|
let { field } = $props();
|
|
4
4
|
const fieldData = $derived(field.fieldData.imageData);
|
|
5
5
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">import { MediaItemView } from '../../../ui/media-items/media-item-view';
|
|
2
|
-
import AltText from './alt-text.svelte';
|
|
2
|
+
import { default as AltText } from './alt-text.svelte';
|
|
3
3
|
let { field } = $props();
|
|
4
4
|
const fieldData = $derived(field.fieldData.mediaData);
|
|
5
5
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">import { MediaItemsGallery } from '../../../ui/media-items/media-items-gallery';
|
|
2
|
-
import AltText from './alt-text.svelte';
|
|
2
|
+
import { default as AltText } from './alt-text.svelte';
|
|
3
3
|
let { field } = $props();
|
|
4
4
|
const fieldData = $derived(field.fieldData.mediaGalleryData);
|
|
5
5
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">import { MediaItemView } from '../../../ui/media-items/media-item-view';
|
|
2
|
-
import AltText from './alt-text.svelte';
|
|
2
|
+
import { default as AltText } from './alt-text.svelte';
|
|
3
3
|
let { field } = $props();
|
|
4
4
|
const fieldData = $derived(field.fieldData.videoData);
|
|
5
5
|
</script>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { default as Article } from './cmp.article.svelte';
|
|
2
|
+
export { default as FactsContainer } from './cmp.facts-container.svelte';
|
|
2
3
|
export { fieldIsFilled, layoutIsFilled, sectionIsFilled } from './helpers';
|
|
3
4
|
export type { ArticleLayoutModel, ArticleLayoutStylesModel, ArticleMetadata, ArticleSectionModel, ArticleSectionStylesModel } from './types';
|
|
4
5
|
export type { ArticleFieldDataModel, ArticleFieldModel, ArticleFieldStylesModel, BylineFieldDataModel, FieldMetadata, ImageFieldDataModel, MediaFieldDataModel, MediaGalleryFieldDataModel, RichTextFieldDataModel, TextFieldDataModel, VideoFieldDataModel } from './fields/types';
|
package/dist/core/graphql.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
export declare const createLocalGQLClient: (graphqlOrigin?: string,
|
|
1
|
+
export declare const createLocalGQLClient: (graphqlOrigin?: string, options?: {
|
|
2
|
+
initiator?: string;
|
|
3
|
+
customFetch?: typeof fetch;
|
|
4
|
+
}) => any;
|
|
2
5
|
export declare const resolveGraphQLOrigin: (origin?: string) => string;
|
|
3
6
|
export declare const constructGraphQLUrl: (graphqlOrigin?: string) => string;
|
package/dist/core/graphql.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createGQLClient } from '@streamscloud/kit/core';
|
|
2
|
-
export const createLocalGQLClient = (graphqlOrigin,
|
|
2
|
+
export const createLocalGQLClient = (graphqlOrigin, options) => createGQLClient({
|
|
3
3
|
url: constructGraphQLUrl(resolveGraphQLOrigin(graphqlOrigin)),
|
|
4
|
-
headers,
|
|
5
|
-
customFetch
|
|
4
|
+
headers: options?.initiator ? { 'x-initiator': options.initiator } : undefined,
|
|
5
|
+
customFetch: options?.customFetch
|
|
6
6
|
});
|
|
7
7
|
export const resolveGraphQLOrigin = (origin) => {
|
|
8
8
|
return origin || 'https://api.streamscloud.com';
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<script lang="ts">import { Article } from '../../articles/article';
|
|
2
|
+
import { createLocalGQLClient } from '../../core/graphql';
|
|
3
|
+
import { GetEmbedArticleDocument } from './operations.generated';
|
|
4
|
+
import { untrack } from 'svelte';
|
|
5
|
+
let { id, slug, initiator, graphqlOrigin, on } = $props();
|
|
6
|
+
let sections = $state.raw(null);
|
|
7
|
+
let metadata = $state.raw(null);
|
|
8
|
+
let notFound = $state(false);
|
|
9
|
+
const mapSections = (article) => article.sections.map((section) => ({
|
|
10
|
+
id: section.id,
|
|
11
|
+
facts: section.facts,
|
|
12
|
+
styles: section.styles,
|
|
13
|
+
layouts: section.layouts.map((layout) => ({
|
|
14
|
+
id: layout.id,
|
|
15
|
+
styles: layout.styles,
|
|
16
|
+
fields: layout.fields.map((field) => ({
|
|
17
|
+
id: field.id,
|
|
18
|
+
name: field.name,
|
|
19
|
+
description: field.description,
|
|
20
|
+
styles: field.styles,
|
|
21
|
+
fieldData: field.fieldData
|
|
22
|
+
}))
|
|
23
|
+
}))
|
|
24
|
+
}));
|
|
25
|
+
const extractCoverImageUrl = (article) => {
|
|
26
|
+
for (const section of article.sections) {
|
|
27
|
+
for (const layout of section.layouts) {
|
|
28
|
+
for (const field of layout.fields) {
|
|
29
|
+
const { fieldData } = field;
|
|
30
|
+
const media = fieldData.imageData?.image ?? fieldData.mediaData?.media ?? fieldData.videoData?.video ?? fieldData.mediaGalleryData?.media?.[0];
|
|
31
|
+
if (media) {
|
|
32
|
+
return media.type === 'IMAGE' ? media.url : (media.thumbnailUrl ?? null);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
const load = async () => {
|
|
40
|
+
const graphql = createLocalGQLClient(graphqlOrigin, { initiator });
|
|
41
|
+
const result = await graphql.query(GetEmbedArticleDocument, { input: { id, slug } }).toPromise();
|
|
42
|
+
if (!result.data?.article) {
|
|
43
|
+
notFound = true;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const article = result.data.article;
|
|
47
|
+
sections = mapSections(article);
|
|
48
|
+
metadata = { displayDate: article.publishedAt ?? '' };
|
|
49
|
+
on?.seoLoaded?.({ ...article.seo, imageUrl: extractCoverImageUrl(article) });
|
|
50
|
+
};
|
|
51
|
+
$effect(() => {
|
|
52
|
+
untrack(() => {
|
|
53
|
+
void load();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
{#if notFound}
|
|
59
|
+
<div class="embed-article__not-found">¯\_(ツ)_/¯</div>
|
|
60
|
+
{:else if sections && metadata}
|
|
61
|
+
<Article sections={sections} metadata={metadata} />
|
|
62
|
+
{/if}
|
|
63
|
+
|
|
64
|
+
<!--
|
|
65
|
+
@component
|
|
66
|
+
Fetches and renders an article by `id` or `slug` via the `embedArticle` GraphQL query.
|
|
67
|
+
Displays a placeholder when the article is not found.
|
|
68
|
+
|
|
69
|
+
### Props
|
|
70
|
+
| Prop | Type | Description |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `id` | `string?` | Article ID to fetch |
|
|
73
|
+
| `slug` | `string?` | Article slug to fetch (alternative to `id`) |
|
|
74
|
+
| `initiator` | `string?` | Value for the `x-initiator` header |
|
|
75
|
+
| `graphqlOrigin` | `string?` | Custom GraphQL API origin |
|
|
76
|
+
|
|
77
|
+
### Callbacks (`on`)
|
|
78
|
+
| Callback | Type | Description |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| `seoLoaded` | `(seo: ArticleSeoModel) => void` | Called after article is loaded with SEO data and cover image URL |
|
|
81
|
+
|
|
82
|
+
### CSS Custom Properties
|
|
83
|
+
| Property | Description | Default |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `--article--background` | Article background color | `white` / `dark-800` |
|
|
86
|
+
| `--article--text-color` | Article text color | `black` / `white` |
|
|
87
|
+
| `--article--min-height` | Minimum article height | `0` |
|
|
88
|
+
-->
|
|
89
|
+
|
|
90
|
+
<style>.embed-article__not-found {
|
|
91
|
+
display: flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
min-height: 12.5rem;
|
|
95
|
+
font-size: 1.5rem;
|
|
96
|
+
color: light-dark(#9ca3af, #6b7280);
|
|
97
|
+
}</style>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type ArticleSeoModel = {
|
|
2
|
+
title: string;
|
|
3
|
+
description: string;
|
|
4
|
+
keywords: string[];
|
|
5
|
+
imageUrl: string | null;
|
|
6
|
+
};
|
|
7
|
+
type Props = {
|
|
8
|
+
id?: string;
|
|
9
|
+
slug?: string;
|
|
10
|
+
initiator?: string;
|
|
11
|
+
graphqlOrigin?: string;
|
|
12
|
+
on?: {
|
|
13
|
+
seoLoaded?: (seo: ArticleSeoModel) => void;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Fetches and renders an article by `id` or `slug` via the `embedArticle` GraphQL query.
|
|
18
|
+
* Displays a placeholder when the article is not found.
|
|
19
|
+
*
|
|
20
|
+
* ### Props
|
|
21
|
+
* | Prop | Type | Description |
|
|
22
|
+
* |---|---|---|
|
|
23
|
+
* | `id` | `string?` | Article ID to fetch |
|
|
24
|
+
* | `slug` | `string?` | Article slug to fetch (alternative to `id`) |
|
|
25
|
+
* | `initiator` | `string?` | Value for the `x-initiator` header |
|
|
26
|
+
* | `graphqlOrigin` | `string?` | Custom GraphQL API origin |
|
|
27
|
+
*
|
|
28
|
+
* ### Callbacks (`on`)
|
|
29
|
+
* | Callback | Type | Description |
|
|
30
|
+
* |---|---|---|
|
|
31
|
+
* | `seoLoaded` | `(seo: ArticleSeoModel) => void` | Called after article is loaded with SEO data and cover image URL |
|
|
32
|
+
*
|
|
33
|
+
* ### CSS Custom Properties
|
|
34
|
+
* | Property | Description | Default |
|
|
35
|
+
* |---|---|---|
|
|
36
|
+
* | `--article--background` | Article background color | `white` / `dark-800` |
|
|
37
|
+
* | `--article--text-color` | Article text color | `black` / `white` |
|
|
38
|
+
* | `--article--min-height` | Minimum article height | `0` |
|
|
39
|
+
*/
|
|
40
|
+
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
41
|
+
type Cmp = ReturnType<typeof Cmp>;
|
|
42
|
+
export default Cmp;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Article, type ArticleSeoModel } from './cmp.embed-article.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Article } from './cmp.embed-article.svelte';
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type * as SchemaTypes from '../../../gql/types';
|
|
2
|
+
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
3
|
+
export type GetEmbedArticleQueryVariables = SchemaTypes.Exact<{
|
|
4
|
+
input: SchemaTypes.EmbedArticleInput;
|
|
5
|
+
}>;
|
|
6
|
+
export type GetEmbedArticleQuery = {
|
|
7
|
+
article: {
|
|
8
|
+
id: string;
|
|
9
|
+
publishedAt: any | null;
|
|
10
|
+
seo: {
|
|
11
|
+
title: string;
|
|
12
|
+
description: string;
|
|
13
|
+
keywords: Array<string>;
|
|
14
|
+
};
|
|
15
|
+
sections: Array<{
|
|
16
|
+
id: string;
|
|
17
|
+
facts: string | null;
|
|
18
|
+
styles: {
|
|
19
|
+
paddingTop: number | null;
|
|
20
|
+
paddingBottom: number | null;
|
|
21
|
+
paddingLeft: number | null;
|
|
22
|
+
paddingRight: number | null;
|
|
23
|
+
} | null;
|
|
24
|
+
layouts: Array<{
|
|
25
|
+
id: string;
|
|
26
|
+
styles: {
|
|
27
|
+
paddingTop: number | null;
|
|
28
|
+
paddingBottom: number | null;
|
|
29
|
+
paddingLeft: number | null;
|
|
30
|
+
paddingRight: number | null;
|
|
31
|
+
} | null;
|
|
32
|
+
fields: Array<{
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
description: string | null;
|
|
36
|
+
styles: {
|
|
37
|
+
marginTop: number | null;
|
|
38
|
+
marginBottom: number | null;
|
|
39
|
+
marginLeft: number | null;
|
|
40
|
+
marginRight: number | null;
|
|
41
|
+
} | null;
|
|
42
|
+
fieldData: {
|
|
43
|
+
type: SchemaTypes.ArticleFieldType;
|
|
44
|
+
bylineData: {
|
|
45
|
+
authorName: string | null;
|
|
46
|
+
} | null;
|
|
47
|
+
imageData: {
|
|
48
|
+
preferredMediaFormat: SchemaTypes.MediaFormat;
|
|
49
|
+
altText: string | null;
|
|
50
|
+
image: {
|
|
51
|
+
type: SchemaTypes.MediaType;
|
|
52
|
+
url: string;
|
|
53
|
+
thumbnailUrl: string | null;
|
|
54
|
+
} | null;
|
|
55
|
+
} | null;
|
|
56
|
+
mediaData: {
|
|
57
|
+
preferredMediaFormat: SchemaTypes.MediaFormat;
|
|
58
|
+
altText: string | null;
|
|
59
|
+
media: {
|
|
60
|
+
type: SchemaTypes.MediaType;
|
|
61
|
+
url: string;
|
|
62
|
+
thumbnailUrl: string | null;
|
|
63
|
+
} | null;
|
|
64
|
+
} | null;
|
|
65
|
+
mediaGalleryData: {
|
|
66
|
+
galleryMode: SchemaTypes.GalleryFieldMode;
|
|
67
|
+
preferredMediaFormat: SchemaTypes.MediaFormat;
|
|
68
|
+
altText: string | null;
|
|
69
|
+
media: Array<{
|
|
70
|
+
type: SchemaTypes.MediaType;
|
|
71
|
+
url: string;
|
|
72
|
+
thumbnailUrl: string | null;
|
|
73
|
+
metadata: {
|
|
74
|
+
width: number;
|
|
75
|
+
height: number;
|
|
76
|
+
};
|
|
77
|
+
}> | null;
|
|
78
|
+
} | null;
|
|
79
|
+
richTextData: {
|
|
80
|
+
text: string | null;
|
|
81
|
+
textSize: number;
|
|
82
|
+
} | null;
|
|
83
|
+
textData: {
|
|
84
|
+
text: string | null;
|
|
85
|
+
textMode: SchemaTypes.TextFieldMode;
|
|
86
|
+
textSize: number;
|
|
87
|
+
textWeight: SchemaTypes.TextFieldWeight;
|
|
88
|
+
} | null;
|
|
89
|
+
videoData: {
|
|
90
|
+
preferredMediaFormat: SchemaTypes.MediaFormat;
|
|
91
|
+
altText: string | null;
|
|
92
|
+
video: {
|
|
93
|
+
type: SchemaTypes.MediaType;
|
|
94
|
+
url: string;
|
|
95
|
+
thumbnailUrl: string | null;
|
|
96
|
+
} | null;
|
|
97
|
+
} | null;
|
|
98
|
+
};
|
|
99
|
+
}>;
|
|
100
|
+
}>;
|
|
101
|
+
}>;
|
|
102
|
+
} | null;
|
|
103
|
+
};
|
|
104
|
+
export declare const GetEmbedArticleDocument: DocumentNode<GetEmbedArticleQuery, GetEmbedArticleQueryVariables>;
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
export const GetEmbedArticleDocument = {
|
|
2
|
+
kind: 'Document',
|
|
3
|
+
definitions: [
|
|
4
|
+
{
|
|
5
|
+
kind: 'OperationDefinition',
|
|
6
|
+
operation: 'query',
|
|
7
|
+
name: { kind: 'Name', value: 'GetEmbedArticle' },
|
|
8
|
+
variableDefinitions: [
|
|
9
|
+
{
|
|
10
|
+
kind: 'VariableDefinition',
|
|
11
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
12
|
+
type: { kind: 'NonNullType', type: { kind: 'NamedType', name: { kind: 'Name', value: 'EmbedArticleInput' } } }
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
selectionSet: {
|
|
16
|
+
kind: 'SelectionSet',
|
|
17
|
+
selections: [
|
|
18
|
+
{
|
|
19
|
+
kind: 'Field',
|
|
20
|
+
alias: { kind: 'Name', value: 'article' },
|
|
21
|
+
name: { kind: 'Name', value: 'embedArticle' },
|
|
22
|
+
arguments: [{ kind: 'Argument', name: { kind: 'Name', value: 'input' }, value: { kind: 'Variable', name: { kind: 'Name', value: 'input' } } }],
|
|
23
|
+
selectionSet: {
|
|
24
|
+
kind: 'SelectionSet',
|
|
25
|
+
selections: [
|
|
26
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
27
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'publishedAt' } },
|
|
28
|
+
{
|
|
29
|
+
kind: 'Field',
|
|
30
|
+
name: { kind: 'Name', value: 'seo' },
|
|
31
|
+
selectionSet: {
|
|
32
|
+
kind: 'SelectionSet',
|
|
33
|
+
selections: [
|
|
34
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'title' } },
|
|
35
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
|
|
36
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'keywords' } }
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
kind: 'Field',
|
|
42
|
+
name: { kind: 'Name', value: 'sections' },
|
|
43
|
+
selectionSet: {
|
|
44
|
+
kind: 'SelectionSet',
|
|
45
|
+
selections: [
|
|
46
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
47
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'facts' } },
|
|
48
|
+
{
|
|
49
|
+
kind: 'Field',
|
|
50
|
+
name: { kind: 'Name', value: 'styles' },
|
|
51
|
+
selectionSet: {
|
|
52
|
+
kind: 'SelectionSet',
|
|
53
|
+
selections: [
|
|
54
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'paddingTop' } },
|
|
55
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'paddingBottom' } },
|
|
56
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'paddingLeft' } },
|
|
57
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'paddingRight' } }
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
kind: 'Field',
|
|
63
|
+
name: { kind: 'Name', value: 'layouts' },
|
|
64
|
+
selectionSet: {
|
|
65
|
+
kind: 'SelectionSet',
|
|
66
|
+
selections: [
|
|
67
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
68
|
+
{
|
|
69
|
+
kind: 'Field',
|
|
70
|
+
name: { kind: 'Name', value: 'styles' },
|
|
71
|
+
selectionSet: {
|
|
72
|
+
kind: 'SelectionSet',
|
|
73
|
+
selections: [
|
|
74
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'paddingTop' } },
|
|
75
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'paddingBottom' } },
|
|
76
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'paddingLeft' } },
|
|
77
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'paddingRight' } }
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
kind: 'Field',
|
|
83
|
+
name: { kind: 'Name', value: 'fields' },
|
|
84
|
+
selectionSet: {
|
|
85
|
+
kind: 'SelectionSet',
|
|
86
|
+
selections: [
|
|
87
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
88
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
89
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
|
|
90
|
+
{
|
|
91
|
+
kind: 'Field',
|
|
92
|
+
name: { kind: 'Name', value: 'styles' },
|
|
93
|
+
selectionSet: {
|
|
94
|
+
kind: 'SelectionSet',
|
|
95
|
+
selections: [
|
|
96
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'marginTop' } },
|
|
97
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'marginBottom' } },
|
|
98
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'marginLeft' } },
|
|
99
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'marginRight' } }
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
kind: 'Field',
|
|
105
|
+
name: { kind: 'Name', value: 'fieldData' },
|
|
106
|
+
selectionSet: {
|
|
107
|
+
kind: 'SelectionSet',
|
|
108
|
+
selections: [
|
|
109
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'type' } },
|
|
110
|
+
{
|
|
111
|
+
kind: 'Field',
|
|
112
|
+
name: { kind: 'Name', value: 'bylineData' },
|
|
113
|
+
selectionSet: { kind: 'SelectionSet', selections: [{ kind: 'Field', name: { kind: 'Name', value: 'authorName' } }] }
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
kind: 'Field',
|
|
117
|
+
name: { kind: 'Name', value: 'imageData' },
|
|
118
|
+
selectionSet: {
|
|
119
|
+
kind: 'SelectionSet',
|
|
120
|
+
selections: [
|
|
121
|
+
{
|
|
122
|
+
kind: 'Field',
|
|
123
|
+
name: { kind: 'Name', value: 'image' },
|
|
124
|
+
selectionSet: {
|
|
125
|
+
kind: 'SelectionSet',
|
|
126
|
+
selections: [
|
|
127
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'type' } },
|
|
128
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'url' } },
|
|
129
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'thumbnailUrl' } }
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'preferredMediaFormat' } },
|
|
134
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'altText' } }
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
kind: 'Field',
|
|
140
|
+
name: { kind: 'Name', value: 'mediaData' },
|
|
141
|
+
selectionSet: {
|
|
142
|
+
kind: 'SelectionSet',
|
|
143
|
+
selections: [
|
|
144
|
+
{
|
|
145
|
+
kind: 'Field',
|
|
146
|
+
name: { kind: 'Name', value: 'media' },
|
|
147
|
+
selectionSet: {
|
|
148
|
+
kind: 'SelectionSet',
|
|
149
|
+
selections: [
|
|
150
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'type' } },
|
|
151
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'url' } },
|
|
152
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'thumbnailUrl' } }
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'preferredMediaFormat' } },
|
|
157
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'altText' } }
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
kind: 'Field',
|
|
163
|
+
name: { kind: 'Name', value: 'mediaGalleryData' },
|
|
164
|
+
selectionSet: {
|
|
165
|
+
kind: 'SelectionSet',
|
|
166
|
+
selections: [
|
|
167
|
+
{
|
|
168
|
+
kind: 'Field',
|
|
169
|
+
name: { kind: 'Name', value: 'media' },
|
|
170
|
+
selectionSet: {
|
|
171
|
+
kind: 'SelectionSet',
|
|
172
|
+
selections: [
|
|
173
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'type' } },
|
|
174
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'url' } },
|
|
175
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'thumbnailUrl' } },
|
|
176
|
+
{
|
|
177
|
+
kind: 'Field',
|
|
178
|
+
name: { kind: 'Name', value: 'metadata' },
|
|
179
|
+
selectionSet: {
|
|
180
|
+
kind: 'SelectionSet',
|
|
181
|
+
selections: [
|
|
182
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'width' } },
|
|
183
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'height' } }
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'galleryMode' } },
|
|
191
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'preferredMediaFormat' } },
|
|
192
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'altText' } }
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
kind: 'Field',
|
|
198
|
+
name: { kind: 'Name', value: 'richTextData' },
|
|
199
|
+
selectionSet: {
|
|
200
|
+
kind: 'SelectionSet',
|
|
201
|
+
selections: [
|
|
202
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'text' } },
|
|
203
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'textSize' } }
|
|
204
|
+
]
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
kind: 'Field',
|
|
209
|
+
name: { kind: 'Name', value: 'textData' },
|
|
210
|
+
selectionSet: {
|
|
211
|
+
kind: 'SelectionSet',
|
|
212
|
+
selections: [
|
|
213
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'text' } },
|
|
214
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'textMode' } },
|
|
215
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'textSize' } },
|
|
216
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'textWeight' } }
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
kind: 'Field',
|
|
222
|
+
name: { kind: 'Name', value: 'videoData' },
|
|
223
|
+
selectionSet: {
|
|
224
|
+
kind: 'SelectionSet',
|
|
225
|
+
selections: [
|
|
226
|
+
{
|
|
227
|
+
kind: 'Field',
|
|
228
|
+
name: { kind: 'Name', value: 'video' },
|
|
229
|
+
selectionSet: {
|
|
230
|
+
kind: 'SelectionSet',
|
|
231
|
+
selections: [
|
|
232
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'type' } },
|
|
233
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'url' } },
|
|
234
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'thumbnailUrl' } }
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'preferredMediaFormat' } },
|
|
239
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'altText' } }
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# noinspection GraphQLSchemaValidation
|
|
2
|
+
query GetEmbedArticle($input: EmbedArticleInput!) {
|
|
3
|
+
article: embedArticle(input: $input) {
|
|
4
|
+
id
|
|
5
|
+
publishedAt
|
|
6
|
+
seo {
|
|
7
|
+
title
|
|
8
|
+
description
|
|
9
|
+
keywords
|
|
10
|
+
}
|
|
11
|
+
sections {
|
|
12
|
+
id
|
|
13
|
+
facts
|
|
14
|
+
styles {
|
|
15
|
+
paddingTop
|
|
16
|
+
paddingBottom
|
|
17
|
+
paddingLeft
|
|
18
|
+
paddingRight
|
|
19
|
+
}
|
|
20
|
+
layouts {
|
|
21
|
+
id
|
|
22
|
+
styles {
|
|
23
|
+
paddingTop
|
|
24
|
+
paddingBottom
|
|
25
|
+
paddingLeft
|
|
26
|
+
paddingRight
|
|
27
|
+
}
|
|
28
|
+
fields {
|
|
29
|
+
id
|
|
30
|
+
name
|
|
31
|
+
description
|
|
32
|
+
styles {
|
|
33
|
+
marginTop
|
|
34
|
+
marginBottom
|
|
35
|
+
marginLeft
|
|
36
|
+
marginRight
|
|
37
|
+
}
|
|
38
|
+
fieldData {
|
|
39
|
+
type
|
|
40
|
+
bylineData {
|
|
41
|
+
authorName
|
|
42
|
+
}
|
|
43
|
+
imageData {
|
|
44
|
+
image {
|
|
45
|
+
type
|
|
46
|
+
url
|
|
47
|
+
thumbnailUrl
|
|
48
|
+
}
|
|
49
|
+
preferredMediaFormat
|
|
50
|
+
altText
|
|
51
|
+
}
|
|
52
|
+
mediaData {
|
|
53
|
+
media {
|
|
54
|
+
type
|
|
55
|
+
url
|
|
56
|
+
thumbnailUrl
|
|
57
|
+
}
|
|
58
|
+
preferredMediaFormat
|
|
59
|
+
altText
|
|
60
|
+
}
|
|
61
|
+
mediaGalleryData {
|
|
62
|
+
media {
|
|
63
|
+
type
|
|
64
|
+
url
|
|
65
|
+
thumbnailUrl
|
|
66
|
+
metadata {
|
|
67
|
+
width
|
|
68
|
+
height
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
galleryMode
|
|
72
|
+
preferredMediaFormat
|
|
73
|
+
altText
|
|
74
|
+
}
|
|
75
|
+
richTextData {
|
|
76
|
+
text
|
|
77
|
+
textSize
|
|
78
|
+
}
|
|
79
|
+
textData {
|
|
80
|
+
text
|
|
81
|
+
textMode
|
|
82
|
+
textSize
|
|
83
|
+
textWeight
|
|
84
|
+
}
|
|
85
|
+
videoData {
|
|
86
|
+
video {
|
|
87
|
+
type
|
|
88
|
+
url
|
|
89
|
+
thumbnailUrl
|
|
90
|
+
}
|
|
91
|
+
preferredMediaFormat
|
|
92
|
+
altText
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -13,7 +13,7 @@ export class InternalMediaCenterDataProvider {
|
|
|
13
13
|
graphql;
|
|
14
14
|
constructor(input) {
|
|
15
15
|
const { mediaPageId, graphqlOrigin, initiator, testingStuff, onNavigationStateChange } = input;
|
|
16
|
-
this.graphql = createLocalGQLClient(graphqlOrigin,
|
|
16
|
+
this.graphql = createLocalGQLClient(graphqlOrigin, { initiator });
|
|
17
17
|
this.fetchModel = async () => {
|
|
18
18
|
const payload = await this.graphql.query(GetMediaPageConfigDocument, { mediaPageId }).toPromise();
|
|
19
19
|
if (!payload.data?.embedMediaPage) {
|
|
@@ -37,7 +37,7 @@ export class InternalShortVideoPlayerItemsProvider {
|
|
|
37
37
|
});
|
|
38
38
|
constructor(input) {
|
|
39
39
|
const { ids, graphqlOrigin, initiator, initialId } = input;
|
|
40
|
-
this.graphql = createLocalGQLClient(graphqlOrigin,
|
|
40
|
+
this.graphql = createLocalGQLClient(graphqlOrigin, { initiator });
|
|
41
41
|
this.ids = ids;
|
|
42
42
|
ids.forEach((id, idx) => this.idOrder.set(id, idx));
|
|
43
43
|
const startIndex = initialId ? ids.indexOf(initialId) : 0;
|
|
@@ -36,7 +36,7 @@ export class InternalStreamsPlayerDataProvider {
|
|
|
36
36
|
});
|
|
37
37
|
constructor(input) {
|
|
38
38
|
const { ids, initialId, graphqlOrigin, initiator } = input;
|
|
39
|
-
this.graphql = createLocalGQLClient(graphqlOrigin,
|
|
39
|
+
this.graphql = createLocalGQLClient(graphqlOrigin, { initiator });
|
|
40
40
|
this.ids = ids;
|
|
41
41
|
if (initialId && this.ids.includes(initialId)) {
|
|
42
42
|
this.ids = [initialId, ...this.ids.filter((id) => id !== initialId)];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { Article, type ArticleSeoModel } from './article';
|
|
1
2
|
export { openMediaPageModal } from './media-page';
|
|
2
|
-
export { openStreamsPlayer } from './streams-player';
|
|
3
3
|
export { openShortVideosPlayer } from './short-videos-player';
|
|
4
|
+
export { openStreamsPlayer } from './streams-player';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamscloud/embeddable",
|
|
3
|
-
"version": "16.0.7-
|
|
3
|
+
"version": "16.0.7-1772096232639",
|
|
4
4
|
"author": "StreamsCloud",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,10 +38,6 @@
|
|
|
38
38
|
"types": "./dist/articles/article/index.d.ts",
|
|
39
39
|
"svelte": "./dist/articles/article/index.js"
|
|
40
40
|
},
|
|
41
|
-
"./article-viewer": {
|
|
42
|
-
"types": "./dist/articles/article-viewer/index.d.ts",
|
|
43
|
-
"svelte": "./dist/articles/article-viewer/index.js"
|
|
44
|
-
},
|
|
45
41
|
"./external-api": {
|
|
46
42
|
"types": "./dist/external-api/index.d.ts",
|
|
47
43
|
"svelte": "./dist/external-api/index.js"
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { ThemeValue } from '../../core/theme';
|
|
2
|
-
import type { AppLocaleValue } from '@streamscloud/kit/core/locale';
|
|
3
|
-
export declare class ArticleViewerHostSettings {
|
|
4
|
-
locale: AppLocaleValue | undefined;
|
|
5
|
-
theme: ThemeValue | undefined;
|
|
6
|
-
constructor(init: {
|
|
7
|
-
locale?: AppLocaleValue;
|
|
8
|
-
theme?: ThemeValue;
|
|
9
|
-
} | undefined);
|
|
10
|
-
update: (data: {
|
|
11
|
-
locale?: AppLocaleValue;
|
|
12
|
-
theme?: ThemeValue;
|
|
13
|
-
} | undefined) => void;
|
|
14
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
<script lang="ts">import {} from '../../ui/player/close-orchestrator';
|
|
2
|
-
import { ShadowRoot } from '../../ui/shadow-dom';
|
|
3
|
-
import ArticleViewerView from './article-viewer-view.svelte';
|
|
4
|
-
let { data, closeOrchestrator, viewerSettings } = $props();
|
|
5
|
-
</script>
|
|
6
|
-
|
|
7
|
-
<ShadowRoot locale={viewerSettings?.locale} theme={viewerSettings?.theme ?? 'light'} backgroundDisabled={true} backgroundImageUrl="not-applicable">
|
|
8
|
-
<ArticleViewerView data={data} closeOrchestrator={closeOrchestrator} />
|
|
9
|
-
</ShadowRoot>
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { type ICloseOrchestrator } from '../../ui/player/close-orchestrator';
|
|
2
|
-
import type { ArticleViewerModel, ArticleViewerSettings } from './types';
|
|
3
|
-
type Props = {
|
|
4
|
-
data: ArticleViewerModel;
|
|
5
|
-
closeOrchestrator: ICloseOrchestrator;
|
|
6
|
-
viewerSettings?: ArticleViewerSettings;
|
|
7
|
-
};
|
|
8
|
-
declare const ArticleViewerProxy: import("svelte").Component<Props, {}, "">;
|
|
9
|
-
type ArticleViewerProxy = ReturnType<typeof ArticleViewerProxy>;
|
|
10
|
-
export default ArticleViewerProxy;
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
<script lang="ts">import { Article } from '../article';
|
|
2
|
-
import {} from '../../ui/player/close-orchestrator';
|
|
3
|
-
let { data, closeOrchestrator } = $props();
|
|
4
|
-
const handleCloseClick = () => {
|
|
5
|
-
closeOrchestrator.requestClose();
|
|
6
|
-
};
|
|
7
|
-
const handleKeydown = (event) => {
|
|
8
|
-
if (event.key === 'Escape' && closeOrchestrator.closeTriggerVisible) {
|
|
9
|
-
closeOrchestrator.requestClose();
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
</script>
|
|
13
|
-
|
|
14
|
-
<svelte:window onkeydown={handleKeydown} />
|
|
15
|
-
|
|
16
|
-
<div class="article-viewer">
|
|
17
|
-
{#if closeOrchestrator.closeTriggerVisible}
|
|
18
|
-
<button type="button" class="article-viewer__close" aria-label="Close" onclick={handleCloseClick}>
|
|
19
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
20
|
-
<path
|
|
21
|
-
d="M4.397 4.554l.073-.084a.75.75 0 01.976-.073l.084.073L12 10.939l6.47-6.47a.75.75 0 111.06 1.061L13.061 12l6.47 6.47a.75.75 0 01.072.976l-.073.084a.75.75 0 01-.976.073l-.084-.073L12 13.061l-6.47 6.47a.75.75 0 01-1.06-1.061L10.939 12l-6.47-6.47a.75.75 0 01-.072-.976l.073-.084-.073.084z"
|
|
22
|
-
></path>
|
|
23
|
-
</svg>
|
|
24
|
-
</button>
|
|
25
|
-
{/if}
|
|
26
|
-
<div class="article-viewer__content">
|
|
27
|
-
<Article sections={data.sections} metadata={data.metadata} />
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<style>.article-viewer {
|
|
32
|
-
width: 100%;
|
|
33
|
-
min-width: 100%;
|
|
34
|
-
max-width: 100%;
|
|
35
|
-
height: 100%;
|
|
36
|
-
min-height: 100%;
|
|
37
|
-
max-height: 100%;
|
|
38
|
-
position: relative;
|
|
39
|
-
display: flex;
|
|
40
|
-
flex-direction: column;
|
|
41
|
-
}
|
|
42
|
-
.article-viewer__close {
|
|
43
|
-
position: absolute;
|
|
44
|
-
top: 0.75rem;
|
|
45
|
-
right: 0.75rem;
|
|
46
|
-
z-index: 10;
|
|
47
|
-
display: flex;
|
|
48
|
-
align-items: center;
|
|
49
|
-
justify-content: center;
|
|
50
|
-
width: 2.25rem;
|
|
51
|
-
height: 2.25rem;
|
|
52
|
-
border-radius: 50%;
|
|
53
|
-
border: none;
|
|
54
|
-
background: rgba(0, 0, 0, 0.4);
|
|
55
|
-
color: white;
|
|
56
|
-
cursor: pointer;
|
|
57
|
-
padding: 0;
|
|
58
|
-
}
|
|
59
|
-
.article-viewer__close:hover {
|
|
60
|
-
background: rgba(0, 0, 0, 0.6);
|
|
61
|
-
}
|
|
62
|
-
.article-viewer__content {
|
|
63
|
-
flex: 1;
|
|
64
|
-
overflow-y: auto;
|
|
65
|
-
--_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, #7d7d7d);
|
|
66
|
-
--_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
|
|
67
|
-
}
|
|
68
|
-
.article-viewer__content::-webkit-scrollbar {
|
|
69
|
-
width: 6px;
|
|
70
|
-
height: 6px;
|
|
71
|
-
}
|
|
72
|
-
.article-viewer__content::-webkit-scrollbar-track {
|
|
73
|
-
background: var(--_cross-browser-scrollbar--track-color);
|
|
74
|
-
border-radius: 100vw;
|
|
75
|
-
}
|
|
76
|
-
.article-viewer__content::-webkit-scrollbar-thumb {
|
|
77
|
-
background: var(--_cross-browser-scrollbar--thumb-color);
|
|
78
|
-
border-radius: 100vw;
|
|
79
|
-
}
|
|
80
|
-
@supports (scrollbar-color: transparent transparent) {
|
|
81
|
-
.article-viewer__content {
|
|
82
|
-
scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
|
|
83
|
-
scrollbar-width: thin;
|
|
84
|
-
}
|
|
85
|
-
}</style>
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type ICloseOrchestrator } from '../../ui/player/close-orchestrator';
|
|
2
|
-
import type { ArticleViewerModel } from './types';
|
|
3
|
-
type Props = {
|
|
4
|
-
data: ArticleViewerModel;
|
|
5
|
-
closeOrchestrator: ICloseOrchestrator;
|
|
6
|
-
};
|
|
7
|
-
declare const ArticleViewerView: import("svelte").Component<Props, {}, "">;
|
|
8
|
-
type ArticleViewerView = ReturnType<typeof ArticleViewerView>;
|
|
9
|
-
export default ArticleViewerView;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<script lang="ts">import { CloseOrchestrator } from '../../ui/player/close-orchestrator';
|
|
2
|
-
import { createShadowRoot } from '../../ui/shadow-dom';
|
|
3
|
-
import { ArticleViewerHostSettings } from './article-viewer-host-settings.svelte';
|
|
4
|
-
import ArticleViewerProxy from './article-viewer-proxy.svelte';
|
|
5
|
-
import { mount, unmount, untrack } from 'svelte';
|
|
6
|
-
let { data, viewerSettings } = $props();
|
|
7
|
-
const settingsHolder = untrack(() => new ArticleViewerHostSettings(viewerSettings));
|
|
8
|
-
$effect(() => {
|
|
9
|
-
settingsHolder.update(viewerSettings);
|
|
10
|
-
});
|
|
11
|
-
const initHost = (node) => {
|
|
12
|
-
const shadowRoot = createShadowRoot(node);
|
|
13
|
-
const mounted = mount(ArticleViewerProxy, {
|
|
14
|
-
target: shadowRoot,
|
|
15
|
-
props: {
|
|
16
|
-
data,
|
|
17
|
-
viewerSettings: settingsHolder,
|
|
18
|
-
closeOrchestrator: new CloseOrchestrator({
|
|
19
|
-
closeFn: async () => {
|
|
20
|
-
await unmount(mounted);
|
|
21
|
-
},
|
|
22
|
-
canClose: false
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
return {
|
|
27
|
-
destroy: () => {
|
|
28
|
-
unmount(mounted);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
</script>
|
|
33
|
-
|
|
34
|
-
<div class="article-viewer-host" use:initHost></div>
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ArticleViewerModel } from './types';
|
|
2
|
-
import type { AppLocaleValue } from '@streamscloud/kit/core/locale';
|
|
3
|
-
type Props = {
|
|
4
|
-
data: ArticleViewerModel;
|
|
5
|
-
viewerSettings?: {
|
|
6
|
-
locale?: AppLocaleValue;
|
|
7
|
-
theme?: 'light' | 'dark';
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
|
-
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
11
|
-
type Cmp = ReturnType<typeof Cmp>;
|
|
12
|
-
export default Cmp;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { ArticleViewerModel, ArticleViewerSettings } from './types';
|
|
2
|
-
export { default as ArticleViewer } from './cmp.article-viewer.svelte';
|
|
3
|
-
export type { ArticleViewerModel, ArticleViewerSettings } from './types';
|
|
4
|
-
/**
|
|
5
|
-
* Opens the article viewer as a full-screen modal.
|
|
6
|
-
*
|
|
7
|
-
* @param init Configuration options for the article viewer.
|
|
8
|
-
*
|
|
9
|
-
* @param {ArticleViewerModel} init.data
|
|
10
|
-
* Article data containing sections and metadata.
|
|
11
|
-
*
|
|
12
|
-
* @param {ArticleViewerSettings} [init.viewerSettings]
|
|
13
|
-
* Viewer UI settings.
|
|
14
|
-
* - {'en'|'no'} [locale='en'] — Localization for the viewer UI.
|
|
15
|
-
* - {'light'|'dark'} [theme='light'] — Theme for the viewer UI.
|
|
16
|
-
* - {boolean} [hideCloseButton] — If true, hides the close button.
|
|
17
|
-
*
|
|
18
|
-
* @param {{ closed?: () => void }} [init.on]
|
|
19
|
-
* Optional event handlers.
|
|
20
|
-
* @param {() => void} [init.on.closed]
|
|
21
|
-
* Called after the viewer is fully closed.
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* ```ts
|
|
25
|
-
* import { openArticleViewer } from '@streamscloud/embeddable/article-viewer';
|
|
26
|
-
*
|
|
27
|
-
* openArticleViewer({
|
|
28
|
-
* data: {
|
|
29
|
-
* sections: articleSections,
|
|
30
|
-
* metadata: { displayDate: '2026-02-25' }
|
|
31
|
-
* },
|
|
32
|
-
* viewerSettings: { locale: 'en', theme: 'light' },
|
|
33
|
-
* on: { closed: () => console.log('Viewer closed') }
|
|
34
|
-
* });
|
|
35
|
-
* ```
|
|
36
|
-
*/
|
|
37
|
-
export declare const openArticleViewer: (init: {
|
|
38
|
-
data: ArticleViewerModel;
|
|
39
|
-
viewerSettings?: ArticleViewerSettings;
|
|
40
|
-
on?: {
|
|
41
|
-
closed?: () => void;
|
|
42
|
-
};
|
|
43
|
-
}) => void;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { CloseOrchestrator } from '../../ui/player/close-orchestrator';
|
|
2
|
-
import { ModalShadowHost } from '../../ui/shadow-dom';
|
|
3
|
-
import ArticleViewerProxy from './article-viewer-proxy.svelte';
|
|
4
|
-
import { mount, unmount } from 'svelte';
|
|
5
|
-
export { default as ArticleViewer } from './cmp.article-viewer.svelte';
|
|
6
|
-
/**
|
|
7
|
-
* Opens the article viewer as a full-screen modal.
|
|
8
|
-
*
|
|
9
|
-
* @param init Configuration options for the article viewer.
|
|
10
|
-
*
|
|
11
|
-
* @param {ArticleViewerModel} init.data
|
|
12
|
-
* Article data containing sections and metadata.
|
|
13
|
-
*
|
|
14
|
-
* @param {ArticleViewerSettings} [init.viewerSettings]
|
|
15
|
-
* Viewer UI settings.
|
|
16
|
-
* - {'en'|'no'} [locale='en'] — Localization for the viewer UI.
|
|
17
|
-
* - {'light'|'dark'} [theme='light'] — Theme for the viewer UI.
|
|
18
|
-
* - {boolean} [hideCloseButton] — If true, hides the close button.
|
|
19
|
-
*
|
|
20
|
-
* @param {{ closed?: () => void }} [init.on]
|
|
21
|
-
* Optional event handlers.
|
|
22
|
-
* @param {() => void} [init.on.closed]
|
|
23
|
-
* Called after the viewer is fully closed.
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```ts
|
|
27
|
-
* import { openArticleViewer } from '@streamscloud/embeddable/article-viewer';
|
|
28
|
-
*
|
|
29
|
-
* openArticleViewer({
|
|
30
|
-
* data: {
|
|
31
|
-
* sections: articleSections,
|
|
32
|
-
* metadata: { displayDate: '2026-02-25' }
|
|
33
|
-
* },
|
|
34
|
-
* viewerSettings: { locale: 'en', theme: 'light' },
|
|
35
|
-
* on: { closed: () => console.log('Viewer closed') }
|
|
36
|
-
* });
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
|
-
export const openArticleViewer = (init) => {
|
|
40
|
-
const { data, viewerSettings, on } = init;
|
|
41
|
-
const shadowHost = new ModalShadowHost();
|
|
42
|
-
let mounted = null;
|
|
43
|
-
const closeOrchestrator = new CloseOrchestrator({
|
|
44
|
-
closeFn: async () => {
|
|
45
|
-
await unmount(mounted);
|
|
46
|
-
shadowHost.remove();
|
|
47
|
-
on?.closed?.();
|
|
48
|
-
},
|
|
49
|
-
canClose: !viewerSettings?.hideCloseButton
|
|
50
|
-
});
|
|
51
|
-
mounted = mount(ArticleViewerProxy, {
|
|
52
|
-
target: shadowHost.shadowRoot,
|
|
53
|
-
props: {
|
|
54
|
-
data,
|
|
55
|
-
viewerSettings,
|
|
56
|
-
closeOrchestrator
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
shadowHost.attachToBody();
|
|
60
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ArticleMetadata, ArticleSectionModel } from '../article';
|
|
2
|
-
import type { ThemeValue } from '../../core/theme';
|
|
3
|
-
import type { AppLocaleValue } from '@streamscloud/kit/core/locale';
|
|
4
|
-
export type ArticleViewerModel = {
|
|
5
|
-
sections: ArticleSectionModel[];
|
|
6
|
-
metadata: ArticleMetadata;
|
|
7
|
-
};
|
|
8
|
-
export type ArticleViewerSettings = {
|
|
9
|
-
locale?: AppLocaleValue;
|
|
10
|
-
theme?: ThemeValue;
|
|
11
|
-
hideCloseButton?: boolean;
|
|
12
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
File without changes
|