@planningcenter/organization-avatars 1.2.1 → 1.4.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.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),i=require("react"),M=require("react-dom"),O=require("@planningcenter/url"),C=require("@planningcenter/tapestry"),w=require("@planningcenter/icons/paths/general"),B=require("@planningcenter/icons/paths/services"),D=require("react-dropzone");function N(a){var o,r,t="";if(typeof a=="string"||typeof a=="number")t+=a;else if(typeof a=="object")if(Array.isArray(a)){var c=a.length;for(o=0;o<c;o++)a[o]&&(r=N(a[o]))&&(t&&(t+=" "),t+=r)}else for(r in a)a[r]&&(t&&(t+=" "),t+=r);return t}function L(){for(var a,o,r=0,t="",c=arguments.length;r<c;r++)(a=arguments[r])&&(o=N(a))&&(t&&(t+=" "),t+=o);return t}function P(){const a=document.querySelector('meta[name="csrf-token"]');if(!a||!a.content)throw new Error('CSRF token not found. Ensure your Rails application includes <meta name="csrf-token" content="..."> in the document head.');return a.content}const T=a=>a==="dark_mode_avatar"?"dark":"light";function U({avatarUrl:a,organization:o,mode:r,pcoEnv:t,onAvatarUpdate:c}){const[s,m]=i.useState(null),[d,f]=i.useState(a),[l,g]=i.useState(!1),[v,u]=i.useState(""),j=i.useId(),k=i.useRef(null),x=T(r),S=h=>{const[n]=h;n&&m(Object.assign(n,{preview:URL.createObjectURL(n)}))};i.useEffect(()=>{f(a)},[a]),i.useEffect(()=>()=>{s?.preview&&(URL.revokeObjectURL(s.preview),u(""))},[s]);const A=async h=>{const n=await fetch(O.pcoApiUrl("accounts",{env:t}),{method:"PATCH",headers:{"Content-Type":"application/json","X-CSRF-Token":P(),Accept:"application/json"},body:JSON.stringify({data:{attributes:h}})}),p=await n.json();if(!n.ok)throw p;return p},z=async h=>{if(h.preventDefault(),!(!s||l)){g(!0);try{const n=new FileReader,p=await new Promise((b,y)=>{n.onloadend=()=>b(n.result),n.onerror=y,n.readAsDataURL(s)}),_=await A({[r]:p,[`${r}_cache`]:""});f(_.data.attributes[r].url),m(null),c(r,_.data.attributes[r].url),k.current?.close()}catch{u("We were unable to save your avatar.")}finally{g(!1)}}},F=async()=>{if(!l){g(!0);try{await A({[`remove_${r}`]:"1"}),f(""),c(r,""),k.current?.close()}catch{u("We were unable to delete your avatar.")}finally{g(!1)}}},R=()=>{m(null),u("")};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"pco-org-avatar",children:[e.jsx("button",{type:"button",commandfor:j,command:"show-modal",className:`pco-org-avatar__button pco-org-avatar__button--${x}`,children:d?e.jsxs(e.Fragment,{children:[e.jsx("img",{src:d,alt:`Church logo for ${o}`}),e.jsx("span",{children:e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{d:w.pencil})})})]}):e.jsx("svg",{width:"48",height:"48",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{d:B.image})})}),e.jsxs("div",{className:"pco-org-avatar__label",children:[x," mode"]})]}),M.createPortal(e.jsx("dialog",{id:j,ref:k,className:"dialog",onClose:R,children:e.jsxs("form",{onSubmit:z,children:[e.jsxs("div",{className:"dialog__header",children:[e.jsxs("h1",{className:"dialog__title",children:["Church logo — ",x," mode"]}),e.jsx("button",{type:"button",commandfor:j,command:"close",className:"dialog__close","aria-label":"Close modal",children:e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{d:w.smallX})})})]}),e.jsxs("div",{className:"dialog__body",children:[v&&e.jsxs("div",{role:"alert",className:"alert alert--danger mb-2",children:[e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",className:"symbol","aria-hidden":"true",children:e.jsx("path",{d:w.exclamationTriangle})}),e.jsx("div",{className:"alert__content",children:e.jsx("p",{children:v})})]}),e.jsx(D,{accept:{"image/*":[".jpg",".jpeg",".png"]},multiple:!1,onDropAccepted:S,children:({getRootProps:h,getInputProps:n,isFocused:p,isDragAccept:_,isDragReject:b,isDragActive:y})=>{const q=L("pco-org-avatar__dropzone",`pco-org-avatar__dropzone--${x}`,{"pco-org-avatar__dropzone--image":s||d,"pco-org-avatar__dropzone--focused":p,"pco-org-avatar__dropzone--accepted":_,"pco-org-avatar__dropzone--rejected":y&&b});return e.jsxs("div",{...h({className:q}),children:[e.jsx("input",{...n()}),s?e.jsx("img",{src:s.preview,alt:`Church logo for ${o}`}):d?e.jsx("img",{src:d,alt:`Church logo for ${o}`}):e.jsxs(e.Fragment,{children:[e.jsx("svg",{width:"64",height:"64",viewBox:"0 0 16 16","aria-hidden":"true",children:e.jsx("path",{d:w.toCloudArrow})}),y&&b?e.jsxs(e.Fragment,{children:[e.jsx("h2",{children:"Wrong file type"}),e.jsx("p",{children:"Please upload a PNG or JPG file."})]}):e.jsxs(e.Fragment,{children:[e.jsx("h2",{children:"Add church logo"}),e.jsx("p",{children:"Use a high-quality image (up to 20mb) with a transparent background."})]})]})]})}})]}),e.jsxs("div",{className:"dialog__actions",children:[d&&e.jsx(C.Button,{label:"Delete logo",kind:"delete",onClick:F,loading:l,disabled:l,className:"mr-a"}),e.jsx(C.Button,{type:"button",label:"Cancel",commandfor:j,command:"close",disabled:l}),e.jsx(C.Button,{type:"submit",label:"Update logo",kind:"primary",loading:l,disabled:!s||l})]})]})}),document.body)]})}function $({avatarUrl:a,darkModeAvatarUrl:o,orgName:r,pcoEnv:t,showDarkModeAvatar:c=!1}){const[s,m]=i.useState(a),[d,f]=i.useState(o),l=(v,u)=>{v==="avatar"?m(u):v==="dark_mode_avatar"&&f(u)},g=d||s;return e.jsxs("div",{className:"d-f g-1",children:[e.jsx(U,{avatarUrl:s,organization:r,mode:"avatar",pcoEnv:t,onAvatarUpdate:l}),c&&e.jsx(U,{avatarUrl:g,organization:r,mode:"dark_mode_avatar",pcoEnv:t,onAvatarUpdate:l})]})}exports.OrganizationAvatars=$;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),i=require("react"),O=require("react-dom"),B=require("@planningcenter/url"),k=require("@planningcenter/tapestry"),A=require("@planningcenter/icons/paths/general"),P=require("@planningcenter/icons/paths/services"),T=require("react-dropzone");function z(a){var o,t,r="";if(typeof a=="string"||typeof a=="number")r+=a;else if(typeof a=="object")if(Array.isArray(a)){var d=a.length;for(o=0;o<d;o++)a[o]&&(t=z(a[o]))&&(r&&(r+=" "),r+=t)}else for(t in a)a[t]&&(r&&(r+=" "),r+=t);return r}function $(){for(var a,o,t=0,r="",d=arguments.length;t<d;t++)(a=arguments[t])&&(o=z(a))&&(r&&(r+=" "),r+=o);return r}function L(){const a=document.querySelector('meta[name="csrf-token"]');if(!a||!a.content)throw new Error('CSRF token not found. Ensure your Rails application includes <meta name="csrf-token" content="..."> in the document head.');return a.content}function E(a){const o=a.split("");return[o.shift()?.toUpperCase(),o.join("")].join("")}const I=a=>a==="dark_mode_avatar"?"dark":"light";function N({avatarUrl:a,organization:o,mode:t,pcoEnv:r,onAvatarUpdate:d}){const[s,p]=i.useState(null),[u,m]=i.useState(a),[l,f]=i.useState(!1),[c,v]=i.useState(!1),[U,j]=i.useState(""),x=i.useId(),C=i.useRef(null),_=I(t),F=g=>{const[n]=g;n&&p(Object.assign(n,{preview:URL.createObjectURL(n)}))};i.useEffect(()=>{m(a)},[a]),i.useEffect(()=>()=>{s?.preview&&(URL.revokeObjectURL(s.preview),j(""))},[s]);const S=async g=>{const n=await fetch(B.pcoApiUrl("accounts",{env:r}),{method:"PATCH",headers:{"Content-Type":"application/json","X-CSRF-Token":L(),Accept:"application/json"},body:JSON.stringify({data:{attributes:g}})}),h=await n.json();if(!n.ok)throw h;return h},R=async g=>{if(g.preventDefault(),!(!s||l||c)){f(!0);try{const n=new FileReader,h=await new Promise((y,w)=>{n.onloadend=()=>y(n.result),n.onerror=w,n.readAsDataURL(s)}),b=await S({[t]:h,[`${t}_cache`]:""});m(b.data.attributes[t].url),p(null),d(t,b.data.attributes[t].url),C.current?.close()}catch{j("We were unable to save your avatar.")}finally{f(!1)}}},q=async()=>{if(!(l||c)){v(!0);try{await S({[`remove_${t}`]:"1"}),m(""),d(t,""),C.current?.close()}catch{j("We were unable to delete your avatar.")}finally{v(!1)}}},D=()=>{p(null),j("")};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"pco-org-avatar",children:[e.jsx("button",{type:"button",commandfor:x,command:"show-modal",className:`pco-org-avatar__button pco-org-avatar__button--${_}`,children:u?e.jsxs(e.Fragment,{children:[e.jsx("img",{src:u,alt:`Church logo for ${o}`}),e.jsx("div",{className:"tds-btn tds-btn--interaction tds-btn--icononly",children:e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{d:A.pencil})})})]}):e.jsx("svg",{width:"48",height:"48",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{d:P.image})})}),e.jsxs("div",{className:"pco-org-avatar__label",children:[E(_)," mode"]})]}),O.createPortal(e.jsx("dialog",{id:x,ref:C,className:"pco-org-avatar__dialog",onClose:D,children:e.jsxs("form",{onSubmit:R,children:[e.jsxs("div",{className:"pco-org-avatar__dialog-header",children:[e.jsxs("h1",{className:"pco-org-avatar__dialog-title",children:["Church logo — ",_," mode"]}),e.jsx("button",{type:"button",commandfor:x,command:"close",className:"pco-org-avatar__dialog-close","aria-label":"Close modal",children:e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{d:A.smallX})})})]}),e.jsxs("div",{className:"pco-org-avatar__dialog-body",children:[U&&e.jsxs("div",{role:"alert",className:"pco-org-avatar__dialog-alert",children:[e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",className:"symbol","aria-hidden":"true",children:e.jsx("path",{d:A.exclamationTriangle})}),e.jsx("p",{children:U})]}),e.jsx(T,{accept:{"image/*":[".jpg",".jpeg",".png"]},multiple:!1,onDropAccepted:F,children:({getRootProps:g,getInputProps:n,isFocused:h,isDragAccept:b,isDragReject:y,isDragActive:w})=>{const M=$("pco-org-avatar__dialog-dropzone",`pco-org-avatar__dialog-dropzone--${_}`,{"pco-org-avatar__dialog-dropzone--image":s||u,"pco-org-avatar__dialog-dropzone--focused":h,"pco-org-avatar__dialog-dropzone--accepted":b,"pco-org-avatar__dialog-dropzone--rejected":w&&y});return e.jsxs("div",{...g({className:M}),children:[e.jsx("input",{...n()}),s?e.jsx("img",{src:s.preview,alt:`Church logo for ${o}`}):u?e.jsx("img",{src:u,alt:`Church logo for ${o}`}):e.jsxs(e.Fragment,{children:[e.jsx("svg",{width:"64",height:"64",viewBox:"0 0 16 16","aria-hidden":"true",children:e.jsx("path",{d:A.toCloudArrow})}),w&&y?e.jsxs(e.Fragment,{children:[e.jsx("h2",{children:"Wrong file type"}),e.jsx("p",{children:"Please upload a PNG or JPG file."})]}):e.jsxs(e.Fragment,{children:[e.jsx("h2",{children:"Add church logo"}),e.jsx("p",{children:"Use a high-quality image (up to 20mb) with a transparent background."})]})]})]})}})]}),e.jsxs("div",{className:"pco-org-avatar__dialog-actions",children:[u&&e.jsx(k.Button,{label:"Delete logo",kind:"delete",onClick:q,loading:c,disabled:c||l,className:"pco-org-avatar__dialog-delete"}),e.jsx(k.Button,{type:"button",label:"Cancel",commandfor:x,command:"close",disabled:l||c}),e.jsx(k.Button,{type:"submit",label:"Update logo",kind:"primary",loading:l,disabled:!s||l||c})]})]})}),document.body)]})}function W({avatarUrl:a,darkModeAvatarUrl:o,orgName:t,pcoEnv:r,showDarkModeAvatar:d=!1}){const[s,p]=i.useState(a),[u,m]=i.useState(o),l=(c,v)=>{c==="avatar"?p(v):c==="dark_mode_avatar"&&m(v)},f=u||s;return e.jsxs("div",{className:"pco-org-avatars",children:[e.jsx(N,{avatarUrl:s,organization:t,mode:"avatar",pcoEnv:r,onAvatarUpdate:l}),d&&e.jsx(N,{avatarUrl:f,organization:t,mode:"dark_mode_avatar",pcoEnv:r,onAvatarUpdate:l})]})}exports.OrganizationAvatars=W;
package/dist/index.js CHANGED
@@ -1,125 +1,129 @@
1
- import { jsxs as o, Fragment as b, jsx as e } from "react/jsx-runtime";
2
- import { useState as p, useId as S, useRef as $, useEffect as j } from "react";
3
- import { createPortal as B } from "react-dom";
4
- import { pcoApiUrl as P } from "@planningcenter/url";
5
- import { Button as N } from "@planningcenter/tapestry";
6
- import { pencil as T, smallX as E, exclamationTriangle as I, toCloudArrow as W } from "@planningcenter/icons/paths/general";
7
- import { image as q } from "@planningcenter/icons/paths/services";
8
- import G from "react-dropzone";
9
- function R(a) {
10
- var n, r, t = "";
11
- if (typeof a == "string" || typeof a == "number") t += a;
12
- else if (typeof a == "object") if (Array.isArray(a)) {
13
- var d = a.length;
14
- for (n = 0; n < d; n++) a[n] && (r = R(a[n])) && (t && (t += " "), t += r);
15
- } else for (r in a) a[r] && (t && (t += " "), t += r);
1
+ import { jsxs as n, Fragment as _, jsx as a } from "react/jsx-runtime";
2
+ import { useState as u, useId as P, useRef as T, useEffect as D } from "react";
3
+ import { createPortal as L } from "react-dom";
4
+ import { pcoApiUrl as I } from "@planningcenter/url";
5
+ import { Button as j } from "@planningcenter/tapestry";
6
+ import { pencil as E, smallX as W, exclamationTriangle as q, toCloudArrow as G } from "@planningcenter/icons/paths/general";
7
+ import { image as J } from "@planningcenter/icons/paths/services";
8
+ import X from "react-dropzone";
9
+ function M(e) {
10
+ var o, r, t = "";
11
+ if (typeof e == "string" || typeof e == "number") t += e;
12
+ else if (typeof e == "object") if (Array.isArray(e)) {
13
+ var s = e.length;
14
+ for (o = 0; o < s; o++) e[o] && (r = M(e[o])) && (t && (t += " "), t += r);
15
+ } else for (r in e) e[r] && (t && (t += " "), t += r);
16
16
  return t;
17
17
  }
18
- function J() {
19
- for (var a, n, r = 0, t = "", d = arguments.length; r < d; r++) (a = arguments[r]) && (n = R(a)) && (t && (t += " "), t += n);
18
+ function H() {
19
+ for (var e, o, r = 0, t = "", s = arguments.length; r < s; r++) (e = arguments[r]) && (o = M(e)) && (t && (t += " "), t += o);
20
20
  return t;
21
21
  }
22
- function X() {
23
- const a = document.querySelector('meta[name="csrf-token"]');
24
- if (!a || !a.content)
22
+ function K() {
23
+ const e = document.querySelector('meta[name="csrf-token"]');
24
+ if (!e || !e.content)
25
25
  throw new Error(
26
26
  'CSRF token not found. Ensure your Rails application includes <meta name="csrf-token" content="..."> in the document head.'
27
27
  );
28
- return a.content;
28
+ return e.content;
29
29
  }
30
- const H = (a) => a === "dark_mode_avatar" ? "dark" : "light";
31
- function x({
32
- avatarUrl: a,
33
- organization: n,
30
+ function Q(e) {
31
+ const o = e.split("");
32
+ return [o.shift()?.toUpperCase(), o.join("")].join("");
33
+ }
34
+ const V = (e) => e === "dark_mode_avatar" ? "dark" : "light";
35
+ function R({
36
+ avatarUrl: e,
37
+ organization: o,
34
38
  mode: r,
35
39
  pcoEnv: t,
36
- onAvatarUpdate: d
40
+ onAvatarUpdate: s
37
41
  }) {
38
- const [i, g] = p(null), [s, f] = p(a), [c, v] = p(!1), [_, h] = p(""), y = S(), A = $(null), w = H(r), M = (u) => {
39
- const [l] = u;
40
- l && g(
41
- Object.assign(l, {
42
- preview: URL.createObjectURL(l)
42
+ const [l, m] = u(null), [h, f] = u(e), [c, U] = u(!1), [d, v] = u(!1), [z, b] = u(""), y = P(), N = T(null), w = V(r), S = (p) => {
43
+ const [i] = p;
44
+ i && m(
45
+ Object.assign(i, {
46
+ preview: URL.createObjectURL(i)
43
47
  })
44
48
  );
45
49
  };
46
- j(() => {
47
- f(a);
48
- }, [a]), j(() => () => {
49
- i?.preview && (URL.revokeObjectURL(i.preview), h(""));
50
- }, [i]);
51
- const z = async (u) => {
52
- const l = await fetch(P("accounts", { env: t }), {
50
+ D(() => {
51
+ f(e);
52
+ }, [e]), D(() => () => {
53
+ l?.preview && (URL.revokeObjectURL(l.preview), b(""));
54
+ }, [l]);
55
+ const x = async (p) => {
56
+ const i = await fetch(I("accounts", { env: t }), {
53
57
  method: "PATCH",
54
58
  headers: {
55
59
  "Content-Type": "application/json",
56
- "X-CSRF-Token": X(),
60
+ "X-CSRF-Token": K(),
57
61
  Accept: "application/json"
58
62
  },
59
63
  body: JSON.stringify({
60
64
  data: {
61
- attributes: u
65
+ attributes: p
62
66
  }
63
67
  })
64
- }), m = await l.json();
65
- if (!l.ok) throw m;
66
- return m;
67
- }, D = async (u) => {
68
- if (u.preventDefault(), !(!i || c)) {
69
- v(!0);
68
+ }), g = await i.json();
69
+ if (!i.ok) throw g;
70
+ return g;
71
+ }, F = async (p) => {
72
+ if (p.preventDefault(), !(!l || c || d)) {
73
+ U(!0);
70
74
  try {
71
- const l = new FileReader(), m = await new Promise((C, U) => {
72
- l.onloadend = () => C(l.result), l.onerror = U, l.readAsDataURL(i);
73
- }), k = await z({
74
- [r]: m,
75
+ const i = new FileReader(), g = await new Promise((A, C) => {
76
+ i.onloadend = () => A(i.result), i.onerror = C, i.readAsDataURL(l);
77
+ }), k = await x({
78
+ [r]: g,
75
79
  [`${r}_cache`]: ""
76
80
  });
77
- f(k.data.attributes[r].url), g(null), d(r, k.data.attributes[r].url), A.current?.close();
81
+ f(k.data.attributes[r].url), m(null), s(r, k.data.attributes[r].url), N.current?.close();
78
82
  } catch {
79
- h("We were unable to save your avatar.");
83
+ b("We were unable to save your avatar.");
80
84
  } finally {
81
- v(!1);
85
+ U(!1);
82
86
  }
83
87
  }
84
- }, F = async () => {
85
- if (!c) {
88
+ }, O = async () => {
89
+ if (!(c || d)) {
86
90
  v(!0);
87
91
  try {
88
- await z({
92
+ await x({
89
93
  [`remove_${r}`]: "1"
90
- }), f(""), d(r, ""), A.current?.close();
94
+ }), f(""), s(r, ""), N.current?.close();
91
95
  } catch {
92
- h("We were unable to delete your avatar.");
96
+ b("We were unable to delete your avatar.");
93
97
  } finally {
94
98
  v(!1);
95
99
  }
96
100
  }
97
- }, L = () => {
98
- g(null), h("");
101
+ }, $ = () => {
102
+ m(null), b("");
99
103
  };
100
- return /* @__PURE__ */ o(b, { children: [
101
- /* @__PURE__ */ o("div", { className: "pco-org-avatar", children: [
102
- /* @__PURE__ */ e(
104
+ return /* @__PURE__ */ n(_, { children: [
105
+ /* @__PURE__ */ n("div", { className: "pco-org-avatar", children: [
106
+ /* @__PURE__ */ a(
103
107
  "button",
104
108
  {
105
109
  type: "button",
106
110
  commandfor: y,
107
111
  command: "show-modal",
108
112
  className: `pco-org-avatar__button pco-org-avatar__button--${w}`,
109
- children: s ? /* @__PURE__ */ o(b, { children: [
110
- /* @__PURE__ */ e("img", { src: s, alt: `Church logo for ${n}` }),
111
- /* @__PURE__ */ e("span", { children: /* @__PURE__ */ e(
113
+ children: h ? /* @__PURE__ */ n(_, { children: [
114
+ /* @__PURE__ */ a("img", { src: h, alt: `Church logo for ${o}` }),
115
+ /* @__PURE__ */ a("div", { className: "tds-btn tds-btn--interaction tds-btn--icononly", children: /* @__PURE__ */ a(
112
116
  "svg",
113
117
  {
114
- width: "16",
115
- height: "16",
118
+ width: "14",
119
+ height: "14",
116
120
  viewBox: "0 0 16 16",
117
121
  fill: "currentColor",
118
122
  "aria-hidden": "true",
119
- children: /* @__PURE__ */ e("path", { d: T })
123
+ children: /* @__PURE__ */ a("path", { d: E })
120
124
  }
121
125
  ) })
122
- ] }) : /* @__PURE__ */ e(
126
+ ] }) : /* @__PURE__ */ a(
123
127
  "svg",
124
128
  {
125
129
  width: "48",
@@ -127,40 +131,40 @@ function x({
127
131
  viewBox: "0 0 16 16",
128
132
  fill: "currentColor",
129
133
  "aria-hidden": "true",
130
- children: /* @__PURE__ */ e("path", { d: q })
134
+ children: /* @__PURE__ */ a("path", { d: J })
131
135
  }
132
136
  )
133
137
  }
134
138
  ),
135
- /* @__PURE__ */ o("div", { className: "pco-org-avatar__label", children: [
136
- w,
139
+ /* @__PURE__ */ n("div", { className: "pco-org-avatar__label", children: [
140
+ Q(w),
137
141
  " mode"
138
142
  ] })
139
143
  ] }),
140
- B(
141
- /* @__PURE__ */ e(
144
+ L(
145
+ /* @__PURE__ */ a(
142
146
  "dialog",
143
147
  {
144
148
  id: y,
145
- ref: A,
146
- className: "dialog",
147
- onClose: L,
148
- children: /* @__PURE__ */ o("form", { onSubmit: D, children: [
149
- /* @__PURE__ */ o("div", { className: "dialog__header", children: [
150
- /* @__PURE__ */ o("h1", { className: "dialog__title", children: [
149
+ ref: N,
150
+ className: "pco-org-avatar__dialog",
151
+ onClose: $,
152
+ children: /* @__PURE__ */ n("form", { onSubmit: F, children: [
153
+ /* @__PURE__ */ n("div", { className: "pco-org-avatar__dialog-header", children: [
154
+ /* @__PURE__ */ n("h1", { className: "pco-org-avatar__dialog-title", children: [
151
155
  "Church logo — ",
152
156
  w,
153
157
  " mode"
154
158
  ] }),
155
- /* @__PURE__ */ e(
159
+ /* @__PURE__ */ a(
156
160
  "button",
157
161
  {
158
162
  type: "button",
159
163
  commandfor: y,
160
164
  command: "close",
161
- className: "dialog__close",
165
+ className: "pco-org-avatar__dialog-close",
162
166
  "aria-label": "Close modal",
163
- children: /* @__PURE__ */ e(
167
+ children: /* @__PURE__ */ a(
164
168
  "svg",
165
169
  {
166
170
  width: "16",
@@ -168,15 +172,15 @@ function x({
168
172
  viewBox: "0 0 16 16",
169
173
  fill: "currentColor",
170
174
  "aria-hidden": "true",
171
- children: /* @__PURE__ */ e("path", { d: E })
175
+ children: /* @__PURE__ */ a("path", { d: W })
172
176
  }
173
177
  )
174
178
  }
175
179
  )
176
180
  ] }),
177
- /* @__PURE__ */ o("div", { className: "dialog__body", children: [
178
- _ && /* @__PURE__ */ o("div", { role: "alert", className: "alert alert--danger mb-2", children: [
179
- /* @__PURE__ */ e(
181
+ /* @__PURE__ */ n("div", { className: "pco-org-avatar__dialog-body", children: [
182
+ z && /* @__PURE__ */ n("div", { role: "alert", className: "pco-org-avatar__dialog-alert", children: [
183
+ /* @__PURE__ */ a(
180
184
  "svg",
181
185
  {
182
186
  width: "16",
@@ -184,66 +188,66 @@ function x({
184
188
  viewBox: "0 0 16 16",
185
189
  className: "symbol",
186
190
  "aria-hidden": "true",
187
- children: /* @__PURE__ */ e("path", { d: I })
191
+ children: /* @__PURE__ */ a("path", { d: q })
188
192
  }
189
193
  ),
190
- /* @__PURE__ */ e("div", { className: "alert__content", children: /* @__PURE__ */ e("p", { children: _ }) })
194
+ /* @__PURE__ */ a("p", { children: z })
191
195
  ] }),
192
- /* @__PURE__ */ e(
193
- G,
196
+ /* @__PURE__ */ a(
197
+ X,
194
198
  {
195
199
  accept: { "image/*": [".jpg", ".jpeg", ".png"] },
196
200
  multiple: !1,
197
- onDropAccepted: M,
201
+ onDropAccepted: S,
198
202
  children: ({
199
- getRootProps: u,
200
- getInputProps: l,
201
- isFocused: m,
203
+ getRootProps: p,
204
+ getInputProps: i,
205
+ isFocused: g,
202
206
  isDragAccept: k,
203
- isDragReject: C,
204
- isDragActive: U
207
+ isDragReject: A,
208
+ isDragActive: C
205
209
  }) => {
206
- const O = J(
207
- "pco-org-avatar__dropzone",
208
- `pco-org-avatar__dropzone--${w}`,
210
+ const B = H(
211
+ "pco-org-avatar__dialog-dropzone",
212
+ `pco-org-avatar__dialog-dropzone--${w}`,
209
213
  {
210
- "pco-org-avatar__dropzone--image": i || s,
211
- "pco-org-avatar__dropzone--focused": m,
212
- "pco-org-avatar__dropzone--accepted": k,
213
- "pco-org-avatar__dropzone--rejected": U && C
214
+ "pco-org-avatar__dialog-dropzone--image": l || h,
215
+ "pco-org-avatar__dialog-dropzone--focused": g,
216
+ "pco-org-avatar__dialog-dropzone--accepted": k,
217
+ "pco-org-avatar__dialog-dropzone--rejected": C && A
214
218
  }
215
219
  );
216
- return /* @__PURE__ */ o("div", { ...u({ className: O }), children: [
217
- /* @__PURE__ */ e("input", { ...l() }),
218
- i ? /* @__PURE__ */ e(
220
+ return /* @__PURE__ */ n("div", { ...p({ className: B }), children: [
221
+ /* @__PURE__ */ a("input", { ...i() }),
222
+ l ? /* @__PURE__ */ a(
219
223
  "img",
220
224
  {
221
- src: i.preview,
222
- alt: `Church logo for ${n}`
225
+ src: l.preview,
226
+ alt: `Church logo for ${o}`
223
227
  }
224
- ) : s ? /* @__PURE__ */ e(
228
+ ) : h ? /* @__PURE__ */ a(
225
229
  "img",
226
230
  {
227
- src: s,
228
- alt: `Church logo for ${n}`
231
+ src: h,
232
+ alt: `Church logo for ${o}`
229
233
  }
230
- ) : /* @__PURE__ */ o(b, { children: [
231
- /* @__PURE__ */ e(
234
+ ) : /* @__PURE__ */ n(_, { children: [
235
+ /* @__PURE__ */ a(
232
236
  "svg",
233
237
  {
234
238
  width: "64",
235
239
  height: "64",
236
240
  viewBox: "0 0 16 16",
237
241
  "aria-hidden": "true",
238
- children: /* @__PURE__ */ e("path", { d: W })
242
+ children: /* @__PURE__ */ a("path", { d: G })
239
243
  }
240
244
  ),
241
- U && C ? /* @__PURE__ */ o(b, { children: [
242
- /* @__PURE__ */ e("h2", { children: "Wrong file type" }),
243
- /* @__PURE__ */ e("p", { children: "Please upload a PNG or JPG file." })
244
- ] }) : /* @__PURE__ */ o(b, { children: [
245
- /* @__PURE__ */ e("h2", { children: "Add church logo" }),
246
- /* @__PURE__ */ e("p", { children: "Use a high-quality image (up to 20mb) with a transparent background." })
245
+ C && A ? /* @__PURE__ */ n(_, { children: [
246
+ /* @__PURE__ */ a("h2", { children: "Wrong file type" }),
247
+ /* @__PURE__ */ a("p", { children: "Please upload a PNG or JPG file." })
248
+ ] }) : /* @__PURE__ */ n(_, { children: [
249
+ /* @__PURE__ */ a("h2", { children: "Add church logo" }),
250
+ /* @__PURE__ */ a("p", { children: "Use a high-quality image (up to 20mb) with a transparent background." })
247
251
  ] })
248
252
  ] })
249
253
  ] });
@@ -251,36 +255,36 @@ function x({
251
255
  }
252
256
  )
253
257
  ] }),
254
- /* @__PURE__ */ o("div", { className: "dialog__actions", children: [
255
- s && /* @__PURE__ */ e(
256
- N,
258
+ /* @__PURE__ */ n("div", { className: "pco-org-avatar__dialog-actions", children: [
259
+ h && /* @__PURE__ */ a(
260
+ j,
257
261
  {
258
262
  label: "Delete logo",
259
263
  kind: "delete",
260
- onClick: F,
261
- loading: c,
262
- disabled: c,
263
- className: "mr-a"
264
+ onClick: O,
265
+ loading: d,
266
+ disabled: d || c,
267
+ className: "pco-org-avatar__dialog-delete"
264
268
  }
265
269
  ),
266
- /* @__PURE__ */ e(
267
- N,
270
+ /* @__PURE__ */ a(
271
+ j,
268
272
  {
269
273
  type: "button",
270
274
  label: "Cancel",
271
275
  commandfor: y,
272
276
  command: "close",
273
- disabled: c
277
+ disabled: c || d
274
278
  }
275
279
  ),
276
- /* @__PURE__ */ e(
277
- N,
280
+ /* @__PURE__ */ a(
281
+ j,
278
282
  {
279
283
  type: "submit",
280
284
  label: "Update logo",
281
285
  kind: "primary",
282
286
  loading: c,
283
- disabled: !i || c
287
+ disabled: !l || c || d
284
288
  }
285
289
  )
286
290
  ] })
@@ -291,33 +295,33 @@ function x({
291
295
  )
292
296
  ] });
293
297
  }
294
- function te({
295
- avatarUrl: a,
296
- darkModeAvatarUrl: n,
298
+ function ia({
299
+ avatarUrl: e,
300
+ darkModeAvatarUrl: o,
297
301
  orgName: r,
298
302
  pcoEnv: t,
299
- showDarkModeAvatar: d = !1
303
+ showDarkModeAvatar: s = !1
300
304
  }) {
301
- const [i, g] = p(a), [s, f] = p(
302
- n
303
- ), c = (_, h) => {
304
- _ === "avatar" ? g(h) : _ === "dark_mode_avatar" && f(h);
305
+ const [l, m] = u(e), [h, f] = u(
306
+ o
307
+ ), c = (d, v) => {
308
+ d === "avatar" ? m(v) : d === "dark_mode_avatar" && f(v);
305
309
  };
306
- return /* @__PURE__ */ o("div", { className: "d-f g-1", children: [
307
- /* @__PURE__ */ e(
308
- x,
310
+ return /* @__PURE__ */ n("div", { className: "pco-org-avatars", children: [
311
+ /* @__PURE__ */ a(
312
+ R,
309
313
  {
310
- avatarUrl: i,
314
+ avatarUrl: l,
311
315
  organization: r,
312
316
  mode: "avatar",
313
317
  pcoEnv: t,
314
318
  onAvatarUpdate: c
315
319
  }
316
320
  ),
317
- d && /* @__PURE__ */ e(
318
- x,
321
+ s && /* @__PURE__ */ a(
322
+ R,
319
323
  {
320
- avatarUrl: s || i,
324
+ avatarUrl: h || l,
321
325
  organization: r,
322
326
  mode: "dark_mode_avatar",
323
327
  pcoEnv: t,
@@ -327,5 +331,5 @@ function te({
327
331
  ] });
328
332
  }
329
333
  export {
330
- te as OrganizationAvatars
334
+ ia as OrganizationAvatars
331
335
  };
package/dist/style.css CHANGED
@@ -1,3 +1,8 @@
1
+ .pco-org-avatars {
2
+ display: flex;
3
+ gap: var(--t-spacing-1);
4
+ }
5
+
1
6
  .pco-org-avatar {
2
7
  align-items: center;
3
8
  display: inline-flex;
@@ -6,7 +11,7 @@
6
11
  }
7
12
 
8
13
  .pco-org-avatar__button {
9
- background: transparent;
14
+ background: var(--t-surface-color-canvas);
10
15
  border: var(--t-border-width) dashed var(--t-border-color);
11
16
  border-radius: var(--t-border-radius-lg);
12
17
  color: var(--t-icon-color-dim);
@@ -24,23 +29,17 @@
24
29
  vertical-align: middle;
25
30
  }
26
31
 
27
- .pco-org-avatar__button span {
28
- background: var(--t-fill-color-interaction);
29
- border-radius: var(--t-border-radius-md);
32
+ .pco-org-avatar__button div {
30
33
  bottom: var(--t-spacing-1);
31
- box-shadow: 0 var(--t-spacing-half) var(--t-spacing-1)
32
- var(--t-fill-color-transparency-dark-static-020);
33
- color: var(--t-icon-color-inverted);
34
34
  opacity: 0;
35
- padding: var(--t-spacing-1);
36
35
  position: absolute;
37
36
  right: var(--t-spacing-1);
38
37
  transition: all 0.1s linear;
39
38
  visibility: hidden;
40
39
  }
41
40
 
42
- .pco-org-avatar__button:hover span,
43
- .pco-org-avatar__button:focus-within span {
41
+ .pco-org-avatar__button:hover div,
42
+ .pco-org-avatar__button:focus-visible div {
44
43
  opacity: 1;
45
44
  visibility: visible;
46
45
  }
@@ -50,7 +49,107 @@
50
49
  font-size: var(--t-font-size-sm);
51
50
  }
52
51
 
53
- .pco-org-avatar__dropzone {
52
+ .pco-org-avatar__dialog {
53
+ background: var(--t-surface-color-canvas);
54
+ border: 0;
55
+ border-radius: var(--t-border-radius-lg);
56
+ box-shadow: 0 0 20px rgb(0 0 0 / 0.15);
57
+ margin: var(--t-spacing-2) auto;
58
+ max-height: calc(100% - calc(var(--t-spacing-2) * 2));
59
+ max-width: 600px;
60
+ padding: var(--t-spacing-1) 0;
61
+ position: relative;
62
+ width: calc(100% - var(--t-spacing-4));
63
+ }
64
+
65
+ @media (min-width: 600px) {
66
+ .pco-org-avatar__dialog {
67
+ margin-block: var(--t-spacing-6);
68
+ max-height: calc(100% - calc(var(--t-spacing-6) * 2));
69
+ }
70
+ }
71
+
72
+ .pco-org-avatar__dialog::backdrop {
73
+ background: rgb(0 0 0 / 0.4);
74
+ }
75
+
76
+ .pco-org-avatar__dialog-title {
77
+ font-size: var(--t-font-size-2xl);
78
+ overflow: hidden;
79
+ margin: 0;
80
+ white-space: nowrap;
81
+ text-overflow: ellipsis;
82
+ }
83
+
84
+ .pco-org-avatar__dialog-close {
85
+ background: transparent;
86
+ border-color: transparent;
87
+ color: var(--t-icon-color-dim);
88
+ cursor: pointer;
89
+ display: grid;
90
+ height: var(--t-spacing-4);
91
+ padding: 0;
92
+ place-items: center;
93
+ width: var(--t-spacing-4);
94
+ }
95
+
96
+ .pco-org-avatar__dialog-header,
97
+ .pco-org-avatar__dialog-actions {
98
+ align-items: center;
99
+ display: flex;
100
+ flex-wrap: wrap;
101
+ gap: var(--t-spacing-1);
102
+ padding: var(--t-spacing-2) var(--t-spacing-4);
103
+ }
104
+
105
+ .pco-org-avatar__dialog-header {
106
+ justify-content: space-between;
107
+ }
108
+
109
+ .pco-org-avatar__dialog-body {
110
+ padding: var(--t-spacing-2) var(--t-spacing-4);
111
+ margin-bottom: var(--t-spacing-2);
112
+ }
113
+
114
+ .pco-org-avatar__dialog-body > :last-child {
115
+ margin-bottom: 0;
116
+ }
117
+
118
+ .pco-org-avatar__dialog-actions {
119
+ border-top: var(--t-border-width) solid var(--t-border-color);
120
+ justify-content: flex-end;
121
+ }
122
+
123
+ .pco-org-avatar__dialog-delete {
124
+ margin-right: auto;
125
+ }
126
+
127
+ .pco-org-avatar__dialog-alert {
128
+ background: var(--t-fill-color-status-error-ghost);
129
+ border-radius: var(--t-border-radius-lg);
130
+ display: flex;
131
+ gap: var(--t-spacing-2);
132
+ margin-bottom: var(--t-spacing-2);
133
+ padding: var(--t-spacing-2);
134
+ }
135
+
136
+ .pco-org-avatar__dialog-alert svg {
137
+ fill: var(--t-icon-color-status-error);
138
+ flex-shrink: 0;
139
+ height: var(--t-element-size-md);
140
+ position: relative;
141
+ top: 1px;
142
+ width: var(--t-element-size-md);
143
+ }
144
+
145
+ .pco-org-avatar__dialog-alert p {
146
+ display: flex;
147
+ flex-direction: column;
148
+ gap: var(--t-spacing-half);
149
+ margin: 0;
150
+ }
151
+
152
+ .pco-org-avatar__dialog-dropzone {
54
153
  aspect-ratio: 16 / 9;
55
154
  border: var(--t-border-width-thick) dashed var(--t-border-color);
56
155
  border-radius: var(--t-border-radius-md);
@@ -65,59 +164,64 @@
65
164
  user-select: none;
66
165
  }
67
166
 
68
- .pco-org-avatar__dropzone svg {
167
+ .pco-org-avatar__dialog-dropzone svg {
69
168
  fill: var(--t-icon-color-status-info);
70
169
  }
71
170
 
72
- .pco-org-avatar__dropzone h2 {
171
+ .pco-org-avatar__dialog-dropzone h2 {
73
172
  color: var(--t-text-color-headline);
74
173
  font-size: var(--t-font-size-md);
75
174
  font-weight: var(--t-font-weight-normal);
76
175
  margin: 0;
77
176
  }
78
177
 
79
- .pco-org-avatar__dropzone p {
178
+ .pco-org-avatar__dialog-dropzone p {
80
179
  color: var(--t-text-color-placeholder);
81
180
  font-size: var(--t-font-size-sm);
82
181
  margin: 0;
83
182
  }
84
183
 
85
- .pco-org-avatar__dropzone img {
184
+ .pco-org-avatar__dialog-dropzone img {
86
185
  max-height: 100%;
87
186
  max-width: 100%;
88
187
  object-fit: contain;
89
188
  vertical-align: middle;
90
189
  }
91
190
 
92
- .pco-org-avatar__dropzone--focused {
191
+ .pco-org-avatar__dialog-dropzone:not(
192
+ .pco-org-avatar__dialog-dropzone:has(img),
193
+ .pco-org-avatar__dialog-dropzone--accepted,
194
+ .pco-org-avatar__dialog-dropzone--rejected
195
+ ):hover,
196
+ .pco-org-avatar__dialog-dropzone--focused {
93
197
  outline: 2px solid var(--t-fill-color-interaction);
94
198
  outline-offset: 1px;
95
199
  }
96
200
 
97
- .pco-org-avatar__dropzone--accepted {
201
+ .pco-org-avatar__dialog-dropzone--accepted {
98
202
  background: var(--t-fill-color-status-info-dim);
99
203
  border-color: var(--t-border-color-button-info);
100
204
  }
101
205
 
102
- .pco-org-avatar__dropzone--rejected {
206
+ .pco-org-avatar__dialog-dropzone--rejected {
103
207
  background: var(--t-fill-color-status-error-dim);
104
208
  border-color: var(--t-border-color-status-error);
105
209
  }
106
210
 
107
- .pco-org-avatar__dropzone--rejected svg {
211
+ .pco-org-avatar__dialog-dropzone--rejected svg {
108
212
  fill: var(--t-fill-color-status-error);
109
213
  }
110
214
 
111
215
  /* Light mode background - static regardless of UI theme */
112
216
  .pco-org-avatar__button--light:has(img),
113
- .pco-org-avatar__dropzone--light:has(img) {
217
+ .pco-org-avatar__dialog-dropzone--light:has(img) {
114
218
  background: hsl(0, 0%, 100%);
115
219
  border-color: transparent;
116
220
  }
117
221
 
118
222
  /* Dark mode background - static regardless of UI theme */
119
223
  .pco-org-avatar__button--dark:has(img),
120
- .pco-org-avatar__dropzone--dark:has(img) {
224
+ .pco-org-avatar__dialog-dropzone--dark:has(img) {
121
225
  background: hsl(0, 0%, 12%);
122
226
  border-color: transparent;
123
227
  }
package/dist/types.d.ts CHANGED
@@ -1,15 +1,16 @@
1
+ import type { Environment } from "@planningcenter/url";
1
2
  export type OrganizationAvatarsProps = {
2
3
  avatarUrl?: string;
3
4
  darkModeAvatarUrl?: string;
4
5
  orgName: string;
5
- pcoEnv?: string;
6
+ pcoEnv?: Environment;
6
7
  showDarkModeAvatar?: boolean;
7
8
  };
8
9
  export type OrganizationAvatarProps = {
9
10
  avatarUrl?: string;
10
11
  organization: string;
11
12
  mode: "avatar" | "dark_mode_avatar";
12
- pcoEnv?: string;
13
+ pcoEnv?: Environment;
13
14
  onAvatarUpdate: (attrName: string, newUrl: string) => void;
14
15
  };
15
16
  export type FileWithPreview = File & {
package/dist/utils.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export declare function getCsrfToken(): string;
2
+ export declare function capitalize(content: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/organization-avatars",
3
- "version": "1.2.1",
3
+ "version": "1.4.0",
4
4
  "description": "Organization avatar upload components for Planning Center apps",
5
5
  "type": "module",
6
6
  "packageManager": "yarn@1.22.22",