@bettercms-ai/kit 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/adapters/dock-values.d.ts +28 -0
- package/dist/adapters/dock-values.js +41 -0
- package/dist/adapters/dock-values.js.map +1 -0
- package/{adapters → dist/adapters}/icons.js +2 -2
- package/dist/adapters/icons.js.map +1 -0
- package/{adapters → dist/adapters}/lossy.d.ts +90 -31
- package/dist/adapters/lossy.js +414 -0
- package/dist/adapters/lossy.js.map +1 -0
- package/{adapters → dist/adapters}/prod-types.d.ts +82 -4
- package/{adapters → dist/adapters}/prod-types.js +71 -3
- package/dist/adapters/prod-types.js.map +1 -0
- package/{adapters → dist/adapters}/schema.d.ts +40 -1
- package/{adapters → dist/adapters}/schema.js +996 -179
- package/dist/adapters/schema.js.map +1 -0
- package/{adapters → dist/adapters}/values.d.ts +26 -5
- package/{adapters → dist/adapters}/values.js +87 -17
- package/dist/adapters/values.js.map +1 -0
- package/dist/brand/logo.js +96 -0
- package/dist/brand/logo.js.map +1 -0
- package/{context.d.ts → dist/context.d.ts} +92 -2
- package/{context.js → dist/context.js} +5 -2
- package/dist/context.js.map +1 -0
- package/{controls → dist/controls}/button.d.ts +19 -5
- package/{controls → dist/controls}/button.js +125 -54
- package/dist/controls/button.js.map +1 -0
- package/{controls → dist/controls}/c1.js +1 -1
- package/dist/controls/c1.js.map +1 -0
- package/{controls → dist/controls}/c2.js +1 -1
- package/dist/controls/c2.js.map +1 -0
- package/{controls → dist/controls}/choice.d.ts +7 -2
- package/{controls → dist/controls}/choice.js +71 -18
- package/dist/controls/choice.js.map +1 -0
- package/{controls → dist/controls}/code-register.js +1 -1
- package/dist/controls/code-register.js.map +1 -0
- package/{controls → dist/controls}/code.js +10 -9
- package/dist/controls/code.js.map +1 -0
- package/{controls → dist/controls}/color.js +8 -8
- package/dist/controls/color.js.map +1 -0
- package/{controls → dist/controls}/component-services.d.ts +42 -0
- package/dist/controls/component-services.js +7 -0
- package/dist/controls/component-services.js.map +1 -0
- package/{controls → dist/controls}/date-register.js +1 -1
- package/dist/controls/date-register.js.map +1 -0
- package/{controls → dist/controls}/date-zone.js +8 -2
- package/dist/controls/date-zone.js.map +1 -0
- package/{controls → dist/controls}/date.js +32 -24
- package/dist/controls/date.js.map +1 -0
- package/{controls → dist/controls}/form-picker-register.js +1 -1
- package/dist/controls/form-picker-register.js.map +1 -0
- package/{controls → dist/controls}/form-picker.js +11 -9
- package/dist/controls/form-picker.js.map +1 -0
- package/{controls → dist/controls}/icon-register.js +1 -1
- package/dist/controls/icon-register.js.map +1 -0
- package/{controls → dist/controls}/icon.d.ts +4 -2
- package/{controls → dist/controls}/icon.js +32 -27
- package/dist/controls/icon.js.map +1 -0
- package/{controls → dist/controls}/index.d.ts +1 -1
- package/{controls → dist/controls}/index.js +4 -3
- package/dist/controls/index.js.map +1 -0
- package/{controls → dist/controls}/json-register.js +1 -1
- package/dist/controls/json-register.js.map +1 -0
- package/{controls → dist/controls}/json.js +13 -3
- package/dist/controls/json.js.map +1 -0
- package/{controls → dist/controls}/link.js +6 -6
- package/dist/controls/link.js.map +1 -0
- package/{controls → dist/controls}/location-register.js +1 -1
- package/dist/controls/location-register.js.map +1 -0
- package/{controls → dist/controls}/location.js +64 -40
- package/dist/controls/location.js.map +1 -0
- package/{controls → dist/controls}/media-register.js +1 -1
- package/dist/controls/media-register.js.map +1 -0
- package/{controls → dist/controls}/media-services.d.ts +6 -0
- package/dist/controls/media-services.js +0 -0
- package/{controls → dist/controls}/media.d.ts +35 -4
- package/{controls → dist/controls}/media.js +491 -171
- package/dist/controls/media.js.map +1 -0
- package/{controls → dist/controls}/number.js +10 -9
- package/dist/controls/number.js.map +1 -0
- package/{controls → dist/controls}/reference-register.js +1 -1
- package/dist/controls/reference-register.js.map +1 -0
- package/{controls → dist/controls}/reference-services.d.ts +4 -0
- package/dist/controls/reference-services.js +0 -0
- package/{controls → dist/controls}/reference.d.ts +1 -1
- package/{controls → dist/controls}/reference.js +93 -77
- package/dist/controls/reference.js.map +1 -0
- package/dist/controls/rich-text/blocks.d.ts +49 -0
- package/{controls → dist/controls}/rich-text/blocks.js +471 -144
- package/dist/controls/rich-text/blocks.js.map +1 -0
- package/{controls → dist/controls}/rich-text/catalog.d.ts +4 -1
- package/{controls → dist/controls}/rich-text/catalog.js +75 -65
- package/dist/controls/rich-text/catalog.js.map +1 -0
- package/{controls → dist/controls}/rich-text/codec.d.ts +9 -1
- package/{controls → dist/controls}/rich-text/codec.js +3 -1
- package/dist/controls/rich-text/codec.js.map +1 -0
- package/{controls → dist/controls}/rich-text/component-card.d.ts +1 -1
- package/{controls → dist/controls}/rich-text/component-card.js +417 -99
- package/dist/controls/rich-text/component-card.js.map +1 -0
- package/dist/controls/rich-text/component-panel.d.ts +47 -0
- package/dist/controls/rich-text/component-panel.js +141 -0
- package/dist/controls/rich-text/component-panel.js.map +1 -0
- package/{controls → dist/controls}/rich-text/control.d.ts +1 -2
- package/{controls → dist/controls}/rich-text/control.js +84 -42
- package/dist/controls/rich-text/control.js.map +1 -0
- package/{controls → dist/controls}/rich-text/dom.d.ts +52 -9
- package/{controls → dist/controls}/rich-text/dom.js +379 -50
- package/dist/controls/rich-text/dom.js.map +1 -0
- package/{controls → dist/controls}/rich-text/editor.d.ts +7 -0
- package/{controls → dist/controls}/rich-text/editor.js +148 -48
- package/dist/controls/rich-text/editor.js.map +1 -0
- package/{controls → dist/controls}/rich-text/floating.d.ts +6 -1
- package/{controls → dist/controls}/rich-text/floating.js +35 -18
- package/dist/controls/rich-text/floating.js.map +1 -0
- package/{controls → dist/controls}/rich-text/index.js +1 -1
- package/dist/controls/rich-text/index.js.map +1 -0
- package/dist/controls/rich-text/link-form.js +147 -0
- package/dist/controls/rich-text/link-form.js.map +1 -0
- package/{controls → dist/controls}/rich-text/markdown.js +4 -2
- package/dist/controls/rich-text/markdown.js.map +1 -0
- package/{controls → dist/controls}/rich-text/ops.js +17 -15
- package/dist/controls/rich-text/ops.js.map +1 -0
- package/dist/controls/rich-text/plain.d.ts +17 -0
- package/dist/controls/rich-text/plain.js +44 -0
- package/dist/controls/rich-text/plain.js.map +1 -0
- package/{controls → dist/controls}/rich-text/toolbar.d.ts +6 -2
- package/{controls → dist/controls}/rich-text/toolbar.js +12 -7
- package/dist/controls/rich-text/toolbar.js.map +1 -0
- package/{controls → dist/controls}/scale.js +5 -5
- package/dist/controls/scale.js.map +1 -0
- package/{controls → dist/controls}/slot-register.js +1 -1
- package/dist/controls/slot-register.js.map +1 -0
- package/{controls → dist/controls}/slot-services.d.ts +25 -0
- package/dist/controls/slot-services.js +155 -0
- package/dist/controls/slot-services.js.map +1 -0
- package/{controls → dist/controls}/slot.js +42 -24
- package/dist/controls/slot.js.map +1 -0
- package/{controls → dist/controls}/table/index.js +1 -1
- package/dist/controls/table/index.js.map +1 -0
- package/{controls → dist/controls}/table/prod.js +3 -3
- package/dist/controls/table/prod.js.map +1 -0
- package/{controls → dist/controls}/table/refs.js +13 -2
- package/dist/controls/table/refs.js.map +1 -0
- package/{controls → dist/controls}/table/stored.js +1 -1
- package/dist/controls/table/stored.js.map +1 -0
- package/{controls → dist/controls}/table/table-editor.js +51 -48
- package/dist/controls/table/table-editor.js.map +1 -0
- package/{controls → dist/controls}/table/table-link.js +3 -3
- package/dist/controls/table/table-link.js.map +1 -0
- package/{controls → dist/controls}/table/table.js +3 -3
- package/dist/controls/table/table.js.map +1 -0
- package/{controls → dist/controls}/text.d.ts +2 -2
- package/{controls → dist/controls}/text.js +78 -43
- package/dist/controls/text.js.map +1 -0
- package/dist/controls/unknown-value.d.ts +17 -0
- package/dist/controls/unknown-value.js +66 -0
- package/dist/controls/unknown-value.js.map +1 -0
- package/dist/core/core.d.ts +63 -0
- package/dist/core/core.js +171 -0
- package/dist/core/core.js.map +1 -0
- package/dist/core/facets.d.ts +347 -0
- package/dist/core/facets.js +334 -0
- package/dist/core/facets.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +3 -0
- package/{engine → dist/engine}/array.js +34 -21
- package/dist/engine/array.js.map +1 -0
- package/{engine → dist/engine}/bits.js +1 -1
- package/dist/engine/bits.js.map +1 -0
- package/{engine → dist/engine}/breadcrumb.d.ts +3 -3
- package/{engine → dist/engine}/breadcrumb.js +12 -36
- package/dist/engine/breadcrumb.js.map +1 -0
- package/{engine → dist/engine}/expand.d.ts +2 -4
- package/{engine → dist/engine}/expand.js +5 -22
- package/dist/engine/expand.js.map +1 -0
- package/{engine → dist/engine}/field-list.js +1 -1
- package/dist/engine/field-list.js.map +1 -0
- package/{engine → dist/engine}/field-shell.js +249 -121
- package/dist/engine/field-shell.js.map +1 -0
- package/{engine → dist/engine}/frame.d.ts +3 -1
- package/{engine → dist/engine}/frame.js +16 -14
- package/dist/engine/frame.js.map +1 -0
- package/{engine → dist/engine}/group-summary.d.ts +2 -1
- package/{engine → dist/engine}/group-summary.js +7 -3
- package/dist/engine/group-summary.js.map +1 -0
- package/{engine → dist/engine}/grouping.d.ts +19 -5
- package/{engine → dist/engine}/grouping.js +193 -21
- package/dist/engine/grouping.js.map +1 -0
- package/{engine → dist/engine}/item-list.d.ts +11 -1
- package/{engine → dist/engine}/item-list.js +35 -13
- package/dist/engine/item-list.js.map +1 -0
- package/{engine → dist/engine}/kit-field.js +45 -10
- package/dist/engine/kit-field.js.map +1 -0
- package/{engine → dist/engine}/schema-form.d.ts +27 -2
- package/{engine → dist/engine}/schema-form.js +182 -40
- package/dist/engine/schema-form.js.map +1 -0
- package/{engine → dist/engine}/slot.js +5 -15
- package/dist/engine/slot.js.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/{kit.css → dist/kit.css} +19 -0
- package/{lib → dist/lib}/cn.js +7 -4
- package/dist/lib/cn.js.map +1 -0
- package/{lib → dist/lib}/columns.js +4 -1
- package/dist/lib/columns.js.map +1 -0
- package/{lib → dist/lib}/frames.js +2 -2
- package/dist/lib/frames.js.map +1 -0
- package/dist/lib/icon-image.d.ts +10 -0
- package/dist/lib/icon-image.js +8 -0
- package/dist/lib/icon-image.js.map +1 -0
- package/{lib → dist/lib}/icons.js +4 -3
- package/dist/lib/icons.js.map +1 -0
- package/dist/lib/input-modality.d.ts +11 -0
- package/dist/lib/input-modality.js +47 -0
- package/dist/lib/input-modality.js.map +1 -0
- package/dist/lib/key-event.d.ts +11 -0
- package/dist/lib/key-event.js +16 -0
- package/dist/lib/key-event.js.map +1 -0
- package/{lib → dist/lib}/path.js +4 -2
- package/dist/lib/path.js.map +1 -0
- package/{lib → dist/lib}/schema.d.ts +34 -3
- package/{lib → dist/lib}/schema.js +110 -13
- package/dist/lib/schema.js.map +1 -0
- package/{lib → dist/lib}/utils.js +1 -1
- package/dist/lib/utils.js.map +1 -0
- package/{lib → dist/lib}/validate.d.ts +11 -1
- package/{lib → dist/lib}/validate.js +85 -11
- package/dist/lib/validate.js.map +1 -0
- package/dist/library/analysis.d.ts +23 -0
- package/dist/library/analysis.js +160 -0
- package/dist/library/analysis.js.map +1 -0
- package/dist/library/catalog.d.ts +57 -0
- package/dist/library/catalog.js +307 -0
- package/dist/library/catalog.js.map +1 -0
- package/dist/library/coreNotes.d.ts +8 -0
- package/dist/library/coreNotes.js +111 -0
- package/dist/library/coreNotes.js.map +1 -0
- package/dist/library/coverage.d.ts +40 -0
- package/dist/library/coverage.js +59 -0
- package/dist/library/coverage.js.map +1 -0
- package/dist/library/entries/advanced.entries.d.ts +2 -0
- package/dist/library/entries/advanced.entries.js +6579 -0
- package/dist/library/entries/advanced.entries.js.map +1 -0
- package/dist/library/entries/commerce.entries.d.ts +2 -0
- package/dist/library/entries/commerce.entries.js +4140 -0
- package/dist/library/entries/commerce.entries.js.map +1 -0
- package/dist/library/entries/company.entries.d.ts +2 -0
- package/dist/library/entries/company.entries.js +2731 -0
- package/dist/library/entries/company.entries.js.map +1 -0
- package/dist/library/entries/conversion.entries.d.ts +2 -0
- package/dist/library/entries/conversion.entries.js +3707 -0
- package/dist/library/entries/conversion.entries.js.map +1 -0
- package/dist/library/entries/data.entries.d.ts +7 -0
- package/dist/library/entries/data.entries.js +4613 -0
- package/dist/library/entries/data.entries.js.map +1 -0
- package/dist/library/entries/events.entries.d.ts +2 -0
- package/dist/library/entries/events.entries.js +3428 -0
- package/dist/library/entries/events.entries.js.map +1 -0
- package/dist/library/entries/features.entries.d.ts +2 -0
- package/dist/library/entries/features.entries.js +3157 -0
- package/dist/library/entries/features.entries.js.map +1 -0
- package/dist/library/entries/heroes.entries.d.ts +2 -0
- package/dist/library/entries/heroes.entries.js +3401 -0
- package/dist/library/entries/heroes.entries.js.map +1 -0
- package/dist/library/entries/index.d.ts +3 -0
- package/dist/library/entries/index.js +35 -0
- package/dist/library/entries/index.js.map +1 -0
- package/dist/library/entries/listings.entries.d.ts +2 -0
- package/dist/library/entries/listings.entries.js +2976 -0
- package/dist/library/entries/listings.entries.js.map +1 -0
- package/dist/library/entries/longform.entries.d.ts +2 -0
- package/dist/library/entries/longform.entries.js +4227 -0
- package/dist/library/entries/longform.entries.js.map +1 -0
- package/dist/library/entries/media.entries.d.ts +2 -0
- package/dist/library/entries/media.entries.js +2781 -0
- package/dist/library/entries/media.entries.js.map +1 -0
- package/dist/library/entries/navigation.entries.d.ts +2 -0
- package/dist/library/entries/navigation.entries.js +4011 -0
- package/dist/library/entries/navigation.entries.js.map +1 -0
- package/dist/library/entries/pricing.entries.d.ts +2 -0
- package/dist/library/entries/pricing.entries.js +2383 -0
- package/dist/library/entries/pricing.entries.js.map +1 -0
- package/dist/library/entries/social-proof.entries.d.ts +2 -0
- package/dist/library/entries/social-proof.entries.js +2297 -0
- package/dist/library/entries/social-proof.entries.js.map +1 -0
- package/dist/library/examples/bento.d.ts +92 -0
- package/dist/library/examples/bento.js +201 -0
- package/dist/library/examples/bento.js.map +1 -0
- package/dist/library/examples/blocks.d.ts +14 -0
- package/dist/library/examples/blocks.js +313 -0
- package/dist/library/examples/blocks.js.map +1 -0
- package/dist/library/examples/faq.d.ts +28 -0
- package/dist/library/examples/faq.js +230 -0
- package/dist/library/examples/faq.js.map +1 -0
- package/dist/library/examples/hero.d.ts +43 -0
- package/dist/library/examples/hero.js +222 -0
- package/dist/library/examples/hero.js.map +1 -0
- package/dist/library/examples/index.d.ts +36 -0
- package/dist/library/examples/index.js +109 -0
- package/dist/library/examples/index.js.map +1 -0
- package/dist/library/examples/journalStory.d.ts +93 -0
- package/dist/library/examples/journalStory.js +338 -0
- package/dist/library/examples/journalStory.js.map +1 -0
- package/dist/library/examples/megaMenu.d.ts +134 -0
- package/dist/library/examples/megaMenu.js +442 -0
- package/dist/library/examples/megaMenu.js.map +1 -0
- package/dist/library/examples/pricing.d.ts +103 -0
- package/dist/library/examples/pricing.js +479 -0
- package/dist/library/examples/pricing.js.map +1 -0
- package/dist/library/examples/tabs.d.ts +87 -0
- package/dist/library/examples/tabs.js +180 -0
- package/dist/library/examples/tabs.js.map +1 -0
- package/dist/library/export.d.ts +42 -0
- package/dist/library/export.js +80 -0
- package/dist/library/export.js.map +1 -0
- package/dist/library/index.d.ts +13 -0
- package/dist/library/index.js +6 -0
- package/dist/library/kit-catalog.json +1510 -0
- package/dist/library/types.d.ts +42 -0
- package/dist/library/types.js +0 -0
- package/{schema → dist/schema}/adapters.js +1 -2
- package/dist/schema/adapters.js.map +1 -0
- package/{schema → dist/schema}/help.d.ts +2 -0
- package/{schema → dist/schema}/help.js +6 -4
- package/dist/schema/help.js.map +1 -0
- package/{schema → dist/schema}/scale.js +1 -1
- package/dist/schema/scale.js.map +1 -0
- package/{schema → dist/schema}/sources.js +1 -1
- package/dist/schema/sources.js.map +1 -0
- package/{schema → dist/schema}/table.js +11 -10
- package/dist/schema/table.js.map +1 -0
- package/{schema → dist/schema}/types.d.ts +29 -1
- package/{schema → dist/schema}/types.js +1 -1
- package/dist/schema/types.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/table/table-view.d.ts +14 -0
- package/dist/table/table-view.js +140 -0
- package/dist/table/table-view.js.map +1 -0
- package/dist/table/table.css +73 -0
- package/dist/testing/corpus.d.ts +63 -0
- package/dist/testing/corpus.js +129 -0
- package/dist/testing/corpus.js.map +1 -0
- package/dist/testing/test-form.d.ts +11 -0
- package/dist/testing/test-form.js +38 -0
- package/dist/testing/test-form.js.map +1 -0
- package/dist/theme.css +345 -0
- package/dist/theme.d.ts +22 -0
- package/dist/theme.js +43 -0
- package/dist/theme.js.map +1 -0
- package/dist/tokens.css +542 -0
- package/dist/types.js +0 -0
- package/{ui → dist/ui}/action-tray.d.ts +1 -1
- package/{ui → dist/ui}/action-tray.js +20 -19
- package/dist/ui/action-tray.js.map +1 -0
- package/dist/ui/autocomplete.d.ts +30 -0
- package/dist/ui/autocomplete.js +139 -0
- package/dist/ui/autocomplete.js.map +1 -0
- package/{ui → dist/ui}/button.d.ts +3 -3
- package/{ui → dist/ui}/button.js +6 -7
- package/dist/ui/button.js.map +1 -0
- package/{ui → dist/ui}/choice-switch.js +1 -1
- package/dist/ui/choice-switch.js.map +1 -0
- package/{ui → dist/ui}/controls.js +51 -39
- package/dist/ui/controls.js.map +1 -0
- package/{ui → dist/ui}/display.d.ts +10 -3
- package/{ui → dist/ui}/display.js +57 -46
- package/dist/ui/display.js.map +1 -0
- package/{ui → dist/ui}/expanded-editor-modal.d.ts +2 -2
- package/{ui → dist/ui}/expanded-editor-modal.js +6 -6
- package/dist/ui/expanded-editor-modal.js.map +1 -0
- package/{ui → dist/ui}/field-context.js +1 -1
- package/dist/ui/field-context.js.map +1 -0
- package/{ui → dist/ui}/floating-panel.d.ts +1 -1
- package/{ui → dist/ui}/floating-panel.js +28 -12
- package/dist/ui/floating-panel.js.map +1 -0
- package/{ui → dist/ui}/index.d.ts +4 -0
- package/dist/ui/index.js +18 -0
- package/{ui → dist/ui}/input.d.ts +1 -1
- package/{ui → dist/ui}/input.js +9 -9
- package/dist/ui/input.js.map +1 -0
- package/{ui → dist/ui}/mode-bar.js +3 -3
- package/dist/ui/mode-bar.js.map +1 -0
- package/{ui → dist/ui}/overlay.d.ts +77 -5
- package/dist/ui/overlay.js +697 -0
- package/dist/ui/overlay.js.map +1 -0
- package/{ui → dist/ui}/path-crumbs.js +37 -3
- package/dist/ui/path-crumbs.js.map +1 -0
- package/{ui → dist/ui}/presence.js +2 -2
- package/dist/ui/presence.js.map +1 -0
- package/{ui → dist/ui}/select.js +89 -87
- package/dist/ui/select.js.map +1 -0
- package/{ui → dist/ui}/shortcut-hint.js +1 -1
- package/dist/ui/shortcut-hint.js.map +1 -0
- package/dist/ui/spinner.d.ts +24 -0
- package/dist/ui/spinner.js +42 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/split-button.d.ts +32 -0
- package/dist/ui/split-button.js +60 -0
- package/dist/ui/split-button.js.map +1 -0
- package/{ui → dist/ui}/surfaces.js +1 -1
- package/dist/ui/surfaces.js.map +1 -0
- package/dist/ui/tab.d.ts +38 -0
- package/dist/ui/tab.js +87 -0
- package/dist/ui/tab.js.map +1 -0
- package/dist/ui/toast.d.ts +20 -0
- package/dist/ui/toast.js +115 -0
- package/dist/ui/toast.js.map +1 -0
- package/{ui → dist/ui}/tooltip-root.d.ts +4 -3
- package/{ui → dist/ui}/tooltip-root.js +9 -8
- package/dist/ui/tooltip-root.js.map +1 -0
- package/{ui → dist/ui}/variants.js +1 -1
- package/dist/ui/variants.js.map +1 -0
- package/package.json +77 -23
- package/adapters/icons.js.map +0 -1
- package/adapters/lossy.js +0 -233
- package/adapters/lossy.js.map +0 -1
- package/adapters/prod-types.js.map +0 -1
- package/adapters/schema.js.map +0 -1
- package/adapters/values.js.map +0 -1
- package/brand/logo.js +0 -9
- package/brand/logo.js.map +0 -1
- package/context.js.map +0 -1
- package/controls/button.js.map +0 -1
- package/controls/c1.js.map +0 -1
- package/controls/c2.js.map +0 -1
- package/controls/choice.js.map +0 -1
- package/controls/code-register.js.map +0 -1
- package/controls/code.js.map +0 -1
- package/controls/color.js.map +0 -1
- package/controls/date-register.js.map +0 -1
- package/controls/date-zone.js.map +0 -1
- package/controls/date.js.map +0 -1
- package/controls/form-picker-register.js.map +0 -1
- package/controls/form-picker.js.map +0 -1
- package/controls/icon-register.js.map +0 -1
- package/controls/icon.js.map +0 -1
- package/controls/index.js.map +0 -1
- package/controls/json-register.js.map +0 -1
- package/controls/json.js.map +0 -1
- package/controls/link.js.map +0 -1
- package/controls/location-register.js.map +0 -1
- package/controls/location.js.map +0 -1
- package/controls/media-register.js.map +0 -1
- package/controls/media.js.map +0 -1
- package/controls/number.js.map +0 -1
- package/controls/reference-register.js.map +0 -1
- package/controls/reference.js.map +0 -1
- package/controls/rich-text/blocks.d.ts +0 -28
- package/controls/rich-text/blocks.js.map +0 -1
- package/controls/rich-text/catalog.js.map +0 -1
- package/controls/rich-text/codec.js.map +0 -1
- package/controls/rich-text/component-card.js.map +0 -1
- package/controls/rich-text/control.js.map +0 -1
- package/controls/rich-text/dom.js.map +0 -1
- package/controls/rich-text/editor.js.map +0 -1
- package/controls/rich-text/floating.js.map +0 -1
- package/controls/rich-text/index.js.map +0 -1
- package/controls/rich-text/link-form.js +0 -111
- package/controls/rich-text/link-form.js.map +0 -1
- package/controls/rich-text/markdown.js.map +0 -1
- package/controls/rich-text/ops.js.map +0 -1
- package/controls/rich-text/toolbar.js.map +0 -1
- package/controls/scale.js.map +0 -1
- package/controls/slot-register.js.map +0 -1
- package/controls/slot-services.js +0 -38
- package/controls/slot-services.js.map +0 -1
- package/controls/slot.js.map +0 -1
- package/controls/table/index.js.map +0 -1
- package/controls/table/prod.js.map +0 -1
- package/controls/table/refs.js.map +0 -1
- package/controls/table/stored.js.map +0 -1
- package/controls/table/table-editor.js.map +0 -1
- package/controls/table/table-link.js.map +0 -1
- package/controls/table/table.js.map +0 -1
- package/controls/text.js.map +0 -1
- package/engine/array.js.map +0 -1
- package/engine/bits.js.map +0 -1
- package/engine/breadcrumb.js.map +0 -1
- package/engine/expand.js.map +0 -1
- package/engine/field-list.js.map +0 -1
- package/engine/field-shell.js.map +0 -1
- package/engine/frame.js.map +0 -1
- package/engine/group-summary.js.map +0 -1
- package/engine/grouping.js.map +0 -1
- package/engine/item-list.js.map +0 -1
- package/engine/kit-field.js.map +0 -1
- package/engine/schema-form.js.map +0 -1
- package/engine/slot.js.map +0 -1
- package/index.js +0 -55
- package/index.js.map +0 -1
- package/lib/cn.js.map +0 -1
- package/lib/columns.js.map +0 -1
- package/lib/frames.js.map +0 -1
- package/lib/icons.js.map +0 -1
- package/lib/path.js.map +0 -1
- package/lib/schema.js.map +0 -1
- package/lib/utils.js.map +0 -1
- package/lib/validate.js.map +0 -1
- package/schema/adapters.js.map +0 -1
- package/schema/help.js.map +0 -1
- package/schema/scale.js.map +0 -1
- package/schema/sources.js.map +0 -1
- package/schema/table.js.map +0 -1
- package/schema/types.js.map +0 -1
- package/ui/action-tray.js.map +0 -1
- package/ui/button.js.map +0 -1
- package/ui/choice-switch.js.map +0 -1
- package/ui/controls.js.map +0 -1
- package/ui/display.js.map +0 -1
- package/ui/expanded-editor-modal.js.map +0 -1
- package/ui/field-context.js.map +0 -1
- package/ui/floating-panel.js.map +0 -1
- package/ui/index.js +0 -13
- package/ui/input.js.map +0 -1
- package/ui/mode-bar.js.map +0 -1
- package/ui/overlay.js +0 -378
- package/ui/overlay.js.map +0 -1
- package/ui/path-crumbs.js.map +0 -1
- package/ui/presence.js.map +0 -1
- package/ui/select.js.map +0 -1
- package/ui/shortcut-hint.js.map +0 -1
- package/ui/surfaces.js.map +0 -1
- package/ui/tooltip-root.js.map +0 -1
- package/ui/variants.js.map +0 -1
- /package/{_virtual → dist/_virtual}/_rolldown/runtime.js +0 -0
- /package/{adapters → dist/adapters}/icons.d.ts +0 -0
- /package/{brand → dist/brand}/logo.d.ts +0 -0
- /package/{controls → dist/controls}/c1.d.ts +0 -0
- /package/{controls → dist/controls}/c2.d.ts +0 -0
- /package/{controls → dist/controls}/code-register.d.ts +0 -0
- /package/{controls → dist/controls}/code.d.ts +0 -0
- /package/{controls → dist/controls}/color.d.ts +0 -0
- /package/{controls → dist/controls}/date-register.d.ts +0 -0
- /package/{controls → dist/controls}/date-zone.d.ts +0 -0
- /package/{controls → dist/controls}/date.d.ts +0 -0
- /package/{controls → dist/controls}/form-picker-register.d.ts +0 -0
- /package/{controls → dist/controls}/form-picker.d.ts +0 -0
- /package/{controls → dist/controls}/icon-register.d.ts +0 -0
- /package/{controls → dist/controls}/json-register.d.ts +0 -0
- /package/{controls → dist/controls}/json.d.ts +0 -0
- /package/{controls → dist/controls}/link.d.ts +0 -0
- /package/{controls → dist/controls}/location-register.d.ts +0 -0
- /package/{controls → dist/controls}/location.d.ts +0 -0
- /package/{controls → dist/controls}/media-register.d.ts +0 -0
- /package/{controls → dist/controls}/number.d.ts +0 -0
- /package/{controls → dist/controls}/reference-register.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/index.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/link-form.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/markdown.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/ops.d.ts +0 -0
- /package/{controls → dist/controls}/scale.d.ts +0 -0
- /package/{controls → dist/controls}/slot-register.d.ts +0 -0
- /package/{controls → dist/controls}/slot.d.ts +0 -0
- /package/{controls → dist/controls}/table/index.d.ts +0 -0
- /package/{controls → dist/controls}/table/prod.d.ts +0 -0
- /package/{controls → dist/controls}/table/refs.d.ts +0 -0
- /package/{controls → dist/controls}/table/stored.d.ts +0 -0
- /package/{controls → dist/controls}/table/table-editor.d.ts +0 -0
- /package/{controls → dist/controls}/table/table-link.d.ts +0 -0
- /package/{controls → dist/controls}/table/table.d.ts +0 -0
- /package/{engine → dist/engine}/array.d.ts +0 -0
- /package/{engine → dist/engine}/bits.d.ts +0 -0
- /package/{engine → dist/engine}/field-list.d.ts +0 -0
- /package/{engine → dist/engine}/field-shell.d.ts +0 -0
- /package/{engine → dist/engine}/kit-field.d.ts +0 -0
- /package/{engine → dist/engine}/slot.d.ts +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{lib → dist/lib}/cn.d.ts +0 -0
- /package/{lib → dist/lib}/columns.d.ts +0 -0
- /package/{lib → dist/lib}/frames.d.ts +0 -0
- /package/{lib → dist/lib}/icons.d.ts +0 -0
- /package/{lib → dist/lib}/path.d.ts +0 -0
- /package/{lib → dist/lib}/utils.d.ts +0 -0
- /package/{schema → dist/schema}/adapters.d.ts +0 -0
- /package/{schema → dist/schema}/scale.d.ts +0 -0
- /package/{schema → dist/schema}/sources.d.ts +0 -0
- /package/{schema → dist/schema}/table.d.ts +0 -0
- /package/{types.d.ts → dist/types.d.ts} +0 -0
- /package/{ui → dist/ui}/choice-switch.d.ts +0 -0
- /package/{ui → dist/ui}/controls.d.ts +0 -0
- /package/{ui → dist/ui}/field-context.d.ts +0 -0
- /package/{ui → dist/ui}/mode-bar.d.ts +0 -0
- /package/{ui → dist/ui}/path-crumbs.d.ts +0 -0
- /package/{ui → dist/ui}/presence.d.ts +0 -0
- /package/{ui → dist/ui}/select.d.ts +0 -0
- /package/{ui → dist/ui}/shortcut-hint.d.ts +0 -0
- /package/{ui → dist/ui}/surfaces.d.ts +0 -0
- /package/{ui → dist/ui}/variants.d.ts +0 -0
|
@@ -0,0 +1,2297 @@
|
|
|
1
|
+
//#region src/library/entries/social-proof.entries.ts
|
|
2
|
+
var img = (seed, alt, w = 800, h = 800) => ({
|
|
3
|
+
url: `https://picsum.photos/seed/${seed}/${w}/${h}`,
|
|
4
|
+
alt,
|
|
5
|
+
name: `${seed}.jpg`,
|
|
6
|
+
width: w * 2,
|
|
7
|
+
height: h * 2
|
|
8
|
+
});
|
|
9
|
+
var logo = (file, alt, w = 160, h = 48) => ({
|
|
10
|
+
url: `https://cdn.bettercms.site/kit/logos/${file}`,
|
|
11
|
+
alt,
|
|
12
|
+
name: file,
|
|
13
|
+
width: w,
|
|
14
|
+
height: h
|
|
15
|
+
});
|
|
16
|
+
var avatar = (n) => `https://i.pravatar.cc/192?img=${n}`;
|
|
17
|
+
var CONTENT_DESIGN = [{
|
|
18
|
+
name: "content",
|
|
19
|
+
title: "Content",
|
|
20
|
+
default: true
|
|
21
|
+
}, {
|
|
22
|
+
name: "design",
|
|
23
|
+
title: "Design"
|
|
24
|
+
}];
|
|
25
|
+
var theme = {
|
|
26
|
+
name: "theme",
|
|
27
|
+
title: "Theme",
|
|
28
|
+
type: "select",
|
|
29
|
+
group: "design",
|
|
30
|
+
layout: "segmented",
|
|
31
|
+
initialValue: "light",
|
|
32
|
+
options: [
|
|
33
|
+
{
|
|
34
|
+
value: "light",
|
|
35
|
+
label: "Light"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
value: "dark",
|
|
39
|
+
label: "Dark"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
value: "brand",
|
|
43
|
+
label: "Brand"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
};
|
|
47
|
+
var testimonialGrid = {
|
|
48
|
+
name: "testimonialGrid",
|
|
49
|
+
title: "Testimonial grid",
|
|
50
|
+
kind: "block",
|
|
51
|
+
icon: "message-star",
|
|
52
|
+
category: "Social proof",
|
|
53
|
+
description: "Customer quotes from the Testimonials collection, in a grid or masonry",
|
|
54
|
+
variants: [
|
|
55
|
+
{
|
|
56
|
+
id: "grid",
|
|
57
|
+
name: "Grid",
|
|
58
|
+
description: "Equal cards in rows"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "masonry",
|
|
62
|
+
name: "Masonry",
|
|
63
|
+
description: "Cards keep their natural height"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "featured",
|
|
67
|
+
name: "Featured + grid",
|
|
68
|
+
description: "The first quote large, the rest small"
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
preview: {
|
|
72
|
+
title: "heading",
|
|
73
|
+
icon: "message-star"
|
|
74
|
+
},
|
|
75
|
+
groups: CONTENT_DESIGN,
|
|
76
|
+
fields: [
|
|
77
|
+
{
|
|
78
|
+
name: "eyebrow",
|
|
79
|
+
title: "Eyebrow",
|
|
80
|
+
type: "string",
|
|
81
|
+
validation: { max: 32 }
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "heading",
|
|
85
|
+
title: "Heading",
|
|
86
|
+
type: "string",
|
|
87
|
+
validation: {
|
|
88
|
+
required: true,
|
|
89
|
+
recommendedMax: 60
|
|
90
|
+
},
|
|
91
|
+
ai: true,
|
|
92
|
+
localized: true
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: "source",
|
|
96
|
+
title: "Which testimonials",
|
|
97
|
+
type: "select",
|
|
98
|
+
layout: "radio",
|
|
99
|
+
initialValue: "pick",
|
|
100
|
+
options: [{
|
|
101
|
+
value: "pick",
|
|
102
|
+
label: "Pick them",
|
|
103
|
+
description: "A fixed set in your order"
|
|
104
|
+
}, {
|
|
105
|
+
value: "query",
|
|
106
|
+
label: "Latest matching",
|
|
107
|
+
description: "Filled from the collection by tag"
|
|
108
|
+
}]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: "testimonials",
|
|
112
|
+
title: "Testimonials",
|
|
113
|
+
type: "array",
|
|
114
|
+
itemNoun: "testimonial",
|
|
115
|
+
hidden: {
|
|
116
|
+
field: "source",
|
|
117
|
+
equals: "pick"
|
|
118
|
+
},
|
|
119
|
+
validation: {
|
|
120
|
+
min: 3,
|
|
121
|
+
max: 12,
|
|
122
|
+
unique: true
|
|
123
|
+
},
|
|
124
|
+
of: [{
|
|
125
|
+
name: "testimonial",
|
|
126
|
+
title: "Testimonial",
|
|
127
|
+
type: "reference",
|
|
128
|
+
reference: { to: ["col_testimonials"] }
|
|
129
|
+
}]
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: "tags",
|
|
133
|
+
title: "Tagged",
|
|
134
|
+
type: "tags",
|
|
135
|
+
hidden: {
|
|
136
|
+
field: "source",
|
|
137
|
+
equals: "query"
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "limit",
|
|
142
|
+
title: "How many",
|
|
143
|
+
type: "number",
|
|
144
|
+
hidden: {
|
|
145
|
+
field: "source",
|
|
146
|
+
equals: "query"
|
|
147
|
+
},
|
|
148
|
+
initialValue: 6,
|
|
149
|
+
numeric: {
|
|
150
|
+
min: 3,
|
|
151
|
+
max: 12,
|
|
152
|
+
step: 3
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: "minRating",
|
|
157
|
+
title: "Minimum rating",
|
|
158
|
+
type: "rating",
|
|
159
|
+
hidden: {
|
|
160
|
+
field: "source",
|
|
161
|
+
equals: "query"
|
|
162
|
+
},
|
|
163
|
+
description: "Leave empty to include quotes without a rating."
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: "showRating",
|
|
167
|
+
title: "Show rating",
|
|
168
|
+
type: "boolean",
|
|
169
|
+
group: "design",
|
|
170
|
+
initialValue: true
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "showPhotos",
|
|
174
|
+
title: "Show photos",
|
|
175
|
+
type: "boolean",
|
|
176
|
+
group: "design",
|
|
177
|
+
initialValue: true
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: "button",
|
|
181
|
+
title: "Button",
|
|
182
|
+
type: "button"
|
|
183
|
+
},
|
|
184
|
+
theme
|
|
185
|
+
]
|
|
186
|
+
};
|
|
187
|
+
var videoSlider = {
|
|
188
|
+
name: "videoTestimonials",
|
|
189
|
+
title: "Video testimonials",
|
|
190
|
+
kind: "block",
|
|
191
|
+
icon: "video",
|
|
192
|
+
category: "Social proof",
|
|
193
|
+
description: "A slider of customer stories: video with captions, or a written quote",
|
|
194
|
+
variants: [{
|
|
195
|
+
id: "cards",
|
|
196
|
+
name: "Cards",
|
|
197
|
+
description: "Several slides visible, peek at the next"
|
|
198
|
+
}, {
|
|
199
|
+
id: "spotlight",
|
|
200
|
+
name: "Spotlight",
|
|
201
|
+
description: "One large slide at a time"
|
|
202
|
+
}],
|
|
203
|
+
preview: {
|
|
204
|
+
title: "heading",
|
|
205
|
+
icon: "movie"
|
|
206
|
+
},
|
|
207
|
+
groups: CONTENT_DESIGN,
|
|
208
|
+
fields: [
|
|
209
|
+
{
|
|
210
|
+
name: "eyebrow",
|
|
211
|
+
title: "Eyebrow",
|
|
212
|
+
type: "string",
|
|
213
|
+
validation: { max: 32 }
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: "heading",
|
|
217
|
+
title: "Heading",
|
|
218
|
+
type: "string",
|
|
219
|
+
validation: {
|
|
220
|
+
required: true,
|
|
221
|
+
recommendedMax: 60
|
|
222
|
+
},
|
|
223
|
+
ai: true,
|
|
224
|
+
localized: true
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "slides",
|
|
228
|
+
title: "Slides",
|
|
229
|
+
type: "array",
|
|
230
|
+
itemNoun: "slide",
|
|
231
|
+
validation: {
|
|
232
|
+
min: 2,
|
|
233
|
+
max: 10
|
|
234
|
+
},
|
|
235
|
+
of: [{
|
|
236
|
+
name: "slide",
|
|
237
|
+
title: "Slide",
|
|
238
|
+
type: "object",
|
|
239
|
+
icon: "movie",
|
|
240
|
+
preview: {
|
|
241
|
+
title: "person.name",
|
|
242
|
+
subtitle: "pullQuote",
|
|
243
|
+
media: "poster",
|
|
244
|
+
fallback: "Untitled slide"
|
|
245
|
+
},
|
|
246
|
+
fields: [
|
|
247
|
+
{
|
|
248
|
+
name: "kind",
|
|
249
|
+
title: "Type",
|
|
250
|
+
type: "select",
|
|
251
|
+
layout: "segmented",
|
|
252
|
+
initialValue: "video",
|
|
253
|
+
options: [{
|
|
254
|
+
value: "video",
|
|
255
|
+
label: "Video"
|
|
256
|
+
}, {
|
|
257
|
+
value: "quote",
|
|
258
|
+
label: "Quote"
|
|
259
|
+
}]
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: "video",
|
|
263
|
+
title: "Video",
|
|
264
|
+
type: "video",
|
|
265
|
+
hidden: {
|
|
266
|
+
field: "kind",
|
|
267
|
+
equals: "video"
|
|
268
|
+
},
|
|
269
|
+
validation: { required: true },
|
|
270
|
+
description: "Hosted MP4, YouTube or Vimeo."
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
name: "poster",
|
|
274
|
+
title: "Poster",
|
|
275
|
+
type: "image",
|
|
276
|
+
hidden: {
|
|
277
|
+
field: "kind",
|
|
278
|
+
equals: "video"
|
|
279
|
+
},
|
|
280
|
+
validation: { required: true }
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
name: "captions",
|
|
284
|
+
title: "Captions",
|
|
285
|
+
type: "file",
|
|
286
|
+
hidden: {
|
|
287
|
+
field: "kind",
|
|
288
|
+
equals: "video"
|
|
289
|
+
},
|
|
290
|
+
validation: { required: true },
|
|
291
|
+
description: "A .vtt file. Required for hosted MP4s."
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: "transcript",
|
|
295
|
+
title: "Transcript",
|
|
296
|
+
type: "richtext",
|
|
297
|
+
hidden: {
|
|
298
|
+
field: "kind",
|
|
299
|
+
equals: "video"
|
|
300
|
+
},
|
|
301
|
+
localized: true
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
name: "pullQuote",
|
|
305
|
+
title: "Pull quote",
|
|
306
|
+
type: "text",
|
|
307
|
+
rows: 3,
|
|
308
|
+
validation: {
|
|
309
|
+
required: true,
|
|
310
|
+
recommendedMax: 160
|
|
311
|
+
},
|
|
312
|
+
localized: true
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
name: "duration",
|
|
316
|
+
title: "Length",
|
|
317
|
+
type: "string",
|
|
318
|
+
hidden: {
|
|
319
|
+
field: "kind",
|
|
320
|
+
equals: "video"
|
|
321
|
+
},
|
|
322
|
+
placeholder: "1:24",
|
|
323
|
+
validation: {
|
|
324
|
+
pattern: "^\\d{1,2}:\\d{2}$",
|
|
325
|
+
patternMessage: "Use m:ss, like 1:24."
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
name: "person",
|
|
330
|
+
title: "Person",
|
|
331
|
+
type: "object",
|
|
332
|
+
icon: "user",
|
|
333
|
+
fields: [
|
|
334
|
+
{
|
|
335
|
+
name: "name",
|
|
336
|
+
title: "Name",
|
|
337
|
+
type: "string",
|
|
338
|
+
validation: {
|
|
339
|
+
required: true,
|
|
340
|
+
max: 48
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
name: "role",
|
|
345
|
+
title: "Role",
|
|
346
|
+
type: "string",
|
|
347
|
+
validation: { max: 64 },
|
|
348
|
+
localized: true,
|
|
349
|
+
placeholder: "Owner"
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
name: "company",
|
|
353
|
+
title: "Company",
|
|
354
|
+
type: "string",
|
|
355
|
+
validation: { max: 48 }
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
name: "photo",
|
|
359
|
+
title: "Photo",
|
|
360
|
+
type: "image",
|
|
361
|
+
description: "Square, at least 192px."
|
|
362
|
+
}
|
|
363
|
+
]
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
name: "testimonial",
|
|
367
|
+
title: "Linked testimonial",
|
|
368
|
+
type: "reference",
|
|
369
|
+
reference: { to: ["col_testimonials"] },
|
|
370
|
+
advanced: true
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
name: "caseStudy",
|
|
374
|
+
title: "Case study link",
|
|
375
|
+
type: "link"
|
|
376
|
+
}
|
|
377
|
+
]
|
|
378
|
+
}]
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
name: "autoplay",
|
|
382
|
+
title: "Play automatically",
|
|
383
|
+
type: "boolean",
|
|
384
|
+
group: "design"
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
name: "allowInlinePlay",
|
|
388
|
+
title: "Play on the card",
|
|
389
|
+
type: "boolean",
|
|
390
|
+
group: "design",
|
|
391
|
+
initialValue: false,
|
|
392
|
+
description: "Off opens videos in a lightbox."
|
|
393
|
+
},
|
|
394
|
+
theme
|
|
395
|
+
]
|
|
396
|
+
};
|
|
397
|
+
var SOURCE_URL = {
|
|
398
|
+
name: "url",
|
|
399
|
+
title: "Original post",
|
|
400
|
+
type: "url",
|
|
401
|
+
validation: { required: true }
|
|
402
|
+
};
|
|
403
|
+
var wallOfLove = {
|
|
404
|
+
name: "wallOfLove",
|
|
405
|
+
title: "Wall of love",
|
|
406
|
+
kind: "block",
|
|
407
|
+
icon: "heart",
|
|
408
|
+
category: "Social proof",
|
|
409
|
+
description: "A masonry wall of real posts and reviews: social posts, store reviews, photos",
|
|
410
|
+
variants: [{
|
|
411
|
+
id: "masonry",
|
|
412
|
+
name: "Masonry"
|
|
413
|
+
}, {
|
|
414
|
+
id: "marquee",
|
|
415
|
+
name: "Scrolling columns",
|
|
416
|
+
description: "Columns drift slowly in opposite directions"
|
|
417
|
+
}],
|
|
418
|
+
preview: {
|
|
419
|
+
title: "heading",
|
|
420
|
+
icon: "heart"
|
|
421
|
+
},
|
|
422
|
+
groups: CONTENT_DESIGN,
|
|
423
|
+
fields: [
|
|
424
|
+
{
|
|
425
|
+
name: "eyebrow",
|
|
426
|
+
title: "Eyebrow",
|
|
427
|
+
type: "string",
|
|
428
|
+
validation: { max: 32 }
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
name: "heading",
|
|
432
|
+
title: "Heading",
|
|
433
|
+
type: "string",
|
|
434
|
+
validation: {
|
|
435
|
+
required: true,
|
|
436
|
+
recommendedMax: 60
|
|
437
|
+
},
|
|
438
|
+
ai: true,
|
|
439
|
+
localized: true
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
name: "items",
|
|
443
|
+
title: "Posts",
|
|
444
|
+
type: "array",
|
|
445
|
+
itemNoun: "post",
|
|
446
|
+
validation: {
|
|
447
|
+
min: 6,
|
|
448
|
+
max: 40
|
|
449
|
+
},
|
|
450
|
+
of: [
|
|
451
|
+
{
|
|
452
|
+
name: "socialPost",
|
|
453
|
+
title: "Social post",
|
|
454
|
+
type: "object",
|
|
455
|
+
icon: "brand-x",
|
|
456
|
+
preview: {
|
|
457
|
+
title: "handle",
|
|
458
|
+
subtitle: "text",
|
|
459
|
+
media: "photo",
|
|
460
|
+
fallback: "Untitled social post"
|
|
461
|
+
},
|
|
462
|
+
fields: [
|
|
463
|
+
{
|
|
464
|
+
name: "network",
|
|
465
|
+
title: "Network",
|
|
466
|
+
type: "select",
|
|
467
|
+
layout: "segmented",
|
|
468
|
+
initialValue: "x",
|
|
469
|
+
options: [
|
|
470
|
+
{
|
|
471
|
+
value: "x",
|
|
472
|
+
label: "X"
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
value: "threads",
|
|
476
|
+
label: "Threads"
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
value: "bluesky",
|
|
480
|
+
label: "Bluesky"
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
value: "linkedin",
|
|
484
|
+
label: "LinkedIn"
|
|
485
|
+
}
|
|
486
|
+
]
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: "name",
|
|
490
|
+
title: "Name",
|
|
491
|
+
type: "string",
|
|
492
|
+
validation: {
|
|
493
|
+
required: true,
|
|
494
|
+
max: 48
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
name: "handle",
|
|
499
|
+
title: "Handle",
|
|
500
|
+
type: "string",
|
|
501
|
+
validation: {
|
|
502
|
+
required: true,
|
|
503
|
+
pattern: "^@?[A-Za-z0-9_.]{1,30}$",
|
|
504
|
+
patternMessage: "Use letters, numbers, dots and underscores, like custom.rank."
|
|
505
|
+
},
|
|
506
|
+
placeholder: "@mayaoutside"
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
name: "photo",
|
|
510
|
+
title: "Photo",
|
|
511
|
+
type: "image"
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
name: "text",
|
|
515
|
+
title: "Post text",
|
|
516
|
+
type: "text",
|
|
517
|
+
rows: 4,
|
|
518
|
+
validation: {
|
|
519
|
+
required: true,
|
|
520
|
+
max: 500
|
|
521
|
+
},
|
|
522
|
+
description: "Copy it exactly, typos and emoji included."
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
name: "date",
|
|
526
|
+
title: "Posted",
|
|
527
|
+
type: "date"
|
|
528
|
+
},
|
|
529
|
+
SOURCE_URL
|
|
530
|
+
]
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
name: "review",
|
|
534
|
+
title: "Store review",
|
|
535
|
+
type: "object",
|
|
536
|
+
icon: "star",
|
|
537
|
+
preview: {
|
|
538
|
+
title: "reviewer",
|
|
539
|
+
subtitle: "title",
|
|
540
|
+
fallback: "Untitled review"
|
|
541
|
+
},
|
|
542
|
+
fields: [
|
|
543
|
+
{
|
|
544
|
+
name: "platform",
|
|
545
|
+
title: "Platform",
|
|
546
|
+
type: "select",
|
|
547
|
+
initialValue: "site",
|
|
548
|
+
options: [
|
|
549
|
+
{
|
|
550
|
+
value: "site",
|
|
551
|
+
label: "Our store"
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
value: "google",
|
|
555
|
+
label: "Google"
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
value: "trustpilot",
|
|
559
|
+
label: "Trustpilot"
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
value: "amazon",
|
|
563
|
+
label: "Amazon"
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
value: "rei",
|
|
567
|
+
label: "REI"
|
|
568
|
+
}
|
|
569
|
+
]
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
name: "rating",
|
|
573
|
+
title: "Rating",
|
|
574
|
+
type: "rating",
|
|
575
|
+
validation: { required: true }
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
name: "title",
|
|
579
|
+
title: "Review title",
|
|
580
|
+
type: "string",
|
|
581
|
+
validation: { max: 80 }
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
name: "text",
|
|
585
|
+
title: "Review",
|
|
586
|
+
type: "text",
|
|
587
|
+
rows: 4,
|
|
588
|
+
validation: {
|
|
589
|
+
required: true,
|
|
590
|
+
max: 600
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
name: "reviewer",
|
|
595
|
+
title: "Reviewer",
|
|
596
|
+
type: "string",
|
|
597
|
+
validation: {
|
|
598
|
+
required: true,
|
|
599
|
+
max: 48
|
|
600
|
+
},
|
|
601
|
+
placeholder: "Jordan K."
|
|
602
|
+
},
|
|
603
|
+
{
|
|
604
|
+
name: "isVerified",
|
|
605
|
+
title: "Verified buyer",
|
|
606
|
+
type: "boolean",
|
|
607
|
+
description: "Only when the platform shows the badge."
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
name: "date",
|
|
611
|
+
title: "Reviewed",
|
|
612
|
+
type: "date"
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
...SOURCE_URL,
|
|
616
|
+
validation: {},
|
|
617
|
+
description: "Link to the review if the platform has one."
|
|
618
|
+
}
|
|
619
|
+
]
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
name: "photoPost",
|
|
623
|
+
title: "Photo post",
|
|
624
|
+
type: "object",
|
|
625
|
+
icon: "brand-instagram",
|
|
626
|
+
preview: {
|
|
627
|
+
title: "handle",
|
|
628
|
+
subtitle: "caption",
|
|
629
|
+
media: "image",
|
|
630
|
+
fallback: "Untitled photo post"
|
|
631
|
+
},
|
|
632
|
+
fields: [
|
|
633
|
+
{
|
|
634
|
+
name: "image",
|
|
635
|
+
title: "Image",
|
|
636
|
+
type: "image",
|
|
637
|
+
validation: { required: true }
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
name: "handle",
|
|
641
|
+
title: "Handle",
|
|
642
|
+
type: "string",
|
|
643
|
+
validation: { required: true },
|
|
644
|
+
placeholder: "@trailkitchen"
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
name: "caption",
|
|
648
|
+
title: "Caption",
|
|
649
|
+
type: "text",
|
|
650
|
+
rows: 2,
|
|
651
|
+
validation: { max: 300 }
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
name: "hasRights",
|
|
655
|
+
title: "Creator gave permission",
|
|
656
|
+
type: "boolean",
|
|
657
|
+
validation: { required: true },
|
|
658
|
+
description: "Reposting a photo needs the creator's written OK."
|
|
659
|
+
},
|
|
660
|
+
SOURCE_URL
|
|
661
|
+
]
|
|
662
|
+
}
|
|
663
|
+
]
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
name: "showSourceIcons",
|
|
667
|
+
title: "Show platform icons",
|
|
668
|
+
type: "boolean",
|
|
669
|
+
group: "design",
|
|
670
|
+
initialValue: true
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
name: "maxHeight",
|
|
674
|
+
title: "Collapse after",
|
|
675
|
+
type: "number",
|
|
676
|
+
group: "design",
|
|
677
|
+
layout: "slider",
|
|
678
|
+
initialValue: 900,
|
|
679
|
+
numeric: {
|
|
680
|
+
min: 400,
|
|
681
|
+
max: 2e3,
|
|
682
|
+
step: 100,
|
|
683
|
+
unit: "px"
|
|
684
|
+
},
|
|
685
|
+
description: "Adds \"Show more\" below this height."
|
|
686
|
+
},
|
|
687
|
+
theme
|
|
688
|
+
]
|
|
689
|
+
};
|
|
690
|
+
var caseStudyCards = {
|
|
691
|
+
name: "caseStudyCards",
|
|
692
|
+
title: "Case study cards",
|
|
693
|
+
kind: "block",
|
|
694
|
+
icon: "briefcase",
|
|
695
|
+
category: "Social proof",
|
|
696
|
+
description: "Cards for customer stories: logo, headline result, link to the full story",
|
|
697
|
+
variants: [
|
|
698
|
+
{
|
|
699
|
+
id: "cards",
|
|
700
|
+
name: "Cards",
|
|
701
|
+
description: "Three across"
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
id: "feature",
|
|
705
|
+
name: "Featured story",
|
|
706
|
+
description: "One large card with the metric front and center"
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
id: "carousel",
|
|
710
|
+
name: "Carousel"
|
|
711
|
+
}
|
|
712
|
+
],
|
|
713
|
+
preview: {
|
|
714
|
+
title: "heading",
|
|
715
|
+
icon: "briefcase"
|
|
716
|
+
},
|
|
717
|
+
groups: CONTENT_DESIGN,
|
|
718
|
+
fields: [
|
|
719
|
+
{
|
|
720
|
+
name: "eyebrow",
|
|
721
|
+
title: "Eyebrow",
|
|
722
|
+
type: "string",
|
|
723
|
+
validation: { max: 32 }
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
name: "heading",
|
|
727
|
+
title: "Heading",
|
|
728
|
+
type: "string",
|
|
729
|
+
validation: {
|
|
730
|
+
required: true,
|
|
731
|
+
recommendedMax: 60
|
|
732
|
+
},
|
|
733
|
+
ai: true,
|
|
734
|
+
localized: true
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
name: "source",
|
|
738
|
+
title: "Which stories",
|
|
739
|
+
type: "select",
|
|
740
|
+
layout: "radio",
|
|
741
|
+
initialValue: "pick",
|
|
742
|
+
options: [
|
|
743
|
+
{
|
|
744
|
+
value: "pick",
|
|
745
|
+
label: "Pick them"
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
value: "industry",
|
|
749
|
+
label: "By industry",
|
|
750
|
+
description: "Newest stories in the industries you choose"
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
value: "latest",
|
|
754
|
+
label: "Latest"
|
|
755
|
+
}
|
|
756
|
+
]
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
name: "stories",
|
|
760
|
+
title: "Stories",
|
|
761
|
+
type: "array",
|
|
762
|
+
itemNoun: "story",
|
|
763
|
+
hidden: {
|
|
764
|
+
field: "source",
|
|
765
|
+
equals: "pick"
|
|
766
|
+
},
|
|
767
|
+
validation: {
|
|
768
|
+
min: 1,
|
|
769
|
+
max: 6,
|
|
770
|
+
unique: true
|
|
771
|
+
},
|
|
772
|
+
of: [{
|
|
773
|
+
name: "card",
|
|
774
|
+
title: "Story",
|
|
775
|
+
type: "object",
|
|
776
|
+
icon: "briefcase",
|
|
777
|
+
preview: {
|
|
778
|
+
title: "caseStudy",
|
|
779
|
+
subtitle: "metricOverride",
|
|
780
|
+
fallback: "Untitled story"
|
|
781
|
+
},
|
|
782
|
+
fields: [{
|
|
783
|
+
name: "caseStudy",
|
|
784
|
+
title: "Case study",
|
|
785
|
+
type: "reference",
|
|
786
|
+
reference: { to: ["col_case_studies"] },
|
|
787
|
+
validation: { required: true }
|
|
788
|
+
}, {
|
|
789
|
+
name: "metricOverride",
|
|
790
|
+
title: "Headline result",
|
|
791
|
+
type: "string",
|
|
792
|
+
placeholder: "Closed books 4× faster",
|
|
793
|
+
validation: { max: 40 },
|
|
794
|
+
description: "Replaces the story's headline metric on this card only."
|
|
795
|
+
}]
|
|
796
|
+
}]
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
name: "industries",
|
|
800
|
+
title: "Industries",
|
|
801
|
+
type: "multiselect",
|
|
802
|
+
hidden: {
|
|
803
|
+
field: "source",
|
|
804
|
+
equals: "industry"
|
|
805
|
+
},
|
|
806
|
+
options: [
|
|
807
|
+
{
|
|
808
|
+
value: "hospitality",
|
|
809
|
+
label: "Hospitality"
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
value: "retail",
|
|
813
|
+
label: "Retail"
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
value: "agency",
|
|
817
|
+
label: "Agencies"
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
value: "construction",
|
|
821
|
+
label: "Construction"
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
value: "nonprofit",
|
|
825
|
+
label: "Nonprofits"
|
|
826
|
+
}
|
|
827
|
+
]
|
|
828
|
+
},
|
|
829
|
+
{
|
|
830
|
+
name: "limit",
|
|
831
|
+
title: "How many",
|
|
832
|
+
type: "number",
|
|
833
|
+
hidden: {
|
|
834
|
+
field: "source",
|
|
835
|
+
equals: ["industry", "latest"]
|
|
836
|
+
},
|
|
837
|
+
initialValue: 3,
|
|
838
|
+
numeric: {
|
|
839
|
+
min: 1,
|
|
840
|
+
max: 9,
|
|
841
|
+
step: 1
|
|
842
|
+
}
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
name: "button",
|
|
846
|
+
title: "Button",
|
|
847
|
+
type: "button"
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
name: "showLogos",
|
|
851
|
+
title: "Show customer logos",
|
|
852
|
+
type: "boolean",
|
|
853
|
+
group: "design",
|
|
854
|
+
initialValue: true
|
|
855
|
+
},
|
|
856
|
+
theme
|
|
857
|
+
]
|
|
858
|
+
};
|
|
859
|
+
var logoCloud = {
|
|
860
|
+
name: "logoCloud",
|
|
861
|
+
title: "Logo cloud",
|
|
862
|
+
kind: "block",
|
|
863
|
+
icon: "building-skyscraper",
|
|
864
|
+
category: "Social proof",
|
|
865
|
+
description: "Logos of customers, retailers or partners, as a static row or an endless marquee",
|
|
866
|
+
variants: [
|
|
867
|
+
{
|
|
868
|
+
id: "row",
|
|
869
|
+
name: "Row",
|
|
870
|
+
description: "One or two centered rows"
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
id: "grid",
|
|
874
|
+
name: "Grid",
|
|
875
|
+
description: "Bordered cells"
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
id: "marquee",
|
|
879
|
+
name: "Marquee",
|
|
880
|
+
description: "Scrolls endlessly; pauses on hover"
|
|
881
|
+
}
|
|
882
|
+
],
|
|
883
|
+
preview: {
|
|
884
|
+
title: "heading",
|
|
885
|
+
icon: "building-skyscraper"
|
|
886
|
+
},
|
|
887
|
+
groups: CONTENT_DESIGN,
|
|
888
|
+
fields: [
|
|
889
|
+
{
|
|
890
|
+
name: "heading",
|
|
891
|
+
title: "Heading",
|
|
892
|
+
type: "string",
|
|
893
|
+
validation: { max: 80 },
|
|
894
|
+
localized: true,
|
|
895
|
+
placeholder: "Sold at"
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
name: "logos",
|
|
899
|
+
title: "Logos",
|
|
900
|
+
type: "array",
|
|
901
|
+
itemNoun: "logo",
|
|
902
|
+
arrayLayout: "grid",
|
|
903
|
+
validation: {
|
|
904
|
+
min: 3,
|
|
905
|
+
max: 30
|
|
906
|
+
},
|
|
907
|
+
of: [{
|
|
908
|
+
name: "logo",
|
|
909
|
+
title: "Logo",
|
|
910
|
+
type: "object",
|
|
911
|
+
icon: "photo",
|
|
912
|
+
openMode: "popover",
|
|
913
|
+
preview: {
|
|
914
|
+
title: "name",
|
|
915
|
+
media: "logo",
|
|
916
|
+
fallback: "Untitled logo"
|
|
917
|
+
},
|
|
918
|
+
fields: [
|
|
919
|
+
{
|
|
920
|
+
name: "name",
|
|
921
|
+
title: "Company name",
|
|
922
|
+
type: "string",
|
|
923
|
+
validation: {
|
|
924
|
+
required: true,
|
|
925
|
+
max: 48
|
|
926
|
+
},
|
|
927
|
+
description: "Not shown. Read by screen readers."
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
name: "logo",
|
|
931
|
+
title: "Logo",
|
|
932
|
+
type: "image",
|
|
933
|
+
validation: { required: true },
|
|
934
|
+
description: "SVG or a transparent PNG."
|
|
935
|
+
},
|
|
936
|
+
{
|
|
937
|
+
name: "link",
|
|
938
|
+
title: "Link",
|
|
939
|
+
type: "link"
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
name: "scale",
|
|
943
|
+
title: "Optical size",
|
|
944
|
+
type: "number",
|
|
945
|
+
layout: "slider",
|
|
946
|
+
initialValue: 100,
|
|
947
|
+
numeric: {
|
|
948
|
+
min: 60,
|
|
949
|
+
max: 140,
|
|
950
|
+
step: 5,
|
|
951
|
+
unit: "%"
|
|
952
|
+
},
|
|
953
|
+
description: "Nudges wide or tall marks so logos look the same size."
|
|
954
|
+
}
|
|
955
|
+
]
|
|
956
|
+
}]
|
|
957
|
+
},
|
|
958
|
+
{
|
|
959
|
+
name: "isGrayscale",
|
|
960
|
+
title: "Grayscale logos",
|
|
961
|
+
type: "boolean",
|
|
962
|
+
group: "design",
|
|
963
|
+
initialValue: true
|
|
964
|
+
},
|
|
965
|
+
{
|
|
966
|
+
name: "speed",
|
|
967
|
+
title: "Scroll speed",
|
|
968
|
+
type: "select",
|
|
969
|
+
group: "design",
|
|
970
|
+
layout: "segmented",
|
|
971
|
+
hidden: {
|
|
972
|
+
field: "_variant",
|
|
973
|
+
equals: "marquee"
|
|
974
|
+
},
|
|
975
|
+
initialValue: "slow",
|
|
976
|
+
options: [
|
|
977
|
+
{
|
|
978
|
+
value: "slow",
|
|
979
|
+
label: "Slow"
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
value: "medium",
|
|
983
|
+
label: "Medium"
|
|
984
|
+
},
|
|
985
|
+
{
|
|
986
|
+
value: "fast",
|
|
987
|
+
label: "Fast"
|
|
988
|
+
}
|
|
989
|
+
]
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
name: "logoHeight",
|
|
993
|
+
title: "Logo height",
|
|
994
|
+
type: "number",
|
|
995
|
+
group: "design",
|
|
996
|
+
layout: "slider",
|
|
997
|
+
initialValue: 32,
|
|
998
|
+
numeric: {
|
|
999
|
+
min: 20,
|
|
1000
|
+
max: 64,
|
|
1001
|
+
step: 4,
|
|
1002
|
+
unit: "px"
|
|
1003
|
+
}
|
|
1004
|
+
},
|
|
1005
|
+
theme
|
|
1006
|
+
]
|
|
1007
|
+
};
|
|
1008
|
+
var pressMentions = {
|
|
1009
|
+
name: "pressMentions",
|
|
1010
|
+
title: "Press mentions",
|
|
1011
|
+
kind: "block",
|
|
1012
|
+
icon: "article",
|
|
1013
|
+
category: "Social proof",
|
|
1014
|
+
description: "What publications said, with the outlet's logo and a link to the article",
|
|
1015
|
+
variants: [{
|
|
1016
|
+
id: "quotes",
|
|
1017
|
+
name: "Quotes",
|
|
1018
|
+
description: "Quote cards with the outlet's logo"
|
|
1019
|
+
}, {
|
|
1020
|
+
id: "rotator",
|
|
1021
|
+
name: "Logo rotator",
|
|
1022
|
+
description: "Logos in a row; the quote changes as each is selected"
|
|
1023
|
+
}],
|
|
1024
|
+
preview: {
|
|
1025
|
+
title: "heading",
|
|
1026
|
+
icon: "news"
|
|
1027
|
+
},
|
|
1028
|
+
groups: CONTENT_DESIGN,
|
|
1029
|
+
fields: [
|
|
1030
|
+
{
|
|
1031
|
+
name: "heading",
|
|
1032
|
+
title: "Heading",
|
|
1033
|
+
type: "string",
|
|
1034
|
+
validation: { recommendedMax: 48 },
|
|
1035
|
+
localized: true,
|
|
1036
|
+
placeholder: "As seen in"
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
name: "mentions",
|
|
1040
|
+
title: "Mentions",
|
|
1041
|
+
type: "array",
|
|
1042
|
+
itemNoun: "mention",
|
|
1043
|
+
validation: {
|
|
1044
|
+
min: 2,
|
|
1045
|
+
max: 8
|
|
1046
|
+
},
|
|
1047
|
+
of: [{
|
|
1048
|
+
name: "mention",
|
|
1049
|
+
title: "Mention",
|
|
1050
|
+
type: "object",
|
|
1051
|
+
icon: "news",
|
|
1052
|
+
preview: {
|
|
1053
|
+
title: "outlet",
|
|
1054
|
+
subtitle: "quote",
|
|
1055
|
+
media: "logo",
|
|
1056
|
+
fallback: "Untitled mention"
|
|
1057
|
+
},
|
|
1058
|
+
fields: [
|
|
1059
|
+
{
|
|
1060
|
+
name: "outlet",
|
|
1061
|
+
title: "Publication",
|
|
1062
|
+
type: "string",
|
|
1063
|
+
validation: {
|
|
1064
|
+
required: true,
|
|
1065
|
+
max: 48
|
|
1066
|
+
}
|
|
1067
|
+
},
|
|
1068
|
+
{
|
|
1069
|
+
name: "logo",
|
|
1070
|
+
title: "Publication logo",
|
|
1071
|
+
type: "image",
|
|
1072
|
+
validation: { required: true },
|
|
1073
|
+
description: "SVG or a transparent PNG."
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
name: "quote",
|
|
1077
|
+
title: "Quote",
|
|
1078
|
+
type: "text",
|
|
1079
|
+
rows: 3,
|
|
1080
|
+
validation: {
|
|
1081
|
+
required: true,
|
|
1082
|
+
recommendedMax: 140
|
|
1083
|
+
},
|
|
1084
|
+
localized: true,
|
|
1085
|
+
description: "Their exact words. Trim with \"…\" if needed."
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
name: "article",
|
|
1089
|
+
title: "Article",
|
|
1090
|
+
type: "link",
|
|
1091
|
+
validation: { required: true }
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
name: "author",
|
|
1095
|
+
title: "Journalist",
|
|
1096
|
+
type: "string",
|
|
1097
|
+
validation: { max: 48 }
|
|
1098
|
+
},
|
|
1099
|
+
{
|
|
1100
|
+
name: "date",
|
|
1101
|
+
title: "Published",
|
|
1102
|
+
type: "date"
|
|
1103
|
+
},
|
|
1104
|
+
{
|
|
1105
|
+
name: "isFeatured",
|
|
1106
|
+
title: "Featured",
|
|
1107
|
+
type: "boolean"
|
|
1108
|
+
}
|
|
1109
|
+
]
|
|
1110
|
+
}]
|
|
1111
|
+
},
|
|
1112
|
+
{
|
|
1113
|
+
name: "isGrayscale",
|
|
1114
|
+
title: "Grayscale logos",
|
|
1115
|
+
type: "boolean",
|
|
1116
|
+
group: "design",
|
|
1117
|
+
initialValue: true
|
|
1118
|
+
},
|
|
1119
|
+
theme
|
|
1120
|
+
]
|
|
1121
|
+
};
|
|
1122
|
+
var awards = {
|
|
1123
|
+
name: "awards",
|
|
1124
|
+
title: "Awards and certifications",
|
|
1125
|
+
kind: "block",
|
|
1126
|
+
icon: "award",
|
|
1127
|
+
category: "Social proof",
|
|
1128
|
+
description: "Badges for awards, security certifications and compliance, each verifiable",
|
|
1129
|
+
variants: [{
|
|
1130
|
+
id: "badges",
|
|
1131
|
+
name: "Badge row"
|
|
1132
|
+
}, {
|
|
1133
|
+
id: "cards",
|
|
1134
|
+
name: "Cards",
|
|
1135
|
+
description: "Badge with issuer, year and a verify link"
|
|
1136
|
+
}],
|
|
1137
|
+
preview: {
|
|
1138
|
+
title: "heading",
|
|
1139
|
+
icon: "award"
|
|
1140
|
+
},
|
|
1141
|
+
groups: CONTENT_DESIGN,
|
|
1142
|
+
fields: [
|
|
1143
|
+
{
|
|
1144
|
+
name: "eyebrow",
|
|
1145
|
+
title: "Eyebrow",
|
|
1146
|
+
type: "string",
|
|
1147
|
+
validation: { max: 32 }
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
name: "heading",
|
|
1151
|
+
title: "Heading",
|
|
1152
|
+
type: "string",
|
|
1153
|
+
validation: { recommendedMax: 60 },
|
|
1154
|
+
localized: true
|
|
1155
|
+
},
|
|
1156
|
+
{
|
|
1157
|
+
name: "badges",
|
|
1158
|
+
title: "Badges",
|
|
1159
|
+
type: "array",
|
|
1160
|
+
itemNoun: "badge",
|
|
1161
|
+
validation: {
|
|
1162
|
+
min: 1,
|
|
1163
|
+
max: 12
|
|
1164
|
+
},
|
|
1165
|
+
of: [{
|
|
1166
|
+
name: "badge",
|
|
1167
|
+
title: "Badge",
|
|
1168
|
+
type: "object",
|
|
1169
|
+
icon: "award",
|
|
1170
|
+
preview: {
|
|
1171
|
+
title: "name",
|
|
1172
|
+
subtitle: "issuer",
|
|
1173
|
+
media: "image",
|
|
1174
|
+
fallback: "Untitled badge"
|
|
1175
|
+
},
|
|
1176
|
+
fields: [
|
|
1177
|
+
{
|
|
1178
|
+
name: "kind",
|
|
1179
|
+
title: "Kind",
|
|
1180
|
+
type: "select",
|
|
1181
|
+
layout: "segmented",
|
|
1182
|
+
initialValue: "award",
|
|
1183
|
+
options: [
|
|
1184
|
+
{
|
|
1185
|
+
value: "award",
|
|
1186
|
+
label: "Award"
|
|
1187
|
+
},
|
|
1188
|
+
{
|
|
1189
|
+
value: "certification",
|
|
1190
|
+
label: "Certification",
|
|
1191
|
+
description: "Audited by a third party, e.g. SOC 2, ISO 27001"
|
|
1192
|
+
},
|
|
1193
|
+
{
|
|
1194
|
+
value: "membership",
|
|
1195
|
+
label: "Membership"
|
|
1196
|
+
}
|
|
1197
|
+
]
|
|
1198
|
+
},
|
|
1199
|
+
{
|
|
1200
|
+
name: "name",
|
|
1201
|
+
title: "Name",
|
|
1202
|
+
type: "string",
|
|
1203
|
+
validation: {
|
|
1204
|
+
required: true,
|
|
1205
|
+
max: 64
|
|
1206
|
+
},
|
|
1207
|
+
description: "Exactly as the issuer writes it, e.g. SOC 2 Type II."
|
|
1208
|
+
},
|
|
1209
|
+
{
|
|
1210
|
+
name: "issuer",
|
|
1211
|
+
title: "Issued by",
|
|
1212
|
+
type: "string",
|
|
1213
|
+
validation: {
|
|
1214
|
+
required: true,
|
|
1215
|
+
max: 64
|
|
1216
|
+
}
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
name: "image",
|
|
1220
|
+
title: "Image",
|
|
1221
|
+
type: "image",
|
|
1222
|
+
validation: { required: true },
|
|
1223
|
+
description: "The issuer's official badge file."
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
name: "year",
|
|
1227
|
+
title: "Year",
|
|
1228
|
+
type: "number",
|
|
1229
|
+
hidden: {
|
|
1230
|
+
field: "kind",
|
|
1231
|
+
equals: ["award", "membership"]
|
|
1232
|
+
},
|
|
1233
|
+
numeric: {
|
|
1234
|
+
min: 1990,
|
|
1235
|
+
max: 2100,
|
|
1236
|
+
step: 1
|
|
1237
|
+
}
|
|
1238
|
+
},
|
|
1239
|
+
{
|
|
1240
|
+
name: "certificateId",
|
|
1241
|
+
title: "Certificate number",
|
|
1242
|
+
type: "string",
|
|
1243
|
+
hidden: {
|
|
1244
|
+
field: "kind",
|
|
1245
|
+
equals: "certification"
|
|
1246
|
+
},
|
|
1247
|
+
validation: { max: 48 }
|
|
1248
|
+
},
|
|
1249
|
+
{
|
|
1250
|
+
name: "validUntil",
|
|
1251
|
+
title: "Valid until",
|
|
1252
|
+
type: "date",
|
|
1253
|
+
hidden: {
|
|
1254
|
+
field: "kind",
|
|
1255
|
+
equals: "certification"
|
|
1256
|
+
},
|
|
1257
|
+
validation: { required: true },
|
|
1258
|
+
description: "The badge hides itself after this date."
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
name: "verify",
|
|
1262
|
+
title: "Verify link",
|
|
1263
|
+
type: "link",
|
|
1264
|
+
description: "Required for certifications."
|
|
1265
|
+
}
|
|
1266
|
+
]
|
|
1267
|
+
}]
|
|
1268
|
+
},
|
|
1269
|
+
{
|
|
1270
|
+
name: "note",
|
|
1271
|
+
title: "Note",
|
|
1272
|
+
type: "text",
|
|
1273
|
+
rows: 2,
|
|
1274
|
+
localized: true
|
|
1275
|
+
},
|
|
1276
|
+
{
|
|
1277
|
+
name: "button",
|
|
1278
|
+
title: "Button",
|
|
1279
|
+
type: "button"
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
name: "isGrayscale",
|
|
1283
|
+
title: "Grayscale badges",
|
|
1284
|
+
type: "boolean",
|
|
1285
|
+
group: "design"
|
|
1286
|
+
},
|
|
1287
|
+
theme
|
|
1288
|
+
]
|
|
1289
|
+
};
|
|
1290
|
+
var reviewSummary = {
|
|
1291
|
+
name: "reviewSummary",
|
|
1292
|
+
title: "Review summary",
|
|
1293
|
+
kind: "block",
|
|
1294
|
+
icon: "stars",
|
|
1295
|
+
category: "Social proof",
|
|
1296
|
+
description: "Average rating, distribution bars, platform scores and a few top reviews",
|
|
1297
|
+
variants: [{
|
|
1298
|
+
id: "split",
|
|
1299
|
+
name: "Summary + reviews",
|
|
1300
|
+
description: "Bars left, featured reviews right"
|
|
1301
|
+
}, {
|
|
1302
|
+
id: "compact",
|
|
1303
|
+
name: "Compact",
|
|
1304
|
+
description: "One line: stars, average, count, platforms"
|
|
1305
|
+
}],
|
|
1306
|
+
preview: {
|
|
1307
|
+
title: "heading",
|
|
1308
|
+
subtitle: "subject",
|
|
1309
|
+
icon: "stars"
|
|
1310
|
+
},
|
|
1311
|
+
groups: [
|
|
1312
|
+
{
|
|
1313
|
+
name: "content",
|
|
1314
|
+
title: "Content",
|
|
1315
|
+
default: true
|
|
1316
|
+
},
|
|
1317
|
+
{
|
|
1318
|
+
name: "data",
|
|
1319
|
+
title: "Ratings"
|
|
1320
|
+
},
|
|
1321
|
+
{
|
|
1322
|
+
name: "design",
|
|
1323
|
+
title: "Design"
|
|
1324
|
+
}
|
|
1325
|
+
],
|
|
1326
|
+
fields: [
|
|
1327
|
+
{
|
|
1328
|
+
name: "heading",
|
|
1329
|
+
title: "Heading",
|
|
1330
|
+
type: "string",
|
|
1331
|
+
validation: { recommendedMax: 48 },
|
|
1332
|
+
localized: true,
|
|
1333
|
+
placeholder: "What cooks are saying"
|
|
1334
|
+
},
|
|
1335
|
+
{
|
|
1336
|
+
name: "subject",
|
|
1337
|
+
title: "Reviews of",
|
|
1338
|
+
type: "reference",
|
|
1339
|
+
reference: { to: ["shopify", "col_products"] },
|
|
1340
|
+
description: "Leave empty for store-wide reviews.",
|
|
1341
|
+
helpMore: "Star snippets in search only appear for a specific product."
|
|
1342
|
+
},
|
|
1343
|
+
{
|
|
1344
|
+
name: "dataSource",
|
|
1345
|
+
title: "Ratings come from",
|
|
1346
|
+
type: "select",
|
|
1347
|
+
group: "data",
|
|
1348
|
+
layout: "radio",
|
|
1349
|
+
initialValue: "connected",
|
|
1350
|
+
options: [{
|
|
1351
|
+
value: "connected",
|
|
1352
|
+
label: "Connected review app",
|
|
1353
|
+
description: "Synced nightly from the reviews integration"
|
|
1354
|
+
}, {
|
|
1355
|
+
value: "manual",
|
|
1356
|
+
label: "Typed in",
|
|
1357
|
+
description: "For ratings you can't sync, e.g. a trade show survey"
|
|
1358
|
+
}]
|
|
1359
|
+
},
|
|
1360
|
+
{
|
|
1361
|
+
name: "provider",
|
|
1362
|
+
title: "Review app",
|
|
1363
|
+
type: "select",
|
|
1364
|
+
group: "data",
|
|
1365
|
+
hidden: {
|
|
1366
|
+
field: "dataSource",
|
|
1367
|
+
equals: "connected"
|
|
1368
|
+
},
|
|
1369
|
+
access: { edit: "schema.manage" },
|
|
1370
|
+
lockReason: "Connected by the developer in Settings › Integrations.",
|
|
1371
|
+
options: [
|
|
1372
|
+
{
|
|
1373
|
+
value: "judgeme",
|
|
1374
|
+
label: "Judge.me"
|
|
1375
|
+
},
|
|
1376
|
+
{
|
|
1377
|
+
value: "okendo",
|
|
1378
|
+
label: "Okendo"
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
value: "yotpo",
|
|
1382
|
+
label: "Yotpo"
|
|
1383
|
+
},
|
|
1384
|
+
{
|
|
1385
|
+
value: "trustpilot",
|
|
1386
|
+
label: "Trustpilot"
|
|
1387
|
+
}
|
|
1388
|
+
]
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
name: "average",
|
|
1392
|
+
title: "Average rating",
|
|
1393
|
+
type: "number",
|
|
1394
|
+
group: "data",
|
|
1395
|
+
hidden: {
|
|
1396
|
+
field: "dataSource",
|
|
1397
|
+
equals: "manual"
|
|
1398
|
+
},
|
|
1399
|
+
validation: { required: true },
|
|
1400
|
+
numeric: {
|
|
1401
|
+
min: 1,
|
|
1402
|
+
max: 5,
|
|
1403
|
+
step: .1
|
|
1404
|
+
}
|
|
1405
|
+
},
|
|
1406
|
+
{
|
|
1407
|
+
name: "count",
|
|
1408
|
+
title: "Number of reviews",
|
|
1409
|
+
type: "number",
|
|
1410
|
+
group: "data",
|
|
1411
|
+
hidden: {
|
|
1412
|
+
field: "dataSource",
|
|
1413
|
+
equals: "manual"
|
|
1414
|
+
},
|
|
1415
|
+
validation: { required: true },
|
|
1416
|
+
numeric: {
|
|
1417
|
+
min: 1,
|
|
1418
|
+
step: 1
|
|
1419
|
+
}
|
|
1420
|
+
},
|
|
1421
|
+
{
|
|
1422
|
+
name: "ratingCounts",
|
|
1423
|
+
title: "Rating breakdown",
|
|
1424
|
+
type: "array",
|
|
1425
|
+
group: "data",
|
|
1426
|
+
hidden: {
|
|
1427
|
+
field: "dataSource",
|
|
1428
|
+
equals: "manual"
|
|
1429
|
+
},
|
|
1430
|
+
validation: {
|
|
1431
|
+
min: 5,
|
|
1432
|
+
max: 5
|
|
1433
|
+
},
|
|
1434
|
+
description: "One row per star level, 5 to 1. Counts must add up to the total.",
|
|
1435
|
+
of: [{
|
|
1436
|
+
name: "bucket",
|
|
1437
|
+
title: "Star level",
|
|
1438
|
+
type: "object",
|
|
1439
|
+
openMode: "inline",
|
|
1440
|
+
preview: {
|
|
1441
|
+
title: "stars",
|
|
1442
|
+
subtitle: "count"
|
|
1443
|
+
},
|
|
1444
|
+
fields: [{
|
|
1445
|
+
name: "stars",
|
|
1446
|
+
title: "Stars",
|
|
1447
|
+
type: "number",
|
|
1448
|
+
readOnly: true,
|
|
1449
|
+
numeric: {
|
|
1450
|
+
min: 1,
|
|
1451
|
+
max: 5,
|
|
1452
|
+
step: 1
|
|
1453
|
+
}
|
|
1454
|
+
}, {
|
|
1455
|
+
name: "count",
|
|
1456
|
+
title: "Reviews",
|
|
1457
|
+
type: "number",
|
|
1458
|
+
numeric: {
|
|
1459
|
+
min: 0,
|
|
1460
|
+
step: 1
|
|
1461
|
+
}
|
|
1462
|
+
}]
|
|
1463
|
+
}]
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
name: "platforms",
|
|
1467
|
+
title: "Other platforms",
|
|
1468
|
+
type: "array",
|
|
1469
|
+
itemNoun: "platform",
|
|
1470
|
+
group: "data",
|
|
1471
|
+
validation: { max: 4 },
|
|
1472
|
+
of: [{
|
|
1473
|
+
name: "platform",
|
|
1474
|
+
title: "Platform",
|
|
1475
|
+
type: "object",
|
|
1476
|
+
icon: "star",
|
|
1477
|
+
preview: {
|
|
1478
|
+
title: "name",
|
|
1479
|
+
subtitle: "rating"
|
|
1480
|
+
},
|
|
1481
|
+
fields: [
|
|
1482
|
+
{
|
|
1483
|
+
name: "name",
|
|
1484
|
+
title: "Platform",
|
|
1485
|
+
type: "select",
|
|
1486
|
+
validation: { required: true },
|
|
1487
|
+
options: [
|
|
1488
|
+
{
|
|
1489
|
+
value: "google",
|
|
1490
|
+
label: "Google"
|
|
1491
|
+
},
|
|
1492
|
+
{
|
|
1493
|
+
value: "trustpilot",
|
|
1494
|
+
label: "Trustpilot"
|
|
1495
|
+
},
|
|
1496
|
+
{
|
|
1497
|
+
value: "amazon",
|
|
1498
|
+
label: "Amazon"
|
|
1499
|
+
},
|
|
1500
|
+
{
|
|
1501
|
+
value: "rei",
|
|
1502
|
+
label: "REI"
|
|
1503
|
+
},
|
|
1504
|
+
{
|
|
1505
|
+
value: "g2",
|
|
1506
|
+
label: "G2"
|
|
1507
|
+
}
|
|
1508
|
+
]
|
|
1509
|
+
},
|
|
1510
|
+
{
|
|
1511
|
+
name: "rating",
|
|
1512
|
+
title: "Rating",
|
|
1513
|
+
type: "number",
|
|
1514
|
+
validation: { required: true },
|
|
1515
|
+
numeric: {
|
|
1516
|
+
min: 1,
|
|
1517
|
+
max: 5,
|
|
1518
|
+
step: .1
|
|
1519
|
+
}
|
|
1520
|
+
},
|
|
1521
|
+
{
|
|
1522
|
+
name: "count",
|
|
1523
|
+
title: "Reviews",
|
|
1524
|
+
type: "number",
|
|
1525
|
+
numeric: {
|
|
1526
|
+
min: 0,
|
|
1527
|
+
step: 1
|
|
1528
|
+
}
|
|
1529
|
+
},
|
|
1530
|
+
{
|
|
1531
|
+
name: "profile",
|
|
1532
|
+
title: "Profile link",
|
|
1533
|
+
type: "link",
|
|
1534
|
+
validation: { required: true }
|
|
1535
|
+
}
|
|
1536
|
+
]
|
|
1537
|
+
}]
|
|
1538
|
+
},
|
|
1539
|
+
{
|
|
1540
|
+
name: "featuredReviews",
|
|
1541
|
+
title: "Featured reviews",
|
|
1542
|
+
type: "array",
|
|
1543
|
+
itemNoun: "review",
|
|
1544
|
+
validation: { max: 3 },
|
|
1545
|
+
of: [{
|
|
1546
|
+
name: "review",
|
|
1547
|
+
title: "Review",
|
|
1548
|
+
type: "reference",
|
|
1549
|
+
reference: { to: ["col_testimonials"] }
|
|
1550
|
+
}]
|
|
1551
|
+
},
|
|
1552
|
+
{
|
|
1553
|
+
name: "button",
|
|
1554
|
+
title: "Button",
|
|
1555
|
+
type: "button"
|
|
1556
|
+
},
|
|
1557
|
+
{
|
|
1558
|
+
name: "useRichResults",
|
|
1559
|
+
title: "Send rating to search engines",
|
|
1560
|
+
type: "boolean",
|
|
1561
|
+
group: "data",
|
|
1562
|
+
hidden: {
|
|
1563
|
+
field: "subject",
|
|
1564
|
+
notEmpty: true
|
|
1565
|
+
},
|
|
1566
|
+
initialValue: true,
|
|
1567
|
+
description: "Shows the stars in search results."
|
|
1568
|
+
},
|
|
1569
|
+
{
|
|
1570
|
+
name: "starColor",
|
|
1571
|
+
title: "Star color",
|
|
1572
|
+
type: "select",
|
|
1573
|
+
group: "design",
|
|
1574
|
+
layout: "segmented",
|
|
1575
|
+
initialValue: "brand",
|
|
1576
|
+
options: [
|
|
1577
|
+
{
|
|
1578
|
+
value: "brand",
|
|
1579
|
+
label: "Brand"
|
|
1580
|
+
},
|
|
1581
|
+
{
|
|
1582
|
+
value: "gold",
|
|
1583
|
+
label: "Gold"
|
|
1584
|
+
},
|
|
1585
|
+
{
|
|
1586
|
+
value: "ink",
|
|
1587
|
+
label: "Ink"
|
|
1588
|
+
}
|
|
1589
|
+
]
|
|
1590
|
+
},
|
|
1591
|
+
theme
|
|
1592
|
+
]
|
|
1593
|
+
};
|
|
1594
|
+
var ENTRIES = [
|
|
1595
|
+
{
|
|
1596
|
+
id: "testimonial-grid",
|
|
1597
|
+
label: "Testimonial grid",
|
|
1598
|
+
proves: "References to a Testimonials collection · pick vs query (tags, limit, min rating) · uniqueness",
|
|
1599
|
+
category: "Social proof",
|
|
1600
|
+
tags: [
|
|
1601
|
+
"references",
|
|
1602
|
+
"dynamic-query",
|
|
1603
|
+
"conditional",
|
|
1604
|
+
"variants",
|
|
1605
|
+
"validation"
|
|
1606
|
+
],
|
|
1607
|
+
brand: "Caldera",
|
|
1608
|
+
previewLayout: "grid-3",
|
|
1609
|
+
schema: testimonialGrid,
|
|
1610
|
+
value: {
|
|
1611
|
+
_variant: "masonry",
|
|
1612
|
+
eyebrow: "Reviews",
|
|
1613
|
+
heading: "Cooked over, carried in, handed down.",
|
|
1614
|
+
source: "pick",
|
|
1615
|
+
testimonials: [
|
|
1616
|
+
"ts_maya",
|
|
1617
|
+
"ts_theo",
|
|
1618
|
+
"ts_amara"
|
|
1619
|
+
],
|
|
1620
|
+
tags: [],
|
|
1621
|
+
limit: 6,
|
|
1622
|
+
showRating: true,
|
|
1623
|
+
showPhotos: true,
|
|
1624
|
+
button: {
|
|
1625
|
+
label: "Read all 2,418 reviews",
|
|
1626
|
+
href: "/reviews",
|
|
1627
|
+
type: "page",
|
|
1628
|
+
title: "Reviews",
|
|
1629
|
+
style: "outline",
|
|
1630
|
+
arrow: true
|
|
1631
|
+
},
|
|
1632
|
+
theme: "light"
|
|
1633
|
+
},
|
|
1634
|
+
notes: {
|
|
1635
|
+
why: "Testimonials are REFERENCES to `col_testimonials` because the same quote appears on the home page, product pages and the reviews page, and each one carries facts that must not drift between copies: the customer's consent date, their exact words, rating, photo and the product they bought. The section only stores which ones and how many. A query mode (by tag, limit, minimum rating) keeps product pages fresh without hand-curation. Inline the quotes only for a one-off campaign page whose quotes appear nowhere else.",
|
|
1636
|
+
sanity: "`testimonialGrid` with `testimonials: array<reference to testimonial>` and validation `Rule.unique()`; the query variant in GROQ: `*[_type=='testimonial' && count((tags[])[@ in $tags]) > 0 && rating >= $min] | order(_createdAt desc)[0...$limit]`.",
|
|
1637
|
+
htmlSignals: [
|
|
1638
|
+
"A grid/masonry (`column-count`, `grid-auto-flow: dense`) of 3+ cards each with a quote, a person name, a role/company and often an avatar",
|
|
1639
|
+
"Star ratings (5 SVG stars, `aria-label=\"5 out of 5 stars\"`, ★ characters)",
|
|
1640
|
+
"`<blockquote>` + `<figcaption>`/`<cite>` per card",
|
|
1641
|
+
"Headings like “What customers say”, “Reviews”, “Loved by …”"
|
|
1642
|
+
],
|
|
1643
|
+
mcp: "For each card, create or match a `col_testimonials` entry: quote (strip surrounding quotation marks), name, role, company, photo, rating (count filled stars or parse aria-label), product if the card names one. Match existing entries by name + first 40 characters of the quote before creating. Store references in source `pick` in DOM order. Uniform card heights → grid; varying heights → masonry; one large first card → featured. Never import a testimonial without a name — flag it.",
|
|
1644
|
+
pitfalls: [
|
|
1645
|
+
"Inlining quotes creates copies that drift when the customer asks for an edit or removal — reference them.",
|
|
1646
|
+
"Grids look broken with 4 or 5 items in a 3-column layout; validation nudges multiples of 3.",
|
|
1647
|
+
"Do not emit Review JSON-LD for testimonials about your own business — Google ignores self-serving reviews."
|
|
1648
|
+
]
|
|
1649
|
+
}
|
|
1650
|
+
},
|
|
1651
|
+
{
|
|
1652
|
+
id: "testimonial-video-slider",
|
|
1653
|
+
label: "Video testimonial slider",
|
|
1654
|
+
proves: "Video vs quote slides via conditional fields · captions file required for a11y · transcript as rich text",
|
|
1655
|
+
category: "Social proof",
|
|
1656
|
+
tags: [
|
|
1657
|
+
"media-heavy",
|
|
1658
|
+
"a11y",
|
|
1659
|
+
"conditional",
|
|
1660
|
+
"repeater",
|
|
1661
|
+
"variants",
|
|
1662
|
+
"references",
|
|
1663
|
+
"validation"
|
|
1664
|
+
],
|
|
1665
|
+
brand: "Ledgerly",
|
|
1666
|
+
previewLayout: "carousel",
|
|
1667
|
+
schema: videoSlider,
|
|
1668
|
+
value: {
|
|
1669
|
+
_variant: "cards",
|
|
1670
|
+
eyebrow: "Customer stories",
|
|
1671
|
+
heading: "Hear it from the people closing their books on Fridays.",
|
|
1672
|
+
slides: [
|
|
1673
|
+
{
|
|
1674
|
+
_key: "v1",
|
|
1675
|
+
kind: "video",
|
|
1676
|
+
video: { url: "https://cdn.ledgerly.com/stories/masa-bakery.mp4" },
|
|
1677
|
+
poster: img("ledgerly-rosa-poster", "Rosa Delgado behind the counter at Masa Bakery", 900, 1200),
|
|
1678
|
+
captions: {
|
|
1679
|
+
name: "masa-bakery.en.vtt",
|
|
1680
|
+
size: 4820,
|
|
1681
|
+
url: "https://cdn.ledgerly.com/stories/masa-bakery.en.vtt"
|
|
1682
|
+
},
|
|
1683
|
+
transcript: "<p><strong>Rosa:</strong> I used to do the books on Sunday nights with a glass of wine and a lot of swearing. Now Ledgerly does most of it before I open on Monday.</p>",
|
|
1684
|
+
pullQuote: "We stopped paying our bookkeeper overtime in March.",
|
|
1685
|
+
duration: "1:12",
|
|
1686
|
+
person: {
|
|
1687
|
+
name: "Rosa Delgado",
|
|
1688
|
+
role: "Owner",
|
|
1689
|
+
company: "Masa Bakery",
|
|
1690
|
+
photo: avatar(32)
|
|
1691
|
+
},
|
|
1692
|
+
caseStudy: {
|
|
1693
|
+
type: "entry",
|
|
1694
|
+
href: "/customers/masa-bakery",
|
|
1695
|
+
label: "Read Masa's story",
|
|
1696
|
+
title: "Masa Bakery"
|
|
1697
|
+
}
|
|
1698
|
+
},
|
|
1699
|
+
{
|
|
1700
|
+
_key: "v2",
|
|
1701
|
+
kind: "video",
|
|
1702
|
+
video: { url: "https://vimeo.com/870112233" },
|
|
1703
|
+
poster: img("ledgerly-north-fork-poster", "Devon Park in the North Fork Builders workshop", 900, 1200),
|
|
1704
|
+
captions: {
|
|
1705
|
+
name: "north-fork.en.vtt",
|
|
1706
|
+
size: 6120,
|
|
1707
|
+
url: "https://cdn.ledgerly.com/stories/north-fork.en.vtt"
|
|
1708
|
+
},
|
|
1709
|
+
pullQuote: "Job costing used to be a spreadsheet only I understood.",
|
|
1710
|
+
duration: "1:38",
|
|
1711
|
+
person: {
|
|
1712
|
+
name: "Devon Park",
|
|
1713
|
+
role: "Operations lead",
|
|
1714
|
+
company: "North Fork Builders",
|
|
1715
|
+
photo: avatar(12)
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
{
|
|
1719
|
+
_key: "v3",
|
|
1720
|
+
kind: "quote",
|
|
1721
|
+
pullQuote: "Our accountant asked what changed. The answer was: everything is just already there.",
|
|
1722
|
+
person: {
|
|
1723
|
+
name: "Priya Shah",
|
|
1724
|
+
role: "Co-founder",
|
|
1725
|
+
company: "Loop & Thread",
|
|
1726
|
+
photo: avatar(45)
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
],
|
|
1730
|
+
autoplay: false,
|
|
1731
|
+
allowInlinePlay: false,
|
|
1732
|
+
theme: "dark"
|
|
1733
|
+
},
|
|
1734
|
+
notes: {
|
|
1735
|
+
why: "Slides are an array of objects with a `kind` select: video slides REQUIRE a poster and a captions file (WCAG 1.2.2 — and most people watch muted), quote slides hide all video fields. The person is a small inline object because video stories are often recorded for one campaign; an optional reference to the written testimonial links consent and rating back to the collection when it exists. The transcript is rich text so it can carry speaker labels and is indexable.",
|
|
1736
|
+
sanity: "array of `videoTestimonial` objects with `mux.video` or `url` + `file` (vtt) + `array<block>` transcript; `hidden` callbacks on `kind`.",
|
|
1737
|
+
htmlSignals: [
|
|
1738
|
+
"A carousel (`swiper`, `splide`, `embla`, `scroll-snap-type: x`) of tall cards with a play button over a portrait poster",
|
|
1739
|
+
"`<video>` with `<track kind=\"captions\" src=\"….vtt\">`, or YouTube/Vimeo iframes opened in a lightbox",
|
|
1740
|
+
"A short quote and a name/role/company under each video, sometimes a duration badge (“1:24”)",
|
|
1741
|
+
"“Read transcript” toggles or `<details>` blocks"
|
|
1742
|
+
],
|
|
1743
|
+
mcp: "Per slide: `<video><source>` / iframe src / `data-video-url` → video.url (normalize YouTube/Vimeo to canonical watch URLs); `poster=` or the card background → poster; `<track kind=captions|subtitles>` → captions (download the .vtt; if missing on a hosted MP4, flag the slide — do NOT publish without captions). Overlay quote → pullQuote, name/role/company → person. Duration badge → duration (m:ss). Slides with no video → kind quote. Transcript blocks → transcript (keep speaker names bold).",
|
|
1744
|
+
pitfalls: ["Hosted MP4s with no captions file fail accessibility — the converter must flag, not skip, them.", "Autoplaying a slider while a video plays is hostile; the renderer pauses advance once any video starts."]
|
|
1745
|
+
}
|
|
1746
|
+
},
|
|
1747
|
+
{
|
|
1748
|
+
id: "wall-of-love",
|
|
1749
|
+
label: "Wall of love",
|
|
1750
|
+
proves: "Polymorphic array (social post · store review · photo post) each with its own required source link and rights flag",
|
|
1751
|
+
category: "Social proof",
|
|
1752
|
+
tags: [
|
|
1753
|
+
"polymorphic-array",
|
|
1754
|
+
"repeater",
|
|
1755
|
+
"validation",
|
|
1756
|
+
"media-heavy",
|
|
1757
|
+
"a11y"
|
|
1758
|
+
],
|
|
1759
|
+
brand: "Caldera",
|
|
1760
|
+
previewLayout: "grid-3",
|
|
1761
|
+
schema: wallOfLove,
|
|
1762
|
+
value: {
|
|
1763
|
+
_variant: "masonry",
|
|
1764
|
+
eyebrow: "#cookedoncaldera",
|
|
1765
|
+
heading: "4,000 campfires and counting.",
|
|
1766
|
+
items: [
|
|
1767
|
+
{
|
|
1768
|
+
_key: "w1",
|
|
1769
|
+
_type: "socialPost",
|
|
1770
|
+
network: "x",
|
|
1771
|
+
name: "Maya Reyes",
|
|
1772
|
+
handle: "@mayaoutside",
|
|
1773
|
+
photo: {
|
|
1774
|
+
url: avatar(47),
|
|
1775
|
+
alt: "",
|
|
1776
|
+
name: "maya.jpg"
|
|
1777
|
+
},
|
|
1778
|
+
text: "Took the Cable Fold on a 6-day Wind River trip. Grilled trout every night, folded it flat every morning. Best thing in my pack and I've been guiding for 12 years.",
|
|
1779
|
+
date: "2026-07-22",
|
|
1780
|
+
url: "https://x.com/mayaoutside/status/1815500112233"
|
|
1781
|
+
},
|
|
1782
|
+
{
|
|
1783
|
+
_key: "w2",
|
|
1784
|
+
_type: "review",
|
|
1785
|
+
platform: "rei",
|
|
1786
|
+
rating: 5,
|
|
1787
|
+
title: "Heirloom quality",
|
|
1788
|
+
text: "Heavier than titanium, obviously, but nothing else sears like this over a fire. Seasoning held up to a week of eggs and bacon.",
|
|
1789
|
+
reviewer: "Jordan K.",
|
|
1790
|
+
isVerified: true,
|
|
1791
|
+
date: "2026-06-03",
|
|
1792
|
+
url: "https://www.rei.com/product/caldera-ridge-skillet#reviews"
|
|
1793
|
+
},
|
|
1794
|
+
{
|
|
1795
|
+
_key: "w3",
|
|
1796
|
+
_type: "photoPost",
|
|
1797
|
+
image: img("ugc-trail-kitchen", "A Dutch oven of chilli on a granite slab at sunset", 900, 1100),
|
|
1798
|
+
handle: "@trailkitchen",
|
|
1799
|
+
caption: "Chilli at 11,000 ft. The Ember came along for all 4 days.",
|
|
1800
|
+
hasRights: true,
|
|
1801
|
+
url: "https://www.instagram.com/p/C9xK2aLvT1m/"
|
|
1802
|
+
},
|
|
1803
|
+
{
|
|
1804
|
+
_key: "w4",
|
|
1805
|
+
_type: "review",
|
|
1806
|
+
platform: "site",
|
|
1807
|
+
rating: 4,
|
|
1808
|
+
title: "Great pan, read the care card",
|
|
1809
|
+
text: "Rusted a little after I left it wet overnight — my fault. Re-oiled it and it's been perfect since. Customer service sent a care kit for free.",
|
|
1810
|
+
reviewer: "Sam O.",
|
|
1811
|
+
isVerified: true,
|
|
1812
|
+
date: "2026-05-18"
|
|
1813
|
+
},
|
|
1814
|
+
{
|
|
1815
|
+
_key: "w5",
|
|
1816
|
+
_type: "socialPost",
|
|
1817
|
+
network: "bluesky",
|
|
1818
|
+
name: "Theo Lindqvist",
|
|
1819
|
+
handle: "@theohikes",
|
|
1820
|
+
photo: {
|
|
1821
|
+
url: avatar(68),
|
|
1822
|
+
alt: "",
|
|
1823
|
+
name: "theo.jpg"
|
|
1824
|
+
},
|
|
1825
|
+
text: "PCT update: still carrying the Trail Kettle at mile 1,900. Every other piece of gear has been replaced at least once.",
|
|
1826
|
+
date: "2026-08-30",
|
|
1827
|
+
url: "https://bsky.app/profile/theohikes.bsky.social/post/3l2kq7xyz"
|
|
1828
|
+
},
|
|
1829
|
+
{
|
|
1830
|
+
_key: "w6",
|
|
1831
|
+
_type: "review",
|
|
1832
|
+
platform: "google",
|
|
1833
|
+
rating: 5,
|
|
1834
|
+
text: "Toured the foundry in Bend — they let my kids pour sand into the moulds. Bought two skillets on the way out.",
|
|
1835
|
+
reviewer: "Lena W.",
|
|
1836
|
+
isVerified: false,
|
|
1837
|
+
date: "2026-04-11",
|
|
1838
|
+
url: "https://maps.google.com/?cid=1188223344556677"
|
|
1839
|
+
}
|
|
1840
|
+
],
|
|
1841
|
+
showSourceIcons: true,
|
|
1842
|
+
maxHeight: 900,
|
|
1843
|
+
theme: "light"
|
|
1844
|
+
},
|
|
1845
|
+
notes: {
|
|
1846
|
+
why: "A wall of love mixes DIFFERENT kinds of proof, so `items` is a POLYMORPHIC ARRAY: each kind (`socialPost`, `review`, `photoPost`) has its own required fields instead of one bloated object where half the fields don't apply. Every item stores a link to the ORIGINAL so the wall stays verifiable (and FTC-safe); reposted photos carry an explicit `hasRights` flag. Posts are inlined rather than referenced because they are snapshots of third-party content that only this wall shows; if the brand runs a UGC programme, move them into a `col_ugc` collection.",
|
|
1847
|
+
sanity: "`array` with `of: [{type:'socialPost'},{type:'storeReview'},{type:'photoPost'}]`; the item `_type` drives the Studio form and the frontend renderer — same pattern as ours.",
|
|
1848
|
+
htmlSignals: [
|
|
1849
|
+
"A masonry of cards that look like embedded tweets/posts (avatar, @handle, network logo, date) mixed with review cards (stars + reviewer) and photo tiles",
|
|
1850
|
+
"Embedded `blockquote.twitter-tweet`, `blockquote.instagram-media` or iframes from `platform.twitter.com`/`instagram.com`",
|
|
1851
|
+
"Columns animating vertically in opposite directions (`@keyframes` translateY loops)",
|
|
1852
|
+
"Headings like “Wall of love”, “#hashtag”, “Don't take our word for it”"
|
|
1853
|
+
],
|
|
1854
|
+
mcp: "Classify each card: has @handle + network icon/embed → socialPost (network from the icon/embed host); has stars + reviewer → review (platform from the logo or link host; default site); image-dominant with handle → photoPost. Copy text EXACTLY. Extract the permalink from embed `cite=`/`href` → url; if a socialPost/photoPost has no permalink, flag it (url is required). Set hasRights false on every imported photoPost and flag for the editor to confirm — never assume permission. Opposite-scrolling columns → marquee.",
|
|
1855
|
+
pitfalls: ["Third-party embed scripts (twitter widgets.js) slow the page and break when posts are deleted — store the content, link the original.", "Reposting customer photos without permission is a copyright problem; the required flag forces the question."]
|
|
1856
|
+
}
|
|
1857
|
+
},
|
|
1858
|
+
{
|
|
1859
|
+
id: "case-study-cards",
|
|
1860
|
+
label: "Case study cards",
|
|
1861
|
+
proves: "Array of objects wrapping a reference + per-card override · three ways to choose (pick, by industry, latest)",
|
|
1862
|
+
category: "Social proof",
|
|
1863
|
+
tags: [
|
|
1864
|
+
"references",
|
|
1865
|
+
"dynamic-query",
|
|
1866
|
+
"conditional",
|
|
1867
|
+
"variants"
|
|
1868
|
+
],
|
|
1869
|
+
brand: "Ledgerly",
|
|
1870
|
+
previewLayout: "grid-3",
|
|
1871
|
+
schema: caseStudyCards,
|
|
1872
|
+
value: {
|
|
1873
|
+
_variant: "cards",
|
|
1874
|
+
eyebrow: "Customers",
|
|
1875
|
+
heading: "Teams that got their Fridays back.",
|
|
1876
|
+
source: "pick",
|
|
1877
|
+
stories: [
|
|
1878
|
+
{
|
|
1879
|
+
_key: "k1",
|
|
1880
|
+
caseStudy: "cs_masa_bakery",
|
|
1881
|
+
metricOverride: "6 hours saved every month"
|
|
1882
|
+
},
|
|
1883
|
+
{
|
|
1884
|
+
_key: "k2",
|
|
1885
|
+
caseStudy: "cs_north_fork_builders"
|
|
1886
|
+
},
|
|
1887
|
+
{
|
|
1888
|
+
_key: "k3",
|
|
1889
|
+
caseStudy: "cs_loop_and_thread",
|
|
1890
|
+
metricOverride: "Paid 9 days sooner"
|
|
1891
|
+
}
|
|
1892
|
+
],
|
|
1893
|
+
industries: [],
|
|
1894
|
+
limit: 3,
|
|
1895
|
+
button: {
|
|
1896
|
+
label: "All customer stories",
|
|
1897
|
+
href: "/customers",
|
|
1898
|
+
type: "page",
|
|
1899
|
+
title: "Customers",
|
|
1900
|
+
style: "outline",
|
|
1901
|
+
arrow: true
|
|
1902
|
+
},
|
|
1903
|
+
showLogos: true,
|
|
1904
|
+
theme: "light"
|
|
1905
|
+
},
|
|
1906
|
+
notes: {
|
|
1907
|
+
why: "Case studies are full CMS items (/customers/masa-bakery) with their own logo, industry, hero metric and body, so the cards REFERENCE `col_case_studies` — card title, logo, image and URL all come from the entry. Each pick is wrapped in a small object so a page can override the headline metric for its audience (the pricing page wants “paid 9 days sooner”, the home page wants “6 hours saved”) without editing the story. Query modes (industry, latest) suit industry landing pages that should update when a new story ships.",
|
|
1908
|
+
sanity: "`caseStudyCards` with `stories: array<object{caseStudy: reference to caseStudy, metricOverride: string}>`, GROQ dereference `caseStudy->{title, logo, heroMetric, slug}`.",
|
|
1909
|
+
htmlSignals: [
|
|
1910
|
+
"Cards with a customer logo, a bold result metric (“3× faster”, “−40% cost”), a short summary and a “Read story” link to `/customers/…` or `/case-studies/…`",
|
|
1911
|
+
"An industry/segment label on each card",
|
|
1912
|
+
"Large cover photos of the customer's team or premises"
|
|
1913
|
+
],
|
|
1914
|
+
mcp: "For each card, follow its link: if the target is a case-study page, create/match a `col_case_studies` entry (title, slug from the URL, logo, industry, hero metric, cover image; the article body goes through the long-form converter). Reference it. If the card's visible metric differs from the story page's main metric, store it in metricOverride. When the cards are under an industry heading or filtered by `?industry=`, set source industry with that industry.",
|
|
1915
|
+
pitfalls: ["Copying the card title/logo into the section duplicates the story — reference it, override only what differs.", "`col_case_studies` must exist before import; create the collection first in the conversion plan."]
|
|
1916
|
+
}
|
|
1917
|
+
},
|
|
1918
|
+
{
|
|
1919
|
+
id: "logo-cloud",
|
|
1920
|
+
label: "Logo cloud",
|
|
1921
|
+
proves: "Grid array of tiny popover objects · required company name for a11y · marquee-only field hidden by variant",
|
|
1922
|
+
category: "Social proof",
|
|
1923
|
+
tags: [
|
|
1924
|
+
"repeater",
|
|
1925
|
+
"variants",
|
|
1926
|
+
"a11y",
|
|
1927
|
+
"validation",
|
|
1928
|
+
"conditional",
|
|
1929
|
+
"media-heavy"
|
|
1930
|
+
],
|
|
1931
|
+
brand: "Caldera",
|
|
1932
|
+
previewLayout: "logos",
|
|
1933
|
+
schema: logoCloud,
|
|
1934
|
+
value: {
|
|
1935
|
+
_variant: "marquee",
|
|
1936
|
+
heading: "Sold at independent outfitters and these retailers",
|
|
1937
|
+
logos: [
|
|
1938
|
+
{
|
|
1939
|
+
_key: "l1",
|
|
1940
|
+
name: "REI Co-op",
|
|
1941
|
+
logo: logo("rei.svg", "REI Co-op logo")
|
|
1942
|
+
},
|
|
1943
|
+
{
|
|
1944
|
+
_key: "l2",
|
|
1945
|
+
name: "Huckberry",
|
|
1946
|
+
logo: logo("huckberry.svg", "Huckberry logo")
|
|
1947
|
+
},
|
|
1948
|
+
{
|
|
1949
|
+
_key: "l3",
|
|
1950
|
+
name: "Backcountry",
|
|
1951
|
+
logo: logo("backcountry.svg", "Backcountry logo"),
|
|
1952
|
+
scale: 90
|
|
1953
|
+
},
|
|
1954
|
+
{
|
|
1955
|
+
_key: "l4",
|
|
1956
|
+
name: "Moosejaw",
|
|
1957
|
+
logo: logo("moosejaw.svg", "Moosejaw logo")
|
|
1958
|
+
},
|
|
1959
|
+
{
|
|
1960
|
+
_key: "l5",
|
|
1961
|
+
name: "Cabela's",
|
|
1962
|
+
logo: logo("cabelas.svg", "Cabela's logo"),
|
|
1963
|
+
scale: 110
|
|
1964
|
+
},
|
|
1965
|
+
{
|
|
1966
|
+
_key: "l6",
|
|
1967
|
+
name: "Williams Sonoma",
|
|
1968
|
+
logo: logo("williams-sonoma.svg", "Williams Sonoma logo"),
|
|
1969
|
+
scale: 85
|
|
1970
|
+
},
|
|
1971
|
+
{
|
|
1972
|
+
_key: "l7",
|
|
1973
|
+
name: "Food52",
|
|
1974
|
+
logo: logo("food52.svg", "Food52 logo")
|
|
1975
|
+
}
|
|
1976
|
+
],
|
|
1977
|
+
isGrayscale: true,
|
|
1978
|
+
speed: "slow",
|
|
1979
|
+
logoHeight: 32,
|
|
1980
|
+
theme: "light"
|
|
1981
|
+
},
|
|
1982
|
+
notes: {
|
|
1983
|
+
why: "Logos are an array of tiny objects edited in a POPOVER (name + file + optional link + optical size) and shown as a grid of tiles, because a logo cloud is managed visually. The company NAME is required and separate from the image's alt because it is what screen readers announce and what the marquee duplicates with `aria-hidden`. Grayscale, height and speed are design; speed only appears for the marquee variant. If the same logos appear on several pages (customers, retailers), promote them to a global block (synced) or a `col_customers` collection.",
|
|
1984
|
+
sanity: "`logoCloud` with `logos: array<object{name, logo, url}>` and `options.layout: 'grid'` on the array; Sanity can't hide a field by layout choice without a custom `hidden` callback reading the parent.",
|
|
1985
|
+
htmlSignals: [
|
|
1986
|
+
"A row/grid of 4–30 small `<img>`/`<svg>` logos with no other text except one label (“Trusted by…”, “As seen at”)",
|
|
1987
|
+
"CSS filters `isGrayscale(1)` / `opacity: .6` that reset on hover",
|
|
1988
|
+
"A duplicated track with `aria-hidden=\"true\"` and a `@keyframes` translateX animation (marquee)"
|
|
1989
|
+
],
|
|
1990
|
+
mcp: "Each logo → name from `alt`, `title`, `aria-label` or the file name (title-case it: `williams-sonoma.svg` → Williams Sonoma); logo = original file (prefer SVG source). Wrapping `<a>` → link. If the track is duplicated for the marquee, import ONE copy only. Detect grayscale from the CSS filter, logoHeight from the rendered height. Variant: animated track → marquee, bordered cells → grid, else row.",
|
|
1991
|
+
pitfalls: [
|
|
1992
|
+
"Marquees duplicate logos in the DOM — de-duplicate on import or you get every logo twice.",
|
|
1993
|
+
"Alt text like “logo” or empty alt on linked logos fails a11y; the required name fixes it.",
|
|
1994
|
+
"Conditions on `_variant` work today because the variant is stored on the block value — this is a schema-language gap worth making official."
|
|
1995
|
+
]
|
|
1996
|
+
}
|
|
1997
|
+
},
|
|
1998
|
+
{
|
|
1999
|
+
id: "press-mentions",
|
|
2000
|
+
label: "Press mentions",
|
|
2001
|
+
proves: "Quotes tied to a required source link · logo + quote + journalist per mention · rotator variant",
|
|
2002
|
+
category: "Social proof",
|
|
2003
|
+
tags: [
|
|
2004
|
+
"repeater",
|
|
2005
|
+
"validation",
|
|
2006
|
+
"variants",
|
|
2007
|
+
"media-heavy",
|
|
2008
|
+
"localized"
|
|
2009
|
+
],
|
|
2010
|
+
brand: "Caldera",
|
|
2011
|
+
previewLayout: "logos",
|
|
2012
|
+
schema: pressMentions,
|
|
2013
|
+
value: {
|
|
2014
|
+
_variant: "rotator",
|
|
2015
|
+
heading: "In the press",
|
|
2016
|
+
mentions: [
|
|
2017
|
+
{
|
|
2018
|
+
_key: "p1",
|
|
2019
|
+
outlet: "Trailhead Quarterly",
|
|
2020
|
+
logo: logo("trailhead-quarterly.svg", "Trailhead Quarterly logo"),
|
|
2021
|
+
quote: "The rare piece of camp gear you'll still own in thirty years.",
|
|
2022
|
+
article: {
|
|
2023
|
+
type: "url",
|
|
2024
|
+
href: "https://trailheadquarterly.com/gear/caldera-ridge-skillet-review",
|
|
2025
|
+
label: "Read the review",
|
|
2026
|
+
newTab: true
|
|
2027
|
+
},
|
|
2028
|
+
author: "Hannah Brooks",
|
|
2029
|
+
date: "2026-03-14",
|
|
2030
|
+
isFeatured: true
|
|
2031
|
+
},
|
|
2032
|
+
{
|
|
2033
|
+
_key: "p2",
|
|
2034
|
+
outlet: "The Gear Desk",
|
|
2035
|
+
logo: logo("the-gear-desk.svg", "The Gear Desk logo"),
|
|
2036
|
+
quote: "Folds flatter than a cutting board and grills like a backyard kettle.",
|
|
2037
|
+
article: {
|
|
2038
|
+
type: "url",
|
|
2039
|
+
href: "https://thegeardesk.com/best-camp-grills-2026",
|
|
2040
|
+
label: "Best camp grills of 2026",
|
|
2041
|
+
newTab: true
|
|
2042
|
+
},
|
|
2043
|
+
author: "Marcus Lee",
|
|
2044
|
+
date: "2026-05-02"
|
|
2045
|
+
},
|
|
2046
|
+
{
|
|
2047
|
+
_key: "p3",
|
|
2048
|
+
outlet: "Field Kitchen Review",
|
|
2049
|
+
logo: logo("field-kitchen-review.svg", "Field Kitchen Review logo"),
|
|
2050
|
+
quote: "Caldera is doing for cast iron what small-batch roasters did for coffee.",
|
|
2051
|
+
article: {
|
|
2052
|
+
type: "url",
|
|
2053
|
+
href: "https://fieldkitchenreview.com/caldera-foundry-visit",
|
|
2054
|
+
label: "A day at the foundry",
|
|
2055
|
+
newTab: true
|
|
2056
|
+
},
|
|
2057
|
+
date: "2025-11-20"
|
|
2058
|
+
},
|
|
2059
|
+
{
|
|
2060
|
+
_key: "p4",
|
|
2061
|
+
outlet: "Pacific Outdoor Journal",
|
|
2062
|
+
logo: logo("pacific-outdoor-journal.svg", "Pacific Outdoor Journal logo"),
|
|
2063
|
+
quote: "Our pick for the best Dutch oven for car camping.",
|
|
2064
|
+
article: {
|
|
2065
|
+
type: "url",
|
|
2066
|
+
href: "https://pacificoutdoorjournal.com/awards/2026",
|
|
2067
|
+
label: "2026 gear awards",
|
|
2068
|
+
newTab: true
|
|
2069
|
+
},
|
|
2070
|
+
author: "Jess Moreno",
|
|
2071
|
+
date: "2026-08-08"
|
|
2072
|
+
}
|
|
2073
|
+
],
|
|
2074
|
+
isGrayscale: true,
|
|
2075
|
+
theme: "light"
|
|
2076
|
+
},
|
|
2077
|
+
notes: {
|
|
2078
|
+
why: "Each mention is an object with the quote, outlet logo and a REQUIRED article link, because a press quote without its source is unverifiable and editors are tempted to paraphrase. Mentions are inlined (not a collection) on most sites because the press page is the only other place they appear; if the site has a /press page listing every article, create `col_press` and reference it instead. `isFeatured` lets the rotator start on the strongest quote.",
|
|
2079
|
+
sanity: "array of `pressMention` objects {outlet, logo, quote, url, author, date}; no structured data.",
|
|
2080
|
+
htmlSignals: [
|
|
2081
|
+
"Publication logos (often grayscale) paired with short italic quotes, each linking to an external article",
|
|
2082
|
+
"“As seen in”, “In the press”, “Featured in” labels",
|
|
2083
|
+
"Rotators where clicking a logo swaps the quote above it (`aria-selected`, `data-quote`)"
|
|
2084
|
+
],
|
|
2085
|
+
mcp: "Per mention: logo img → logo (keep the original file), `alt`/file name → outlet, quote text → quote (strip curly quotes), wrapping or nearby external link → article (type url, newTab true), byline → author, date text → date. Logos WITHOUT quotes are a logo cloud, not this block. Mark the first or visually largest quote as featured.",
|
|
2086
|
+
pitfalls: ["Never shorten a quote by paraphrasing — use an ellipsis and keep the source link.", "Outlet logos are trademarks; use the outlet's press-kit file and do not recolour it in content."]
|
|
2087
|
+
}
|
|
2088
|
+
},
|
|
2089
|
+
{
|
|
2090
|
+
id: "awards-certifications",
|
|
2091
|
+
label: "Awards & certifications",
|
|
2092
|
+
proves: "Kind select changes required fields (certificate id + expiry for certifications) · expiry hides stale badges",
|
|
2093
|
+
category: "Social proof",
|
|
2094
|
+
tags: [
|
|
2095
|
+
"conditional",
|
|
2096
|
+
"validation",
|
|
2097
|
+
"repeater",
|
|
2098
|
+
"seo-structured",
|
|
2099
|
+
"a11y"
|
|
2100
|
+
],
|
|
2101
|
+
brand: "Juniper Health",
|
|
2102
|
+
previewLayout: "logos",
|
|
2103
|
+
schema: awards,
|
|
2104
|
+
value: {
|
|
2105
|
+
_variant: "cards",
|
|
2106
|
+
eyebrow: "Trust",
|
|
2107
|
+
heading: "Your health data, held to the highest standard.",
|
|
2108
|
+
badges: [
|
|
2109
|
+
{
|
|
2110
|
+
_key: "b1",
|
|
2111
|
+
kind: "certification",
|
|
2112
|
+
name: "SOC 2 Type II",
|
|
2113
|
+
issuer: "AICPA (audited by Prescient Assurance)",
|
|
2114
|
+
image: logo("soc2-type2.svg", "SOC 2 Type II badge", 120, 120),
|
|
2115
|
+
certificateId: "",
|
|
2116
|
+
validUntil: "2027-03-31",
|
|
2117
|
+
verify: {
|
|
2118
|
+
type: "url",
|
|
2119
|
+
href: "https://trust.junipercare.com",
|
|
2120
|
+
label: "Trust centre",
|
|
2121
|
+
newTab: true
|
|
2122
|
+
}
|
|
2123
|
+
},
|
|
2124
|
+
{
|
|
2125
|
+
_key: "b2",
|
|
2126
|
+
kind: "certification",
|
|
2127
|
+
name: "HITRUST CSF r2",
|
|
2128
|
+
issuer: "HITRUST Alliance",
|
|
2129
|
+
image: logo("hitrust-r2.svg", "HITRUST CSF r2 badge", 120, 120),
|
|
2130
|
+
certificateId: "HT-2025-118842",
|
|
2131
|
+
validUntil: "2027-01-15",
|
|
2132
|
+
verify: {
|
|
2133
|
+
type: "url",
|
|
2134
|
+
href: "https://hitrustalliance.net/validated-assessment-registry",
|
|
2135
|
+
label: "Validated registry",
|
|
2136
|
+
newTab: true
|
|
2137
|
+
}
|
|
2138
|
+
},
|
|
2139
|
+
{
|
|
2140
|
+
_key: "b3",
|
|
2141
|
+
kind: "certification",
|
|
2142
|
+
name: "ISO/IEC 27001:2022",
|
|
2143
|
+
issuer: "BSI",
|
|
2144
|
+
image: logo("iso-27001.svg", "ISO/IEC 27001:2022 badge", 120, 120),
|
|
2145
|
+
certificateId: "IS 781204",
|
|
2146
|
+
validUntil: "2028-06-30",
|
|
2147
|
+
verify: {
|
|
2148
|
+
type: "url",
|
|
2149
|
+
href: "https://www.bsigroup.com/en-US/validate-bsi-issued-certificates/",
|
|
2150
|
+
label: "Validate with BSI",
|
|
2151
|
+
newTab: true
|
|
2152
|
+
}
|
|
2153
|
+
},
|
|
2154
|
+
{
|
|
2155
|
+
_key: "b4",
|
|
2156
|
+
kind: "award",
|
|
2157
|
+
name: "Best Virtual Care Experience 2026",
|
|
2158
|
+
issuer: "Digital Health Awards",
|
|
2159
|
+
image: logo("dha-2026.svg", "Best Virtual Care Experience 2026 badge", 120, 120),
|
|
2160
|
+
year: 2026
|
|
2161
|
+
}
|
|
2162
|
+
],
|
|
2163
|
+
note: "Our SOC 2 report is available under NDA. HIPAA has no official certification — we sign a BAA with every covered entity.",
|
|
2164
|
+
button: {
|
|
2165
|
+
label: "Visit our trust centre",
|
|
2166
|
+
href: "https://trust.junipercare.com",
|
|
2167
|
+
type: "url",
|
|
2168
|
+
style: "outline",
|
|
2169
|
+
newTab: true
|
|
2170
|
+
},
|
|
2171
|
+
isGrayscale: false,
|
|
2172
|
+
theme: "light"
|
|
2173
|
+
},
|
|
2174
|
+
notes: {
|
|
2175
|
+
why: "Badges are an array of objects with a `kind` that changes what is REQUIRED: a certification needs an expiry (`validUntil`) and ideally a certificate number and verify link; an award needs a year. The renderer hides an expired certification automatically, which is the bug this entry exists to catch — sites routinely show lapsed badges for years. Badge images stay untouched (issuers have usage rules). If the brand has a trust center with the same badges, this should be a global block (synced) so a renewal updates every page.",
|
|
2176
|
+
sanity: "array of `badge` objects with a `kind` string and `hidden`/`validation` callbacks on `validUntil`; Sanity would need a custom input or a scheduled job to hide expired badges.",
|
|
2177
|
+
htmlSignals: [
|
|
2178
|
+
"A row of square/circular badge images (SOC 2, ISO, HIPAA, PCI, awards) with small captions",
|
|
2179
|
+
"Links to trust centres (`trust.`, `security.` subdomains), Vanta/Drata/SafeBase pages or certification registries",
|
|
2180
|
+
"Text like “Certified”, “Compliant”, “Award winner”, “Best of 2026”"
|
|
2181
|
+
],
|
|
2182
|
+
mcp: "Per badge: image → image, alt/caption → name; classify: SOC, ISO, HITRUST, PCI, FedRAMP, GDPR-seal → certification; “award”, “best”, “winner”, year-bearing titles → award; association logos → membership. Linked registry/trust pages → verify. For certifications with no expiry in the source, set validUntil to one year from the import date and FLAG it for confirmation. If the source says “HIPAA certified”, flag the claim — there is no official HIPAA certification.",
|
|
2183
|
+
pitfalls: [
|
|
2184
|
+
"Expired certifications shown as current are a compliance risk — `validUntil` is required on certifications for that reason.",
|
|
2185
|
+
"“HIPAA certified” and “GDPR certified” badges are marketing inventions; the converter flags them.",
|
|
2186
|
+
"Organization JSON-LD `award` should only list awards, never certifications."
|
|
2187
|
+
]
|
|
2188
|
+
}
|
|
2189
|
+
},
|
|
2190
|
+
{
|
|
2191
|
+
id: "review-summary",
|
|
2192
|
+
label: "Review summary",
|
|
2193
|
+
proves: "Synced vs typed ratings (developer-locked provider) · 5-bucket distribution validation · AggregateRating only with a product subject",
|
|
2194
|
+
category: "Social proof",
|
|
2195
|
+
tags: [
|
|
2196
|
+
"seo-structured",
|
|
2197
|
+
"references",
|
|
2198
|
+
"conditional",
|
|
2199
|
+
"validation",
|
|
2200
|
+
"a11y",
|
|
2201
|
+
"commerce"
|
|
2202
|
+
],
|
|
2203
|
+
brand: "Caldera",
|
|
2204
|
+
previewLayout: "split",
|
|
2205
|
+
schema: reviewSummary,
|
|
2206
|
+
value: {
|
|
2207
|
+
_variant: "split",
|
|
2208
|
+
heading: "What cooks are saying",
|
|
2209
|
+
subject: "gid://shopify/Product/8813",
|
|
2210
|
+
dataSource: "connected",
|
|
2211
|
+
provider: "judgeme",
|
|
2212
|
+
average: 4.8,
|
|
2213
|
+
count: 2418,
|
|
2214
|
+
ratingCounts: [
|
|
2215
|
+
{
|
|
2216
|
+
_key: "d5",
|
|
2217
|
+
stars: 5,
|
|
2218
|
+
count: 2031
|
|
2219
|
+
},
|
|
2220
|
+
{
|
|
2221
|
+
_key: "d4",
|
|
2222
|
+
stars: 4,
|
|
2223
|
+
count: 290
|
|
2224
|
+
},
|
|
2225
|
+
{
|
|
2226
|
+
_key: "d3",
|
|
2227
|
+
stars: 3,
|
|
2228
|
+
count: 58
|
|
2229
|
+
},
|
|
2230
|
+
{
|
|
2231
|
+
_key: "d2",
|
|
2232
|
+
stars: 2,
|
|
2233
|
+
count: 22
|
|
2234
|
+
},
|
|
2235
|
+
{
|
|
2236
|
+
_key: "d1",
|
|
2237
|
+
stars: 1,
|
|
2238
|
+
count: 17
|
|
2239
|
+
}
|
|
2240
|
+
],
|
|
2241
|
+
platforms: [{
|
|
2242
|
+
_key: "pl1",
|
|
2243
|
+
name: "rei",
|
|
2244
|
+
rating: 4.7,
|
|
2245
|
+
count: 612,
|
|
2246
|
+
profile: {
|
|
2247
|
+
type: "url",
|
|
2248
|
+
href: "https://www.rei.com/product/caldera-ember-dutch-oven",
|
|
2249
|
+
label: "REI reviews",
|
|
2250
|
+
newTab: true
|
|
2251
|
+
}
|
|
2252
|
+
}, {
|
|
2253
|
+
_key: "pl2",
|
|
2254
|
+
name: "amazon",
|
|
2255
|
+
rating: 4.6,
|
|
2256
|
+
count: 1290,
|
|
2257
|
+
profile: {
|
|
2258
|
+
type: "url",
|
|
2259
|
+
href: "https://www.amazon.com/dp/B0CALDERA55",
|
|
2260
|
+
label: "Amazon reviews",
|
|
2261
|
+
newTab: true
|
|
2262
|
+
}
|
|
2263
|
+
}],
|
|
2264
|
+
featuredReviews: ["ts_amara", "ts_maya"],
|
|
2265
|
+
button: {
|
|
2266
|
+
label: "Read all 2,418 reviews",
|
|
2267
|
+
href: "/products/ember-dutch-oven#reviews",
|
|
2268
|
+
type: "entry",
|
|
2269
|
+
title: "Ember Dutch Oven",
|
|
2270
|
+
style: "outline"
|
|
2271
|
+
},
|
|
2272
|
+
useRichResults: true,
|
|
2273
|
+
starColor: "brand",
|
|
2274
|
+
theme: "light"
|
|
2275
|
+
},
|
|
2276
|
+
notes: {
|
|
2277
|
+
why: "Ratings are DATA, not copy: when a review app is connected the average, count and distribution are synced (the provider is developer-locked) and editors only choose presentation; manual mode exists for sources that can't sync. The distribution is exactly five buckets (validation min=max=5) so bars always render 5→1. The block references its SUBJECT product because AggregateRating structured data is only valid for a specific product/service, and must match what is visible — so JSON-LD is emitted only when a subject is set (the toggle is hidden otherwise). Featured reviews reference the testimonials collection.",
|
|
2278
|
+
sanity: "`reviewSummary` with `subject: reference to product`, numbers as `number` fields with `Rule.min(1).max(5).precision(1)`; synced data typically lives outside Sanity and is fetched at render time.",
|
|
2279
|
+
htmlSignals: [
|
|
2280
|
+
"A big average number (“4.8”) next to stars and “Based on 2,418 reviews”",
|
|
2281
|
+
"Five horizontal bars labeled 5★…1★ with counts or percentages (`<progress>`, `<meter>`, width-% divs)",
|
|
2282
|
+
"Review-app markup: `jdgm-`, `okendo-`, `yotpo-`, `trustpilot-widget` classes or their script tags",
|
|
2283
|
+
"`application/ld+json` with `AggregateRating` / `ratingValue` / `reviewCount`"
|
|
2284
|
+
],
|
|
2285
|
+
mcp: "Detect the review app from class prefixes/scripts → dataSource connected + provider (and tell the developer to connect it); otherwise manual. Read average/count from JSON-LD first (most reliable), then visible text. Bars → ratingCounts: parse each bar's count; if only percentages are shown, compute counts from the total and round so they sum to it. Badges for other platforms → platforms with their profile links. The product the page is about → subject. Never emit AggregateRating for store-wide/self-serving ratings.",
|
|
2286
|
+
pitfalls: [
|
|
2287
|
+
"AggregateRating on a home page about your own business is ignored or penalised — only with a product subject.",
|
|
2288
|
+
"Typed-in ratings drift from the real ones; prefer the connected source and show “Synced …” in the UI.",
|
|
2289
|
+
"Distribution counts that don't sum to the total look fake; validate the sum."
|
|
2290
|
+
]
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
];
|
|
2294
|
+
//#endregion
|
|
2295
|
+
export { ENTRIES };
|
|
2296
|
+
|
|
2297
|
+
//# sourceMappingURL=social-proof.entries.js.map
|