forked from mirrors/gecko-dev
This is still far from perfect given the limitations of the Storybook web components package, but I figured this was worth putting up since it's still an improvement over the current state of our args tables (I think). I'm mostly leaving the default generated `custom-elements-manifest.json` alone save for filtering some internal properties we don't want documented since they shouldn't really be accessed directly. If it seems too strange to just have the `aria-label` attr documented we could possibly remove `attributes` from the docs for now (this happens because it's the only attr where the name is different from the property name). Open to feedback/thoughts on if this is useful or too wonky for now given the weirdness around how Storybook creates naming collisions. Differential Revision: https://phabricator.services.mozilla.com/D162599
160 lines
4.8 KiB
Python
160 lines
4.8 KiB
Python
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
import os
|
|
|
|
from mach.decorators import Command, CommandArgument
|
|
|
|
LICENSE_HEADER = """/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
"""
|
|
|
|
JS_HEADER = """{license}
|
|
import {{ html }} from "../vendor/lit.all.mjs";
|
|
import {{ MozLitElement }} from "../lit-utils.mjs";
|
|
|
|
/**
|
|
* Component description goes here.
|
|
*
|
|
* @tagname {element_name}
|
|
* @property {{string}} variant - Property description goes here
|
|
*/
|
|
export default class {class_name} extends MozLitElement {{
|
|
static properties = {{
|
|
variant: {{ type: String }},
|
|
}};
|
|
|
|
// Use a relative URL in storybook to get faster reloads on style changes.
|
|
static stylesheetUrl = window.IS_STORYBOOK
|
|
? "./{element_name}/{element_name}.css"
|
|
: "chrome://global/content/elements/{element_name}.css";
|
|
|
|
constructor() {{
|
|
super();
|
|
this.variant = "default";
|
|
}}
|
|
|
|
render() {{
|
|
return html`
|
|
<link rel="stylesheet" href=${{this.constructor.stylesheetUrl}} />
|
|
<div>Variant type: ${{this.variant}}</div>
|
|
`;
|
|
}}
|
|
}}
|
|
customElements.define("{element_name}", {class_name});
|
|
"""
|
|
|
|
STORY_HEADER = """{license}
|
|
import {{ html }} from "../vendor/lit.all.mjs";
|
|
// eslint-disable-next-line import/no-unassigned-import
|
|
import "./{element_name}.mjs";
|
|
|
|
export default {{
|
|
title: "Design System/Experiments/{class_name}",
|
|
component: "{element_name}",
|
|
argTypes: {{
|
|
variant: {{
|
|
options: ["default", "other"],
|
|
control: {{ type: "select" }},
|
|
}},
|
|
}},
|
|
}};
|
|
|
|
const Template = ({{ variant }}) => html`
|
|
<{element_name} .variant=${{variant}}></{element_name}>
|
|
`;
|
|
|
|
export const Default = Template.bind({{}});
|
|
Default.args = {{
|
|
variant: "default",
|
|
}};
|
|
"""
|
|
|
|
|
|
def run_mach(command_context, cmd, **kwargs):
|
|
return command_context._mach_context.commands.dispatch(
|
|
cmd, command_context._mach_context, **kwargs
|
|
)
|
|
|
|
|
|
def run_npm(command_context, args):
|
|
return run_mach(
|
|
command_context, "npm", args=[*args, "--prefix=browser/components/storybook"]
|
|
)
|
|
|
|
|
|
@Command(
|
|
"addwidget",
|
|
category="misc",
|
|
description="Scaffold a front-end component.",
|
|
)
|
|
@CommandArgument(
|
|
"names",
|
|
nargs="+",
|
|
help="Component names to create in kebab-case, eg. my-card.",
|
|
)
|
|
def addwidget(command_context, names):
|
|
for name in names:
|
|
component_dir = "toolkit/content/widgets/{0}".format(name)
|
|
|
|
try:
|
|
os.mkdir(component_dir)
|
|
except FileExistsError:
|
|
pass
|
|
|
|
with open("{0}/{1}.mjs".format(component_dir, name), "w", newline="\n") as f:
|
|
class_name = "".join(p.capitalize() for p in name.split("-"))
|
|
f.write(
|
|
JS_HEADER.format(
|
|
license=LICENSE_HEADER,
|
|
element_name=name,
|
|
class_name=class_name,
|
|
)
|
|
)
|
|
|
|
with open("{0}/{1}.css".format(component_dir, name), "w", newline="\n") as f:
|
|
f.write(LICENSE_HEADER)
|
|
|
|
test_name = name.replace("-", "_")
|
|
test_path = "toolkit/content/tests/widgets/test_{0}.html".format(test_name)
|
|
jar_path = "toolkit/content/jar.mn"
|
|
jar_lines = None
|
|
with open(jar_path, "r") as f:
|
|
jar_lines = f.readlines()
|
|
elements_startswith = " content/global/elements/"
|
|
new_css_line = "{0}{1}.css (widgets/{1}/{1}.css)\n".format(
|
|
elements_startswith, name
|
|
)
|
|
new_js_line = "{0}{1}.mjs (widgets/{1}/{1}.mjs)\n".format(
|
|
elements_startswith, name
|
|
)
|
|
new_jar_lines = []
|
|
found_elements_section = False
|
|
added_widget = False
|
|
for line in jar_lines:
|
|
if line.startswith(elements_startswith):
|
|
found_elements_section = True
|
|
if found_elements_section and not added_widget and line > new_css_line:
|
|
added_widget = True
|
|
new_jar_lines.append(new_css_line)
|
|
new_jar_lines.append(new_js_line)
|
|
new_jar_lines.append(line)
|
|
|
|
with open(jar_path, "w", newline="\n") as f:
|
|
f.write("".join(new_jar_lines))
|
|
|
|
story_path = "{0}/{1}.stories.mjs".format(component_dir, name)
|
|
with open(story_path, "w", newline="\n") as f:
|
|
f.write(
|
|
STORY_HEADER.format(
|
|
license=LICENSE_HEADER,
|
|
element_name=name,
|
|
class_name=class_name,
|
|
)
|
|
)
|
|
|
|
run_mach(
|
|
command_context, "addtest", argv=[test_path, "--suite", "mochitest-chrome"]
|
|
)
|