create-bearminion 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +5 -3
- package/package.json +3 -3
- package/template/README.md +3 -3
- package/template/package.json +4 -4
- package/template/src/components/atoms/Typography.astro +5 -2
- package/template/src/components/sections/SectionList.astro +6 -3
- package/template/src/components/sections/definitions.ts +4 -2
- package/template/src/components/sections/gallery/Gallery.astro +128 -0
- package/template/src/components/sections/gallery/Gallery.stories.ts +24 -0
- package/template/src/components/sections/gallery/definition.ts +59 -0
- package/template/src/components/sections/gallery/lightbox.ts +159 -0
- package/template/src/components/sections/gallery/wireframe.ts +12 -0
- package/template/src/components/sections/media/Media.astro +1 -0
- package/template/src/components/sections/media/MediaPlayer.astro +29 -1
- package/template/src/components/sections/media/definition.ts +6 -1
- package/template/src/components/sections/media/source.ts +3 -33
- package/template/src/components/sections/registry.ts +4 -2
- package/template/src/components/sections/text/Text.astro +43 -0
- package/template/src/components/sections/text/Text.stories.ts +17 -0
- package/template/src/components/sections/text/definition.ts +36 -0
- package/template/src/components/sections/text/wireframe.ts +12 -0
- package/template/src/components/seo/Seo.astro +11 -9
- package/template/src/lib/content-model.ts +4 -1
- package/template/src/lib/migrations.ts +27 -0
- package/template/src/styles/global.css +161 -0
- package/template/src/components/sections/video/Video.astro +0 -78
- package/template/src/components/sections/video/Video.stories.ts +0 -17
- package/template/src/components/sections/video/VideoFrame.astro +0 -60
- package/template/src/components/sections/video/definition.ts +0 -58
- package/template/src/components/sections/video/wireframe.ts +0 -9
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { Image } from 'bearminion'
|
|
3
|
-
import { imageUrl } from '../../../lib/image-url'
|
|
4
|
-
import { cn } from '../../../lib/cn'
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
/** A video file URL, or `placeholder` for an empty frame. */
|
|
8
|
-
src: string
|
|
9
|
-
poster?: Image
|
|
10
|
-
label?: string
|
|
11
|
-
loop: boolean
|
|
12
|
-
roundedClass?: string
|
|
13
|
-
class?: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const { src, poster, label, loop, roundedClass = 'rounded-card-lg', class: className } = Astro.props
|
|
17
|
-
const placeholder = src === 'placeholder'
|
|
18
|
-
|
|
19
|
-
const posterSrc = await imageUrl(poster)
|
|
20
|
-
// A looping video starts muted and without controls once the page script sees it on screen. Until then, and without
|
|
21
|
-
// JavaScript or with reduced motion, it keeps its controls so it can still be played.
|
|
22
|
-
const playback = loop ? { muted: true, loop: true, controls: true, 'data-video-loop': '' } : { controls: true }
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
<div class={cn('relative overflow-hidden bg-surface', placeholder && 'placeholder-stripes aspect-video', roundedClass, className)}>
|
|
26
|
-
{
|
|
27
|
-
placeholder ? (
|
|
28
|
-
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 text-center">
|
|
29
|
-
<span class="flex size-14 items-center justify-center rounded-full bg-fg text-bg" aria-hidden="true">
|
|
30
|
-
<svg viewBox="0 0 16 16" class="ms-0.5 size-5" fill="currentColor"><path d="M4 2.5v11l9-5.5z" /></svg>
|
|
31
|
-
</span>
|
|
32
|
-
<span class="font-mono text-[0.6875rem] tracking-[0.04em] text-muted">Add a video link in the section settings</span>
|
|
33
|
-
</div>
|
|
34
|
-
) : (
|
|
35
|
-
<video class="block h-auto w-full" src={src} poster={posterSrc} preload="metadata" playsinline aria-label={label} {...playback} />
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
</div>
|
|
39
|
-
|
|
40
|
-
<script>
|
|
41
|
-
/** Looping videos play while at least a quarter of them is on screen, and not at all with reduced motion. */
|
|
42
|
-
function bindLoopingVideos() {
|
|
43
|
-
const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
44
|
-
for (const video of document.querySelectorAll<HTMLVideoElement>('video[data-video-loop]')) {
|
|
45
|
-
if (video.dataset.bound === 'true') continue
|
|
46
|
-
video.dataset.bound = 'true'
|
|
47
|
-
if (reduced) continue
|
|
48
|
-
video.controls = false
|
|
49
|
-
new IntersectionObserver(
|
|
50
|
-
([entry]) => {
|
|
51
|
-
if (entry?.isIntersecting) void video.play().catch(() => (video.controls = true))
|
|
52
|
-
else video.pause()
|
|
53
|
-
},
|
|
54
|
-
{ threshold: 0.25 },
|
|
55
|
-
).observe(video)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
bindLoopingVideos()
|
|
59
|
-
document.addEventListener('bearminion:preview', bindLoopingVideos)
|
|
60
|
-
</script>
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
import { defineSection, imageSchema, richTextSchema, textSchema, withEmphasis } from 'bearminion'
|
|
3
|
-
import { VIDEO_FILE } from '../media/source'
|
|
4
|
-
import { accent, eyebrow, heading } from '../shared'
|
|
5
|
-
import { videoWireframe } from './wireframe'
|
|
6
|
-
|
|
7
|
-
export const videoVariants = ['framed', 'wide', 'split'] as const
|
|
8
|
-
|
|
9
|
-
/** `controls`: the visitor presses play. `loop`: plays silently and on repeat while it is on screen, like a moving image. */
|
|
10
|
-
export const videoPlayback = ['controls', 'loop'] as const
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* A video file the browser can play: a path in the site's `public/` folder (`/videos/demo.webm`) or an `https://` link
|
|
14
|
-
* to the file. `placeholder` shows an empty frame. A page link such as YouTube does not play in a video element.
|
|
15
|
-
*/
|
|
16
|
-
export const videoSourceSchema = z
|
|
17
|
-
.string()
|
|
18
|
-
.min(1)
|
|
19
|
-
.refine((value) => value === 'placeholder' || VIDEO_FILE.test(value), {
|
|
20
|
-
message:
|
|
21
|
-
'Use a link to a video file ending in .mp4 or .webm, or a path in public/ such as /videos/demo.webm. YouTube and similar page links do not play here.',
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
export const videoSchema = withEmphasis({
|
|
25
|
-
eyebrow,
|
|
26
|
-
heading,
|
|
27
|
-
intro: richTextSchema.optional(),
|
|
28
|
-
video: videoSourceSchema,
|
|
29
|
-
/** What the video shows, read out by screen readers. */
|
|
30
|
-
label: textSchema.optional(),
|
|
31
|
-
/** Shown before the video plays and while it loads. */
|
|
32
|
-
poster: imageSchema.optional(),
|
|
33
|
-
caption: textSchema.optional(),
|
|
34
|
-
playback: z.enum(videoPlayback).default('controls'),
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
export type VideoProps = z.infer<typeof videoSchema>
|
|
38
|
-
|
|
39
|
-
export const video = defineSection({
|
|
40
|
-
type: 'video',
|
|
41
|
-
label: 'Video',
|
|
42
|
-
description: 'A video with a heading, a poster image and a caption.',
|
|
43
|
-
schema: videoSchema,
|
|
44
|
-
defaults: {
|
|
45
|
-
eyebrow: 'Watch',
|
|
46
|
-
heading: 'See it in action.',
|
|
47
|
-
marks: accent('See it in action.', 'in action.'),
|
|
48
|
-
intro: 'A short video says more than a page of text. Link an .mp4 or .webm file and add a poster image to show before it plays.',
|
|
49
|
-
video: 'placeholder',
|
|
50
|
-
label: 'Product walkthrough',
|
|
51
|
-
playback: 'controls',
|
|
52
|
-
},
|
|
53
|
-
variants: videoVariants,
|
|
54
|
-
defaultVariant: 'framed',
|
|
55
|
-
options: [{ name: 'playback', label: 'Playback', type: 'enum', choices: videoPlayback, default: 'controls' }],
|
|
56
|
-
optional: { props: ['eyebrow', 'heading', 'intro', 'label', 'poster', 'caption'] },
|
|
57
|
-
wireframe: videoWireframe,
|
|
58
|
-
})
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { defineWireframe } from 'bearminion'
|
|
2
|
-
|
|
3
|
-
/** Add section picker thumbnail: [left %, top %, width %, height %, kind]. */
|
|
4
|
-
export const videoWireframe = defineWireframe([
|
|
5
|
-
[30, 10, 40, 8, 'title'],
|
|
6
|
-
[24, 22, 52, 4, 'text'],
|
|
7
|
-
[12, 32, 76, 58, 'dark'],
|
|
8
|
-
[45, 54, 10, 14, 'light'],
|
|
9
|
-
])
|