@edifice.io/react 2.5.8 → 2.5.9-develop-pedago.20260203115913

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 (109) hide show
  1. package/README.md +5 -0
  2. package/dist/_virtual/isSameOrAfter.js +4 -0
  3. package/dist/_virtual/isToday.js +4 -0
  4. package/dist/components/Badge/Badge.d.ts +7 -1
  5. package/dist/components/Badge/Badge.js +13 -1
  6. package/dist/components/DatePicker/DatePicker.d.ts +57 -0
  7. package/dist/components/DatePicker/DatePicker.js +6 -3
  8. package/dist/components/Dropdown/DropdownContext.js +1 -1
  9. package/dist/components/Form/FormContext.js +1 -1
  10. package/dist/components/Layout/Layout.js +1 -2
  11. package/dist/components/Layout/components/Header.js +5 -2
  12. package/dist/components/Layout/components/WidgetApps.js +2 -2
  13. package/dist/components/MediaViewer/MediaViewer.d.ts +17 -0
  14. package/dist/components/MediaViewer/MediaViewer.js +36 -0
  15. package/dist/components/MediaViewer/MediaWrapper.d.ts +7 -0
  16. package/dist/components/MediaViewer/MediaWrapper.js +72 -0
  17. package/dist/components/MediaViewer/PdfViewer.d.ts +4 -0
  18. package/dist/components/MediaViewer/PdfViewer.js +26 -0
  19. package/dist/components/MediaViewer/ToolbarViewer.d.ts +7 -0
  20. package/dist/components/MediaViewer/ToolbarViewer.js +41 -0
  21. package/dist/components/MediaViewer/ToolbarZoom.d.ts +4 -0
  22. package/dist/components/MediaViewer/ToolbarZoom.js +19 -0
  23. package/dist/components/MediaViewer/index.d.ts +2 -0
  24. package/dist/components/Modal/Modal.d.ts +4 -0
  25. package/dist/components/Modal/Modal.js +13 -12
  26. package/dist/components/PromotionCard/PromotionCard.d.ts +74 -0
  27. package/dist/components/PromotionCard/PromotionCard.js +31 -0
  28. package/dist/components/PromotionCard/PromotionCardBody.d.ts +10 -0
  29. package/dist/components/PromotionCard/PromotionCardBody.js +15 -0
  30. package/dist/components/PromotionCard/PromotionCardDescription.d.ts +9 -0
  31. package/dist/components/PromotionCard/PromotionCardDescription.js +12 -0
  32. package/dist/components/PromotionCard/PromotionCardFooter.d.ts +9 -0
  33. package/dist/components/PromotionCard/PromotionCardFooter.js +12 -0
  34. package/dist/components/PromotionCard/PromotionCardHeader.d.ts +11 -0
  35. package/dist/components/PromotionCard/PromotionCardHeader.js +17 -0
  36. package/dist/components/PromotionCard/PromotionCardIcon.d.ts +10 -0
  37. package/dist/components/PromotionCard/PromotionCardIcon.js +15 -0
  38. package/dist/components/PromotionCard/PromotionCardTitle.d.ts +9 -0
  39. package/dist/components/PromotionCard/PromotionCardTitle.js +12 -0
  40. package/dist/components/PromotionCard/index.d.ts +2 -0
  41. package/dist/components/SmartEllipsis/SmartEllipsis.d.ts +5 -0
  42. package/dist/components/SmartEllipsis/SmartEllipsis.js +21 -0
  43. package/dist/components/SmartEllipsis/index.d.ts +2 -0
  44. package/dist/components/Toolbar/Toolbar.js +1 -1
  45. package/dist/components/index.d.ts +2 -0
  46. package/dist/editor.js +40 -40
  47. package/dist/hooks/useConversation/useConversation.js +3 -1
  48. package/dist/hooks/useDate/useDate.d.ts +5 -1
  49. package/dist/hooks/useDate/useDate.js +18 -2
  50. package/dist/hooks/useDropdown/useDropdown.js +1 -1
  51. package/dist/hooks/useDropzone/useDropzone.js +21 -16
  52. package/dist/hooks/useEdificeIcons/useEdificeIcons.d.ts +1 -0
  53. package/dist/hooks/useEdificeIcons/useEdificeIcons.js +5 -0
  54. package/dist/hooks/useZoom/index.d.ts +1 -0
  55. package/dist/hooks/useZoom/useZoom.d.ts +7 -0
  56. package/dist/hooks/useZoom/useZoom.js +14 -0
  57. package/dist/icons-apps.js +234 -232
  58. package/dist/icons.js +366 -350
  59. package/dist/index.js +231 -226
  60. package/dist/modals.js +18 -18
  61. package/dist/modules/audience/ViewsCounter.d.ts +3 -17
  62. package/dist/modules/audience/ViewsCounter.js +9 -7
  63. package/dist/modules/comments/components/Comment.js +4 -4
  64. package/dist/modules/comments/components/CommentDate.js +7 -10
  65. package/dist/modules/comments/components/CommentDeleted.js +1 -1
  66. package/dist/modules/comments/components/CommentForm.d.ts +1 -1
  67. package/dist/modules/comments/components/CommentForm.js +6 -6
  68. package/dist/modules/comments/components/CommentTitle.js +1 -1
  69. package/dist/modules/comments/provider/CommentProvider.js +4 -4
  70. package/dist/modules/comments/types.d.ts +3 -1
  71. package/dist/modules/editor/hooks/useTipTapEditor.js +4 -4
  72. package/dist/modules/icons/components/IconAdjustSettings.d.ts +7 -0
  73. package/dist/modules/icons/components/IconAdjustSettings.js +12 -0
  74. package/dist/modules/icons/components/IconAiFill.d.ts +7 -0
  75. package/dist/modules/icons/components/IconAiFill.js +12 -0
  76. package/dist/modules/icons/components/IconCalendarEdit.d.ts +7 -0
  77. package/dist/modules/icons/components/IconCalendarEdit.js +12 -0
  78. package/dist/modules/icons/components/IconCollect.d.ts +7 -0
  79. package/dist/modules/icons/components/IconCollect.js +12 -0
  80. package/dist/modules/icons/components/IconExercizerAi.d.ts +7 -0
  81. package/dist/modules/icons/components/IconExercizerAi.js +14 -0
  82. package/dist/modules/icons/components/IconLabel.d.ts +7 -0
  83. package/dist/modules/icons/components/IconLabel.js +12 -0
  84. package/dist/modules/icons/components/IconRender.d.ts +7 -0
  85. package/dist/modules/icons/components/IconRender.js +12 -0
  86. package/dist/modules/icons/components/IconTeacher.d.ts +7 -0
  87. package/dist/modules/icons/components/IconTeacher.js +12 -0
  88. package/dist/modules/icons/components/apps/IconAssistancetic.d.ts +7 -0
  89. package/dist/modules/icons/components/apps/IconAssistancetic.js +14 -0
  90. package/dist/modules/icons/components/apps/index.d.ts +1 -0
  91. package/dist/modules/icons/components/index.d.ts +8 -0
  92. package/dist/modules/modals/OnboardingModal/OnboardingModal.js +5 -5
  93. package/dist/modules/modals/ResourceModal/ResourceModal.js +1 -2
  94. package/dist/modules/modals/ShareModal/ShareResources.d.ts +3 -0
  95. package/dist/modules/modals/ShareModal/ShareResources.js +9 -5
  96. package/dist/modules/multimedia/FileCard/FileCard.js +1 -1
  97. package/dist/modules/multimedia/Linker/ExternalLinker/ExternalLinker.js +1 -2
  98. package/dist/modules/multimedia/Linker/InternalLinker/InternalLinker.js +1 -2
  99. package/dist/modules/multimedia/MediaLibrary/MediaLibrary.js +1 -1
  100. package/dist/multimedia.js +10 -10
  101. package/dist/node_modules/.pnpm/dayjs@1.11.19/node_modules/dayjs/plugin/isSameOrAfter.js +18 -0
  102. package/dist/node_modules/.pnpm/dayjs@1.11.19/node_modules/dayjs/plugin/isToday.js +19 -0
  103. package/dist/providers/AntThemeProvider/antThemeConfig.js +1 -2
  104. package/dist/utilities/mime-types/index.d.ts +1 -0
  105. package/dist/utilities/mime-types/mime-types-utils.d.ts +1 -0
  106. package/dist/utilities/mime-types/mime-types-utils.js +4 -0
  107. package/package.json +7 -6
  108. package/dist/modules/comments/components/CommentHeader.d.ts +0 -3
  109. package/dist/modules/comments/components/CommentHeader.js +0 -8
