@q2devel/q2-storybook 1.0.40 → 1.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/components/Base/badge/Badge.d.ts +11 -0
  2. package/dist/components/Base/badge/Badge.js +4 -0
  3. package/dist/components/Base/button/AddToCart.d.ts +10 -0
  4. package/dist/components/Base/button/AddToCart.js +7 -0
  5. package/dist/components/Base/button/Button.d.ts +18 -0
  6. package/dist/components/Base/button/Button.js +38 -0
  7. package/dist/components/Base/heading/Heading.d.ts +9 -0
  8. package/dist/components/Base/heading/Heading.js +16 -0
  9. package/dist/components/Base/modal/Modal.d.ts +18 -0
  10. package/dist/components/Base/modal/Modal.js +12 -0
  11. package/dist/components/Base/spinner/Spinner.d.ts +10 -0
  12. package/dist/components/Base/spinner/Spinner.js +12 -0
  13. package/dist/components/Base/tooltip/Tooltip.d.ts +18 -0
  14. package/dist/components/Base/tooltip/Tooltip.js +18 -0
  15. package/dist/components/Ecommerce/basket-dialog/BasketDialog.d.ts +55 -0
  16. package/dist/components/Ecommerce/basket-dialog/BasketDialog.js +101 -0
  17. package/dist/components/Ecommerce/category-tree/CategoryTree.d.ts +14 -0
  18. package/dist/components/Ecommerce/category-tree/CategoryTree.js +55 -0
  19. package/dist/components/Ecommerce/product-card/ProductCard.d.ts +66 -0
  20. package/dist/components/Ecommerce/product-card/ProductCard.js +156 -0
  21. package/dist/components/Ecommerce/progress-stepper/ProgressStepper.d.ts +26 -0
  22. package/dist/components/Ecommerce/progress-stepper/ProgressStepper.js +44 -0
  23. package/dist/components/Ecommerce/wishlist/DeleteButton.d.ts +10 -0
  24. package/dist/components/Ecommerce/wishlist/DeleteButton.js +30 -0
  25. package/dist/components/Ecommerce/wishlist/LikeButton.d.ts +21 -0
  26. package/dist/components/Ecommerce/wishlist/LikeButton.js +41 -0
  27. package/dist/components/Ecommerce/wishlist/WishlistDropdown.d.ts +18 -0
  28. package/dist/components/Ecommerce/wishlist/WishlistDropdown.js +49 -0
  29. package/dist/components/Forms/dropdown/Dropdown.d.ts +11 -0
  30. package/dist/components/Forms/dropdown/Dropdown.js +12 -0
  31. package/dist/components/Forms/select-field/SelectField.d.ts +29 -0
  32. package/dist/components/Forms/select-field/SelectField.js +142 -0
  33. package/dist/components/Forms/select-field/SelectFieldOption.d.ts +4 -0
  34. package/dist/components/Forms/select-field/SelectFieldOption.js +7 -0
  35. package/dist/components/Forms/text-area/TextArea.d.ts +8 -0
  36. package/dist/components/Forms/text-area/TextArea.js +7 -0
  37. package/dist/components/Forms/text-field/TextField.d.ts +22 -0
  38. package/dist/components/Forms/text-field/TextField.js +80 -0
  39. package/dist/components/Forms/text-field/TextField.types.d.ts +24 -0
  40. package/dist/components/Forms/text-field/TextField.types.js +1 -0
  41. package/dist/components/Web/banner/Banner.d.ts +37 -0
  42. package/dist/components/Web/banner/Banner.js +126 -0
  43. package/dist/components/Web/breadcrumb/Breadcrumb.d.ts +17 -0
  44. package/dist/components/Web/breadcrumb/Breadcrumb.js +13 -0
  45. package/dist/components/Web/faq/FaqSection.d.ts +11 -0
  46. package/dist/components/Web/faq/FaqSection.js +18 -0
  47. package/dist/components/Web/nav-bar/NavBar.d.ts +19 -0
  48. package/dist/components/Web/nav-bar/NavBar.js +17 -0
  49. package/dist/components/Web/stats-card/StatsCard.d.ts +12 -0
  50. package/dist/components/Web/stats-card/StatsCard.js +9 -0
  51. package/dist/components/Web/tabs/HorizontalTab.d.ts +8 -0
  52. package/dist/components/Web/tabs/HorizontalTab.js +11 -0
  53. package/dist/components/Web/text-with-image/ImageWithText.d.ts +14 -0
  54. package/dist/components/Web/text-with-image/ImageWithText.js +7 -0
  55. package/dist/components/banner/Banner.d.ts +1 -17
  56. package/dist/components/banner/Banner.js +1 -1
  57. package/dist/components/breadcrumb/Breadcrumb.d.ts +17 -0
  58. package/dist/components/breadcrumb/Breadcrumb.js +13 -0
  59. package/dist/components/button/AddToCart.d.ts +10 -0
  60. package/dist/components/button/AddToCart.js +7 -0
  61. package/dist/components/button/Button.d.ts +11 -2
  62. package/dist/components/button/Button.js +35 -2
  63. package/dist/components/category-tree/CategoryTree.d.ts +14 -0
  64. package/dist/components/category-tree/CategoryTree.js +55 -0
  65. package/dist/components/like-button/DeleteButton.d.ts +10 -0
  66. package/dist/components/like-button/DeleteButton.js +30 -0
  67. package/dist/components/like-button/LikeButton.d.ts +21 -0
  68. package/dist/components/like-button/LikeButton.js +41 -0
  69. package/dist/components/like-button/WishlistDropdown.d.ts +18 -0
  70. package/dist/components/like-button/WishlistDropdown.js +49 -0
  71. package/dist/components/product-card/ProductCard.d.ts +30 -25
  72. package/dist/components/product-card/ProductCard.js +88 -42
  73. package/dist/components/select-field/SelectField.d.ts +2 -0
  74. package/dist/components/select-field/SelectField.js +51 -31
  75. package/dist/components/spinner/Spinner.d.ts +10 -0
  76. package/dist/components/spinner/Spinner.js +12 -0
  77. package/dist/components/tabs/HorizontalTab.d.ts +8 -0
  78. package/dist/components/tabs/HorizontalTab.js +11 -0
  79. package/dist/i18n/navigation.d.ts +6 -0
  80. package/dist/i18n/navigation.js +6 -0
  81. package/dist/index.d.ts +22 -9
  82. package/dist/index.js +22 -9
  83. package/dist/style.css +1 -1
  84. package/dist/utils/generalHelperFunction.d.ts +7 -0
  85. package/dist/utils/generalHelperFunction.js +47 -0
  86. package/package.json +4 -3
