feat: add StorybookJS

This commit is contained in:
Michal 2025-04-04 11:51:33 +02:00
parent 1039a4788d
commit cbc1260553
116 changed files with 3560 additions and 2 deletions

2
.gitignore vendored
View file

@ -30,3 +30,5 @@ Thumbs.db
# Pico # Pico
.pico .pico
*storybook.log

17
.storybook/main.ts Normal file
View file

@ -0,0 +1,17 @@
/** @type { import('@storybook/html-vite').StorybookConfig } */
const config = {
stories: [
"../stories/**/*.mdx",
"../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)",
],
addons: [
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-themes",
],
framework: {
name: "@storybook/html-vite",
options: {},
},
};
export default config;

467
.storybook/preview.ts Normal file
View file

@ -0,0 +1,467 @@
import "../scss/pico.scss";
import { withThemeByDataAttribute } from "@storybook/addon-themes";
import { HtmlRenderer, Preview } from "@storybook/html";
import { withActions } from "@storybook/addon-actions/decorator";
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /datetime$/i,
},
},
},
decorators: [
withActions,
withThemeByDataAttribute<HtmlRenderer>({
themes: {
light: "light",
dark: "dark",
},
defaultTheme: "light",
attributeName: "data-theme",
}),
],
argTypes: {
accesskey: {
control: "text",
description: "Specifies a shortcut key to activate/focus an element.",
table: {
category: "Gobal HTML Attributes",
},
},
anchor: {
control: "text",
description: "Defines a named anchor within a document.",
table: {
category: "Gobal HTML Attributes",
},
},
autocapitalize: {
control: "radio",
description: "Controls the capitalization of text.",
table: {
category: "Gobal HTML Attributes",
},
options: ["none", "sentences", "words", "characters"],
},
autocorrect: {
control: "radio",
description: "Controls whether text correction is enabled or not.",
table: {
category: "Gobal HTML Attributes",
},
options: ["on", "off"],
},
autofocus: {
control: "boolean",
description: "Indicates if the element should receive focus on page load.",
table: {
category: "Gobal HTML Attributes",
},
},
class: {
control: "text",
description: "Specifies one or more class names for the element.",
table: {
category: "Gobal HTML Attributes",
},
},
contenteditable: {
control: "radio",
description: "Indicates if the element is editable.",
table: {
category: "Gobal HTML Attributes",
},
options: [true, false, "plaintext-only"],
},
dir: {
control: "radio",
description: "Specifies the text direction for the content.",
table: {
category: "Gobal HTML Attributes",
},
options: ["ltr", "rtl", "auto"],
},
draggable: {
control: "boolean",
description: "Specifies whether an element is draggable.",
table: {
category: "Gobal HTML Attributes",
},
},
enterkeyhint: {
control: "text",
description: "Hints what action label to present for the enter key.",
table: {
category: "Gobal HTML Attributes",
},
},
exportparts: {
control: "text",
description: "Defines which shadow DOM parts can be exposed for styling.",
table: {
category: "Gobal HTML Attributes",
},
},
hidden: {
control: "boolean",
description: "Indicates if the element is not relevant and should be hidden.",
table: {
category: "Gobal HTML Attributes",
},
},
id: {
control: "text",
description: "Specifies a unique id for the element.",
table: {
category: "Gobal HTML Attributes",
},
},
inert: {
control: "boolean",
description: "Indicates if the element is inactive and not focusable.",
table: {
category: "Gobal HTML Attributes",
},
},
inputmode: {
control: "radio",
description: "Provides a hint for input type devices.",
table: {
category: "Gobal HTML Attributes",
},
options: ["none", "text", "decimal", "numeric", "tel", "search", "email", "url"],
},
is: {
control: "text",
description: "Allows extending built-in HTML elements.",
table: {
category: "Gobal HTML Attributes",
},
},
itemid: {
control: "text",
description: "Defines a unique identifier for microdata.",
table: {
category: "Gobal HTML Attributes",
},
},
itemprop: {
control: "text",
description: "Specifies a property of an item.",
table: {
category: "Gobal HTML Attributes",
},
},
itemref: {
control: "text",
description: "Provides a list of IDs for microdata.",
table: {
category: "Gobal HTML Attributes",
},
},
itemscope: {
control: "boolean",
description: "Defines the scope of an item for microdata.",
table: {
category: "Gobal HTML Attributes",
},
},
itemtype: {
control: "text",
description: "Specifies the type of an item for microdata.",
table: {
category: "Gobal HTML Attributes",
},
},
lang: {
control: "text",
description: "Specifies the language of the elements content.",
table: {
category: "Gobal HTML Attributes",
},
},
nonce: {
control: "text",
description: "Cryptographic nonce used by Content Security Policy.",
table: {
category: "Gobal HTML Attributes",
},
},
part: {
control: "text",
description: "Defines the parts of an element exposed to CSS.",
table: {
category: "Gobal HTML Attributes",
},
},
popover: {
control: "radio",
description: "Specifies the popover attribute for interactive UI.",
table: {
category: "Gobal HTML Attributes",
},
options: ["auto", "hint", "manual"],
},
role: {
control: "text",
description: "Defines an ARIA role for the element.",
table: {
category: "Gobal HTML Attributes",
},
},
slot: {
control: "text",
description: "Specifies the slot the element should be assigned to.",
table: {
category: "Gobal HTML Attributes",
},
},
spellcheck: {
control: "boolean",
description: "Indicates if spelling and grammar checking is enabled.",
table: {
category: "Gobal HTML Attributes",
},
},
style: {
control: "text",
description: "Specifies an inline CSS style for the element.",
table: {
category: "Gobal HTML Attributes",
},
},
tabindex: {
control: "number",
description: "Defines the tab order of the element.",
table: {
category: "Gobal HTML Attributes",
},
},
title: {
control: "text",
description: "Provides additional information about an element.",
table: {
category: "Gobal HTML Attributes",
},
},
translate: {
control: "radio",
description: "Specifies if the content should be translated or not.",
table: {
category: "Gobal HTML Attributes",
},
options: ["yes", "no"],
},
writingsuggestions: {
control: "boolean",
description:
"An enumerated attribute indicating if browser-provided writing suggestions should be enabled under the scope of the element or not.",
table: {
category: "Gobal HTML Attributes",
},
},
"data-test-attribute": {
control: "text",
description: "Custom attribute for testing purposes.",
table: {
category: "Gobal HTML Attributes",
},
},
// Aria Attributes
"aria-atomic": {
control: "boolean",
description: "Indicates if assistive technologies should present changes atomically.",
table: {
category: "Aria Attributes",
},
},
"aria-busy": {
control: "boolean",
description: "Indicates if the element is currently being updated.",
table: {
category: "Aria Attributes",
},
},
"aria-controls": {
control: "text",
description: "Identifies the element (or elements) that control the current element.",
table: {
category: "Aria Attributes",
},
},
"aria-current": {
control: "radio",
description: "Indicates the current item within a container or set.",
table: {
category: "Aria Attributes",
},
options: ["page", "step", "location", "date", "time"],
},
"aria-describedby": {
control: "text",
description: "Identifies the element (or elements) that describe the current element.",
table: {
category: "Aria Attributes",
},
},
"aria-description": {
control: "text",
description: "Provides a description for the current element.",
table: {
category: "Aria Attributes",
},
},
"aria-details": {
control: "text",
description:
"Identifies the element (or elements) that provide additional information about the current element.",
table: {
category: "Aria Attributes",
},
},
"aria-disabled": {
control: "boolean",
description: "Indicates that the element is perceivable but disabled.",
table: {
category: "Aria Attributes",
},
},
"aria-dropeffect": {
control: "radio",
description: "Indicates the allowed drag-and-drop operations.",
table: {
category: "Aria Attributes",
},
options: ["none", "copy", "execute", "link", "move", "popup"],
},
"aria-errormessage": {
control: "text",
description: "Identifies the element (or elements) that contains the error message.",
table: {
category: "Aria Attributes",
},
},
"aria-flowto": {
control: "text",
description: "Identifies the next element in an alternate reading order.",
table: {
category: "Aria Attributes",
},
},
"aria-grabbed": {
control: "boolean",
description: "Indicates if the element is currently grabbed.",
table: {
category: "Aria Attributes",
},
},
"aria-haspopup": {
control: "radio",
description: "Indicates if the element has a popup context menu.",
table: {
category: "Aria Attributes",
},
options: ["false", "true", "menu", "listbox", "tree", "grid"],
},
"aria-hidden": {
control: "boolean",
description: "Indicates if the element is hidden from assistive technologies.",
table: {
category: "Aria Attributes",
},
},
"aria-invalid": {
control: "boolean",
description: "Indicates if the element has an invalid value.",
table: {
category: "Aria Attributes",
},
},
"aria-keyshortcuts": {
control: "text",
description: "Defines keyboard shortcuts for the element.",
table: {
category: "Aria Attributes",
},
},
"aria-label": {
control: "text",
description: "Defines a string value that labels the current element.",
table: {
category: "Aria Attributes",
},
},
"aria-labelledby": {
control: "text",
description: "Identifies the element (or elements) that label the current element.",
table: {
category: "Aria Attributes",
},
},
"aria-live": {
control: "radio",
description: "Indicates that an element will be updated and describes the type of update.",
table: {
category: "Aria Attributes",
},
options: ["off", "assertive", "polite"],
},
"aria-owns": {
control: "text",
description: "Identifies the element (or elements) that the current element owns.",
table: {
category: "Aria Attributes",
},
},
"aria-relevant": {
control: "radio",
description: "Indicates what types of changes should be presented to the user.",
table: {
category: "Aria Attributes",
},
options: ["additions", "removals", "text"],
},
"aria-roledescription": {
control: "text",
description: "Defines a human-readable description for the role.",
table: {
category: "Aria Attributes",
},
},
},
// args: {
// onclick: action("clicked"),
// onmouseover: action("mouseover"),
// onmouseout: action("mouseout"),
// onfocus: action("focused"),
// onblur: action("blurred"),
// onkeydown: action("key down"),
// onkeyup: action("key up"),
// onkeypress: action("key pressed"),
// oninput: action("input"),
// onchange: action("changed"),
// onsubmit: action("submitted"),
// onreset: action("reset"),
// onselect: action("selected"),
// ondrag: action("dragged"),
// ondragstart: action("drag started"),
// ondragend: action("drag ended"),
// ondragenter: action("drag entered"),
// ondragleave: action("drag left"),
// ondragover: action("drag over"),
// ondragdrop: action("drag dropped"),
// ondragexit: action("drag exited"),
// oncopy: action("copied"),
// oncut: action("cut"),
// onpaste: action("pasted"),
// oncontextmenu: action("context menu opened"),
// onwheel: action("wheel scrolled"),
// },
};
export default preview;

