druxt-site 0.10.5 → 0.11.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.
@@ -5,27 +5,20 @@ import DruxtModule from 'druxt/dist/components/DruxtModule.vue'
5
5
  import { mapActions } from 'vuex'
6
6
 
7
7
  /**
8
- * Renders all available block regions based on the specified theme.
8
+ * The DruxtSite component renders all available Drupal block regions and
9
+ * content, based on the specified theme.
10
+ *
11
+ * While Drupal provides placement configuration for blocks, it does not provide
12
+ * any information on where each region should be placed.
13
+ *
14
+ * All regions are provided as scoped slots for the Druxt Wrapper component.
9
15
  *
10
16
  * @example @lang vue
11
17
  * <template>
12
18
  * <DruxtSite theme="umami" />
13
19
  * </template>
14
20
  *
15
- * @example <caption>Default slot override</caption> @lang vue
16
- * <template>
17
- * <DruxtSite theme="umami">
18
- * <template #default="{ props, regions, theme }">
19
- * <DruxtBlockRegion
20
- * v-for="region of regions"
21
- * :key="region"
22
- * v-bind="props[region]"
23
- * />
24
- * </template>
25
- * </DruxtSite>
26
- * </template>
27
- *
28
- * @example <caption>Wrapper component</caption> @lang vue
21
+ * @example <caption>DruxtSite Wrapper component boilerplate</caption> @lang vue
29
22
  * <template>
30
23
  * <div>
31
24
  * <slot name="header" />
@@ -34,16 +27,32 @@ import { mapActions } from 'vuex'
34
27
  * </div>
35
28
  * </template>
36
29
  *
37
- * @see {@link https://blocks.druxtjs.org/api/components/DruxtBlockRegion|DruxtBlockRegion}
30
+ * <script>
31
+ * import { DruxtSiteMixin } from 'druxt-site'
32
+ * export default {
33
+ * mixins: [DruxtSiteMixin]
34
+ * }
35
+ *
36
+ * @example <caption>DruxtSite with template injection</caption> @lang vue
37
+ * <DruxtSite>
38
+ * <template #default="{ props, regions, theme }">
39
+ * <!-- Do whatever you want here -->
40
+ * <DruxtBlockRegion
41
+ * v-for="region of regions"
42
+ * :key="region"
43
+ * v-bind="props[region]"
44
+ * />
45
+ * </template>
46
+ * </DruxtSite>
47
+ *
48
+ * @see {@link /api/packages/blocks/components/DruxtBlockRegion|DruxtBlockRegion}
38
49
  */
