diff --git a/.storybook/main.js b/.storybook/main.js index d5cb59c1c..13ca83d95 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -38,6 +38,40 @@ module.exports = { use: ["@svgr/webpack"], }); + // Support Svelte + config.module.rules.push({ + test: /\.svelte$/, + use: [ + { + loader: "svelte-loader", + options: { + compilerOptions: { + dev: true, + }, + emitCss: true, + hotReload: true, + }, + }, + ], + }); + + // TODO: make the mock work + // Force Storybook to always use the mock instead of the real component ? + config.resolve.alias["./src/pat/contentbrowser/src/App.svelte"] = path.resolve( + __dirname, + "../src/pat/contentbrowser/src/App.mock.js" + ); + config.resolve.alias["#pat/contentbrowser/src/App"] = path.resolve( + __dirname, + "../src/pat/contentbrowser/src/App.mock.js" + ); + config.resolve.alias["./src/pat/contentbrowser/src/SelectedItem.svelte"] = + path.resolve(__dirname, "../src/pat/contentbrowser/src/App.mock.js"); + config.resolve.alias["#pat/contentbrowser/src/App"] = path.resolve( + __dirname, + "../src/pat/contentbrowser/src/SelectedItem.mock.js" + ); + return config; }, }; diff --git a/package.json b/package.json index 5e75d9e4e..e7b2f1507 100644 --- a/package.json +++ b/package.json @@ -101,6 +101,16 @@ "sass": "~1.77.8", "underscore": "1.13.7" }, + "imports": { + "#pat/contentbrowser/src/App": { + "storybook": "./src/pat/contentbrowser/src/App.mock.js", + "default": "./src/pat/contentbrowser/src/App.svelte" + }, + "#pat/contentbrowser/src/SelectedItem": { + "storybook": "./src/pat/contentbrowser/src/SelectedItem.mock.js", + "default": "./src/pat/contentbrowser/src/SelectedItem.svelte" + } + }, "scripts": { "clean": "rimraf docs/_site", "build:webpack": "NODE_ENV=production webpack --config webpack.config.js", diff --git a/src/pat/contentbrowser/contentbrowser.docs.mdx b/src/pat/contentbrowser/contentbrowser.docs.mdx new file mode 100644 index 000000000..7788fa398 --- /dev/null +++ b/src/pat/contentbrowser/contentbrowser.docs.mdx @@ -0,0 +1,48 @@ +import { Meta, Story } from "@storybook/addon-docs"; +import { ContentBrowser } from "./contentbrowser.stories.js"; + + + +# Contentbrowser + +Show a widget to select items in an offcanvas miller-column browser. + +## Configuration + +```md +| Option | Type | Default | Description | +| :------------------: | :-----: | :-------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------: | +| vocabularyUrl | string | null | This is a URL to a JSON-formatted file used to populate the list | +| attributes | array | ['UID', 'Title', 'portal_type', 'path'] | This list is passed to the server during an AJAX request to specify the attributes which should be included on each item. | +| rootPath | string | "/" | Browsing/searching root path. You will not get beneath this path | +| rootUrl | string | | Browsing/searching root url. | +| basePath | string | set to rootPath. | Start browse/search in this path. | +| contextPath | string | | Path of the object, which is currently edited. If this path is given, this object will not be selectable. | +| favorites | array | [] | Array of objects. These are favorites, which can be used to quickly jump to different locations. Objects have the attributes "title" and "path". | +| maximumSelectionSize | integer | -1 | The maximum number of items that can be selected in a multi-select control. If this number is less than 1 selection is not limited. | +| mode | string | "browse" | Toggle between "browse" and "search" | +| width | integer | | Override the width of the selected items field | +| bSize | integer | 10 | Batch size of the items listed in levels | +| maxDepth | integer | | Maximum level depth for "browse" mode | +| separator | string | ',' | Select2 option. String which separates multiple items. | +| upload | boolean | | Allow file and image uploads from within the related items widget. | +| recentlyUsed | boolean | false | Show the recently used items dropdown. | +| recentlyUsedKey | integer | | Storage key for saving the recently used items. This is generated with fieldname and username in the patternoptions. | +| recentlyUsedMaxItems | integer | 20 | Maximum items to keep in recently used list. 0: no restriction. | +| customComponentKeys | dict | {} | Register custom components. Currently only "SelectedItem" implemented | +``` + +## Examples + +### Simple + +
+ + +```html + +``` diff --git a/src/pat/contentbrowser/contentbrowser.js b/src/pat/contentbrowser/contentbrowser.js index 2968dede0..ba833529f 100644 --- a/src/pat/contentbrowser/contentbrowser.js +++ b/src/pat/contentbrowser/contentbrowser.js @@ -4,6 +4,11 @@ import registry from "@patternslib/patternslib/src/core/registry"; import utils from "../../core/utils"; import plone_registry from "@plone/registry"; +// TODO: make SB mock work ? +// Subpath imports from package.json (so Storybook can mock them) +import SelectedItem from "#pat/contentbrowser/src/SelectedItem"; +import ContentBrowserApp from "#pat/contentbrowser/src/App"; + // Contentbrowser pattern export const parser = new Parser("contentbrowser"); diff --git a/src/pat/contentbrowser/contentbrowser.stories.js b/src/pat/contentbrowser/contentbrowser.stories.js new file mode 100644 index 000000000..6fb0de2e2 --- /dev/null +++ b/src/pat/contentbrowser/contentbrowser.stories.js @@ -0,0 +1,45 @@ +import $ from "jquery"; +import { RenderHTML } from "../../../.storybook/setup.js"; +import ContentBrowserComponent from "./contentbrowser.js"; + +export default { + title: "Patterns/ContentBrowser", + parameters: { + mockData: [ + { + url: "/contentbrowser-test.json", // Fake API URL + method: "GET", + status: 200, + response: { + items: [ + { + UID: "1234", + Title: "Example Document", + path: "/example-document", + }, + { UID: "5678", Title: "Another Item", path: "/another-item" }, + ], + }, + }, + ], + }, +}; + +// Basic Contentbrowser +const getContentBrowser = (args) => ` + +`; + +// TODO: +// Story for this component: error Invalid URL +// Check svelte components mocks ? +export const ContentBrowser = { + render: (args) => RenderHTML(args, getContentBrowser), + args: { + vocabularyUrl: "/contentbrowser-test.json", + }, +}; diff --git a/src/pat/contentbrowser/src/App.mock.js b/src/pat/contentbrowser/src/App.mock.js new file mode 100644 index 000000000..712cc064c --- /dev/null +++ b/src/pat/contentbrowser/src/App.mock.js @@ -0,0 +1,17 @@ +console.log("Using App:", import.meta.url); + +// TODO: +// How to prevent App.svelte from running ? +// both mock and real App.svelte are running rn +if (typeof window !== "undefined") { + console.log({ aqui: window.ContentBrowserApp }); + window.ContentBrowserApp = "alala"; + console.log({ aqui: window.ContentBrowserApp }); +} + +export default function MockContentBrowserApp({ target, props }) { + console.log("MockSelectedItem initialized with", props); + target.innerHTML = `
+ Mocked Content Browser App +
`; +} diff --git a/src/pat/contentbrowser/src/App.svelte b/src/pat/contentbrowser/src/App.svelte index 36d608240..83dbc5292 100644 --- a/src/pat/contentbrowser/src/App.svelte +++ b/src/pat/contentbrowser/src/App.svelte @@ -1,4 +1,6 @@