View file

@ -46,9 +46,19 @@
"prebuild:autoprefix": "echo '[@picocss/pico] ✨ Autoprefix'", "prebuild:autoprefix": "echo '[@picocss/pico] ✨ Autoprefix'",
"prebuild:minify": "echo '[@picocss/pico] ✨ Minify'", "prebuild:minify": "echo '[@picocss/pico] ✨ Minify'",
"start": "echo '\\033[96m[@picocss/pico] ✨ Start\\033[0m'", "start": "echo '\\033[96m[@picocss/pico] ✨ Start\\033[0m'",
"done": "echo '\\033[32m[@picocss/pico] ✨ Done\\033[0m'" "done": "echo '\\033[32m[@picocss/pico] ✨ Done\\033[0m'",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
}, },
"devDependencies": { "devDependencies": {
"@storybook/addon-actions": "^8.6.12",
"@storybook/addon-essentials": "^8.6.12",
"@storybook/addon-interactions": "^8.6.12",
"@storybook/addon-themes": "^8.6.12",
"@storybook/blocks": "^8.6.12",
"@storybook/html": "^8.6.12",
"@storybook/html-vite": "^8.6.12",
"@storybook/test": "^8.6.12",
"autoprefixer": "^10.4.21", "autoprefixer": "^10.4.21",
"caniuse-lite": "1.0.30001704", "caniuse-lite": "1.0.30001704",
"clean-css-cli": "^5.6.3", "clean-css-cli": "^5.6.3",
@ -59,7 +69,9 @@
"postcss-cli": "^11.0.1", "postcss-cli": "^11.0.1",
"postcss-scss": "^4.0.9", "postcss-scss": "^4.0.9",
"prettier": "^3.5.3", "prettier": "^3.5.3",
"sass": "^1.85.1" "sass": "^1.85.1",
"storybook": "^8.6.12",
"vite": "^6.2.5"
}, },
"browserslist": [ "browserslist": [
"defaults" "defaults"

48
stories/HTMLElement.ts Normal file
View file

@ -0,0 +1,48 @@
export const createHTMLElement = (element, { ...args }) => {
const elem: HTMLElement | null = document.createElement(element);
if (!elem) {
return null;
}
console.log("content", args.content instanceof Array);
if (args.content instanceof HTMLElement) {
elem.appendChild(args.content);
} else if (args.content instanceof Array) {
args.content.forEach((content) => {
if (content instanceof HTMLElement) {
elem.appendChild(content);
} else if (typeof content === "string") {
const textNode = document.createTextNode(content);
elem.appendChild(textNode);
}
});
} else if (typeof args.content === "string") {
const textNode = document.createTextNode(args.content);
elem.appendChild(textNode);
}
Object.keys(args).forEach((key) => {
// Skip the content key
if (key === "content") {
return;
}
// If the value is false or null or empty, skip it
if (!args[key]) {
return;
}
// If the value is a function, add it as an event listener
console.log("key", key, typeof args[key], typeof args[key] === "function");
if (typeof args[key] === "function") {
// If it starts with "on", we need to remove it
const eventKey = key.startsWith("on") ? key.substring(2) : key;
// We need to set the attribute as a callback
elem.addEventListener(eventKey, args[key]);
}
elem.setAttribute(key, args[key]);
});
return elem;
};

3
stories/Welcome.mdx Normal file
View file

@ -0,0 +1,3 @@
# Welcome to PicoCSS
This Storybook is a collection of all HTML elements and components available in PicoCSS. It is a great way to explore the library and see how different elements look and behave.

View file

@ -0,0 +1,17 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "DemarcatingEdits/Del",
tags: ["autodocs"],
args: {
content: "Content",
cite: "https://example.com",
datetime: "2023-10-01T12:00:00Z",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("del", args);
},
};
export const Default = {};

View file

@ -0,0 +1,17 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "DemarcatingEdits/Ins",
tags: ["autodocs"],
args: {
content: "Content",
cite: "https://example.com",
datetime: "2023-10-01T12:00:00Z",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("ins", args);
},
};
export const Default = {};

