keystone-design-bootstrap 1.0.48 → 1.0.49

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 (35) hide show
  1. package/dist/{blog-post-CvRhU9ss.d.ts → blog-post-D7HFCDp1.d.ts} +2 -2
  2. package/dist/design_system/elements/index.d.ts +25 -1
  3. package/dist/design_system/elements/index.js +103 -3
  4. package/dist/design_system/elements/index.js.map +1 -1
  5. package/dist/design_system/sections/index.d.ts +64 -3
  6. package/dist/design_system/sections/index.js +1305 -458
  7. package/dist/design_system/sections/index.js.map +1 -1
  8. package/dist/form-BLZuTGkr.d.ts +137 -0
  9. package/dist/index.d.ts +6 -5
  10. package/dist/index.js +1335 -487
  11. package/dist/index.js.map +1 -1
  12. package/dist/lib/server-api.d.ts +49 -4
  13. package/dist/lib/server-api.js +17 -0
  14. package/dist/lib/server-api.js.map +1 -1
  15. package/dist/photos-8jMeetqV.d.ts +47 -0
  16. package/dist/types/index.d.ts +6 -5
  17. package/dist/utils/photo-helpers.d.ts +6 -15
  18. package/dist/utils/photo-helpers.js +10 -1
  19. package/dist/utils/photo-helpers.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/design_system/elements/index.tsx +4 -0
  22. package/src/design_system/elements/modal/modal.tsx +129 -0
  23. package/src/design_system/sections/index.tsx +20 -2
  24. package/src/design_system/sections/offer-detail.tsx +46 -0
  25. package/src/design_system/sections/offers-gallery.tsx +40 -0
  26. package/src/design_system/sections/offers-grid.tsx +108 -0
  27. package/src/design_system/sections/offers-section.tsx +90 -0
  28. package/src/design_system/sections/service-menu-section.tsx +813 -0
  29. package/src/lib/server-api.ts +63 -0
  30. package/src/types/api/photos.ts +11 -10
  31. package/src/types/api/service.ts +21 -0
  32. package/src/utils/photo-helpers.ts +3 -14
  33. package/dist/company-information-C_k_sLSB.d.ts +0 -46
  34. package/dist/form-CWXC-IHT.d.ts +0 -88
  35. package/dist/website-photos-_n2g24IM.d.ts +0 -20
@@ -1,4 +1,4 @@
1
- import { a as PhotoAttachment } from './form-CWXC-IHT.js';
1
+ import { P as PhotoAttachment } from './photos-8jMeetqV.js';
2
2
 
