@yatoday/astro-ui 0.0.2

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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -0
  3. package/astro.d.ts +31 -0
  4. package/astro.js +19 -0
  5. package/components/Analytics/Analytics.astro +15 -0
  6. package/components/Analytics/AnalyticsGoogle.astro +17 -0
  7. package/components/Analytics/types.ts +6 -0
  8. package/components/Background/Background.astro +9 -0
  9. package/components/Background/Background.svelte +13 -0
  10. package/components/Background/types.ts +9 -0
  11. package/components/Card0/Card0.astro +23 -0
  12. package/components/Card0/card0.ts +6 -0
  13. package/components/Card0/types.ts +6 -0
  14. package/components/ConditionalWrapper/ConditionalWrapper.astro +15 -0
  15. package/components/ConditionalWrapper/ConditionalWrapper.svelte +18 -0
  16. package/components/ConditionalWrapper/types.ts +10 -0
  17. package/components/DarkMode/DarkMode.astro +77 -0
  18. package/components/DarkMode/types.ts +7 -0
  19. package/components/Layout/Layout.astro +35 -0
  20. package/components/Layout/types.ts +13 -0
  21. package/components/Metadata/AstroSeo.astro +40 -0
  22. package/components/Metadata/Metadata.astro +60 -0
  23. package/components/Metadata/types.ts +186 -0
  24. package/components/Metadata/utils/buildTags.ts +380 -0
  25. package/components/SeoAnalytics/SeoAnalytics.astro +15 -0
  26. package/components/SeoAnalytics/types.ts +3 -0
  27. package/components/SeoAnalyticsGoogleProvider/SeoAnalyticsGoogleProvider.astro +17 -0
  28. package/components/SeoAnalyticsGoogleProvider/types.ts +4 -0
  29. package/components/SeoAstroSeo/SeoAstroSeo.astro +40 -0
  30. package/components/SeoAstroSeo/SeoAstroSeo.svelte +3 -0
  31. package/components/SeoAstroSeo/types.ts +146 -0
  32. package/components/SeoMetadata/SeoMetadata.astro +8 -0
  33. package/components/SeoMetadata/types.ts +38 -0
  34. package/components/SeoSiteVerification/SeoSiteVerification.astro +6 -0
  35. package/components/SeoSiteVerification/types.ts +3 -0
  36. package/components/SiteVerification/SiteVerification.astro +6 -0
  37. package/components/SiteVerification/types.ts +1 -0
  38. package/components/WidgetWrapper/WidgetWrapper.astro +31 -0
  39. package/components/WidgetWrapper/WidgetWrapper.ts +6 -0
  40. package/components/WidgetWrapper/types.ts +10 -0
  41. package/index.d.ts +180 -0
  42. package/index.js +6 -0
  43. package/package.json +99 -0
  44. package/svelte.d.ts +32 -0
  45. package/svelte.js +19 -0
  46. package/utils/buildTags.ts +380 -0
  47. package/utils/css.ts +39 -0
  48. package/utils/images-optimization.ts +356 -0
  49. package/utils/images.ts +138 -0
  50. package/utils/index.ts +5 -0
  51. package/utils/permalinks.ts +38 -0
  52. package/utils/utils.ts +58 -0
  53. package/vendor-config/index.ts +115 -0
  54. package/vendor-config/types.d.ts +10 -0
  55. package/vendor-config/utils/configBuilder.ts +206 -0
  56. package/vendor-config/utils/loadConfig.ts +16 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Frontendland
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ > [!IMPORTANT]
2
+ > This library is still in early development. New changes can break existing functionality, and no functionality should be considered final at this stage. The library will be considered stable once it reaches v1.0.
package/astro.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import type { AnalyticsProps as YtAnalyticsProps } from './components/Analytics/types'
2
+ import type { BackgroundProps as YtBackgroundProps } from './components/Background/types'
3
+ import type { Card0Props as YtCard0Props } from './components/Card0/types'
4
+ import type { ConditionalWrapperProps as YtConditionalWrapperProps } from './components/ConditionalWrapper/types'
5
+ import type { DarkModeProps as YtDarkModeProps } from './components/DarkMode/types'
6
+ import type { LayoutProps as YtLayoutProps } from './components/Layout/types'
7
+ import type { MetadataProps as YtMetadataProps } from './components/Metadata/types'
8
+ import type { SiteVerificationProps as YtSiteVerificationProps } from './components/SiteVerification/types'
9
+ import type { WidgetWrapperProps as YtWidgetWrapperProps } from './components/WidgetWrapper/types'
10
+
11
+ declare module '@yatoday/astro-ui/astro' {
12
+ export function Analytics(_props: YtAnalyticsProps): any
13
+ export function Background(_props: YtBackgroundProps): any
14
+ export function Card0(_props: YtCard0Props): any
15
+ export function ConditionalWrapper(_props: YtConditionalWrapperProps): any
16
+ export function DarkMode(_props: YtDarkModeProps): any
17
+ export function Layout(_props: YtLayoutProps): any
18
+ export function Metadata(_props: YtMetadataProps): any
19
+ export function SiteVerification(_props: YtSiteVerificationProps): any
20
+ export function WidgetWrapper(_props: YtWidgetWrapperProps): any
21
+
22
+ export type AnalyticsProps = YtAnalyticsProps
23
+ export type BackgroundProps = YtBackgroundProps
24
+ export type Card0Props = YtCard0Props
25
+ export type ConditionalWrapperProps = YtConditionalWrapperProps
26
+ export type DarkModeProps = YtDarkModeProps
27
+ export type LayoutProps = YtLayoutProps
28
+ export type MetadataProps = YtMetadataProps
29
+ export type SiteVerificationProps = YtSiteVerificationProps
30
+ export type WidgetWrapperProps = YtWidgetWrapperProps
31
+ }
package/astro.js ADDED
@@ -0,0 +1,19 @@
1
+ import AnalyticsComponent from './components/Analytics/Analytics.astro'
2
+ import BackgroundComponent from './components/Background/Background.astro'
3
+ import Card0Component from './components/Card0/Card0.astro'
4
+ import ConditionalWrapperComponent from './components/ConditionalWrapper/ConditionalWrapper.astro'
5
+ import DarkModeComponent from './components/DarkMode/DarkMode.astro'
6
+ import LayoutComponent from './components/Layout/Layout.astro'
7
+ import MetadataComponent from './components/Metadata/Metadata.astro'
8
+ import SiteVerificationComponent from './components/SiteVerification/SiteVerification.astro'
9
+ import WidgetWrapperComponent from './components/WidgetWrapper/WidgetWrapper.astro'
10
+
11
+ export const Analytics = AnalyticsComponent
12
+ export const Background = BackgroundComponent
13
+ export const Card0 = Card0Component
14
+ export const ConditionalWrapper = ConditionalWrapperComponent
15
+ export const DarkMode = DarkModeComponent
16
+ export const Layout = LayoutComponent
17
+ export const Metadata = MetadataComponent
18
+ export const SiteVerification = SiteVerificationComponent
19
+ export const WidgetWrapper = WidgetWrapperComponent
@@ -0,0 +1,15 @@
1
+ ---
2
+ //import type { AnalyticsProps as Props } from './types';
3
+ import AnalyticsGoogleProvider from './AnalyticsGoogle.astro';
4
+
5
+ import { ANALYTICS } from 'vendor:config';
6
+ ---
7
+
8
+ {
9
+ ANALYTICS?.vendors?.googleAnalytics?.id ? (
10
+ <AnalyticsGoogleProvider
11
+ id={String(ANALYTICS.vendors.googleAnalytics.id)}
12
+ partytown={ANALYTICS?.vendors?.googleAnalytics?.partytown}
13
+ />
14
+ ) : null
15
+ }
@@ -0,0 +1,17 @@
1
+ ---
2
+ import type { AnalyticsGoogleProps as Props } from './types';
3
+
4
+ const { id = 'GA_MEASUREMENT_ID', partytown = false } = Astro.props;
5
+ const attrs = partytown ? { type: 'text/partytown' } : {};
6
+ ---
7
+
8
+ <script is:inline async src={`https://www.googletagmanager.com/gtag/js?id=${id}`} {...attrs}></script>
9
+
10
+ <script is:inline define:vars={{ id }} {...attrs}>
11
+ window.dataLayer = window.dataLayer || [];
12
+ function gtag() {
13
+ window.dataLayer.push(arguments);
14
+ }
15
+ gtag('js', new Date());
16
+ gtag('config', id);
17
+ </script>
@@ -0,0 +1,6 @@
1
+ export type AnalyticsProps = {};
2
+
3
+ export type AnalyticsGoogleProps = {
4
+ id: string;
5
+ partytown?: boolean;
6
+ };
@@ -0,0 +1,9 @@
1
+ ---
2
+ import type { BackgroundProps as Props } from './types';
3
+
4
+ const { isDark = false } = Astro.props;
5
+ ---
6
+
7
+ <div class:list={['absolute inset-0', { 'bg-dark dark:bg-transparent': isDark }]}>
8
+ <slot />
9
+ </div>
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ import type { SvelteBackgroundProps } from './types.ts';
3
+
4
+ const {
5
+ isDark,
6
+ children,
7
+ ...rest
8
+ }: SvelteBackgroundProps = $props()
9
+ </script>
10
+
11
+ <div class:list={['absolute inset-0', { 'bg-dark dark:bg-transparent': isDark }]} {...rest}>
12
+ {@render children?.()}
13
+ </div>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+
3
+ export type BackgroundProps = {
4
+ isDark?: boolean;
5
+ };
6
+
7
+ export type SvelteBackgroundProps = {
8
+ children?: Snippet;
9
+ } & BackgroundProps;
@@ -0,0 +1,23 @@
1
+ ---
2
+ import type { Card0Props as Props } from './types';
3
+ import { twMerge } from 'tailwind-merge';
4
+
5
+ const { as = 'article', classes = {} } = Astro.props;
6
+
7
+ const WrapperTag = as;
8
+
9
+ const { container: containerClass = '', badge: badgeClass = '' } = classes;
10
+ ---
11
+
12
+ <WrapperTag
13
+ class={twMerge(
14
+ 'relative flex flex-col justify-between gap-6 overflow-hidden rounded-lg border border-input bg-card text-card-foreground py-6 group',
15
+ containerClass
16
+ )}
17
+ >
18
+ <div class={twMerge('absolute', badgeClass)}>
19
+ <slot name="badge" />
20
+ </div>
21
+ <slot name="image" />
22
+ <slot />
23
+ </WrapperTag>
@@ -0,0 +1,6 @@
1
+ import type { HTMLTag } from 'astro/types';
2
+
3
+ export type Card0Props = {
4
+ as?: HTMLTag;
5
+ classes?: Record<string, string>;
6
+ };
@@ -0,0 +1,6 @@
1
+ import type { HTMLTag } from 'astro/types';
2
+
3
+ export type Card0Props = {
4
+ as?: HTMLTag;
5
+ classes?: Record<string, string>;
6
+ };
@@ -0,0 +1,15 @@
1
+ ---
2
+ import type { ConditionalWrapperProps as Props } from './types';
3
+
4
+ const { condition } = Astro.props;
5
+
6
+ const wrapper = await Astro.slots.render('wrapper');
7
+ const children = await Astro.slots.render('default');
8
+ const wrapped = wrapper?.replace('children', children);
9
+
10
+ if (!Astro.slots.has('wrapper')) {
11
+ console.error('Missing wrapper. Add slot="wrapper" to one of the elements.');
12
+ }
13
+ ---
14
+
15
+ <Fragment set:html={condition ? wrapped : children} />
@@ -0,0 +1,18 @@
1
+ <script lang="ts">
2
+ import type {SvelteConditionalWrapperProps} from './types'
3
+
4
+ const {
5
+ condition,
6
+ element = 'div',
7
+ children,
8
+ ...rest
9
+ }: SvelteConditionalWrapperProps = $props()
10
+ </script>
11
+
12
+ {#if condition}
13
+ <svelte:element this={element} {...rest}>
14
+ {@render children?.()}
15
+ </svelte:element>
16
+ {:else}
17
+ {@render children?.()}
18
+ {/if}
@@ -0,0 +1,10 @@
1
+ import type { Snippet } from 'svelte';
2
+
3
+ export type ConditionalWrapperProps = {
4
+ condition: boolean;
5
+ [key: string]: any;
6
+ };
7
+
8
+ export type SvelteConditionalWrapperProps = {
9
+ children: Snippet;
10
+ } & ConditionalWrapperProps;
@@ -0,0 +1,77 @@
1
+ ---
2
+ import { Icon } from 'astro-icon/components';
3
+ import { twMerge } from 'tailwind-merge';
4
+
5
+ import type { DarkModeProps as Props } from './types';
6
+
7
+ const {
8
+ label = 'Toggle between Dark and Light mode',
9
+ class:
10
+ className = 'dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-hidden focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5',
11
+ iconClass = 'w-6 h-6',
12
+ iconName = 'tabler:sun',
13
+ initialMode = 'system',
14
+ } = Astro.props;
15
+ ---
16
+
17
+ {
18
+ !initialMode.endsWith(':only') && (
19
+ <button
20
+ type="button"
21
+ class={twMerge('cursor-pointer inline-flex items-center', className)}
22
+ aria-label={label}
23
+ data-aw-toggle-color-scheme
24
+ >
25
+ <slot>
26
+ <Icon name={iconName} class={iconClass} />
27
+ </slot>
28
+ </button>
29
+ )
30
+ }
31
+
32
+ <script is:inline define:vars={{ mode: initialMode }}>
33
+ // Only run once
34
+ if (!window.darkModeInitialized) {
35
+ window.darkModeInitialized = true;
36
+
37
+ const root = document.documentElement;
38
+
39
+ function applyTheme(theme) {
40
+ if (theme === 'dark') {
41
+ root.classList.add('dark');
42
+ } else {
43
+ root.classList.remove('dark');
44
+ }
45
+ }
46
+
47
+ const initialize = function () {
48
+ if ((mode && mode.endsWith(':only')) || (!localStorage.theme && mode !== 'system')) {
49
+ applyTheme(mode.replace(':only', ''));
50
+ } else if (
51
+ localStorage.theme === 'dark' ||
52
+ (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
53
+ ) {
54
+ applyTheme('dark');
55
+ } else {
56
+ applyTheme('light');
57
+ }
58
+ };
59
+ initialize();
60
+
61
+ // Add click handlers to all toggles
62
+ document.addEventListener('click', (e) => {
63
+ if (e.target.closest('[data-aw-toggle-color-scheme]')) {
64
+ if (mode.endsWith(':only')) {
65
+ return;
66
+ }
67
+ root.classList.toggle('dark');
68
+ localStorage.theme = root.classList.contains('dark') ? 'dark' : 'light';
69
+ }
70
+ });
71
+
72
+ // Listen for view transitions
73
+ document.addEventListener('astro:after-swap', () => {
74
+ initialize();
75
+ });
76
+ }
77
+ </script>
@@ -0,0 +1,7 @@
1
+ export type DarkModeProps = {
2
+ label?: string;
3
+ class?: string;
4
+ iconClass?: string;
5
+ iconName?: string;
6
+ initialMode?: 'system' | 'light' | 'dark' | 'light:only' | 'dark:only';
7
+ };
@@ -0,0 +1,35 @@
1
+ ---
2
+ import { getAsset } from '../../utils';
3
+ import SeoMetadata from '../Metadata/Metadata.astro';
4
+ import SeoSiteVerification from '../SiteVerification/SiteVerification.astro';
5
+ import SeoAnalytics from '../Analytics/Analytics.astro';
6
+ import type { LayoutProps as Props } from './types';
7
+
8
+ import { I18N } from 'vendor:config';
9
+
10
+ const { metadata = {} } = Astro.props;
11
+ const { language, textDirection } = I18N;
12
+ ---
13
+
14
+ <!doctype html>
15
+ <html lang={language} dir={textDirection}>
16
+ <head>
17
+ <meta charset="UTF-8" />
18
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
19
+
20
+ <link rel="sitemap" href={getAsset('/sitemap-index.xml')} />
21
+ <SeoMetadata {...metadata} />
22
+
23
+ <slot name="favicons" />
24
+ <slot name="styles" />
25
+
26
+ <SeoSiteVerification />
27
+ <SeoAnalytics />
28
+ </head>
29
+
30
+ <body class="antialiased bg-background text-foreground tracking-tight">
31
+ <slot />
32
+
33
+ <slot name="scripts" />
34
+ </body>
35
+ </html>
@@ -0,0 +1,13 @@
1
+ import type { MetaData, MetaDataOpenGraph, MetaDataRobots, MetaDataTwitter } from '~/components/SeoMetadata/types';
2
+
3
+ export type LayoutProps = {
4
+ title?: string;
5
+ description?: string;
6
+ ignoreTitleTemplate?: boolean;
7
+ canonical?: string;
8
+
9
+ robots?: MetaDataRobots;
10
+ openGraph?: MetaDataOpenGraph;
11
+ twitter?: MetaDataTwitter;
12
+ metadata?: MetaData;
13
+ };
@@ -0,0 +1,40 @@
1
+ ---
2
+ import type { AstroSeoProps as Props } from './types';
3
+ import { buildTags } from './utils/buildTags';
4
+
5
+ const {
6
+ title,
7
+ titleTemplate,
8
+ noindex,
9
+ nofollow,
10
+ robotsProps,
11
+ description,
12
+ canonical,
13
+ mobileAlternate,
14
+ languageAlternates,
15
+ openGraph,
16
+ facebook,
17
+ twitter,
18
+ additionalMetaTags,
19
+ additionalLinkTags,
20
+ } = Astro.props;
21
+ ---
22
+
23
+ <Fragment
24
+ set:html={buildTags({
25
+ title,
26
+ titleTemplate,
27
+ noindex,
28
+ nofollow,
29
+ robotsProps,
30
+ description,
31
+ canonical,
32
+ mobileAlternate,
33
+ languageAlternates,
34
+ openGraph,
35
+ facebook,
36
+ twitter,
37
+ additionalMetaTags,
38
+ additionalLinkTags,
39
+ })}
40
+ />
@@ -0,0 +1,60 @@
1
+ ---
2
+ import type { AstroSeoProps, MetadataProps as Props } from './types';
3
+ import AstroSeo from './AstroSeo.astro';
4
+ import { adaptOpenGraphImages, getCanonical } from '../../utils';
5
+
6
+ import merge from 'lodash.merge';
7
+ import { I18N, METADATA, SITE } from 'vendor:config';
8
+
9
+ const {
10
+ title,
11
+ ignoreTitleTemplate = false,
12
+ canonical = String(getCanonical(String(Astro.url.pathname))),
13
+ robots = {},
14
+ description,
15
+ openGraph = {},
16
+ twitter = {},
17
+ } = Astro.props;
18
+
19
+ const seoProps: AstroSeoProps = merge(
20
+ {
21
+ title: '',
22
+ titleTemplate: '%s',
23
+ canonical,
24
+ noindex: true,
25
+ nofollow: true,
26
+ description: undefined,
27
+ openGraph: {
28
+ url: canonical,
29
+ site_name: SITE?.name,
30
+ images: [],
31
+ locale: I18N?.language || 'en',
32
+ type: 'website',
33
+ },
34
+ twitter: {
35
+ cardType: openGraph?.images?.length ? 'summary_large_image' : 'summary',
36
+ },
37
+ },
38
+ {
39
+ title: METADATA?.title?.default,
40
+ titleTemplate: METADATA?.title?.template,
41
+ noindex: typeof METADATA?.robots?.index !== 'undefined' ? !METADATA.robots.index : undefined,
42
+ nofollow: typeof METADATA?.robots?.follow !== 'undefined' ? !METADATA.robots.follow : undefined,
43
+ description: METADATA?.description,
44
+ openGraph: METADATA?.openGraph,
45
+ twitter: METADATA?.twitter,
46
+ },
47
+ {
48
+ title,
49
+ titleTemplate: ignoreTitleTemplate ? '%s' : undefined,
50
+ canonical,
51
+ noindex: typeof robots?.index !== 'undefined' ? !robots.index : undefined,
52
+ nofollow: typeof robots?.follow !== 'undefined' ? !robots.follow : undefined,
53
+ description,
54
+ openGraph: { url: canonical, ...openGraph },
55
+ twitter,
56
+ }
57
+ );
58
+ ---
59
+
60
+ <AstroSeo {...{ ...seoProps, openGraph: await adaptOpenGraphImages(seoProps?.openGraph, Astro.site) }} />
@@ -0,0 +1,186 @@
1
+ export type MetadataProps = {
2
+ dontUseTitleTemplate?: boolean;
3
+ } extends MetaData
4
+ ? never
5
+ : MetaData;
6
+
7
+ export interface MetaData {
8
+ title?: string;
9
+ ignoreTitleTemplate?: boolean;
10
+ canonical?: string;
11
+ robots?: MetaDataRobots;
12
+ description?: string;
13
+ openGraph?: MetaDataOpenGraph;
14
+ twitter?: MetaDataTwitter;
15
+ }
16
+
17
+ export interface MetaDataRobots {
18
+ index?: boolean;
19
+ follow?: boolean;
20
+ }
21
+
22
+ export interface MetaDataImage {
23
+ url: string;
24
+ width?: number;
25
+ height?: number;
26
+ }
27
+
28
+ export interface MetaDataOpenGraph {
29
+ url?: string;
30
+ siteName?: string;
31
+ images?: Array<MetaDataImage>;
32
+ locale?: string;
33
+ type?: string;
34
+ }
35
+
36
+ export interface MetaDataTwitter {
37
+ handle?: string;
38
+ site?: string;
39
+ cardType?: string;
40
+ }
41
+
42
+ export type AstroSeoProps = {
43
+ title?: string;
44
+ titleTemplate?: string;
45
+ noindex?: boolean;
46
+ nofollow?: boolean;
47
+ robotsProps?: AdditionalRobotsProps;
48
+ description?: string;
49
+ canonical?: string;
50
+ mobileAlternate?: MobileAlternate;
51
+ languageAlternates?: ReadonlyArray<LanguageAlternate>;
52
+ openGraph?: OpenGraph;
53
+ facebook?: { appId: string };
54
+ twitter?: Twitter;
55
+ additionalMetaTags?: ReadonlyArray<MetaTag>;
56
+ additionalLinkTags?: ReadonlyArray<LinkTag>;
57
+ };
58
+
59
+ export interface OpenGraphMedia {
60
+ url: string;
61
+ width?: number;
62
+ height?: number;
63
+ alt?: string;
64
+ type?: string;
65
+ secureUrl?: string;
66
+ }
67
+
68
+ export interface AdditionalRobotsProps {
69
+ nosnippet?: boolean;
70
+ maxSnippet?: number;
71
+ maxImagePreview?: ImagePrevSize;
72
+ maxVideoPreview?: number;
73
+ noarchive?: boolean;
74
+ unavailableAfter?: string;
75
+ noimageindex?: boolean;
76
+ notranslate?: boolean;
77
+ }
78
+
79
+ export type ImagePrevSize = 'none' | 'standard' | 'large';
80
+
81
+ export interface OpenGraphVideoActors {
82
+ profile: string;
83
+ role?: string;
84
+ }
85
+
86
+ export interface OpenGraph {
87
+ url?: string;
88
+ type?: string;
89
+ title?: string;
90
+ description?: string;
91
+ images?: ReadonlyArray<OpenGraphMedia>;
92
+ videos?: ReadonlyArray<OpenGraphMedia>;
93
+ defaultImageHeight?: number;
94
+ defaultImageWidth?: number;
95
+ locale?: string;
96
+ site_name?: string;
97
+ profile?: OpenGraphProfile;
98
+ book?: OpenGraphBook;
99
+ article?: OpenGraphArticle;
100
+ video?: OpenGraphVideo;
101
+ }
102
+
103
+ export interface OpenGraphProfile {
104
+ firstName?: string;
105
+ lastName?: string;
106
+ username?: string;
107
+ gender?: string;
108
+ }
109
+
110
+ export interface OpenGraphBook {
111
+ authors?: ReadonlyArray<string>;
112
+ isbn?: string;
113
+ releaseDate?: string;
114
+ tags?: ReadonlyArray<string>;
115
+ }
116
+
117
+ export interface OpenGraphArticle {
118
+ publishedTime?: string;
119
+ modifiedTime?: string;
120
+ expirationTime?: string;
121
+
122
+ authors?: ReadonlyArray<string>;
123
+ section?: string;
124
+ tags?: ReadonlyArray<string>;
125
+ }
126
+
127
+ export interface OpenGraphVideo {
128
+ actors?: ReadonlyArray<OpenGraphVideoActors>;
129
+ directors?: ReadonlyArray<string>;
130
+ writers?: ReadonlyArray<string>;
131
+ duration?: number;
132
+ releaseDate?: string;
133
+ tags?: ReadonlyArray<string>;
134
+ series?: string;
135
+ }
136
+
137
+ export interface Twitter {
138
+ handle?: string;
139
+ site?: string;
140
+ cardType?: string;
141
+ }
142
+
143
+ interface MobileAlternate {
144
+ media: string;
145
+ href: string;
146
+ }
147
+
148
+ interface LanguageAlternate {
149
+ hreflang: string;
150
+ href: string;
151
+ }
152
+
153
+ interface LinkTag {
154
+ rel: string;
155
+ href: string;
156
+ sizes?: string;
157
+ media?: string;
158
+ type?: string;
159
+ color?: string;
160
+ as?: string;
161
+ crossOrigin?: string;
162
+ }
163
+
164
+ export interface BaseMetaTag {
165
+ content: string;
166
+ }
167
+
168
+ export interface HTML5MetaTag extends BaseMetaTag {
169
+ name: string;
170
+ property?: undefined;
171
+ httpEquiv?: undefined;
172
+ }
173
+
174
+ export interface RDFaMetaTag extends BaseMetaTag {
175
+ property: string;
176
+ name?: undefined;
177
+ httpEquiv?: undefined;
178
+ }
179
+
180
+ export interface HTTPEquivMetaTag extends BaseMetaTag {
181
+ httpEquiv: 'content-security-policy' | 'content-type' | 'default-style' | 'x-ua-compatible' | 'refresh';
182
+ name?: undefined;
183
+ property?: undefined;
184
+ }
185
+
186
+ export type MetaTag = HTML5MetaTag | RDFaMetaTag | HTTPEquivMetaTag;