View file

@ -0,0 +1,18 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "EmbeddedContent/Embed",
tags: ["autodocs"],
args: {
src: "https://example.com",
type: "text/html",
width: 300,
height: 200,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("embed", args);
},
};
export const Default = {};

View file

@ -0,0 +1,18 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "EmbeddedContent/FencedFrame",
tags: ["autodocs"],
args: {
src: "https://example.com",
type: "text/html",
width: 300,
height: 200,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("fencedframe", args);
},
};
export const Default = {};

View file

@ -0,0 +1,29 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "EmbeddedContent/Iframe",
tags: ["autodocs"],
args: {
src: "https://example.com",
type: "text/html",
width: 300,
height: 200,
allow:
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
allowfullscreen: false,
allowpaymentrequest: false,
browsingtopics: false,
credentialless: true,
loading: "lazy",
name: "iframe-name",
refererpolicy: "no-referrer",
sandbox: "allow-same-origin allow-scripts",
srcdoc: "<p>Your browser does not support iframes.</p>",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("iframe", args);
},
};
export const Default = {};

View file

@ -0,0 +1,21 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "EmbeddedContent/Object",
tags: ["autodocs"],
args: {
content: "Content",
data: "https://example.com",
type: "text/html",
form: "form",
width: 300,
height: 200,
name: "objectName",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("object", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "EmbeddedContent/Picture",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("picture", args);
},
};
export const Default = {};

View file

@ -0,0 +1,22 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "EmbeddedContent/Source",
tags: ["autodocs"],
args: {
type: "video/mp4",
src: "https://www.example.com/video.mp4",
srcset:
"https://www.example.com/video_720p.mp4 720w, https://www.example.com/video_1080p.mp4 1080w",
sizes: "100vw",
media: "(min-width: 600px)",
height: 240,
width: 320,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("source", args);
},
};
export const Default = {};

View file