@@ -0,0 +1,11 @@
1
+ import { MouseEvent, ReactNode } from 'react';
2
+ interface BadgeProps {
3
+ children: ReactNode;
4
+ onClick?: (e: MouseEvent) => void;
5
+ color?: string;
6
+ className?: string;
7
+ labelClassName?: string;
8
+ rightIcon?: ReactNode;
9
+ }
10
+ declare const Badge: ({ children, onClick, color, className, labelClassName, rightIcon, }: BadgeProps) => import("react/jsx-runtime").JSX.Element;
11
+ export default Badge;
@@ -0,0 +1,4 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ const Badge = ({ children, onClick, color = 'bg-blue-100 text-blue-800', className = '', labelClassName = '', rightIcon, }) => (_jsxs("span", { className: `inline-flex items-center rounded px-2.5 py-0.5 text-xs font-medium ${color} ${className}`, onClick: onClick, children: [_jsx("span", { className: labelClassName, children: children }), rightIcon && _jsx("span", { className: "ml-1", children: rightIcon })] }));
4
+ export default Badge;
@@ -0,0 +1,10 @@
1
+ import { ReactNode } from 'react';
2
+ interface AddToCartProps {
3
+ showAddButton: boolean;
4
+ disabled?: boolean;
5
+ customAddButton?: ReactNode;
6
+ addButtonIcon: ReactNode;
7
+ handleAddToCart: () => void;
8
+ }
9
+ declare const AddToCart: ({ showAddButton, disabled, customAddButton, addButtonIcon, handleAddToCart, }: AddToCartProps) => import("react/jsx-runtime").JSX.Element | null;
10
+ export default AddToCart;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ const AddToCart = ({ showAddButton, disabled = false, customAddButton, addButtonIcon, handleAddToCart, }) => {
3
+ if (!showAddButton)
4
+ return null;
5
+ return (_jsx("div", { className: "absolute bottom-2 right-2 z-10", onClick: (e) => e.stopPropagation(), children: _jsx("div", { className: "relative", children: customAddButton || (_jsx("button", { onClick: handleAddToCart, className: `p-2 w-10 h-10 flex items-center justify-center rounded-full bg-green-500 text-white shadow-md hover:bg-green-600 transition-colors duration-200 ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`, "aria-label": "Add to cart", disabled: disabled, children: addButtonIcon })) }) }));
6
+ };
7
+ export default AddToCart;
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ export interface ButtonProps {
3
+ children?: React.ReactNode;
4
+ label?: string;
5
+ variant?: 'primary' | 'secondary';
6
+ disabled?: boolean;
7
+ asLink?: boolean;
8
+ openInNewTab?: boolean;
9
+ href?: string;
10
+ onClick?: (event: any) => void;
11
+ rounded?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
12
+ className?: string;
13
+ target?: string;
14
+ rel?: string;
15
+ unstyled?: boolean;
16
+ }
17
+ declare const Button: React.FC<ButtonProps>;
18
+ export default Button;
@@ -0,0 +1,38 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import Link from 'next/link';
4
+ import buildClassesByJoining from '../../../utils/StyleHelper';
5
+ const roundedClasses = {
6
+ none: 'rounded-none',
7
+ sm: 'rounded-sm',
8
+ md: 'rounded-md',
9
+ lg: 'rounded-lg',
10
+ xl: 'rounded-xl',
11
+ full: 'rounded-full',
12
+ };
13
+ const variantClasses = {
14
+ primary: 'bg-blue-500 hover:bg-blue-600 text-white',
15
+ secondary: 'bg-gray-500 hover:bg-gray-600 text-white',
16
+ };
17
+ const Button = ({ children, label, variant, disabled = false, asLink = false, openInNewTab = false, href, onClick, rounded = 'md', className = '', target, rel, unstyled = false, }) => {
18
+ const baseClasses = unstyled
19
+ ? className
20
+ : buildClassesByJoining('inline-block px-4 py-2 font-medium transition-colors duration-200', variantClasses[variant ?? 'primary'], roundedClasses[rounded], {
21
+ 'opacity-50 cursor-not-allowed pointer-events-none': disabled,
22
+ 'cursor-pointer': !disabled,
23
+ }, className);
24
+ const content = children ?? label;
25
+ if (asLink) {
26
+ if (!href) {
27
+ console.warn('Button is rendered as a link but "href" is not provided.');
28
+ return null;
29
+ }
30
+ // Pokud disabled, použij <span> místo <Link>, aby nešel kliknout
31
+ if (disabled) {
32
+ return (_jsx("span", { className: baseClasses, "aria-disabled": "true", children: content }));
33
+ }
34
+ return (_jsx(Link, { href: href, className: baseClasses, onClick: onClick, target: openInNewTab ? '_blank' : target, rel: openInNewTab ? 'noopener noreferrer' : rel, children: content }));
35
+ }
36
+ return (_jsx("button", { onClick: onClick, className: baseClasses, disabled: disabled, children: content }));
37
+ };
38
+ export default Button;
@@ -0,0 +1,9 @@
1
+ import { ReactNode } from 'react';
2
+ interface HeadingProps {
3
+ level?: 1 | 2 | 3 | 4 | 5 | 6;
4
+ children: ReactNode;
5
+ className?: string;
6
+ id?: string;
7
+ }
8
+ declare const Heading: ({ level, children, className, id, }: HeadingProps) => import("react/jsx-runtime").JSX.Element;
9
+ export default Heading;
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { buildClassesByJoining } from '../../../utils/StyleHelper';
4
+ const Heading = ({ level = 1, children, className = '', id, }) => {
5
+ const Tag = `h${level}`;
6
+ const baseStyles = {
7
+ 1: 'text-4xl font-bold mt-12 mb-8 text-gray-900',
8
+ 2: 'text-3xl font-semibold text-gray-900',
9
+ 3: 'text-2xl font-semibold text-gray-900',
10
+ 4: 'text-xl font-medium text-gray-900',
11
+ 5: 'text-lg font-medium text-gray-900',
12
+ 6: 'text-base font-medium text-gray-900',
13
+ };
14
+ return (_jsx(Tag, { id: id, className: buildClassesByJoining(baseStyles[level], className), children: children }));
15
+ };
16
+ export default Heading;
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from 'react';
2
+ interface ModalProps {
3
+ title: string;
4
+ description: string;
5
+ buttonText: string;
6
+ icon?: ReactNode;
7
+ iconBackgroundColor?: string;
8
+ iconColor?: string;
9
+ buttonClassName?: string;
10
+ panelClassName?: string;
11
+ backdropClassName?: string;
12
+ onClose?: () => void;
13
+ isOpen: boolean;
14
+ showCloseButton?: boolean;
15
+ closeButtonClassName?: string;
16
+ }
17
+ export declare const Modal: ({ title, description, buttonText, icon, iconBackgroundColor, iconColor, buttonClassName, panelClassName, backdropClassName, onClose, isOpen, showCloseButton, closeButtonClassName, }: ModalProps) => import("react/jsx-runtime").JSX.Element;
18
+ export default Modal;
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { buildClassesByJoining } from '../../../utils/StyleHelper';
4
+ import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react';
5
+ import { CheckIcon, XMarkIcon } from '@heroicons/react/24/outline';
6
+ export const Modal = ({ title, description, buttonText, icon = _jsx(CheckIcon, { "aria-hidden": "true", className: "size-6" }), iconBackgroundColor = 'bg-green-100', iconColor = 'text-green-600', buttonClassName, panelClassName, backdropClassName, onClose, isOpen, showCloseButton = false, closeButtonClassName, }) => {
7
+ const handleClose = (value) => {
8
+ onClose?.();
9
+ };
10
+ return (_jsxs(Dialog, { open: isOpen, onClose: handleClose, className: "relative z-10", children: [_jsx(DialogBackdrop, { transition: true, className: buildClassesByJoining('fixed inset-0 bg-gray-500/75 transition-opacity data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in', backdropClassName) }), _jsx("div", { className: "fixed inset-0 z-10 w-screen overflow-y-auto", children: _jsx("div", { className: "flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0", children: _jsxs(DialogPanel, { transition: true, className: buildClassesByJoining('relative transform overflow-hidden rounded-lg bg-white px-4 pt-5 pb-4 text-left shadow-xl transition-all data-closed:translate-y-4 data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in sm:my-8 sm:w-full sm:max-w-sm sm:p-6 data-closed:sm:translate-y-0 data-closed:sm:scale-95', panelClassName), children: [showCloseButton && (_jsxs("button", { type: "button", className: buildClassesByJoining('absolute top-4 right-4 text-gray-400 hover:text-gray-500 focus:outline-none', closeButtonClassName), onClick: () => onClose?.(), children: [_jsx("span", { className: "sr-only", children: "Close" }), _jsx(XMarkIcon, { className: "h-6 w-6", "aria-hidden": "true" })] })), _jsxs("div", { children: [_jsx("div", { className: buildClassesByJoining('mx-auto flex size-12 items-center justify-center rounded-full', iconBackgroundColor), children: _jsx("div", { className: iconColor, children: icon }) }), _jsxs("div", { className: "mt-3 text-center sm:mt-5", children: [_jsx(DialogTitle, { as: "h3", className: "text-base font-semibold text-gray-900", children: title }), _jsx("div", { className: "mt-2", children: _jsx("p", { className: "text-sm text-gray-500", children: description }) })] })] }), _jsx("div", { className: "mt-5 sm:mt-6", children: _jsx("button", { type: "button", onClick: () => onClose?.(), className: buildClassesByJoining('inline-flex w-full justify-center rounded-md bg-green-600 px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-green-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600', buttonClassName), children: buttonText }) })] }) }) })] }));
11
+ };
12
+ export default Modal;
@@ -0,0 +1,10 @@
1
+ import { FC } from "react";
2
+ type SpinnerSize = "sm" | "md" | "lg" | number;
3
+ export interface SpinnerProps {
4
+ size?: SpinnerSize;
5
+ color?: string;
6
+ className?: string;
7
+ "aria-label"?: string;
8
+ }
9
+ export declare const Spinner: FC<SpinnerProps>;
10
+ export default Spinner;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import clsx from "clsx";
3
+ const sizeMap = {
4
+ sm: "h-4 w-4",
5
+ md: "h-6 w-6",
6
+ lg: "h-10 w-10",
7
+ };
8
+ export const Spinner = ({ size = "md", color = "text-gray-500", className, "aria-label": ariaLabel = "Loading...", }) => {
9
+ const dimensionClass = typeof size === "number" ? `h-[${size}px] w-[${size}px]` : sizeMap[size];
10
+ return (_jsxs("svg", { className: clsx("animate-spin", dimensionClass, color, className), fill: "none", viewBox: "0 0 24 24", role: "status", "aria-label": ariaLabel, children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "m4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }));
11
+ };
12
+ export default Spinner;
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { ReactNode } from 'react';
3
+ export interface TooltipRef {
4
+ show: () => void;
5
+ hide: () => void;
6
+ }
7
+ interface TooltipProps {
8
+ content?: ReactNode;
9
+ children: ReactNode;
10
+ backgroundColor?: string;
11
+ textColor?: string;
12
+ placement?: 'top' | 'bottom' | 'left' | 'right';
13
+ contentClassName?: string;
14
+ disabled?: boolean;
15
+ lazy?: boolean;
16
+ }
17
+ declare const Tooltip: React.ForwardRefExoticComponent<TooltipProps & React.RefAttributes<TooltipRef>>;
18
+ export default Tooltip;
@@ -0,0 +1,18 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ const Tooltip = forwardRef(({ content, children, backgroundColor = 'bg-black', textColor = 'text-white', placement = 'bottom', contentClassName = '', disabled = false, lazy = true, }, ref) => {
4
+ if (disabled)
5
+ return _jsx(_Fragment, { children: children });
6
+ return (_jsxs("span", { className: "relative group cursor-pointer", children: [children, content && (_jsx("span", { className: `absolute z-10 hidden group-hover:block
7
+ ${placement === 'top'
8
+ ? 'bottom-full mb-2'
9
+ : placement === 'bottom'
10
+ ? 'top-full mt-2'
11
+ : placement === 'left'
12
+ ? 'right-full mr-2'
13
+ : 'left-full ml-2'}
14
+ left-1/2 -translate-x-1/2 px-3 py-2 rounded ${backgroundColor} ${textColor}
15
+ text-xs whitespace-pre-wrap ${contentClassName}`, children: content }))] }));
16
+ });
17
+ Tooltip.displayName = 'Tooltip';
18
+ export default Tooltip;
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ export type BasketProduct = {
3
+ id: string;
4
+ name: string;
5
+ price: number;
6
+ quantity: number;
7
+ image?: {
8
+ src: string;
9
+ alt: string;
10
+ };
11
+ href?: string;
12
+ color?: string;
13
+ [key: string]: any;
14
+ };
15
+ export type BasketDialogVariant = 'default' | 'compact' | 'full';
16
+ export type BasketDialogPosition = 'right' | 'left';
17
+ export type BasketDialogProps = {
18
+ isOpen: boolean;
19
+ onClose: () => void;
20
+ products: BasketProduct[];
21
+ subtotal: string | number;
22
+ onQuantityChange?: (productId: string, quantity: number) => void;
23
+ onRemoveProduct?: (productId: string) => void;
24
+ onCheckout?: () => void;
25
+ onContinueShopping?: () => void;
26
+ onProductClick?: (product: BasketProduct) => void;
27
+ title?: string;
28
+ checkoutText?: string;
29
+ continueShoppingText?: string;
30
+ emptyCartText?: string;
31
+ quantityLabel?: string;
32
+ removeButtonText?: string;
33
+ totalLabel?: string;
34
+ shippingNoteText?: string;
35
+ variant?: BasketDialogVariant;
36
+ position?: BasketDialogPosition;
37
+ showProductImages?: boolean;
38
+ showProductColors?: boolean;
39
+ showProductLinks?: boolean;
40
+ showRemoveButton?: boolean;
41
+ showSubtotal?: boolean;
42
+ showCheckoutButton?: boolean;
43
+ showContinueShoppingButton?: boolean;
44
+ showShippingNote?: boolean;
45
+ showQuantityControls?: boolean;
46
+ customClassName?: string;
47
+ maxHeight?: string;
48
+ animationDuration?: number;
49
+ backdropOpacity?: number;
50
+ renderCustomProduct?: (product: BasketProduct) => React.ReactNode;
51
+ renderCustomFooter?: () => React.ReactNode;
52
+ pendingUpdates?: Record<string, number>;
53
+ processingItems?: Record<string, boolean>;
54
+ };
55
+ export declare const BasketDialog: ({ isOpen, onClose, products, subtotal, onQuantityChange, onRemoveProduct, onCheckout, onContinueShopping, onProductClick, title, checkoutText, continueShoppingText, emptyCartText, quantityLabel, removeButtonText, totalLabel, shippingNoteText, variant, position, showProductImages, showProductColors, showProductLinks, showRemoveButton, showSubtotal, showCheckoutButton, showContinueShoppingButton, showShippingNote, showQuantityControls, customClassName, maxHeight, animationDuration, backdropOpacity, renderCustomProduct, renderCustomFooter, pendingUpdates, processingItems, }: BasketDialogProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,101 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react';
4
+ import { MinusIcon, PlusIcon, XMarkIcon } from '@heroicons/react/24/outline';
5
+ // Helper funkcia pre formátovanie ceny
6
+ const formatPrice = (price) => {
7
+ return new Intl.NumberFormat('cs-CZ', {
8
+ style: 'currency',
9
+ currency: 'CZK',
10
+ }).format(price);
11
+ };
12
+ export const BasketDialog = ({
13
+ // Základné props
14
+ isOpen, onClose, products, subtotal,
15
+ // Callback funkcie
16
+ onQuantityChange, onRemoveProduct, onCheckout, onContinueShopping, onProductClick,
17
+ // Texty s predvolenými hodnotami
18
+ title = 'Váš košík', checkoutText = 'Pokračovat k objednávce', continueShoppingText = 'Pokračovat v nákupu', emptyCartText = 'Váš košík je prázdný', quantityLabel = 'Množství:', removeButtonText = 'Odstranit', totalLabel = 'Celkem', shippingNoteText = 'Doprava a daně budou vypočítány při dokončení objednávky.',
19
+ // Zobrazenie/konfigurácia s predvolenými hodnotami
20
+ variant = 'default', position = 'right', showProductImages = true, showProductColors = true, showProductLinks = true, showRemoveButton = true, showSubtotal = true, showCheckoutButton = true, showContinueShoppingButton = true, showShippingNote = true, showQuantityControls = true,
21
+ // Štýlovanie s predvolenými hodnotami
22
+ customClassName = '', maxHeight = '100vh', animationDuration = 500, backdropOpacity = 0.75,
23
+ // Vlastné renderovanie
24
+ renderCustomProduct, renderCustomFooter,
25
+ // Stav
26
+ pendingUpdates = {}, processingItems = {}, }) => {
27
+ const handleCheckout = () => {
28
+ if (onCheckout) {
29
+ onCheckout();
30
+ }
31
+ };
32
+ const handleContinueShopping = () => {
33
+ if (onContinueShopping) {
34
+ onContinueShopping();
35
+ }
36
+ else {
37
+ onClose();
38
+ }
39
+ };
40
+ const handleIncrement = (productId, quantity) => {
41
+ if (onQuantityChange) {
42
+ onQuantityChange(productId, quantity + 1);
43
+ }
44
+ };
45
+ const handleDecrement = (productId, quantity) => {
46
+ if (onQuantityChange) {
47
+ if (quantity > 1) {
48
+ onQuantityChange(productId, quantity - 1);
49
+ }
50
+ else {
51
+ onQuantityChange(productId, 0);
52
+ }
53
+ }
54
+ };
55
+ const getVariantClasses = () => {
56
+ switch (variant) {
57
+ case 'compact':
58
+ return 'max-w-sm';
59
+ case 'full':
60
+ return 'max-w-2xl';
61
+ default:
62
+ return 'max-w-md';
63
+ }
64
+ };
65
+ const getPositionClasses = () => {
66
+ return position === 'left' ? 'left-0' : 'right-0';
67
+ };
68
+ return (_jsxs(Dialog, { open: isOpen, onClose: onClose, className: "relative z-60", children: [_jsx(DialogBackdrop, { transition: true, className: `fixed inset-0 bg-gray-500/75 transition-opacity duration-${animationDuration} ease-in-out data-closed:opacity-0`, style: { opacity: backdropOpacity } }), _jsx("div", { className: "fixed inset-0 overflow-hidden", children: _jsx("div", { className: "absolute inset-0 overflow-hidden", children: _jsx("div", { className: `pointer-events-none fixed inset-y-0 ${getPositionClasses()} flex max-w-full pl-10`, children: _jsx(DialogPanel, { transition: true, className: `pointer-events-auto w-screen ${getVariantClasses()} transform transition duration-${animationDuration} ease-in-out data-closed:translate-x-full sm:duration-700 ${customClassName}`, children: _jsxs("div", { className: "flex h-full flex-col overflow-y-scroll bg-white shadow-xl", style: { maxHeight }, children: [_jsxs("div", { className: "flex-1 overflow-y-auto px-4 py-6 sm:px-6", children: [_jsxs("div", { className: "flex items-start justify-between", children: [_jsx(DialogTitle, { className: "text-lg font-medium text-gray-900", children: title }), _jsx("div", { className: "ml-3 flex h-7 items-center", children: _jsxs("button", { type: "button", onClick: onClose, className: "relative -m-2 p-2 text-gray-400 hover:text-gray-500", children: [_jsx("span", { className: "absolute -inset-0.5" }), _jsx("span", { className: "sr-only", children: "Close panel" }), _jsx(XMarkIcon, { "aria-hidden": "true", className: "size-6" })] }) })] }), _jsx("div", { className: "mt-8", children: _jsx("div", { className: "flow-root", children: products.length === 0 ? (_jsx("div", { className: "py-6 text-center text-gray-500", children: emptyCartText })) : (_jsx("ul", { role: "list", className: "-my-6 divide-y divide-gray-200", children: products.map((product) => {
69
+ if (renderCustomProduct) {
70
+ return renderCustomProduct(product);
71
+ }
72
+ const displayQuantity = product.id in pendingUpdates
73
+ ? pendingUpdates[product.id]
74
+ : product.quantity;
75
+ const isProcessing = processingItems[product.id] === true;
76
+ return (_jsxs("li", { className: "flex py-6", children: [showProductImages &&
77
+ product.image && (_jsx("div", { className: "size-24 shrink-0 overflow-hidden rounded-md border border-gray-200", children: _jsx("img", { alt: product.image
78
+ .alt, src: product.image
79
+ .src, className: "size-full object-cover" }) })), _jsxs("div", { className: "ml-4 flex flex-1 flex-col", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex justify-between text-base font-medium text-gray-900", children: [_jsx("h3", { children: showProductLinks &&
80
+ product.href ? (_jsx("a", { href: product.href, onClick: (e) => {
81
+ if (onProductClick) {
82
+ e.preventDefault();
83
+ onProductClick(product);
84
+ }
85
+ }, children: product.name })) : (product.name) }), _jsx("p", { className: "ml-4", children: formatPrice(product.price) })] }), showProductColors &&
86
+ product.color && (_jsx("p", { className: "mt-1 text-sm text-gray-500", children: product.color }))] }), _jsxs("div", { className: "flex flex-1 items-end justify-between text-sm", children: [showQuantityControls &&
87
+ onQuantityChange ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("p", { className: "text-gray-500 mr-2", children: quantityLabel }), _jsxs("div", { className: "flex items-center", children: [_jsx("button", { type: "button", onClick: () => !isProcessing &&
88
+ handleDecrement(product.id, displayQuantity), disabled: isProcessing, className: `rounded-full p-1 text-gray-600 ${isProcessing
89
+ ? 'bg-gray-100 cursor-not-allowed opacity-50'
90
+ : 'bg-gray-200 hover:bg-gray-300'}`, children: _jsx(MinusIcon, { className: "h-4 w-4" }) }), _jsx("span", { className: "mx-2 min-w-[20px] text-center text-black", children: displayQuantity }), _jsx("button", { type: "button", onClick: () => !isProcessing &&
91
+ handleIncrement(product.id, displayQuantity), disabled: isProcessing, className: `rounded-full p-1 text-gray-600 ${isProcessing
92
+ ? 'bg-gray-100 cursor-not-allowed opacity-50'
93
+ : 'bg-gray-200 hover:bg-gray-300'}`, children: _jsx(PlusIcon, { className: "h-4 w-4" }) })] })] })) : (_jsxs("p", { className: "text-gray-500", children: [quantityLabel, ' ', displayQuantity] })), showRemoveButton &&
94
+ onRemoveProduct && (_jsx("div", { className: "flex", children: _jsx("button", { type: "button", className: `font-medium ${isProcessing
95
+ ? 'text-gray-400 cursor-not-allowed'
96
+ : 'text-green-600 hover:text-green-500'}`, onClick: () => !isProcessing &&
97
+ onRemoveProduct(product.id), disabled: isProcessing, children: removeButtonText }) }))] })] })] }, product.id));
98
+ }) })) }) })] }), _jsxs("div", { className: "border-t border-gray-200 px-4 py-6 sm:px-6", children: [showSubtotal && (_jsxs("div", { className: "flex justify-between text-base font-medium text-gray-900", children: [_jsx("p", { children: totalLabel }), _jsx("p", { children: typeof subtotal === 'number'
99
+ ? formatPrice(subtotal)
100
+ : subtotal })] })), showShippingNote && (_jsx("p", { className: "mt-0.5 text-sm text-gray-500", children: shippingNoteText })), products.length > 0 && showCheckoutButton && onCheckout && (_jsx("div", { className: "mt-6", children: _jsx("button", { onClick: handleCheckout, className: "flex w-full items-center justify-center rounded-md border border-transparent bg-green-600 px-6 py-3 text-base font-medium text-white shadow-xs hover:bg-green-700", children: checkoutText }) })), showContinueShoppingButton && (_jsx("div", { className: "mt-6 flex justify-center text-center text-sm text-gray-500", children: _jsx("p", { children: _jsxs("button", { type: "button", onClick: handleContinueShopping, className: "font-medium text-green-600 hover:text-green-500", children: [continueShoppingText, _jsx("span", { "aria-hidden": "true", children: " \u2192" })] }) }) })), renderCustomFooter && renderCustomFooter()] })] }) }) }) }) })] }));
101
+ };
@@ -0,0 +1,14 @@
1
+ import { Term } from '@q2devel/q2-core';
2
+ type CategoryTreeProps = {
3
+ terms: Term[];
4
+ activeTerm: Term;
5
+ labels: {
6
+ category: string;
7
+ };
8
+ onTermClick?: (term: Term) => void;
9
+ };
10
+ export declare const findChildren: (term: Term, terms: Term[]) => Term[];
11
+ export declare const flattenTermIds: (terms: Term[]) => string[];
12
+ export declare const findParentTerm: (term: Term, terms: Term[]) => Term[];
13
+ export default function CategoryTree({ terms, activeTerm, labels, onTermClick }: CategoryTreeProps): import("react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { PlusIcon, MinusIcon } from '@heroicons/react/20/solid';
4
+ import { useState, useEffect } from 'react';
5
+ import Button from '../../Base/button/Button';
6
+ export const findChildren = (term, terms) => {
7
+ const children = terms
8
+ .filter((t) => t.parent?.drupal_internal__tid === term.id)
9
+ .map((child) => ({
10
+ ...child,
11
+ children: findChildren(child, terms),
12
+ }));
13
+ return children.sort((a, b) => a.name?.localeCompare(b.name || '') || 0);
14
+ };
15
+ export const flattenTermIds = (terms) => {
16
+ return terms.flatMap((term) => [
17
+ term.id,
18
+ ...(term.children ? flattenTermIds(term.children) : []),
19
+ ]);
20
+ };
21
+ export const findParentTerm = (term, terms) => {
22
+ let parent = terms.find((item) => item.id === term?.parent?.drupal_internal__tid);
23
+ if (parent !== undefined) {
24
+ return [term, ...findParentTerm(parent, terms)];
25
+ }
26
+ return [term];
27
+ };
28
+ function CategoryNode({ term, allTerms, level, activeTerm, parentIds, onTermClick, }) {
29
+ const children = findChildren(term, allTerms);
30
+ const hasChildren = children.length > 0;
31
+ const [isOpen, setIsOpen] = useState(false);
32
+ useEffect(() => {
33
+ if (parentIds?.includes(term.id) && term.id !== activeTerm.id) {
34
+ setIsOpen(true);
35
+ }
36
+ }, [term.id, parentIds, activeTerm.id]);
37
+ return (_jsxs("div", { className: "py-1", children: [_jsxs("div", { className: `
38
+ flex w-full items-center justify-between text-left text-sm
39
+ border-l-2 border-transparent
40
+ hover:border-green-500 transition-colors duration-200 cursor-pointer
41
+ ${term.id === activeTerm.id ? 'font-semibold text-green-700 underline border-green-700' : ''}
42
+ ${parentIds?.includes(term.id) && term.id !== activeTerm.id ? 'font-medium text-green-600' : 'text-gray-900'}
43
+ hover:text-green-600 select-none
44
+ `, style: { paddingLeft: `${level * 16}px` }, onClick: () => {
45
+ if (hasChildren)
46
+ setIsOpen((prev) => !prev);
47
+ onTermClick?.(term);
48
+ }, children: [_jsx(Button, { asLink: true, unstyled: true, href: term.href, className: "flex-1", children: term.name }), hasChildren && (_jsxs("span", { className: "ml-2 flex items-center", children: [_jsx(PlusIcon, { className: `w-5 h-5 text-gray-400 ${isOpen ? 'hidden' : 'block'}` }), _jsx(MinusIcon, { className: `w-5 h-5 text-gray-400 ${isOpen ? 'block' : 'hidden'}` })] }))] }), hasChildren && isOpen && (_jsx("div", { className: "mt-1 space-y-0.5", children: children.map((child) => (_jsx(CategoryNode, { term: child, allTerms: allTerms, level: level + 1, activeTerm: activeTerm, parentIds: parentIds, onTermClick: onTermClick }, child.id))) }))] }));
49
+ }
50
+ export default function CategoryTree({ terms, activeTerm, labels, onTermClick }) {
51
+ const parentIds = findParentTerm(activeTerm, terms).map((term) => term.id);
52
+ const firstLevelTerms = terms.filter((term) => !term.parent);
53
+ const [isOpen, setIsOpen] = useState(true);
54
+ return (_jsxs("div", { className: "border-b border-gray-300 py-6", children: [_jsxs("div", { className: "flex w-full items-center justify-between text-left text-sm font-medium text-gray-900 hover:text-green-600 transition-colors duration-300 cursor-pointer select-none", onClick: () => setIsOpen((prev) => !prev), children: [_jsx("span", { children: labels.category }), _jsxs("span", { className: "ml-2 flex items-center", children: [_jsx(PlusIcon, { className: `w-5 h-5 text-gray-400 ${isOpen ? 'hidden' : 'block'}` }), _jsx(MinusIcon, { className: `w-5 h-5 text-gray-400 ${isOpen ? 'block' : 'hidden'}` })] })] }), isOpen && (_jsx("div", { className: "mt-4 space-y-1", children: firstLevelTerms.map((term) => (_jsx(CategoryNode, { term: term, allTerms: terms, level: 1, activeTerm: activeTerm, parentIds: parentIds, onTermClick: onTermClick }, term.id))) }))] }));
55
+ }
@@ -0,0 +1,66 @@
1
+ import { Product } from '@q2devel/q2-core';
2
+ import React from 'react';
3
+ export type Wishlist = {
4
+ id: string;
5
+ name: string;
6
+ };
7
+ export type ProductCardProps = {
8
+ product: Product;
9
+ href: string;
10
+ className?: string;
11
+ imageClassName?: string;
12
+ contentClassName?: string;
13
+ titleClassName?: string;
14
+ colorClassName?: string;
15
+ priceClassName?: string;
16
+ descriptionClassName?: string;
17
+ badgeClassName?: string;
18
+ aspectRatio?: 'square' | 'auto' | 'video' | 'wide';
19
+ imagePosition?: 'top' | 'bottom' | 'center';
20
+ imageObjectFit?: 'cover' | 'contain' | 'fill' | 'none';
21
+ layout?: 'default' | 'compact' | 'horizontal';
22
+ hoverEffect?: 'opacity' | 'scale' | 'shadow' | 'border' | 'none';
23
+ renderBadges?: boolean;
24
+ renderColor?: boolean;
25
+ renderDescription?: boolean;
26
+ elevationLevel?: 0 | 1 | 2 | 3;
27
+ rounded?: 'none' | 'sm' | 'md' | 'lg' | 'full';
28
+ titleLines?: 1 | 2 | 3;
29
+ onCardClick?: (product: Product) => void;
30
+ onImageClick?: (product: Product) => void;
31
+ renderFooter?: (product: Product) => React.ReactNode;
32
+ renderHeader?: (product: Product) => React.ReactNode;
33
+ actionButton?: React.ReactNode;
34
+ showAddButton?: boolean;
35
+ currentQuantity: number;
36
+ onQuantityChange?: (product: Product, quantity: number) => void;
37
+ addButtonIcon?: React.ReactNode;
38
+ maxQuantity?: number;
39
+ controlsClassName?: string;
40
+ buttonClassName?: string;
41
+ quantityClassName?: string;
42
+ customAddButton?: React.ReactNode;
43
+ disabled?: boolean;
44
+ locale: string;
45
+ cartMode?: 'full' | 'add-only';
46
+ showSpinnerInAdd?: boolean;
47
+ showWishlistButton?: boolean;
48
+ isInWishlist?: boolean;
49
+ onWishlistToggle?: (product: Product) => void;
50
+ wishlistButtonClassName?: string;
51
+ isWishlistPending?: boolean;
52
+ enableMultipleWishlists?: boolean;
53
+ wishlists?: Wishlist[];
54
+ onAddToWishlist?: (product: Product, wishlistId: string) => void;
55
+ onRemoveFromWishlist?: (product: Product, wishlistId: string) => void;
56
+ onCreateWishlist?: (name: string, product: Product) => void;
57
+ wishlistDropdownClassName?: string;
58
+ productWishlistIds?: string[];
59
+ showDeleteButton?: boolean;
60
+ onDelete?: (product: Product) => void;
61
+ deleteButtonClassName?: string;
62
+ isDeletePending?: boolean;
63
+ deleteButtonSize?: 'sm' | 'md' | 'lg';
64
+ deleteButtonPosition?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
65
+ };
66
+ export declare const ProductCard: ({ product, href, className, imageClassName, contentClassName, titleClassName, colorClassName, priceClassName, descriptionClassName, badgeClassName, aspectRatio, imagePosition, imageObjectFit, layout, hoverEffect, renderBadges, renderColor, renderDescription, elevationLevel, rounded, titleLines, onCardClick, onImageClick, renderFooter, renderHeader, actionButton, showAddButton, currentQuantity, onQuantityChange, addButtonIcon, maxQuantity, controlsClassName, buttonClassName, quantityClassName, customAddButton, disabled, locale, cartMode, showSpinnerInAdd, showWishlistButton, isInWishlist, onWishlistToggle, wishlistButtonClassName, isWishlistPending, enableMultipleWishlists, wishlists, onAddToWishlist, onRemoveFromWishlist, onCreateWishlist, wishlistDropdownClassName, productWishlistIds, showDeleteButton, onDelete, deleteButtonClassName, isDeletePending, deleteButtonSize, deleteButtonPosition, }: ProductCardProps) => import("react/jsx-runtime").JSX.Element;