UNPKG

notion-design-system

Version:

A comprehensive Notion-inspired design system built with React, TypeScript, and Tailwind CSS

734 lines (659 loc) 38.7 kB
import { jsxs, jsx, Fragment } from 'react/jsx-runtime'; import { forwardRef, createElement, useState, useRef, useEffect } from 'react'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n} var Button = function (_a) { var children = _a.children, className = _a.className, _b = _a.variant, variant = _b === void 0 ? 'primary' : _b, _c = _a.size, size = _c === void 0 ? 'md' : _c, _d = _a.disabled, disabled = _d === void 0 ? false : _d, _e = _a.loading, loading = _e === void 0 ? false : _e, onClick = _a.onClick, _f = _a.type, type = _f === void 0 ? 'button' : _f, icon = _a.icon, _g = _a.iconPosition, iconPosition = _g === void 0 ? 'left' : _g, props = __rest(_a, ["children", "className", "variant", "size", "disabled", "loading", "onClick", "type", "icon", "iconPosition"]); var baseClasses = 'notion-button-base disabled:opacity-50 disabled:cursor-not-allowed'; var variantClasses = { primary: 'bg-notion-blue text-white hover:bg-notion-blue-dark active:bg-notion-blue-dark', secondary: 'bg-notion-bg-tertiary text-notion-text-primary hover:bg-notion-border-hover border border-notion-border', ghost: 'text-notion-text-primary hover:bg-notion-bg-tertiary', danger: 'bg-notion-red text-white hover:bg-notion-red-dark active:bg-notion-red-dark', }; var sizeClasses = { sm: 'px-3 py-1.5 text-notion-sm gap-1.5', md: 'px-4 py-2 text-notion-base gap-2', lg: 'px-6 py-3 text-notion-lg gap-2.5', }; var darkVariantClasses = { primary: 'dark:bg-notion-blue dark:hover:bg-notion-blue-dark', secondary: 'dark:bg-notion-dark-bg-tertiary dark:text-notion-dark-text-primary dark:hover:bg-notion-dark-border-hover dark:border-notion-dark-border', ghost: 'dark:text-notion-dark-text-primary dark:hover:bg-notion-dark-bg-tertiary', danger: 'dark:bg-notion-red dark:hover:bg-notion-red-dark', }; return (jsxs("button", __assign({ type: type, disabled: disabled || loading, onClick: onClick, className: clsx(baseClasses, variantClasses[variant], darkVariantClasses[variant], sizeClasses[size], className) }, props, { children: [loading && (jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-2 border-current border-t-transparent" })), !loading && icon && iconPosition === 'left' && icon, children, !loading && icon && iconPosition === 'right' && icon] }))); }; var Input = forwardRef(function (_a, ref) { var className = _a.className, _b = _a.variant, variant = _b === void 0 ? 'default' : _b, _c = _a.size, size = _c === void 0 ? 'md' : _c, label = _a.label, error = _a.error, helperText = _a.helperText, leftIcon = _a.leftIcon, rightIcon = _a.rightIcon, _d = _a.fullWidth, fullWidth = _d === void 0 ? false : _d, disabled = _a.disabled, props = __rest(_a, ["className", "variant", "size", "label", "error", "helperText", "leftIcon", "rightIcon", "fullWidth", "disabled"]); var baseClasses = 'notion-input-base transition-colors duration-150'; var variantClasses = { default: 'border-notion-border focus:border-notion-blue hover:border-notion-border-hover', filled: 'border-transparent bg-notion-bg-tertiary focus:border-notion-blue hover:bg-notion-border-hover', }; var sizeClasses = { sm: 'px-2.5 py-1.5 text-notion-sm', md: 'px-3 py-2 text-notion-base', lg: 'px-4 py-3 text-notion-lg', }; var darkVariantClasses = { default: 'dark:border-notion-dark-border dark:focus:border-notion-blue dark:hover:border-notion-dark-border-hover', filled: 'dark:bg-notion-dark-bg-tertiary dark:hover:bg-notion-dark-border-hover', }; var errorClasses = error ? 'border-notion-red focus:border-notion-red dark:border-notion-red' : ''; var disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''; var inputElement = (jsxs("div", { className: clsx('relative', fullWidth ? 'w-full' : 'w-auto'), children: [leftIcon && (jsx("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-notion-text-tertiary dark:text-notion-dark-text-tertiary", children: leftIcon })), jsx("input", __assign({ ref: ref, disabled: disabled, className: clsx(baseClasses, variantClasses[variant], darkVariantClasses[variant], sizeClasses[size], errorClasses, disabledClasses, leftIcon && 'pl-10', rightIcon && 'pr-10', className) }, props)), rightIcon && (jsx("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-notion-text-tertiary dark:text-notion-dark-text-tertiary", children: rightIcon }))] })); if (label || error || helperText) { return (jsxs("div", { className: clsx('space-y-1', fullWidth ? 'w-full' : 'w-auto'), children: [label && (jsx("label", { className: "block text-notion-sm font-medium text-notion-text-primary dark:text-notion-dark-text-primary", children: label })), inputElement, (error || helperText) && (jsx("p", { className: clsx('text-notion-xs', error ? 'text-notion-red' : 'text-notion-text-secondary dark:text-notion-dark-text-secondary'), children: error || helperText }))] })); } return inputElement; }); Input.displayName = 'Input'; var Typography = function (_a) { var children = _a.children, className = _a.className, _b = _a.variant, variant = _b === void 0 ? 'body1' : _b, _c = _a.color, color = _c === void 0 ? 'default' : _c, _d = _a.weight, weight = _d === void 0 ? 'normal' : _d, _e = _a.align, align = _e === void 0 ? 'left' : _e, as = _a.as, props = __rest(_a, ["children", "className", "variant", "color", "weight", "align", "as"]); var variantStyles = { h1: 'text-notion-3xl font-bold leading-tight', h2: 'text-notion-2xl font-bold leading-tight', h3: 'text-notion-xl font-semibold leading-tight', h4: 'text-notion-lg font-semibold leading-snug', h5: 'text-notion-base font-semibold leading-snug', h6: 'text-notion-sm font-semibold leading-snug', body1: 'text-notion-base leading-relaxed', body2: 'text-notion-sm leading-relaxed', caption: 'text-notion-xs leading-normal', overline: 'text-notion-xs uppercase tracking-wide leading-normal', }; var colorStyles = { default: 'text-notion-text-primary dark:text-notion-dark-text-primary', blue: 'text-notion-blue', red: 'text-notion-red', yellow: 'text-notion-yellow-dark', green: 'text-notion-green', purple: 'text-notion-purple', pink: 'text-notion-pink', orange: 'text-notion-orange', gray: 'text-notion-text-secondary dark:text-notion-dark-text-secondary', }; var weightStyles = { normal: 'font-normal', medium: 'font-medium', semibold: 'font-semibold', bold: 'font-bold', }; var alignStyles = { left: 'text-left', center: 'text-center', right: 'text-right', }; var defaultElements = { h1: 'h1', h2: 'h2', h3: 'h3', h4: 'h4', h5: 'h5', h6: 'h6', body1: 'p', body2: 'p', caption: 'span', overline: 'span', }; var Component = as || defaultElements[variant] || 'p'; return (jsx(Component, __assign({ className: clsx(variantStyles[variant], colorStyles[color], weightStyles[weight], alignStyles[align], className) }, props, { children: children }))); }; var Card = function (_a) { var children = _a.children, className = _a.className, _b = _a.variant, variant = _b === void 0 ? 'default' : _b, _c = _a.padding, padding = _c === void 0 ? 'md' : _c, _d = _a.hoverable, hoverable = _d === void 0 ? false : _d, _e = _a.clickable, clickable = _e === void 0 ? false : _e, onClick = _a.onClick, props = __rest(_a, ["children", "className", "variant", "padding", "hoverable", "clickable", "onClick"]); var baseClasses = 'rounded-notion-md transition-all duration-150'; var variantClasses = { default: 'bg-notion-bg-primary border border-notion-border dark:bg-notion-dark-bg-primary dark:border-notion-dark-border', outlined: 'bg-transparent border border-notion-border dark:border-notion-dark-border', elevated: 'bg-notion-bg-primary shadow-notion border border-notion-border dark:bg-notion-dark-bg-primary dark:border-notion-dark-border dark:shadow-none', }; var paddingClasses = { none: '', sm: 'p-3', md: 'p-4', lg: 'p-6', }; var interactiveClasses = (hoverable || clickable) ? 'hover:shadow-notion-hover hover:border-notion-border-hover dark:hover:border-notion-dark-border-hover' : ''; var clickableClasses = clickable ? 'cursor-pointer' : ''; return (jsx("div", __assign({ className: clsx(baseClasses, variantClasses[variant], paddingClasses[padding], interactiveClasses, clickableClasses, className), onClick: clickable ? onClick : undefined }, props, { children: children }))); }; var Badge = function (_a) { var children = _a.children, className = _a.className, _b = _a.variant, variant = _b === void 0 ? 'soft' : _b, _c = _a.color, color = _c === void 0 ? 'default' : _c, _d = _a.size, size = _d === void 0 ? 'md' : _d, _e = _a.removable, removable = _e === void 0 ? false : _e, onRemove = _a.onRemove, props = __rest(_a, ["children", "className", "variant", "color", "size", "removable", "onRemove"]); var baseClasses = 'inline-flex items-center gap-1 font-medium rounded-notion transition-colors duration-150'; var sizeClasses = { sm: 'px-2 py-0.5 text-notion-xs', md: 'px-2.5 py-1 text-notion-sm', lg: 'px-3 py-1.5 text-notion-base', }; var variantColorClasses = { solid: { default: 'bg-notion-text-primary text-notion-bg-primary dark:bg-notion-dark-text-primary dark:text-notion-dark-bg-primary', blue: 'bg-notion-blue text-white', red: 'bg-notion-red text-white', yellow: 'bg-notion-yellow text-notion-text-primary', green: 'bg-notion-green text-white', purple: 'bg-notion-purple text-white', pink: 'bg-notion-pink text-white', orange: 'bg-notion-orange text-white', gray: 'bg-notion-text-secondary text-notion-bg-primary dark:bg-notion-dark-text-secondary dark:text-notion-dark-bg-primary', }, soft: { default: 'bg-notion-bg-tertiary text-notion-text-primary dark:bg-notion-dark-bg-tertiary dark:text-notion-dark-text-primary', blue: 'bg-notion-blue-light text-notion-blue-dark dark:bg-notion-blue/20 dark:text-notion-blue', red: 'bg-notion-red-light text-notion-red-dark dark:bg-notion-red/20 dark:text-notion-red', yellow: 'bg-notion-yellow-light text-notion-yellow-dark dark:bg-notion-yellow/20 dark:text-notion-yellow', green: 'bg-notion-green-light text-notion-green-dark dark:bg-notion-green/20 dark:text-notion-green', purple: 'bg-notion-purple-light text-notion-purple-dark dark:bg-notion-purple/20 dark:text-notion-purple', pink: 'bg-notion-pink-light text-notion-pink-dark dark:bg-notion-pink/20 dark:text-notion-pink', orange: 'bg-notion-orange-light text-notion-orange-dark dark:bg-notion-orange/20 dark:text-notion-orange', gray: 'bg-notion-bg-tertiary text-notion-text-secondary dark:bg-notion-dark-bg-tertiary dark:text-notion-dark-text-secondary', }, outline: { default: 'border border-notion-border text-notion-text-primary dark:border-notion-dark-border dark:text-notion-dark-text-primary', blue: 'border border-notion-blue text-notion-blue', red: 'border border-notion-red text-notion-red', yellow: 'border border-notion-yellow-dark text-notion-yellow-dark dark:border-notion-yellow dark:text-notion-yellow', green: 'border border-notion-green text-notion-green', purple: 'border border-notion-purple text-notion-purple', pink: 'border border-notion-pink text-notion-pink', orange: 'border border-notion-orange text-notion-orange', gray: 'border border-notion-text-secondary text-notion-text-secondary dark:border-notion-dark-text-secondary dark:text-notion-dark-text-secondary', }, }; return (jsxs("span", __assign({ className: clsx(baseClasses, sizeClasses[size], variantColorClasses[variant][color], className) }, props, { children: [children, removable && (jsx("button", { onClick: onRemove, className: "ml-1 hover:bg-black/10 dark:hover:bg-white/10 rounded-full p-0.5 transition-colors", "aria-label": "Remove badge", children: jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", children: jsx("path", { d: "M9 3L3 9M3 3l6 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }))] }))); }; /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var defaultAttributes = { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }; /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().trim(); const createLucideIcon = (iconName, iconNode) => { const Component = forwardRef( ({ color = "currentColor", size = 24, strokeWidth = 2, absoluteStrokeWidth, className = "", children, ...rest }, ref) => createElement( "svg", { ref, ...defaultAttributes, width: size, height: size, stroke: color, strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth, className: ["lucide", `lucide-${toKebabCase(iconName)}`, className].join(" "), ...rest }, [ ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)), ...Array.isArray(children) ? children : [children] ] ) ); Component.displayName = `${iconName}`; return Component; }; /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const CheckSquare = createLucideIcon("CheckSquare", [ ["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }], ["path", { d: "M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11", key: "1jnkn4" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const ChevronDown = createLucideIcon("ChevronDown", [ ["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const ChevronRight = createLucideIcon("ChevronRight", [ ["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Code = createLucideIcon("Code", [ ["polyline", { points: "16 18 22 12 16 6", key: "z7tu5w" }], ["polyline", { points: "8 6 2 12 8 18", key: "1eg1df" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const FileText = createLucideIcon("FileText", [ [ "path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z", key: "1nnpy2" } ], ["polyline", { points: "14 2 14 8 20 8", key: "1ew0cm" }], ["line", { x1: "16", x2: "8", y1: "13", y2: "13", key: "14keom" }], ["line", { x1: "16", x2: "8", y1: "17", y2: "17", key: "17nazh" }], ["line", { x1: "10", x2: "8", y1: "9", y2: "9", key: "1a5vjj" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const FolderOpen = createLucideIcon("FolderOpen", [ [ "path", { d: "m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2", key: "usdka0" } ] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Folder = createLucideIcon("Folder", [ [ "path", { d: "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z", key: "1kt360" } ] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Hash = createLucideIcon("Hash", [ ["line", { x1: "4", x2: "20", y1: "9", y2: "9", key: "4lhtct" }], ["line", { x1: "4", x2: "20", y1: "15", y2: "15", key: "vyu0kd" }], ["line", { x1: "10", x2: "8", y1: "3", y2: "21", key: "1ggp8o" }], ["line", { x1: "16", x2: "14", y1: "3", y2: "21", key: "weycgp" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const ListOrdered = createLucideIcon("ListOrdered", [ ["line", { x1: "10", x2: "21", y1: "6", y2: "6", key: "76qw6h" }], ["line", { x1: "10", x2: "21", y1: "12", y2: "12", key: "16nom4" }], ["line", { x1: "10", x2: "21", y1: "18", y2: "18", key: "u3jurt" }], ["path", { d: "M4 6h1v4", key: "cnovpq" }], ["path", { d: "M4 10h2", key: "16xx2s" }], ["path", { d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1", key: "m9a95d" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const List = createLucideIcon("List", [ ["line", { x1: "8", x2: "21", y1: "6", y2: "6", key: "7ey8pc" }], ["line", { x1: "8", x2: "21", y1: "12", y2: "12", key: "rjfblc" }], ["line", { x1: "8", x2: "21", y1: "18", y2: "18", key: "c3b1m8" }], ["line", { x1: "3", x2: "3.01", y1: "6", y2: "6", key: "1g7gq3" }], ["line", { x1: "3", x2: "3.01", y1: "12", y2: "12", key: "1pjlvk" }], ["line", { x1: "3", x2: "3.01", y1: "18", y2: "18", key: "28t2mc" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const MoreHorizontal = createLucideIcon("MoreHorizontal", [ ["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }], ["circle", { cx: "19", cy: "12", r: "1", key: "1wjl8i" }], ["circle", { cx: "5", cy: "12", r: "1", key: "1pcz8c" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Plus = createLucideIcon("Plus", [ ["path", { d: "M5 12h14", key: "1ays0h" }], ["path", { d: "M12 5v14", key: "s699le" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Quote = createLucideIcon("Quote", [ [ "path", { d: "M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z", key: "4rm80e" } ], [ "path", { d: "M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z", key: "10za9r" } ] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Search = createLucideIcon("Search", [ ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }], ["path", { d: "m21 21-4.3-4.3", key: "1qie3q" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Square = createLucideIcon("Square", [ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Type = createLucideIcon("Type", [ ["polyline", { points: "4 7 4 4 20 4 20 7", key: "1nosan" }], ["line", { x1: "9", x2: "15", y1: "20", y2: "20", key: "swin9y" }], ["line", { x1: "12", x2: "12", y1: "4", y2: "20", key: "1tx1rr" }] ]); /** * @license lucide-react v0.294.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const User = createLucideIcon("User", [ ["path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", key: "975kel" }], ["circle", { cx: "12", cy: "7", r: "4", key: "17ys0d" }] ]); var Avatar = function (_a) { var src = _a.src, alt = _a.alt, _b = _a.size, size = _b === void 0 ? 'md' : _b, fallback = _a.fallback, _c = _a.shape, shape = _c === void 0 ? 'circle' : _c, className = _a.className, props = __rest(_a, ["src", "alt", "size", "fallback", "shape", "className"]); var sizeClasses = { xs: 'w-6 h-6 text-xs', sm: 'w-8 h-8 text-sm', md: 'w-10 h-10 text-base', lg: 'w-12 h-12 text-lg', xl: 'w-16 h-16 text-xl', }; var shapeClasses = { circle: 'rounded-full', square: 'rounded-notion', }; var iconSizes = { xs: 12, sm: 16, md: 20, lg: 24, xl: 32, }; var baseClasses = 'inline-flex items-center justify-center bg-notion-bg-tertiary dark:bg-notion-dark-bg-tertiary text-notion-text-secondary dark:text-notion-dark-text-secondary font-medium overflow-hidden'; if (src) { return (jsx("img", __assign({ src: src, alt: alt || 'Avatar', className: clsx(baseClasses, sizeClasses[size], shapeClasses[shape], className) }, props))); } return (jsx("div", __assign({ className: clsx(baseClasses, sizeClasses[size], shapeClasses[shape], className) }, props, { children: fallback ? (jsx("span", { className: "uppercase", children: fallback.slice(0, 2) })) : (jsx(User, { size: iconSizes[size] })) }))); }; var Tooltip = function (_a) { var children = _a.children, content = _a.content, _b = _a.placement, placement = _b === void 0 ? 'top' : _b, _c = _a.trigger, trigger = _c === void 0 ? 'hover' : _c, _d = _a.delay, delay = _d === void 0 ? 500 : _d, _e = _a.disabled, disabled = _e === void 0 ? false : _e, className = _a.className, props = __rest(_a, ["children", "content", "placement", "trigger", "delay", "disabled", "className"]); var _f = useState(false), isVisible = _f[0], setIsVisible = _f[1]; var _g = useState({ top: 0, left: 0 }), position = _g[0], setPosition = _g[1]; var triggerRef = useRef(null); var tooltipRef = useRef(null); var timeoutRef = useRef(); var showTooltip = function () { if (disabled) return; if (timeoutRef.current) { clearTimeout(timeoutRef.current); } timeoutRef.current = setTimeout(function () { setIsVisible(true); updatePosition(); }, delay); }; var hideTooltip = function () { if (timeoutRef.current) { clearTimeout(timeoutRef.current); } setIsVisible(false); }; var updatePosition = function () { if (!triggerRef.current || !tooltipRef.current) return; var triggerRect = triggerRef.current.getBoundingClientRect(); var tooltipRect = tooltipRef.current.getBoundingClientRect(); var top = 0; var left = 0; switch (placement) { case 'top': top = triggerRect.top - tooltipRect.height - 8; left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2; break; case 'bottom': top = triggerRect.bottom + 8; left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2; break; case 'left': top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2; left = triggerRect.left - tooltipRect.width - 8; break; case 'right': top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2; left = triggerRect.right + 8; break; } setPosition({ top: top, left: left }); }; useEffect(function () { if (isVisible) { updatePosition(); } }, [isVisible, placement]); useEffect(function () { return function () { if (timeoutRef.current) { clearTimeout(timeoutRef.current); } }; }, []); var handleTriggerEvents = function () { if (trigger === 'hover') { return { onMouseEnter: showTooltip, onMouseLeave: hideTooltip, }; } else { return { onClick: function () { if (isVisible) { hideTooltip(); } else { showTooltip(); } }, }; } }; var placementClasses = { top: 'mb-2', bottom: 'mt-2', left: 'mr-2', right: 'ml-2', }; return (jsxs(Fragment, { children: [jsx("div", __assign({ ref: triggerRef, className: clsx('inline-block', className) }, handleTriggerEvents(), props, { children: children })), isVisible && (jsx("div", { ref: tooltipRef, className: "fixed z-50 pointer-events-none", style: { top: position.top, left: position.left, }, children: jsx("div", { className: clsx('px-2 py-1 text-notion-xs text-white bg-notion-text-primary dark:bg-notion-dark-text-primary rounded-notion shadow-notion-md', 'animate-in fade-in-0 zoom-in-95 duration-200', placementClasses[placement]), children: content }) }))] })); }; var Block = function (_a) { var className = _a.className, id = _a.id, type = _a.type, _b = _a.content, content = _b === void 0 ? '' : _b, _c = _a.level, level = _c === void 0 ? 1 : _c, _d = _a.checked, checked = _d === void 0 ? false : _d, _e = _a.collapsed, collapsed = _e === void 0 ? false : _e, children = _a.children, props = __rest(_a, ["className", "id", "type", "content", "level", "checked", "collapsed", "children"]); var _f = useState(collapsed), isCollapsed = _f[0], setIsCollapsed = _f[1]; var _g = useState(checked), isChecked = _g[0], setIsChecked = _g[1]; var _h = useState(content), text = _h[0], setText = _h[1]; var getVariant = function () { switch (type) { case 'heading': return level === 1 ? 'h1' : level === 2 ? 'h2' : 'h3'; default: return 'body1'; } }; var variant = getVariant(); var getIcon = function () { switch (type) { case 'text': return jsx(Type, { size: 16, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }); case 'heading': return jsx(Hash, { size: 16, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }); case 'bullet': return jsx(List, { size: 16, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }); case 'numbered': return jsx(ListOrdered, { size: 16, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }); case 'todo': return (jsx("button", { onClick: function () { return setIsChecked(!isChecked); }, className: "flex items-center justify-center w-4 h-4 border border-notion-border rounded-sm hover:bg-notion-bg-secondary dark:border-notion-dark-border dark:hover:bg-notion-dark-bg-secondary", children: isChecked && jsx(CheckSquare, { size: 12, className: "text-notion-blue" }) })); case 'toggle': return (jsx("button", { onClick: function () { return setIsCollapsed(!isCollapsed); }, className: "flex items-center justify-center w-4 h-4 text-notion-text-tertiary hover:text-notion-text-primary dark:text-notion-dark-text-tertiary dark:hover:text-notion-dark-text-primary", children: isCollapsed ? jsx(ChevronRight, { size: 12 }) : jsx(ChevronDown, { size: 12 }) })); case 'quote': return jsx(Quote, { size: 16, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }); case 'code': return jsx(Code, { size: 16, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }); default: return jsx(Square, { size: 16, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }); } }; var renderContent = function () { if (type === 'code') { return (jsx("pre", { className: "bg-notion-bg-secondary dark:bg-notion-dark-bg-secondary p-3 rounded-notion font-mono text-notion-sm", children: jsx("code", { children: text }) })); } return (jsxs("div", { className: "flex-1", children: [jsx("div", { className: clsx('outline-none', isChecked && type === 'todo' && 'line-through', type === 'quote' && 'italic'), contentEditable: true, suppressContentEditableWarning: true, onBlur: function (e) { return setText(e.currentTarget.textContent || ''); }, children: jsx(Typography, { variant: variant, children: text }) }), type === 'toggle' && !isCollapsed && children && (jsx("div", { className: "ml-6 mt-2 space-y-1", children: children }))] })); }; return (jsxs("div", __assign({ id: id, className: clsx('flex items-start space-x-2 py-1 px-2 rounded-notion hover:bg-notion-bg-secondary dark:hover:bg-notion-dark-bg-secondary group', type === 'quote' && 'border-l-4 border-notion-text-tertiary dark:border-notion-dark-text-tertiary pl-4', className) }, props, { children: [jsx("div", { className: "flex-shrink-0 pt-1", children: getIcon() }), renderContent()] }))); }; var SidebarItem = function (_a) { var _b; var item = _a.item, onItemClick = _a.onItemClick, onItemToggle = _a.onItemToggle, selectedId = _a.selectedId, level = _a.level; var _c = useState(item.expanded || false), isExpanded = _c[0], setIsExpanded = _c[1]; var _d = useState(false), showActions = _d[0], setShowActions = _d[1]; var handleToggle = function () { var newExpanded = !isExpanded; setIsExpanded(newExpanded); onItemToggle === null || onItemToggle === void 0 ? void 0 : onItemToggle(__assign(__assign({}, item), { expanded: newExpanded })); }; var handleClick = function () { onItemClick === null || onItemClick === void 0 ? void 0 : onItemClick(item); }; var isSelected = selectedId === item.id; var hasChildren = item.children && item.children.length > 0; var paddingLeft = level * 12 + 8; return (jsxs("div", { children: [jsxs("div", { className: clsx('group flex items-center gap-1 py-1 px-2 rounded-notion cursor-pointer transition-colors duration-150', 'hover:bg-notion-bg-tertiary dark:hover:bg-notion-dark-bg-tertiary', isSelected && 'bg-notion-blue-light dark:bg-notion-blue/20'), style: { paddingLeft: paddingLeft }, onMouseEnter: function () { return setShowActions(true); }, onMouseLeave: function () { return setShowActions(false); }, onClick: handleClick, children: [hasChildren && (jsx("button", { onClick: function (e) { e.stopPropagation(); handleToggle(); }, className: "flex items-center justify-center w-4 h-4 hover:bg-notion-border-hover dark:hover:bg-notion-dark-border-hover rounded-notion-sm", children: isExpanded ? (jsx(ChevronDown, { size: 12, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" })) : (jsx(ChevronRight, { size: 12, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" })) })), !hasChildren && jsx("div", { className: "w-4" }), jsx("div", { className: "flex items-center justify-center w-4 h-4", children: item.icon || (item.type === 'folder' ? (isExpanded ? (jsx(FolderOpen, { size: 14, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" })) : (jsx(Folder, { size: 14, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }))) : (jsx(FileText, { size: 14, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }))) }), jsx(Typography, { variant: "body2", className: "flex-1 truncate", children: item.title }), showActions && (jsxs("div", { className: "flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity", children: [jsx("button", { onClick: function (e) { e.stopPropagation(); // Handle add action }, className: "flex items-center justify-center w-5 h-5 hover:bg-notion-border-hover dark:hover:bg-notion-dark-border-hover rounded-notion-sm", children: jsx(Plus, { size: 12, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }) }), jsx("button", { onClick: function (e) { e.stopPropagation(); // Handle more actions }, className: "flex items-center justify-center w-5 h-5 hover:bg-notion-border-hover dark:hover:bg-notion-dark-border-hover rounded-notion-sm", children: jsx(MoreHorizontal, { size: 12, className: "text-notion-text-tertiary dark:text-notion-dark-text-tertiary" }) })] }))] }), hasChildren && isExpanded && (jsx("div", { children: (_b = item.children) === null || _b === void 0 ? void 0 : _b.map(function (child) { return (jsx(SidebarItem, { item: child, onItemClick: onItemClick, onItemToggle: onItemToggle, selectedId: selectedId, level: level + 1 }, child.id)); }) }))] })); }; var Sidebar = function (_a) { var className = _a.className, items = _a.items, onItemClick = _a.onItemClick, onItemToggle = _a.onItemToggle, selectedId = _a.selectedId, _b = _a.searchable, searchable = _b === void 0 ? true : _b, _c = _a.width, width = _c === void 0 ? 240 : _c, props = __rest(_a, ["className", "items", "onItemClick", "onItemToggle", "selectedId", "searchable", "width"]); var _d = useState(''), searchQuery = _d[0], setSearchQuery = _d[1]; var filteredItems = searchQuery ? items.filter(function (item) { return item.title.toLowerCase().includes(searchQuery.toLowerCase()); }) : items; return (jsxs("div", __assign({ className: clsx('flex flex-col bg-notion-bg-secondary dark:bg-notion-dark-bg-secondary border-r border-notion-border dark:border-notion-dark-border', className), style: { width: width } }, props, { children: [searchable && (jsx("div", { className: "p-3 border-b border-notion-border dark:border-notion-dark-border", children: jsx(Input, { placeholder: "Search...", value: searchQuery, onChange: function (e) { return setSearchQuery(e.target.value); }, leftIcon: jsx(Search, { size: 14 }), size: "sm" }) })), jsx("div", { className: "flex-1 overflow-y-auto p-2", children: jsx("div", { className: "space-y-0.5", children: filteredItems.map(function (item) { return (jsx(SidebarItem, { item: item, onItemClick: onItemClick, onItemToggle: onItemToggle, selectedId: selectedId, level: 0 }, item.id)); }) }) })] }))); }; export { Avatar, Badge, Block, Button, Card, Input, Sidebar, Tooltip, Typography };