@ -0,0 +1,354 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<title>Class-less preview • Pico CSS</title>
<meta name="description" content="A class-less example, without dependencies.">
</head>
<body>
<!-- Header -->
<header>
<hgroup>
<h1>Pico</h1>
<p>A class-less example, without dependencies.</p>
</hgroup>
<nav>
<ul>
<li><a href="#" data-theme-switcher="auto">Auto</a></li>
<li><a href="#" data-theme-switcher="light">Light</a></li>
<li><a href="#" data-theme-switcher="dark">Dark</a></li>
</ul>
</nav>
</header>
<!-- ./ Header -->
<!-- Main -->
<main>
<!-- Preview -->
<section id="preview">
<h2>Preview</h2>
<p>
Sed ultricies dolor non ante vulputate hendrerit. Vivamus sit amet suscipit sapien. Nulla
iaculis eros a elit pharetra egestas.
</p>
<form>
<input type="text" name="firstname" placeholder="First name" aria-label="First name" required>
<input type="email" name="email" placeholder="Email address" aria-label="Email address"
autocomplete="email" required>
<button type="submit">Subscribe</button>
<fieldset>
<label for="terms">
<input type="checkbox" role="switch" id="terms" name="terms">
I agree to the
<a href="#" onclick="event.preventDefault()">Privacy Policy</a>
</label>
</fieldset>
</form>
</section>
<!-- ./ Preview -->
<!-- Typography-->
<section id="typography">
<h2>Typography</h2>
<p>
Aliquam lobortis vitae nibh nec rhoncus. Morbi mattis neque eget efficitur feugiat.
Vivamus porta nunc a erat mattis, mattis feugiat turpis pretium. Quisque sed tristique
felis.
</p>
<!-- Blockquote-->
<blockquote>
"Maecenas vehicula metus tellus, vitae congue turpis hendrerit non. Nam at dui sit amet
ipsum cursus ornare."
<footer>
<cite>- Phasellus eget lacinia</cite>
</footer>
</blockquote>
<!-- Lists-->
<h3>Lists</h3>
<ul>
<li>Aliquam lobortis lacus eu libero ornare facilisis.</li>
<li>Nam et magna at libero scelerisque egestas.</li>
<li>Suspendisse id nisl ut leo finibus vehicula quis eu ex.</li>
<li>Proin ultricies turpis et volutpat vehicula.</li>
</ul>
<!-- Inline text elements-->
<h3>Inline text elements</h3>
<p><a href="#" onclick="event.preventDefault()">Link</a></p>
<p><strong>Bold</strong></p>
<p><em>Italic</em></p>
<p><u>Underline</u></p>
<p><del>Deleted</del></p>
<p><ins>Inserted</ins></p>
<p><s>Strikethrough</s></p>
<p><small>Small </small></p>
<p>Text <sub>Sub</sub></p>
<p>Text <sup>Sup</sup></p>
<p>
<abbr title="Abbreviation" data-tooltip="Abbreviation">Abbr.</abbr>
</p>
<p><kbd>Kbd</kbd></p>
<p><mark>Highlighted</mark></p>
<!-- Headings-->
<h3>Heading 3</h3>
<p>
Integer bibendum malesuada libero vel eleifend. Fusce iaculis turpis ipsum, at efficitur
sem scelerisque vel. Aliquam auctor diam ut purus cursus fringilla. Class aptent taciti
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
</p>
<h4>Heading 4</h4>
<p>
Cras fermentum velit vitae auctor aliquet. Nunc non congue urna, at blandit nibh. Donec ac
fermentum felis. Vivamus tincidunt arcu ut lacus hendrerit, eget mattis dui finibus.
</p>
<h5>Heading 5</h5>
<p>
Donec nec egestas nulla. Sed varius placerat felis eu suscipit. Mauris maximus ante in
consequat luctus. Morbi euismod sagittis efficitur. Aenean non eros orci. Vivamus ut diam
sem.
</p>
<h6>Heading 6</h6>
<p>
Ut sed quam non mauris placerat consequat vitae id risus. Vestibulum tincidunt nulla ut
tortor posuere, vitae malesuada tortor molestie. Sed nec interdum dolor. Vestibulum id
auctor nisi, a efficitur sem. Aliquam sollicitudin efficitur turpis, sollicitudin
hendrerit ligula semper id. Nunc risus felis, egestas eu tristique eget, convallis in
velit.
</p>
<!-- Medias-->
<figure>
<img src="https://picsum.photos/200/300" alt="Minimal landscape">
<figcaption>
Image from
<a href="https://picsum.photos/200/300" target="_blank">unsplash.com</a>
</figcaption>
</figure>
</section>
<!-- ./ Typography-->
<!-- Form elements-->
<section id="form">
<form>
<h2>Form elements</h2>
<!-- Search -->
<label for="search">Search</label>
<input type="search" id="search" name="search" placeholder="Search">
<!-- Text -->
<label for="text">Text</label>
<input type="text" id="text" name="text" placeholder="Text">
<small>Curabitur consequat lacus at lacus porta finibus.</small>
<!-- Select -->
<label for="select">Select</label>
<select id="select" name="select" required>
<option value="" selected>Select…</option>
<option></option>
</select>
<!-- File browser -->
<label for="file">File browser
<input type="file" id="file" name="file">
</label>
<!-- Range slider control -->
<label for="range">Range slider
<input type="range" min="0" max="100" value="50" id="range" name="range">
</label>
<!-- States -->
<label for="valid">
Valid
<input type="text" id="valid" name="valid" placeholder="Valid" aria-invalid="false">
</label>
<label for="invalid">
Invalid
<input type="text" id="invalid" name="invalid" placeholder="Invalid" aria-invalid="true">
</label>
<label for="disabled">
Disabled
<input type="text" id="disabled" name="disabled" placeholder="Disabled" disabled>
</label>
<!-- Date-->
<label for="date">Date
<input type="date" id="date" name="date">
</label>
<!-- Time-->
<label for="time">Time
<input type="time" id="time" name="time">
</label>
<!-- Color-->
<label for="color">Color
<input type="color" id="color" name="color" value="#0eaaaa">
</label>
<!-- Checkboxes -->
<fieldset>
<legend><strong>Checkboxes</strong></legend>
<label for="checkbox-1">
<input type="checkbox" id="checkbox-1" name="checkbox-1" checked>
Checkbox
</label>
<label for="checkbox-2">
<input type="checkbox" id="checkbox-2" name="checkbox-2">
Checkbox
</label>
</fieldset>
<!-- Radio buttons -->
<fieldset>
<legend><strong>Radio buttons</strong></legend>
<label for="radio-1">
<input type="radio" id="radio-1" name="radio" value="radio-1" checked>
Radio button
</label>
<label for="radio-2">
<input type="radio" id="radio-2" name="radio" value="radio-2">
Radio button
</label>
</fieldset>
<!-- Switch -->
<fieldset>
<legend><strong>Switches</strong></legend>
<label for="switch-1">
<input type="checkbox" id="switch-1" name="switch-1" role="switch" checked>
Switch
</label>
<label for="switch-2">
<input type="checkbox" id="switch-2" name="switch-2" role="switch">
Switch
</label>
</fieldset>
<!-- Buttons -->
<input type="reset" value="Reset" onclick="event.preventDefault()">
<input type="submit" value="Submit" onclick="event.preventDefault()">
</form>
</section>
<!-- ./ Form elements-->
<!-- Modal -->
<section id="modal">
<h2>Modal</h2>
<button class="contrast" onclick="modalExample.showModal()">Launch demo modal</button>
</section>
<!-- ./ Modal -->
<!-- Accordions -->
<section id="accordions">
<h2>Accordions</h2>
<details>
<summary>Accordion 1</summary>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque urna diam,
tincidunt nec porta sed, auctor id velit. Etiam venenatis nisl ut orci consequat, vitae
tempus quam commodo. Nulla non mauris ipsum. Aliquam eu posuere orci. Nulla convallis
lectus rutrum quam hendrerit, in facilisis elit sollicitudin. Mauris pulvinar pulvinar
mi, dictum tristique elit auctor quis. Maecenas ac ipsum ultrices, porta turpis sit
amet, congue turpis.
</p>
</details>
<details open>
<summary>Accordion 2</summary>
<ul>
<li>Vestibulum id elit quis massa interdum sodales.</li>
<li>Nunc quis eros vel odio pretium tincidunt nec quis neque.</li>
<li>Quisque sed eros non eros ornare elementum.</li>
<li>Cras sed libero aliquet, porta dolor quis, dapibus ipsum.</li>
</ul>
</details>
</section>
<!-- ./ Accordions -->
<!-- Article-->
<article id="article">
<h2>Article</h2>
<p>
Nullam dui arcu, malesuada et sodales eu, efficitur vitae dolor. Sed ultricies dolor non
ante vulputate hendrerit. Vivamus sit amet suscipit sapien. Nulla iaculis eros a elit
pharetra egestas. Nunc placerat facilisis cursus. Sed vestibulum metus eget dolor pharetra
rutrum.
</p>
<footer>
<small>Duis nec elit placerat, suscipit nibh quis, finibus neque.</small>
</footer>
</article>
<!-- ./ Article-->
<!-- Group -->
<section id="group">
<h2>Group</h2>
<form>
<fieldset role="group">
<input name="email" type="email" placeholder="Enter your email" autocomplete="email">
<input type="submit" value="Subscribe">
</fieldset>
</form>
</section>
<!-- ./ Group -->
<!-- Progress -->
<section id="progress">
<h2>Progress bar</h2>
<progress id="progress-1" value="25" max="100"></progress>
<progress id="progress-2"></progress>
</section>
<!-- ./ Progress -->
<!-- Loading -->
<section id="loading">
<h2>Loading</h2>
<article aria-busy="true"></article>
<button aria-busy="true">Please wait…</button>
</section>
<!-- ./ Loading -->
</main>
<!-- ./ Main -->
<!-- Footer -->
<footer>
<small>Built with <a href="https://picocss.com">Pico</a>
<a href="https://github.com/picocss/examples/blob/master/v2-html-classless/index.html">Source
code</a></small>
</footer>
<!-- ./ Footer -->
<!-- Modal example -->
<dialog id="modalExample">
<article>
<header>
<button aria-label="Close" rel="prev" onclick="modalExample.close()"></button>
<h3>Confirm your action!</h3>
</header>
<p>
Cras sit amet maximus risus. Pellentesque sodales odio sit amet augue finibus
pellentesque. Nullam finibus risus non semper euismod.
</p>
<footer>
<button role="button" onclick="modalExample.close()">Cancel</button><button autofocus role="button"
onclick="modalExample.close()">Confirm</button>
</footer>
</article>
</dialog>
<!-- ./ Modal example -->
<!-- Minimal theme switcher -->
<script src="js/minimal-theme-switcher.js"></script>
</body>
</html>