package/README.md CHANGED
@@ -105,6 +105,11 @@ export interface ButtonProps {
105
105
  export * from './Button';
106
106
  ```
107
107
 
108
+ ## Adding Icons
109
+
110
+ https://edifice-community.atlassian.net/wiki/spaces/ODE/pages/4371611649/Overview#Ajout-de-l%E2%80%99ic%C3%B4ne
111
+
108
112
  ## Dev
109
113
 
110
114
  You can build your component using `Storybook`. See [README](../../docs//README.md)
115
+
@@ -0,0 +1,4 @@
1
+ var isSameOrAfter = { exports: {} };
2
+ export {
3
+ isSameOrAfter as __module
4
+ };
@@ -0,0 +1,4 @@
1
+ var isToday = { exports: {} };
2
+ export {
3
+ isToday as __module
4
+ };
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { UserProfile } from '@edifice.io/client';
2
+ import { IWebApp, UserProfile } from '@edifice.io/client';
3
3
  export type BadgeRef = HTMLSpanElement;
4
4
  /** Badge variant : notification */
5
5
  export type NotificationBadgeVariant = {
@@ -31,10 +31,16 @@ export type LinkBadgeVariant = {
31
31
  * Beta Badge is used to indicate that a feature is in beta phase.
32
32
  * The color prop allows to customize the badge color to match the app color.
33
33
  * Defaults to black if not provided.
34
+ * Beta Badge has a fixed text 'BÊTA' unless children is provided.
35
+ * If app is provided, the color of the Beta Badge is derived from the application colors.
36
+ * Example:
37
+ * <Badge variant={{ type: 'beta', color: '#823AA1', app: myApp }} />
38
+ * where myApp is of type IWebApp.
34
39
  */
35
40
  export type BetaBadgeVariant = {
36
41
  type: 'beta';
37
42
  color?: string;
43
+ app?: IWebApp;
38
44
  };
39
45
  export type BadgeVariants = NotificationBadgeVariant | ContentBadgeVariant | ProfileBadgeVariant | ChipBadgeVariant | LinkBadgeVariant | BetaBadgeVariant;
40
46
  export interface BadgeProps extends React.ComponentPropsWithRef<'span'> {
@@ -1,6 +1,7 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import clsx from "clsx";
4
+ import useEdificeIcons from "../../hooks/useEdificeIcons/useEdificeIcons.js";
4
5
  const Badge = /* @__PURE__ */ forwardRef(({
5
6
  className,
6
7
  variant = {
@@ -10,7 +11,18 @@ const Badge = /* @__PURE__ */ forwardRef(({
10
11
  children,
11
12
  ...restProps
12
13
  }, ref) => {
13
- const classes = clsx("badge rounded-pill", (variant.type === "content" || variant.type === "user") && "background" in variant ? "bg-gray-200" : (variant.type === "content" || variant.type === "user") && !("background" in variant) ? "border border-0" : "", variant.type === "content" && `text-${variant.level}`, variant.type === "notification" && `badge-notification bg-${variant.level} text-light border border-0`, variant.type === "user" && `badge-profile-${variant.profile.toLowerCase()}`, variant.type === "link" && "badge-link border border-0", variant.type === "chip" && "bg-gray-200", className);
14
+ const {
15
+ getIconClass,
16
+ getBackgroundLightIconClass,
17
+ getBorderIconClass
18
+ } = useEdificeIcons();
19
+ let badgeColorClassName = "";
20
+ if (variant.type === "beta" && variant.app) {
21
+ const colorAppClassName = getIconClass(variant.app), backgroundLightAppClassName = getBackgroundLightIconClass(variant.app), borderAppClassName = getBorderIconClass(variant.app);
22
+ badgeColorClassName = `${colorAppClassName} ${backgroundLightAppClassName} ${borderAppClassName}`;
23
+ }
24
+ console.log(badgeColorClassName);
25
+ const classes = clsx("badge rounded-pill", (variant.type === "content" || variant.type === "user") && "background" in variant ? "bg-gray-200" : (variant.type === "content" || variant.type === "user") && !("background" in variant) ? "border border-0" : "", variant.type === "content" && `text-${variant.level}`, variant.type === "notification" && `badge-notification bg-${variant.level} text-light border border-0`, variant.type === "user" && `badge-profile-${variant.profile.toLowerCase()}`, variant.type === "link" && "badge-link border border-0", variant.type === "chip" && "bg-gray-200", variant.type === "beta" && badgeColorClassName, className);
14
26
  return /* @__PURE__ */ jsxs("span", { ref, className: classes, style: (() => {
15
27
  if (variant.type !== "beta") return;
16
28
  const color = variant.color ?? "#000000";
@@ -0,0 +1,57 @@
1
+ /**
2
+ * DatePicker component props
3
+ *
4
+ * Minimal interface that only exposes what is necessary.
5
+ * Ant Design implementation is hidden and no Ant Design-specific props are exposed.
6
+ * Standard HTML div attributes are supported (passed through to the underlying DOM element).
7
+ */
8
+ export interface DatePickerProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange' | 'value' | 'defaultValue'> {
9
+ /**
10
+ * Selected date values
11
+ * @default today's date is setted by ant design if no value is provided
12
+ */
13
+ value?: Date;
14
+ /**
15
+ * Callback called when date changes
16
+ */
17
+ onChange?: (date?: Date) => void;
18
+ /**
19
+ * Date format to display in the picker
20
+ * @default 'DD / MM / YYYY'
21
+ */
22
+ dateFormat?: string;
23
+ /**
24
+ * Minimum selectable date
25
+ */
26
+ minDate?: Date;
27
+ /**
28
+ * Maximum selectable date
29
+ */
30
+ maxDate?: Date;
31
+ }
32
+ /**
33
+ * Type for DatePicker ref
34
+ */
35
+ /**
36
+ * DatePicker component
37
+ *
38
+ * Date picker component for selecting a date.
39
+ *
40
+ * **Note:** This component uses Ant Design's DatePicker component internally.
41
+ * Only the props defined in DatePickerProps are allowed to prevent
42
+ * dependency on Ant Design-specific features. To replace the implementation,
43
+ * modify the component body below.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * <DatePicker
48
+ * value={date}
49
+ * onChange={(date) => setDate(date)}
50
+ * dateFormat="YYYY-MM-DD"
51
+ * minDate={new Date(today.setDate(today.getDate() - 2))}
52
+ * maxDate={new Date(today.setDate(today.getDate() + 3))}
53
+ * />
54
+ * ```
55
+ */
56
+ declare const DatePicker: import('react').ForwardRefExoticComponent<DatePickerProps & import('react').RefAttributes<HTMLElement>>;
57
+ export default DatePicker;
@@ -16,7 +16,8 @@ const DatePicker = /* @__PURE__ */ forwardRef(({
16
16
  onChange,
17
17
  dateFormat = "DD / MM / YYYY",
18
18
  minDate,
19
- maxDate
19
+ maxDate,
20
+ ...htmlProps
20
21
  }, ref) => {
21
22
  const handleChange = (date) => {
22
23
  onChange == null || onChange(date ? date.toDate() : void 0);
@@ -26,9 +27,11 @@ const DatePicker = /* @__PURE__ */ forwardRef(({
26
27
  format: dateFormat,
27
28
  minDate: minDate ? dayjs(minDate) : void 0,
28
29
  maxDate: maxDate ? dayjs(maxDate) : void 0,
29
- ref
30
+ ref,
31
+ // Cast necessary because AntDatePicker expects a specific type, but our API exposes only HTMLElement to avoid dependency on Ant Design-specific features.
32
+ ...htmlProps
30
33
  };
31
- return /* @__PURE__ */ jsx(DatePicker$1, { ...antProps });
34
+ return /* @__PURE__ */ jsx(DatePicker$1, { ...antProps, getPopupContainer: (triggerNode) => triggerNode.parentElement || document.body });
32
35
  });
33
36
  export {
34
37
  DatePicker as default
@@ -1,4 +1,4 @@
1
- import { createContext, useContext } from "react";
1
+ import { useContext, createContext } from "react";
2
2
  const DropdownContext = /* @__PURE__ */ createContext(null), useDropdownContext = () => {
3
3
  const context = useContext(DropdownContext);
4
4
  if (!context)
@@ -1,4 +1,4 @@
1
- import { createContext, useContext } from "react";
1
+ import { useContext, createContext } from "react";
2
2
  const Context = /* @__PURE__ */ createContext(null), useFormControl = () => {
3
3
  const context = useContext(Context);
4
4
  if (!context)
@@ -42,6 +42,5 @@ const Layout = ({
42
42
  ] });
43
43
  };
44
44
  export {
45
- Layout,
46
- Layout as default
45
+ Layout
47
46
  };
@@ -93,7 +93,7 @@ const Header = ({
93
93
  }, className: "position-absolute", children: messages }),
94
94
  /* @__PURE__ */ jsx(VisuallyHidden, { children: t("navbar.messages") })
95
95
  ] }) }),
