@helpwave/hightide
Version:
helpwave's component and theming library
395 lines (389 loc) • 14.2 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/components/layout-and-navigation/FAQSection.tsx
var FAQSection_exports = {};
__export(FAQSection_exports, {
FAQSection: () => FAQSection
});
module.exports = __toCommonJS(FAQSection_exports);
var import_clsx2 = __toESM(require("clsx"));
// src/components/layout-and-navigation/Expandable.tsx
var import_react = require("react");
var import_lucide_react = require("lucide-react");
var import_clsx = __toESM(require("clsx"));
// src/util/noop.ts
var noop = () => void 0;
// src/components/layout-and-navigation/Expandable.tsx
var import_jsx_runtime = require("react/jsx-runtime");
var ExpansionIcon = ({ isExpanded, className }) => {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_lucide_react.ChevronDown,
{
className: (0, import_clsx.default)(
"min-w-6 w-6 min-h-6 h-6 transition-transform duration-200 ease-in-out",
{ "rotate-180": isExpanded },
className
)
}
);
};
var Expandable = (0, import_react.forwardRef)(function Expandable2({
children,
label,
icon,
isExpanded = false,
onChange = noop,
clickOnlyOnHeader = true,
disabled = false,
className,
headerClassName,
contentClassName,
contentExpandedClassName
}, ref) {
const defaultIcon = (0, import_react.useCallback)((expanded) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExpansionIcon, { isExpanded: expanded }), []);
icon ??= defaultIcon;
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
"div",
{
ref,
className: (0, import_clsx.default)("flex-col-0 bg-surface text-on-surface group rounded-lg shadow-sm", { "cursor-pointer": !clickOnlyOnHeader && !disabled }, className),
onClick: () => !clickOnlyOnHeader && !disabled && onChange(!isExpanded),
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
"div",
{
className: (0, import_clsx.default)(
"flex-row-2 py-2 px-4 rounded-lg justify-between items-center bg-surface text-on-surface select-none",
{
"group-hover:brightness-97": !isExpanded,
"hover:brightness-97": isExpanded && !disabled,
"cursor-pointer": clickOnlyOnHeader && !disabled
},
headerClassName
),
onClick: () => clickOnlyOnHeader && !disabled && onChange(!isExpanded),
children: [
label,
icon(isExpanded)
]
}
),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
className: (0, import_clsx.default)(
"flex-col-2 px-4 transition-all duration-300 ease-in-out",
{
[(0, import_clsx.default)("max-h-96 opacity-100 pb-2 overflow-y-auto", contentExpandedClassName)]: isExpanded,
"max-h-0 opacity-0 overflow-hidden": !isExpanded
},
contentClassName
),
children
}
)
]
}
);
});
var ExpandableUncontrolled = (0, import_react.forwardRef)(function ExpandableUncontrolled2({
isExpanded,
onChange = noop,
...props
}, ref) {
const [usedIsExpanded, setUsedIsExpanded] = (0, import_react.useState)(isExpanded);
(0, import_react.useEffect)(() => {
setUsedIsExpanded(isExpanded);
}, [isExpanded]);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
Expandable,
{
...props,
ref,
isExpanded: usedIsExpanded,
onChange: (value) => {
onChange(value);
setUsedIsExpanded(value);
}
}
);
});
// src/components/layout-and-navigation/MarkdownInterpreter.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
var astNodeInserterType = ["helpwave", "newline"];
var ASTNodeInterpreter = ({
node,
isRoot = false,
className = ""
}) => {
switch (node.type) {
case "newline":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("br", {});
case "text":
return isRoot ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className, children: node.text }) : node.text;
case "helpwave":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-bold font-space no-underline", children: "helpwave" });
case "none":
return isRoot ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className, children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
ASTNodeInterpreter,
{
node: value
},
index
)) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ASTNodeInterpreter, { node: value }, index)) });
case "bold":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ASTNodeInterpreter, { node: value }, index)) });
case "italic":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ASTNodeInterpreter, { node: value }, index)) });
case "underline":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("u", { children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ASTNodeInterpreter, { node: value }, index)) });
case "font-space":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-space", children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
ASTNodeInterpreter,
{
node: value
},
index
)) });
case "primary":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-primary", children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
ASTNodeInterpreter,
{
node: value
},
index
)) });
case "secondary":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-secondary", children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
ASTNodeInterpreter,
{
node: value
},
index
)) });
case "warn":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-warning", children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
ASTNodeInterpreter,
{
node: value
},
index
)) });
case "positive":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-positive", children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
ASTNodeInterpreter,
{
node: value
},
index
)) });
case "negative":
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-negative", children: node.children.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
ASTNodeInterpreter,
{
node: value
},
index
)) });
default:
return null;
}
};
var modifierIdentifierMapping = [
{ id: "i", name: "italic" },
{ id: "b", name: "bold" },
{ id: "u", name: "underline" },
{ id: "space", name: "font-space" },
{ id: "primary", name: "primary" },
{ id: "secondary", name: "secondary" },
{ id: "warn", name: "warn" },
{ id: "positive", name: "positive" },
{ id: "negative", name: "negative" }
];
var inserterIdentifierMapping = [
{ id: "helpwave", name: "helpwave" },
{ id: "newline", name: "newline" }
];
var parseMarkdown = (text, commandStart = "\\", open = "{", close = "}") => {
let start = text.indexOf(commandStart);
const children = [];
while (text !== "") {
if (start === -1) {
children.push({
type: "text",
text
});
break;
}
children.push(parseMarkdown(text.substring(0, start)));
text = text.substring(start);
if (text.length <= 1) {
children.push({
type: "text",
text
});
text = "";
continue;
}
const simpleReplace = [commandStart, open, close];
if (simpleReplace.some((value) => text[1] === value)) {
children.push({
type: "text",
text: simpleReplace.find((value) => text[1] === value)
});
text = text.substring(2);
start = text.indexOf(commandStart);
continue;
}
const inserter = inserterIdentifierMapping.find((value) => text.substring(1).startsWith(value.id));
if (inserter) {
children.push({
type: inserter.name
});
text = text.substring(inserter.id.length + 1);
start = text.indexOf(commandStart);
continue;
}
const modifier = modifierIdentifierMapping.find((value) => text.substring(1).startsWith(value.id));
if (modifier) {
if (text[modifier.id.length + 1] !== open) {
children.push({
type: "text",
text: text.substring(0, modifier.id.length + 1)
});
text = text.substring(modifier.id.length + 2);
start = text.indexOf(commandStart);
continue;
}
let closing = -1;
let index = modifier.id.length + 2;
let counter = 1;
let escaping = false;
while (index < text.length) {
if (text[index] === open && !escaping) {
counter++;
}
if (text[index] === close && !escaping) {
counter--;
if (counter === 0) {
closing = index;
break;
}
}
escaping = text[index] === commandStart;
index++;
}
if (closing !== -1) {
children.push({
type: modifier.name,
children: [parseMarkdown(text.substring(modifier.id.length + 2, closing))]
});
text = text.substring(closing + 1);
start = text.indexOf(commandStart);
continue;
}
}
children.push({
type: "text",
text: text[0]
});
text = text.substring(1);
start = text.indexOf(commandStart);
}
return {
type: "none",
children
};
};
var optimizeTree = (node) => {
if (node.type === "text") {
return !node.text ? void 0 : node;
}
if (astNodeInserterType.some((value) => value === node.type)) {
return node;
}
const currentNode = node;
if (currentNode.children.length === 0) {
return void 0;
}
let children = [];
for (let i = 0; i < currentNode.children.length; i++) {
const child = optimizeTree(currentNode.children[i]);
if (!child) {
continue;
}
if (child.type === "none") {
children.push(...child.children);
} else {
children.push(child);
}
}
currentNode.children = children;
children = [];
for (let i = 0; i < currentNode.children.length; i++) {
const child = currentNode.children[i];
if (child) {
if (child.type === "text" && children[children.length - 1]?.type === "text") {
children[children.length - 1].text += child.text;
} else {
children.push(child);
}
}
}
currentNode.children = children;
return currentNode;
};
var MarkdownInterpreter = ({ text, className }) => {
const tree = parseMarkdown(text);
const optimizedTree = optimizeTree(tree);
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ASTNodeInterpreter, { node: optimizedTree, isRoot: true, className });
};
// src/components/layout-and-navigation/FAQSection.tsx
var import_jsx_runtime3 = require("react/jsx-runtime");
var FAQSection = ({
entries,
expandableClassName
}) => {
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-col-4", children: entries.map(({ id, title, content, ...restProps }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
ExpandableUncontrolled,
{
...restProps,
label: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { id, className: "textstyle-title-md", children: title }),
clickOnlyOnHeader: false,
icon: (expanded) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ExpansionIcon, { isExpanded: expanded, className: "text-primary" }),
className: (0, import_clsx2.default)("rounded-xl", expandableClassName),
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mt-2", children: content.type === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MarkdownInterpreter, { text: content.value }) : content.value })
},
id
)) });
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
FAQSection
});
//# sourceMappingURL=FAQSection.js.map