View file

@ -0,0 +1,14 @@
import { expect, userEvent, within } from "@storybook/test";
// @ts-ignore
import AllHTML from "./classless.html?raw";
export default {
title: "Examples/PicoCSSClassless",
render: (args) => AllHTML,
parameters: {
// layout: "fullscreen",
},
};
export const Default = {};

View file

@ -0,0 +1,30 @@
import { createHTMLElement } from "../HTMLElement";
import { fn } from "@storybook/test";
export default {
title: "Forms/Button",
tags: ["autodocs"],
args: {
content: "Content",
disabled: false,
form: "",
formaction: "",
formenctype: "",
formmethod: "GET",
formnovalidate: false,
formtarget: "",
name: "",
popovertarget: "",
popovertargetaction: "toggle",
type: "button",
value: "",
onclick: fn(),
},
// Render the <html> element
render: (args) => {
return createHTMLElement("button", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Datalist",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("datalist", args);
},
};
export const Default = {};

View file

@ -0,0 +1,18 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Fieldset",
tags: ["autodocs"],
args: {
content: "Content",
disabled: false,
form: "form",
name: "name",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("fieldset", args);
},
};
export const Default = {};

View file

@ -0,0 +1,23 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Form",
tags: ["autodocs"],
args: {
content: "Content",
"accept-charset": "UTF-8",
name: "name",
rel: "noopener",
action: "action",
enctype: "application/x-www-form-urlencoded",
method: "get",
novalidate: false,
target: "_self",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("form", args);
},
};
export const Default = {};

View file

@ -0,0 +1,220 @@
import { render } from "sass-embedded";
import { createHTMLElement } from "../HTMLElement";
const inputTypes = [
"button",
"checkbox",
"color",
"date",
"datetime-local",
"email",
"file",
"hidden",
"image",
"month",
"number",
"password",
"radio",
"range",
"reset",
"search",
"submit",
"tel",
"text",
"time",
"url",
"week",
];
export default {
title: "Forms/Input",
tags: ["autodocs"],
argTypes: {
type: {
control: "select",
options: inputTypes,
},
},
args: {
content: "Content",
accept: "text/plain",
alt: "Alt text",
capture: "camera",
checked: true,
dirname: "input-dir",
disabled: false,
form: "form-id",
formaction: "action-url",
formenctype: "application/x-www-form-urlencoded",
formmethod: "GET",
formnovalidate: false,
formtarget: "_blank",
height: 100,
list: "datalist-id",
max: 100,
maxlength: 50,
min: 0,
minlength: 5,
multiple: true,
name: "input-name",
pattern: "[a-zA-Z0-9]",
placeholder: "Placeholder text",
popvertarget: "popover-target-id",
popovertargetaction: "toggle",
readonly: false,
required: true,
size: 20,
src: "https://picsum.photos/200/300",
step: 1,
type: "text",
value: "Input value",
width: 200,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("input", args);
},
};
export const Default = {};
// All input types
export const AllInputTypes = {
render: (args) => {
const fragment = document.createDocumentFragment();
for (const type of inputTypes) {
args.type = type;
// Create a new input element for each type
const element = createHTMLElement("input", {
...args,
type: type,
placeholder: `Input type: ${type}`,
});
if (!element) {
console.error(`Failed to create input element for type: ${type}`);
continue;
}
// Add the element to the array
fragment.appendChild(element);
}
return fragment;
},
};
export const WithLabelSibling = {
args: {
labelText: "Label text",
},
render: (args) => {
// Fragment
const fragment = document.createDocumentFragment();
const label = createHTMLElement("label", {
content: args.labelText,
});
const input = createHTMLElement("input", {
...args,
type: args.type,
});
if (!input) {
console.error(`Failed to create input element for type: ${args.type}`);
return;
}
// Append the label to the fragment
fragment.appendChild(label);
// Append the input to the fragment
fragment.appendChild(input);
// Return the fragment
return fragment;
},
};
export const AsChildOfLabel = {
args: {
labelText: "Label text",
},
render: (args) => {
// Fragment
const fragment = document.createDocumentFragment();
const label = createHTMLElement("label", {
content: args.labelText,
});
const input = createHTMLElement("input", {
...args,
type: args.type,
});
if (!input) {
console.error(`Failed to create input element for type: ${args.type}`);
return;
}
label.appendChild(input);
fragment.appendChild(label);
// Return the fragment
return fragment;
},
};
export const AsPrependedChildOfLabel = {
args: {
labelText: "Label text",
},
render: (args) => {
// Fragment
const fragment = document.createDocumentFragment();
const label = createHTMLElement("label", {
content: args.labelText,
});
const input = createHTMLElement("input", {
...args,
type: args.type,
});
if (!input) {
console.error(`Failed to create input element for type: ${args.type}`);
return;
}
label.prepend(input);
fragment.appendChild(label);
// Return the fragment
return fragment;
},
};
export const Inline = {
args: {
labelText: "Label text",
},
render: (args) => {
// We want to encapsulate the input with text before and after it, e.g. have the input in the middle of a sentence
// Fragment
const fragment = document.createDocumentFragment();
const label = createHTMLElement("label", {
content: args.labelText,
});
const input = createHTMLElement("input", {
...args,
type: args.type,
});
if (!input) {
console.error(`Failed to create input element for type: ${args.type}`);
return;
}
// Create a span to encapsulate the input
const span = document.createElement("span");
span.appendChild(input);
// Add text before the input
const beforeText = document.createTextNode("Before text ");
span.prepend(beforeText);
// Add text after the input
const afterText = document.createTextNode(" After text goes here");
span.appendChild(afterText);
// Append the span to the label
label.appendChild(span);
// Append the label to the fragment
fragment.appendChild(label);
// Return the fragment
return fragment;
},
};

