@nascentdigital/funnel-ui 4.6.1 → 5.0.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.
Files changed (68) hide show
  1. package/dist/client/fields/EmbeddedVideo/EmbeddedVideo.d.ts +2 -2
  2. package/dist/client/fields/EmbeddedVideo/EmbeddedVideo.js +3 -3
  3. package/dist/client/fields/EmbeddedVideo/vimeo/VimeoVideo.d.ts +3 -3
  4. package/dist/client/fields/EmbeddedVideo/vimeo/VimeoVideo.js +4 -3
  5. package/dist/client/fields/EmbeddedVideo/youtube/YoutubeVideo.d.ts +3 -3
  6. package/dist/client/fields/EmbeddedVideo/youtube/YoutubeVideo.js +4 -3
  7. package/dist/client/fields/LazyVideo.d.ts +6 -1
  8. package/dist/client/fields/LazyVideo.js +6 -4
  9. package/dist/client/hooks/useTouch.js +1 -0
  10. package/dist/client/interaction/paginator/Paginator.js +0 -1
  11. package/dist/server/blocks/Block.d.ts +82 -14
  12. package/dist/server/blocks/Block.js +782 -61
  13. package/dist/server/blocks/MediaLayout.d.ts +23 -4
  14. package/dist/server/blocks/MediaLayout.js +2 -12
  15. package/dist/server/blocks/RelatedPages.d.ts +2 -0
  16. package/dist/server/blocks/RelatedPages.js +4 -4
  17. package/dist/server/fields/Media.d.ts +79 -0
  18. package/dist/server/fields/Media.js +174 -0
  19. package/dist/server/fields/Visual.d.ts +7 -2
  20. package/dist/server/fields/Visual.js +9 -5
  21. package/dist/server/fields/index.d.ts +1 -0
  22. package/dist/server/fields/index.js +1 -0
  23. package/dist/server/index.d.ts +1 -0
  24. package/dist/server/index.js +1 -0
  25. package/dist/server/layouts/accordion/Accordion.d.ts +21 -0
  26. package/dist/server/layouts/accordion/Accordion.js +66 -0
  27. package/dist/server/layouts/accordion/AccordionContainer.d.ts +5 -0
  28. package/dist/server/layouts/accordion/AccordionContainer.js +18 -0
  29. package/dist/server/layouts/accordion/AccordionContext.d.ts +7 -0
  30. package/dist/server/layouts/accordion/AccordionContext.js +7 -0
  31. package/dist/server/layouts/accordion/AccordionExpander.d.ts +9 -0
  32. package/dist/server/layouts/accordion/AccordionExpander.js +72 -0
  33. package/dist/server/layouts/accordion/AccordionItem.d.ts +8 -0
  34. package/dist/server/layouts/accordion/AccordionItem.js +22 -0
  35. package/dist/server/layouts/accordion/AccordionLayout.d.ts +7 -0
  36. package/dist/server/layouts/accordion/AccordionLayout.js +26 -0
  37. package/dist/server/layouts/accordion/AccordionOptions.d.ts +3 -0
  38. package/dist/server/layouts/accordion/AccordionOptions.js +2 -0
  39. package/dist/server/layouts/accordion/index.d.ts +3 -0
  40. package/dist/server/layouts/accordion/index.js +19 -0
  41. package/dist/server/layouts/accordion/useAccordion.d.ts +1 -0
  42. package/dist/server/layouts/accordion/useAccordion.js +34 -0
  43. package/dist/server/layouts/index.d.ts +2 -1
  44. package/dist/server/layouts/index.js +2 -1
  45. package/dist/server/panels/BlockPanel.d.ts +14 -77
  46. package/dist/server/panels/BlockPanel.js +46 -702
  47. package/dist/server/panels/ListPanel.js +6 -3
  48. package/dist/server/panels/MessagePanel.js +33 -33
  49. package/dist/server/panels/VisualPanel.d.ts +58 -10
  50. package/dist/server/panels/VisualPanel.js +155 -79
  51. package/dist/server/schema/ListPanelLayout.d.ts +1 -0
  52. package/dist/server/schema/ListPanelLayout.js +1 -0
  53. package/dist/server/schema/RowRatio.d.ts +7 -0
  54. package/dist/server/schema/RowRatio.js +26 -0
  55. package/dist/server/schema/index.d.ts +1 -0
  56. package/dist/server/schema/index.js +1 -0
  57. package/dist/styles/blocks/Block-layout.css +88 -47
  58. package/dist/styles/blocks/Editorial.css +2 -2
  59. package/dist/styles/blocks/Form.css +2 -2
  60. package/dist/styles/blocks/MediaLayout.css +1 -1
  61. package/dist/styles/components/container.css +3 -24
  62. package/dist/styles/components/embed/YoutubePlayer.css +1 -1
  63. package/dist/styles/fields/Media.css +37 -0
  64. package/dist/styles/fields/_index.css +1 -0
  65. package/dist/styles/layouts/Accordion.css +29 -0
  66. package/dist/styles/layouts/_index.css +2 -1
  67. package/dist/styles/panels/VisualPanel.css +2 -1
  68. package/package.json +2 -2
