@nascentdigital/funnel-ui 4.4.21 → 4.5.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 (91) hide show
  1. package/dist/Tailwind.d.ts +5 -1
  2. package/dist/Tailwind.js +9 -0
  3. package/dist/server/blocks/Block.d.ts +42 -2
  4. package/dist/server/blocks/Block.js +88 -0
  5. package/dist/server/blocks/Clients.d.ts +20 -28
  6. package/dist/server/blocks/Clients.js +13 -57
  7. package/dist/server/blocks/MediaLayout.d.ts +11 -302
  8. package/dist/server/blocks/MediaLayout.js +19 -65
  9. package/dist/server/blocks/Message.d.ts +9 -67
  10. package/dist/server/blocks/Message.js +15 -292
  11. package/dist/server/blocks/Outcome.d.ts +22 -81
  12. package/dist/server/blocks/Outcome.js +20 -474
  13. package/dist/server/blocks/OutcomeDetail.d.ts +5 -2
  14. package/dist/server/blocks/Testimonial.d.ts +81 -16
  15. package/dist/server/blocks/Testimonial.js +59 -27
  16. package/dist/server/blocks/Testimonials.d.ts +41 -0
  17. package/dist/server/blocks/Testimonials.js +90 -0
  18. package/dist/server/blocks/ValueProp.d.ts +19 -37
  19. package/dist/server/blocks/ValueProp.js +14 -100
  20. package/dist/server/blocks/index.d.ts +1 -0
  21. package/dist/server/blocks/index.js +1 -0
  22. package/dist/server/blocks/summary/Statement.d.ts +304 -0
  23. package/dist/server/blocks/summary/Statement.js +52 -0
  24. package/dist/server/blocks/summary/Summary.d.ts +19 -0
  25. package/dist/server/blocks/summary/Summary.js +34 -0
  26. package/dist/server/blocks/summary/index.d.ts +1 -0
  27. package/dist/server/blocks/summary/index.js +17 -0
  28. package/dist/server/entities/Client.d.ts +1 -1
  29. package/dist/server/entities/Person.d.ts +27 -2
  30. package/dist/server/entities/Person.js +55 -5
  31. package/dist/server/entities/UniqueSellingPoint.d.ts +1 -1
  32. package/dist/server/layouts/BrickLayout.d.ts +290 -0
  33. package/dist/server/layouts/BrickLayout.js +25 -0
  34. package/dist/server/layouts/CardLayout.d.ts +291 -0
  35. package/dist/server/layouts/CardLayout.js +25 -0
  36. package/dist/server/layouts/FlexWrapLayout.d.ts +290 -0
  37. package/dist/server/layouts/FlexWrapLayout.js +41 -0
  38. package/dist/server/layouts/StackLayout.d.ts +290 -0
  39. package/dist/server/layouts/StackLayout.js +25 -0
  40. package/dist/server/layouts/grid/GridItem.d.ts +8 -0
  41. package/dist/server/layouts/grid/GridItem.js +9 -0
  42. package/dist/server/layouts/grid/GridLayout.d.ts +293 -0
  43. package/dist/server/layouts/grid/GridLayout.js +25 -0
  44. package/dist/server/layouts/grid/index.d.ts +2 -0
  45. package/dist/server/layouts/grid/index.js +18 -0
  46. package/dist/server/layouts/index.d.ts +5 -0
  47. package/dist/server/layouts/index.js +21 -0
  48. package/dist/server/panels/BlockPanel.d.ts +96 -1
  49. package/dist/server/panels/BlockPanel.js +856 -0
  50. package/dist/server/panels/ListPanel.d.ts +63 -0
  51. package/dist/server/panels/ListPanel.js +147 -0
  52. package/dist/server/panels/MessagePanel.d.ts +71 -5
  53. package/dist/server/panels/MessagePanel.js +158 -6
  54. package/dist/server/panels/TestimonialPanel.d.ts +47 -0
  55. package/dist/server/panels/TestimonialPanel.js +71 -0
  56. package/dist/server/panels/VisualPanel.d.ts +46 -13
  57. package/dist/server/panels/VisualPanel.js +85 -17
  58. package/dist/server/panels/index.d.ts +2 -0
  59. package/dist/server/panels/index.js +2 -0
  60. package/dist/server/schema/BlockConfig.d.ts +3 -1
  61. package/dist/server/schema/BlockConfig.js +2 -1
  62. package/dist/server/schema/ItemAlignment.d.ts +2 -0
  63. package/dist/server/schema/ItemPosition.d.ts +1 -0
  64. package/dist/server/schema/ItemSize.d.ts +2 -1
  65. package/dist/server/schema/ItemSize.js +2 -1
  66. package/dist/server/schema/ListPanelLayout.d.ts +34 -0
  67. package/dist/server/schema/ListPanelLayout.js +24 -0
  68. package/dist/server/schema/PanelLayout.d.ts +14 -0
  69. package/dist/server/schema/PanelLayout.js +70 -0
  70. package/dist/server/schema/SlotVariation.d.ts +9 -0
  71. package/dist/server/schema/SlotVariation.js +48 -0
  72. package/dist/server/schema/TextAlignment.d.ts +1 -0
  73. package/dist/server/schema/index.d.ts +3 -0
  74. package/dist/server/schema/index.js +3 -0
  75. package/dist/styles/blocks/Clients.css +0 -1
  76. package/dist/styles/blocks/Message.css +0 -343
  77. package/dist/styles/blocks/Outcome.css +13 -50
  78. package/dist/styles/blocks/Summary.css +15 -0
  79. package/dist/styles/blocks/Testimonial.css +1 -318
  80. package/dist/styles/blocks/ValueProp.css +0 -126
  81. package/dist/styles/blocks/_index.css +1 -0
  82. package/dist/styles/layouts/BrickLayout.css +43 -0
  83. package/dist/styles/layouts/CardLayout.css +46 -0
  84. package/dist/styles/layouts/FlexWrapLayout.css +38 -0
  85. package/dist/styles/layouts/GridLayout.css +25 -0
  86. package/dist/styles/layouts/StackLayout.css +46 -0
  87. package/dist/styles/layouts/_index.css +6 -1
  88. package/dist/styles/panels/ListPanel.css +3 -0
  89. package/dist/styles/panels/TestimonialPanel.css +64 -0
  90. package/dist/styles/panels/_index.css +2 -0
  91. package/package.json +3 -2