View file

@ -0,0 +1,16 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Label",
tags: ["autodocs"],
args: {
content: "Content",
for: "input-id",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("label", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Legend",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("legend", args);
},
};
export const Default = {};

View file

@ -0,0 +1,22 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Meter",
tags: ["autodocs"],
args: {
content: "Content",
value: 0.5,
min: 0,
max: 1,
low: 0.2,
high: 0.8,
optimum: 0.5,
form: "form",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("meter", args);
},
};
export const Default = {};

View file

@ -0,0 +1,17 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Optgroup",
tags: ["autodocs"],
args: {
content: "Content",
label: "Label",
disabled: false,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("optgroup", args);
},
};
export const Default = {};

View file

@ -0,0 +1,19 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Option",
tags: ["autodocs"],
args: {
content: "Content",
disabled: false,
label: "Label",
selected: false,
value: "Value",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("option", args);
},
};
export const Default = {};

View file

@ -0,0 +1,18 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Output",
tags: ["autodocs"],
args: {
content: "Content",
for: "for",
form: "form",
name: "name",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("output", args);
},
};
export const Default = {};

View file

@ -0,0 +1,17 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Progress",
tags: ["autodocs"],
args: {
content: "Content",
max: 100,
value: 50,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("progress", args);
},
};
export const Default = {};

View file

@ -0,0 +1,22 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Select",
tags: ["autodocs"],
args: {
content: "Content",
autocomplete: "on",
disabled: false,
form: "form",
multiple: false,
name: "name",
required: false,
size: 0,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("select", args);
},
};
export const Default = {};

View file

@ -0,0 +1,27 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Forms/Textarea",
tags: ["autodocs"],
args: {
content: "Content",
cols: 20,
dirname: "dirname",
disabled: false,
form: "form",
maxlength: 100,
minlength: 0,
name: "name",
placeholder: "placeholder",
readonly: false,
required: false,
rows: 2,
wrap: "soft",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("textarea", args);
},
};
export const Default = {};

20
stories/html.stories.ts Normal file
View file

@ -0,0 +1,20 @@
export default {
title: "Example/HTML",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return `<html>
<head>
<title>HTML Story</title>
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>`;
},
};
export const Default = {};

View file

@ -0,0 +1,24 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "ImageAndMultimedia/Area",
tags: ["autodocs"],
args: {
content: "Content",
shape: "poly",
coords: "129,0,260,95,129,138",
href: "https://developer.mozilla.org/docs/Web/HTTP",
alt: "Content",
download: "download",
ping: "https://developer.mozilla.org/docs/Web/HTTP",
referrerpolicy: "no-referrer",
rel: "noopener",
target: "_blank",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("area", args);
},
};
export const Default = {};

View file

@ -0,0 +1,23 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "ImageAndMultimedia/Audio",
tags: ["autodocs"],
args: {
src: "https://www.w3schools.com/html/horse.mp3",
controls: true,
autoplay: false,
controlslist: "nodownload",
crossorigin: "anonymous",
disableremoteplayback: false,
loop: false,
muted: false,
preload: "auto",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("audio", args);
},
};
export const Default = {};

View file

@ -0,0 +1,30 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "ImageAndMultimedia/Img",
tags: ["autodocs"],
args: {
src: "https://picsum.photos/200/300",
alt: "Sample Image",
attributionsrc: "https://example.com/attribution",
crossorigin: "anonymous",
decoding: "async",
elementtiming: "image",
fetchpriority: "high",
height: 300,
width: 200,
ismap: false,
loading: "lazy",
referrerpolicy: "no-referrer",
sizes: "(max-width: 600px) 100vw, 50vw",
srcset:
"https://picsum.photos/200/300 200w, https://picsum.photos/400/600 400w",
usemap: "#map",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("img", args);
},
};
export const Default = {};

View file

@ -0,0 +1,16 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "ImageAndMultimedia/Map",
tags: ["autodocs"],
args: {
content: "Content",
name: "name",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("map", args);
},
};
export const Default = {};

View file

@ -0,0 +1,19 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "ImageAndMultimedia/Track",
tags: ["autodocs"],
args: {
src: "https://www.w3schools.com/html/mov_bbb.vtt",
default: "default",
kind: "captions",
label: "English",
srclang: "en",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("track", args);
},
};
export const Default = {};

View file

