@hanzo/ui 4.5.4 → 4.7.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.
Files changed (203) hide show
  1. package/README.md +229 -0
  2. package/bin/create-registry.js +1 -1
  3. package/bin/test-mcp.sh +1 -1
  4. package/bin/update-registry.js +2 -2
  5. package/dist/index.d.mts +16 -0
  6. package/dist/index.d.ts +16 -0
  7. package/dist/index.js +9458 -0
  8. package/dist/index.mjs +9449 -0
  9. package/dist/lib/utils.d.mts +2 -0
  10. package/dist/lib/utils.d.ts +2 -0
  11. package/dist/lib/utils.js +47 -0
  12. package/dist/lib/utils.mjs +28 -0
  13. package/dist/src/utils.d.mts +7 -0
  14. package/dist/src/utils.d.ts +7 -0
  15. package/dist/src/utils.js +47 -0
  16. package/dist/src/utils.mjs +28 -0
  17. package/dist/tailwind/index.d.mts +2 -0
  18. package/dist/tailwind/index.d.ts +2 -0
  19. package/dist/tailwind/index.js +2048 -0
  20. package/dist/tailwind/index.mjs +2017 -0
  21. package/dist/types/index.d.mts +12 -0
  22. package/dist/types/index.d.ts +12 -0
  23. package/dist/types/index.js +79 -0
  24. package/dist/types/index.mjs +56 -0
  25. package/package.json +170 -23
  26. package/style/theme-provider.tsx +1 -1
  27. package/MCP-INSTRUCTIONS.md +0 -73
  28. package/README-MCP.md +0 -175
  29. package/blocks/components/accordian-block.tsx +0 -48
  30. package/blocks/components/block-component-props.ts +0 -11
  31. package/blocks/components/bullet-cards-block.tsx +0 -46
  32. package/blocks/components/card-block/index.tsx +0 -171
  33. package/blocks/components/card-block/link-out-button.tsx +0 -20
  34. package/blocks/components/card-block/util.ts +0 -28
  35. package/blocks/components/carte-blanche-block/index.tsx +0 -127
  36. package/blocks/components/carte-blanche-block/variant-content-left.tsx +0 -49
  37. package/blocks/components/content.tsx +0 -70
  38. package/blocks/components/cta-block.tsx +0 -115
  39. package/blocks/components/enh-heading-block.tsx +0 -204
  40. package/blocks/components/grid-block/grid-block-mutator.ts +0 -12
  41. package/blocks/components/grid-block/index.tsx +0 -83
  42. package/blocks/components/grid-block/mutator-registry.ts +0 -10
  43. package/blocks/components/grid-block/table-borders.mutator.ts +0 -47
  44. package/blocks/components/group-block.tsx +0 -83
  45. package/blocks/components/heading-block.tsx +0 -88
  46. package/blocks/components/image-block.tsx +0 -111
  47. package/blocks/components/index.ts +0 -30
  48. package/blocks/components/screenful-block/content.tsx +0 -123
  49. package/blocks/components/screenful-block/index.tsx +0 -107
  50. package/blocks/components/screenful-block/poster-background.tsx +0 -34
  51. package/blocks/components/screenful-block/video-background.tsx +0 -45
  52. package/blocks/components/space-block.tsx +0 -66
  53. package/blocks/components/video-block.tsx +0 -138
  54. package/blocks/def/accordian-block.ts +0 -14
  55. package/blocks/def/block.ts +0 -7
  56. package/blocks/def/bullet-cards-block.ts +0 -22
  57. package/blocks/def/card-block.ts +0 -22
  58. package/blocks/def/carte-blanche-block.ts +0 -21
  59. package/blocks/def/cta-block.ts +0 -19
  60. package/blocks/def/element-block.ts +0 -11
  61. package/blocks/def/enh-heading-block.ts +0 -44
  62. package/blocks/def/grid-block.ts +0 -16
  63. package/blocks/def/group-block.ts +0 -11
  64. package/blocks/def/heading-block.ts +0 -15
  65. package/blocks/def/image-block.ts +0 -31
  66. package/blocks/def/index.ts +0 -35
  67. package/blocks/def/screenful-block.ts +0 -54
  68. package/blocks/def/space-block.ts +0 -64
  69. package/blocks/def/video-block.ts +0 -9
  70. package/blocks/index.ts +0 -2
  71. package/dist/mcp/enhanced-server.d.ts +0 -29
  72. package/dist/mcp/enhanced-server.js +0 -1128
  73. package/dist/mcp/index.d.ts +0 -28
  74. package/dist/mcp/index.js +0 -436
  75. package/dist/registry/api.d.ts +0 -37
  76. package/dist/registry/api.js +0 -129
  77. package/dist/registry/index.d.ts +0 -353
  78. package/dist/registry/index.js +0 -45
  79. package/environment.d.ts +0 -6
  80. package/primitives/accordion.tsx +0 -66
  81. package/primitives/action-button.tsx +0 -42
  82. package/primitives/apply-typography.tsx +0 -55
  83. package/primitives/aspect-ratio.tsx +0 -5
  84. package/primitives/avatar.tsx +0 -49
  85. package/primitives/badge.tsx +0 -36
  86. package/primitives/breadcrumb.tsx +0 -115
  87. package/primitives/breakpoint-indicator.tsx +0 -19
  88. package/primitives/button.tsx +0 -85
  89. package/primitives/calendar.tsx +0 -72
  90. package/primitives/card.tsx +0 -83
  91. package/primitives/carousel.tsx +0 -237
  92. package/primitives/checkbox.tsx +0 -32
  93. package/primitives/combobox.tsx +0 -239
  94. package/primitives/command.tsx +0 -157
  95. package/primitives/context-menu.tsx +0 -200
  96. package/primitives/dialog-video-controller.tsx +0 -38
  97. package/primitives/dialog.tsx +0 -157
  98. package/primitives/drawer.tsx +0 -138
  99. package/primitives/form.tsx +0 -178
  100. package/primitives/icons/github.tsx +0 -14
  101. package/primitives/icons/index.ts +0 -18
  102. package/primitives/icons/youtube-logo.tsx +0 -59
  103. package/primitives/index-common.ts +0 -224
  104. package/primitives/index-next.ts +0 -2
  105. package/primitives/input-otp.tsx +0 -65
  106. package/primitives/input.tsx +0 -30
  107. package/primitives/label.tsx +0 -28
  108. package/primitives/list-adaptor.ts +0 -12
  109. package/primitives/list-box.tsx +0 -74
  110. package/primitives/loading-spinner.tsx +0 -33
  111. package/primitives/navigation-menu.tsx +0 -147
  112. package/primitives/next/image.tsx +0 -90
  113. package/primitives/next/index.ts +0 -7
  114. package/primitives/next/inline-icon.tsx +0 -36
  115. package/primitives/next/link-element.tsx +0 -109
  116. package/primitives/next/mdx-link.tsx +0 -22
  117. package/primitives/next/media-stack.tsx +0 -69
  118. package/primitives/next/nav-items.tsx +0 -45
  119. package/primitives/next/youtube-embed.tsx +0 -83
  120. package/primitives/popover.tsx +0 -37
  121. package/primitives/progress.tsx +0 -27
  122. package/primitives/radio-group.tsx +0 -56
  123. package/primitives/scroll-area.tsx +0 -47
  124. package/primitives/select.tsx +0 -169
  125. package/primitives/separator.tsx +0 -29
  126. package/primitives/sheet.tsx +0 -178
  127. package/primitives/skeleton.tsx +0 -20
  128. package/primitives/slider.tsx +0 -72
  129. package/primitives/sonner.tsx +0 -35
  130. package/primitives/step-indicator.tsx +0 -69
  131. package/primitives/switch.tsx +0 -35
  132. package/primitives/table.tsx +0 -117
  133. package/primitives/tabs.tsx +0 -60
  134. package/primitives/text-area.tsx +0 -26
  135. package/primitives/toggle-group.tsx +0 -63
  136. package/primitives/toggle.tsx +0 -73
  137. package/primitives/tooltip.tsx +0 -48
  138. package/primitives/video-player.tsx +0 -23
  139. package/public/r/accordion.json +0 -11
  140. package/public/r/alert.json +0 -11
  141. package/public/r/avatar.json +0 -11
  142. package/public/r/badge.json +0 -11
  143. package/public/r/button.json +0 -11
  144. package/public/r/card.json +0 -11
  145. package/public/r/checkbox.json +0 -11
  146. package/public/r/default.json +0 -6
  147. package/public/r/dialog.json +0 -11
  148. package/public/r/input.json +0 -11
  149. package/public/r/label.json +0 -11
  150. package/public/r/new-york.json +0 -6
  151. package/public/r/popover.json +0 -11
  152. package/public/r/select.json +0 -11
  153. package/public/r/table.json +0 -11
  154. package/public/r/tabs.json +0 -11
  155. package/public/r/toast.json +0 -11
  156. package/registry.json +0 -184
  157. package/src/mcp/README.md +0 -141
  158. package/src/mcp/enhanced-server.ts +0 -1208
  159. package/src/mcp/index.ts +0 -518
  160. package/src/mcp/package.json +0 -10
  161. package/src/registry/api.ts +0 -164
  162. package/src/registry/index.ts +0 -60
  163. package/src/registry/package.json +0 -10
  164. package/tailwind/colors.tailwind.js +0 -53
  165. package/tailwind/fontFamily.tailwind.ts +0 -7
  166. package/tailwind/fontSize.tailwind.ts +0 -13
  167. package/tailwind/index.ts +0 -7
  168. package/tailwind/safelist.tailwind.js +0 -26
  169. package/tailwind/screens.tailwind.js +0 -8
  170. package/tailwind/spacing.tailwind.js +0 -65
  171. package/tailwind/tailwind.config.hanzo-preset.d.ts +0 -5
  172. package/tailwind/tailwind.config.hanzo-preset.js +0 -915
  173. package/tailwind/tw-font-desc.ts +0 -15
  174. package/tailwind/typo-plugin/get-plugin-styles.js +0 -679
  175. package/tailwind/typo-plugin/index.d.ts +0 -9
  176. package/tailwind/typo-plugin/index.js +0 -141
  177. package/tailwind/typo-plugin/utils.js +0 -60
  178. package/tailwind/typography-test.mdx +0 -35
  179. package/tailwind/z-index.tailwind.js +0 -71
  180. package/test/test-registry.js +0 -73
  181. package/tsconfig.json +0 -22
  182. package/types/animation-def.ts +0 -3
  183. package/types/breakpoints.ts +0 -11
  184. package/types/bullet-item.ts +0 -10
  185. package/types/button-def.ts +0 -39
  186. package/types/dimensions.ts +0 -8
  187. package/types/grid-def.ts +0 -56
  188. package/types/image-def.ts +0 -32
  189. package/types/index.ts +0 -29
  190. package/types/link-def.ts +0 -56
  191. package/types/media-stack-def.ts +0 -31
  192. package/types/t-shirt-size.ts +0 -5
  193. package/types/tshirt-dimensions.ts +0 -20
  194. package/types/video-def.ts +0 -25
  195. package/util/format-and-abbreviate-as-currency.ts +0 -125
  196. package/util/format-to-max-char.ts +0 -68
  197. package/util/index-client.ts +0 -3
  198. package/util/index.ts +0 -78
  199. package/util/number-abbreviate.ts +0 -49
  200. package/util/specifier.ts +0 -43
  201. package/util/spread-to-transform.ts +0 -24
  202. package/util/step-animation.ts +0 -90
  203. package/util/two-way-map.ts +0 -19
