@kodiak-finance/orderly-ui-notification 2.8.20 → 2.8.21-alpha.0

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.
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { FC } from 'react';
1
+ import React, { FC } from 'react';
2
2
  import { API, AnnouncementType, RouterAdapter } from '@kodiak-finance/orderly-types';
3
3
 
4
4
  declare const AnnouncementCenterUI: FC<{
@@ -42,4 +42,15 @@ declare const useAnnouncement: (options?: AnnouncementOptions) => {
42
42
  showAnnouncement: boolean;
43
43
  };
44
44
 
45
- export { AnnouncementCenterPage, AnnouncementCenterUI, AnnouncementItem, NotificationUI, useAnnouncement };
45
+ type AnnouncementBannerProps = {
46
+ dataSource: API.AnnouncementRow[];
47
+ maintenanceDialogInfo?: string;
48
+ showAnnouncement: boolean;
49
+ onClose: () => void;
50
+ onItemClick?: (url: string) => void;
51
+ className?: string;
52
+ style?: React.CSSProperties;
53
+ };
54
+ declare const AnnouncementBannerUI: React.FC<Readonly<AnnouncementBannerProps>>;
55
+
56
+ export { AnnouncementBannerUI, AnnouncementCenterPage, AnnouncementCenterUI, AnnouncementItem, NotificationUI, useAnnouncement };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { FC } from 'react';
1
+ import React, { FC } from 'react';
2
2
  import { API, AnnouncementType, RouterAdapter } from '@kodiak-finance/orderly-types';
3
3
 
4
4
  declare const AnnouncementCenterUI: FC<{
@@ -42,4 +42,15 @@ declare const useAnnouncement: (options?: AnnouncementOptions) => {
42
42
  showAnnouncement: boolean;
43
43
  };
44
44
 
45
- export { AnnouncementCenterPage, AnnouncementCenterUI, AnnouncementItem, NotificationUI, useAnnouncement };
45
+ type AnnouncementBannerProps = {
46
+ dataSource: API.AnnouncementRow[];
47
+ maintenanceDialogInfo?: string;
48
+ showAnnouncement: boolean;
49
+ onClose: () => void;
50
+ onItemClick?: (url: string) => void;
51
+ className?: string;
52
+ style?: React.CSSProperties;
53
+ };
54
+ declare const AnnouncementBannerUI: React.FC<Readonly<AnnouncementBannerProps>>;
55
+
56
+ export { AnnouncementBannerUI, AnnouncementCenterPage, AnnouncementCenterUI, AnnouncementItem, NotificationUI, useAnnouncement };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var react = require('react');
3
+ var React2 = require('react');
4
4
  var orderlyI18n = require('@kodiak-finance/orderly-i18n');
5
5
  var orderlyUi = require('@kodiak-finance/orderly-ui');
6
6
  var orderlyTypes = require('@kodiak-finance/orderly-types');
@@ -11,6 +11,10 @@ var immer = require('immer');
11
11
  var orderlyHooks = require('@kodiak-finance/orderly-hooks');
12
12
  var orderlyReactApp = require('@kodiak-finance/orderly-react-app');
13
13
 
14
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
+
16
+ var React2__default = /*#__PURE__*/_interopDefault(React2);
17
+
14
18
  // src/components/announcementCenter/announcementCenter.ui.tsx
15
19
  var BattleIcon = (props) => {
16
20
  return /* @__PURE__ */ jsxRuntime.jsxs(orderlyUi.Icon, { size: 18, viewBox: "0 0 18 18", ...props, children: [
@@ -118,7 +122,7 @@ var SecurityIcon = (props) => {
118
122
  };
119
123
  var AnnouncementItem = (props) => {
120
124
  const { t } = orderlyI18n.useTranslation();
121
- const Icon2 = react.useMemo(() => {
125
+ const Icon2 = React2.useMemo(() => {
122
126
  switch (props.type) {
123
127
  case orderlyTypes.AnnouncementType.Campaign:
124
128
  return CampaignIcon;
@@ -131,7 +135,7 @@ var AnnouncementItem = (props) => {
131
135
  return AnnouncementIcon;
132
136
  }
133
137
  }, [props.type]);
134
- const title = react.useMemo(() => {
138
+ const title = React2.useMemo(() => {
135
139
  switch (props.type) {
136
140
  case orderlyTypes.AnnouncementType.Campaign:
137
141
  return t("notification.campaign");
@@ -153,7 +157,7 @@ var AnnouncementItem = (props) => {
153
157
  return false;
154
158
  }
155
159
  };
156
- const action = react.useMemo(() => {
160
+ const action = React2.useMemo(() => {
157
161
  if (props.type === orderlyTypes.AnnouncementType.Campaign && typeof props.url === "string" && props.url !== "" && typeof props.onItemClick === "function") {
158
162
  return /* @__PURE__ */ jsxRuntime.jsxs(
159
163
  orderlyUi.Flex,
@@ -188,7 +192,7 @@ var AnnouncementItem = (props) => {
188
192
  }
189
193
  return null;
190
194
  }, [props.type, props.url, t]);
191
- const updateTime = react.useMemo(() => {
195
+ const updateTime = React2.useMemo(() => {
192
196
  if (props.type === orderlyTypes.AnnouncementType.Maintenance) {
193
197
  return /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "2xs", intensity: 36, children: t("notification.recentlyUpdated") });
194
198
  }
@@ -292,7 +296,7 @@ var AnnouncementContent = (props) => {
292
296
  };
293
297
  var AnnouncementCenterUI = (props) => {
294
298
  const { t } = orderlyI18n.useTranslation();
295
- const [expanded, setExpanded] = react.useState(null);
299
+ const [expanded, setExpanded] = React2.useState(null);
296
300
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
297
301
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-px-5 oui-pt-4", children: /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { intensity: 80, weight: "bold", children: t("notification.title") }) }),
298
302
  /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.ScrollArea, { className: "oui-flex oui-h-[300px] oui-flex-col oui-space-y-1 oui-p-3", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -343,7 +347,7 @@ var CampaignContentCard = ({ message, coverImage, url, onItemClick }) => {
343
347
  };
344
348
  var MaintenanceContentCard = ({ message, startTime, endTime }) => {
345
349
  const { t } = orderlyI18n.useTranslation();
346
- const formattedMessage = react.useMemo(() => {
350
+ const formattedMessage = React2.useMemo(() => {
347
351
  const hours = dateFns.differenceInHours(endTime, startTime);
348
352
  const minutes = dateFns.differenceInMinutes(endTime, startTime) - hours * 60;
349
353
  const startUtc = new utc.UTCDate(startTime);
@@ -403,7 +407,7 @@ var NotificationHeader = (props) => {
403
407
  const { t } = orderlyI18n.useTranslation();
404
408
  const { expanded } = props;
405
409
  const { type } = props.dataSource[props.current];
406
- const title = react.useMemo(() => {
410
+ const title = React2.useMemo(() => {
407
411
  switch (type) {
408
412
  case orderlyTypes.AnnouncementType.Campaign:
409
413
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -424,7 +428,7 @@ var NotificationHeader = (props) => {
424
428
  return /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "sm", color: "inherit", children: t("notification.generalTitle") });
425
429
  }
426
430
  }, [type, t]);
427
- const icon = react.useMemo(() => {
431
+ const icon = React2.useMemo(() => {
428
432
  switch (type) {
429
433
  case orderlyTypes.AnnouncementType.Campaign:
430
434
  return /* @__PURE__ */ jsxRuntime.jsx(BattleIcon, { color: "white" });
@@ -496,7 +500,7 @@ var NotificationFooter = (props) => {
496
500
  );
497
501
  };
498
502
  var NotificationContent = (props) => {
499
- const elements = react.useMemo(() => {
503
+ const elements = React2.useMemo(() => {
500
504
  return props.dataSource.map((message) => {
501
505
  const { type } = message;
502
506
  switch (type) {
@@ -542,9 +546,9 @@ var NotificationContent = (props) => {
542
546
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: elements[props.current] });
543
547
  };
544
548
  var NotificationUI = (props) => {
545
- const [expanded, setExpanded] = react.useState(true);
546
- const [current, setCurrent] = react.useState(0);
547
- const len = react.useMemo(() => props.dataSource?.length ?? 0, [props.dataSource]);
549
+ const [expanded, setExpanded] = React2.useState(true);
550
+ const [current, setCurrent] = React2.useState(0);
551
+ const len = React2.useMemo(() => props.dataSource?.length ?? 0, [props.dataSource]);
548
552
  if (len === 0) {
549
553
  return null;
550
554
  }
@@ -626,8 +630,8 @@ var useAnnouncementData = () => {
626
630
  ORDERLY_ANNOUNCEMENT_KEY,
627
631
  {}
628
632
  );
629
- const [tips, setTips] = react.useState({});
630
- const [maintenanceDialogInfo, setMaintenanceDialogInfo] = react.useState();
633
+ const [tips, setTips] = React2.useState({});
634
+ const [maintenanceDialogInfo, setMaintenanceDialogInfo] = React2.useState();
631
635
  const { startTime, endTime, status, brokerName } = orderlyHooks.useMaintenanceStatus();
632
636
  const { t } = orderlyI18n.useTranslation();
633
637
  const { data: announcements } = orderlyHooks.useQuery(
@@ -641,7 +645,7 @@ var useAnnouncementData = () => {
641
645
  );
642
646
  const getMaintentTipsContent = (brokerName2, startDate, endDate) => t("maintenance.tips.description", { brokerName: brokerName2, startDate, endDate });
643
647
  const getMaintentDialogContent = (brokerName2, endDate) => t("maintenance.dialog.description", { brokerName: brokerName2, endDate });
644
- react.useEffect(() => {
648
+ React2.useEffect(() => {
645
649
  const unsubscribe = ws.subscribe("announcement", {
646
650
  onMessage(message) {
647
651
  if (message) {
@@ -676,7 +680,7 @@ var useAnnouncementData = () => {
676
680
  unsubscribe?.();
677
681
  };
678
682
  }, [ws]);
679
- react.useEffect(() => {
683
+ React2.useEffect(() => {
680
684
  if (!announcements?.rows) {
681
685
  return;
682
686
  }
@@ -716,7 +720,7 @@ var useAnnouncementData = () => {
716
720
  });
717
721
  }
718
722
  }, [announcements]);
719
- react.useEffect(() => {
723
+ React2.useEffect(() => {
720
724
  const startDate = startTime ? getTimeString(startTime) : "-";
721
725
  const endDate = endTime ? getTimeString(endTime) : "-";
722
726
  if (status === orderlyHooks.MaintenanceStatus.Maintenance) {
@@ -760,7 +764,7 @@ var useAnnouncementData = () => {
760
764
  }
761
765
  }, [startTime, endTime, status, brokerName, t]);
762
766
  const { customAnnouncements } = orderlyReactApp.useAppContext();
763
- const mergedTips = react.useMemo(() => {
767
+ const mergedTips = React2.useMemo(() => {
764
768
  const tipsCopy = { ...tips };
765
769
  if (customAnnouncements && customAnnouncements.length > 0) {
766
770
  tipsCopy.rows = [...customAnnouncements, ...tips.rows || []];
@@ -776,7 +780,7 @@ var useAnnouncement = (options) => {
776
780
  const { showAnnouncement, setShowAnnouncement } = orderlyReactApp.useAppContext();
777
781
  const { dataAdapter } = orderlyHooks.useOrderlyContext();
778
782
  const { tips: mergedTips, maintenanceDialogInfo } = useAnnouncementData();
779
- const memoizedTips = react.useMemo(() => {
783
+ const memoizedTips = React2.useMemo(() => {
780
784
  if (typeof dataAdapter?.announcementList === "function") {
781
785
  return dataAdapter.announcementList(
782
786
  mergedTips?.rows ?? orderlyTypes.EMPTY_LIST
@@ -791,7 +795,7 @@ var useAnnouncement = (options) => {
791
795
  const closeTips = () => {
792
796
  setStore((prev) => ({ ...prev, show: false }));
793
797
  };
794
- react.useEffect(() => {
798
+ React2.useEffect(() => {
795
799
  const len = memoizedTips.length;
796
800
  setShowAnnouncement(
797
801
  Boolean(len) && announcementStore.show && !options?.hideTips
@@ -813,7 +817,7 @@ var useAnnouncement = (options) => {
813
817
  // src/pages/announcementCenter.script.tsx
814
818
  var useAnnouncementCenterScript = () => {
815
819
  const { tips } = useAnnouncement();
816
- const [current, setCurrent] = react.useState(null);
820
+ const [current, setCurrent] = React2.useState(null);
817
821
  return {
818
822
  dataSource: tips,
819
823
  current,
@@ -835,7 +839,7 @@ var AnnouncementCenterUI2 = (props) => {
835
839
  };
836
840
  var AnnouncementCenterWidget = (props) => {
837
841
  const { dataSource, current, setCurrent } = useAnnouncementCenterScript();
838
- const onItemClick = react.useCallback(
842
+ const onItemClick = React2.useCallback(
839
843
  (url) => {
840
844
  if (!url)
841
845
  return;
@@ -868,7 +872,465 @@ var AnnouncementCenterPage = (props) => {
868
872
  }
869
873
  );
870
874
  };
875
+ var useMarqueeOnce = (opts) => {
876
+ const {
877
+ isActive,
878
+ pxPerSec = 60,
879
+ startDelayMs = 500,
880
+ endDelayMs = 500,
881
+ fallbackStayMs = 2500,
882
+ onFinish
883
+ } = opts;
884
+ const containerRef = React2.useRef(null);
885
+ const contentRef = React2.useRef(null);
886
+ const rafRef = React2.useRef(null);
887
+ const stopAll = () => {
888
+ if (rafRef.current) {
889
+ cancelAnimationFrame(rafRef.current);
890
+ }
891
+ rafRef.current = null;
892
+ };
893
+ const timers = React2.useRef([]);
894
+ const clearTimers = () => {
895
+ timers.current?.forEach((id) => {
896
+ if (id) {
897
+ clearTimeout(id);
898
+ }
899
+ });
900
+ timers.current = [];
901
+ };
902
+ const [overflow, setOverflow] = React2.useState(false);
903
+ const [delta, setDelta] = React2.useState(0);
904
+ React2.useLayoutEffect(() => {
905
+ const c = containerRef.current;
906
+ const t = contentRef.current;
907
+ if (!c || !t) {
908
+ return;
909
+ }
910
+ const update = () => {
911
+ const cw = c.clientWidth;
912
+ const tw = t.scrollWidth;
913
+ const need = Math.max(0, tw - cw);
914
+ setOverflow(need > 0);
915
+ setDelta(need);
916
+ };
917
+ update();
918
+ const ro = new ResizeObserver(update);
919
+ ro.observe(c);
920
+ ro.observe(t);
921
+ return () => {
922
+ ro.disconnect();
923
+ };
924
+ }, []);
925
+ React2.useEffect(() => {
926
+ if (!isActive) {
927
+ stopAll();
928
+ clearTimers();
929
+ if (contentRef.current) {
930
+ contentRef.current.style.transform = "translate3d(0, 0, 0)";
931
+ }
932
+ return;
933
+ }
934
+ const run = async () => {
935
+ stopAll();
936
+ clearTimers();
937
+ if (!overflow || delta <= 0) {
938
+ const id = setTimeout(() => {
939
+ onFinish?.();
940
+ }, fallbackStayMs);
941
+ timers.current.push(id);
942
+ return;
943
+ }
944
+ const startId = setTimeout(() => {
945
+ const distance = delta;
946
+ const durationMs = distance / pxPerSec * 1e3;
947
+ const el = contentRef.current;
948
+ if (!el) {
949
+ return;
950
+ }
951
+ let startTs = 0;
952
+ const startX = 0;
953
+ const endX = -distance;
954
+ const step = (ts) => {
955
+ if (!startTs) {
956
+ startTs = ts;
957
+ }
958
+ const progress = Math.min(1, (ts - startTs) / durationMs);
959
+ const x = startX + (endX - startX) * progress;
960
+ el.style.transform = `translate3d(${x}px, 0, 0)`;
961
+ if (progress < 1) {
962
+ rafRef.current = requestAnimationFrame(step);
963
+ } else {
964
+ const endId = setTimeout(() => {
965
+ onFinish?.();
966
+ }, endDelayMs);
967
+ timers.current.push(endId);
968
+ }
969
+ };
970
+ rafRef.current = requestAnimationFrame(step);
971
+ }, startDelayMs);
972
+ timers.current.push(startId);
973
+ };
974
+ run();
975
+ return () => {
976
+ stopAll();
977
+ clearTimers();
978
+ };
979
+ }, [
980
+ isActive,
981
+ overflow,
982
+ delta,
983
+ pxPerSec,
984
+ startDelayMs,
985
+ endDelayMs,
986
+ fallbackStayMs,
987
+ onFinish
988
+ ]);
989
+ return { containerRef, contentRef, overflow, delta };
990
+ };
991
+ var usePrevNextButtons = (emblaApi, onButtonClick) => {
992
+ const [prevBtnDisabled, setPrevBtnDisabled] = React2.useState(true);
993
+ const [nextBtnDisabled, setNextBtnDisabled] = React2.useState(true);
994
+ const onPrevButtonClick = React2.useCallback(() => {
995
+ if (!emblaApi) {
996
+ return;
997
+ }
998
+ emblaApi.scrollPrev();
999
+ }, [emblaApi, onButtonClick]);
1000
+ const onNextButtonClick = React2.useCallback(() => {
1001
+ if (!emblaApi) {
1002
+ return;
1003
+ }
1004
+ emblaApi.scrollNext();
1005
+ }, [emblaApi, onButtonClick]);
1006
+ const onSelect = React2.useCallback((api) => {
1007
+ setPrevBtnDisabled(!api.canScrollPrev());
1008
+ setNextBtnDisabled(!api.canScrollNext());
1009
+ }, []);
1010
+ React2.useEffect(() => {
1011
+ if (!emblaApi) {
1012
+ return;
1013
+ }
1014
+ onSelect(emblaApi);
1015
+ emblaApi.on("reInit", onSelect).on("select", onSelect);
1016
+ return () => {
1017
+ emblaApi.off("reInit", onSelect).off("select", onSelect);
1018
+ };
1019
+ }, [emblaApi, onSelect]);
1020
+ return {
1021
+ prevBtnDisabled,
1022
+ nextBtnDisabled,
1023
+ onPrevButtonClick,
1024
+ onNextButtonClick
1025
+ };
1026
+ };
1027
+ var useSelectedSnapDisplay = (emblaApi) => {
1028
+ const [selectedSnap, setSelectedSnap] = React2.useState(0);
1029
+ const [snapCount, setSnapCount] = React2.useState(0);
1030
+ const updateScrollSnapState = React2.useCallback((api) => {
1031
+ if (api) {
1032
+ setSnapCount(api.scrollSnapList().length);
1033
+ setSelectedSnap(api.selectedScrollSnap());
1034
+ }
1035
+ }, []);
1036
+ React2.useEffect(() => {
1037
+ if (!emblaApi) {
1038
+ return;
1039
+ }
1040
+ updateScrollSnapState(emblaApi);
1041
+ emblaApi.on("select", updateScrollSnapState);
1042
+ emblaApi.on("reInit", updateScrollSnapState);
1043
+ return () => {
1044
+ emblaApi.off("select", updateScrollSnapState);
1045
+ emblaApi.off("reInit", updateScrollSnapState);
1046
+ };
1047
+ }, [emblaApi, updateScrollSnapState]);
1048
+ return {
1049
+ selectedSnap,
1050
+ snapCount
1051
+ };
1052
+ };
1053
+ var TipsType = ({ type }) => {
1054
+ const { t } = orderlyI18n.useTranslation();
1055
+ const { label, className } = React2.useMemo(() => {
1056
+ const map = {
1057
+ [orderlyTypes.AnnouncementType.Listing]: {
1058
+ label: t("announcement.type.listing"),
1059
+ className: "oui-bg-primary/15 oui-text-primary"
1060
+ },
1061
+ [orderlyTypes.AnnouncementType.Maintenance]: {
1062
+ label: t("announcement.type.maintenance"),
1063
+ className: "oui-bg-[rgba(232,136,0,0.15)] oui-text-warning-darken"
1064
+ },
1065
+ [orderlyTypes.AnnouncementType.Delisting]: {
1066
+ label: t("announcement.type.delisting"),
1067
+ className: "oui-bg-[rgba(232,136,0,0.15)] oui-text-warning-darken"
1068
+ }
1069
+ };
1070
+ return map[type] || {
1071
+ label: type,
1072
+ className: map[orderlyTypes.AnnouncementType.Listing].className
1073
+ };
1074
+ }, [type, t]);
1075
+ if (!label) {
1076
+ return null;
1077
+ }
1078
+ return /* @__PURE__ */ jsxRuntime.jsx(
1079
+ orderlyUi.Flex,
1080
+ {
1081
+ justify: "center",
1082
+ px: 2,
1083
+ r: "base",
1084
+ className: orderlyUi.cn(
1085
+ "oui-text-2xs oui-font-medium oui-leading-[18px]",
1086
+ "oui-whitespace-nowrap oui-break-normal",
1087
+ className
1088
+ ),
1089
+ children: label
1090
+ }
1091
+ );
1092
+ };
1093
+ var AnnouncementItem2 = (props) => {
1094
+ const { type, text, url, isActive, onItemFinish, onItemClick } = props;
1095
+ const { containerRef, contentRef, overflow } = useMarqueeOnce({
1096
+ isActive,
1097
+ pxPerSec: 90,
1098
+ startDelayMs: 1e3,
1099
+ endDelayMs: 1e3,
1100
+ fallbackStayMs: 2500,
1101
+ onFinish: onItemFinish
1102
+ });
1103
+ const onClick = () => {
1104
+ if (url) {
1105
+ onItemClick?.(url);
1106
+ }
1107
+ };
1108
+ return /* @__PURE__ */ jsxRuntime.jsx(
1109
+ orderlyUi.Flex,
1110
+ {
1111
+ height: "100%",
1112
+ itemAlign: "center",
1113
+ className: "oui-flex-none oui-basis-full oui-transform-gpu",
1114
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1115
+ "div",
1116
+ {
1117
+ ref: containerRef,
1118
+ className: orderlyUi.cn(
1119
+ "oui-relative oui-flex oui-h-[34px] oui-w-full oui-transform-gpu oui-items-center oui-overflow-hidden",
1120
+ overflow ? "oui-justify-start" : "oui-justify-center"
1121
+ ),
1122
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1123
+ "div",
1124
+ {
1125
+ ref: contentRef,
1126
+ className: orderlyUi.cn(
1127
+ "oui-inline-flex oui-items-center oui-gap-2",
1128
+ "oui-h-[34px] oui-whitespace-nowrap oui-leading-[34px]",
1129
+ "oui-w-fit oui-transform-gpu oui-will-change-transform"
1130
+ ),
1131
+ children: [
1132
+ /* @__PURE__ */ jsxRuntime.jsx(TipsType, { type }),
1133
+ /* @__PURE__ */ jsxRuntime.jsx(
1134
+ orderlyUi.Text,
1135
+ {
1136
+ size: "xs",
1137
+ intensity: 80,
1138
+ className: orderlyUi.cn(
1139
+ "oui-transform-gpu",
1140
+ url ? "oui-cursor-pointer" : void 0
1141
+ ),
1142
+ onClick: url ? onClick : void 0,
1143
+ children: text
1144
+ }
1145
+ )
1146
+ ]
1147
+ }
1148
+ )
1149
+ }
1150
+ )
1151
+ }
1152
+ );
1153
+ };
1154
+ var SoundIcon = React2__default.default.forwardRef((props, ref) => {
1155
+ return /* @__PURE__ */ jsxRuntime.jsx(
1156
+ "svg",
1157
+ {
1158
+ xmlns: "http://www.w3.org/2000/svg",
1159
+ width: 18,
1160
+ height: 18,
1161
+ viewBox: "0 0 18 18",
1162
+ fill: "currentColor",
1163
+ ref,
1164
+ focusable: false,
1165
+ ...props,
1166
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1167
+ "path",
1168
+ {
1169
+ d: "M11.5312 2.25534C11.2703 2.14734 10.9472 2.18333 10.7109 2.41958C10.1862 2.94383 9.52305 3.37884 8.7642 3.70434C7.99343 4.03434 6.411 4.46108 5.25547 4.45358C3.00765 4.43858 1.49993 5.71283 1.5 8.18033C1.5 10.3426 2.72745 11.6003 4.49423 11.8831L4.5 13.4476C4.5 14.6888 5.50733 15.6953 6.75 15.6953C7.89188 15.6953 8.83245 14.8118 8.97765 13.7071C8.98462 13.6538 9 13.4476 9 12.6976C9.67373 13.0118 10.232 13.5091 10.7109 13.9876C11.1834 14.4593 12 14.1166 12 13.4491C12 12.7711 11.9964 11.5433 11.9964 10.3186C12.8805 9.99159 13.5 9.15383 13.5 8.20358C13.5 7.25333 12.9149 6.39385 12.004 6.0751C12.004 4.85035 12 3.63609 12 2.95809C12 2.62434 11.7923 2.36409 11.5312 2.25534ZM13.3359 3.59033C13.1501 3.63833 12.9956 3.7636 12.8906 3.94135C12.6809 4.29835 12.7913 4.76259 13.1484 4.97184C14.2882 5.64084 15 6.85883 15 8.20358C15 9.54908 14.289 10.7663 13.1484 11.4353C12.7912 11.6446 12.6576 12.1081 12.8672 12.4651C13.0768 12.8221 13.5411 12.9323 13.8984 12.7231C15.4934 11.7878 16.4999 10.0861 16.5 8.20358C16.5 6.32183 15.4922 4.61933 13.8984 3.68408C13.7198 3.57908 13.5217 3.54233 13.3359 3.59033ZM10.5035 4.47384C10.5035 5.16759 10.5 5.89059 10.5 6.70509C10.5 8.20359 10.5 8.2036 10.5 9.7021C10.5 10.5166 10.5024 11.2103 10.5024 11.9041C8.98343 11.0078 7.41735 10.6103 6.00157 10.4828C6.00157 9.33909 5.99775 7.07709 5.99775 5.89884C6.14475 5.89209 6.31575 5.87335 6.5625 5.83885C7.52017 5.7016 8.4717 5.45259 9.375 5.06559C9.80505 4.88184 10.1247 4.71534 10.5035 4.47384ZM4.49887 6.02484C4.49887 7.17684 4.49775 9.21234 4.49775 10.3643C3.52177 10.0943 3 9.40508 3 8.18033C3 6.96983 3.47025 6.25209 4.49887 6.02484ZM6 11.9971C6.23745 12.0053 7.0977 12.1583 7.49243 12.2581L7.5 13.4476C7.5 13.8616 7.16423 14.1968 6.75 14.1968C6.33577 14.1968 6 13.8616 6 13.4476V11.9971Z",
1170
+ fill: "#fff",
1171
+ fillOpacity: 0.98
1172
+ }
1173
+ )
1174
+ }
1175
+ );
1176
+ });
1177
+ if (process.env.NODE_ENV !== "production") {
1178
+ SoundIcon.displayName = "SoundIcon";
1179
+ }
1180
+ var SwitchTips = (props) => {
1181
+ const { selectedSnap, snapCount, prevDisabled, nextDisabled, prevTips, nextTips } = props;
1182
+ const { isMobile } = orderlyUi.useScreen();
1183
+ if (isMobile) {
1184
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-live": "polite", className: "oui-text-sm oui-tabular-nums oui-text-base-contrast-54", children: [
1185
+ selectedSnap + 1,
1186
+ "/",
1187
+ snapCount
1188
+ ] });
1189
+ }
1190
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-flex oui-items-center oui-justify-center oui-gap-0 oui-text-base-contrast-54", children: [
1191
+ /* @__PURE__ */ jsxRuntime.jsx(
1192
+ orderlyUi.ChevronLeftIcon,
1193
+ {
1194
+ size: 16,
1195
+ opacity: 1,
1196
+ className: orderlyUi.cn(
1197
+ "oui-size-4 oui-shrink-0 oui-text-base-contrast-54 hover:oui-text-base-contrast-80 lg:oui-size-5",
1198
+ prevDisabled ? "oui-cursor-not-allowed" : "oui-cursor-pointer"
1199
+ ),
1200
+ onClick: prevDisabled ? void 0 : prevTips
1201
+ }
1202
+ ),
1203
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-live": "polite", className: "oui-text-sm oui-tabular-nums oui-text-base-contrast-54", children: [
1204
+ selectedSnap + 1,
1205
+ "/",
1206
+ snapCount
1207
+ ] }),
1208
+ /* @__PURE__ */ jsxRuntime.jsx(
1209
+ orderlyUi.ChevronRightIcon,
1210
+ {
1211
+ size: 16,
1212
+ opacity: 1,
1213
+ className: orderlyUi.cn(
1214
+ "oui-size-4 oui-shrink-0 oui-text-base-contrast-54 hover:oui-text-base-contrast-80 lg:oui-size-5",
1215
+ nextDisabled ? "oui-cursor-not-allowed" : "oui-cursor-pointer"
1216
+ ),
1217
+ onClick: nextDisabled ? void 0 : nextTips
1218
+ }
1219
+ )
1220
+ ] });
1221
+ };
1222
+ var Controls = (props) => {
1223
+ const { selectedSnap, snapCount, prevDisabled, nextDisabled, prevTips, nextTips, closeTips } = props;
1224
+ const { isMobile } = orderlyUi.useScreen();
1225
+ return /* @__PURE__ */ jsxRuntime.jsxs(orderlyUi.Flex, { gap: isMobile ? 1 : 2, justify: "center", itemAlign: "center", children: [
1226
+ /* @__PURE__ */ jsxRuntime.jsx(
1227
+ SwitchTips,
1228
+ {
1229
+ prevDisabled,
1230
+ nextDisabled,
1231
+ selectedSnap,
1232
+ snapCount,
1233
+ prevTips,
1234
+ nextTips
1235
+ }
1236
+ ),
1237
+ /* @__PURE__ */ jsxRuntime.jsx(
1238
+ orderlyUi.CloseIcon,
1239
+ {
1240
+ size: 18,
1241
+ onClick: closeTips,
1242
+ className: "oui-cursor-pointer oui-text-base-contrast-80 hover:oui-text-base-contrast"
1243
+ }
1244
+ )
1245
+ ] });
1246
+ };
1247
+ var AnnouncementBannerUI = (props) => {
1248
+ const { maintenanceDialogInfo, showAnnouncement, dataSource, onClose, style, className } = props;
1249
+ const { t, i18n } = orderlyI18n.useTranslation();
1250
+ const [emblaRef, emblaApi] = orderlyUi.useEmblaCarousel({
1251
+ loop: true,
1252
+ axis: "y",
1253
+ align: "center",
1254
+ duration: 30
1255
+ });
1256
+ const { prevBtnDisabled, nextBtnDisabled, onPrevButtonClick, onNextButtonClick } = usePrevNextButtons(emblaApi);
1257
+ const { selectedSnap, snapCount } = useSelectedSnapDisplay(emblaApi);
1258
+ const goNext = React2.useCallback(() => {
1259
+ if (!emblaApi) {
1260
+ return;
1261
+ }
1262
+ emblaApi.scrollNext();
1263
+ }, [emblaApi]);
1264
+ if (maintenanceDialogInfo) {
1265
+ return /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Dialog, { open: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1266
+ orderlyUi.DialogContent,
1267
+ {
1268
+ closable: false,
1269
+ onOpenAutoFocus: (event) => event.preventDefault(),
1270
+ className: "oui-w-[320px] lg:oui-w-auto",
1271
+ children: [
1272
+ /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.DialogTitle, { children: t("maintenance.dialog.title") }) }),
1273
+ /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.DialogBody, { className: "oui-text-2xs lg:oui-text-xs", children: maintenanceDialogInfo })
1274
+ ]
1275
+ }
1276
+ ) });
1277
+ }
1278
+ if (!showAnnouncement || !dataSource?.length) {
1279
+ return null;
1280
+ }
1281
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1282
+ "div",
1283
+ {
1284
+ style,
1285
+ className: orderlyUi.cn(
1286
+ "oui-relative oui-z-[1] oui-flex oui-transform-gpu oui-flex-row oui-flex-nowrap oui-items-center oui-justify-between oui-gap-x-1.5 oui-overflow-hidden oui-rounded-xl oui-bg-base-9 oui-px-4 oui-font-semibold",
1287
+ className
1288
+ ),
1289
+ children: [
1290
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-size-[18px]", children: /* @__PURE__ */ jsxRuntime.jsx(SoundIcon, {}) }),
1291
+ /* @__PURE__ */ jsxRuntime.jsx(
1292
+ "div",
1293
+ {
1294
+ ref: emblaRef,
1295
+ className: "oui-relative oui-h-[34px] oui-w-full oui-max-w-full oui-transform-gpu oui-overflow-hidden",
1296
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-flex oui-h-full oui-transform-gpu oui-flex-col", children: dataSource.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
1297
+ AnnouncementItem2,
1298
+ {
1299
+ type: item?.type,
1300
+ text: item?.i18n?.[i18n.language] || item?.message?.trim() || "",
1301
+ url: item?.url || void 0,
1302
+ isActive: index === selectedSnap,
1303
+ onItemFinish: goNext,
1304
+ onItemClick: (url) => {
1305
+ if (props.onItemClick) {
1306
+ props.onItemClick(url);
1307
+ } else {
1308
+ window.open(url, "_blank");
1309
+ }
1310
+ }
1311
+ },
1312
+ `item-${item.announcement_id}-${index}`
1313
+ )) })
1314
+ }
1315
+ ),
1316
+ /* @__PURE__ */ jsxRuntime.jsx(
1317
+ Controls,
1318
+ {
1319
+ selectedSnap,
1320
+ snapCount,
1321
+ closeTips: onClose,
1322
+ prevTips: onPrevButtonClick,
1323
+ nextTips: onNextButtonClick,
1324
+ prevDisabled: prevBtnDisabled,
1325
+ nextDisabled: nextBtnDisabled
1326
+ }
1327
+ )
1328
+ ]
1329
+ }
1330
+ );
1331
+ };
871
1332
 
1333
+ exports.AnnouncementBannerUI = AnnouncementBannerUI;
872
1334
  exports.AnnouncementCenterPage = AnnouncementCenterPage;
873
1335
  exports.AnnouncementCenterUI = AnnouncementCenterUI;
874
1336
  exports.AnnouncementItem = AnnouncementItem;