@ -0,0 +1,28 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "ImageAndMultimedia/Video",
tags: ["autodocs"],
args: {
src: "https://www.w3schools.com/html/mov_bbb.mp4",
controls: true,
autoplay: false,
controlslist: "nodownload",
crossorigin: "anonymous",
disablepictureinpicture: false,
disableremoteplayback: false,
height: 240,
width: 320,
loop: false,
muted: false,
playsinline: false,
poster: "https://picsum.photos/200/300",
preload: "auto",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("video", args);
},
};
export const Default = {};

View file

@ -0,0 +1,23 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/A",
tags: ["autodocs"],
args: {
content: "Content",
href: "https://example.com",
target: "_blank",
download: "file.txt",
rel: "noopener noreferrer",
hreflang: "en",
ping: "https://example.com/ping",
referrerpolicy: "no-referrer",
type: "text/html",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("a", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Abbr",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("abbr", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/B",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("b", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Bdi",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("bdi", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Bdo",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("bdo", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/BR",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("br", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Cite",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("cite", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Code",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return `<data>${args.content}</code>`;
},
};
export const Default = {};

View file

@ -0,0 +1,16 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Data",
tags: ["autodocs"],
args: {
content: "Content",
value: "Value",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("data", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Dfn",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("dfn", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Em",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("em", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/I",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("i", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Kbd",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("kbd", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Mark",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("mark", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Q",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("q", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Rp",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("rp", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Rt",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("rt", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Ruby",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("ruby", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/S",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("s", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Samp",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("samp", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Small",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("small", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Span",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("span", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Strong",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("strong", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Sub",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("sub", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Sup",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("sup", args);
},
};
export const Default = {};

View file

@ -0,0 +1,16 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Time",
tags: ["autodocs"],
args: {
content: "Content",
datetime: "2023-10-01T12:00:00Z",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("time", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/U",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("u", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Var",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("var", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InlineTextSemantics/Wbr",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("wbr", args);
},
};
export const Default = {};

View file

@ -0,0 +1,23 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InteractiveElements/Details",
tags: ["autodocs"],
args: {
content: "Content",
name: "details",
open: false,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("details", args);
},
};
export const Default = {};
export const Open = {
args: {
open: true,
},
};

View file

@ -0,0 +1,31 @@
import { createHTMLElement } from "../HTMLElement";
// Import the details and summary stories
import Details from "./details.stories";
import Summary from "./summary.stories";
export default {
title: "InteractiveElements/DetailsAndSummary",
tags: ["autodocs"],
args: {
...Details.args,
...Summary.args,
content: "Details and Summary content",
summary: "Summary Label",
},
render: (args) => {
return createHTMLElement("details", {
...args,
content: [
createHTMLElement("summary", {
...args,
content: args.summary,
}),
args.content,
],
});
},
};
export const Default = {};

View file

@ -0,0 +1,16 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InteractiveElements/Dialog",
tags: ["autodocs"],
args: {
content: "Content",
open: false,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("dialog", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "InteractiveElements/Summary",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("summary", args);
},
};
export const Default = {};

View file

@ -0,0 +1,17 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Scripting/Canvas",
tags: ["autodocs"],
args: {
content: "Content",
height: 100,
width: 100,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("canvas", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Scripting/Noscript",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("noscript", args);
},
};
export const Default = {};

View file

@ -0,0 +1,26 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Scripting/Script",
tags: ["autodocs"],
args: {
content: "Content",
async: false,
attributionsrc: "",
blocking: false,
crossorigin: "",
defer: false,
fetchpriority: "auto",
integrity: "",
nomodule: false,
referrerpolicy: "no-referrer",
src: "",
type: "text/javascript",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("script", args);
},
};
export const Default = {};

View file

@ -0,0 +1,38 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Address",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return `<address
${Object.entries(args)
.map(([key, value]) => {
if (!value) {
return "";
}
return `${key}="${value}"`;
})
.join(" ")}
>${args.content}</address>`;
},
};
export const Default = {};
export const MozillaExample = {
render: (args) => `<address>
You can contact author at
<a href="http://www.example.com/contact">www.example.com</a>.<br />
If you see any bugs, please
<a href="mailto:webmaster@example.com">contact webmaster</a>.<br />
You may also want to visit us:<br />
Mozilla Foundation<br />
331 E Evelyn Ave<br />
Mountain View, CA 94041<br />
USA
</address>`,
};

View file

@ -0,0 +1,70 @@
import { render } from "sass-embedded";
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Article",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return `<article>Article Content</article>`;
},
};
export const Default = {};
export const WithContent = {
render: (args) => {
return createHTMLElement("article", {
content: `<header><h1>Article Title</h1></header>
<p>This is the first paragraph of the article.</p>
<p>This is the second paragraph of the article.</p>
<footer><p>Author: John Doe</p></footer>`,
});
},
};
export const MozillaExample = {
render: (args) => `<article>
<h2>Jurassic Park</h2>
<section >
<h3>Review</h3>
<p>Dinos were great!</p>
</section>
<section>
<h3>User reviews</h3>
<article>
<h4>Too scary!</h4>
<p>Way too scary for me.</p>
<footer>
<p>
Posted on
<time datetime="2015-05-16 19:00">May 16</time>
by Lisa.
</p>
</footer>
</article>
<article>
<h4>Love the dinos!</h4>
<p>I agree, dinos are my favorite.</p>
<footer>
<p>
Posted on
<time datetime="2015-05-17 19:00">May 17</time>
by Tom.
</p>
</footer>
</article>
</section>
<footer>
<p>
Posted on
<time datetime="2015-05-15 19:00">May 15</time>
by Staff.
</p>
</footer>
</article>
`,
};

View file

@ -0,0 +1,29 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Aside",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return `<aside>Aside content</aside>`;
},
};
export const Default = {};
export const MozillaExample = {
render: (args) => `<article>
<p>
The Disney movie <cite>The Little Mermaid</cite> was first released to
theatres in 1989.
</p>
<aside>
<p>The movie earned $87 million during its initial release.</p>
</aside>
<p>More info about the movie</p>
</article>
`,
};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Body",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("body", args);
},
};
export const Default = {};

View file

@ -0,0 +1,31 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Footer",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("footer", args);
},
};
export const Default = {};
export const MozillaExample = {
render: (args) => `<h3>FIFA World Cup top goalscorers</h3>
<ol>
<li>Miroslav Klose, 16</li>
<li>Ronaldo Nazário, 15</li>
<li>Gerd Müller, 14</li>
</ol>
<footer>
<small>
Copyright © 2023 Football History Archives. All Rights Reserved.
</small>
</footer>
`,
};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/H1",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("h1", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/H2",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("h2", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/H3",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("h3", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/H4",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("h4", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/H5",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("h5", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/H6",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("h6", args);
},
};
export const Default = {};

View file

@ -0,0 +1,39 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Header",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("header", args);
},
};
export const Default = {};
export const MozillaExamplePageHeader = {
render: (args) => `<header>
<h1>Main Page Title</h1>
<img src="https://picsum.photos/200/300" alt="MDN logo" />
</header>`,
};
export const MozillaExampleArticleHeader = {
render: (args) => `<article>
<header>
<h2>The Planet Earth</h2>
<p>
Posted on Wednesday, <time datetime="2017-10-04">4 October 2017</time> by
Jane Smith
</p>
</header>
<p>
We live on a planet that's blue and green, with so many things still unseen.
</p>
<p><a href="https://example.com/the-planet-earth/">Continue reading</a></p>
</article>
`,
};

View file

@ -0,0 +1,30 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/HGroup",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("hgroup", args);
},
};
export const Default = {};
export const MozillaExample = {
render: (args) => `<hgroup id="document-title">
<h1>HTML: Living Standard</h1>
<p>Last Updated 12 July 2022</p>
</hgroup>
<p>Some intro to the document.</p>
<h2>Table of contents</h2>
<ol id="toc">
</ol>
<h2>First section</h2>
<p>Some intro to the first section.</p>
`,
};

View file

@ -0,0 +1,38 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Main",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("main", args);
},
};
export const Default = {};
export const MozillaExample = {
render: (args) => `<main>
<h1>Apples</h1>
<p>The apple is the pomaceous fruit of the apple tree.</p>
<article>
<h2>Red Delicious</h2>
<p>
These bright red apples are the most common found in many supermarkets.
</p>
<p></p>
<p></p>
</article>
<article>
<h2>Granny Smith</h2>
<p>These juicy, green apples make a great filling for apple pies.</p>
<p></p>
<p></p>
</article>
</main>`,
};

View file

@ -0,0 +1,49 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Nav",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("nav", args);
},
};
export const Default = {};
export const MozillaExample = {
render: (args) => `<nav class="menu">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
`,
};
export const MozillaExampleInProse = {
render: (args) => `<nav>
<h2>Navigation</h2>
<p>
You are on my home page. To the north lies <a href="/blog">my blog</a>, from
whence the sounds of battle can be heard. To the east you can see a large
mountain, upon which many <a href="/school">school papers</a> are littered.
Far up this mountain you can spy a little figure who appears to be me,
desperately scribbling a <a href="/school/thesis">thesis</a>.
</p>
<p>
To the west are several exits. One fun-looking exit is labeled
<a href="https://games.example.com/">"games"</a>. Another more
boring-looking exit is labeled <a href="https://isp.example.net/">ISP</a>.
</p>
<p>
To the south lies a dark and dank <a href="/about">contacts page</a>.
Cobwebs cover its disused entrance, and at one point you see a rat run
quickly out of the page.
</p>
</nav>`,
};

View file

@ -0,0 +1,57 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Search",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("search", args);
},
};
export const Default = {};
export const MozillaExample = {
render: (args) => `<search>
<label>
Find and filter your query
<input type="search" id="query" />
</label>
<label>
<input type="checkbox" id="exact-only" />
Exact matches only
</label>
<section>
<h3>Results:</h3>
<ul id="results">
<!-- search result content -->
</ul>
<output id="no-results">
<!-- no results content -->
</output>
</section>
</search>
`,
};
export const MozillaExample2 = {
render: (args) => `<header>
<h1>Car rental agency</h1>
<search title="Website">...</search>
</header>
<main>
<h2>Cars available for rent</h2>
<search title="Cars">
<h3>Filter results</h3>
...
</search>
<article>
<!-- search result content -->
</article>
</main>
`,
};

View file

@ -0,0 +1,28 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "Sectioning/Section",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("section", args);
},
};
export const Default = {};
export const MozillaExample = {
render: (args) => `<section>
<a href="#">Previous article</a>
<a href="#">Next article</a>
</section><section>
<button class="reply">Reply</button>
<button class="reply-all">Reply to all</button>
<button class="fwd">Forward</button>
<button class="del">Delete</button>
</section>
`,
};

View file

@ -0,0 +1,16 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "SvgAndMathML/Math",
tags: ["autodocs"],
args: {
content: "Content",
display: "block",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("math", args);
},
};
export const Default = {};

View file

@ -0,0 +1,21 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "SvgAndMathML/SVG",
tags: ["autodocs"],
args: {
content: "Content",
height: 100,
width: 100,
preserveAspectRatio: "xMidYMid meet",
viewBox: "0 0 100 100",
x: 0,
y: 0,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("svg", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "TableContent/Caption",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("caption", args);
},
};
export const Default = {};

View file

@ -0,0 +1,16 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "TableContent/Col",
tags: ["autodocs"],
args: {
content: "Content",
span: 1,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("col", args);
},
};
export const Default = {};

View file

@ -0,0 +1,16 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "TableContent/Colgroup",
tags: ["autodocs"],
args: {
content: "Content",
span: 1,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("colgroup", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "TableContent/Table",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("table", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "TableContent/TBody",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("tbody", args);
},
};
export const Default = {};

View file

@ -0,0 +1,18 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "TableContent/TD",
tags: ["autodocs"],
args: {
content: "Content",
colspan: 1,
headers: "",
rowspan: 1,
},
// Render the <html> element
render: (args) => {
return createHTMLElement("td", args);
},
};
export const Default = {};

View file

@ -0,0 +1,15 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "TableContent/TFoot",
tags: ["autodocs"],
args: {
content: "Content",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("tfoot", args);
},
};
export const Default = {};

View file

@ -0,0 +1,20 @@
import { createHTMLElement } from "../HTMLElement";
export default {
title: "TableContent/TH",
tags: ["autodocs"],
args: {
content: "Content",
abbr: "Abbreviation",
colspan: 2,
headers: "Header",
rowspan: 2,
scope: "col",
},
// Render the <html> element
render: (args) => {
return createHTMLElement("th", args);
},
};
export const Default = {};

Some files were not shown because too many files have changed in this diff Show more