summaryrefslogtreecommitdiffstats
path: root/browser/components/storybook/docs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /browser/components/storybook/docs
parentInitial commit. (diff)
downloadfirefox-esr-upstream.tar.xz
firefox-esr-upstream.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/storybook/docs')
-rw-r--r--browser/components/storybook/docs/README.reusable-widgets.stories.md183
-rw-r--r--browser/components/storybook/docs/README.storybook.stories.md127
2 files changed, 310 insertions, 0 deletions
diff --git a/browser/components/storybook/docs/README.reusable-widgets.stories.md b/browser/components/storybook/docs/README.reusable-widgets.stories.md
new file mode 100644
index 0000000000..3cdbf0967f
--- /dev/null
+++ b/browser/components/storybook/docs/README.reusable-widgets.stories.md
@@ -0,0 +1,183 @@
+# Reusable UI widgets
+
+## Background
+
+Different Firefox surfaces make use of similar UI elements such as cards, menus,
+toggles, and message bars. A group of designers and developers have started
+working together to create standardized versions of these elements in the form
+of new web components. The intention is for these components to encapsulate our
+design system, ensure accessibility and usability across the application, and
+reduce the maintenance burden associated with supporting multiple different
+implementations of the same UI patterns.
+
+Many of these components are being built using the [Lit
+library](https://lit.dev/) to take advantage of its templating syntax and
+re-rendering logic. All new components are being documented in Storybook in an
+effort to create a catalog that engineers and designers can use to see which
+components can be easily lifted off the shelf for use throughout Firefox.
+
+## Designing new reusable widgets
+
+Widgets that live at the global level, "UI Widgets", should be created in collaboration with the Design System team.
+This ensures consistency with the rest of the elements in the Design System and the existing UI elements.
+Otherwise, you should consult with your team and the appropriate designer to create domain-specific UI widgets.
+Ideally, these domain widgets should be consistent with the rest of the UI patterns established in Firefox.
+
+### Does an existing widget cover the use case you need?
+
+Before creating a new reusable widget, make sure there isn't a widget you could use already.
+When designing a new reusable widget, ensure it is designed for all users.
+Here are some questions you can use to help include all users: how will people perceive, operate, and understand this widget? Will the widget use standards proven technology.
+[Please refer to the "General Considerations" section of the Mozilla Accessibility Release Guidelines document](https://wiki.mozilla.org/Accessibility/Guidelines#General_Considerations) for more details to ensure your widget adheres to accessibility standards.
+
+### Supporting widget use in different processes
+
+A newly designed widget may need to work in the parent process, the content process, or both depending on your use case.
+[See the Process Model document for more information about these different processes](https://firefox-source-docs.mozilla.org/dom/ipc/process_model.html).
+You will likely be using your widget in a privileged process (such as the parent or privileged content) with access to `Services`, `XPCOMUtils`, and other globals.
+Storybook and other web content do not have access to these privileged globals, so you will need to write workarounds for `Services`, `XPCOMUtils`, chrome URIs for CSS files and assets, etc.
+[Check out moz-support-link.mjs and moz-support-link.stories.mjs for an example of a widget being used in the parent/chrome and needing to handle `XPCOMUtils` in Storybook](https://searchfox.org/mozilla-central/search?q=moz-support-link&path=&case=false&regexp=false).
+[See moz-toggle.mjs for handling chrome URIs for CSS in Storybook](https://searchfox.org/mozilla-central/source/toolkit/content/widgets/moz-toggle/moz-toggle.mjs).
+[See moz-label.mjs for an example of handling `Services` in Storybook](https://searchfox.org/mozilla-central/source/toolkit/content/widgets/moz-label/moz-label.mjs).
+
+### Autonomous or Customized built-in Custom Elements
+
+There are two types of custom elements, autonomous elements that extend `HTMLElement` and customized built-in elements that extend basic HTML elements.
+If you use autonomous elements, you can use Shadow DOM and/or the Lit library.
+[Lit does not support customized built-in custom elements](https://github.com/lit/lit-element/issues/879).
+
+In some cases, you may want to provide some functionality on top of a built-in HTML element, [like how `moz-support-link` prepares the `href` value for anchor elements](https://searchfox.org/mozilla-central/rev/3563da061ca2b32f7f77f5f68088dbf9b5332a9f/toolkit/content/widgets/moz-support-link/moz-support-link.mjs#83-89).
+In other cases, you may want to focus on creating markup and reacting to changes on the element.
+This is where Lit can be useful for declaritively defining the markup and reacting to changes when attributes are updated.
+
+### How will developers use your widget?
+
+What does the interface to your widget look like?
+Do you expect developers to use reactive attributes or [slots](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots#adding_flexibility_with_slots)?
+If there are many ways to accomplish the same end result, this could result in future confusion and increase the maintainance cost.
+
+You should write stories for your widget to demonstrate how it can be used.
+These stories can be used as guides for new use cases that may appear in the future.
+This can also help draw the line for the responsibilities of your widget.
+
+## Adding new design system components
+
+We have a `./mach addwidget` scaffold command to make it easier to create new
+reusable components and hook them up to Storybook. Currently this command can
+only be used to add a new Lit based web component to `toolkit/content/widgets`.
+In the future we may expand it to support options for creating components
+without using Lit and for adding components to different directories.
+See [Bug 1803677](https://bugzilla.mozilla.org/show_bug.cgi?id=1803677) for more details on these future use cases.
+
+To create a new component, you run:
+
+```sh
+# Component names should be in kebab-case and contain at least 1 -.
+./mach addwidget component-name
+```
+
+The scaffold command will generate the following files:
+
+```sh
+└── toolkit
+ └── content
+ ├── tests
+ │ └── widgets
+ │ └── test_component_name.html # chrome test
+ └── widgets
+ └── component-name # new folder for component code
+ ├── component-name.css # component specific CSS
+ ├── component-name.mjs # Lit based component
+ └── component-name.stories.mjs # component stories
+```
+
+It will also make modifications to `toolkit/content/jar.mn` to add `chrome://`
+URLs for the new files, and to `toolkit/content/tests/widgets/chrome.ini` to
+enable running the newly added test.
+
+After running the scaffold command you can start Storybook and you will see
+placeholder content that has been generated for your component. You can then
+start altering the generated files and see your changes reflected in Storybook.
+
+### Known `browser_all_files_referenced.js` issue
+
+Unfortunately for now [the
+browser_all_files_referenced.js test](https://searchfox.org/mozilla-central/source/browser/base/content/test/static/browser_all_files_referenced.js)
+will fail unless your new component is immediately used somewhere outside
+of Storybook. We have plans to fix this issue, [see Bug 1806002 for more details](https://bugzilla.mozilla.org/show_bug.cgi?id=1806002), but for now you can get around it
+by updating [this array](https://searchfox.org/mozilla-central/rev/5c922d8b93b43c18bf65539bfc72a30f84989003/browser/base/content/test/static/browser_all_files_referenced.js#113) to include your new chrome filepath.
+
+### Using new design system components
+
+Once you've added a new component to `toolkit/content/widgets` and created
+`chrome://` URLs via `toolkit/content/jar.mn` you should be able to start using it
+throughout Firefox. You can import the component into `html`/`xhtml` files via a
+`script` tag with `type="module"`:
+
+```html
+<script type="module" src="chrome://global/content/elements/your-component-name.mjs"></script>
+```
+
+If you are unable to import the new component in html, you can use [`ensureCustomElements()` in customElements.js](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/toolkit/content/customElements.js#865) in the relevant JS file.
+For example, [we use `window.ensureCustomElements("moz-button-group")` in `browser-siteProtections.js`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/browser/base/content/browser-siteProtections.js#1749).
+**Note** you will need to add your new widget to [the switch in importCustomElementFromESModule](https://searchfox.org/mozilla-central/rev/85b4f7363292b272eb9b606e00de2c37a6be73f0/toolkit/content/customElements.js#845-859) for `ensureCustomElements()` to work as expected.
+Once [Bug 1803810](https://bugzilla.mozilla.org/show_bug.cgi?id=1803810) lands, this process will be simplified: you won't need to use `ensureCustomElements()` and you will [add your widget to the appropriate array in customElements.js instead of the switch statement](https://searchfox.org/mozilla-central/rev/85b4f7363292b272eb9b606e00de2c37a6be73f0/toolkit/content/customElements.js#818-841).
+
+## Adding new domain-specific widgets
+
+While we do have the `./mach addwidget` command, as noted in the [adding new design system components](#adding-new-design-system-components), this does not currently support the domain-specific widget case.
+[See Bug 1828181 for more details on supporting this case](https://bugzilla.mozilla.org/show_bug.cgi?id=1828181).
+Instead, you will need to do two things to have your new story appear in Storybook:
+1. Create `<your-team-or-project>/<your-widget>.stories.mjs` in `browser/components/storybook/stories`
+2. In this newly created story file, add the following default export:
+ ```js
+ export default {
+ title: "Domain-specific UI Widgets/<your-team-or-project>/<your-widget>"
+ component: "<your-widget>"
+ };
+ ```
+The next time you run `./mach storybook`, a blank story entry for your widget should appear in your local Storybook.
+
+Since Storybook is unaware of how the actual code is added or built, we won't go into detail about adding your new widget to the codebase.
+It's recommended to have a `.html` test for your new widget since this lets you unit test the component directly rather than using integration tests with the domain.
+To see what kind of files you may need for your widget, please refer back to [the output of the `./mach addwidget` command](#adding-new-design-system-components).
+Just like with the UI widgets, [the `browser_all_files_referenced.js` will fail unless you use your component immediately outside of Storybook.](#known-browser_all_files_referencedjs-issue)
+
+### Using new domain-specific widgets
+
+This is effectively the same as [using new design system components](#using-new-design-system-components).
+You will need to import your widget into the relevant `html`/`xhtml` files via a `script` tag with `type="module"`:
+
+```html
+<script type="module" src="chrome://browser/content/<domain-directory>/<your-widget>.mjs"></script>
+```
+
+Or use `window.ensureCustomElements("<your-widget>")` as previously stated in [the using new design system components section.](#using-new-design-system-components)
+
+## Common pitfalls
+
+If you're trying to use a reusable widget but nothing is appearing on the
+page it may be due to one of the following issues:
+
+- Omitting the `type="module"` in your `script` tag.
+- Wrong file path for the `src` of your imported module.
+- Widget is not declared or incorrectly declared in the correct `jar.mn` file.
+- Not specifying the `html:` namespace when using a custom HTML element in an
+ `xhtml` file. For example the tag should look something like this:
+
+ ```html
+ <html:your-component-name></html:your-component-name>
+ ```
+- Adding a `script` tag to an `inc.xhtml` file. For example when using a new
+ component in the privacy section of `about:preferences` the `script` tag needs
+ to be added to `preferences.xhtml` rather than to `privacy.inc.xhtml`.
+- Trying to extend a built-in HTML element in Lit. [Because Webkit never
+ implemented support for customized built-ins, Lit doesn't support it either.](https://github.com/lit/lit-element/issues/879#issuecomment-1061892879)
+ That means if you want to do something like:
+
+ ```js
+ customElements.define("cool-button", CoolButton, { extends: "button" });
+ ```
+
+ you will need to make a vanilla custom element, you cannot use Lit.
+ [For an example of extending an HTML element, see `moz-support-link`](https://searchfox.org/mozilla-central/source/toolkit/content/widgets/moz-support-link/moz-support-link.mjs).
diff --git a/browser/components/storybook/docs/README.storybook.stories.md b/browser/components/storybook/docs/README.storybook.stories.md
new file mode 100644
index 0000000000..0363ee8d78
--- /dev/null
+++ b/browser/components/storybook/docs/README.storybook.stories.md
@@ -0,0 +1,127 @@
+# Storybook for Firefox
+
+[Storybook](https://storybook.js.org/) is a component library to document our
+design system, reusable components, and any specific components you might want
+to test with dummy data. [Take a look at our Storybook instance!](https://firefoxux.github.io/firefox-desktop-components/?path=/story/docs-reusable-widgets--page)
+
+## Background
+
+Storybook lists components that can be reused, and helps document
+what common elements we have. It can also list implementation specific
+components, but they should be added to the "Domain-Specific UI Widgets" section.
+
+Changes to files directly referenced from Storybook (so basically non-chrome://
+paths) should automatically reflect changes in the opened browser. If you make a
+change to a `chrome://` referenced file then you'll need to do a hard refresh
+(Cmd+Shift+R/Ctrl+Shift+R) to notice the changes. If you're on Windows you may
+need to `./mach build faster` to have the `chrome://` URL show the latest version.
+
+## Running Storybook
+
+Installing the npm dependencies and running the `storybook` npm script should be
+enough to get Storybook running. This can be done via `./mach storybook`
+commands, or with your personal npm/node that happens to be compatible.
+
+### Running with mach commands
+
+This is the recommended approach for installing dependencies and running
+Storybook locally.
+
+To install dependencies and start Storybook, just run:
+
+```sh
+# This uses npm ci under the hood to install the package-lock.json exactly.
+./mach storybook
+```
+
+This single command will first install any missing dependencies then start the
+local Storybook server. You should run your local build to test in Storybook
+since `chrome://` URLs are currently being pulled from the running browser, so any
+changes to common-shared.css for example will come from your build.
+
+The Storybook server will continue running and will watch for component file
+changes. To access your local Storybook preview you can use the `launch`
+subcommand:
+
+```sh
+# In another terminal:
+./mach storybook launch
+```
+
+This will run your local browser and point it at `http://localhost:5703`. The
+`launch` subcommand will also enable SVG context-properties so the `fill` CSS
+property works in storybook.
+
+Alternatively, you can simply navigate to `http://localhost:5703/` or run:
+
+```sh
+# In another terminal:
+./mach run http://localhost:5703/
+```
+
+although with these options SVG context-properties won't be enabled, so what's
+displayed in Storybook may not exactly reflect how components will look when
+used in Firefox.
+
+### Personal npm
+
+You can use your own `npm` to install and run Storybook. Compatibility is up
+to you to sort out.
+
+```sh
+cd browser/components/storybook
+npm ci # Install the package-lock.json exactly so lockfileVersion won't change.
+npm run storybook
+```
+
+## Updating Storybook dependencies
+
+On occasion you may need to update or add a npm dependency for Storybook.
+This can be done using the version of `npm` packaged with `mach`:
+
+```sh
+# Install a dev dependency from within the storybook directory.
+cd browser/components/storybook && ../../../mach npm i -D your-package
+```
+
+## Adding new stories
+
+Storybook is currently configured to search for story files (any file with a
+`.stories.(js|mjs|md)` extension) in `toolkit/content/widgets` and
+`browser/components/storybook/stories`.
+
+Stories in `toolkit/content/widgets` are used to document design system
+components, also known as UI widgets.
+As long as you used `./mach addwidget` correctly, there is no additional setup needed to view your newly created story in Storybook.
+
+Stories in `browser/components/storybook/stories` are used for non-design system components, also called domain-specific UI widgets.
+The easiest way to use Storybook for non-design system elements is
+to add a new `.stories.mjs` file to `browser/components/storybook/stories`.
+You will also need to set the title of your widget to be: `Domain-specific UI Widgets/<team-or-project-name>/<widget-name>` in the default exported object.
+[See the Credential Management/Timeline widget for an example.](https://searchfox.org/mozilla-central/rev/2c11f18f89056a806c299a9d06bfa808718c2e84/browser/components/storybook/stories/credential-management.stories.mjs#11)
+
+If you want to colocate your story with the code it is documenting you will need
+to add to the `stories` array in the `.storybook/main.js` [configuration
+file](https://searchfox.org/mozilla-central/source/browser/components/storybook/.storybook/main.js)
+so that Storybook knows where to look for your files.
+
+The Storybook docs site has a [good
+overview](https://storybook.js.org/docs/web-components/get-started/whats-a-story)
+of what's involved in writing a new story. For convenience you can use the [Lit
+library](https://lit.dev/) to define the template code for your story, but this
+is not a requirement.
+
+### UI Widgets versus Domain-Specific UI Widgets
+
+Widgets that are part of [our design system](https://acorn.firefox.com/latest/acorn.html) and intended to be used across the Mozilla suite of products live under the "UI Widgets" category in Storybook and under `toolkit/content/widgets/` in Firefox.
+These global widgets are denoted in code by the `moz-` prefix in their name.
+For example, the name `moz-support-link` informs us that this widget is design system compliant and can be used anywhere in Firefox.
+
+Storybook can also be used to help document and prototype widgets that are specific to a part of the codebase and not intended for more global use.
+Stories for these types of widgets live under the "Domain-Specific UI Widgets" category, while the code can live in any appropriate folder in `mozilla-central`.
+[See the Credential Management folder as an example of a domain specific folder](https://firefoxux.github.io/firefox-desktop-components/?path=/docs/domain-specific-ui-widgets-credential-management-timeline--empty-timeline) and [see the credential-management.stories.mjs for how to make a domain specific folder in Storybook](https://searchfox.org/mozilla-central/source/browser/components/storybook/stories/credential-management.stories.mjs).
+[To add a non-team specific widget to the "Domain-specific UI Widgets" section, see the migration-wizard.stories.mjs file](https://searchfox.org/mozilla-central/source/browser/components/storybook/stories/migration-wizard.stories.mjs).
+
+Creating and documenting domain specific UI widgets allows other teams to be aware of and take inspiration from existing UI patterns.
+With these widgets, **there is no guarantee that the element will work for your domain.**
+If you need to use a domain-specific widget outside of its intended domain, it may be worth discussing how to convert this domain specific widget into a global UI widget.