96
- hasCarbonioPreauthWorkflow && /* @__PURE__ */ jsx(NavItem, { children: /* @__PURE__ */ jsxs("a", { href: "/auth/carbonio/preauth", className: "nav-link", children: [
96
+ hasCarbonioPreauthWorkflow && /* @__PURE__ */ jsx(NavItem, { children: /* @__PURE__ */ jsxs("a", { href: "/auth/carbonio/preauth", target: "_blank", className: "nav-link", children: [
97
97
  /* @__PURE__ */ jsx(SvgIconOneMessaging, { className: "icon notification" }),
98
98
  /* @__PURE__ */ jsx(VisuallyHidden, { children: t("navbar.messages") })
99
99
  ] }) }),
@@ -157,7 +157,10 @@ const Header = ({
157
157
  level: "warning"
158
158
  }, className: "position-absolute", children: messages })
159
159
  ] }) }),
160
- hasCarbonioPreauthWorkflow && /* @__PURE__ */ jsx(NavItem, { children: /* @__PURE__ */ jsx(NavLink, { className: "position-relative", link: "/auth/carbonio/preauth", translate: t("conversation"), children: /* @__PURE__ */ jsx(SvgIconNeoMessaging, { color: "#fff" }) }) }),
160
+ hasCarbonioPreauthWorkflow && /* @__PURE__ */ jsx(NavItem, { children: /* @__PURE__ */ jsxs("a", { className: "nav-link position-relative", href: "/auth/carbonio/preauth", target: "_blank", children: [
161
+ /* @__PURE__ */ jsx(SvgIconNeoMessaging, { color: "#fff" }),
162
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: t("conversation") })
163
+ ] }) }),
161
164
  currentLanguage === "fr" && hasOldHelpEnableWorkflow ? /* @__PURE__ */ jsxs(NavItem, { children: [
162
165
  /* @__PURE__ */ jsxs("button", { className: "nav-link btn btn-naked", onClick: () => {
163
166
  setIsHelpOpen(!0);
@@ -6,7 +6,7 @@ const WidgetAppsFooter = () => {
6
6
  t
7
7
  } = useTranslation();
8
8
  return /* @__PURE__ */ jsx("div", { className: "widget-footer", children: /* @__PURE__ */ jsx("div", { className: "widget-footer-action", children: /* @__PURE__ */ jsx("a", { href: "/welcome", className: "link", children: t("plus") }) }) });
9
- }, WidgetAppsBody = ({
9
+ }, appToOpenOnBlank = ["Administration"], WidgetAppsBody = ({
10
10
  bookmarkedApps
11
11
  }) => {
12
12
  const {
@@ -14,7 +14,7 @@ const WidgetAppsFooter = () => {
14
14
  } = useTranslation();
15
15
  return /* @__PURE__ */ jsxs("div", { className: "widget-body d-flex flex-wrap", children: [
16
16
  !bookmarkedApps.length && /* @__PURE__ */ jsx("div", { className: "text-dark", children: t("navbar.myapps.more") }),
17
- bookmarkedApps.slice(0, 6).map((app, index) => /* @__PURE__ */ jsx("a", { href: app.address, className: "bookmarked-app", target: app.isExternal || app.category === "connector" ? "_blank" : void 0, children: /* @__PURE__ */ jsx(AppIcon, { app, size: "32" }) }, index))
17
+ bookmarkedApps.slice(0, 6).map((app, index) => /* @__PURE__ */ jsx("a", { href: app.address, className: "bookmarked-app", target: appToOpenOnBlank.includes(app.name) || app.isExternal || app.category === "connector" ? "_blank" : void 0, rel: appToOpenOnBlank.includes(app.name) || app.isExternal || app.category === "connector" ? "noopener noreferrer" : void 0, children: /* @__PURE__ */ jsx(AppIcon, { app, size: "32" }) }, index))
18
18
  ] });
19
19
  };
20
20
  export {
@@ -0,0 +1,17 @@
1
+ import { MediaLibraryType } from 'src/modules/multimedia';
2
+ export interface MediaProps {
3
+ name: string;
4
+ url: string;
5
+ type: MediaLibraryType;
6
+ mimeType?: string;
7
+ }
8
+ interface MediaViewerProps {
9
+ onClose: () => void;
10
+ media: MediaProps[];
11
+ indexMedia?: number;
12
+ }
13
+ declare const MediaViewer: {
14
+ ({ onClose, media, indexMedia }: MediaViewerProps): import("react/jsx-runtime").JSX.Element;
15
+ displayName: string;
16
+ };
17
+ export default MediaViewer;
@@ -0,0 +1,36 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { Carousel } from "antd";
3
+ import ToolbarZoom from "./ToolbarZoom.js";
4
+ import useZoom from "../../hooks/useZoom/useZoom.js";
5
+ import ToolbarViewer from "./ToolbarViewer.js";
6
+ import { useState, useEffect } from "react";
7
+ import { MediaWrapper } from "./MediaWrapper.js";
8
+ import Flex from "../Flex/Flex.js";
9
+ const MediaViewer = ({
10
+ onClose,
11
+ media,
12
+ indexMedia = 0
13
+ }) => {
14
+ const {
15
+ zoomIn,
16
+ zoomOut,
17
+ setScale,
18
+ scale
19
+ } = useZoom(1), [currentIndex, setCurrentIndex] = useState(indexMedia);
20
+ return useEffect(() => {
21
+ setCurrentIndex(indexMedia);
22
+ }, [indexMedia]), /* @__PURE__ */ jsxs("div", { className: "media-viewer", children: [
23
+ /* @__PURE__ */ jsx(ToolbarViewer, { onClose, mediaUrl: media[currentIndex].url, mediaName: media[currentIndex].name, nbMedia: media.length, currentIndex }),
24
+ /* @__PURE__ */ jsx(Flex, { className: "media-viewer-inner-overlay", onClick: onClose, children: /* @__PURE__ */ jsxs("div", { className: "media-viewer-inner", onClick: (e) => e.stopPropagation(), children: [
25
+ /* @__PURE__ */ jsx(Carousel, { initialSlide: indexMedia, dots: !1, arrows: !0, draggable: !0, infinite: !1, afterChange: (current) => {
26
+ setCurrentIndex(current);
27
+ }, beforeChange: () => {
28
+ setScale(1);
29
+ }, children: media.map((item, index) => /* @__PURE__ */ jsx("div", { className: "viewer-slide", children: /* @__PURE__ */ jsx(MediaWrapper, { mediaUrl: item.url, mediaType: item.type, mimeType: item.mimeType, scale: index === currentIndex ? scale : 1 }) }, index)) }),
30
+ /* @__PURE__ */ jsx(ToolbarZoom, { zoomIn, zoomOut })
31
+ ] }) })
32
+ ] });
33
+ };
34
+ export {
35
+ MediaViewer as default
36
+ };
@@ -0,0 +1,7 @@
1
+ import { MediaLibraryType } from 'src/modules/multimedia';
2
+ export declare const MediaWrapper: ({ mediaUrl, mediaType, mimeType, scale, }: {
3
+ mediaUrl: string;
4
+ mediaType: MediaLibraryType;
5
+ mimeType?: string;
6
+ scale?: number;
7
+ }) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,72 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import SvgIconTextPage from "../../modules/icons/components/IconTextPage.js";
3
+ import SvgIconLink from "../../modules/icons/components/IconLink.js";
4
+ import SvgIconHeadphone from "../../modules/icons/components/IconHeadphone.js";
5
+ import SvgIconDownload from "../../modules/icons/components/IconDownload.js";
6
+ import SvgIconExternalLink from "../../modules/icons/components/IconExternalLink.js";
7
+ import { useTranslation } from "react-i18next";
8
+ import PdfViewer from "./PdfViewer.js";
9
+ import Flex from "../Flex/Flex.js";
10
+ import Button from "../Button/Button.js";
11
+ import Image from "../Image/Image.js";
12
+ const MediaWrapper = ({
13
+ mediaUrl,
14
+ mediaType,
15
+ mimeType,
16
+ scale
17
+ }) => {
18
+ const {
19
+ t
20
+ } = useTranslation(), imageMediaStyle = {
21
+ flex: "none",
22
+ height: "100%",
23
+ transform: `scale(${scale})`,
24
+ maxHeight: "70vh"
25
+ }, audioStyle = {
26
+ width: "100%",
27
+ maxWidth: "500px"
28
+ }, videoMediaStyle = {
29
+ height: "100%",
30
+ objectFit: "cover",
31
+ transform: `scale(${scale})`
32
+ }, iframeMediaStyle = {
33
+ width: "100%",
34
+ height: "600px",
35
+ maxWidth: "900px",
36
+ transform: `scale(${scale})`
37
+ };
38
+ switch (mediaType) {
39
+ case "image":
40
+ return /* @__PURE__ */ jsx(Image, { className: "rounded-2", src: mediaUrl, alt: mediaType, width: "100%", objectFit: "contain", style: imageMediaStyle });
41
+ case "audio":
42
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", align: "center", style: {
43
+ height: "200px"
44
+ }, children: [
45
+ /* @__PURE__ */ jsx(Flex, { justify: "center", align: "center", className: "bg-gray-300 h-100 w-100 rounded-2 mb-8", style: {
46
+ maxWidth: "500px"
47
+ }, children: /* @__PURE__ */ jsx(SvgIconHeadphone, { width: 40, height: 40, color: "#B0B0B0" }) }),
48
+ /* @__PURE__ */ jsx("audio", { src: mediaUrl, className: "media-audio", controls: !0, style: audioStyle })
49
+ ] });
50
+ case "video":
51
+ return /* @__PURE__ */ jsx(Flex, { justify: "center", align: "center", children: /* @__PURE__ */ jsx("video", { src: mediaUrl, controls: !0, className: "media-video", style: videoMediaStyle }) });
52
+ case "embedder":
53
+ return /* @__PURE__ */ jsx(Flex, { justify: "center", align: "center", children: /* @__PURE__ */ jsx("iframe", { title: "Embedded media content", src: mediaUrl, className: "media-video", style: iframeMediaStyle }) });
54
+ case "hyperlink":
55
+ case "attachment":
56
+ return mimeType && mimeType === "application/pdf" ? /* @__PURE__ */ jsx(PdfViewer, { mediaUrl, scale }) : /* @__PURE__ */ jsxs(Flex, { direction: "column", align: "center", children: [
57
+ /* @__PURE__ */ jsx(Flex, { justify: "center", align: "center", className: "bg-gray-300 w-100 rounded-2 mb-8", style: {
58
+ maxWidth: "500px",
59
+ height: "200px"
60
+ }, children: mediaType === "hyperlink" ? /* @__PURE__ */ jsx(SvgIconLink, { width: 40, height: 40, color: "#B0B0B0" }) : /* @__PURE__ */ jsx(SvgIconTextPage, { width: 40, height: 40, color: "#B0B0B0" }) }),
61
+ /* @__PURE__ */ jsx("a", { className: "w-100 d-flex justify-content-center", href: mediaUrl, download: mediaType !== "hyperlink", target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsx(Button, { className: "w-100", style: {
62
+ height: "40px",
63
+ maxWidth: "500px"
64
+ }, leftIcon: mediaType === "hyperlink" ? /* @__PURE__ */ jsx(SvgIconExternalLink, {}) : /* @__PURE__ */ jsx(SvgIconDownload, {}), color: "tertiary", children: t(mediaType === "hyperlink" ? "mediaWrapper.attachment.open" : "mediaWrapper.attachment.download") }) })
65
+ ] });
66
+ default:
67
+ return null;
68
+ }
69
+ };
70
+ export {
71
+ MediaWrapper
72
+ };
@@ -0,0 +1,4 @@
1
+ export default function PdfViewer({ mediaUrl, scale, }: {
2
+ mediaUrl: string;
3
+ scale?: number;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,26 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useState, useRef } from "react";
3
+ import { Document, Page } from "react-pdf";
4
+ import LoadingScreen from "../LoadingScreen/LoadingScreen.js";
5
+ function PdfViewer({
6
+ mediaUrl,
7
+ scale
8
+ }) {
9
+ const [numPages, setNumPages] = useState(null), pagesRef = useRef([]), onDocumentLoadSuccess = ({
10
+ numPages: numPages2
11
+ }) => {
12
+ setNumPages(numPages2);
13
+ };
14
+ return /* @__PURE__ */ jsx("div", { style: {
15
+ width: `calc(600px * ${scale})`,
16
+ height: "calc(100vh - 52px)",
17
+ overflowY: "auto",
18
+ marginTop: "20px"
19
+ }, children: /* @__PURE__ */ jsx(Document, { file: mediaUrl, onLoadSuccess: onDocumentLoadSuccess, loading: /* @__PURE__ */ jsx(LoadingScreen, {}), children: Array.from(new Array(numPages), (_, index) => /* @__PURE__ */ jsx("div", { ref: (el) => pagesRef.current[index] = el, style: {
20
+ marginBottom: 32,
21
+ transformOrigin: "top center"
22
+ }, children: /* @__PURE__ */ jsx(Page, { className: "pdf-page", pageNumber: index + 1, renderTextLayer: !1, renderAnnotationLayer: !1, width: 600 * (scale ?? 1), loading: /* @__PURE__ */ jsx(LoadingScreen, {}) }) }, index)) }) });
23
+ }
24
+ export {
25
+ PdfViewer as default
26
+ };
@@ -0,0 +1,7 @@
1
+ export default function ToolbarViewer({ onClose, mediaName, mediaUrl, nbMedia, currentIndex, }: {
2
+ onClose: () => void;
3
+ mediaName: string;
4
+ nbMedia?: number;
5
+ mediaUrl?: string;
6
+ currentIndex: number;
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,41 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useEffect } from "react";
3
+ import SvgIconClose from "../../modules/icons/components/IconClose.js";
4
+ import SvgIconDownload from "../../modules/icons/components/IconDownload.js";
5
+ import SvgIconExternalLink from "../../modules/icons/components/IconExternalLink.js";
6
+ import Flex from "../Flex/Flex.js";
7
+ import IconButton from "../Button/IconButton.js";
8
+ import SmartEllipsis from "../SmartEllipsis/SmartEllipsis.js";
9
+ function ToolbarViewer({
10
+ onClose,
11
+ mediaName,
12
+ mediaUrl,
13
+ nbMedia,
14
+ currentIndex
15
+ }) {
16
+ return useEffect(() => {
17
+ const handleKeyDown = (e) => {
18
+ e.key === "Escape" && onClose();
19
+ };
20
+ return window.addEventListener("keydown", handleKeyDown), () => {
21
+ window.removeEventListener("keydown", handleKeyDown);
22
+ };
23
+ }, [onClose]), /* @__PURE__ */ jsxs(Flex, { className: "media-viewer-toolbar p-8", align: "center", children: [
24
+ /* @__PURE__ */ jsxs(Flex, { gap: "8", align: "center", style: {
25
+ minWidth: "50%"
26
+ }, children: [
27
+ /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(SvgIconClose, { color: "#fff" }), onClick: onClose, variant: "ghost" }),
28
+ /* @__PURE__ */ jsx(SmartEllipsis, { text: mediaName })
29
+ ] }),
30
+ /* @__PURE__ */ jsxs(Flex, { gap: "8", align: "center", justify: "between", className: "w-100", children: [
31
+ nbMedia ? /* @__PURE__ */ jsx("p", { children: `${currentIndex + 1}/${nbMedia} ` }) : /* @__PURE__ */ jsx("p", { children: `${currentIndex + 1}` }),
32
+ mediaUrl && /* @__PURE__ */ jsxs(Flex, { className: "ms-8", gap: "8", align: "center", children: [
33
+ /* @__PURE__ */ jsx("a", { href: mediaUrl, download: !0, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(SvgIconDownload, { color: "#fff" }), variant: "ghost" }) }),
34
+ /* @__PURE__ */ jsx("a", { href: mediaUrl, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(SvgIconExternalLink, { color: "#fff" }), variant: "ghost" }) })
35
+ ] })
36
+ ] })
37
+ ] });
38
+ }
39
+ export {
40
+ ToolbarViewer as default
41
+ };
@@ -0,0 +1,4 @@
1
+ export default function ToolbarZoom({ zoomIn, zoomOut, }: {
2
+ zoomIn: () => void;
3
+ zoomOut: () => void;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import SvgIconMinus from "../../modules/icons/components/IconMinus.js";
3
+ import SvgIconPlus from "../../modules/icons/components/IconPlus.js";
4
+ import SvgIconZoomIn from "../../modules/icons/components/IconZoomIn.js";
5
+ import Flex from "../Flex/Flex.js";
6
+ import IconButton from "../Button/IconButton.js";
7
+ function ToolbarZoom({
8
+ zoomIn,
9
+ zoomOut
10
+ }) {
11
+ return /* @__PURE__ */ jsx(Flex, { justify: "center", className: "media-viewer-toolbar-zoom-container", children: /* @__PURE__ */ jsxs(Flex, { gap: "4", className: "p-12 media-viewer-toolbar-zoom", align: "center", children: [
12
+ /* @__PURE__ */ jsx(IconButton, { variant: "ghost", icon: /* @__PURE__ */ jsx(SvgIconMinus, { color: "#fff" }), onClick: zoomOut }),
13
+ /* @__PURE__ */ jsx(SvgIconZoomIn, { color: "#fff", className: "m-4" }),
14
+ /* @__PURE__ */ jsx(IconButton, { variant: "ghost", icon: /* @__PURE__ */ jsx(SvgIconPlus, { color: "#fff" }), onClick: zoomIn })
15
+ ] }) });
16
+ }
17
+ export {
18
+ ToolbarZoom as default
19
+ };
@@ -0,0 +1,2 @@
1
+ export * from './MediaViewer';
2
+ export { default as MediaViewer } from './MediaViewer';
@@ -5,6 +5,10 @@ export interface ModalProps {
5
5
  * Modal id (useful when multiple modal on the same page)
6
6
  */
7
7
  id: string;
8
+ /**
9
+ * Modal testid
10
+ */
11
+ ['data-testid']?: string;
8
12
  /**
9
13
  * Is Modal Open
10
14
  */
@@ -10,17 +10,18 @@ import ModalSubtitle from "./ModalSubtitle.js";
10
10
  import useClickOutside from "../../hooks/useClickOutside/useClickOutside.js";
11
11
  import useTrapFocus from "../../hooks/useTrapFocus/useTrapFocus.js";
12
12
  import useKeyPress from "../../hooks/useKeyPress/useKeyPress.js";
13
- const Root = /* @__PURE__ */ forwardRef((props, ref) => {
14
- const {
15
- id,
16
- isOpen,
17
- onModalClose,
18
- size = "md",
19
- viewport = !1,
20
- scrollable = !1,
21
- focusId,
22
- children
23
- } = props, ariaLabelId = `aria_label_${id}`, ariaDescriptionId = `aria_desc_${id}`, modalRef = useClickOutside(onModalClose), trapRef = useTrapFocus(isOpen);
13
+ const Root = /* @__PURE__ */ forwardRef(({
14
+ id,
15
+ isOpen,
16
+ onModalClose,
17
+ size = "md",
18
+ viewport = !1,
19
+ scrollable = !1,
20
+ focusId,
21
+ children,
22
+ ...otherDivProps
23
+ }, ref) => {
24
+ const ariaLabelId = `aria_label_${id}`, ariaDescriptionId = `aria_desc_${id}`, modalRef = useClickOutside(onModalClose), trapRef = useTrapFocus(isOpen);
24
25
  useKeyPress(onModalClose, ["Escape"]), useEffect(() => {
25
26
  if (isOpen && (document.body.style.overflow = "hidden", focusId)) {
26
27
  const elem = document.getElementById(focusId);
@@ -54,7 +55,7 @@ const Root = /* @__PURE__ */ forwardRef((props, ref) => {
54
55
  }
55
56
  });
56
57
  return /* @__PURE__ */ jsx(ModalContext.Provider, { value: modalContextValue, children: transition((style, isOpen2) => /* @__PURE__ */ jsxs(Fragment, { children: [
57
- isOpen2 && /* @__PURE__ */ jsx(animated.div, { id, ref, role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelId, "aria-describedby": ariaDescriptionId, className: modalClasses, style, tabIndex: -1, children: /* @__PURE__ */ jsx("div", { id: `${id}_ref`, ref: (node) => {
58
+ isOpen2 && /* @__PURE__ */ jsx(animated.div, { id, ref, role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelId, "aria-describedby": ariaDescriptionId, className: modalClasses, style, tabIndex: -1, ...otherDivProps, children: /* @__PURE__ */ jsx("div", { id: `${id}_ref`, ref: (node) => {
58
59
  modalRef.current = node, isOpen2 && (trapRef.current = node);
59
60
  }, className: dialogClasses, children: /* @__PURE__ */ jsx("div", { className: "modal-content", children }) }) }),
60
61
  isOpen2 && /* @__PURE__ */ jsx(animated.div, { className: "modal-backdrop fade show", style: {
@@ -0,0 +1,74 @@
1
+ export interface PromotionCardProps {
2
+ children: React.ReactNode;
3
+ borderColor?: string;
4
+ backgroundColor?: string;
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Promotion Card component to display promotional features in a card format.
9
+ *
10
+ * The component PromotionCard is a Compound Component composed of:
11
+ * - PromotionCardHeader: information on the top right corner
12
+ * - PromotionCardIcon: Icon on the left side (background color and Icon)
13
+ * - PromotionCardBody:
14
+ * - PromotionCardTitle: Card Title
15
+ * - PromotionCardDescription: Card Description
16
+ * - PromotionCardAction: Card Action (mainly a button with a onClick action)
17
+ *
18
+ * @example
19
+ * <PromotionCard>
20
+ * <PromotionCard.Header backgroundColor="#faea9c">
21
+ * header content
22
+ * </PromotionCard.Header>
23
+ * <PromotionCard.Icon
24
+ * backgroundColor="#FFEFE3"
25
+ * icon={<IconEdit color="#FF8D2E" />}
26
+ * />
27
+ * <PromotionCard.Body>
28
+ * <PromotionCard.Title>Création Libre</PromotionCard.Title>
29
+ * <PromotionCard.Description>
30
+ * Vous n'avez pas peur de la "page blanche" ? Lancez-vous pour créer
31
+ * votre cours ou votre document !
32
+ * </PromotionCard.Description>
33
+ * <PromotionCard.Actions>
34
+ * <Button
35
+ * color="tertiary"
36
+ * variant="ghost"
37
+ * size="sm"
38
+ * onClick={() => {}}
39
+ * leftIcon={<IconPlus />}
40
+ * >
41
+ * Nouvelle page
42
+ * </Button>
43
+ * </PromotionCard.Actions>
44
+ * </PromotionCard.Body>
45
+ * </PromotionCard>
46
+ */
47
+ export declare const Root: ({ children, borderColor, backgroundColor, className, }: PromotionCardProps) => import("react/jsx-runtime").JSX.Element;
48
+ declare const PromotionCard: (({ children, borderColor, backgroundColor, className, }: PromotionCardProps) => import("react/jsx-runtime").JSX.Element) & {
49
+ Header: {
50
+ ({ backgroundColor, textColor, children, className, }: import('./PromotionCardHeader').PromotionCardHeaderProps): import("react/jsx-runtime").JSX.Element;
51
+ displayName: string;
52
+ };
53
+ Body: {
54
+ ({ children, textColor, className, }: import('./PromotionCardBody').PromotionCardBodyProps): import("react/jsx-runtime").JSX.Element;
55
+ displayName: string;
56
+ };
57
+ Icon: {
58
+ ({ icon, backgroundColor, className, }: import('./PromotionCardIcon').PromotionCardIconProps): import("react/jsx-runtime").JSX.Element;
59
+ displayName: string;
60
+ };
61
+ Title: {
62
+ ({ children, className, }: import('./PromotionCardTitle').PromotionCardTitleProps): import("react/jsx-runtime").JSX.Element;
63
+ displayName: string;
64
+ };
65
+ Description: {
66
+ ({ children, className, }: import('./PromotionCardDescription').PromotionCardDescriptionProps): import("react/jsx-runtime").JSX.Element;
67
+ displayName: string;
68
+ };
69
+ Footer: {
70
+ ({ children, className, }: import('./PromotionCardFooter').PromotionCardFooterProps): import("react/jsx-runtime").JSX.Element;
71
+ displayName: string;
72
+ };
73
+ };
74
+ export default PromotionCard;
@@ -0,0 +1,31 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import PromotionCardBody from "./PromotionCardBody.js";
3
+ import PromotionCardDescription from "./PromotionCardDescription.js";
4
+ import PromotionCardFooter from "./PromotionCardFooter.js";
5
+ import PromotionCardHeader from "./PromotionCardHeader.js";
6
+ import PromotionCardIcon from "./PromotionCardIcon.js";
7
+ import PromotionCardTitle from "./PromotionCardTitle.js";
8
+ import clsx from "clsx";
9
+ const Root = ({
10
+ children,
11
+ borderColor,
12
+ backgroundColor,
13
+ className
14
+ }) => {
15
+ const classNames = clsx("promotion-card", className);
16
+ return /* @__PURE__ */ jsx("div", { className: classNames, style: {
17
+ borderColor,
18
+ backgroundColor
19
+ }, children });
20
+ }, PromotionCard = /* @__PURE__ */ Object.assign(Root, {
21
+ Header: PromotionCardHeader,
22
+ Body: PromotionCardBody,
23
+ Icon: PromotionCardIcon,
24
+ Title: PromotionCardTitle,
25
+ Description: PromotionCardDescription,
26
+ Footer: PromotionCardFooter
27
+ });
28
+ export {
29
+ Root,
30
+ PromotionCard as default
31
+ };