@@ -1,111 +0,0 @@
1
- import React from 'react'
2
- import Image from 'next/image'
3
-
4
- import type { Dimensions } from '../../types'
5
- import type { ImageBlock } from '../def'
6
- import { constrain, containsToken, cn } from '../../util'
7
-
8
- import type BlockComponentProps from './block-component-props'
9
-
10
-
11
- const ImageBlockComponent: React.FC<BlockComponentProps & {
12
- constraintTo?: Dimensions
13
- }> = ({
14
- block,
15
- className='',
16
- agent,
17
- constraintTo
18
- }) => {
19
-
20
- if (block.blockType !== 'image') {
21
- return <>image block required</>
22
- }
23
-
24
- const {
25
- src,
26
- alt,
27
- dim,
28
- props,
29
- sizes,
30
- fullWidthOnMobile,
31
- svgFillClass,
32
- specifiers
33
- } = block as ImageBlock
34
-
35
- const specified = (s: string): boolean => (containsToken(specifiers, s))
36
-
37
- const toSpread: any = {}
38
- if (props?.fill === undefined) {
39
- const resolved = constraintTo ? constrain(dim, constraintTo) : dim
40
- toSpread.width = resolved.w
41
- toSpread.height = resolved.h
42
- }
43
-
44
- let _alt: string
45
- if (alt) {
46
- _alt = alt
47
- }
48
- else {
49
- const tokens = src.split('/')
50
- // Something remotely meaningful
51
- _alt = (tokens.length > 0) ? tokens[tokens.length] : src
52
- }
53
-
54
- const _svgFillClass = svgFillClass ?? ''
55
-
56
- // TODO: use two elements with 'md:hidden' for 3/4 size
57
- // https://nextjs.org/docs/app/building-your-application/optimizing/images#responsive
58
- if (agent === 'phone' ) {
59
- if (specified('mobile-full-width') || fullWidthOnMobile) {
60
- const toSpread: any = {
61
- style: {
62
- width: '100%',
63
- height: 'auto',
64
- maxWidth: '420px'
65
- },
66
- sizes: '100vw',
67
- }
68
- // only for aspect ratio and to satisfy parser
69
- toSpread.width = dim.w
70
- toSpread.height = dim.h
71
-
72
- return (
73
- <div className='flex flex-col items-center w-full'>
74
- <Image src={src} alt={_alt} {...toSpread} className={cn(_svgFillClass, className)}/>
75
- </div>
76
- )
77
- }
78
- // TODO use constraint
79
- else if (!specified('mobile-no-scale')) {
80
- if (props?.style?.width === 'auto' && typeof props.style.height === 'number' ) {
81
- props.style.height = props.style.height *.75
82
- }
83
- else if (props?.style?.height === 'auto' && typeof props?.style?.width === 'number' ) {
84
- props.style.width = props.style.width *.75
85
- }
86
- else if (props?.style && !props?.style.width) {
87
- toSpread.width = dim.w * .75
88
- toSpread.height = dim.h * .75
89
- }
90
- }
91
- }
92
- if (sizes) {
93
- toSpread.sizes = sizes
94
- }
95
-
96
- const right = containsToken(specifiers, 'right')
97
- const center = containsToken(specifiers, 'center')
98
-
99
- const alignSelfClx = right ? 'self-end' : (center ? 'self-center' : 'self-start')
100
-
101
- return (props?.fill) ? (
102
- <div className='relative w-full h-full'>
103
- <Image src={src} alt={_alt} {...toSpread} {...props} className={cn(_svgFillClass, 'max-w-[70vw] mx-auto', className)}/>
104
- </div>
105
- ) : (
106
- <Image src={src} alt={_alt} {...toSpread} {...props} className={cn(alignSelfClx, _svgFillClass, 'max-w-[70vw] mx-auto', className)}/>
107
- )
108
- }
109
-
110
- export default ImageBlockComponent
111
-
@@ -1,30 +0,0 @@
1
- import AccordianBlock from './accordian-block'
2
- import type BlockComponentProps from './block-component-props'
3
- import Blocks from './content'
4
- import CardBlock from './card-block'
5
- import { default as ContentComponent, registerBlockType} from './content'
6
- import CTABlock from './cta-block'
7
- import EnhHeadingBlock from './enh-heading-block'
8
- import GroupBlock from './group-block'
9
- import HeadingBlock from './heading-block'
10
- import ImageBlock from './image-block'
11
- import SpaceBlock from './space-block'
12
- import ScreenfulBlock from './screenful-block'
13
- import VideoBlock from './video-block'
14
-
15
- export {
16
- AccordianBlock as AccordianBlockComponent,
17
- type BlockComponentProps,
18
- Blocks as BlocksComponent,
19
- CardBlock as CardBlockComponent,
20
- ContentComponent,
21
- CTABlock as CTABlockComponent,
22
- EnhHeadingBlock as EnhHeadingBlockComponent,
23
- GroupBlock as GroupBlockComponent,
24
- HeadingBlock as HeadingBlockComponent,
25
- ImageBlock as ImageBlockComponent,
26
- registerBlockType,
27
- SpaceBlock as SpaceBlockComponent,
28
- ScreenfulBlock as ScreenfulBlockComponent,
29
- VideoBlock as VideoBlockComponent,
30
- }
@@ -1,123 +0,0 @@
1
- import React, { type PropsWithChildren } from 'react'
2
-
3
- import type { Block, ScreenfulBlock} from '../../def'
4
- import { containsToken, cn } from '../../../util'
5
- import ContentComponent from '../content'
6
-
7
- const ContentColumn: React.FC<{
8
- blocks: Block[]
9
- specifiers?: string
10
- agent?: string
11
- className?: string
12
- }> = ({
13
- blocks,
14
- specifiers,
15
- agent,
16
- className='',
17
- }) => {
18
-
19
- const specified = (s: string) => (containsToken(specifiers, s))
20
-
21
- let modifiers = ''
22
-
23
- if (agent !== 'phone') {
24
- if (specified('right')) {
25
- modifiers += 'items-end '
26
-
27
- }
28
- else if (specified('center')) {
29
- modifiers += 'items-center '
30
- }
31
- // default to left
32
- else {
33
- modifiers += 'items-start '
34
- }
35
- }
36
- // default to left
37
- else {
38
- modifiers += 'items-start '
39
- }
40
-
41
- if (agent !== 'phone') {
42
- if (specified('bottom')) {
43
- modifiers += 'justify-end '
44
- }
45
- else if (specified('vert-center')) {
46
- modifiers += 'justify-center '
47
- }
48
- // default to top
49
- else {
50
- modifiers += 'justify-start '
51
- }
52
- // right aligned text looks shitty on mobile
53
- if (specified('text-align-right')) {
54
- modifiers += 'text-right '
55
- }
56
- else {
57
- modifiers += 'text-left '
58
- }
59
- }
60
- else {
61
- if (specified('mobile-vert-center')) {
62
- modifiers += 'justify-center '
63
- }
64
- else {
65
- modifiers += 'justify-start '
66
- }
67
- }
68
-
69
- if (agent === 'phone' && specified('mobile-center-headings')) {
70
- modifiers += 'typography-headings:text-center '
71
- }
72
-
73
- /* ContentComponent's parent div needs h-full class in order for vertical alignment with flexbox to work.
74
- * This affects specifiers: bottom, vert-center, mobile-vert-center
75
- */
76
- return (
77
- <div className={cn('flex flex-col justify-center h-full', modifiers, className)} >
78
- <ContentComponent blocks={blocks} agent={agent} />
79
- </div>
80
- )
81
- }
82
-
83
- const Content: React.FC<{
84
- block: ScreenfulBlock
85
- agent?: string
86
- className?: string
87
- }> = ({
88
- block: b,
89
- agent,
90
- className='',
91
- }) => {
92
-
93
- // We need to set h-full when we have more than 1 column too, so the grid takes full height - Firefox and Safari fix.
94
- const layoutClx = 'flex flex-col gap-2 sm:gap-4 h-full ' + ((agent !== 'phone') ? ('md:grid md:gap-8 ' + `md:grid-cols-${b.contentColumns.length} `) : '')
95
-
96
- const orderclx = (columnIndex: number): string => {
97
- const orderIndex = b.mobileOrder?.indexOf(columnIndex)
98
- return (orderIndex && orderIndex >= 0) ? `order-${orderIndex} md:order-none` : '' // one-based in flexbox slec
99
- }
100
-
101
- return b.contentColumns.length == 1 ? (
102
- <ContentColumn
103
- blocks={b.contentColumns[0]}
104
- specifiers={b.columnSpecifiers?.[0]}
105
- agent={agent}
106
- className={cn(className)}
107
- />
108
- ) : (
109
- <div className={cn(layoutClx, className)}>
110
- {b.contentColumns.map((column, index) => (
111
- <ContentColumn
112
- blocks={column}
113
- specifiers={b.columnSpecifiers?.[index]}
114
- agent={agent}
115
- className={orderclx(index)}
116
- key={index}
117
- />
118
- ))}
119
- </div>
120
- )
121
- }
122
-
123
- export default Content
@@ -1,107 +0,0 @@
1
- 'use client'
2
-
3
- import React from 'react'
4
- import dynamic from 'next/dynamic'
5
-
6
- import type { Block, ScreenfulBlock, VideoBlock } from '../../def'
7
- import { containsToken, cn } from '../../../util'
8
- import { ApplyTypography } from '../../../primitives/index-common'
9
-
10
- import Poster from './poster-background'
11
- import Content from './content'
12
- const Video = dynamic(() => (import('./video-background')), {ssr: false, loading: () => (<></>)})
13
-
14
- const ScreenfulComponent: React.FC<{
15
- block: Block
16
- agent?: string
17
- initialInView?: boolean
18
- snapTile?: boolean
19
- clx?: string
20
- contentClx?: string
21
- bottom?: React.ReactNode
22
- }> = ({
23
- block,
24
- agent,
25
- initialInView=false,
26
- snapTile=false,
27
- clx='',
28
- contentClx='',
29
- bottom
30
- }) => {
31
-
32
- if (block.blockType !== 'screenful') {
33
- return <>screenful block required</>
34
- }
35
- const b = block as ScreenfulBlock
36
-
37
- const hasBannerVideo = (): boolean => (!!b.banner && (typeof b.banner === 'object'))
38
-
39
- const tileHeight = (agent === 'desktop') ? 'h-full ' : 'h-[100svh] '
40
-
41
- const specified = (s: string) => (containsToken(b.specifiers, s))
42
- const narrowGutters = specified('narrow-gutters') // eg, for a table object that is large
43
- const noGutters = specified('no-gutters')
44
- const fullScreenWidth = specified('full-screen-width')
45
- const vertCenter = specified('vert-center') // at the main level, it seems only useful w one column
46
- const oneColumn = b.contentColumns.length === 1
47
-
48
- // content wrapper clx:
49
- // [
50
- // positioning,
51
- // p&m,
52
- // p&m-modifiers
53
- // ]
54
- const cwclx = [
55
- 'xl:mx-auto overflow-y-hidden h-full',
56
- fullScreenWidth ? '' : 'max-w-screen-xl',
57
- // desktop header: 80px / pt-20
58
- // mobile header: 44px / pt-11
59
- narrowGutters ?
60
- 'px-6 lg:px-8 2xl:px-2 pb-4 lg:pb-6 xl:pb-8 ' + (snapTile ? 'pt-15 md:pt-26 lg:pt-28 ' : '') // otherwise assume there is a Main
61
- :
62
- noGutters ?
63
- 'px-0 pb-0 ' + (snapTile ? 'pt-11 lg:pt-20 ' : '') // otherwise assume there is a Main
64
- :
65
- 'px-[8vw] xl:px-[1vw] pb-[8vh] pt-[calc(44px+4vh)] md:pt-[calc(80px+6vh)] ',
66
-
67
- (agent && agent !== 'desktop') ? 'pt-15 sm:pt-17 pb-0 px-3 sm:px-8' : ''
68
- ]
69
-
70
- return (
71
- <section {...((b.anchorId) ? {id: b.anchorId} : {})} className={cn(
72
- snapTile ? 'snap-start snap-always h-[100vh]' : 'min-h-screen',
73
- bottom ? 'flex flex-col' : '',
74
- clx
75
- )}>
76
- <ApplyTypography className={cn(
77
- 'w-full flex flex-row justify-center self-stretch',
78
- snapTile ? tileHeight : '',
79
- bottom ? 'grow' : ''
80
- )}>
81
- <Poster banner={b.banner}>
82
- {hasBannerVideo() && (
83
- <Video
84
- block={b.banner! as VideoBlock}
85
- className='absolute top-0 left-0 bottom-0 right-0'
86
- initialInView={initialInView}
87
- />
88
- )}
89
- <div className={cn(
90
- ...cwclx,
91
- snapTile ? 'absolute left-0 right-0 top-0 bottom-0 ' : 'flex min-h-screen w-full',
92
- contentClx,
93
- // TODO :aa py-0 breaks padding for header! Investigate why I would have done this!
94
- vertCenter ? 'self-center ' + (oneColumn ? '!py-0' : '' ) : ''
95
- )}
96
- >
97
- <Content block={b} agent={agent} className='w-full'/>
98
- {b.footer}
99
- </div>
100
- </Poster>
101
- </ApplyTypography>
102
- {bottom}
103
- </section>
104
- )
105
- }
106
-
107
- export default ScreenfulComponent
@@ -1,34 +0,0 @@
1
- import React, { type PropsWithChildren } from 'react'
2
-
3
- import type { VideoBlock } from '../../def'
4
- import { cn } from '../../../util'
5
-
6
- const Poster: React.FC<{
7
- banner: VideoBlock | string | undefined,
8
- className?: string
9
- } & PropsWithChildren> = ({
10
- children,
11
- banner,
12
- className=''
13
- }) => (
14
- banner ? (
15
- <div
16
- className={cn('relative', className)}
17
- style={{
18
- height: '100%',
19
- width: '100%',
20
- backgroundImage: `url(${(typeof banner === 'string') ? banner : banner.poster!})`,
21
- backgroundSize: 'cover',
22
- backgroundRepeat: 'no-repeat',
23
- }}
24
- >
25
- {children}
26
- </div>
27
- ) : (
28
- <div className={cn('bg-transparent h-full w-full relative', className)}>
29
- {children}
30
- </div>
31
- )
32
- )
33
-
34
- export default Poster
@@ -1,45 +0,0 @@
1
- 'use client'
2
- import React from 'react'
3
-
4
- import { useInView } from 'react-intersection-observer'
5
-
6
- import type { VideoBlock } from '../../def'
7
-
8
- const VideoBG: React.FC<{
9
- block: VideoBlock,
10
- className?: string,
11
- initialInView: boolean
12
- }> = ({
13
- block,
14
- className='',
15
- initialInView
16
- }) => {
17
- const { ref, inView } = useInView({
18
- threshold: 0.75,
19
- initialInView,
20
- })
21
-
22
- return block ? (
23
- <div ref={ref} className={className}>
24
- {inView && (
25
- <video
26
- autoPlay
27
- loop
28
- muted
29
- style={{
30
- margin: 0,
31
- height: '100%',
32
- width: '100%',
33
- objectFit: 'cover',
34
- }}
35
- >
36
- {block.sources?.map((src, index) => (
37
- <source key={index} src={src} />
38
- ))}
39
- </video>
40
- )}
41
- </div>
42
- ) : null
43
- }
44
-
45
- export default VideoBG
@@ -1,66 +0,0 @@
1
- import React from 'react'
2
-
3
- import { ldMerge, cn } from '../../util'
4
-
5
- import type { Breakpoint } from '../../types'
6
- import { SPACE_DEFAULTS , type TWSpaceUnit, type HeadingLevel} from '../def/space-block'
7
- import type SpaceBlock from '../def/space-block'
8
- import { ApplyTypography } from '../../primitives/index-common'
9
-
10
- import type BlockComponentProps from './block-component-props'
11
-
12
- const TAGS = [
13
- 'div',
14
- 'h1',
15
- 'h2',
16
- 'h3',
17
- 'h4',
18
- 'h5',
19
- 'h6',
20
- ] satisfies React.ElementType[]
21
-
22
- const SpaceBlockComponent: React.FC<BlockComponentProps> = ({
23
- block,
24
- className=''
25
- }) => {
26
-
27
- if (block && block.blockType !== 'space') {
28
- return <>space block required</>
29
- }
30
-
31
- const b = block as SpaceBlock
32
-
33
- // This code path should handle a undefined or empty sizes field.
34
- if (!b.level) {
35
- if (typeof b.sizes == 'number') {
36
- return <div className={cn(`invisible w-[1px] h-${b.sizes}`, className) } />
37
- }
38
- const _sizes: {
39
- [key in (Breakpoint)]?: TWSpaceUnit
40
- } = {}
41
- ldMerge(_sizes, SPACE_DEFAULTS, b.sizes)
42
-
43
- let clx = ''
44
- for (const [key, value] of Object.entries(_sizes)) {
45
- // ts brain fart!
46
- clx += `${key}:h-${value as TWSpaceUnit} `
47
- }
48
-
49
- if (b.test) {
50
- console.log(clx)
51
- }
52
-
53
- return <div className={cn('invisible w-[1px] ' + clx, className)} />
54
- }
55
-
56
- const Tag = TAGS[b.level]
57
- const heightClx = (b.level === (0 satisfies HeadingLevel as HeadingLevel)) ? 'h-4' : ''
58
-
59
- return (
60
- <ApplyTypography className={className}>
61
- <Tag className={'invisible m-0 ' + heightClx} >&nbsp;</Tag>
62
- </ApplyTypography>
63
- )
64
- }
65
-
66
- export default SpaceBlockComponent
@@ -1,138 +0,0 @@
1
- 'use client'
2
- import React, { useEffect, useLayoutEffect, useState } from 'react'
3
-
4
- import Image from 'next/image'
5
-
6
- import type { Dimensions, TShirtSize, TShirtDimensions } from '../../types'
7
- import { constrain, asNum, cn } from '../../util'
8
- import type { VideoBlock } from '../def'
9
- import { VideoPlayer } from '../../primitives/index-common'
10
-
11
- import type BlockComponentProps from './block-component-props'
12
-
13
- const VideoBlockComponent: React.FC<BlockComponentProps & {
14
- usePoster?: boolean
15
- size?: TShirtSize
16
- constrainTo?: Dimensions
17
- }> = ({
18
- block,
19
- className='',
20
- agent,
21
- usePoster=false,
22
- size='md',
23
- constrainTo
24
- }) => {
25
-
26
- const [_dim, setDim] = useState<Dimensions | undefined>(undefined)
27
-
28
- const onResize = () => {
29
- setDim({
30
- w: window.innerWidth,
31
- h: window.innerHeight
32
- })
33
- }
34
-
35
- const windowDefined = typeof window !== 'undefined'
36
-
37
- useEffect(() => {
38
- if (window && agent === 'desktop') {
39
- window.addEventListener('resize', onResize)
40
- return () => window.removeEventListener('resize', onResize)
41
- }
42
- }, [windowDefined])
43
-
44
- useLayoutEffect(() => {
45
- onResize()
46
- }, [])
47
-
48
-
49
- if (block.blockType !== 'video') {
50
- return <>video block required</>
51
- }
52
-
53
- const b = block as VideoBlock
54
- const ar = b.dim.md.w / b.dim.md.h
55
- if (agent === 'phone') {
56
- if (b.sizing?.mobile?.vw) {
57
- // serverside, or at least while the video is loading,
58
- // generate the css for the correctly sized poster image
59
- if (!_dim) {
60
- const width = `${b.sizing.mobile.vw}vw`
61
- return <div className='dummy-div' style={{
62
- maxWidth: '100%',
63
- maxHeight: '100%',
64
- width,
65
- height: `calc(${width}/${ar})`,
66
- backgroundImage: `url(${b.poster!})`,
67
- backgroundSize: 'contain',
68
- backgroundRepeat: 'no-repeat',
69
- }} />
70
- }
71
- else {
72
- const width = ((b.sizing.mobile.vw / 100) * _dim.w)
73
- const dim = {
74
- h: width / ar,
75
- w: width
76
- }
77
- return ((
78
- <VideoPlayer
79
- className={cn('mx-auto', className)}
80
- sources={b.sources}
81
- width={dim.w}
82
- height={dim.h}
83
- {...b.videoProps}
84
- />
85
- ))
86
- }
87
- }
88
- }
89
- else if (b.sizing?.vh) {
90
- // serverside, generate the css for the correctly sized poster image
91
- if (!_dim) {
92
- const height = `${b.sizing.vh}vh`
93
- return <div className='dummy-div' style={{
94
- maxWidth: '100%',
95
- maxHeight: '100%',
96
- height: height,
97
- width: `calc(${height}*${ar})`,
98
- backgroundImage: `url(${b.poster!})`,
99
- backgroundSize: 'contain',
100
- backgroundRepeat: 'no-repeat',
101
- }} />
102
- }
103
- else {
104
-
105
- const height = ((b.sizing.vh / 100) * _dim.h)
106
- const dim = {
107
- h: height,
108
- w: height * ar
109
- }
110
- return ((
111
- <VideoPlayer
112
- className={cn('mx-auto', className)}
113
- sources={b.sources}
114
- width={dim.w}
115
- height={dim.h}
116
- {...b.videoProps}
117
- />
118
- ))
119
- }
120
- }
121
-
122
- const videoDims = b.dim as TShirtDimensions
123
- const dim = ((size && size in videoDims) ? videoDims[size] : videoDims.md) as Dimensions
124
- const conDim = (constrainTo ? constrain(dim, constrainTo) : dim)
125
- return usePoster ? (
126
- <Image src={b.poster!} alt='image' width={conDim.w} height={conDim.h} className={className}/>
127
- ) : (
128
- <VideoPlayer
129
- className={cn('mx-auto', className)}
130
- sources={b.sources}
131
- width={conDim.w}
132
- height={conDim.h}
133
- {...b.videoProps}
134
- />
135
- )
136
- }
137
-
138
- export default VideoBlockComponent
@@ -1,14 +0,0 @@
1
- import React from 'react'
2
- import type Block from './block'
3
-
4
- interface AccordianBlock extends Block {
5
- blockType: 'accordian'
6
- items: {
7
- trigger: string
8
- content: React.ReactNode
9
- }[]
10
- }
11
-
12
- export {
13
- type AccordianBlock as default
14
- }
@@ -1,7 +0,0 @@
1
- interface Block {
2
- blockType: string
3
- }
4
-
5
- export {
6
- type Block as default
7
- }