@@ -1,15 +1,34 @@
1
1
  import { Schema } from '@nascentdigital/funnel-core';
2
2
  import { ComponentProps, JSXElementConstructor } from 'react';
3
3
  import { EmbeddedVideo } from '../../client/refs';
4
+ import { Media } from '../fields';
4
5
  import { Block } from './Block';
5
6
  export declare function MediaLayout({ EmbeddedVideoElement, ...props }: MediaLayout.Props): import("react/jsx-runtime").JSX.Element;
6
7
  export declare namespace MediaLayout {
7
8
  const Component: import("react").FunctionComponent<Block.Create.Result.ComponentProps<"_nd-mediaLayout", true, undefined, Schema.ListField<{
8
- visual: Schema.AssetField<Schema.AssetField.LinkedValue.Visual>;
9
- embedded: Schema.EmbeddedVideoField;
9
+ media: Schema.CollectionField<Schema.Collection<{
10
+ image: Schema.AssetField<Schema.AssetField.LinkedValue.Image>;
11
+ mobileImage: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Image>>;
12
+ }> | Schema.Collection<{
13
+ video: Schema.ObjectField<{
14
+ type: Schema.EnumField<Schema.EnumField.Options<Media.Video.Source.Type>>;
15
+ local: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Video>>;
16
+ remote: Schema.Optional<Schema.EmbeddedVideoField>;
17
+ }>;
18
+ cover: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Image>>;
19
+ }>>;
10
20
  }>, Schema.Block.Config, any>>, schema: Block.Create.Result.Schema<"_nd-mediaLayout", true, undefined, Schema.ListField<{
11
- visual: Schema.AssetField<Schema.AssetField.LinkedValue.Visual>;
12
- embedded: Schema.EmbeddedVideoField;
21
+ media: Schema.CollectionField<Schema.Collection<{
22
+ image: Schema.AssetField<Schema.AssetField.LinkedValue.Image>;
23
+ mobileImage: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Image>>;
24
+ }> | Schema.Collection<{
25
+ video: Schema.ObjectField<{
26
+ type: Schema.EnumField<Schema.EnumField.Options<Media.Video.Source.Type>>;
27
+ local: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Video>>;
28
+ remote: Schema.Optional<Schema.EmbeddedVideoField>;
29
+ }>;
30
+ cover: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Image>>;
31
+ }>>;
13
32
  }>, Schema.Block.Config>;
14
33
  type Model = Schema.Block.LinkedData<typeof schema>;
15
34
  type Props = Omit<ComponentProps<typeof Component>, 'children'> & {
@@ -16,17 +16,12 @@ const jsx_runtime_1 = require("react/jsx-runtime");
16
16
  const funnel_core_1 = require("@nascentdigital/funnel-core");
17
17
  const refs_1 = require("../../client/refs");
18
18
  const fields_1 = require("../fields");
19
- const panels_1 = require("../panels");
20
19
  const Block_1 = require("./Block");
21
20
  // block
22
21
  function MediaLayout(_a) {
23
22
  var { EmbeddedVideoElement = refs_1.EmbeddedVideo } = _a, props = __rest(_a, ["EmbeddedVideoElement"]);
24
23
  // render
25
- return ((0, jsx_runtime_1.jsx)(MediaLayout.Component, Object.assign({}, props, { children: ({ item }) => (0, jsx_runtime_1.jsx)("div", { className: "nd-MediaLayout-itemWrap", children: funnel_core_1.Schema.EmbeddedVideoField.Value.filter(item.value)
26
- ?
27
- (0, jsx_runtime_1.jsx)(EmbeddedVideoElement, { className: "nd-MediaLayout-item", video: item.value })
28
- :
29
- (0, jsx_runtime_1.jsx)(fields_1.Visual, { className: "nd-MediaLayout-item", visual: item.value }) }) })));
24
+ return ((0, jsx_runtime_1.jsx)(MediaLayout.Component, Object.assign({}, props, { children: ({ item }) => (0, jsx_runtime_1.jsx)("div", { className: "nd-MediaLayout-itemWrap", children: (0, jsx_runtime_1.jsx)(fields_1.Media, { className: "nd-MediaLayout-item", media: item.value }) }) })));
30
25
  }
31
26
  // extension
32
27
  (function (MediaLayout) {
@@ -42,12 +37,7 @@ function MediaLayout(_a) {
42
37
  name: 'Assets',
43
38
  description: 'Add one or more assets and then configure the layout.',
44
39
  itemTypes: {
45
- visual: panels_1.VisualPanel.Fields.visual.unwrap(),
46
- embedded: funnel_core_1.Schema.Field.embeddedVideo({
47
- name: 'Embedded Video',
48
- description: 'A remote streaming video (e.g. YouTube)',
49
- allowMuting: true
50
- })
40
+ media: fields_1.Media.schema
51
41
  },
52
42
  min: 1,
53
43
  max: 20
@@ -26,6 +26,7 @@ export declare namespace RelatedPages {
26
26
  slotVariation: import("..").SlotVariation.Schema;
27
27
  } & Record<"messageTextAlign", Schema.EnumField<Schema.EnumField.Options<import("..").TextAlignment>>> & Record<"messageWidth", Schema.EnumField<Schema.EnumField.Options<import("..").ItemSize>>> & Record<"messageHorizontalAlign", Schema.EnumField<Schema.EnumField.Options<import("..").ItemAlignment>>> & Record<"messageVerticalAlign", Schema.EnumField<Schema.EnumField.Options<import("..").ItemAlignment>>> & {
28
28
  contentAlign: import("..").ItemAlignment.Vertical.Schema;
29
+ contentSplit: import("..").RowRatio.Schema;
29
30
  } & Schema.Block.Config) | ({
30
31
  readonly theme: Schema.EnumField<Readonly<import("@nascentdigital/funnel-core").BlockThemes.Options>>;
31
32
  } & {
@@ -40,6 +41,7 @@ export declare namespace RelatedPages {
40
41
  slotVariation: import("..").SlotVariation.Schema;
41
42
  } & Record<"messageTextAlign", Schema.EnumField<Schema.EnumField.Options<import("..").TextAlignment>>> & Record<"messageWidth", Schema.EnumField<Schema.EnumField.Options<import("..").ItemSize>>> & Record<"messageHorizontalAlign", Schema.EnumField<Schema.EnumField.Options<import("..").ItemAlignment>>> & Record<"messageVerticalAlign", Schema.EnumField<Schema.EnumField.Options<import("..").ItemAlignment>>> & Record<`${any}Layout`, Schema.EnumField<Schema.EnumField.Options<keyof import("..").ListPanelLayout.Configs>>> & Record<`${any}Width`, Schema.EnumField<Schema.EnumField.Options<import("..").ItemSize>>> & Record<`${any}HorizontalAlign`, Schema.EnumField<Schema.EnumField.Options<import("..").ItemAlignment>>> & Record<`${any}VerticalAlign`, Schema.EnumField<Schema.EnumField.Options<import("..").ItemAlignment>>> & {
42
43
  contentAlign: import("..").ItemAlignment.Vertical.Schema;
44
+ contentSplit: import("..").RowRatio.Schema;
43
45
  } & Schema.Block.Config)>;
44
46
  namespace schema {
45
47
  type Args = {
@@ -39,7 +39,7 @@ function RelatedPages(_a) {
39
39
  const ctas = ctasRaw === null || ctasRaw === void 0 ? void 0 : ctasRaw.value;
40
40
  const pages = (_e = (_d = listRaw === null || listRaw === void 0 ? void 0 : listRaw.value) === null || _d === void 0 ? void 0 : _d.pages) !== null && _e !== void 0 ? _e : [];
41
41
  // panel layout
42
- const layout = panels_1.BlockPanel.getLayout({
42
+ const layout = Block_1.Block.getLayout({
43
43
  args: { fields, config },
44
44
  messageKey: 'message',
45
45
  listKey: 'list'
@@ -69,7 +69,7 @@ function RelatedPages(_a) {
69
69
  size
70
70
  }) });
71
71
  }
72
- const configSchema = panels_1.BlockPanel.getConfigSchema({
72
+ const configSchema = Block_1.Block.getConfigSchema({
73
73
  fields: fieldsSchema({ pageType: 'any', size: 0 }),
74
74
  messageKey: 'message',
75
75
  listKey: 'list'
@@ -81,12 +81,12 @@ function RelatedPages(_a) {
81
81
  version: 1,
82
82
  fields: fieldsSchema(args),
83
83
  config: configSchema,
84
- getConfig: args => panels_1.BlockPanel.getConfig({
84
+ getConfig: args => Block_1.Block.getConfig({
85
85
  args,
86
86
  messageKey: 'message',
87
87
  listKey: 'list'
88
88
  }),
89
- getLayout: args => panels_1.BlockPanel.getLayout({
89
+ getLayout: args => Block_1.Block.getLayout({
90
90
  args,
91
91
  messageKey: 'message',
92
92
  listKey: 'list'
@@ -0,0 +1,79 @@
1
+ import { Schema as SchemaCore } from '@nascentdigital/funnel-core';
2
+ import { Visual } from './Visual';
3
+ export declare function Media({ className, media, ...props }: Media.Props): import("react/jsx-runtime").JSX.Element | null;
4
+ export declare namespace Media {
5
+ namespace Image {
6
+ const collection: SchemaCore.Collection<{
7
+ image: SchemaCore.AssetField<SchemaCore.AssetField.LinkedValue.Image>;
8
+ mobileImage: SchemaCore.Optional<SchemaCore.AssetField<SchemaCore.AssetField.LinkedValue.Image>>;
9
+ }>;
10
+ type Collection = typeof collection;
11
+ type Value = SchemaCore.Collection.Data<Collection>;
12
+ type LinkedValue = SchemaCore.Collection.LinkedData<Collection>;
13
+ }
14
+ namespace Video {
15
+ namespace Source {
16
+ type Type = 'local' | 'remote';
17
+ const schema: SchemaCore.ObjectField<{
18
+ type: SchemaCore.EnumField<SchemaCore.EnumField.Options<Type>>;
19
+ local: SchemaCore.Optional<SchemaCore.AssetField<SchemaCore.AssetField.LinkedValue.Video>>;
20
+ remote: SchemaCore.Optional<SchemaCore.EmbeddedVideoField>;
21
+ }>;
22
+ type Schema = typeof schema;
23
+ type Value = SchemaCore.Field.Value<Schema>;
24
+ type LinkedValue = SchemaCore.Field.LinkedValue<Schema>;
25
+ type LocalSchema = SchemaCore.Optional.InnerType<Schema['content']['local']>;
26
+ type RemoteSchema = SchemaCore.Optional.InnerType<Schema['content']['remote']>;
27
+ }
28
+ const collection: SchemaCore.Collection<{
29
+ video: SchemaCore.ObjectField<{
30
+ type: SchemaCore.EnumField<SchemaCore.EnumField.Options<Source.Type>>;
31
+ local: SchemaCore.Optional<SchemaCore.AssetField<SchemaCore.AssetField.LinkedValue.Video>>;
32
+ remote: SchemaCore.Optional<SchemaCore.EmbeddedVideoField>;
33
+ }>;
34
+ cover: SchemaCore.Optional<SchemaCore.AssetField<SchemaCore.AssetField.LinkedValue.Image>>;
35
+ }>;
36
+ type Collection = typeof collection;
37
+ type Value = SchemaCore.Collection.Data<Collection>;
38
+ type LinkedValue = SchemaCore.Collection.LinkedData<Collection>;
39
+ }
40
+ const schema: SchemaCore.CollectionField<SchemaCore.Collection<{
41
+ image: SchemaCore.AssetField<SchemaCore.AssetField.LinkedValue.Image>;
42
+ mobileImage: SchemaCore.Optional<SchemaCore.AssetField<SchemaCore.AssetField.LinkedValue.Image>>;
43
+ }> | SchemaCore.Collection<{
44
+ video: SchemaCore.ObjectField<{
45
+ type: SchemaCore.EnumField<SchemaCore.EnumField.Options<Video.Source.Type>>;
46
+ local: SchemaCore.Optional<SchemaCore.AssetField<SchemaCore.AssetField.LinkedValue.Video>>;
47
+ remote: SchemaCore.Optional<SchemaCore.EmbeddedVideoField>;
48
+ }>;
49
+ cover: SchemaCore.Optional<SchemaCore.AssetField<SchemaCore.AssetField.LinkedValue.Image>>;
50
+ }>>;
51
+ type Schema = typeof schema;
52
+ namespace Schema {
53
+ function filter(value: SchemaCore.CollectionField): value is Media.Schema;
54
+ }
55
+ type Collection = Image.Collection | Video.Collection;
56
+ type Data = SchemaCore.Field.Data<Schema>;
57
+ type Value = Data['value'];
58
+ namespace Value {
59
+ function filter(value: any): value is Value;
60
+ function isImage(value: Value): value is Image.Value;
61
+ function isVideo(value: Value): value is Video.Value;
62
+ }
63
+ type LinkedData = SchemaCore.Field.LinkedData<Schema>;
64
+ type LinkedValue = LinkedData['value'];
65
+ namespace LinkedValue {
66
+ function filter(value: any): value is LinkedValue;
67
+ function isImage(value: LinkedValue): value is Image.LinkedValue;
68
+ function isVideo(value: LinkedValue): value is Video.LinkedValue;
69
+ }
70
+ type Props = {
71
+ className?: string;
72
+ media?: LinkedValue;
73
+ loading?: Visual.Loading;
74
+ controls?: boolean;
75
+ autoPlay?: boolean;
76
+ loop?: boolean;
77
+ mute?: boolean;
78
+ };
79
+ }
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Media = Media;
18
+ const jsx_runtime_1 = require("react/jsx-runtime");
19
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
20
+ const classnames_1 = __importDefault(require("classnames"));
21
+ const Visual_1 = require("./Visual");
22
+ // component
23
+ function Media(_a) {
24
+ var { className, media } = _a, props = __rest(_a, ["className", "media"]);
25
+ // skip if there's no media
26
+ if (!media) {
27
+ return null;
28
+ }
29
+ // or render image
30
+ let mediaClassName = undefined;
31
+ let content;
32
+ if (Media.LinkedValue.isImage(media)) {
33
+ mediaClassName = 'nd-Media-image';
34
+ content = renderImage(Object.assign({ media }, props));
35
+ }
36
+ // or render video
37
+ else if (Media.LinkedValue.isVideo(media)) {
38
+ // handle streaming video
39
+ mediaClassName = 'nd-Media-video';
40
+ content = renderVideo(Object.assign({ media }, props));
41
+ }
42
+ // or indicate error
43
+ else {
44
+ content = null;
45
+ }
46
+ // render
47
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('nd-Media', mediaClassName, className), children: content }));
48
+ }
49
+ // extension
50
+ (function (Media) {
51
+ // media types
52
+ let Image;
53
+ (function (Image) {
54
+ // collection
55
+ Image.collection = funnel_core_1.Schema.Collection.create({
56
+ type: '_nd-Media-image',
57
+ name: 'Image',
58
+ description: 'Image content for your website',
59
+ version: 1,
60
+ fields: {
61
+ image: funnel_core_1.Schema.Field.image({ name: 'Primary' }),
62
+ mobileImage: funnel_core_1.Schema.Field.image({ name: 'Mobile Optimized' }).optional()
63
+ }
64
+ });
65
+ })(Image = Media.Image || (Media.Image = {}));
66
+ let Video;
67
+ (function (Video) {
68
+ // source
69
+ let Source;
70
+ (function (Source) {
71
+ // schema
72
+ Source.schema = funnel_core_1.Schema.Field.object({
73
+ name: 'Video Source',
74
+ description: 'Represents local/remote video source',
75
+ preview: { title: 'type' },
76
+ content: {
77
+ type: funnel_core_1.Schema.Field.enumeration({
78
+ name: 'Type',
79
+ options: {
80
+ local: { name: 'Local' },
81
+ remote: { name: 'Remote' }
82
+ }
83
+ }),
84
+ local: funnel_core_1.Schema.Field.video({ name: 'Local Video' }).optional(),
85
+ remote: funnel_core_1.Schema.Field.embeddedVideo({ name: 'Remote Video' }).optional()
86
+ }
87
+ });
88
+ })(Source = Video.Source || (Video.Source = {}));
89
+ // schema
90
+ Video.collection = funnel_core_1.Schema.Collection.create({
91
+ type: '_nd-Media-video',
92
+ name: 'Video',
93
+ description: 'Small, decorative background video content',
94
+ version: 1,
95
+ fields: {
96
+ video: Source.schema,
97
+ cover: funnel_core_1.Schema.Field.image({ name: 'Cover' }).optional()
98
+ }
99
+ });
100
+ })(Video = Media.Video || (Media.Video = {}));
101
+ // schema
102
+ Media.schema = funnel_core_1.Schema.Field.collection({
103
+ name: 'Media',
104
+ description: 'Image, video, or streaming video content',
105
+ hint: 'Add and configure an image or video',
106
+ collections: [Image.collection, Video.collection]
107
+ });
108
+ let Schema;
109
+ (function (Schema) {
110
+ function filter(value) {
111
+ return value.type === 'collection'
112
+ && value.collections.every(schema => schema.type === Image.collection.type || schema.type === Video.collection.type);
113
+ }
114
+ Schema.filter = filter;
115
+ })(Schema = Media.Schema || (Media.Schema = {}));
116
+ let Value;
117
+ (function (Value) {
118
+ // helpers
119
+ function filter(value) {
120
+ return !!value
121
+ && typeof value === 'object' && !Array.isArray(value)
122
+ && 'type' in value && typeof value.type === 'string'
123
+ && (value.type === Image.collection.type || value.type === Video.collection.type);
124
+ }
125
+ Value.filter = filter;
126
+ function isImage(value) {
127
+ return value.type === Image.collection.type;
128
+ }
129
+ Value.isImage = isImage;
130
+ function isVideo(value) {
131
+ return value.type === Video.collection.type;
132
+ }
133
+ Value.isVideo = isVideo;
134
+ })(Value = Media.Value || (Media.Value = {}));
135
+ let LinkedValue;
136
+ (function (LinkedValue) {
137
+ // helpers
138
+ function filter(value) {
139
+ return !!value
140
+ && typeof value === 'object' && !Array.isArray(value)
141
+ && 'type' in value && typeof value.type === 'string'
142
+ && (value.type === Image.collection.type || value.type === Video.collection.type);
143
+ }
144
+ LinkedValue.filter = filter;
145
+ function isImage(value) {
146
+ return value.type === Image.collection.type;
147
+ }
148
+ LinkedValue.isImage = isImage;
149
+ function isVideo(value) {
150
+ return value.type === Video.collection.type;
151
+ }
152
+ LinkedValue.isVideo = isVideo;
153
+ })(LinkedValue = Media.LinkedValue || (Media.LinkedValue = {}));
154
+ })(Media || (exports.Media = Media = {}));
155
+ function renderImage({ media, loading }) {
156
+ // bind props
157
+ const { image: imageRaw, mobileImage: mobileImageRaw } = media.fields;
158
+ const image = imageRaw === null || imageRaw === void 0 ? void 0 : imageRaw.value;
159
+ const mobileImage = mobileImageRaw === null || mobileImageRaw === void 0 ? void 0 : mobileImageRaw.value;
160
+ // render
161
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Visual_1.Visual, { className: "nd-Media-image-desktop", visual: image, loading: loading }), mobileImage &&
162
+ (0, jsx_runtime_1.jsx)(Visual_1.Visual, { className: "nd-Media-image-mobile", visual: mobileImage, loading: loading })] }));
163
+ }
164
+ function renderVideo({ media, loading, controls, autoPlay, loop, mute }) {
165
+ var _a, _b, _c, _d;
166
+ // bind props
167
+ const { video: videoRaw, cover: coverRaw } = media.fields;
168
+ const { value: video } = (_d = (_b = (_a = videoRaw === null || videoRaw === void 0 ? void 0 : videoRaw.value) === null || _a === void 0 ? void 0 : _a.local) !== null && _b !== void 0 ? _b : (_c = videoRaw === null || videoRaw === void 0 ? void 0 : videoRaw.value) === null || _c === void 0 ? void 0 : _c.remote) !== null && _d !== void 0 ? _d : {};
169
+ const cover = coverRaw === null || coverRaw === void 0 ? void 0 : coverRaw.value;
170
+ // render
171
+ return ((0, jsx_runtime_1.jsx)(Visual_1.Visual, { className: (0, classnames_1.default)('nd-Media-video-player', {
172
+ '': media.type === ''
173
+ }), visual: video, loading: loading, cover: cover, controls: controls, autoPlay: autoPlay, loop: loop, muted: mute }));
174
+ }
@@ -1,11 +1,16 @@
1
1
  import { Schema } from '@nascentdigital/funnel-core';
2
2
  import { HTMLAttributes } from 'react';
3
- export declare function Visual({ className, visual, loading, ...props }: Visual.Props): import("react/jsx-runtime").JSX.Element | null;
3
+ export declare function Visual({ className, visual, cover, loading, controls, autoPlay, loop, muted, ...props }: Visual.Props): import("react/jsx-runtime").JSX.Element | null;
4
4
  export declare namespace Visual {
5
5
  const schema: Schema.AssetField<Schema.AssetField.LinkedValue.Visual>;
6
6
  type Props = Omit<HTMLAttributes<HTMLImageElement> & HTMLAttributes<HTMLVideoElement>, 'children'> & {
7
- visual?: Model;
7
+ visual?: Model | Schema.EmbeddedVideoField.Value;
8
+ cover?: Schema.AssetField.LinkedValue.Image;
8
9
  loading?: Loading;
10
+ controls?: boolean;
11
+ autoPlay?: boolean;
12
+ loop?: boolean;
13
+ muted?: boolean;
9
14
  };
10
15
  type Model = Schema.Field.LinkedValue<typeof schema>;
11
16
  type Loading = 'eager' | 'lazy';
@@ -22,18 +22,22 @@ const image_1 = __importDefault(require("next/image"));
22
22
  const refs_1 = require("../../client/refs");
23
23
  // component
24
24
  function Visual(_a) {
25
- var { className, visual, loading = 'lazy' } = _a, props = __rest(_a, ["className", "visual", "loading"]);
25
+ var { className, visual, cover, loading = 'lazy', controls = true, autoPlay = false, loop = false, muted = false } = _a, props = __rest(_a, ["className", "visual", "cover", "loading", "controls", "autoPlay", "loop", "muted"]);
26
26
  // skip if not set
27
27
  if (!visual) {
28
28
  return null;
29
29
  }
30
+ // handle embedded videos
31
+ else if (funnel_core_1.Schema.EmbeddedVideoField.Value.filter(visual)) {
32
+ return ((0, jsx_runtime_1.jsx)(refs_1.EmbeddedVideo, { className: (0, classnames_1.default)(className, 'nd-Visual nd-Visual-video'), video: visual, controls: controls, autoPlay: autoPlay, muted: muted }));
33
+ }
30
34
  // or error if not a visual
31
35
  else if (!funnel_core_1.Schema.AssetField.LinkedValue.Visual.filter(visual)) {
32
36
  return ((0, jsx_runtime_1.jsx)("span", { children: "Invalid media!" }));
33
37
  }
34
38
  // or render image
35
39
  else if (funnel_core_1.Schema.AssetField.LinkedValue.Image.filter(visual)) {
36
- const { url, description = '', metadata: { crop = 'center', dimensions } = {} } = visual !== null && visual !== void 0 ? visual : {};
40
+ const { url, description = '', metadata: { dimensions } = {} } = visual !== null && visual !== void 0 ? visual : {};
37
41
  const { width, height } = dimensions !== null && dimensions !== void 0 ? dimensions : {};
38
42
  return ((0, jsx_runtime_1.jsx)(image_1.default, Object.assign({}, props, { className: (0, classnames_1.default)(className, 'nd-Visual nd-Visual-image'), src: url, alt: description !== null && description !== void 0 ? description : '', width: dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, height: dimensions === null || dimensions === void 0 ? void 0 : dimensions.height, loading: loading, draggable: false, style: {
39
43
  '--_nd-visual-native-width': width ? `${width}` : '1',
@@ -42,16 +46,16 @@ function Visual(_a) {
42
46
  }
43
47
  // or render lazy
44
48
  else if (loading === 'eager') {
45
- const { type, url, metadata: { crop = 'center', dimensions } = {} } = visual !== null && visual !== void 0 ? visual : {};
49
+ const { type, url, metadata: { dimensions } = {} } = visual !== null && visual !== void 0 ? visual : {};
46
50
  const { width, height } = dimensions !== null && dimensions !== void 0 ? dimensions : {};
47
- return ((0, jsx_runtime_1.jsx)("video", Object.assign({}, props, { className: (0, classnames_1.default)(className, 'nd-Visual nd-Visual-video'), autoPlay: true, muted: true, loop: true, playsInline: true, style: {
51
+ return ((0, jsx_runtime_1.jsx)("video", Object.assign({}, props, { className: (0, classnames_1.default)(className, 'nd-Visual nd-Visual-video'), controls: controls, autoPlay: autoPlay, muted: muted, loop: loop, playsInline: true, poster: cover === null || cover === void 0 ? void 0 : cover.url, style: {
48
52
  '--_nd-visual-native-width': width ? `${width}` : '1',
49
53
  '--_nd-visual-native-height': height ? `${height}` : '1'
50
54
  }, children: (0, jsx_runtime_1.jsx)("source", { src: url, type: type }) })));
51
55
  }
52
56
  // or render image
53
57
  else {
54
- return ((0, jsx_runtime_1.jsx)(refs_1.LazyVideo, Object.assign({}, props, { className: (0, classnames_1.default)(className, 'nd-Visual nd-Visual-video'), video: visual })));
58
+ return ((0, jsx_runtime_1.jsx)(refs_1.LazyVideo, Object.assign({}, props, { className: (0, classnames_1.default)(className, 'nd-Visual nd-Visual-video'), controls: controls, autoPlay: autoPlay, muted: muted, loop: loop, video: visual, poster: cover === null || cover === void 0 ? void 0 : cover.url })));
55
59
  }
56
60
  }
57
61
  // extension
@@ -5,6 +5,7 @@ export * from './FreeFormContent';
5
5
  export * from './Headline';
6
6
  export * from './Icon';
7
7
  export * from './Link';
8
+ export * from './Media';
8
9
  export * from './Quote';
9
10
  export * from './RichText';
10
11
  export * from './Title';
@@ -21,6 +21,7 @@ __exportStar(require("./FreeFormContent"), exports);
21
21
  __exportStar(require("./Headline"), exports);
22
22
  __exportStar(require("./Icon"), exports);
23
23
  __exportStar(require("./Link"), exports);
24
+ __exportStar(require("./Media"), exports);
24
25
  __exportStar(require("./Quote"), exports);
25
26
  __exportStar(require("./RichText"), exports);
26
27
  __exportStar(require("./Title"), exports);
@@ -2,6 +2,7 @@ export * from './atomic';
2
2
  export * from './blocks';
3
3
  export * from './data';
4
4
  export * from './fields';
5
+ export * from './layouts';
5
6
  export * from './panels';
6
7
  export * from './schema';
7
8
  export * from './sections';
@@ -18,6 +18,7 @@ __exportStar(require("./atomic"), exports);
18
18
  __exportStar(require("./blocks"), exports);
19
19
  __exportStar(require("./data"), exports);
20
20
  __exportStar(require("./fields"), exports);
21
+ __exportStar(require("./layouts"), exports);
21
22
  __exportStar(require("./panels"), exports);
22
23
  __exportStar(require("./schema"), exports);
23
24
  __exportStar(require("./sections"), exports);
@@ -0,0 +1,21 @@
1
+ import { Tagged } from 'type-fest';
2
+ import { AccordionOptions } from './AccordionOptions';
3
+ export declare class Accordion {
4
+ private readonly _expanded$;
5
+ private readonly _focused$;
6
+ readonly multiExpand: boolean;
7
+ constructor({ multiExpand }?: Accordion.ConstructorArgs);
8
+ get expanded$(): import("rxjs").Observable<readonly Accordion.Id[]>;
9
+ get expanded(): readonly Accordion.Id[];
10
+ get focused$(): import("rxjs").Observable<Accordion.Id | undefined>;
11
+ get focused(): Accordion.Id | undefined;
12
+ isExpanded(accordionId: Accordion.Id): boolean;
13
+ onExpand(accordionId: Accordion.Id): void;
14
+ onCollapse(accordionId: Accordion.Id): void;
15
+ onFocus(accordionId: Accordion.Id): void;
16
+ onBlur(accordionId: Accordion.Id): void;
17
+ }
18
+ export declare namespace Accordion {
19
+ type Id = Tagged<string, 'Accordion.Id'>;
20
+ type ConstructorArgs = Partial<AccordionOptions>;
21
+ }
@@ -0,0 +1,66 @@
1
+ 'use client';
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Accordion = void 0;
5
+ const rxjs_1 = require("rxjs");
6
+ // class
7
+ class Accordion {
8
+ constructor({ multiExpand = false } = {}) {
9
+ // initialize instance variables
10
+ this._expanded$ = new rxjs_1.BehaviorSubject([]);
11
+ this._focused$ = new rxjs_1.BehaviorSubject(undefined);
12
+ this.multiExpand = multiExpand;
13
+ }
14
+ get expanded$() {
15
+ return this._expanded$.asObservable();
16
+ }
17
+ get expanded() {
18
+ return this._expanded$.value;
19
+ }
20
+ get focused$() {
21
+ return this._focused$.asObservable();
22
+ }
23
+ get focused() {
24
+ return this._focused$.value;
25
+ }
26
+ isExpanded(accordionId) {
27
+ return this.expanded.includes(accordionId);
28
+ }
29
+ onExpand(accordionId) {
30
+ // skip if already expanded
31
+ const { expanded, multiExpand } = this;
32
+ if (expanded.includes(accordionId)) {
33
+ return;
34
+ }
35
+ // add to expanded if multi-expand is enabled
36
+ if (multiExpand) {
37
+ this._expanded$.next([...expanded, accordionId]);
38
+ }
39
+ // otherwise, replace
40
+ else {
41
+ this._expanded$.next([accordionId]);
42
+ }
43
+ }
44
+ onCollapse(accordionId) {
45
+ // skip if not expanded
46
+ const { expanded, multiExpand } = this;
47
+ if (!expanded.includes(accordionId)) {
48
+ return;
49
+ }
50
+ // update by stripping out id from list
51
+ this._expanded$.next(expanded.filter(id => id !== accordionId));
52
+ }
53
+ onFocus(accordionId) {
54
+ // update if not already focused
55
+ if (this.focused !== accordionId) {
56
+ this._focused$.next(accordionId);
57
+ }
58
+ }
59
+ onBlur(accordionId) {
60
+ // update if id was in focus
61
+ if (this.focused === accordionId) {
62
+ this._focused$.next(undefined);
63
+ }
64
+ }
65
+ }
66
+ exports.Accordion = Accordion;
@@ -0,0 +1,5 @@
1
+ import { PropsWithChildren } from 'react';
2
+ export declare function AccordionContainer({ children }: AccordionContainer.Props): import("react/jsx-runtime").JSX.Element;
3
+ export declare namespace AccordionContainer {
4
+ type Props = PropsWithChildren;
5
+ }
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AccordionContainer = AccordionContainer;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("motion/react");
7
+ const react_2 = require("react");
8
+ const Accordion_1 = require("./Accordion");
9
+ const AccordionContext_1 = require("./AccordionContext");
10
+ // component
11
+ function AccordionContainer({ children }) {
12
+ // bind context
13
+ const context = (0, react_2.useMemo)(() => ({
14
+ accordion: new Accordion_1.Accordion()
15
+ }), []);
16
+ // render
17
+ return ((0, jsx_runtime_1.jsx)(AccordionContext_1.AccordionContext.Provider, { value: context, children: (0, jsx_runtime_1.jsx)(react_1.MotionConfig, { transition: { duration: 0.3 }, children: children }) }));
18
+ }
@@ -0,0 +1,7 @@
1
+ import { Accordion } from './Accordion';
2
+ export declare const AccordionContext: import("react").Context<AccordionContext.Data>;
3
+ export declare namespace AccordionContext {
4
+ type Data = {
5
+ accordion?: Accordion;
6
+ };
7
+ }
@@ -0,0 +1,7 @@
1
+ 'use client';
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AccordionContext = void 0;
5
+ const react_1 = require("react");
6
+ // context
7
+ exports.AccordionContext = (0, react_1.createContext)({});
@@ -0,0 +1,9 @@
1
+ import { ReactNode } from 'react';
2
+ export declare function AccordionExpander({ className, header, content, ...props }: AccordionExpander.Props): import("react/jsx-runtime").JSX.Element;
3
+ export declare namespace AccordionExpander {
4
+ type Props = {
5
+ className?: string;
6
+ header: ReactNode;
7
+ content: ReactNode;
8
+ };
9
+ }