3
3
  interface BlogPost {
4
4
  id: number;
@@ -47,4 +47,4 @@ interface BlogPostTag {
47
47
  updated_at: string;
48
48
  }
49
49
 
50
- export type { BlogPost as B, BlogPostAuthor as a, BlogPostTag as b, BlogPostParams as c, BlogPostResponse as d };
50
+ export type { BlogPost as B, BlogPostParams as a, BlogPostResponse as b, BlogPostAuthor as c, BlogPostTag as d };
@@ -310,6 +310,30 @@ interface VideoPlayButtonProps {
310
310
  }
311
311
  declare function VideoPlayButton({ onClick, className }: VideoPlayButtonProps): React.JSX.Element;
312
312
 
313
+ interface ModalProps {
314
+ /** Whether the modal is open */
315
+ isOpen: boolean;
316
+ /** Called when the user requests close (button, Escape, or overlay click) */
317
+ onClose: () => void;
318
+ /** Optional title for the dialog (used for aria-labelledby) */
319
+ title?: string;
320
+ /** Optional id for the title element (must be set if title is set for a11y) */
321
+ titleId?: string;
322
+ /** Dialog content */
323
+ children: React__default.ReactNode;
324
+ /** Optional className for the overlay (backdrop) */
325
+ overlayClassName?: string;
326
+ /** Optional className for the dialog panel */
327
+ panelClassName?: string;
328
+ /** Optional max width class for the panel (default: max-w-md). Use max-w-lg, max-w-2xl, etc. */
329
+ maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl';
330
+ }
331
+ /**
332
+ * Shared modal (dialog) component. Accessible: focus trap, Escape to close, aria-modal, overlay click to close.
333
+ * Use for detail views, confirmations, and other overlay content. Renders in place (use a portal from the consumer if needed).
334
+ */
335
+ declare function Modal({ isOpen, onClose, title, titleId, children, overlayClassName, panelClassName, maxWidth, }: ModalProps): React__default.JSX.Element | null;
336
+
313
337
  declare const Button: (props: Record<string, unknown>) => React__default.ReactElement<Record<string, unknown>, string | React__default.JSXElementConstructor<any>>;
314
338
  declare const RoundButton: (props: Record<string, unknown>) => React__default.ReactElement<Record<string, unknown>, string | React__default.JSXElementConstructor<any>>;
315
339
  declare const ButtonGroup: (props: Record<string, unknown>) => React__default.ReactElement<Record<string, unknown>, string | React__default.JSXElementConstructor<any>>;
@@ -345,4 +369,4 @@ declare const PaginationPageMinimalCenter: (props: Record<string, unknown>) => R
345
369
  declare const GoogleMap: (props: Record<string, unknown>) => React__default.ReactElement<Record<string, unknown>, string | React__default.JSXElementConstructor<any>>;
346
370
  declare const MarkdownRenderer: (props: Record<string, unknown>) => React__default.ReactElement<Record<string, unknown>, string | React__default.JSXElementConstructor<any>>;
347
371
 
348
- export { Avatar, AvatarLabelGroup, Badge, BadgeGroup, BadgeWithDot, Breadcrumb, Button, ButtonGroup, Carousel, CarouselContext, CarouselSectionWrapper, ComboBox, FeaturedIcon, Form, FormContainer, GoogleMap, HintText, Input, InputBase, InputGroup, Label, MarkdownRenderer, NativeSelect, Pagination, PaginationPageDefault, PaginationPageMinimalCenter, PhotoWithFallback, PrivacyCheckbox, RatingBadge, RatingStars, RoundButton, Select, SelectItem, SocialIcon, StarIcon, Textarea, Tooltip, VerifiedTick, VideoModal, VideoPlayButton, Wreath, getSocialIcon, getStarProgress, useCarousel };
372
+ export { Avatar, AvatarLabelGroup, Badge, BadgeGroup, BadgeWithDot, Breadcrumb, Button, ButtonGroup, Carousel, CarouselContext, CarouselSectionWrapper, ComboBox, FeaturedIcon, Form, FormContainer, GoogleMap, HintText, Input, InputBase, InputGroup, Label, MarkdownRenderer, Modal, type ModalProps, NativeSelect, Pagination, PaginationPageDefault, PaginationPageMinimalCenter, PhotoWithFallback, PrivacyCheckbox, RatingBadge, RatingStars, RoundButton, Select, SelectItem, SocialIcon, StarIcon, Textarea, Tooltip, VerifiedTick, VideoModal, VideoPlayButton, Wreath, getSocialIcon, getStarProgress, useCarousel };
@@ -32,7 +32,7 @@ var __objRest = (source, exclude) => {
32
32
  };
33
33
 
34
34
  // src/design_system/elements/index.tsx
35
- import React13 from "react";
35
+ import React14 from "react";
36
36
 
37
37
  // src/lib/component-registry.ts
38
38
  var registry = /* @__PURE__ */ new Map();
@@ -3683,15 +3683,114 @@ function VideoPlayButton({ onClick, className = "" }) {
3683
3683
  );
3684
3684
  }
3685
3685
 
