@planningcenter/topbar 11.0.1 → 11.0.3-rc.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.
@@ -1,6 +1,6 @@
1
1
  import { Link } from '@planningcenter/tapestry';
2
2
  import * as React from 'react';
3
- import React__default, { useState, useEffect, useMemo, useCallback, useRef } from 'react';
3
+ import React__default, { useState, useEffect, useMemo, useLayoutEffect, useCallback, useRef } from 'react';
4
4
  import pcoUrl from '@planningcenter/url';
5
5
  import * as general from '@planningcenter/icons/paths/general';
6
6
  import Jolt from '@planningcenter/jolt-client';
@@ -345,7 +345,7 @@ const X = ({
345
345
  fill: fill
346
346
  })));
347
347
 
348
- var styles$b = {"announcement":"announcement-pI5tM","announcement--platform":"announcement--platform-EcUn2","announcement-icon":"announcement-icon-Ov39-","announcement-content":"announcement-content-q2ad6","dismiss":"dismiss-wUAoU"};
348
+ var styles$b = {"announcement":"announcement-pI5tM","announcement--platform":"announcement--platform-EcUn2","announcement--promo":"announcement--promo-FarUk","announcement-icon":"announcement-icon-Ov39-","announcement-content":"announcement-content-q2ad6","dismiss":"dismiss-wUAoU","dismiss--promo":"dismiss--promo-7zvO4"};
349
349
 
