diff --git a/src/stories/Badge.js b/src/stories/Badge.js new file mode 100644 index 00000000..99b6c017 --- /dev/null +++ b/src/stories/Badge.js @@ -0,0 +1,78 @@ +const classNames = ["font-semibold"]; + +const getColorClassNames = (color) => { + switch (color) { + case "default": + return ["bg-blue-100 text-blue-800 dark:bg-blue-200 dark:text-blue-800"]; + case "dark": + return ["bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300"]; + case "red": + return ["bg-red-100 text-red-800 dark:bg-red-200 dark:text-red-9000"]; + case "green": + return [ + "bg-green-100 text-green-800 dark:bg-green-200 dark:text-green-900", + ]; + case "yellow": + return [ + "bg-yellow-100 text-yellow-800 dark:bg-yellow-200 dark:text-yellow-900", + ]; + case "indigo": + return [ + "bg-indigo-100 text-indigo-800 dark:bg-indigo-200 dark:text-indigo-900", + ]; + case "purple": + return [ + "bg-purple-100 text-purple-800 dark:bg-purple-200 dark:text-purple-900", + ]; + case "pink": + return ["bg-pink-100 text-pink-800 dark:bg-pink-200 dark:text-pink-900"]; + } +}; + +const getLargerClassNames = (larger) => { + return larger ? ["text-sm font-medium"] : ["text-xs"]; +}; + +const getIconClassNames = (icon) => { + return icon ? ["inline-flex items-center"] : []; +}; + +const getOnlyIconClassNames = (onlyIcon) => { + return onlyIcon + ? ["inline-flex items-center p-1 text-sm font-semibold text rounded-full "] + : ["rounded px-2.5 py-0.5"]; +}; + +export const createBadge = ({ + color = "default", + label = "Default", + larger = false, + href = null, + displayMode, +}) => { + const badge = document.createElement(href ? "a" : "span"); + + if (href) { + badge.href = href; + } + + if (displayMode === "icon" || displayMode === "icon + text") { + badge.innerHTML = ``; + } + + if (displayMode === "text" || displayMode === "icon + text") { + badge.append(label); + } + + const onlyIcon = displayMode == "icon"; + const icon = displayMode != "text"; + + badge.className = [ + ...classNames, + ...getColorClassNames(color), + ...getLargerClassNames(larger), + ...getIconClassNames(icon), + ...getOnlyIconClassNames(onlyIcon), + ].join(" "); + return badge; +}; diff --git a/src/stories/Badge.stories.js b/src/stories/Badge.stories.js new file mode 100644 index 00000000..3b1a15b2 --- /dev/null +++ b/src/stories/Badge.stories.js @@ -0,0 +1,93 @@ +import { createBadge } from "./Badge"; + +export default { + title: "Example/Badge", + argTypes: { + label: { + control: { + type: "text", + }, + defaultValue: { + summary: "Default", + }, + }, + color: { + control: "select", + options: [ + "default", + "dark", + "red", + "green", + "yellow", + "indigo", + "purple", + "pink", + ], + }, + larger: { + control: "boolean", + description: + "Use the `text-sm` to create a larger variant of the badges.", + defaultValue: { + summary: "false", + }, + }, + href: { + description: "Use badges as anchor `a` element to link to another page", + control: { + type: "text", + }, + }, + displayMode: { + control: "radio", + options: ["text", "icon", "icon + text"], + description: "Use `SVG` icons inside the badge elements", + defaultValue: { + summary: "Default", + }, + }, + }, +}; + +const Template = ({ label, ...args }) => { + return createBadge({ label, ...args }); +}; + +export const Default = Template.bind({}); +Default.storyName = "Default"; +Default.args = { + color: "default", + label: "Default", + displayMode: "text", +}; + +export const Larger = Template.bind({}); +Larger.storyName = "Larger"; +Larger.args = { + label: "Default", + larger: true, + displayMode: "text", +}; + +export const WithLink = Template.bind({}); +WithLink.storyName = "WithLink"; +WithLink.args = { + label: "Default", + larger: false, + displayMode: "text", + href: "http://flowbite.com", +}; + +export const WithIcon = Template.bind({}); +WithIcon.storyName = "WithIcon"; +WithIcon.args = { + label: "default", + displayMode: "icon + text", +}; + +export const OnlyIcon = Template.bind({}); +OnlyIcon.storyName = "OnlyIcon"; +OnlyIcon.args = { + label: "default", + displayMode: "icon", +};