@hanzo/ui 3.5.3 → 3.6.1
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/package.json +2 -1
- package/primitives/image.tsx +25 -6
- package/primitives/index.ts +112 -105
- package/primitives/media-stack.tsx +11 -9
- package/primitives/slider.tsx +72 -0
- package/types/index.ts +1 -1
- package/types/media-stack-def.ts +16 -1
- package/util/index.ts +2 -0
- package/util/spread-to-transform.ts +24 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.1",
|
|
4
4
|
"description": "Library that contains shared UI primitives, support for a common design system, and other boilerplate support.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"@radix-ui/react-scroll-area": "^1.0.5",
|
|
44
44
|
"@radix-ui/react-select": "^2.0.0",
|
|
45
45
|
"@radix-ui/react-separator": "^1.0.3",
|
|
46
|
+
"@radix-ui/react-slider": "^1.1.2",
|
|
46
47
|
"@radix-ui/react-slot": "^1.0.2",
|
|
47
48
|
"@radix-ui/react-switch": "^1.0.3",
|
|
48
49
|
"@radix-ui/react-tabs": "^1.0.4",
|
package/primitives/image.tsx
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import NextImage from 'next/image'
|
|
3
3
|
|
|
4
|
-
import type { ImageDef, Dimensions } from '../types'
|
|
5
|
-
import { constrain, cn } from '../util'
|
|
4
|
+
import type { ImageDef, Dimensions, MediaTransform } from '../types'
|
|
5
|
+
import { constrain, cn, spreadToTransform } from '../util'
|
|
6
6
|
|
|
7
7
|
const Image: React.FC<{
|
|
8
8
|
def: ImageDef
|
|
9
9
|
constrainTo?: Dimensions
|
|
10
|
+
transform?: MediaTransform
|
|
10
11
|
fullWidth?: boolean
|
|
11
12
|
className?: string
|
|
12
13
|
preload?: boolean
|
|
13
14
|
}> = ({
|
|
14
15
|
def,
|
|
15
16
|
constrainTo,
|
|
17
|
+
transform={},
|
|
16
18
|
fullWidth=false,
|
|
17
19
|
className='',
|
|
18
20
|
preload=false
|
|
@@ -31,6 +33,7 @@ const Image: React.FC<{
|
|
|
31
33
|
toSpread.style = {
|
|
32
34
|
width: '100%',
|
|
33
35
|
height: 'auto',
|
|
36
|
+
...spreadToTransform(transform)
|
|
34
37
|
}
|
|
35
38
|
if (constrainTo) {
|
|
36
39
|
toSpread.style.maxWidth = constrainTo.w
|
|
@@ -41,6 +44,7 @@ const Image: React.FC<{
|
|
|
41
44
|
const resolved = constrainTo ? constrain(dim, constrainTo) : dim
|
|
42
45
|
toSpread.width = resolved.w
|
|
43
46
|
toSpread.height = resolved.h
|
|
47
|
+
toSpread.style = {...spreadToTransform(transform)}
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
if (sizes) {
|
|
@@ -61,13 +65,28 @@ const Image: React.FC<{
|
|
|
61
65
|
const svgFillClass = _svgFillClass ?? ''
|
|
62
66
|
|
|
63
67
|
return (fullWidth) ? (
|
|
64
|
-
<div className='relative flex flex-col items-center w-full'>
|
|
65
|
-
<NextImage
|
|
68
|
+
<div className='relative flex flex-col items-center justify-center w-full'>
|
|
69
|
+
<NextImage
|
|
70
|
+
data-vaul-no-drag
|
|
71
|
+
src={src}
|
|
72
|
+
alt={alt}
|
|
73
|
+
{...toSpread}
|
|
74
|
+
priority={preload}
|
|
75
|
+
loading={preload ? 'eager' : 'lazy'}
|
|
76
|
+
className={cn(svgFillClass, className)}
|
|
77
|
+
/>
|
|
66
78
|
</div>
|
|
67
79
|
) : (
|
|
68
|
-
<NextImage
|
|
80
|
+
<NextImage
|
|
81
|
+
src={src}
|
|
82
|
+
alt={alt}
|
|
83
|
+
data-vaul-no-drag
|
|
84
|
+
{...toSpread}
|
|
85
|
+
priority={preload}
|
|
86
|
+
loading={preload ? 'eager' : 'lazy'}
|
|
87
|
+
className={cn(svgFillClass, className)}
|
|
88
|
+
/>
|
|
69
89
|
)
|
|
70
90
|
}
|
|
71
91
|
|
|
72
92
|
export default Image
|
|
73
|
-
|
package/primitives/index.ts
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export {
|
|
2
|
+
Accordion,
|
|
3
|
+
AccordionItem,
|
|
4
|
+
AccordionTrigger,
|
|
5
|
+
AccordionContent
|
|
6
|
+
} from './accordion'
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
Avatar,
|
|
10
|
+
AvatarImage,
|
|
11
|
+
AvatarFallback
|
|
12
|
+
} from './avatar'
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
Breadcrumb,
|
|
16
|
+
BreadcrumbList,
|
|
17
|
+
BreadcrumbItem,
|
|
18
|
+
BreadcrumbLink,
|
|
19
|
+
BreadcrumbPage,
|
|
20
|
+
BreadcrumbSeparator,
|
|
21
|
+
BreadcrumbEllipsis,
|
|
22
|
+
} from './breadcrumb'
|
|
4
23
|
|
|
5
24
|
export {
|
|
6
25
|
default as Button,
|
|
@@ -10,20 +29,36 @@ export {
|
|
|
10
29
|
buttonVariants,
|
|
11
30
|
} from './button'
|
|
12
31
|
|
|
13
|
-
export {
|
|
14
|
-
|
|
32
|
+
export {
|
|
33
|
+
Card,
|
|
34
|
+
CardHeader,
|
|
35
|
+
CardFooter,
|
|
36
|
+
CardTitle,
|
|
37
|
+
CardDescription,
|
|
38
|
+
CardContent
|
|
39
|
+
} from './card'
|
|
40
|
+
|
|
15
41
|
export {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
42
|
+
type CarouselApi,
|
|
43
|
+
type CarouselOptions,
|
|
44
|
+
Carousel,
|
|
45
|
+
CarouselContent,
|
|
46
|
+
CarouselItem,
|
|
47
|
+
CarouselNext,
|
|
48
|
+
CarouselPrevious,
|
|
49
|
+
} from './carousel'
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
Command,
|
|
53
|
+
CommandDialog,
|
|
54
|
+
CommandInput,
|
|
55
|
+
CommandList,
|
|
56
|
+
CommandEmpty,
|
|
57
|
+
CommandGroup,
|
|
58
|
+
CommandItem,
|
|
59
|
+
CommandShortcut,
|
|
60
|
+
CommandSeparator,
|
|
61
|
+
} from './command'
|
|
27
62
|
|
|
28
63
|
export {
|
|
29
64
|
Drawer,
|
|
@@ -38,6 +73,18 @@ export {
|
|
|
38
73
|
DrawerDescription,
|
|
39
74
|
} from './drawer'
|
|
40
75
|
|
|
76
|
+
export {
|
|
77
|
+
Dialog,
|
|
78
|
+
DialogPortal,
|
|
79
|
+
DialogOverlay,
|
|
80
|
+
DialogClose,
|
|
81
|
+
DialogTrigger,
|
|
82
|
+
DialogContent,
|
|
83
|
+
DialogHeader,
|
|
84
|
+
DialogFooter,
|
|
85
|
+
DialogTitle,
|
|
86
|
+
DialogDescription,
|
|
87
|
+
} from './dialog'
|
|
41
88
|
|
|
42
89
|
export {
|
|
43
90
|
useFormField,
|
|
@@ -50,20 +97,34 @@ export {
|
|
|
50
97
|
FormField,
|
|
51
98
|
} from './form'
|
|
52
99
|
|
|
53
|
-
export {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
100
|
+
export {
|
|
101
|
+
InputOTP,
|
|
102
|
+
InputOTPGroup,
|
|
103
|
+
InputOTPSeparator,
|
|
104
|
+
InputOTPSlot,
|
|
105
|
+
} from './input-otp'
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
Popover,
|
|
109
|
+
PopoverAnchor,
|
|
110
|
+
PopoverArrow,
|
|
111
|
+
PopoverClose,
|
|
112
|
+
PopoverContent,
|
|
113
|
+
PopoverTrigger,
|
|
114
|
+
} from './popover'
|
|
57
115
|
|
|
58
116
|
export {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
117
|
+
Select,
|
|
118
|
+
SelectGroup,
|
|
119
|
+
SelectValue,
|
|
120
|
+
SelectTrigger,
|
|
121
|
+
SelectContent,
|
|
122
|
+
SelectLabel,
|
|
123
|
+
SelectItem,
|
|
124
|
+
SelectSeparator,
|
|
125
|
+
SelectScrollUpButton,
|
|
126
|
+
SelectScrollDownButton,
|
|
127
|
+
} from './select'
|
|
67
128
|
|
|
68
129
|
export {
|
|
69
130
|
Sheet,
|
|
@@ -89,42 +150,6 @@ export {
|
|
|
89
150
|
TableCaption,
|
|
90
151
|
} from './table'
|
|
91
152
|
|
|
92
|
-
export { default as BreakpointIndicator } from './breakpoint-indicator'
|
|
93
|
-
|
|
94
|
-
export {
|
|
95
|
-
Select,
|
|
96
|
-
SelectGroup,
|
|
97
|
-
SelectValue,
|
|
98
|
-
SelectTrigger,
|
|
99
|
-
SelectContent,
|
|
100
|
-
SelectLabel,
|
|
101
|
-
SelectItem,
|
|
102
|
-
SelectSeparator,
|
|
103
|
-
SelectScrollUpButton,
|
|
104
|
-
SelectScrollDownButton,
|
|
105
|
-
} from './select'
|
|
106
|
-
|
|
107
|
-
export {
|
|
108
|
-
Popover,
|
|
109
|
-
PopoverAnchor,
|
|
110
|
-
PopoverArrow,
|
|
111
|
-
PopoverClose,
|
|
112
|
-
PopoverContent,
|
|
113
|
-
PopoverTrigger,
|
|
114
|
-
} from './popover'
|
|
115
|
-
|
|
116
|
-
export {
|
|
117
|
-
Command,
|
|
118
|
-
CommandDialog,
|
|
119
|
-
CommandInput,
|
|
120
|
-
CommandList,
|
|
121
|
-
CommandEmpty,
|
|
122
|
-
CommandGroup,
|
|
123
|
-
CommandItem,
|
|
124
|
-
CommandShortcut,
|
|
125
|
-
CommandSeparator,
|
|
126
|
-
} from './command'
|
|
127
|
-
|
|
128
153
|
export {
|
|
129
154
|
Tabs,
|
|
130
155
|
TabsList,
|
|
@@ -132,56 +157,38 @@ export {
|
|
|
132
157
|
TabsContent
|
|
133
158
|
} from './tabs'
|
|
134
159
|
|
|
135
|
-
export {
|
|
136
|
-
|
|
137
|
-
AvatarImage,
|
|
138
|
-
AvatarFallback
|
|
139
|
-
} from './avatar'
|
|
140
|
-
|
|
141
|
-
export {
|
|
142
|
-
InputOTP,
|
|
143
|
-
InputOTPGroup,
|
|
144
|
-
InputOTPSeparator,
|
|
145
|
-
InputOTPSlot,
|
|
146
|
-
} from './input-otp'
|
|
147
|
-
|
|
148
|
-
export {
|
|
149
|
-
type CarouselApi,
|
|
150
|
-
type CarouselOptions,
|
|
151
|
-
Carousel,
|
|
152
|
-
CarouselContent,
|
|
153
|
-
CarouselItem,
|
|
154
|
-
CarouselNext,
|
|
155
|
-
CarouselPrevious,
|
|
156
|
-
} from './carousel'
|
|
157
|
-
|
|
158
|
-
export { Toggle, toggleVariants } from './toggle'
|
|
159
|
-
export { ToggleGroup, ToggleGroupItem } from './toggle-group'
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
export { ScrollArea, ScrollBar } from './scroll-area'
|
|
163
|
-
|
|
164
|
-
export { Toaster, toast } from './sonner'
|
|
165
|
-
export { RadioGroup, RadioGroupItem } from './radio-group'
|
|
166
|
-
|
|
160
|
+
export { default as ActionButton } from './action-button'
|
|
161
|
+
export { default as ApplyTypography, type TypographySize} from './apply-typography'
|
|
167
162
|
export { default as AspectRatio } from './aspect-ratio'
|
|
168
163
|
export { default as Badge } from './badge'
|
|
169
|
-
export { default as
|
|
170
|
-
export { default as YouTubeEmbed } from './youtube-embed'
|
|
171
|
-
export { default as Switch } from './switch'
|
|
172
|
-
export { default as TextArea } from './text-area'
|
|
164
|
+
export { default as BreakpointIndicator } from './breakpoint-indicator'
|
|
173
165
|
export { default as Calendar } from './calendar'
|
|
174
166
|
export { default as Checkbox } from './checkbox'
|
|
167
|
+
export { default as DialogVideoController } from './dialog-video-controller'
|
|
175
168
|
export { default as Image } from './image'
|
|
176
|
-
export { default as
|
|
169
|
+
export { default as InlineIcon } from './inline-icon'
|
|
170
|
+
export { default as Input } from './input'
|
|
171
|
+
export { default as Label } from './label'
|
|
172
|
+
export { default as LinkElement } from './link-element'
|
|
173
|
+
export { default as ListBox } from './list-box'
|
|
174
|
+
export { default as Main } from './main'
|
|
175
|
+
export { default as MDXLink } from './mdx-link'
|
|
177
176
|
export { default as MediaStack } from './media-stack'
|
|
177
|
+
export { default as NavItems} from './nav-items'
|
|
178
|
+
export { default as Progress } from './progress'
|
|
179
|
+
export { RadioGroup, RadioGroupItem } from './radio-group'
|
|
180
|
+
export { ScrollArea, ScrollBar } from './scroll-area'
|
|
178
181
|
export { default as Separator } from './separator'
|
|
182
|
+
export { default as Slider } from './slider'
|
|
179
183
|
export { default as Skeleton } from './skeleton'
|
|
180
|
-
export { default as InlineIcon } from './inline-icon'
|
|
181
|
-
export { default as NavItems} from './nav-items'
|
|
182
|
-
export { default as Main } from './main'
|
|
183
|
-
export { default as ListBox } from './list-box'
|
|
184
184
|
export { default as StepIndicator } from './step-indicator'
|
|
185
|
+
export { default as Switch } from './switch'
|
|
186
|
+
export { default as TextArea } from './text-area'
|
|
187
|
+
export { Toaster, toast } from './sonner'
|
|
188
|
+
export { Toggle, toggleVariants } from './toggle'
|
|
189
|
+
export { ToggleGroup, ToggleGroupItem } from './toggle-group'
|
|
190
|
+
export { default as VideoPlayer } from './video-player'
|
|
191
|
+
export { default as YouTubeEmbed } from './youtube-embed'
|
|
185
192
|
|
|
186
193
|
export * as Icons from './icons'
|
|
187
194
|
|
|
@@ -3,8 +3,7 @@ import React from 'react'
|
|
|
3
3
|
|
|
4
4
|
import Spline from '@splinetool/react-spline'
|
|
5
5
|
|
|
6
|
-
import { cn, constrain } from '../util'
|
|
7
|
-
import { type Block, type VideoBlock, VideoBlockComponent } from '../blocks'
|
|
6
|
+
import { cn, constrain, spreadToTransform } from '../util'
|
|
8
7
|
import type { MediaStackDef, Dimensions } from '../types'
|
|
9
8
|
|
|
10
9
|
import Image from './image'
|
|
@@ -15,11 +14,13 @@ const MediaStack: React.FC<{
|
|
|
15
14
|
constrainTo?: Dimensions
|
|
16
15
|
clx?: string
|
|
17
16
|
}> = ({
|
|
18
|
-
media
|
|
17
|
+
media,
|
|
19
18
|
constrainTo: cnst = {w: 250, h: 250},
|
|
20
19
|
clx=''
|
|
21
20
|
}) => {
|
|
21
|
+
const {img, video, animation, mediaTransform} = media
|
|
22
22
|
|
|
23
|
+
const transform = mediaTransform ?? {}
|
|
23
24
|
|
|
24
25
|
// Order of precedence: 3D > MP4 > Image
|
|
25
26
|
if (animation) {
|
|
@@ -31,22 +32,23 @@ const MediaStack: React.FC<{
|
|
|
31
32
|
style={{
|
|
32
33
|
// // !aspect-[12/10]
|
|
33
34
|
width: (6/5 * (typeof cnst.h === 'number' ? cnst.h as number : parseInt(cnst.h as string)) ),
|
|
34
|
-
height: cnst.h
|
|
35
|
+
height: cnst.h,
|
|
36
|
+
...spreadToTransform(transform)
|
|
35
37
|
}}
|
|
36
38
|
/>
|
|
37
39
|
)
|
|
38
40
|
}
|
|
39
41
|
if (video) {
|
|
40
|
-
|
|
41
42
|
const dim = constrain(video.dim.md, cnst)
|
|
42
43
|
return (
|
|
43
44
|
<VideoPlayer
|
|
44
|
-
className={
|
|
45
|
+
className={clx}
|
|
45
46
|
sources={video.sources}
|
|
46
47
|
width={dim.w}
|
|
47
48
|
height={dim.h}
|
|
48
49
|
style={{
|
|
49
|
-
minHeight: dim.h // prevents layout jumps
|
|
50
|
+
minHeight: dim.h, // prevents layout jumps
|
|
51
|
+
...spreadToTransform(transform)
|
|
50
52
|
}}
|
|
51
53
|
{...video.videoProps}
|
|
52
54
|
/>
|
|
@@ -56,12 +58,12 @@ const MediaStack: React.FC<{
|
|
|
56
58
|
<Image
|
|
57
59
|
def={img}
|
|
58
60
|
constrainTo={cnst}
|
|
59
|
-
className={
|
|
61
|
+
className={clx}
|
|
62
|
+
transform={transform}
|
|
60
63
|
/>
|
|
61
64
|
) : (
|
|
62
65
|
<div style={{width: cnst.w, height: cnst.h}} className={cn('bg-level-2', clx)} />
|
|
63
66
|
)
|
|
64
|
-
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
export default MediaStack
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
import * as SliderPrimitive from '@radix-ui/react-slider'
|
|
4
|
+
|
|
5
|
+
import { cn } from '../util'
|
|
6
|
+
import { useState } from 'react'
|
|
7
|
+
|
|
8
|
+
const Slider = React.forwardRef<
|
|
9
|
+
React.ElementRef<typeof SliderPrimitive.Root>,
|
|
10
|
+
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root> & {
|
|
11
|
+
trackBgClx?: string
|
|
12
|
+
rangeBgClx?: string
|
|
13
|
+
thumbClx?: string
|
|
14
|
+
thumbSlidingClx?: string
|
|
15
|
+
}
|
|
16
|
+
>(({
|
|
17
|
+
className,
|
|
18
|
+
trackBgClx='bg-level-2',
|
|
19
|
+
rangeBgClx='bg-primary',
|
|
20
|
+
thumbClx='',
|
|
21
|
+
thumbSlidingClx='',
|
|
22
|
+
onValueChange,
|
|
23
|
+
onValueCommit,
|
|
24
|
+
...rest
|
|
25
|
+
}, ref) => {
|
|
26
|
+
|
|
27
|
+
const [sliding, setSliding] = useState<boolean>(false)
|
|
28
|
+
|
|
29
|
+
const _onChange = (value: number[]): void => {
|
|
30
|
+
if (!sliding) {
|
|
31
|
+
setSliding(true)
|
|
32
|
+
}
|
|
33
|
+
if (onValueChange) {
|
|
34
|
+
onValueChange(value)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const _onCommit = (value: number[]): void => {
|
|
39
|
+
setSliding(false)
|
|
40
|
+
if (onValueCommit) {
|
|
41
|
+
onValueCommit(value)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<SliderPrimitive.Root
|
|
47
|
+
ref={ref}
|
|
48
|
+
className={cn(
|
|
49
|
+
'relative flex w-full touch-none select-none items-center',
|
|
50
|
+
className
|
|
51
|
+
)}
|
|
52
|
+
onValueChange={_onChange}
|
|
53
|
+
onValueCommit={_onCommit}
|
|
54
|
+
{...rest}
|
|
55
|
+
>
|
|
56
|
+
<SliderPrimitive.Track data-vaul-no-drag className={'relative h-2 w-full grow overflow-hidden rounded-full ' + trackBgClx}>
|
|
57
|
+
<SliderPrimitive.Range data-vaul-no-drag className={'absolute h-full ' + rangeBgClx} />
|
|
58
|
+
</SliderPrimitive.Track>
|
|
59
|
+
<SliderPrimitive.Thumb data-vaul-no-drag className={cn(
|
|
60
|
+
'block h-5 w-5 rounded-full border-2 border-primary bg-background ',
|
|
61
|
+
'ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-1 ',
|
|
62
|
+
'focus-visible:ring-muted-2 focus-visible:ring-offset-1 disabled:pointer-events-none disabled:opacity-50',
|
|
63
|
+
thumbClx,
|
|
64
|
+
(sliding ? thumbSlidingClx : '')
|
|
65
|
+
)}/>
|
|
66
|
+
</SliderPrimitive.Root>
|
|
67
|
+
)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
Slider.displayName = SliderPrimitive.Root.displayName
|
|
71
|
+
|
|
72
|
+
export default Slider
|
package/types/index.ts
CHANGED
|
@@ -24,8 +24,8 @@ export {
|
|
|
24
24
|
export type { default as Icon } from './icon'
|
|
25
25
|
export type { default as ImageDef } from './image-def'
|
|
26
26
|
export type { default as LinkDef } from './link-def'
|
|
27
|
-
export type { default as MediaStackDef } from './media-stack-def'
|
|
28
27
|
export type { default as TShirtDimensions } from './tshirt-dimensions'
|
|
29
28
|
export type { default as TShirtSize } from './t-shirt-size'
|
|
30
29
|
export type { default as VideoDef } from './video-def'
|
|
31
30
|
|
|
31
|
+
export type { MediaStackDef, MediaTransform } from './media-stack-def'
|
package/types/media-stack-def.ts
CHANGED
|
@@ -2,10 +2,25 @@ import type AnimationDef from './animation-def'
|
|
|
2
2
|
import type ImageDef from './image-def'
|
|
3
3
|
import type VideoDef from './video-def'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* This will be implemented via css transforms,
|
|
7
|
+
* so will be a subset of those capabilities.
|
|
8
|
+
* Individual transforms will be added as they
|
|
9
|
+
* are needed.
|
|
10
|
+
*/
|
|
11
|
+
interface MediaTransform {
|
|
12
|
+
/** (X and Y) or [X, Y] */
|
|
13
|
+
scale?: number | number[]
|
|
14
|
+
}
|
|
15
|
+
|
|
5
16
|
interface MediaStackDef {
|
|
6
17
|
img?: ImageDef
|
|
7
18
|
video?: VideoDef
|
|
8
19
|
animation?: AnimationDef
|
|
20
|
+
mediaTransform?: MediaTransform
|
|
9
21
|
}
|
|
10
22
|
|
|
11
|
-
export
|
|
23
|
+
export type {
|
|
24
|
+
MediaStackDef,
|
|
25
|
+
MediaTransform
|
|
26
|
+
}
|
package/util/index.ts
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { MediaTransform } from '../types'
|
|
2
|
+
|
|
3
|
+
export default (t: MediaTransform) => {
|
|
4
|
+
|
|
5
|
+
let transformStrings: string[] = []
|
|
6
|
+
const scaleVal = 'scale' in t ? t.scale : undefined
|
|
7
|
+
if (scaleVal) {
|
|
8
|
+
if (typeof scaleVal === 'number') {
|
|
9
|
+
transformStrings.push(`scale(${scaleVal})`)
|
|
10
|
+
}
|
|
11
|
+
else if (
|
|
12
|
+
Array.isArray(scaleVal) &&
|
|
13
|
+
scaleVal.length == 2 &&
|
|
14
|
+
typeof scaleVal[0] === 'number'
|
|
15
|
+
) {
|
|
16
|
+
transformStrings.push(`scale(${scaleVal[0]}, ${scaleVal[1]})`)
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
throw new Error("parsing MediaTransform: Unrecognized value for 'scale'!")
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return transformStrings.length > 0 ? { transform: transformStrings.join(' ') } : {}
|
|
24
|
+
}
|