350
350
  function AnnouncementIcon() {
351
351
  return /*#__PURE__*/React__default.createElement("svg", {
@@ -413,11 +413,14 @@ let StyledAnnouncement$1 = class StyledAnnouncement extends React__default.Compo
413
413
  render() {
414
414
  const {
415
415
  style,
416
+ variant,
416
417
  ...platformProps
417
418
  } = this.props;
419
+ const isPromo = variant === "promo";
418
420
  return /*#__PURE__*/React__default.createElement("div", {
419
- className: classnames(styles$b["announcement"], styles$b["announcement--platform"])
420
- }, /*#__PURE__*/React__default.createElement(AnnouncementIcon, null), /*#__PURE__*/React__default.createElement("div", {
421
+ className: classnames(styles$b["announcement"], styles$b[`announcement--${variant !== null && variant !== void 0 ? variant : "platform"}`]),
422
+ "data-announcement-variant": variant !== null && variant !== void 0 ? variant : "platform"
423
+ }, !isPromo && /*#__PURE__*/React__default.createElement(AnnouncementIcon, null), /*#__PURE__*/React__default.createElement("div", {
421
424
  className: styles$b["announcement-content"],
422
425
  style: style,
423
426
  ...platformProps
@@ -440,10 +443,12 @@ class PlatformAnnouncements extends React__default.Component {
440
443
  env: this.props.env,
441
444
  initialAnnouncements: this.props.data,
442
445
  configuredFetch: this.props.configuredFetch
443
- }, (data, actions) => Boolean(data.announcements.length > 0) ? (/*#__PURE__*/React__default.createElement("div", null, data.announcements.map(announcement => this.props.renderItem({
444
- actions,
445
- announcement
446
- })))) : null));
446
+ }, (data, actions) => {
447
+ return data.announcements.length > 0 ? (/*#__PURE__*/React__default.createElement("div", null, data.announcements.map(announcement => this.props.renderItem({
448
+ actions,
449
+ announcement
450
+ })))) : null;
451
+ }));
447
452
  }
448
453
  }
449
454
  PlatformAnnouncements.defaultProps = {
@@ -451,33 +456,39 @@ PlatformAnnouncements.defaultProps = {
451
456
  renderItem: ({
452
457
  announcement,
453
458
  actions
454
- }) => (/*#__PURE__*/React__default.createElement(DissmissibleAnnouncement, {
459
+ }) => (/*#__PURE__*/React__default.createElement(DismissibleAnnouncement, {
455
460
  key: announcement.id,
456
461
  html: announcement.data.html,
462
+ variant: announcement.data.style,
457
463
  onClick: () => actions.dismissAnnouncements(announcement.id)
458
464
  }))
459
465
  };
460
466
  function StyledDismissButton$1({
467
+ variant,
461
468
  ...props
462
469
  }) {
470
+ const isPromo = variant === "promo";
463
471
  return /*#__PURE__*/React__default.createElement("button", {
464
472
  type: "button",
465
- className: styles$b.dismiss,
473
+ className: classnames(styles$b.dismiss, isPromo && styles$b["dismiss--promo"]),
466
474
  ...props
467
475
  }, /*#__PURE__*/React__default.createElement(X, {
468
- fill: "white",
476
+ fill: isPromo ? "currentColor" : "white",
469
477
  style: {
470
478
  height: 20,
471
479
  width: 20
472
480
  }
473
481
  }));
474
482
  }
475
- function DissmissibleAnnouncement(props) {
476
- return /*#__PURE__*/React__default.createElement(StyledAnnouncement$1, null, /*#__PURE__*/React__default.createElement("span", {
483
+ function DismissibleAnnouncement(props) {
484
+ return /*#__PURE__*/React__default.createElement(StyledAnnouncement$1, {
485
+ variant: props.variant
486
+ }, /*#__PURE__*/React__default.createElement("span", {
477
487
  dangerouslySetInnerHTML: {
478
488
  __html: props.html
479
489
  }
480
490
  }), /*#__PURE__*/React__default.createElement(StyledDismissButton$1, {
491
+ variant: props.variant,
481
492
  onClick: props.onClick
482
493
  }));
483
494
  }
@@ -674,7 +685,47 @@ const useJoltEffect = (channelSubscription, eventName, callback) => {
674
685
  }, [channelSubscription, callback]);
675
686
  };
676
687
 
688
+ function useMediaQuery(query) {
689
+ const getMatches = query => {
690
+ // Prevents SSR issues
691
+ if (typeof window !== "undefined") {
692
+ return window.matchMedia(query).matches;
693
+ }
694
+ return false;
695
+ };
696
+ const [matches, setMatches] = useState(getMatches(query));
697
+ function handleChange() {
698
+ setMatches(getMatches(query));
699
+ }
700
+ useEffect(() => {
701
+ const matchMedia = window.matchMedia(query);
702
+ // Triggered at the first client-side load and if query changes
703
+ handleChange();
704
+ // Listen matchMedia
705
+ if (matchMedia.addListener) {
706
+ matchMedia.addListener(handleChange);
707
+ } else {
708
+ matchMedia.addEventListener("change", handleChange);
709
+ }
710
+ return () => {
711
+ if (matchMedia.removeListener) {
712
+ matchMedia.removeListener(handleChange);
713
+ } else {
714
+ matchMedia.removeEventListener("change", handleChange);
715
+ }
716
+ };
717
+ }, [query]);
718
+ return matches;
719
+ }
720
+
677
721
  const capitalize = s => s.charAt(0).toUpperCase() + s.slice(1);
722
+ const RESOLVED_COLOR_MODE_ATTRIBUTE = "data-resolved-color-mode";
723
+ function resolveColorMode(colorMode) {
724
+ if (colorMode === "system") {
725
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
726
+ }
727
+ return colorMode;
728
+ }
678
729
  const debounce = (func, wait) => {
679
730
  let timeout;
680
731
  return function (...args) {
@@ -755,6 +806,25 @@ const useNotificationsHasUnread = ({
755
806
  return storedValue;
756
807
  };
757
808
 
809
+ function createStore(initialState) {
810
+ let currentState = initialState;
811
+ const listeners = new Set();
812
+ return {
813
+ getState: () => currentState,
814
+ setState: newState => {
815
+ currentState = newState;
816
+ listeners.forEach(listener => listener(currentState));
817
+ },
818
+ subscribe: listener => {
819
+ listeners.add(listener);
820
+ return () => listeners.delete(listener);
821
+ }
822
+ };
823
+ }
824
+ const store$1 = createStore({});
825
+
826
+ const useStore = (selector = state => state) => useSyncExternalStore(store$1.subscribe, () => selector(store$1.getState()));
827
+
758
828
  const useTopbarAPI = ({
759
829
  configuredFetch,
760
830
  env
@@ -781,23 +851,6 @@ const useTopbarAPI = ({
781
851
  return resp;
782
852
  };
783
853
 
784
- function createStore(initialState) {
785
- let currentState = initialState;
786
- const listeners = new Set();
787
- return {
788
- getState: () => currentState,
789
- setState: newState => {
790
- currentState = newState;
791
- listeners.forEach(listener => listener(currentState));
792
- },
793
- subscribe: listener => {
794
- listeners.add(listener);
795
- return () => listeners.delete(listener);
796
- }
797
- };
798
- }
799
- const store$1 = createStore({});
800
-
801
854
  const AppsProvider = ({
802
855
  configuredFetch = defaultFetch,
803
856
  enableJoltLogging,
@@ -817,6 +870,10 @@ const AppsProvider = ({
817
870
  const hasConnectedPeople = (_b = (_a = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _a === void 0 ? void 0 : _a.attributes) === null || _b === void 0 ? void 0 : _b.has_connected_people;
818
871
  const mfaConfigured = !!((_d = (_c = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _c === void 0 ? void 0 : _c.attributes) === null || _d === void 0 ? void 0 : _d.mfa_configured);
819
872
  const colorMode = (_f = (_e = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _e === void 0 ? void 0 : _e.attributes) === null || _f === void 0 ? void 0 : _f.color_mode;
873
+ const {
874
+ colorMode: currentColorMode
875
+ } = useStore();
876
+ const prefersDark = useMediaQuery("(prefers-color-scheme: dark)");
820
877
  const name = (_h = (_g = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _g === void 0 ? void 0 : _g.attributes) === null || _h === void 0 ? void 0 : _h.name;
821
878
  const notificationsEnabled = !window.notificationsDisabled;
822
879
  const organizationTimeZone = ((_k = (_j = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _j === void 0 ? void 0 : _j.attributes) === null || _k === void 0 ? void 0 : _k.org_time_zone) || "America/Los_Angeles";
@@ -868,6 +925,16 @@ const AppsProvider = ({
868
925
  enabled: true,
869
926
  joltChannel: notificationsJoltChannel
870
927
  });
928
+ useLayoutEffect(() => {
929
+ if (colorMode) {
930
+ document.documentElement.setAttribute(RESOLVED_COLOR_MODE_ATTRIBUTE, resolveColorMode(colorMode));
931
+ }
932
+ }, [colorMode]);
933
+ useEffect(() => {
934
+ if (currentColorMode === "system") {
935
+ document.documentElement.setAttribute(RESOLVED_COLOR_MODE_ATTRIBUTE, prefersDark ? "dark" : "light");
936
+ }
937
+ }, [currentColorMode, prefersDark]);
871
938
  useEffect(() => {
872
939
  const state = store$1.getState();
873
940
  store$1.setState({
@@ -2036,8 +2103,6 @@ const useSetCurrentRouteInfo = ({
2036
2103
  }, [routes, app]);
2037
2104
  };
2038
2105
 
2039
- const useStore = (selector = state => state) => useSyncExternalStore(store$1.subscribe, () => selector(store$1.getState()));
2040
-
2041
2106
  const useUpdateStore = () => useCallback(updates => {
2042
2107
  const currentState = store$1.getState();
2043
2108
  store$1.setState({
@@ -2403,7 +2468,7 @@ function AccountSettingsLink({
2403
2468
  width: 24,
2404
2469
  xmlns: "http://www.w3.org/2000/svg"
2405
2470
  }, /*#__PURE__*/React__default.createElement(Accounts$1, {
2406
- color: "var(--t-icon-color-secondary",
2471
+ color: "var(--t-icon-color-secondary)",
2407
2472
  key: "key2"
2408
2473
  })), /*#__PURE__*/React__default.createElement("span", null, "Account settings"));
2409
2474
  }
@@ -2651,8 +2716,8 @@ function useFragmentKey(key) {
2651
2716
  function onHashChange() {
2652
2717
  updateFragment(location.hash);
2653
2718
  }
2654
- window.addEventListener('hashchange', onHashChange);
2655
- return () => window.removeEventListener('hashchange', onHashChange);
2719
+ window.addEventListener("hashchange", onHashChange);
2720
+ return () => window.removeEventListener("hashchange", onHashChange);
2656
2721
  }, [updateFragment]);
2657
2722
  return [value, updateFragment];
2658
2723
  }
@@ -2666,9 +2731,9 @@ function useFragmentRouting() {
2666
2731
  }, [updateFragment]);
2667
2732
  const route = useMemo(() => {
2668
2733
  if (toolbarFragment) {
2669
- const [tool, ...rest] = toolbarFragment.split('/');
2734
+ const [tool, ...rest] = toolbarFragment.split("/");
2670
2735
  return {
2671
- path: rest.join('/'),
2736
+ path: rest.join("/"),
2672
2737
  tool
2673
2738
  };
2674
2739
  } else {
@@ -2945,6 +3010,7 @@ function ColorModeSwitcher() {
2945
3010
  colorMode
2946
3011
  });
2947
3012
  document.documentElement.setAttribute("data-color-mode", colorMode);
3013
+ document.documentElement.setAttribute(RESOLVED_COLOR_MODE_ATTRIBUTE, resolveColorMode(colorMode));
2948
3014
  updateColorMode(colorMode);
2949
3015
  }
2950
3016
  }), /*#__PURE__*/React__default.createElement(ColorModeIcon, {
@@ -4201,11 +4267,11 @@ function useStableIframeSrcAttributeAndSyncFragmentRoute({
4201
4267
  return iframeSrc;
4202
4268
  }
4203
4269
  function encodeQueryString(path) {
4204
- const [pathPart, queryPart] = path.split('?', 2);
4270
+ const [pathPart, queryPart] = path.split("?", 2);
4205
4271
  return queryPart ? `${pathPart}?${encodeURIComponent(queryPart)}` : pathPart;
4206
4272
  }
4207
4273
  function decodeQueryString(path) {
4208
- const [pathPart, queryPart] = path.split('?', 2);
4274
+ const [pathPart, queryPart] = path.split("?", 2);
4209
4275
  return queryPart ? `${pathPart}?${decodeURIComponent(queryPart)}` : pathPart;
4210
4276
  }
4211
4277
 
@@ -4379,7 +4445,7 @@ function Toolbar({
4379
4445
  document.body.style.overflow = "hidden";
4380
4446
  window.scrollTo(0, 0);
4381
4447
  } else {
4382
- document.body.style.overflow = "auto";
4448
+ document.body.style.overflow = "";
4383
4449
  }
4384
4450
  }, [open]);
4385
4451
  // Listen for external close requests from store