@@ -0,0 +1,63 @@
1
+ import { BlockLayout, Schema, Transform } from '@nascentdigital/funnel-core';
2
+ import { ReactNode } from 'react';
3
+ import { HTMLElements } from '../../types';
4
+ import { ItemAlignment, ItemSize, ListPanelLayout } from '../schema';
5
+ import { BlockPanel } from './BlockPanel';
6
+ export declare function ListPanel<TItem extends ListPanel.Item>({ as, className, panel, layout, items, overrides, children }: ListPanel.Props<TItem>): import("react/jsx-runtime").JSX.Element;
7
+ export declare namespace ListPanel {
8
+ namespace Config {
9
+ type Key<TPrefix extends string = string> = Key.HorizontalAlign<TPrefix> | Key.VerticalAlign<TPrefix> | Key.Width<TPrefix>;
10
+ namespace Key {
11
+ type Layout<TPrefix extends string> = `${TPrefix}Layout`;
12
+ function layout<TPrefix extends string>(prefix: TPrefix): Layout<TPrefix>;
13
+ type Width<TPrefix extends string> = `${TPrefix}Width`;
14
+ function width<TPrefix extends string>(prefix: TPrefix): Width<TPrefix>;
15
+ type HorizontalAlign<TPrefix extends string> = `${TPrefix}HorizontalAlign`;
16
+ function horizontalAlign<TPrefix extends string>(prefix: TPrefix): HorizontalAlign<TPrefix>;
17
+ type VerticalAlign<TPrefix extends string> = `${TPrefix}VerticalAlign`;
18
+ function verticalAlign<TPrefix extends string>(prefix: TPrefix): VerticalAlign<TPrefix>;
19
+ }
20
+ type Keys<TPrefix extends string> = {
21
+ layout: Key.Layout<TPrefix>;
22
+ width: Key.Width<TPrefix>;
23
+ horizontalAlign: Key.HorizontalAlign<TPrefix>;
24
+ verticalAlign: Key.VerticalAlign<TPrefix>;
25
+ };
26
+ function getKeys<TPrefix extends string>(prefix: TPrefix): Keys<TPrefix>;
27
+ type Entries<TPrefix extends string> = Record<Key.Width<TPrefix>, ItemSize.Schema> & Record<Key.HorizontalAlign<TPrefix>, ItemAlignment.Horizontal.Schema> & Record<Key.VerticalAlign<TPrefix>, ItemAlignment.Vertical.Schema>;
28
+ }
29
+ type Item = {
30
+ id: string;
31
+ };
32
+ type Props<TItem extends Item> = {
33
+ as?: HTMLElements.Standard.Container;
34
+ className?: string;
35
+ panel: BlockLayout.List;
36
+ layout: ListPanelLayout;
37
+ items: ReadonlyArray<TItem>;
38
+ overrides?: Overrides;
39
+ children: Transform<TItem, ReactNode>;
40
+ };
41
+ namespace Props {
42
+ type Configuration = Pick<Partial<Props<any>>, 'className' | 'layout' | 'overrides'>;
43
+ }
44
+ type Overrides = {
45
+ [TKey in keyof ListPanelLayout.Configs]?: Partial<ListPanelLayout.Configs[TKey]>;
46
+ };
47
+ namespace GetConfig {
48
+ type ConfigSchema<TPrefix extends string> = Record<Config.Key.Layout<TPrefix>, ListPanelLayout.Schema> & Record<Config.Key.Width<TPrefix>, ItemSize.Schema> & Record<Config.Key.HorizontalAlign<TPrefix>, ItemAlignment.Horizontal.Schema> & Record<Config.Key.VerticalAlign<TPrefix>, ItemAlignment.Vertical.Schema>;
49
+ type ConfigData<TPrefix extends string> = Schema.Block.Data.ForConfig<ConfigSchema<TPrefix>>;
50
+ type Args<TPrefix extends string> = {
51
+ listKey: TPrefix;
52
+ config?: Partial<ConfigData<TPrefix>>;
53
+ flexDirection?: BlockPanel.Slots.FlexDirection;
54
+ };
55
+ type Result<TPrefix extends string> = {
56
+ configSchema: Partial<ConfigSchema<TPrefix>>;
57
+ config: Partial<ConfigData<TPrefix>>;
58
+ defaultConfig: Partial<ConfigData<TPrefix>>;
59
+ };
60
+ }
61
+ function getConfig<TPrefix extends string>({ listKey, config, flexDirection }: GetConfig.Args<TPrefix>): GetConfig.Result<TPrefix>;
62
+ function ItemPlaceholder(): import("react/jsx-runtime").JSX.Element;
63
+ }
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ListPanel = ListPanel;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
9
+ const classnames_1 = __importDefault(require("classnames"));
10
+ const react_1 = require("react");
11
+ const layouts_1 = require("../layouts");
12
+ const schema_1 = require("../schema");
13
+ const BlockPanel_1 = require("./BlockPanel");
14
+ // component
15
+ function ListPanel({ as = 'ul', className, panel, layout, items, overrides = {}, children }) {
16
+ // render items (or placeholder)
17
+ const itemsComponent = items.length > 0
18
+ ?
19
+ items.map(item => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: children(item) }, item.id))
20
+ :
21
+ funnel_core_1.ArrayUtils.series(panel.itemCount.base - 1).map(num => (0, jsx_runtime_1.jsx)(ListPanel.ItemPlaceholder, {}, num));
22
+ // build layout options
23
+ const { brick, brickFlipped, card, flexWrap, grid, horizontalStack, verticalStack, } = overrides;
24
+ // render layout
25
+ let layoutComponent;
26
+ switch (layout) {
27
+ case 'brick':
28
+ layoutComponent = ((0, jsx_runtime_1.jsx)(layouts_1.BrickLayout, Object.assign({ as: as }, brick, { children: itemsComponent })));
29
+ break;
30
+ case 'brickFlipped':
31
+ layoutComponent = ((0, jsx_runtime_1.jsx)(layouts_1.BrickLayout, Object.assign({ as: as, flipped: true }, brickFlipped, { children: itemsComponent })));
32
+ break;
33
+ case 'card':
34
+ layoutComponent = ((0, jsx_runtime_1.jsx)(layouts_1.CardLayout, Object.assign({ as: as }, card, { children: itemsComponent })));
35
+ break;
36
+ case 'flexWrap':
37
+ layoutComponent = ((0, jsx_runtime_1.jsx)(layouts_1.FlexWrapLayout, Object.assign({ as: as }, flexWrap, { children: itemsComponent })));
38
+ break;
39
+ case 'grid':
40
+ layoutComponent = ((0, jsx_runtime_1.jsx)(layouts_1.GridLayout, Object.assign({ as: as, columns: 3 }, grid, { children: itemsComponent })));
41
+ break;
42
+ case 'horizontalStack':
43
+ layoutComponent = ((0, jsx_runtime_1.jsx)(layouts_1.StackLayout, Object.assign({ as: as, direction: "horizontal" }, horizontalStack, { children: itemsComponent })));
44
+ break;
45
+ case 'verticalStack':
46
+ layoutComponent = ((0, jsx_runtime_1.jsx)(layouts_1.StackLayout, Object.assign({ as: as, direction: "vertical" }, verticalStack, { children: itemsComponent })));
47
+ }
48
+ // render
49
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, '@container nd-ListPanel',
50
+ // base layout
51
+ BlockPanel_1.BlockPanel.getClassNames({ panel })), children: (0, jsx_runtime_1.jsx)("div", { className: "nd-BlockPanel-content nd-ListPanel-content", children: layoutComponent }) }));
52
+ }
53
+ // extension
54
+ (function (ListPanel) {
55
+ // config
56
+ let Config;
57
+ (function (Config) {
58
+ let Key;
59
+ (function (Key) {
60
+ function layout(prefix) {
61
+ return `${prefix}Layout`;
62
+ }
63
+ Key.layout = layout;
64
+ function width(prefix) {
65
+ return `${prefix}Width`;
66
+ }
67
+ Key.width = width;
68
+ function horizontalAlign(prefix) {
69
+ return `${prefix}HorizontalAlign`;
70
+ }
71
+ Key.horizontalAlign = horizontalAlign;
72
+ function verticalAlign(prefix) {
73
+ return `${prefix}VerticalAlign`;
74
+ }
75
+ Key.verticalAlign = verticalAlign;
76
+ })(Key = Config.Key || (Config.Key = {}));
77
+ function getKeys(prefix) {
78
+ return {
79
+ layout: `${prefix}Layout`,
80
+ width: `${prefix}Width`,
81
+ horizontalAlign: `${prefix}HorizontalAlign`,
82
+ verticalAlign: `${prefix}VerticalAlign`
83
+ };
84
+ }
85
+ Config.getKeys = getKeys;
86
+ })(Config = ListPanel.Config || (ListPanel.Config = {}));
87
+ function getConfig({ listKey, config = {}, flexDirection }) {
88
+ var _a, _b, _c, _d, _e, _f, _g, _h;
89
+ const keys = Config.getKeys(listKey);
90
+ const configSchema = {
91
+ [keys.layout]: schema_1.ListPanelLayout.schema,
92
+ [keys.width]: schema_1.ItemSize.schema,
93
+ [keys.horizontalAlign]: schema_1.ItemAlignment.Horizontal.schema,
94
+ [keys.verticalAlign]: schema_1.ItemAlignment.Vertical.schema
95
+ };
96
+ // resolve values
97
+ const defaultLayout = 'card';
98
+ const layout = (_b = (_a = config[keys.layout]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : defaultLayout;
99
+ const defaultWidth = 'md';
100
+ let width = (_d = (_c = config[keys.width]) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : defaultWidth;
101
+ const defaultHorizontalAlign = 'start';
102
+ const horizontalAlign = (_f = (_e = config[keys.horizontalAlign]) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : defaultHorizontalAlign;
103
+ const defaultVerticalAlign = 'start';
104
+ const verticalAlign = (_h = (_g = config[keys.verticalAlign]) === null || _g === void 0 ? void 0 : _g.value) !== null && _h !== void 0 ? _h : defaultVerticalAlign;
105
+ if (flexDirection === 'x') {
106
+ delete configSchema[keys.verticalAlign];
107
+ }
108
+ else if (flexDirection === 'y') {
109
+ delete configSchema[keys.width];
110
+ delete configSchema[keys.horizontalAlign];
111
+ }
112
+ else if (flexDirection === 'none') {
113
+ // update options for width
114
+ const newWidthSchema = schema_1.ItemSize.schema.keepOptions('full', 'fullBleed');
115
+ configSchema[keys.width] = newWidthSchema;
116
+ newWidthSchema.isValidOption(width);
117
+ width = newWidthSchema.isValidOption(width) ? width : 'full';
118
+ // drop unnecessary config
119
+ delete configSchema[keys.horizontalAlign];
120
+ delete configSchema[keys.verticalAlign];
121
+ }
122
+ if (width === 'full' || width === 'fullBleed') {
123
+ delete configSchema[keys.horizontalAlign];
124
+ }
125
+ return {
126
+ configSchema,
127
+ config: {
128
+ [keys.layout]: funnel_core_1.Schema.EnumField.Value.toData(layout),
129
+ [keys.width]: funnel_core_1.Schema.EnumField.Value.toData(width),
130
+ [keys.verticalAlign]: funnel_core_1.Schema.EnumField.Value.toData(verticalAlign),
131
+ [keys.horizontalAlign]: funnel_core_1.Schema.EnumField.Value.toData(horizontalAlign)
132
+ },
133
+ defaultConfig: {
134
+ [keys.layout]: funnel_core_1.Schema.EnumField.Value.toData(defaultLayout),
135
+ [keys.width]: funnel_core_1.Schema.EnumField.Value.toData(defaultWidth),
136
+ [keys.verticalAlign]: funnel_core_1.Schema.EnumField.Value.toData(defaultVerticalAlign),
137
+ [keys.horizontalAlign]: funnel_core_1.Schema.EnumField.Value.toData(defaultHorizontalAlign)
138
+ },
139
+ };
140
+ }
141
+ ListPanel.getConfig = getConfig;
142
+ // item placeholder
143
+ function ItemPlaceholder() {
144
+ return ((0, jsx_runtime_1.jsx)("div", { className: "nd-ListPanel-itemPlaceholder", children: "No items" }));
145
+ }
146
+ ListPanel.ItemPlaceholder = ItemPlaceholder;
147
+ })(ListPanel || (exports.ListPanel = ListPanel = {}));
@@ -1,8 +1,9 @@
1
1
  import { BlockLayout, Schema } from '@nascentdigital/funnel-core';
2
+ import { ReactNode } from 'react';
2
3
  import { Caption, Headline, Title } from '../fields';
3
- import { TextAlignment } from '../schema';
4
+ import { ItemAlignment, ItemSize, TextAlignment } from '../schema';
4
5
  import { BlockPanel } from './BlockPanel';
5
- export declare function MessagePanel({ className, panel, titleTag, title, headlineTag, headline, captionTag, caption, ctas: ctasRaw, textAlign, alignX, alignY, size, fullbleed, mobileOrder }: MessagePanel.Props): import("react/jsx-runtime").JSX.Element;
6
+ export declare function MessagePanel({ className, panel, titleTag, title, headlineTag, headline, captionTag, caption, ctas: ctasRaw, textAlign, alignX, alignY, size, fullbleed, mobileOrder, decorator }: MessagePanel.Props): import("react/jsx-runtime").JSX.Element;
6
7
  export declare namespace MessagePanel {
7
8
  type Props = BlockPanel.Props & {
8
9
  className?: string;
@@ -10,15 +11,42 @@ export declare namespace MessagePanel {
10
11
  titleTag?: Title.Tag;
11
12
  title?: Title.Value;
12
13
  headlineTag?: Headline.Tag;
13
- headline: Headline.Value;
14
+ headline?: Headline.Value;
14
15
  caption?: Caption.Value;
15
16
  captionTag?: Caption.Tag;
16
17
  ctas?: Schema.LinkField.LinkedValue | Fields.ctas.Value;
17
18
  textAlign?: TextAlignment;
19
+ decorator?: ReactNode;
18
20
  };
21
+ namespace Props {
22
+ type Configuration = Pick<Props, 'className' | 'titleTag' | 'headlineTag' | 'captionTag' | 'decorator'>;
23
+ }
24
+ namespace Config {
25
+ type Key<TPrefix extends string = string> = Key.TextAlign<TPrefix> | Key.HorizontalAlign<TPrefix> | Key.VerticalAlign<TPrefix> | Key.Width<TPrefix>;
26
+ namespace Key {
27
+ type Position<TPrefix extends string> = `${TPrefix}Position`;
28
+ function position<TPrefix extends string>(prefix: TPrefix): Position<TPrefix>;
29
+ type TextAlign<TPrefix extends string> = `${TPrefix}TextAlign`;
30
+ function textAlign<TPrefix extends string>(prefix: TPrefix): TextAlign<TPrefix>;
31
+ type Width<TPrefix extends string> = `${TPrefix}Width`;
32
+ function width<TPrefix extends string>(prefix: TPrefix): Width<TPrefix>;
33
+ type HorizontalAlign<TPrefix extends string> = `${TPrefix}HorizontalAlign`;
34
+ function horizontalAlign<TPrefix extends string>(prefix: TPrefix): HorizontalAlign<TPrefix>;
35
+ type VerticalAlign<TPrefix extends string> = `${TPrefix}VerticalAlign`;
36
+ function verticalAlign<TPrefix extends string>(prefix: TPrefix): VerticalAlign<TPrefix>;
37
+ }
38
+ type Keys<TPrefix extends string> = {
39
+ textAlign: Key.TextAlign<TPrefix>;
40
+ width: Key.Width<TPrefix>;
41
+ horizontalAlign: Key.HorizontalAlign<TPrefix>;
42
+ verticalAlign: Key.VerticalAlign<TPrefix>;
43
+ };
44
+ function getKeys<TPrefix extends string>(prefix: TPrefix): Keys<TPrefix>;
45
+ type Entries<TPrefix extends string> = Record<Key.TextAlign<TPrefix>, TextAlignment.Schema> & Record<Key.Width<TPrefix>, ItemSize.Schema> & Record<Key.HorizontalAlign<TPrefix>, ItemAlignment.Horizontal.Schema> & Record<Key.VerticalAlign<TPrefix>, ItemAlignment.Vertical.Schema>;
46
+ }
19
47
  namespace Fields {
20
- const title: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Visual>>;
21
- const headline: Schema.RichTextField;
48
+ const title: Schema.Optional<Schema.TextField>;
49
+ const headline: Schema.Optional<Schema.RichTextField>;
22
50
  const caption: Schema.Optional<Schema.RichTextField>;
23
51
  const cta: Schema.LinkField;
24
52
  const ctas: Schema.Optional<Schema.ListField<{
@@ -27,5 +55,43 @@ export declare namespace MessagePanel {
27
55
  namespace ctas {
28
56
  type Value = Schema.Field.LinkedValue.ForOptionalType<typeof ctas>;
29
57
  }
58
+ const all: {
59
+ readonly title: Schema.Optional<Schema.TextField>;
60
+ readonly headline: Schema.Optional<Schema.RichTextField>;
61
+ readonly caption: Schema.Optional<Schema.RichTextField>;
62
+ readonly ctas: Schema.Optional<Schema.ListField<{
63
+ cta: Schema.LinkField;
64
+ }>>;
65
+ };
66
+ type Keys<TitleKey extends string | undefined = string | undefined, HeadlineKey extends string | undefined = string | undefined, CaptionKey extends string | undefined = string | undefined, CtasKey extends string | undefined = string | undefined> = {
67
+ title: TitleKey;
68
+ headline: HeadlineKey;
69
+ caption: CaptionKey;
70
+ ctas: CtasKey;
71
+ };
72
+ namespace GetSchema {
73
+ type Result<TKeys extends Partial<Keys> = {}> = Record<TKeys['title'] extends string ? TKeys['title'] : 'title', typeof title> & Record<TKeys['headline'] extends string ? TKeys['headline'] : 'headline', typeof headline> & Record<TKeys['caption'] extends string ? TKeys['caption'] : 'caption', typeof caption> & Record<TKeys['ctas'] extends string ? TKeys['ctas'] : 'ctas', typeof ctas>;
74
+ }
75
+ function getSchema<TitleKey extends string | undefined, HeadlineKey extends string | undefined, CaptionKey extends string | undefined, CtasKey extends string | undefined>(keys?: Partial<Keys<TitleKey, HeadlineKey, CaptionKey, CtasKey>>): GetSchema.Result<Keys<TitleKey, HeadlineKey, CaptionKey, CtasKey>>;
76
+ function exists(fields: Record<string, Schema.Field.Data | Schema.Field.LinkedData>, keys?: Partial<Keys>): boolean;
77
+ function isEmpty(fields: Record<string, Schema.Field.Data | Schema.Field.LinkedData>, keys?: Partial<Keys>): boolean;
78
+ }
79
+ namespace GetConfig {
80
+ type ConfigSchema<TPrefix extends string> = Record<Config.Key.TextAlign<TPrefix>, TextAlignment.Schema> & Record<Config.Key.Width<TPrefix>, ItemSize.Schema> & Record<Config.Key.HorizontalAlign<TPrefix>, ItemAlignment.Horizontal.Schema> & Record<Config.Key.VerticalAlign<TPrefix>, ItemAlignment.Vertical.Schema>;
81
+ type ConfigData<TPrefix extends string> = Schema.Block.Data.ForConfig<ConfigSchema<TPrefix>>;
82
+ type Args<TPrefix extends string, TFields extends Schema.Fields = Schema.Fields> = {
83
+ messageKey: TPrefix;
84
+ config?: Partial<ConfigData<TPrefix>>;
85
+ fields: TFields;
86
+ flexDirection?: BlockPanel.Slots.FlexDirection;
87
+ };
88
+ type Result<TPrefix extends string> = {
89
+ configSchema: Partial<ConfigSchema<TPrefix>>;
90
+ config: Partial<ConfigData<TPrefix>>;
91
+ defaultConfig: Partial<ConfigData<TPrefix>>;
92
+ isInline: boolean;
93
+ };
30
94
  }
95
+ function getConfig<TPrefix extends string, TFields extends Schema.Fields = Schema.Fields>({ messageKey, config, flexDirection }: GetConfig.Args<TPrefix, TFields>): GetConfig.Result<TPrefix>;
96
+ function Placeholder(): import("react/jsx-runtime").JSX.Element;
31
97
  }
@@ -8,9 +8,10 @@ const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const funnel_core_1 = require("@nascentdigital/funnel-core");
9
9
  const classnames_1 = __importDefault(require("classnames"));
10
10
  const fields_1 = require("../fields");
11
+ const schema_1 = require("../schema");
11
12
  const BlockPanel_1 = require("./BlockPanel");
12
13
  // component
13
- function MessagePanel({ className, panel, titleTag = 'span', title, headlineTag = 'h2', headline, captionTag = 'div', caption, ctas: ctasRaw = [], textAlign, alignX, alignY, size, fullbleed, mobileOrder }) {
14
+ function MessagePanel({ className, panel, titleTag = 'span', title, headlineTag = 'h2', headline, captionTag = 'div', caption, ctas: ctasRaw = [], textAlign, alignX, alignY, size, fullbleed, mobileOrder, decorator }) {
14
15
  // normalize ctas
15
16
  let ctas;
16
17
  if (Array.isArray(ctasRaw)) {
@@ -54,20 +55,60 @@ function MessagePanel({ className, panel, titleTag = 'span', title, headlineTag
54
55
  center: 'lg:nd-MessagePanel-textCenter',
55
56
  right: 'lg:nd-MessagePanel-textEnd'
56
57
  }
57
- })), children: (0, jsx_runtime_1.jsxs)("div", { className: "nd-BlockPanel-content nd-MessagePanel-content", children: [title &&
58
- (0, jsx_runtime_1.jsx)(fields_1.Title, { className: "nd-MessagePanel-title", as: titleTag, title: title }), (0, jsx_runtime_1.jsx)(fields_1.Headline, { className: "nd-MessagePanel-headline", as: headlineTag, headline: headline }), caption &&
58
+ })), children: (0, jsx_runtime_1.jsxs)("div", { className: "nd-BlockPanel-content nd-MessagePanel-content", children: [!title && !headline && !caption && ctas.length === 0 &&
59
+ (0, jsx_runtime_1.jsx)(MessagePanel.Placeholder, {}), title &&
60
+ (0, jsx_runtime_1.jsx)(fields_1.Title, { className: "nd-MessagePanel-title", as: titleTag, title: title }), headline &&
61
+ (0, jsx_runtime_1.jsx)(fields_1.Headline, { className: "nd-MessagePanel-headline", as: headlineTag, headline: headline }), caption &&
59
62
  (0, jsx_runtime_1.jsx)(fields_1.Caption, { className: "nd-MessagePanel-caption", as: captionTag, caption: caption }), ctas.length > 0 &&
60
- (0, jsx_runtime_1.jsx)("div", { className: "nd-MessagePanel-ctas", children: ctas.map(cta => (0, jsx_runtime_1.jsx)(fields_1.Link, { className: "nd-MessagePanel-cta", link: cta.value }, cta.id)) })] }) }));
63
+ (0, jsx_runtime_1.jsx)("div", { className: "nd-MessagePanel-ctas", children: ctas.map(cta => (0, jsx_runtime_1.jsx)(fields_1.Link, { className: "nd-MessagePanel-cta", link: cta.value }, cta.id)) }), decorator &&
64
+ (0, jsx_runtime_1.jsx)("div", { className: "nd-MessagePanel-decorator", children: decorator })] }) }));
61
65
  }
