UNPKG

material-you-react

Version:

Material You: Material You (M3) Design system and its components for simple integration with Next.Js or other react-based frameworks

1,027 lines (1,011 loc) 106 kB
'use strict'; var React = require('react'); /** * @params backgroundColor: string - sets Background color * @params items: string[] - An array of icon names to display. Example: `['home', 'search']`. * @params floatingActionButton: Displays the FAB when `true`. Example: `true`. | * @returns React.ReactNode- * @description * This component is a BottomAppBar component. */ function BottomAppBar({ innerRef, ...props }) { var _a; const [isHovered, setIsHovered] = React.useState(false); const [isActive, setIsActive] = React.useState(false); return (React.createElement("div", { ref: innerRef, id: "bottomAppBar", className: "bottom-app-bar", style: { backgroundColor: `${(_a = props.backgroundColor) !== null && _a !== void 0 ? _a : "rgb(var(--md-sys-color-surface-container))"}`, width: "100vw", height: "80px", padding: props.floatingActionButton ? "16px" : "12px 16px", display: "flex", justifyContent: "space-between", alignItems: "center", position: "fixed", bottom: 0, left: 0, } }, React.createElement("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", gap: "16px", } }, props.items.map((element, index) => (React.createElement("span", { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onMouseDown: () => setIsActive(true), onMouseUp: () => setIsActive(false), key: index, className: `md-elevation ${!isHovered ? "md-elevation-0" : "md-elevation-1"} label-large material-symbols-rounded material-symbols-outlined`, style: { width: "24px", height: "24px", cursor: "pointer", color: `${isActive ? "rgb(var(--md-sys-color-on-tertiary-container))" : "rgb(var(--md-sys-color-on-secondary-container))"}`, } }, element || "add")))), props.floatingActionButton)); } function TopAppBarCenterAligned(props) { var _a; const [isScrolled, setScrollState] = React.useState(false); window.onscroll = function () { if (window.scrollY > 0) { setScrollState(true); } else { setScrollState(false); } }; return (React.createElement("div", { className: `md-elevation $isScrolled ? "md-elevation-2" : "md-elevation-0"}`, style: { zIndex: 1, backgroundColor: `${(_a = props.containerBackgroundColor) !== null && _a !== void 0 ? _a : (isScrolled ? "rgb(var(--md-sys-color-surface-container))" : "rgb(var(--md-sys-color-surface))")}`, position: "sticky", width: "100vw", height: "64px", borderRadius: "0px", padding: "0px 16px", display: "flex", justifyContent: "space-between", alignItems: "center", gap: "24px", top: "0", left: "0", color: "rgb(var(--md-sys-color-on-surface))", } }, React.createElement("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", width: "48px", height: "48px", cursor: "pointer", } }, props.leadingIcon && (React.createElement("div", { style: { width: "24px", height: "24px", } }, React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, props.leadingIcon || "arrow_back")))), React.createElement("p", { className: "title-large", style: { width: "fit-content", color: "rgb(var(--md-sys-color-on-surface))", } }, props.headline), props.avatar || props.avatarImage ? (React.createElement("div", { key: "avatar", style: { width: "48px", fontSize: "30px", display: "flex", justifyContent: "center", alignItems: "center", height: "48px", cursor: "pointer", color: "rgb(var(--md-sys-color-on-surface-variant))", } }, props.avatarImage ? (React.createElement("img", { src: props.avatarImage, style: { width: "30px", height: "30px", objectFit: "cover", borderRadius: "15px", } })) : (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined", style: { fontSize: "30px", } }, "account_circle")))) : (React.createElement("div", { style: { width: "48px", fontSize: "30px", display: "flex", justifyContent: "center", alignItems: "center", height: "48px", cursor: "pointer", color: "rgb(var(--md-sys-color-on-surface-variant))", } })))); } function TopAppBarCenterSmall(props) { var _a; const [isScrolled, setScrollState] = React.useState(false); window.onscroll = function () { if (window.scrollY > 0) { setScrollState(true); } else { setScrollState(false); } }; return (React.createElement("div", { className: `${isScrolled ? "md-elevation-2" : "md-elevation-0"} md-elevation`, style: { zIndex: 1, backgroundColor: `${(_a = props.containerBackgroundColor) !== null && _a !== void 0 ? _a : (isScrolled ? "rgb(var(--md-sys-color-surface-container))" : "rgb(var(--md-sys-color-surface))")}`, position: "sticky", width: "100vw", height: "64px", borderRadius: "0px", padding: "0px 16px", display: "flex", justifyContent: "space-between", alignItems: "center", gap: "24px", top: "0", left: "0", color: "rgb(var(--md-sys-color-on-surface))", } }, React.createElement("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", gap: "16px", } }, props.leadingIcon && (React.createElement("div", { style: { width: "24px", height: "24px", cursor: "pointer", } }, React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, props.leadingIcon || "arrow_back"))), React.createElement("p", { className: "title-large", style: { color: "rgb(var(--md-sys-color-on-surface))", } }, props.headline)), (props.trailingIcons || props.avatar || props.avatarImage) && (React.createElement("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", gap: "24px", } }, props.trailingIcons && props.trailingIcons.map((icon, index) => (React.createElement("div", { key: index, style: { width: "24px", height: "24px", cursor: "pointer", color: "rgb(var(--md-sys-color-on-surface-variant))", } }, React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, icon)))), (props.avatar || props.avatarImage) && (React.createElement("div", { key: "avatar", style: { width: "48px", fontSize: "30px", display: "flex", justifyContent: "center", alignItems: "center", height: "48px", cursor: "pointer", color: "rgb(var(--md-sys-color-on-surface-variant))", } }, props.avatarImage ? (React.createElement("img", { src: props.avatarImage, style: { width: "30px", height: "30px", objectFit: "cover", borderRadius: "15px", } })) : (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined", style: { fontSize: "30px", } }, "account_circle")))))))); } function TopAppBarCenterMedium(props) { var _a; const [isScrolled, setScrollState] = React.useState(false); const [scrollY, setScrollY] = React.useState(0); window.onscroll = function () { if (window.scrollY > 0) { setScrollY(window.scrollY); setScrollState(true); } else { setScrollY(0); setScrollState(false); } }; return (React.createElement("div", { className: "md-elevation-0 md-elevation", style: { zIndex: 1, backgroundColor: `${((_a = props.containerBackgroundColor) !== null && _a !== void 0 ? _a : isScrolled) ? "rgb(var(--md-sys-color-surface-container))" : "rgb(var(--md-sys-color-surface))"}`, width: "100vw", height: isScrolled ? `${112 - Math.min(96, scrollY) / 2}px` : "112px", borderRadius: "0px", padding: isScrolled ? "0px 16px" : "20px 16px 24px 24px", display: "flex", justifyContent: "space-between", alignItems: isScrolled ? "center" : "start", gap: "24px", position: "sticky", top: "0", left: "0", transition: "all 0.3s ease", } }, React.createElement("div", { style: { transition: "all 0.3s ease", display: "flex", flexDirection: isScrolled ? "row" : "column", justifyContent: isScrolled ? "space-between" : "start", alignItems: "start", gap: "16px", width: isScrolled ? `100%` : "auto", } }, React.createElement("div", { style: { width: "24px", height: "24px", color: "rgb(var(--md-sys-color-on-surface))", cursor: "pointer", } }, React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, props.leadingIcon || "arrow_back")), React.createElement("p", { className: isScrolled ? "title-large" : "headline-small", style: { width: isScrolled ? "100%" : "auto", transition: "all 0.3s ease", textAlign: isScrolled ? "center" : "start", color: "rgb(var(--md-sys-color-on-surface))", } }, props.headline)), props.trailingIcons && (React.createElement("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", gap: "24px", } }, props.trailingIcons.map((icon, index) => (React.createElement("div", { key: index, style: { width: "24px", height: "24px", color: "rgb(var(--md-sys-color-on-surface-variant))", cursor: "pointer", } }, React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, icon)))))))); } function TopAppBarCenterLarge(props) { var _a; const [isScrolled, setScrollState] = React.useState(false); const [scrollY, setScrollY] = React.useState(0); window.onscroll = function () { if (window.scrollY > 0) { setScrollState(true); setScrollY(window.scrollY); } else { setScrollState(false); setScrollY(0); } }; return (React.createElement("div", { style: { zIndex: 1, backgroundColor: `${((_a = props.containerBackgroundColor) !== null && _a !== void 0 ? _a : isScrolled) ? "rgb(var(--md-sys-color-surface-container))" : "rgb(var(--md-sys-color-surface))"}`, width: "100vw", height: isScrolled ? `${152 - Math.min(64, scrollY) / 2}px` : "152px", borderRadius: "0px", padding: isScrolled ? "16px" : "20px 16px 28px", display: "flex", justifyContent: "space-between", alignItems: "start", gap: "24px", position: "sticky", top: "0", left: "0", } }, React.createElement("div", { style: { height: "100%", display: "flex", flexDirection: "column", justifyContent: "space-between", alignItems: "start", gap: "16px", } }, React.createElement("div", { style: { width: "24px", height: "24px", color: "rgb(var(--md-sys-color-on-surface))", cursor: "pointer", } }, React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, props.leadingIcon || "arrow_back")), React.createElement("p", { className: "headline-medium", style: { whiteSpace: "pre-line", color: "rgb(var(--md-sys-color-on-surface))", } }, props.headline)), props.trailingIcons && (React.createElement("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", gap: "24px", } }, props.trailingIcons.map((icon, index) => (React.createElement("div", { key: index, style: { width: "24px", height: "24px", color: "rgb(var(--md-sys-color-on-surface-variant))", cursor: "pointer", } }, React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, icon)))))))); } const ElevatedButton = (props) => { const [isHovered, setIsHovered] = React.useState(false); const [isFocused, setIsFocused] = React.useState(false); const [isFocusedWithKeyboard, setIsFocusedWithKeyboard] = React.useState(true); const [isActive, setIsActive] = React.useState(false); const handleClick = () => { const params = {}; props.onClickCallback(params); }; return (React.createElement("button", { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onFocus: () => setIsFocused(true), onBlur: () => { setIsFocused(false); setIsFocusedWithKeyboard(true); }, onMouseDown: () => { setIsActive(true); setIsFocusedWithKeyboard(false); }, onTouchStart: () => setIsFocusedWithKeyboard(false), onMouseUp: () => setIsActive(false), onClick: handleClick, className: ` md-elevation ${props.disabled ? "md-elevation-0" : isActive || isFocused || !isHovered ? "md-elevation-1" : "md-elevation-2"} label-large`, style: { width: props.width || "fit-content", outlineOffset: isFocused && isFocusedWithKeyboard ? "2px" : undefined, outline: isFocused && isFocusedWithKeyboard ? "3px solid rgb(var(--md-sys-color-secondary))" : "", cursor: props.disabled ? "not-allowed" : "pointer", display: "flex", height: "40px", backgroundColor: props.disabled ? "rgba(var(--md-sys-color-on-surface), 12%)" : isFocused || isActive ? `color-mix(in srgb, ${props.containerColor || "rgb(var(--md-sys-color-surface-container-low))"},rgb(var(--md-sys-color-primary)) 10%)` : isHovered ? `color-mix(in srgb, ${props.containerColor || "rgb(var(--md-sys-color-surface-container-low))"},rgb(var(--md-sys-color-primary)) 8%)` : `${props.containerColor || "rgb(var(--md-sys-color-surface-container-low))"}`, borderRadius: "20px", padding: props.icon != null ? "0px 24px 0px 16px" : "0px 24px", alignItems: "center", justifyContent: "center", color: props.disabled ? "rgba(var(--md-sys-color-on-surface), 38%)" : props.contentColor || "rgb(var(--md-sys-color-primary))", } }, props.icon && (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined", style: { fontSize: "18px !important", marginRight: "8px", } }, props.icon)), props.children)); }; const FilledButton = (props) => { var _a; const [isHovered, setIsHovered] = React.useState(false); const [isFocused, setIsFocused] = React.useState(false); const [isActive, setIsActive] = React.useState(false); const [isFocusedWithKeyboard, setIsFocusedWithKeyboard] = React.useState(true); const [isDragged, setIsDragged] = React.useState(false); const handleClick = () => { const params = {}; props.onClickCallback(params); }; return (React.createElement("button", { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onFocus: () => setIsFocused(true), onBlur: () => { setIsFocused(false); setIsFocusedWithKeyboard(true); }, onMouseDown: () => { setIsActive(true); setIsFocusedWithKeyboard(false); }, onTouchStart: () => setIsFocusedWithKeyboard(false), onMouseUp: () => setIsActive(false), onDragStart: () => setIsDragged(true), onDragEnd: () => setIsDragged(false), draggable: (_a = props.draggable) !== null && _a !== void 0 ? _a : true, onClick: handleClick, className: ` md-elevation ${isDragged ? "md-elevation-3" : !isHovered ? "md-elevation-0" : "md-elevation-1"} label-large`, style: { width: props.width || "fit-content", outlineOffset: isFocusedWithKeyboard ? "2px" : undefined, outline: isFocused && !isDragged && isFocusedWithKeyboard ? "3px solid rgb(var(--md-sys-color-secondary))" : "", cursor: props.disabled ? "not-allowed" : "pointer", display: "flex", height: "40px", backgroundColor: props.disabled ? "rgba(var(--md-sys-color-on-surface), 12%)" : isDragged ? `color-mix(in srgb, ${props.containerColor || "rgb(var(--md-sys-color-primary))"},rgb(var(--md-sys-color-on-primary)) 16%)` : isFocused || isActive ? `color-mix(in srgb, ${props.containerColor || "rgb(var(--md-sys-color-primary))"},rgb(var(--md-sys-color-on-primary)) 10%)` : isHovered ? `color-mix(in srgb, ${props.containerColor || "rgb(var(--md-sys-color-primary))"},rgb(var(--md-sys-color-on-primary)) 8%)` : `${props.containerColor || "rgb(var(--md-sys-color-primary))"}`, borderRadius: "20px", padding: props.icon != null ? "0px 24px 0px 16px" : "0px 24px", alignItems: "center", justifyContent: "center", color: props.disabled ? "rgba(var(--md-sys-color-on-surface), 38%)" : props.contentColor || "rgb(var(--md-sys-color-on-primary))", } }, props.icon && (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined", style: { fontSize: "18px !important", marginRight: "8px", } }, props.icon)), props.children)); }; const FilledTonalButton = (props) => { return (React.createElement(FilledButton, { onClickCallback: props.onClickCallback, children: props.children, icon: props.icon, disabled: props.disabled, containerColor: "rgb(var(--md-sys-color-secondary-container))", contentColor: "rgb(var(--md-sys-color-on-secondary-container))", width: props.width, draggable: false })); }; const OutlinedButton = (props) => { const [isHovered, setIsHovered] = React.useState(false); const [isFocused, setIsFocused] = React.useState(false); const [isActive, setIsActive] = React.useState(false); const [isFocusedWithKeyboard, setIsFocusedWithKeyboard] = React.useState(true); const handleClick = () => { const params = {}; props.onClickCallback(params); }; return (React.createElement("button", { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onFocus: () => setIsFocused(true), onBlur: () => { setIsFocused(false); setIsFocusedWithKeyboard(true); }, onMouseDown: () => { setIsActive(true); setIsFocusedWithKeyboard(false); }, onTouchStart: () => setIsFocusedWithKeyboard(false), onMouseUp: () => setIsActive(false), onClick: handleClick, className: `md-elevation-0 label-large`, style: { width: props.width || "fit-content", outlineOffset: isFocused && isFocusedWithKeyboard ? "2px" : undefined, outline: isFocused && isFocusedWithKeyboard ? "3px solid rgb(var(--md-sys-color-secondary))" : "", border: props.disabled ? "rgba(var(--md-sys-color-on-surface), 12%)" : isFocused ? "1px solid rgb(var(--md-sys-color-primary))" : "1px solid rgb(var(--md-sys-color-outline))", cursor: props.disabled ? "not-allowed" : "pointer", display: "flex", height: "40px", backgroundColor: props.disabled ? "transparent" : // isFocused || isActive ? `rgba(var(--md-sys-color-primary), 10%)` : isHovered ? `rgba(var(--md-sys-color-primary), 8%)` : "transparent", // : `${props.containerColor || "rgb(var(--md-sys-color-primary))"}`, borderRadius: "20px", padding: props.icon != null ? "0px 24px 0px 16px" : "0px 24px", alignItems: "center", justifyContent: "center", color: props.disabled ? "rgba(var(--md-sys-color-on-surface), 38%)" : props.contentColor || "rgb(var(--md-sys-color-primary))", } }, props.icon && (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined", style: { fontSize: "18px !important", marginRight: "8px", } }, props.icon)), props.children)); }; const TextButton = (props) => { const [isHovered, setIsHovered] = React.useState(false); const [isFocused, setIsFocused] = React.useState(false); const [isActive, setIsActive] = React.useState(false); const [isFocusedWithKeyboard, setIsFocusedWithKeyboard] = React.useState(true); const handleClick = () => { const params = {}; props.onClickCallback(params); }; return (React.createElement("button", { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onFocus: () => setIsFocused(true), onBlur: () => { setIsFocused(false); setIsFocusedWithKeyboard(true); }, onMouseDown: () => { setIsActive(true); setIsFocusedWithKeyboard(false); }, onTouchStart: () => setIsFocusedWithKeyboard(false), onMouseUp: () => setIsActive(false), className: `md-elevation-0 label-large`, onClick: handleClick, style: { width: props.width || "fit-content", outlineOffset: isFocused && isFocusedWithKeyboard ? "2px" : undefined, outline: isFocused && isFocusedWithKeyboard ? "3px solid rgb(var(--md-sys-color-secondary))" : "", cursor: props.disabled ? "not-allowed" : "pointer", display: "flex", height: "40px", backgroundColor: props.disabled ? "transparent" : // isFocused || isActive ? `rgba(var(--md-sys-color-primary), 10%)` : isHovered ? `rgba(var(--md-sys-color-primary), 8%)` : "transparent", // : `${props.containerColor || "rgb(var(--md-sys-color-primary))"}`, borderRadius: "20px", padding: props.icon != null ? "0px 16px 0px 12px" : "0px 12px", alignItems: "center", justifyContent: "center", color: props.disabled ? "rgba(var(--md-sys-color-on-surface), 38%)" : props.contentColor || "rgb(var(--md-sys-color-primary))", } }, props.icon && (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined", style: { fontSize: "18px !important", marginRight: "8px", } }, props.icon)), props.children)); }; const FloatingActionButton = (props) => { const ref = React.useRef(null); const [parentClass, setParentClass] = React.useState(""); React.useEffect(() => { var _a; const domNode = ref.current; if (domNode !== undefined && domNode !== null && domNode.parentNode) { setParentClass(((_a = domNode.parentElement) === null || _a === void 0 ? void 0 : _a.className) || "ID"); } }, [ref.current]); const handleClick = () => { const params = {}; props.onClickCallback(params); }; return (React.createElement("button", { onClick: handleClick, ref: ref, className: parentClass.includes("bottom-app-bar") ? "md-elevation-0" : "md-elevation-3", style: { backgroundColor: "rgb(var(--md-sys-color-primary-container))", width: "56px", height: "56px", borderRadius: "16px", display: "flex", justifyContent: "center", alignItems: "center", } }, React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined", style: { width: "24px", height: "24px", color: "rgb(var(--md-sys-color-on-primary-container))", } }, "add"))); }; /** * Props for the Menu component. * @params {React.ReactNode} `children` - The content to be rendered inside the menu. Accepts `MenuItem` as a childrens. * @params {number} `displayLimit` - Optional. Specifies the maximum number of items to display before enabling scroll. * If not provided, the menu will expand to fit all content without scrolling. */ function Menu(props) { const [allowedHeight, setAllowedHeight] = React.useState('fit-content'); const [shouldScroll, setShouldScroll] = React.useState(false); React.useEffect(() => { if (props.displayLimit) { const calculatedHeight = props.displayLimit * 48; setAllowedHeight(`${calculatedHeight}px`); setShouldScroll(true); } }, [props.displayLimit]); return (React.createElement("div", { style: { width: '200px', // minWidth: '112px', // maxWidth: '280px', backgroundColor: 'rgb(var(--md-sys-color-surface-container))', height: allowedHeight, borderRadius: '4px', display: 'flex', justifyContent: 'start', alignItems: 'center', flexDirection: 'column', ...(shouldScroll && { overflowY: 'scroll' }) }, className: "md-elevation-2" }, props.children)); } /** * Props for MenuItem Component * @param (string) [optional] `leadingIcon` - Icon displayed at start of item * @param (string) [optional] `trailingIcon` - Icon displayed at end of item * @param (string) [optional] `trailingText` - Text displayed at end of item * @param (string) [required] `label` - Primary text content of menu item * @param (boolean) [optional] `disable` - Whether item is disabled * @param (React.ReactNode) [optional] `children` - Inner content to render * @param (function) [optional] `onClickCallback` - Callback fired on item click, accepts generic param */ const MenuItem = (props) => { const [isHovered, setIsHovered] = React.useState(false); const [isFocused, setIsFocused] = React.useState(false); const [isPressed, setIsPressed] = React.useState(false); const menuItemRef = React.useRef(null); // Defines where to position the child Menus of Menu-Item. const [childPosition, setChildPosition] = React.useState("Right"); const [subChildren, setSubChildren] = React.useState(null); const [showChild, setShowChild] = React.useState(false); React.useEffect(() => { if (menuItemRef.current) { const rect = menuItemRef.current.getBoundingClientRect(); const menuLeftPosition = rect.left; const menuRightPosition = rect.right; setChildPosition(`${menuLeftPosition > menuRightPosition ? "Left" : "Right"}`); } // Restricting to only display whose Children.type = `Menu` const childrenArray = React.Children.toArray(props.children); childrenArray.forEach((child) => { if (React.isValidElement(child)) { setSubChildren(child); } }); }, []); const handleClick = () => { const params = {}; if (props.onClickCallback) { props.onClickCallback(params); } }; return (React.createElement("div", { ref: menuItemRef, onMouseEnter: () => { setIsHovered(true); setShowChild(true); }, onMouseLeave: () => { setIsHovered(false); setShowChild(false); }, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), onMouseDown: () => setIsPressed(true), onMouseUp: () => setIsPressed(false), onClick: handleClick, style: { width: "100%", padding: "8px 12px", height: "48px", display: "flex", justifyContent: "space-between", alignItems: "center", backgroundColor: isFocused ? "rgb(var(--md-sys-color-secondary))" : isHovered ? "rgba(var(--md-sys-color-on-surface), 8%)" : isFocused || isPressed ? "rgba(var(--md-sys-color-on-surface), 1%)" : "rgb(var(--md-sys-color-surface-container))", cursor: props.disable ? "not-allowed" : "pointer", pointerEvents: props.disable ? "none" : "auto", position: "relative", } }, React.createElement("div", { style: { gap: "12px", display: "flex", justifyContent: "start", alignItems: "center", } }, props.leadingIcon && (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined", style: { fontSize: "24px", color: props.disable ? "rgb(var(--md-sys-color-on-surface))" : isHovered || isFocused || isPressed ? "rgb(var(--md-sys-color-on-surface-variant)" : "rgb(var(--md-sys-color-on-surface-variant))", opacity: props.disable ? "0.38" : "", } }, props.leadingIcon || "")), React.createElement("p", { style: { font: "var(--md-sys-typescale-label-large-font)", fontWeight: "var(--md-sys-typescale-label-large-weight)", fontSize: "var(--md-sys-typescale-label-large-size)", lineHeight: "var(--md-sys-typescale-label-large-line-height)", letterSpacing: "var(--md-sys-typescale-label-large-tracking)", color: props.disable || isHovered || isFocused || isPressed ? "rgb(var(--md-sys-color-on-surface))" : "rgb(var(--md-sys-color-on-surface))", opacity: props.disable ? "0.38" : "", } }, props.label)), React.createElement("div", { style: { height: "100%", display: "flex", justifyContent: "center", alignItems: "center", } }, props.trailingIcon && (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined", style: { fontSize: "24px", color: props.disable ? "rgb(var(--md-sys-color-on-surface))" : isHovered || isFocused || isPressed ? "rgb(var(--md-sys-color-on-surface-variant)" : "rgb(var(--md-sys-color-on-surface-variant))", opacity: props.disable ? "0.38" : "", } }, subChildren ? "arrow_drop_down" : props.trailingIcon || "")), props.trailingText && (React.createElement("span", { style: { font: "var(--md-sys-typescale-label-large-font)", fontWeight: "var(--md-sys-typescale-label-large-weight)", fontSize: "var(--md-sys-typescale-label-large-size)", lineHeight: "var(--md-sys-typescale-label-large-line-height)", letterSpacing: "var(--md-sys-typescale-label-large-tracking)", color: "rgb(var(--md-sys-color-on-surface-variant))", } }, props.trailingText || ""))), showChild && (React.createElement("div", { style: { position: "absolute", top: 0, right: childPosition === "Right" ? "100%" : "", left: childPosition === "Left" ? "100%" : "", } }, subChildren && subChildren)))); }; /** * Props for OutlinedTextField Component * @param (string) [required] `value` - Current value of the input field * @param (function) [required] `onValueChange` - Handler function for value changes * @param ("textarea" | "" | "dropdown") [optional] `type` - Type of input field * @param (string[]) [optional] `options` - Available options for dropdown type * @param (number) [optional] `rows` - Number of rows for textarea * @param (string) [optional] `containerWidth` - Width of the input container * @param (string) [optional] `leadingIcon` - Icon displayed at start of input * @param (string) [required] `labelText` - Label text for the input field * @param (string) [optional] `inputType` - HTML input type attribute * @param (number) [optional] `maxLength` - Maximum allowed input length * @param (boolean) [optional] `required` - Whether field is required * @param (string) [optional] `supportingText` - Helper text below input * @param (string) [optional] `trailingIcon` - Icon displayed at end of input * @param (boolean) [optional] `disabled` - Whether field is disabled * @param (boolean) [optional] `error` - Whether field is in error state */ function FilledTextField(props) { var _a; const [givenInputType, setGivenInputType] = React.useState(""); const [isFocused, setIsFocused] = React.useState(false); const textareaRef = React.useRef(null); const [menuPosition, setMenuPosition] = React.useState("Bottom"); const textFieldRef = React.useRef(null); const [isMenuOpen, setIsMenuOpen] = React.useState(false); const menuRef = React.useRef(null); const handleInputChange = (e) => { props.onValueChange(e.target.value); }; const handleMenuItemClick = (value) => { props.onValueChange(value); setIsMenuOpen(false); }; const handleFocus = () => { setIsFocused(true); if (props.type === "dropdown") { setIsMenuOpen(true); } }; const handleBlur = (e) => { var _a; if (props.type === "dropdown") { const isClickInsideMenu = (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget); if (!isClickInsideMenu) { setTimeout(() => { setIsFocused(false); }, 200); } } else { setIsFocused(false); } }; const handleTrailingIconClick = (e) => { if (props.inputType === "password") { setGivenInputType(givenInputType === "text" ? "password" : "text"); } else { props.onValueChange(""); } }; React.useEffect(() => { var _a; if (props.type === "textarea" && textareaRef.current) { const textarea = textareaRef.current; textarea.style.height = "auto"; textarea.style.height = `${textarea.scrollHeight}px`; } if (givenInputType === "") { setGivenInputType((_a = props.inputType) !== null && _a !== void 0 ? _a : "text"); } if (props.type === "dropdown") { if (textFieldRef.current) { const rect = textFieldRef.current.getBoundingClientRect(); const menuTopPosition = rect.top; const menuBottomPosition = rect.bottom; setMenuPosition(`${menuTopPosition > menuBottomPosition ? "Top" : "Bottom"}`); } } }, [props.value, props.type]); return (React.createElement("div", { ref: textFieldRef, style: { width: (_a = props.containerWidth) !== null && _a !== void 0 ? _a : "", display: "flex", flexDirection: "column", justifyContent: "start", alignItems: "center", gap: "4px", opacity: props.disabled ? 0.4 : 1, pointerEvents: props.disabled ? "none" : "auto", cursor: "pointer", transition: "all 0.3s ease", position: "relative", } }, React.createElement("div", { className: `filled-text-field-inner-container ${isFocused ? "focused" : ""} ${props.error ? "error" : ""}`, style: { width: "100%", minHeight: "56px", height: "auto", padding: `${props.leadingIcon && props.trailingIcon ? "8px 12px" : props.leadingIcon ? "8px 16px 8px 12px" : "8px 16px"}`, borderTopLeftRadius: "4px", borderTopRightRadius: "4px", display: "flex", justifyContent: "space-between", alignItems: "center", gap: `${props.leadingIcon || props.trailingIcon ? "16px" : "0px"}`, }, onFocus: handleFocus, onBlur: handleBlur }, props.leadingIcon && (React.createElement("div", { className: `filled-text-field-leading-icon ${props.error && "error"}`, style: { width: "24px", height: "24px", color: "rgb(var(--md-sys-color-on-surface-variant))", cursor: "none", } }, React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, props.leadingIcon || ""))), React.createElement("div", { className: "filled-text-field-input-box", style: { position: "relative" } }, props.type === "textarea" ? (React.createElement("textarea", { ref: textareaRef, value: props.value, required: props.required, disabled: props.disabled, maxLength: props.maxLength, onChange: handleInputChange, placeholder: "", className: `filled-text-field-input ${props.error ? "error" : ""}`, style: { color: "rgb(var(--md-sys-color-on-surface))", font: "var(--md-sys-typescale-body-large-font)", lineHeight: "var(--md-sys-typescale-body-large-line-height)", fontSize: "var(--md-sys-typescale-body-large-size)", fontWeight: "var(--md-sys-typescale-body-large-weight)", letterSpacing: "var(--md-sys-typescale-body-large-tracking)", caretColor: props.error ? "rgb(var(--md-sys-color-error))" : "rgb(var(--md-sys-color-primary))", resize: "none", overflow: "hidden", } })) : (React.createElement("input", { type: givenInputType, value: props.value, required: props.required, disabled: props.disabled, maxLength: props.maxLength, onChange: handleInputChange, onKeyDown: (e) => { if (props.type === "dropdown") { e.preventDefault(); } }, placeholder: "", className: `filled-text-field-input ${props.error ? "error" : ""}`, style: { color: "rgb(var(--md-sys-color-on-surface))", font: "var(--md-sys-typescale-body-large-font)", lineHeight: "var(--md-sys-typescale-body-large-line-height)", fontSize: "var(--md-sys-typescale-body-large-size)", fontWeight: "var(--md-sys-typescale-body-large-weight)", letterSpacing: "var(--md-sys-typescale-body-large-tracking)", caretColor: props.error ? "rgb(var(--md-sys-color-error))" : "rgb(var(--md-sys-color-primary))", } })), React.createElement("label", { className: `filled-text-field-label ${props.error ? "error" : ""}` }, props.labelText, props.required && "*")), props.trailingIcon && props.value.length > 0 && (React.createElement("div", { onClick: (e) => handleTrailingIconClick(), className: `filled-text-field-trailing-icon ${props.error && "error"}`, style: { width: "24px", height: "24px", cursor: "pointer", userSelect: "none", } }, " ", props.inputType === "password" ? (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, givenInputType === "text" ? "visibility_off" : "visibility")) : (React.createElement("span", { className: "material-symbols-rounded material-symbols-outlined" }, props.trailingIcon || ""))))), React.createElement("div", { style: { width: "100%", display: "flex", justifyContent: "space-between", alignItems: "start", padding: "0px 16px", gap: "16px", color: `${props.error ? "rgb(var(--md-sys-color-error))" : "rgb(var(--md-sys-color-on-surface-variant))"}`, font: "var(--md-sys-typescale-body-small-font)", fontWeight: "var(--md-sys-typescale-body-small-weight)", fontSize: "var(--md-sys-typescale-body-small-size)", lineHeight: "var(--md-sys-typescale-body-small-line-height)", letterSpacing: "var(--md-sys-typescale-body-small-tracking)", } }, React.createElement("p", null, props.supportingText), props.maxLength && (React.createElement("p", null, props.value.length, "/", props.maxLength))), props.type === "dropdown" && props.options && isMenuOpen && (React.createElement("div", { ref: menuRef, style: { position: "absolute", top: menuPosition === "Top" ? 0 : "", bottom: menuPosition === "Bottom" ? 0 : "", left: 0, } }, React.createElement(Menu, null, props.options.map((item, index) => (React.createElement(MenuItem, { key: index, label: item, onClickCallback: () => handleMenuItemClick(item) })))))))); } /** * Props for OutlinedTextField Component * @param (string) [required] `value` - Current value of the input field * @param (function) [required] `onValueChange` - Handler function for value changes * @param ("textarea" | "" | "dropdown") [optional] `type` - Type of input field * @param (string[]) [optional] `options` - Available options for dropdown type * @param (number) [optional] `rows` - Number of rows for textarea * @param (string) [optional] `containerWidth` - Width of the input container * @param (string) [optional] `leadingIcon` - Icon displayed at start of input * @param (string) [required] `labelText` - Label text for the input field * @param (string) [optional] `inputType` - HTML input type attribute * @param (number) [optional] `maxLength` - Maximum allowed input length * @param (boolean) [optional] `required` - Whether field is required * @param (string) [optional] `supportingText` - Helper text below input * @param (string) [optional] `trailingIcon` - Icon displayed at end of input * @param (boolean) [optional] `disabled` - Whether field is disabled * @param (boolean) [optional] `error` - Whether field is in error state */ function OutlinedTextField(props) { var _a; const [givenInputType, setGivenInputType] = React.useState(""); const [isFocused, setIsFocused] = React.useState(false); const [parentBGColor, setParentBGColor] = React.useState(""); const textareaRef = React.useRef(null); // const textFieldRef = useRef<HTMLDivElement | null>(null); const [menuPosition, setMenuPosition] = React.useState("Bottom"); const textFieldRef = React.useRef(null); const [isMenuOpen, setIsMenuOpen] = React.useState(false); const menuRef = React.useRef(null); const handleInputChange = (e) => { props.onValueChange(e.target.value); }; const handleMenuItemClick = (value) => { props.onValueChange(value); setIsMenuOpen(false); }; const handleFocus = () => { setIsFocused(true); if (props.type === "dropdown") { setIsMenuOpen(true); } }; const handleBlur = (e) => { var _a; if (props.type === "dropdown") { const isClickInsideMenu = (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget); if (!isClickInsideMenu) { setTimeout(() => { setIsFocused(false); }, 200); } } else { setIsFocused(false); } }; // Recursively gets the background color of the parent, which uses this component. const getParentBackgroundColor = (element) => { if (!element) return null; const computedStyle = window.getComputedStyle(element); const bgColor = computedStyle.backgroundColor; if (bgColor !== "transparent" && bgColor !== "rgba(0, 0, 0, 0)") { return bgColor; } return getParentBackgroundColor(element.parentElement); }; const handleTrailingIconClick = (e) => { if (props.inputType === "password") { setGivenInputType(givenInputType === "text" ? "password" : "text"); } else { props.onValueChange(""); } }; React.useEffect(() => { var _a; if (props.type === "textarea" && textareaRef.current) { const textarea = textareaRef.current; textarea.style.height = "auto"; textarea.style.height = `${textarea.scrollHeight}px`; } if (givenInputType === "") { setGivenInputType((_a = props.inputType) !== null && _a !== void 0 ? _a : "text"); } if (props.type === "dropdown") { if (textFieldRef.current) { const rect = textFieldRef.current.getBoundingClientRect(); const menuTopPosition = rect.top; const menuBottomPosition = rect.bottom; setMenuPosition(`${menuTopPosition > menuBottomPosition ? "Top" : "Bottom"}`); } } }, [props.value, props.type]); React.useEffect(() => { if (parentBGColor === "") { if (textFieldRef.current) { let parentBackgroundColor = getParentBackgroundColor(textFieldRef.current); setParentBGColor(parentBackgroundColor); } } }, []); return (React.createElement("div", { ref: textFieldRef, style: { width: (_a = props.containerWidth) !== null && _a !== void 0 ? _a : "", display: "flex", flexDirection: "column", justifyContent: "start", alignItems: "center", gap: "4px", opacity: props.disabled ? 0.4 : 1, pointerEvents: props.disabled ? "none" : "auto", cursor: "pointer", transition: "all 0