39
50
  export default {
40
51
  name: 'DruxtSite',
41
52
 
42
53
  extends: DruxtModule,
43
54
 
44
- /**
45
- * Vue.js Properties.
46
- */
55
+ /** */
47
56
  props: {
48
57
  /**
49
58
  * Drupal theme ID.
@@ -63,9 +72,7 @@ export default {
63
72
  defaultTheme: ($druxt.settings.site || {}).theme,
64
73
  }),
65
74
 
66
- /**
67
- * Vue.js Computed properties.
68
- */
75
+ /** */
69
76
  computed: {
70
77
  /**
71
78
  * DruxtBlockRegion propsData for regions.
@@ -158,15 +165,15 @@ export default {
158
165
  *
159
166
  * @return {ScopedSlots} The Scoped slots object.
160
167
  */
161
- slots() {
168
+ slots(h) {
162
169
  // If no regions, return Nuxt component.
163
170
  if (!this.regions.length) {
164
- return { default: () => this.$createElement('Nuxt') }
171
+ return { default: () => h('Nuxt') }
165
172
  }
166
173
 
167
174
  // Build scoped slots for each region.
168
175
  const scopedSlots = {
169
- ...Object.fromEntries(this.regions.map((region) => [region, (attrs) => this.$createElement('DruxtBlockRegion', {
176
+ ...Object.fromEntries(this.regions.map((region) => [region, (attrs) => h('DruxtBlockRegion', {
170
177
  attrs,
171
178
  key: region,
172
179
  props: this.props[region],
@@ -11,18 +11,23 @@ async function DruxtSiteStorybook({ options, stories }) {
11
11
  const query = new DrupalJsonApiParams().addFields(type, ["theme"]);
12
12
  const resources = (await druxt.getCollectionAll(type, query)).map((collection) => collection.data).flat();
13
13
  const themes = [...new Set(resources.map((o) => o.attributes.theme))].sort();
14
- const siteStories = themes.map((theme) => {
14
+ addTemplate({
15
+ src: resolve(__dirname, `../templates/druxt-site.stories.js`),
16
+ fileName: `stories/druxt-site.stories.js`,
17
+ options: { themes }
18
+ });
19
+ themes.forEach((theme) => {
15
20
  addTemplate({
16
- src: resolve(__dirname, "../templates/druxt-site.stories.js"),
21
+ src: resolve(__dirname, "../templates/druxt-site.instance.stories.js"),
17
22
  fileName: `stories/druxt-site.${theme}.stories.js`,
18
23
  options: {
19
24
  theme,
20
25
  title: titleFn(["Druxt", "Site", "Themes", theme])
21
26
  }
22
27
  });
23
- return resolve(this.options.buildDir, `./stories/druxt-site.${theme}.stories.js`);
24
28
  });
25
- stories.push.apply(stories, siteStories);
29
+ stories.push(resolve(this.options.buildDir, "./stories/druxt-site.stories.js"));
30
+ stories.push(resolve(this.options.buildDir, "./stories/druxt-site.*.stories.js"));
26
31
  }
27
32
 
28
33
  const DruxtSiteNuxtModule = async function(moduleOptions = {}) {
@@ -65,7 +70,6 @@ const DruxtSiteNuxtModule = async function(moduleOptions = {}) {
65
70
  this.addLayout(resolve(__dirname, "./layouts/default.vue"), "default");
66
71
  }
67
72
  this.nuxt.hook("storybook:config", async ({ stories }) => {
68
- stories.push("druxt-site/dist/components/*.stories.mjs");
69
73
  await DruxtSiteStorybook.call(this, { options, stories });
70
74
  });
71
75
  };
@@ -15,18 +15,23 @@ async function DruxtSiteStorybook({ options, stories }) {
15
15
  const query = new drupalJsonapiParams.DrupalJsonApiParams().addFields(type, ["theme"]);
16
16
  const resources = (await druxt$1.getCollectionAll(type, query)).map((collection) => collection.data).flat();
17
17
  const themes = [...new Set(resources.map((o) => o.attributes.theme))].sort();
18
- const siteStories = themes.map((theme) => {
18
+ addTemplate({
19
+ src: path.resolve(__dirname, `../templates/druxt-site.stories.js`),
20
+ fileName: `stories/druxt-site.stories.js`,
21
+ options: { themes }
22
+ });
23
+ themes.forEach((theme) => {
19
24
  addTemplate({
20
- src: path.resolve(__dirname, "../templates/druxt-site.stories.js"),
25
+ src: path.resolve(__dirname, "../templates/druxt-site.instance.stories.js"),
21
26
  fileName: `stories/druxt-site.${theme}.stories.js`,
22
27
  options: {
23
28
  theme,
24
29
  title: titleFn(["Druxt", "Site", "Themes", theme])
25
30
  }
26
31
  });
27
- return path.resolve(this.options.buildDir, `./stories/druxt-site.${theme}.stories.js`);
28
32
  });
29
- stories.push.apply(stories, siteStories);
33
+ stories.push(path.resolve(this.options.buildDir, "./stories/druxt-site.stories.js"));
34
+ stories.push(path.resolve(this.options.buildDir, "./stories/druxt-site.*.stories.js"));
30
35
  }
31
36
 
32
37
  const DruxtSiteNuxtModule = async function(moduleOptions = {}) {
@@ -69,7 +74,6 @@ const DruxtSiteNuxtModule = async function(moduleOptions = {}) {
69
74
  this.addLayout(path.resolve(__dirname, "./layouts/default.vue"), "default");
70
75
  }
71
76
  this.nuxt.hook("storybook:config", async ({ stories }) => {
72
- stories.push("druxt-site/dist/components/*.stories.mjs");
73
77
  await DruxtSiteStorybook.call(this, { options, stories });
74
78
  });
75
79
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "druxt-site",
3
- "version": "0.10.5",
3
+ "version": "0.11.0",
4
4
  "description": "Out of the box Decoupled Drupal sites with Druxt.",
5
5
  "keywords": [
6
6
  "cms",
@@ -43,14 +43,14 @@
43
43
  ],
44
44
  "dependencies": {
45
45
  "drupal-jsonapi-params": "^1.2.2",
46
- "druxt": "^0.16.0",
47
- "druxt-blocks": "^0.14.5",
48
- "druxt-breadcrumb": "^0.13.4",
49
- "druxt-entity": "^0.23.0",
50
- "druxt-menu": "^0.15.3",
51
- "druxt-router": "^0.25.0",
52
- "druxt-schema": "^0.10.0",
53
- "druxt-views": "^0.17.2",
46
+ "druxt": "^0.17.0",
47
+ "druxt-blocks": "^0.15.0",
48
+ "druxt-breadcrumb": "^0.14.0",
49
+ "druxt-entity": "^0.24.0",
50
+ "druxt-menu": "^0.16.0",
51
+ "druxt-router": "^0.26.0",
52
+ "druxt-schema": "^0.10.1",
53
+ "druxt-views": "^0.18.0",
54
54
  "md5": "^2.2.1"
55
55
  },
56
56
  "optionalDependencies": {
@@ -0,0 +1,38 @@
1
+ import DruxtSite from 'druxt-site/dist/components/DruxtSite.vue'
2
+
3
+ export default {
4
+ title: '<%= options.title %>',
5
+ component: DruxtSite,
6
+ argTypes: {
7
+ theme: {
8
+ control: false,
9
+ },
10
+ },
11
+ parameters: {
12
+ docs: {
13
+ description: {
14
+ component: 'Renders a Drupal block regions using the **<%= options.theme %>** theme configuration.\n\n```jsx\n\n<DruxtSite theme="<%= options.theme %>" />\n```'
15
+ },
16
+ },
17
+ },
18
+ }
19
+
20
+ const Template = (args, { argTypes }) => {
21
+ return {
22
+ props: Object.keys(argTypes),
23
+ template: '<DruxtSite v-bind="$props" />',
24
+ }
25
+ }
26
+
27
+ export const Default = Template.bind({})
28
+ Default.args = {
29
+ theme: '<%= options.theme %>',
30
+ }
31
+ Default.storyName = '<%= options.theme.charAt(0).toUpperCase() + options.theme.slice(1) %>'
32
+ Default.parameters = {
33
+ docs: {
34
+ source: {
35
+ code: '<DruxtSite theme="<%= options.theme %>" />'
36
+ }
37
+ }
38
+ }
@@ -1,33 +1,75 @@
1
1
  import DruxtSite from 'druxt-site/dist/components/DruxtSite.vue'
2
2
 
3
3
  export default {
4
- title: '<%= options.title %>',
4
+ title: 'Druxt/Site/DruxtSite',
5
5
  component: DruxtSite,
6
- parameters: {
7
- docs: {
8
- description: {
9
- component: ' '
10
- },
11
- },
12
- },
6
+ argTypes: {
7
+ theme: {
8
+ options: [<%= (options.themes || []).map((s) => `'${s}'`).join(', ') %>],
9
+ control: {
10
+ type: 'select'
11
+ }
12
+ }
13
+ }
13
14
  }
14
15
 
15
- const Template = (args, { argTypes }) => {
16
- return {
17
- props: Object.keys(argTypes),
18
- template: '<DruxtSite v-bind="$props" />',
16
+ // Default story.
17
+ export const Default = (args, { argTypes }) => ({
18
+ components: { DruxtSite },
19
+ props: Object.keys(argTypes),
20
+ template: `<DruxtSite v-bind="$props" />`
21
+ })
22
+
23
+ let code
24
+
25
+ // Wrapper story.
26
+ code = `<template>
27
+ <div>
28
+ <slot name="header" />
29
+ <slot name="content" />
30
+ <slot name="footer" />
31
+ </div>
32
+ </template>
33
+
34
+ <script>
35
+ import { DruxtSiteMixin } from 'druxt-site'
36
+ export default {
37
+ mixins: [DruxtSiteMixin]
38
+ }`
39
+ export const Wrapper = (args, { argTypes }) => ({
40
+ components: { DruxtSite },
41
+ props: Object.keys(argTypes),
42
+ template: `<DruxtSite v-bind="$props" ref="module">
43
+ <template #default>
44
+ Component options:
45
+ <ul>
46
+ <li v-for="option of $refs.module.getModuleComponents()" :key="option.name">{{ option.name }}</li>
47
+ </ul>
48
+ </template>
49
+ </DruxtSite>`
50
+ })
51
+ Wrapper.parameters = {
52
+ docs: {
53
+ storyDescription: 'The DruxtSite component can be themed by using a Druxt Wrapper component.\n\nCreate an appropriately named component, using the relevant component option, with the following boilerplate:\n\n```jsx\n' + code + '\n```',
54
+ source: { code }
19
55
  }
20
56
  }
21
57
 
22
- export const Default = Template.bind({})
23
- Default.args = {
24
- theme: '<%= options.theme %>',
25
- }
26
- Default.storyName = '<%= options.theme.charAt(0).toUpperCase() + options.theme.slice(1) %>'
27
- Default.parameters = {
58
+ // Template injection story.
59
+ code = `<DruxtSite theme="">
60
+ <template #default="{ regions }">
61
+ <!-- Do whatever you want here -->
62
+ <DruxtDebug :json="{ regions }" />
63
+ </template>
64
+ </DruxtSite>`
65
+ export const TemplateInjection = (args, { argTypes }) => ({
66
+ components: { DruxtSite },
67
+ props: Object.keys(argTypes),
68
+ template: code.replace('theme=""', 'v-bind="$props"')
69
+ })
70
+ TemplateInjection.parameters = {
28
71
  docs: {
29
- source: {
30
- code: '<DruxtSite theme="<%= options.theme %>" />'
31
- }
72
+ storyDescription: 'The DruxtSite component can be themed by injecting the default template into the compomnent.\n\n```jsx\n' + code + '\n```',
73
+ source: { code }
32
74
  }
33
75
  }
@@ -1,15 +0,0 @@
1
- import DruxtSite from './DruxtSite.vue'
2
-
3
- export default {
4
- title: 'Druxt/Site/DruxtSite',
5
- component: DruxtSite
6
- }
7
-
8
- const Template = (args, { argTypes }) => ({
9
- components: { DruxtSite },
10
- props: Object.keys(argTypes),
11
- template: `<DruxtSite v-bind="$props" />`
12
- })
13
-
14
- export const Default = Template.bind({})
15
- Default.storyName = 'DruxtSite'