62
66
  // extension
63
67
  (function (MessagePanel) {
68
+ // config
69
+ let Config;
70
+ (function (Config) {
71
+ let Key;
72
+ (function (Key) {
73
+ function position(prefix) {
74
+ return `${prefix}Position`;
75
+ }
76
+ Key.position = position;
77
+ function textAlign(prefix) {
78
+ return `${prefix}TextAlign`;
79
+ }
80
+ Key.textAlign = textAlign;
81
+ function width(prefix) {
82
+ return `${prefix}Width`;
83
+ }
84
+ Key.width = width;
85
+ function horizontalAlign(prefix) {
86
+ return `${prefix}HorizontalAlign`;
87
+ }
88
+ Key.horizontalAlign = horizontalAlign;
89
+ function verticalAlign(prefix) {
90
+ return `${prefix}VerticalAlign`;
91
+ }
92
+ Key.verticalAlign = verticalAlign;
93
+ })(Key = Config.Key || (Config.Key = {}));
94
+ function getKeys(prefix) {
95
+ return {
96
+ textAlign: `${prefix}TextAlign`,
97
+ width: `${prefix}Width`,
98
+ horizontalAlign: `${prefix}HorizontalAlign`,
99
+ verticalAlign: `${prefix}VerticalAlign`
100
+ };
101
+ }
102
+ Config.getKeys = getKeys;
103
+ })(Config = MessagePanel.Config || (MessagePanel.Config = {}));
64
104
  // fields
65
105
  let Fields;
66
106
  (function (Fields) {
67
- Fields.title = fields_1.Visual.schema.modify({
107
+ // schemas
108
+ Fields.title = fields_1.Title.schema.modify({
68
109
  description: 'A short intro or heading for the message'
69
110
  }).optional();
70
- Fields.headline = fields_1.Headline.schema;
111
+ Fields.headline = fields_1.Headline.schema.optional();
71
112
  Fields.caption = fields_1.Caption.schema.optional();
72
113
  Fields.cta = funnel_core_1.Schema.Field.link({ name: 'Call to Action' });
73
114
  Fields.ctas = funnel_core_1.Schema.Field.list({
@@ -77,5 +118,116 @@ function MessagePanel({ className, panel, titleTag = 'span', title, headlineTag
77
118
  min: 1,
78
119
  max: 2
79
120
  }).optional();
121
+ Fields.all = {
122
+ title: Fields.title,
123
+ headline: Fields.headline,
124
+ caption: Fields.caption,
125
+ ctas: Fields.ctas
126
+ };
127
+ function getSchema(keys = {}) {
128
+ var _a, _b, _c, _d;
129
+ return {
130
+ [(_a = keys.title) !== null && _a !== void 0 ? _a : 'title']: Fields.title,
131
+ [(_b = keys.headline) !== null && _b !== void 0 ? _b : 'headline']: Fields.headline,
132
+ [(_c = keys.caption) !== null && _c !== void 0 ? _c : 'caption']: Fields.caption,
133
+ [(_d = keys.ctas) !== null && _d !== void 0 ? _d : 'ctas']: Fields.ctas
134
+ };
135
+ }
136
+ Fields.getSchema = getSchema;
137
+ // exists
138
+ function exists(fields, keys = {}) {
139
+ var _a, _b, _c, _d;
140
+ return !!fields[((_a = keys.title) !== null && _a !== void 0 ? _a : 'title')]
141
+ || !!fields[((_b = keys.headline) !== null && _b !== void 0 ? _b : 'headline')]
142
+ || !!fields[((_c = keys.caption) !== null && _c !== void 0 ? _c : 'caption')]
143
+ || !!fields[((_d = keys.ctas) !== null && _d !== void 0 ? _d : 'ctas')];
144
+ }
145
+ Fields.exists = exists;
146
+ // exists
147
+ function isEmpty(fields, keys = {}) {
148
+ var _a, _b, _c, _d;
149
+ // helper
150
+ const isEmptyText = (key) => {
151
+ var _a;
152
+ const data = fields[key];
153
+ return !data || ((_a = funnel_core_1.Schema.Field.Data.getText(data)) !== null && _a !== void 0 ? _a : '').trim().length === 0;
154
+ };
155
+ const isEmptyList = (key) => {
156
+ var _a;
157
+ const data = fields[key];
158
+ return !data || ((_a = data.value) !== null && _a !== void 0 ? _a : []).length === 0;
159
+ };
160
+ // evaluate
161
+ return isEmptyText((_a = keys.title) !== null && _a !== void 0 ? _a : 'title')
162
+ && isEmptyText((_b = keys.headline) !== null && _b !== void 0 ? _b : 'headline')
163
+ && isEmptyText((_c = keys.caption) !== null && _c !== void 0 ? _c : 'caption')
164
+ && isEmptyList((_d = keys.ctas) !== null && _d !== void 0 ? _d : 'ctas');
165
+ }
166
+ Fields.isEmpty = isEmpty;
80
167
  })(Fields = MessagePanel.Fields || (MessagePanel.Fields = {}));
168
+ function getConfig({ messageKey, config = {}, flexDirection }) {
169
+ var _a, _b, _c, _d, _e, _f, _g, _h;
170
+ // create schema
171
+ const keys = Config.getKeys(messageKey);
172
+ const configSchema = {
173
+ [keys.textAlign]: schema_1.TextAlignment.schema,
174
+ [keys.width]: schema_1.ItemSize.schema,
175
+ [keys.horizontalAlign]: schema_1.ItemAlignment.Horizontal.schema,
176
+ [keys.verticalAlign]: schema_1.ItemAlignment.Vertical.schema
177
+ };
178
+ // resolve values
179
+ const defaultTextAlign = 'left';
180
+ const textAlign = (_b = (_a = config[keys.textAlign]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : defaultTextAlign;
181
+ const defaultWidth = 'full';
182
+ let width = (_d = (_c = config[keys.width]) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : defaultWidth;
183
+ const defaultHorizontalAlign = 'start';
184
+ const horizontalAlign = (_f = (_e = config[keys.horizontalAlign]) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : defaultHorizontalAlign;
185
+ const defaultVerticalAlign = 'start';
186
+ const verticalAlign = (_h = (_g = config[keys.verticalAlign]) === null || _g === void 0 ? void 0 : _g.value) !== null && _h !== void 0 ? _h : defaultVerticalAlign;
187
+ if (flexDirection === 'x') {
188
+ delete configSchema[keys.verticalAlign];
189
+ }
190
+ else if (flexDirection === 'y') {
191
+ delete configSchema[keys.textAlign];
192
+ delete configSchema[keys.width];
193
+ delete configSchema[keys.horizontalAlign];
194
+ }
195
+ else if (flexDirection === 'none') {
196
+ // update options for width
197
+ const newWidthSchema = schema_1.ItemSize.schema.keepOptions('full', 'fullBleed');
198
+ configSchema[keys.width] = newWidthSchema;
199
+ newWidthSchema.isValidOption(width);
200
+ width = newWidthSchema.isValidOption(width) ? width : 'full';
201
+ // drop unnecessary config
202
+ // drop unnecessary config
203
+ delete configSchema[keys.textAlign];
204
+ delete configSchema[keys.horizontalAlign];
205
+ delete configSchema[keys.verticalAlign];
206
+ }
207
+ if (width === 'full' || width === 'fullBleed') {
208
+ delete configSchema[keys.horizontalAlign];
209
+ }
210
+ // return result
211
+ return {
212
+ configSchema,
213
+ config: {
214
+ [keys.textAlign]: funnel_core_1.Schema.EnumField.Value.toData(textAlign),
215
+ [keys.width]: funnel_core_1.Schema.EnumField.Value.toData(width),
216
+ [keys.verticalAlign]: funnel_core_1.Schema.EnumField.Value.toData(verticalAlign),
217
+ [keys.horizontalAlign]: funnel_core_1.Schema.EnumField.Value.toData(horizontalAlign)
218
+ },
219
+ defaultConfig: {
220
+ [keys.textAlign]: funnel_core_1.Schema.EnumField.Value.toData(defaultTextAlign),
221
+ [keys.width]: funnel_core_1.Schema.EnumField.Value.toData(defaultWidth),
222
+ [keys.verticalAlign]: funnel_core_1.Schema.EnumField.Value.toData(defaultVerticalAlign),
223
+ [keys.horizontalAlign]: funnel_core_1.Schema.EnumField.Value.toData(defaultHorizontalAlign)
224
+ },
225
+ };
226
+ }
227
+ MessagePanel.getConfig = getConfig;
228
+ // placeholder
229
+ function Placeholder() {
230
+ return ((0, jsx_runtime_1.jsx)("div", { className: "nd-BlockPanel-placeholder nd-MessagePanel-placeholder", children: "No message content" }));
231
+ }
232
+ MessagePanel.Placeholder = Placeholder;
81
233
  })(MessagePanel || (exports.MessagePanel = MessagePanel = {}));
@@ -0,0 +1,47 @@
1
+ import { BlockLayout, Schema } from '@nascentdigital/funnel-core';
2
+ import { ReactNode } from 'react';
3
+ import { Person } from '../entities';
4
+ import { Quote, Title } from '../fields';
5
+ export declare function TestimonialPanel({ className, panel, layout, title, titleTag, quote, quoteTag, author, authorTag, ctas, decorator }: TestimonialPanel.Props): import("react/jsx-runtime").JSX.Element;
6
+ export declare namespace TestimonialPanel {
7
+ type Layout = 'companyQuoteAuthor' | 'quoteAuthor';
8
+ type Props = {
9
+ className?: string;
10
+ panel: BlockLayout.Message;
11
+ layout?: Layout;
12
+ titleTag?: Title.Tag;
13
+ title?: Title.Value;
14
+ quoteTag?: Quote.Tag;
15
+ quote: Quote.Value;
16
+ authorTag?: Person.Tag;
17
+ author: Person.Value;
18
+ ctas?: Fields.ctas.Value;
19
+ decorator?: ReactNode;
20
+ };
21
+ namespace Props {
22
+ type Configuration = Pick<Props, 'className' | 'layout' | 'titleTag' | 'quoteTag' | 'authorTag' | 'decorator'>;
23
+ }
24
+ namespace Fields {
25
+ const title: Schema.Optional<Schema.TextField>;
26
+ const quote: Schema.RichTextField;
27
+ const author: Schema.CollectionField<Schema.Collection<{
28
+ title: Schema.Optional<Schema.TextField>;
29
+ company: Schema.Optional<Schema.CollectionField<Schema.Collection<{
30
+ division: Schema.Optional<Schema.TextField>;
31
+ location: Schema.Optional<Schema.TextField>;
32
+ logo: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Visual>>;
33
+ badge: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Image>>;
34
+ badgeText: Schema.Optional<Schema.TextField>;
35
+ }>>>;
36
+ location: Schema.Optional<Schema.TextField>;
37
+ picture: Schema.Optional<Schema.AssetField<Schema.AssetField.LinkedValue.Image>>;
38
+ }>>;
39
+ const cta: Schema.LinkField;
40
+ const ctas: Schema.Optional<Schema.ListField<{
41
+ cta: Schema.LinkField;
42
+ }>>;
43
+ namespace ctas {
44
+ type Value = Schema.Field.LinkedValue.ForOptionalType<typeof ctas>;
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TestimonialPanel = TestimonialPanel;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
9
+ const classnames_1 = __importDefault(require("classnames"));
10
+ const entities_1 = require("../entities");
11
+ const fields_1 = require("../fields");
12
+ const BlockPanel_1 = require("./BlockPanel");
13
+ // component
14
+ function TestimonialPanel({ className, panel, layout = 'quoteAuthor', title, titleTag = 'span', quote, quoteTag = 'h2', author, authorTag = 'div', ctas = [], decorator }) {
15
+ var _a, _b;
16
+ // extract company from author
17
+ const company = (_b = (_a = author.fields) === null || _a === void 0 ? void 0 : _a.company) === null || _b === void 0 ? void 0 : _b.value;
18
+ // render
19
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(className, 'nd-TestimonialPanel',
20
+ // base layout
21
+ BlockPanel_1.BlockPanel.getClassNames({ panel }),
22
+ // text-align
23
+ funnel_core_1.BlockLayout.ResponsiveClassNames.parse({
24
+ value: panel.textAlign,
25
+ mobile: {
26
+ left: 'max-md:nd-TestimonialPanel-textStart',
27
+ center: 'max-md:nd-TestimonialPanel-textCenter',
28
+ right: 'max-md:nd-TestimonialPanel-textEnd'
29
+ },
30
+ base: {
31
+ left: 'md:nd-TestimonialPanel-textStart',
32
+ center: 'md:nd-TestimonialPanel-textCenter',
33
+ right: 'md:nd-TestimonialPanel-textEnd'
34
+ },
35
+ desktop: {
36
+ left: 'lg:nd-TestimonialPanel-textStart',
37
+ center: 'lg:nd-TestimonialPanel-textCenter',
38
+ right: 'lg:nd-TestimonialPanel-textEnd'
39
+ }
40
+ })), children: (0, jsx_runtime_1.jsxs)("div", { className: "nd-BlockPanel-content nd-TestimonialPanel-content", children: [company && layout === 'companyQuoteAuthor' &&
41
+ (0, jsx_runtime_1.jsx)(entities_1.Client, { as: "div", className: "nd-TestimonialPanel-company", client: company, displayFields: ['name', 'logo'] }), title &&
42
+ (0, jsx_runtime_1.jsx)(fields_1.Title, { className: "nd-TestimonialPanel-title", as: titleTag, title: title }), (0, jsx_runtime_1.jsx)(fields_1.Quote, { className: "nd-TestimonialPanel-quote", as: quoteTag, quote: quote }), (0, jsx_runtime_1.jsx)(entities_1.Person, { as: authorTag, className: "nd-TestimonialPanel-author", person: author, displayFields: layout === 'companyQuoteAuthor'
43
+ ? entities_1.Person.DisplayFields.exclude('company')
44
+ : entities_1.Person.DisplayFields.Id.values }), ctas.length > 0 &&
45
+ (0, jsx_runtime_1.jsx)("div", { className: "nd-TestimonialPanel-ctas", children: ctas.map(cta => (0, jsx_runtime_1.jsx)(fields_1.Link, { className: "nd-TestimonialPanel-cta", link: cta.value }, cta.id)) }), decorator &&
46
+ (0, jsx_runtime_1.jsx)("div", { className: "nd-TestimonialPanel-decorator", children: decorator })] }) }));
47
+ }
48
+ // extension
49
+ (function (TestimonialPanel) {
50
+ // fields
51
+ let Fields;
52
+ (function (Fields) {
53
+ Fields.title = fields_1.Title.schema.modify({
54
+ description: 'A short intro or heading for the message'
55
+ }).optional();
56
+ Fields.quote = fields_1.Quote.schema;
57
+ Fields.author = funnel_core_1.Schema.Field.collection({
58
+ name: 'Author',
59
+ hint: 'Who said it?',
60
+ collections: [entities_1.Person.schema]
61
+ });
62
+ Fields.cta = funnel_core_1.Schema.Field.link({ name: 'Call to Action' });
63
+ Fields.ctas = funnel_core_1.Schema.Field.list({
64
+ name: 'CTAs',
65
+ description: 'Add your call-to-actions in the order you\'d like them to appear *(these are optional)*.',
66
+ itemTypes: { cta: Fields.cta },
67
+ min: 1,
68
+ max: 2
69
+ }).optional();
70
+ })(Fields = TestimonialPanel.Fields || (TestimonialPanel.Fields = {}));
71
+ })(TestimonialPanel || (exports.TestimonialPanel = TestimonialPanel = {}));