From e7d67e84e9673f916c2da72996d985053c8c0eae Mon Sep 17 00:00:00 2001 From: Daniel Lautzenheiser Date: Wed, 21 Dec 2022 14:38:26 -0500 Subject: [PATCH] Demo setup (#266) --- packages/app/webpack.config.js | 14 +- packages/demo/config.yml | 1162 ++++++++++++++++++++++++++++++++ packages/demo/example.css | 21 + packages/demo/index.html | 248 +++++++ packages/demo/index.js | 173 +++++ yarn.lock | 30 +- 6 files changed, 1622 insertions(+), 26 deletions(-) create mode 100644 packages/demo/config.yml create mode 100644 packages/demo/example.css create mode 100644 packages/demo/index.html create mode 100644 packages/demo/index.js diff --git a/packages/app/webpack.config.js b/packages/app/webpack.config.js index 03aa4296..0eadba40 100644 --- a/packages/app/webpack.config.js +++ b/packages/app/webpack.config.js @@ -94,18 +94,10 @@ module.exports = { ].filter(Boolean), output: { path: path.resolve(__dirname, 'dist'), - filename: 'static-cms-core.js', + filename: 'static-cms-app.js', library: { - name: 'StaticCmsCore', + name: 'StaticCmsApp', type: 'umd', }, - }, - devServer: { - static: { - directory: './dev-test', - }, - host: '0.0.0.0', - port: devServerPort, - hot: true, - }, + } }; diff --git a/packages/demo/config.yml b/packages/demo/config.yml new file mode 100644 index 00000000..58e214ad --- /dev/null +++ b/packages/demo/config.yml @@ -0,0 +1,1162 @@ +backend: + name: demo-repo +site_url: 'https://staticjscms.netlify.app/' +media_folder: assets/uploads +locale: en +collections: + - name: posts + label: Posts + label_singular: Post + description: > + The description is a great place for tone setting, high level information, + and editing guidelines that are specific to a collection. + folder: _posts + slug: '{{year}}-{{month}}-{{day}}-{{slug}}' + summary: '{{title}} -- {{year}}/{{month}}/{{day}}' + sortable_fields: + fields: + - title + - date + default: + field: title + create: true + view_filters: + - label: Posts With Index + field: title + pattern: 'This is post #' + - label: Posts Without Index + field: title + pattern: front matter post + - label: Drafts + field: draft + pattern: true + view_groups: + - label: Year + field: date + pattern: '\d{4}' + - label: Drafts + field: draft + fields: + - label: Title + name: title + widget: string + - label: Draft + name: draft + widget: boolean + default: false + - label: Publish Date + name: date + widget: datetime + date_format: yyyy-MM-dd + time_format: 'HH:mm' + format: "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" + - label: Cover Image + name: image + widget: image + required: false + - label: Body + name: body + widget: markdown + hint: Main content goes here. + - name: faq + label: FAQ + folder: _faqs + create: true + editor: + frame: false + fields: + - label: Question + name: title + widget: string + - label: Answer + name: body + widget: markdown + - name: posts + label: Posts + label_singular: Post + widget: list + summary: "{{fields.post | split('|', '$1')}}" + fields: + - label: Related Post + name: post + widget: relationKitchenSinkPost + collection: posts + display_fields: + - title + - date + search_fields: + - title + - body + value_field: '{{title}}|{{date}}' + - name: widgets + label: Widgets + delete: false + files: + - name: boolean + label: Boolean + file: _widgets/boolean.json + description: Boolean widget + fields: + - name: required + label: Required Validation + widget: boolean + - name: with_default + label: Required With Default + widget: boolean + default: true + - name: pattern + label: Pattern Validation + widget: boolean + pattern: ['true', 'Must be true'] + required: false + - name: code + label: Code + file: _widgets/code.json + description: Code widget + fields: + - name: required + label: Required Validation + widget: code + - name: with_default + label: Required With Default + widget: code + default: '
Some html!
' + - name: pattern + label: Pattern Validation + widget: code + pattern: ['.{12,}', 'Must have at least 12 characters'] + allow_input: true + required: false + - name: language + label: Language Selection + widget: code + allow_language_selection: true + required: false + - name: language_with_default + label: Language Selection With Default Language + widget: code + allow_language_selection: true + required: false + default_language: html + - name: language_with_default_language_and_value + label: Language Selection With Default Language and Value + widget: code + allow_language_selection: true + required: false + default: + lang: html + code: '
Some html!
' + - name: language_with_default_language_and_value_string_default + label: Language Selection With Default Language and Value (String Default) + widget: code + allow_language_selection: true + required: false + default_language: html + default: '
Some html!
' + - name: color + label: Color + file: _widgets/color.json + description: Color widget + fields: + - name: required + label: Required Validation + widget: color + - name: with_default + label: Required With Default + widget: color + default: '#2121c5' + - name: pattern + label: Pattern Validation + widget: color + pattern: ['^#([0-9a-fA-F]{3})(?:[0-9a-fA-F]{3})?$', 'Must be a valid hex code'] + allow_input: true + required: false + - name: alpha + label: Alpha + widget: color + enable_alpha: true + required: false + - name: alpha_with_default + label: Alpha With Default + widget: color + enable_alpha: true + required: false + default: 'rgba(175, 28, 28, 0.65)' + - name: datetime + label: DateTime + file: _widgets/datetime.json + description: DateTime widget + fields: + - name: required + label: 'Required Validation' + widget: datetime + - name: pattern + label: 'Pattern Validation' + widget: datetime + format: 'MMM d, yyyy h:mm aaa' + date_format: 'MMM d, yyyy' + time_format: 'h:mm aaa' + pattern: ['pm', 'Must be in the afternoon'] + required: false + - name: date_and_time + label: Date and Time + widget: datetime + format: 'MMM d, yyyy h:mm aaa' + date_format: 'MMM d, yyyy' + time_format: 'h:mm aaa' + required: false + - name: date_and_time_with_default + label: Date and Time With Deafult + widget: datetime + format: 'MMM d, yyyy h:mm aaa' + date_format: 'MMM d, yyyy' + time_format: 'h:mm aaa' + required: false + default: 'Jan 12, 2023 12:00 am' + - name: date + label: Date + widget: datetime + format: 'MMM d, yyyy' + date_format: 'MMM d, yyyy' + required: false + - name: date_with_default + label: Date With Deafult + widget: datetime + format: 'MMM d, yyyy' + date_format: 'MMM d, yyyy' + required: false + default: 'Jan 12, 2023' + - name: time + label: Time + widget: datetime + format: 'h:mm aaa' + time_format: 'h:mm aaa' + required: false + - name: time_with_default + label: Time With Deafult + widget: datetime + format: 'h:mm aaa' + time_format: 'h:mm aaa' + required: false + default: '12:00 am' + - name: file + label: File + file: _widgets/file.json + description: File widget + fields: + - name: required + label: Required Validation + widget: file + - name: with_default + label: Required With Default + widget: file + default: /assets/uploads/moby-dick.jpg + - name: pattern + label: Pattern Validation + widget: file + pattern: ['\.pdf', 'Must be a pdf'] + required: false + - name: choose_url + label: Choose URL + widget: file + required: false + media_library: + choose_url: true + - name: image + label: Image + file: _widgets/image.json + description: Image widget + fields: + - name: required + label: Required Validation + widget: image + - name: with_default + label: Required With Default + widget: image + default: /assets/uploads/moby-dick.jpg + - name: pattern + label: Pattern Validation + widget: image + pattern: ['\.png', 'Must be a png'] + required: false + - name: choose_url + label: Choose URL + widget: image + required: false + media_library: + choose_url: true + - name: list + label: List + file: _widgets/list.yml + description: List widget + fields: + - name: list + label: Required List + widget: list + fields: + - label: Name + name: name + widget: string + hint: First and Last + - label: Description + name: description + widget: text + - name: with_default + label: Required With Default + widget: list + default: + - name: Bob Billy + description: Some text about bob + fields: + - label: Name + name: name + widget: string + hint: First and Last + - label: Description + name: description + widget: text + - name: optional + label: Optional List + widget: list + required: false + fields: + - label: Name + name: name + widget: string + hint: First and Last + - label: Description + name: description + widget: text + - name: typed_list + label: Typed List + widget: list + types: + - label: Type 1 Object + name: type_1_object + widget: object + fields: + - label: String + name: string + widget: string + - label: Boolean + name: boolean + widget: boolean + - label: Text + name: text + widget: text + - label: Type 2 Object + name: type_2_object + widget: object + fields: + - label: Number + name: number + widget: number + - label: Select + name: select + widget: select + options: + - a + - b + - c + - label: Datetime + name: datetime + widget: datetime + - label: Markdown + name: markdown + widget: markdown + - label: Type 3 Object + name: type_3_object + widget: object + fields: + - label: Image + name: image + widget: image + - label: File + name: file + widget: file + - name: typed_list_with_default + label: Typed List With Default + widget: list + default: + - type: type_2_object + number: 5 + select: c + datetime: '2022-12-05T20:22:52+0000' + markdown: Some ***Markdown*** ~content~ text + types: + - label: Type 1 Object + name: type_1_object + widget: object + fields: + - label: String + name: string + widget: string + - label: Boolean + name: boolean + widget: boolean + - label: Text + name: text + widget: text + - label: Type 2 Object + name: type_2_object + widget: object + fields: + - label: Number + name: number + widget: number + - label: Select + name: select + widget: select + options: + - a + - b + - c + - label: Datetime + name: datetime + widget: datetime + - label: Markdown + name: markdown + widget: markdown + - label: Type 3 Object + name: type_3_object + widget: object + fields: + - label: Image + name: image + widget: image + - label: File + name: file + widget: file + - name: map + label: Map + file: _widgets/map.json + description: Map widget + fields: + - name: required + label: Required Validation + widget: map + - name: with_default + label: Required With Default + widget: map + default: '{ "type": "Point", "coordinates": [-73.9852661, 40.7478738] }' + - name: pattern + label: Pattern Validation + widget: map + pattern: ['\[-([7-9][0-9]|1[0-2][0-9])\.', 'Must be between latitude -70 and -129'] + required: false + - name: markdown + label: Markdown + file: _widgets/markdown.json + description: Markdown widget + fields: + - name: required + label: Required Validation + widget: markdown + - name: with_default + label: Required With Default + widget: markdown + default: Default **markdown** value + - name: pattern + label: Pattern Validation + widget: markdown + pattern: ['# [a-zA-Z0-9]+', 'Must have a header'] + required: false + - name: number + label: Number + file: _widgets/number.json + description: Number widget + fields: + - name: required + label: Required Validation + widget: number + - name: with_default + label: Required With Default + widget: number + default: 5 + - name: min + label: Min Validation + widget: number + min: 5 + required: false + - name: max + label: Max Validation + widget: number + max: 10 + required: false + - name: min_and_max + label: Min and Max Validation + widget: number + min: 5 + max: 10 + required: false + - name: pattern + label: Pattern Validation + widget: number + pattern: ['[0-9]{3,}', 'Must be at least 3 digits'] + required: false + - name: object + label: Object + file: _widgets/object.json + description: Object widget + fields: + - label: Required Validation + name: required + widget: object + fields: + - label: Number of posts on frontpage + name: front_limit + widget: number + - label: Author + name: author + widget: string + - label: Thumbnail + name: thumb + widget: image + - label: Required With Defaults + name: with_defaults + widget: object + fields: + - label: Number of posts on frontpage + name: front_limit + widget: number + default: 5 + - label: Author + name: author + widget: string + default: Bob + - label: Thumbnail + name: thumb + widget: image + default: /assets/uploads/moby-dick.jpg + - label: Optional Validation + name: optional + widget: object + required: false + fields: + - label: Number of posts on frontpage + name: front_limit + widget: number + required: false + - label: Author + name: author + widget: string + required: false + - label: Thumbnail + name: thumb + widget: image + required: false + - label: With Hidden Field + name: hidden_field + widget: object + required: false + fields: + - name: layout + widget: hidden + default: post + - label: Number of posts on frontpage + name: front_limit + widget: number + required: false + - label: Author + name: author + widget: string + required: false + - label: Thumbnail + name: thumb + widget: image + required: false + - name: relation + label: Relation + file: _widgets/relation.json + description: Relation widget + fields: + - label: Required Validation + name: required + widget: relation + collection: posts + display_fields: + - title + - date + search_fields: + - title + - body + value_field: title + - label: Required With Default + name: with_default + widget: relation + collection: posts + display_fields: + - title + - date + search_fields: + - title + - body + value_field: title + default: This is a YAML front matter post + - label: Optional Validation + name: optional + widget: relation + required: false + collection: posts + display_fields: + - title + - date + search_fields: + - title + - body + value_field: title + - label: Multiple + name: multiple + widget: relation + multiple: true + required: false + collection: posts + display_fields: + - title + - date + search_fields: + - title + - body + value_field: title + - label: Multiple With Default + name: multiple_with_default + widget: relation + multiple: true + required: false + collection: posts + default: + - This is a JSON front matter post + - This is a YAML front matter post + display_fields: + - title + - date + search_fields: + - title + - body + value_field: title + - name: select + label: Select + file: _widgets/select.json + description: Select widget + fields: + - label: Required Validation + name: required + widget: select + options: + - a + - b + - c + - label: Required With Default + name: with_default + widget: select + default: b + options: + - a + - b + - c + - label: Pattern Validation + name: pattern + widget: select + options: + - a + - b + - c + pattern: ['[a-b]', 'Must be a or b'] + required: false + - label: Number Value + name: number + widget: select + options: + - 1 + - 2 + - 3 + - label: Number With Default + name: number_with_default + widget: select + default: 3 + options: + - 1 + - 2 + - 3 + - label: Value and Label + name: value_and_label + widget: select + options: + - value: a + label: A fancy label + - value: 2 + label: Another fancy label + - value: c + label: And one more fancy label + - label: Value and Label With Default + name: value_and_label_with_default + widget: select + default: 2 + options: + - value: a + label: A fancy label + - value: 2 + label: Another fancy label + - value: c + label: And one more fancy label + - label: Multiple + name: multiple + widget: select + options: + - a + - b + - c + pattern: ['[a-b]', 'Must be a or b'] + multiple: true + required: false + - label: Multiple With Default + name: multiple_with_default + widget: select + default: + - b + - c + options: + - a + - b + - c + pattern: ['[a-b]', 'Must be a or b'] + multiple: true + required: false + - label: Value and Label Multiple + name: value_and_label_multiple + widget: select + multiple: true + options: + - value: a + label: A fancy label + - value: b + label: Another fancy label + - value: c + label: And one more fancy label + - name: string + label: String + file: _widgets/string.json + description: String widget + fields: + - name: required + label: Required Validation + widget: string + - name: with_default + label: Required With Default + widget: string + default: Default value + - name: pattern + label: Pattern Validation + widget: string + pattern: ['.{12,}', 'Must have at least 12 characters'] + required: false + - name: text + label: Text + file: _widgets/text.json + description: Text widget + fields: + - name: required + label: 'Required Validation' + widget: text + - name: with_default + label: Required With Default + widget: text + default: Default value + - name: pattern + label: 'Pattern Validation' + widget: text + pattern: ['.{12,}', 'Must have at least 12 characters'] + required: false + - name: settings + label: Settings + delete: false + editor: + preview: false + files: + - name: general + label: Site Settings + file: _data/settings.json + description: General Site Settings + editor: + preview: true + fields: + - label: Number of posts on frontpage + name: front_limit + widget: number + min: 1 + max: 10 + - label: Global title + name: site_title + widget: string + - label: Post Settings + name: posts + widget: object + fields: + - label: Number of posts on frontpage + name: front_limit + widget: number + min: 1 + max: 10 + - label: Default Author + name: author + widget: string + - label: Default Thumbnail + name: thumb + widget: image + required: false + - name: authors + label: Authors + file: _data/authors.yml + description: Author descriptions + editor: + preview: true + fields: + - name: authors + label: Authors + label_singular: Author + widget: list + fields: + - label: Name + name: name + widget: string + hint: First and Last + - label: Description + name: description + widget: text + - name: kitchenSink + label: Kitchen Sink + folder: _sink + create: true + fields: + - label: Related Post + name: post + widget: relationKitchenSinkPost + collection: posts + display_fields: + - title + - date + search_fields: + - title + - body + value_field: title + - label: Title + name: title + widget: string + - label: Boolean + name: boolean + widget: boolean + default: true + - label: Map + name: map + widget: map + - label: Text + name: text + widget: text + hint: 'Plain text, not markdown' + - label: Number + name: number + widget: number + hint: To infinity and beyond! + - label: Markdown + name: markdown + widget: markdown + - label: Datetime + name: datetime + widget: datetime + - label: Color + name: color + widget: color + - label: Color string editable and alpha enabled + name: colorEditable + widget: color + enable_alpha: true + allow_input: true + - label: Image + name: image + widget: image + - label: File + name: file + widget: file + - label: Select + name: select + widget: select + options: + - a + - b + - c + - label: Select multiple + name: select_multiple + widget: select + options: + - a + - b + - c + multiple: true + - label: Select numeric + name: select_numeric + widget: select + options: + - label: One + value: 1 + - label: Two + value: 2 + - label: Three + value: 3 + - label: Select mixed string and numeric + name: select_mixed_string_numeric + widget: select + options: + - label: One + value: 'One' + - label: Two + value: 2 + - label: Three + value: 3 + - label: Hidden + name: hidden + widget: hidden + default: hidden + - label: Object + name: object + widget: object + collapsed: true + fields: + - label: Related Post + name: post + widget: relationKitchenSinkPost + collection: posts + search_fields: + - title + - body + value_field: title + - label: String + name: string + widget: string + - label: Boolean + name: boolean + widget: boolean + default: false + - label: Text + name: text + widget: text + - label: Number + name: number + widget: number + - label: Markdown + name: markdown + widget: markdown + - label: Datetime + name: datetime + widget: datetime + - label: Image + name: image + widget: image + - label: File + name: file + widget: file + - label: Select + name: select + widget: select + options: + - a + - b + - c + - label: List + name: list + widget: list + fields: + - label: String + name: string + widget: string + - label: Boolean + name: boolean + widget: boolean + - label: Text + name: text + widget: text + - label: Number + name: number + widget: number + - label: Markdown + name: markdown + widget: markdown + - label: Datetime + name: datetime + widget: datetime + - label: Image + name: image + widget: image + - label: File + name: file + widget: file + - label: Select + name: select + widget: select + options: + - a + - b + - c + - label: Object + name: object + widget: object + fields: + - label: String + name: string + widget: string + - label: Boolean + name: boolean + widget: boolean + - label: Text + name: text + widget: text + - label: Number + name: number + widget: number + - label: Markdown + name: markdown + widget: markdown + - label: Datetime + name: datetime + widget: datetime + - label: Image + name: image + widget: image + - label: File + name: file + widget: file + - label: Select + name: select + widget: select + options: + - a + - b + - c + - label: List + name: list + widget: list + fields: + - label: Related Post + name: post + widget: relationKitchenSinkPost + collection: posts + search_fields: + - title + - body + value_field: title + - label: String + name: string + widget: string + - label: Boolean + name: boolean + widget: boolean + - label: Text + name: text + widget: text + - label: Number + name: number + widget: number + - label: Markdown + name: markdown + widget: markdown + - label: Datetime + name: datetime + widget: datetime + - label: Image + name: image + widget: image + - label: File + name: file + widget: file + - label: Select + name: select + widget: select + options: + - a + - b + - c + - label: Hidden + name: hidden + widget: hidden + default: hidden + - label: Object + name: object + widget: object + fields: + - label: String + name: string + widget: string + - label: Boolean + name: boolean + widget: boolean + - label: Text + name: text + widget: text + - label: Number + name: number + widget: number + - label: Markdown + name: markdown + widget: markdown + - label: Datetime + name: datetime + widget: datetime + - label: Image + name: image + widget: image + - label: File + name: file + widget: file + - label: Select + name: select + widget: select + options: + - a + - b + - c + - label: Typed List + name: typed_list + widget: list + types: + - label: Type 1 Object + name: type_1_object + widget: object + fields: + - label: String + name: string + widget: string + - label: Boolean + name: boolean + widget: boolean + - label: Text + name: text + widget: text + - label: Type 2 Object + name: type_2_object + widget: object + fields: + - label: Number + name: number + widget: number + - label: Select + name: select + widget: select + options: + - a + - b + - c + - label: Datetime + name: datetime + widget: datetime + - label: Markdown + name: markdown + widget: markdown + - label: Type 3 Object + name: type_3_object + widget: object + fields: + - label: Image + name: image + widget: image + - label: File + name: file + widget: file diff --git a/packages/demo/example.css b/packages/demo/example.css new file mode 100644 index 00000000..7b683ec3 --- /dev/null +++ b/packages/demo/example.css @@ -0,0 +1,21 @@ +html, +body { + color: #444; + font-size: 14px; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +body { + padding: 20px; +} + +h1 { + margin-top: 20px; + color: #666; + font-weight: bold; + font-size: 32px; +} + +img { + max-width: 100%; +} diff --git a/packages/demo/index.html b/packages/demo/index.html new file mode 100644 index 00000000..c2f0c027 --- /dev/null +++ b/packages/demo/index.html @@ -0,0 +1,248 @@ + + + + + + Static CMS Demo + + + + + + + diff --git a/packages/demo/index.js b/packages/demo/index.js new file mode 100644 index 00000000..0428dfd3 --- /dev/null +++ b/packages/demo/index.js @@ -0,0 +1,173 @@ +// Register all the things +CMS.init(); + +const PostPreview = ({ entry, widgetFor, widgetsFor }) => { + return h( + 'div', + {}, + h('div', { className: 'cover' }, h('h1', {}, entry.data.title), widgetFor('image')), + h('p', {}, h('small', {}, 'Written ' + entry.data.date)), + h('div', { className: 'text' }, widgetFor('body')), + ); +}; + +const GeneralPreview = ({ widgetsFor, getAsset, entry }) => { + const title = entry.data.site_title; + const posts = entry.data.posts; + const thumb = posts && posts.thumb; + + const [thumbUrl, setThumbUrl] = useState(''); + + useEffect(() => { + let alive = true; + + const loadThumb = async () => { + const thumbAsset = await getAsset(thumb); + if (alive) { + setThumbUrl(thumbAsset.toString()); + } + }; + + loadThumb(); + + return () => { + alive = false; + }; + }, [thumb]); + + return h( + 'div', + {}, + h('h1', {}, title), + h( + 'dl', + {}, + h('dt', {}, 'Posts on Frontpage'), + h('dd', {}, widgetsFor('posts').widgets.front_limit ?? 0), + + h('dt', {}, 'Default Author'), + h('dd', {}, widgetsFor('posts').data?.author ?? 'None'), + + h('dt', {}, 'Default Thumbnail'), + h('dd', {}, thumb && h('img', { src: thumbUrl })), + ), + ); +}; + +const AuthorsPreview = ({ widgetsFor }) => { + return h( + 'div', + {}, + h('h1', {}, 'Authors'), + widgetsFor('authors').map(function (author, index) { + return h( + 'div', + { key: index }, + h('hr', {}), + h('strong', {}, author.data.name), + author.widgets.description, + ); + }), + ); +}; + +const RelationKitchenSinkPostPreview = ({ fieldsMetaData }) => { + // When a post is selected from the relation field, all of it's data + // will be available in the field's metadata nested under the collection + // name, and then further nested under the value specified in `value_field`. + // In this case, the post would be nested under "posts" and then under + // the title of the selected post, since our `value_field` in the config + // is "title". + const post = fieldsMetaData && fieldsMetaData.posts.value; + const style = { border: '2px solid #ccc', borderRadius: '8px', padding: '20px' }; + return post + ? h( + 'div', + { style: style }, + h('h2', {}, 'Related Post'), + h('h3', {}, post.title), + h('img', { src: post.image }), + h('p', {}, (post.body ?? '').slice(0, 100) + '...'), + ) + : null; +}; + +const CustomPage = () => { + return h('div', {}, 'I am a custom page!'); +}; + +CMS.registerPreviewStyle('.toastui-editor-contents h1 { color: blue }', { raw: true }); +CMS.registerPreviewTemplate('posts', PostPreview); +CMS.registerPreviewTemplate('general', GeneralPreview); +CMS.registerPreviewTemplate('authors', AuthorsPreview); +// Pass the name of a registered control to reuse with a new widget preview. +CMS.registerWidget('relationKitchenSinkPost', 'relation', RelationKitchenSinkPostPreview); +CMS.registerAdditionalLink({ + id: 'example', + title: 'Example.com', + data: 'https://example.com', + options: { + icon: 'page', + }, +}); +CMS.registerAdditionalLink({ + id: 'custom-page', + title: 'Custom Page', + data: CustomPage, + options: { + icon: 'page', + }, +}); + +CMS.registerShortcode('youtube', { + label: 'YouTube', + openTag: '[', + closeTag: ']', + separator: '|', + toProps: args => { + if (args.length > 0) { + return { src: args[0] }; + } + + return { src: '' }; + }, + toArgs: ({ src }) => { + return [src]; + }, + control: ({ src, onChange }) => { + return h('span', {}, [ + h('input', { + key: 'control-input', + value: src, + onChange: event => { + onChange({ src: event.target.value }); + }, + }), + h( + 'iframe', + { + key: 'control-preview', + width: '420', + height: '315', + src: `https://www.youtube.com/embed/${src}`, + }, + '', + ), + ]); + }, + preview: ({ src }) => { + return h( + 'span', + {}, + h( + 'iframe', + { + width: '420', + height: '315', + src: `https://www.youtube.com/embed/${src}`, + }, + '', + ), + ); + }, +}); diff --git a/yarn.lock b/yarn.lock index a1858f24..a271ca9f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3393,10 +3393,10 @@ redux-thunk "^2.4.2" reselect "^4.1.7" -"@remix-run/router@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.1.0.tgz#b48db8148c8a888e50580a8152b6f68161c49406" - integrity sha512-rGl+jH/7x1KBCQScz9p54p0dtPLNeKGb3e0wD2H5/oZj41bwQUnXdzbj2TbUAFhvD7cp9EyEQA4dEgpUFa1O7Q== +"@remix-run/router@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.2.0.tgz#54eff8306938b64c521f4a9ed313d33a91ef019a" + integrity sha512-GO82KYYTWPRCgdNtnheaZG3LcViUlxRFlHM7ykh7N+ufoXi6PVIHoP+9RUG/vuzl2hr9i/h6EA1Eq+2HpqJ0gQ== "@rollup/plugin-babel@^5.2.0": version "5.3.1" @@ -13151,20 +13151,20 @@ react-refresh@0.14.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== -react-router-dom@6.5.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.5.0.tgz#3970bdcaa7c710a6e0b478a833ba0b4b8ae61a6f" - integrity sha512-/XzRc5fq80gW1ctiIGilyKFZC/j4kfe75uivMsTChFbkvrK4ZrF3P3cGIc1f/SSkQ4JiJozPrf+AwUHHWVehVg== +react-router-dom@6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.6.0.tgz#ad20b37b69e9fe7c6389663a0767ba40a19f71fe" + integrity sha512-qC4jnvpfCPKVle1mKLD75IvZLcbVJyFMlSn16WY9ZiOed3dgSmqhslCf/u3tmSccWOujkdsT/OwGq12bELmvjg== dependencies: - "@remix-run/router" "1.1.0" - react-router "6.5.0" + "@remix-run/router" "1.2.0" + react-router "6.6.0" -react-router@6.5.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.5.0.tgz#b53f15543a60750c925609d2e38037ac5aed6dd3" - integrity sha512-fqqUSU0NC0tSX0sZbyuxzuAzvGqbjiZItBQnyicWlOUmzhAU8YuLgRbaCL2hf3sJdtRy4LP/WBrWtARkMvdGPQ== +react-router@6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.6.0.tgz#9ae27cfc6bf7f2b28e1f028fe01fdbec96a3a41d" + integrity sha512-+VPfCIaFbkW7BAiB/2oeprxKAt1KLbl+zXZ10CXOYezKWgBmTKyh8XjI53eLqY5kd7uY+V4rh3UW44FclwUU+Q== dependencies: - "@remix-run/router" "1.1.0" + "@remix-run/router" "1.2.0" react-schemaorg@2.0.0: version "2.0.0"