3686
+ // src/design_system/elements/modal/modal.tsx
3687
+ import React13, { useEffect as useEffect6, useRef as useRef4 } from "react";
3688
+ var MAX_WIDTH_CLASSES = {
3689
+ sm: "max-w-sm",
3690
+ md: "max-w-md",
3691
+ lg: "max-w-lg",
3692
+ xl: "max-w-xl",
3693
+ "2xl": "max-w-2xl",
3694
+ "3xl": "max-w-3xl",
3695
+ "4xl": "max-w-4xl",
3696
+ "5xl": "max-w-5xl"
3697
+ };
3698
+ function Modal({
3699
+ isOpen,
3700
+ onClose,
3701
+ title,
3702
+ titleId = "modal-title",
3703
+ children,
3704
+ overlayClassName,
3705
+ panelClassName,
3706
+ maxWidth = "md"
3707
+ }) {
3708
+ const overlayRef = useRef4(null);
3709
+ const closeButtonRef = useRef4(null);
3710
+ useEffect6(() => {
3711
+ var _a;
3712
+ if (!isOpen) return;
3713
+ const previouslyFocused = document.activeElement;
3714
+ (_a = closeButtonRef.current) == null ? void 0 : _a.focus();
3715
+ const handleEscape = (e) => {
3716
+ if (e.key === "Escape") onClose();
3717
+ };
3718
+ document.addEventListener("keydown", handleEscape);
3719
+ document.body.style.overflow = "hidden";
3720
+ return () => {
3721
+ document.removeEventListener("keydown", handleEscape);
3722
+ document.body.style.overflow = "";
3723
+ previouslyFocused == null ? void 0 : previouslyFocused.focus();
3724
+ };
3725
+ }, [isOpen, onClose]);
3726
+ if (!isOpen) return null;
3727
+ const maxWidthClass = MAX_WIDTH_CLASSES[maxWidth];
3728
+ return /* @__PURE__ */ React13.createElement(
3729
+ "div",
3730
+ {
3731
+ ref: overlayRef,
3732
+ className: overlayClassName != null ? overlayClassName : "fixed inset-0 z-[200] flex items-center justify-center p-4 bg-black/50",
3733
+ role: "dialog",
3734
+ "aria-modal": "true",
3735
+ "aria-labelledby": title ? titleId : void 0,
3736
+ onClick: (e) => e.target === overlayRef.current && onClose()
3737
+ },
3738
+ /* @__PURE__ */ React13.createElement(
3739
+ "div",
3740
+ {
3741
+ className: panelClassName != null ? panelClassName : `bg-primary border border-secondary rounded-lg shadow-xl w-full overflow-hidden ${maxWidthClass} max-h-[90vh] flex flex-col`,
3742
+ onClick: (e) => e.stopPropagation()
3743
+ },
3744
+ /* @__PURE__ */ React13.createElement("div", { className: "flex items-start justify-between gap-4 p-4 md:p-6 border-b border-secondary flex-shrink-0" }, title ? /* @__PURE__ */ React13.createElement(
3745
+ "h2",
3746
+ {
3747
+ id: titleId,
3748
+ className: "font-display text-lg font-normal text-fg-primary md:text-xl flex-1 min-w-0"
3749
+ },
3750
+ title
3751
+ ) : /* @__PURE__ */ React13.createElement("span", { className: "flex-1", "aria-hidden": true }), /* @__PURE__ */ React13.createElement(
3752
+ "button",
3753
+ {
3754
+ ref: closeButtonRef,
3755
+ type: "button",
3756
+ onClick: onClose,
3757
+ className: "shrink-0 p-1 text-fg-primary hover:text-brand-accent rounded focus:outline-none focus:ring-2 focus:ring-brand-accent",
3758
+ "aria-label": "Close"
3759
+ },
3760
+ /* @__PURE__ */ React13.createElement(
3761
+ "svg",
3762
+ {
3763
+ className: "w-5 h-5",
3764
+ fill: "none",
3765
+ stroke: "currentColor",
3766
+ viewBox: "0 0 24 24",
3767
+ "aria-hidden": true
3768
+ },
3769
+ /* @__PURE__ */ React13.createElement(
3770
+ "path",
3771
+ {
3772
+ strokeLinecap: "round",
3773
+ strokeLinejoin: "round",
3774
+ strokeWidth: 2,
3775
+ d: "M6 18L18 6M6 6l12 12"
3776
+ }
3777
+ )
3778
+ )
3779
+ )),
3780
+ /* @__PURE__ */ React13.createElement("div", { className: "overflow-y-auto flex-1 p-4 md:p-6" }, children)
3781
+ )
3782
+ );
3783
+ }
3784
+
3686
3785
  // src/design_system/elements/index.tsx
3687
3786
  function createThemedExport(componentName, BaseComponent) {
3688
3787
  return function ThemedComponent(props) {
3689
3788
  const { theme } = useTheme();
3690
3789
  try {
3691
3790
  const Component = getThemedComponent(componentName, theme);
3692
- return React13.createElement(Component, props);
3791
+ return React14.createElement(Component, props);
3693
3792
  } catch (e) {
3694
- return React13.createElement(BaseComponent, props);
3793
+ return React14.createElement(BaseComponent, props);
3695
3794
  }
3696
3795
  };
3697
3796
  }
@@ -3749,6 +3848,7 @@ export {
3749
3848
  InputGroup2 as InputGroup,
3750
3849
  Label2 as Label,
3751
3850
  MarkdownRenderer2 as MarkdownRenderer,
3851
+ Modal,
3752
3852
  NativeSelect2 as NativeSelect,
3753
3853
  Pagination,
3754
3854
  PaginationPageDefault2 as PaginationPageDefault,