@planningcenter/organization-avatars 1.6.2 → 1.7.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/README.md +32 -5
- package/dist/index.cjs +1 -1
- package/dist/index.js +214 -178
- package/dist/organization_avatar.d.ts +1 -1
- package/dist/style.css +24 -15
- package/dist/types.d.ts +1 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -2,15 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
This package provides an `OrganizationAvatars` React component which encapsulates displaying and updating an organization's avatar.
|
|
4
4
|
|
|
5
|
-
See [the component's type signature](https://github.com/planningcenter/organization-avatars/blob/main/src/types.ts) for up-to-date props.
|
|
6
|
-
|
|
7
5
|
## Usage
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
```tsx
|
|
8
|
+
import { OrganizationAvatars } from "@planningcenter/organization-avatars"
|
|
9
|
+
import "@planningcenter/organization-avatars/style.css"
|
|
10
|
+
|
|
11
|
+
<OrganizationAvatars
|
|
12
|
+
orgName="Demo Church"
|
|
13
|
+
avatarUrl="https://example.com/avatar.png"
|
|
14
|
+
darkModeAvatarUrl="https://example.com/avatar-dark.png"
|
|
15
|
+
showDarkModeAvatar
|
|
16
|
+
onAvatarUpdate={(mode, newUrl) => console.log(mode, newUrl)}
|
|
17
|
+
/>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
To see a working example, see the [`/organization` page in Accounts](https://accounts.planningcenteronline.com/organization). The `OrganizationAvatars` component is mounted in [the `_church_information` partial](https://github.com/planningcenter/accounts/blob/main/app/views/organization/show/_church_information.html.erb).
|
|
21
|
+
|
|
22
|
+
## Props
|
|
23
|
+
|
|
24
|
+
| Prop | Type | Default | Description |
|
|
25
|
+
| --- | --- | --- | --- |
|
|
26
|
+
| `orgName` | `string` | **required** | The organization name, used for avatar alt text. |
|
|
27
|
+
| `avatarUrl` | `string` | `undefined` | URL of the current light mode avatar. When no `darkModeAvatarUrl` is provided, this is also used for the dark mode slot. |
|
|
28
|
+
| `darkModeAvatarUrl` | `string` | `undefined` | URL of the current dark mode avatar. Falls back to `avatarUrl` if not set. |
|
|
29
|
+
| `showDarkModeAvatar` | `boolean` | `false` | Whether to render the dark mode avatar UI alongside the light mode avatar. Intended to be controlled by a feature flag. |
|
|
30
|
+
| `onAvatarUpdate` | `(mode: AvatarMode, newUrl: string) => void` | `undefined` | Callback fired after a successful upload or delete. `mode` is `"avatar"` or `"dark_mode_avatar"`. `newUrl` is the new URL (or `""` on delete). |
|
|
31
|
+
| `pcoEnv` | `Environment` | `undefined` | Planning Center environment override (`"production"`, `"staging"`, `"development"`, `"test"`, `"prototype"`). When omitted, the environment is inferred automatically. |
|
|
32
|
+
| `readOnly` | `boolean` | `false` | Disables the edit button, preventing uploads and deletes. |
|
|
33
|
+
|
|
34
|
+
### Types
|
|
10
35
|
|
|
11
|
-
|
|
36
|
+
```ts
|
|
37
|
+
type AvatarMode = "avatar" | "dark_mode_avatar"
|
|
12
38
|
|
|
13
|
-
|
|
39
|
+
type Environment = "production" | "staging" | "development" | "test" | "prototype"
|
|
40
|
+
```
|
|
14
41
|
|
|
15
42
|
## Development
|
|
16
43
|
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("react"),T=require("react-dom"),$=require("@planningcenter/url"),b=require("@planningcenter/tapestry"),I=require("@planningcenter/sweetest-alert"),_=require("@planningcenter/icons/paths/general"),L=require("@planningcenter/icons/paths/services"),E=require("react-dropzone");function B(a){var r,t,o="";if(typeof a=="string"||typeof a=="number")o+=a;else if(typeof a=="object")if(Array.isArray(a)){var d=a.length;for(r=0;r<d;r++)a[r]&&(t=B(a[r]))&&(o&&(o+=" "),o+=t)}else for(t in a)a[t]&&(o&&(o+=" "),o+=t);return o}function W(){for(var a,r,t=0,o="",d=arguments.length;t<d;t++)(a=arguments[t])&&(r=B(a))&&(o&&(o+=" "),o+=r);return o}function G(){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 J(a){const r=a.split("");return[r.shift()?.toUpperCase(),r.join("")].join("")}const X=a=>a==="dark_mode_avatar"?"dark":"light",z=({open:a})=>e.jsxs("h2",{className:"pco-org-avatar__instructions",children:["Drag & drop your logo file to upload, or"," ",e.jsx(b.Button,{label:"browse",kind:"inline-text",onClick:r=>{r.stopPropagation(),a()}})]});function F({avatarUrl:a,organization:r,mode:t,pcoEnv:o,readOnly:d,onAvatarUpdate:x,fallbackAvatarUrl:A}){const[n,f]=c.useState(null),[l,y]=c.useState(!1),[i,p]=c.useState(!1),[u,w]=c.useState(""),q=c.useId(),v=c.useRef(null),g=X(t),m=a||A,D=h=>{const[s]=h;s&&f(Object.assign(s,{preview:URL.createObjectURL(s)}))};c.useEffect(()=>()=>{n?.preview&&(URL.revokeObjectURL(n.preview),w(""))},[n]);const S=async h=>{const s=await fetch($.pcoApiUrl("accounts",{env:o}),{method:"PATCH",headers:{"Content-Type":"application/json","X-CSRF-Token":G(),Accept:"application/json"},body:JSON.stringify({data:{attributes:h}})}),j=await s.json();if(!s.ok)throw j;return j},M=async h=>{if(h.preventDefault(),!(!n||l||i)){y(!0);try{const s=new FileReader,j=await new Promise((k,C)=>{s.onloadend=()=>k(s.result),s.onerror=C,s.readAsDataURL(n)}),N=await S({[t]:j,[`${t}_cache`]:""});f(null),x(t,N.data.attributes[t].url),v.current?.close()}catch{w("We were unable to save your avatar.")}finally{y(!1)}}},U=async()=>{l||i||(p(!0),I.SweetestAlert({type:"danger",title:"Remove this logo?",content:`Removing this logo will mean your light mode logo appear in ${g} mode. This cannot be undone.`,confirmButton:"Remove logo",onConfirm:async()=>{try{await S({[`remove_${t}`]:"1"}),x(t,""),v.current?.close()}catch{w("We were unable to delete your avatar.")}finally{p(!1)}},onCancel:()=>{p(!1)}}))},O=()=>{f(null),w("")};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"pco-org-avatar",children:[e.jsx("button",{type:"button",onClick:()=>v.current?.showModal(),disabled:d,className:`pco-org-avatar__button pco-org-avatar__button--${g}`,children:m?e.jsxs(e.Fragment,{children:[e.jsx("img",{src:m,alt:`Church logo for ${r}`}),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:_.pencil})})})]}):e.jsxs(e.Fragment,{children:[e.jsx("svg",{width:"48",height:"48",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{d:L.image})}),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:_.pencil})})})]})}),e.jsxs("div",{className:"pco-org-avatar__label",children:[J(g)," mode"]})]}),T.createPortal(e.jsx("dialog",{id:q,ref:v,className:"pco-org-avatar__dialog",onClose:O,children:e.jsxs("form",{onSubmit:M,children:[e.jsxs("div",{className:"pco-org-avatar__dialog-header",children:[e.jsxs("h1",{className:"pco-org-avatar__dialog-title",children:["Church logo — ",g," mode"]}),e.jsx("button",{type:"button",onClick:()=>v.current?.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:_.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:_.exclamationTriangle})}),e.jsx("p",{children:u})]}),e.jsx(E,{accept:{"image/*":[".jpg",".jpeg",".png"]},multiple:!1,onDropAccepted:D,children:({getRootProps:h,getInputProps:s,isFocused:j,isDragAccept:N,isDragReject:k,isDragActive:C,open:R})=>{const P=W("pco-org-avatar__dialog-dropzone",`pco-org-avatar__dialog-dropzone--${g}`,{"pco-org-avatar__dialog-dropzone--image":n||m,"pco-org-avatar__dialog-dropzone--focused":j,"pco-org-avatar__dialog-dropzone--accepted":N,"pco-org-avatar__dialog-dropzone--rejected":C&&k});return e.jsxs(e.Fragment,{children:[e.jsxs("div",{...h({className:P}),children:[e.jsx("input",{...s()}),n?e.jsx("img",{src:n.preview,alt:`Church logo for ${r}`}):m?e.jsx("img",{src:m,alt:`Church logo for ${r}`}):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:_.toCloudArrow})}),C&&k?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(z,{open:R}),e.jsx("p",{className:"pco-org-avatar__instructions-sub",children:"Use a high-quality image (up to 20mb) with a transparent background."})]})]})]}),(n||m)&&e.jsx(z,{open:R})]})}})]}),e.jsxs("div",{className:"pco-org-avatar__dialog-actions",children:[a&&g==="light"&&e.jsx(b.Button,{label:"Remove logo",kind:"secondary-delete",onClick:U,loading:i,disabled:i||l,className:"pco-org-avatar__dialog-delete"}),a&&g==="dark"&&e.jsx(b.Button,{label:"Use light mode logo",kind:"secondary",onClick:U,loading:i,disabled:i||l,className:"pco-org-avatar__dialog-delete"}),e.jsx(b.Button,{type:"button",label:"Cancel",onClick:()=>v.current?.close(),disabled:l||i}),e.jsx(b.Button,{type:"submit",label:"Update logo",kind:"primary",loading:l,disabled:!n||l||i})]})]})}),document.body)]})}function H({avatarUrl:a,darkModeAvatarUrl:r,orgName:t,onAvatarUpdate:o,pcoEnv:d,readOnly:x,showDarkModeAvatar:A=!1}){const[n,f]=c.useState(a),[l,y]=c.useState(r),i=(p,u)=>{p==="avatar"?(f(u),o?.("avatar",u)):p==="dark_mode_avatar"&&(y(u),o?.("dark_mode_avatar",u))};return e.jsxs("div",{className:"pco-org-avatars",children:[e.jsx(F,{avatarUrl:n,organization:t,mode:"avatar",pcoEnv:d,readOnly:x,onAvatarUpdate:i}),A&&e.jsx(F,{avatarUrl:l,organization:t,mode:"dark_mode_avatar",pcoEnv:d,readOnly:x,onAvatarUpdate:i,fallbackAvatarUrl:n})]})}exports.OrganizationAvatars=H;
|
package/dist/index.js
CHANGED
|
@@ -1,118 +1,140 @@
|
|
|
1
|
-
import { jsxs as n, Fragment as
|
|
2
|
-
import { useState as
|
|
3
|
-
import { createPortal as
|
|
4
|
-
import { pcoApiUrl as
|
|
5
|
-
import { Button as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
|
|
1
|
+
import { jsxs as n, Fragment as u, jsx as a } from "react/jsx-runtime";
|
|
2
|
+
import { useState as b, useId as L, useRef as E, useEffect as W } from "react";
|
|
3
|
+
import { createPortal as q } from "react-dom";
|
|
4
|
+
import { pcoApiUrl as G } from "@planningcenter/url";
|
|
5
|
+
import { Button as k } from "@planningcenter/tapestry";
|
|
6
|
+
import { SweetestAlert as J } from "@planningcenter/sweetest-alert";
|
|
7
|
+
import { pencil as B, smallX as X, exclamationTriangle as H, toCloudArrow as K } from "@planningcenter/icons/paths/general";
|
|
8
|
+
import { image as Q } from "@planningcenter/icons/paths/services";
|
|
9
|
+
import V from "react-dropzone";
|
|
10
|
+
function M(e) {
|
|
10
11
|
var o, r, t = "";
|
|
11
|
-
if (typeof
|
|
12
|
-
else if (typeof
|
|
13
|
-
var
|
|
14
|
-
for (o = 0; o <
|
|
15
|
-
} else for (r in
|
|
12
|
+
if (typeof e == "string" || typeof e == "number") t += e;
|
|
13
|
+
else if (typeof e == "object") if (Array.isArray(e)) {
|
|
14
|
+
var s = e.length;
|
|
15
|
+
for (o = 0; o < s; o++) e[o] && (r = M(e[o])) && (t && (t += " "), t += r);
|
|
16
|
+
} else for (r in e) e[r] && (t && (t += " "), t += r);
|
|
16
17
|
return t;
|
|
17
18
|
}
|
|
18
|
-
function
|
|
19
|
-
for (var
|
|
19
|
+
function Y() {
|
|
20
|
+
for (var e, o, r = 0, t = "", s = arguments.length; r < s; r++) (e = arguments[r]) && (o = M(e)) && (t && (t += " "), t += o);
|
|
20
21
|
return t;
|
|
21
22
|
}
|
|
22
|
-
function
|
|
23
|
-
const
|
|
24
|
-
if (!
|
|
23
|
+
function Z() {
|
|
24
|
+
const e = document.querySelector('meta[name="csrf-token"]');
|
|
25
|
+
if (!e || !e.content)
|
|
25
26
|
throw new Error(
|
|
26
27
|
'CSRF token not found. Ensure your Rails application includes <meta name="csrf-token" content="..."> in the document head.'
|
|
27
28
|
);
|
|
28
|
-
return
|
|
29
|
+
return e.content;
|
|
29
30
|
}
|
|
30
|
-
function
|
|
31
|
-
const o =
|
|
31
|
+
function aa(e) {
|
|
32
|
+
const o = e.split("");
|
|
32
33
|
return [o.shift()?.toUpperCase(), o.join("")].join("");
|
|
33
34
|
}
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const ea = (e) => e === "dark_mode_avatar" ? "dark" : "light", D = ({ open: e }) => /* @__PURE__ */ n("h2", { className: "pco-org-avatar__instructions", children: [
|
|
36
|
+
"Drag & drop your logo file to upload, or",
|
|
37
|
+
" ",
|
|
38
|
+
/* @__PURE__ */ a(
|
|
39
|
+
k,
|
|
40
|
+
{
|
|
41
|
+
label: "browse",
|
|
42
|
+
kind: "inline-text",
|
|
43
|
+
onClick: (o) => {
|
|
44
|
+
o.stopPropagation(), e();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
] });
|
|
49
|
+
function F({
|
|
50
|
+
avatarUrl: e,
|
|
37
51
|
organization: o,
|
|
38
52
|
mode: r,
|
|
39
53
|
pcoEnv: t,
|
|
40
|
-
readOnly:
|
|
41
|
-
onAvatarUpdate:
|
|
54
|
+
readOnly: s,
|
|
55
|
+
onAvatarUpdate: y,
|
|
56
|
+
fallbackAvatarUrl: R
|
|
42
57
|
}) {
|
|
43
|
-
const [
|
|
44
|
-
const [
|
|
45
|
-
|
|
46
|
-
Object.assign(
|
|
47
|
-
preview: URL.createObjectURL(
|
|
58
|
+
const [i, w] = b(null), [d, C] = b(!1), [c, m] = b(!1), [g, A] = b(""), $ = L(), v = E(null), h = ea(r), f = e || R, P = (p) => {
|
|
59
|
+
const [l] = p;
|
|
60
|
+
l && w(
|
|
61
|
+
Object.assign(l, {
|
|
62
|
+
preview: URL.createObjectURL(l)
|
|
48
63
|
})
|
|
49
64
|
);
|
|
50
65
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}, [
|
|
54
|
-
const
|
|
55
|
-
const
|
|
66
|
+
W(() => () => {
|
|
67
|
+
i?.preview && (URL.revokeObjectURL(i.preview), A(""));
|
|
68
|
+
}, [i]);
|
|
69
|
+
const z = async (p) => {
|
|
70
|
+
const l = await fetch(G("accounts", { env: t }), {
|
|
56
71
|
method: "PATCH",
|
|
57
72
|
headers: {
|
|
58
73
|
"Content-Type": "application/json",
|
|
59
|
-
"X-CSRF-Token":
|
|
74
|
+
"X-CSRF-Token": Z(),
|
|
60
75
|
Accept: "application/json"
|
|
61
76
|
},
|
|
62
77
|
body: JSON.stringify({
|
|
63
78
|
data: {
|
|
64
|
-
attributes:
|
|
79
|
+
attributes: p
|
|
65
80
|
}
|
|
66
81
|
})
|
|
67
|
-
}),
|
|
68
|
-
if (!
|
|
69
|
-
return
|
|
70
|
-
},
|
|
71
|
-
if (
|
|
72
|
-
|
|
82
|
+
}), _ = await l.json();
|
|
83
|
+
if (!l.ok) throw _;
|
|
84
|
+
return _;
|
|
85
|
+
}, T = async (p) => {
|
|
86
|
+
if (p.preventDefault(), !(!i || d || c)) {
|
|
87
|
+
C(!0);
|
|
73
88
|
try {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
}), j = await
|
|
77
|
-
[r]:
|
|
89
|
+
const l = new FileReader(), _ = await new Promise((N, U) => {
|
|
90
|
+
l.onloadend = () => N(l.result), l.onerror = U, l.readAsDataURL(i);
|
|
91
|
+
}), j = await z({
|
|
92
|
+
[r]: _,
|
|
78
93
|
[`${r}_cache`]: ""
|
|
79
94
|
});
|
|
80
|
-
|
|
95
|
+
w(null), y(r, j.data.attributes[r].url), v.current?.close();
|
|
81
96
|
} catch {
|
|
82
|
-
|
|
97
|
+
A("We were unable to save your avatar.");
|
|
83
98
|
} finally {
|
|
84
|
-
|
|
99
|
+
C(!1);
|
|
85
100
|
}
|
|
86
101
|
}
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
}, x = async () => {
|
|
103
|
+
d || c || (m(!0), J({
|
|
104
|
+
type: "danger",
|
|
105
|
+
title: "Remove this logo?",
|
|
106
|
+
content: `Removing this logo will mean your light mode logo appear in ${h} mode. This cannot be undone.`,
|
|
107
|
+
confirmButton: "Remove logo",
|
|
108
|
+
onConfirm: async () => {
|
|
109
|
+
try {
|
|
110
|
+
await z({
|
|
111
|
+
[`remove_${r}`]: "1"
|
|
112
|
+
}), y(r, ""), v.current?.close();
|
|
113
|
+
} catch {
|
|
114
|
+
A("We were unable to delete your avatar.");
|
|
115
|
+
} finally {
|
|
116
|
+
m(!1);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
onCancel: () => {
|
|
120
|
+
m(!1);
|
|
98
121
|
}
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
|
|
122
|
+
}));
|
|
123
|
+
}, O = () => {
|
|
124
|
+
w(null), A("");
|
|
102
125
|
};
|
|
103
|
-
return /* @__PURE__ */ n(
|
|
126
|
+
return /* @__PURE__ */ n(u, { children: [
|
|
104
127
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar", children: [
|
|
105
|
-
/* @__PURE__ */
|
|
128
|
+
/* @__PURE__ */ a(
|
|
106
129
|
"button",
|
|
107
130
|
{
|
|
108
131
|
type: "button",
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
/* @__PURE__ */
|
|
115
|
-
/* @__PURE__ */ e("div", { className: "tds-btn tds-btn--interaction tds-btn--icononly", children: /* @__PURE__ */ e(
|
|
132
|
+
onClick: () => v.current?.showModal(),
|
|
133
|
+
disabled: s,
|
|
134
|
+
className: `pco-org-avatar__button pco-org-avatar__button--${h}`,
|
|
135
|
+
children: f ? /* @__PURE__ */ n(u, { children: [
|
|
136
|
+
/* @__PURE__ */ a("img", { src: f, alt: `Church logo for ${o}` }),
|
|
137
|
+
/* @__PURE__ */ a("div", { className: "tds-btn tds-btn--interaction tds-btn--icononly", children: /* @__PURE__ */ a(
|
|
116
138
|
"svg",
|
|
117
139
|
{
|
|
118
140
|
width: "14",
|
|
@@ -120,11 +142,11 @@ function D({
|
|
|
120
142
|
viewBox: "0 0 16 16",
|
|
121
143
|
fill: "currentColor",
|
|
122
144
|
"aria-hidden": "true",
|
|
123
|
-
children: /* @__PURE__ */
|
|
145
|
+
children: /* @__PURE__ */ a("path", { d: B })
|
|
124
146
|
}
|
|
125
147
|
) })
|
|
126
|
-
] }) : /* @__PURE__ */ n(
|
|
127
|
-
/* @__PURE__ */
|
|
148
|
+
] }) : /* @__PURE__ */ n(u, { children: [
|
|
149
|
+
/* @__PURE__ */ a(
|
|
128
150
|
"svg",
|
|
129
151
|
{
|
|
130
152
|
width: "48",
|
|
@@ -132,10 +154,10 @@ function D({
|
|
|
132
154
|
viewBox: "0 0 16 16",
|
|
133
155
|
fill: "currentColor",
|
|
134
156
|
"aria-hidden": "true",
|
|
135
|
-
children: /* @__PURE__ */
|
|
157
|
+
children: /* @__PURE__ */ a("path", { d: Q })
|
|
136
158
|
}
|
|
137
159
|
),
|
|
138
|
-
/* @__PURE__ */
|
|
160
|
+
/* @__PURE__ */ a("div", { className: "tds-btn tds-btn--interaction tds-btn--icononly", children: /* @__PURE__ */ a(
|
|
139
161
|
"svg",
|
|
140
162
|
{
|
|
141
163
|
width: "14",
|
|
@@ -143,41 +165,40 @@ function D({
|
|
|
143
165
|
viewBox: "0 0 16 16",
|
|
144
166
|
fill: "currentColor",
|
|
145
167
|
"aria-hidden": "true",
|
|
146
|
-
children: /* @__PURE__ */
|
|
168
|
+
children: /* @__PURE__ */ a("path", { d: B })
|
|
147
169
|
}
|
|
148
170
|
) })
|
|
149
171
|
] })
|
|
150
172
|
}
|
|
151
173
|
),
|
|
152
174
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar__label", children: [
|
|
153
|
-
|
|
175
|
+
aa(h),
|
|
154
176
|
" mode"
|
|
155
177
|
] })
|
|
156
178
|
] }),
|
|
157
|
-
|
|
158
|
-
/* @__PURE__ */
|
|
179
|
+
q(
|
|
180
|
+
/* @__PURE__ */ a(
|
|
159
181
|
"dialog",
|
|
160
182
|
{
|
|
161
|
-
id:
|
|
162
|
-
ref:
|
|
183
|
+
id: $,
|
|
184
|
+
ref: v,
|
|
163
185
|
className: "pco-org-avatar__dialog",
|
|
164
|
-
onClose:
|
|
165
|
-
children: /* @__PURE__ */ n("form", { onSubmit:
|
|
186
|
+
onClose: O,
|
|
187
|
+
children: /* @__PURE__ */ n("form", { onSubmit: T, children: [
|
|
166
188
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar__dialog-header", children: [
|
|
167
189
|
/* @__PURE__ */ n("h1", { className: "pco-org-avatar__dialog-title", children: [
|
|
168
190
|
"Church logo — ",
|
|
169
|
-
|
|
191
|
+
h,
|
|
170
192
|
" mode"
|
|
171
193
|
] }),
|
|
172
|
-
/* @__PURE__ */
|
|
194
|
+
/* @__PURE__ */ a(
|
|
173
195
|
"button",
|
|
174
196
|
{
|
|
175
197
|
type: "button",
|
|
176
|
-
|
|
177
|
-
command: "close",
|
|
198
|
+
onClick: () => v.current?.close(),
|
|
178
199
|
className: "pco-org-avatar__dialog-close",
|
|
179
200
|
"aria-label": "Close modal",
|
|
180
|
-
children: /* @__PURE__ */
|
|
201
|
+
children: /* @__PURE__ */ a(
|
|
181
202
|
"svg",
|
|
182
203
|
{
|
|
183
204
|
width: "16",
|
|
@@ -185,15 +206,15 @@ function D({
|
|
|
185
206
|
viewBox: "0 0 16 16",
|
|
186
207
|
fill: "currentColor",
|
|
187
208
|
"aria-hidden": "true",
|
|
188
|
-
children: /* @__PURE__ */
|
|
209
|
+
children: /* @__PURE__ */ a("path", { d: X })
|
|
189
210
|
}
|
|
190
211
|
)
|
|
191
212
|
}
|
|
192
213
|
)
|
|
193
214
|
] }),
|
|
194
215
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar__dialog-body", children: [
|
|
195
|
-
|
|
196
|
-
/* @__PURE__ */
|
|
216
|
+
g && /* @__PURE__ */ n("div", { role: "alert", className: "pco-org-avatar__dialog-alert", children: [
|
|
217
|
+
/* @__PURE__ */ a(
|
|
197
218
|
"svg",
|
|
198
219
|
{
|
|
199
220
|
width: "16",
|
|
@@ -201,103 +222,117 @@ function D({
|
|
|
201
222
|
viewBox: "0 0 16 16",
|
|
202
223
|
className: "symbol",
|
|
203
224
|
"aria-hidden": "true",
|
|
204
|
-
children: /* @__PURE__ */
|
|
225
|
+
children: /* @__PURE__ */ a("path", { d: H })
|
|
205
226
|
}
|
|
206
227
|
),
|
|
207
|
-
/* @__PURE__ */
|
|
228
|
+
/* @__PURE__ */ a("p", { children: g })
|
|
208
229
|
] }),
|
|
209
|
-
/* @__PURE__ */
|
|
210
|
-
|
|
230
|
+
/* @__PURE__ */ a(
|
|
231
|
+
V,
|
|
211
232
|
{
|
|
212
233
|
accept: { "image/*": [".jpg", ".jpeg", ".png"] },
|
|
213
234
|
multiple: !1,
|
|
214
|
-
onDropAccepted:
|
|
235
|
+
onDropAccepted: P,
|
|
215
236
|
children: ({
|
|
216
|
-
getRootProps:
|
|
217
|
-
getInputProps:
|
|
218
|
-
isFocused:
|
|
237
|
+
getRootProps: p,
|
|
238
|
+
getInputProps: l,
|
|
239
|
+
isFocused: _,
|
|
219
240
|
isDragAccept: j,
|
|
220
|
-
isDragReject:
|
|
221
|
-
isDragActive:
|
|
241
|
+
isDragReject: N,
|
|
242
|
+
isDragActive: U,
|
|
243
|
+
open: S
|
|
222
244
|
}) => {
|
|
223
|
-
const
|
|
245
|
+
const I = Y(
|
|
224
246
|
"pco-org-avatar__dialog-dropzone",
|
|
225
|
-
`pco-org-avatar__dialog-dropzone--${
|
|
247
|
+
`pco-org-avatar__dialog-dropzone--${h}`,
|
|
226
248
|
{
|
|
227
|
-
"pco-org-avatar__dialog-dropzone--image":
|
|
228
|
-
"pco-org-avatar__dialog-dropzone--focused":
|
|
249
|
+
"pco-org-avatar__dialog-dropzone--image": i || f,
|
|
250
|
+
"pco-org-avatar__dialog-dropzone--focused": _,
|
|
229
251
|
"pco-org-avatar__dialog-dropzone--accepted": j,
|
|
230
|
-
"pco-org-avatar__dialog-dropzone--rejected":
|
|
252
|
+
"pco-org-avatar__dialog-dropzone--rejected": U && N
|
|
231
253
|
}
|
|
232
254
|
);
|
|
233
|
-
return /* @__PURE__ */ n(
|
|
234
|
-
/* @__PURE__ */
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
src: a,
|
|
245
|
-
alt: `Church logo for ${o}`
|
|
246
|
-
}
|
|
247
|
-
) : /* @__PURE__ */ n(f, { children: [
|
|
248
|
-
/* @__PURE__ */ e(
|
|
249
|
-
"svg",
|
|
255
|
+
return /* @__PURE__ */ n(u, { children: [
|
|
256
|
+
/* @__PURE__ */ n("div", { ...p({ className: I }), children: [
|
|
257
|
+
/* @__PURE__ */ a("input", { ...l() }),
|
|
258
|
+
i ? /* @__PURE__ */ a(
|
|
259
|
+
"img",
|
|
260
|
+
{
|
|
261
|
+
src: i.preview,
|
|
262
|
+
alt: `Church logo for ${o}`
|
|
263
|
+
}
|
|
264
|
+
) : f ? /* @__PURE__ */ a(
|
|
265
|
+
"img",
|
|
250
266
|
{
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
viewBox: "0 0 16 16",
|
|
254
|
-
"aria-hidden": "true",
|
|
255
|
-
children: /* @__PURE__ */ e("path", { d: q })
|
|
267
|
+
src: f,
|
|
268
|
+
alt: `Church logo for ${o}`
|
|
256
269
|
}
|
|
257
|
-
),
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
270
|
+
) : /* @__PURE__ */ n(u, { children: [
|
|
271
|
+
/* @__PURE__ */ a(
|
|
272
|
+
"svg",
|
|
273
|
+
{
|
|
274
|
+
width: "64",
|
|
275
|
+
height: "64",
|
|
276
|
+
viewBox: "0 0 16 16",
|
|
277
|
+
"aria-hidden": "true",
|
|
278
|
+
children: /* @__PURE__ */ a("path", { d: K })
|
|
279
|
+
}
|
|
280
|
+
),
|
|
281
|
+
U && N ? /* @__PURE__ */ n(u, { children: [
|
|
282
|
+
/* @__PURE__ */ a("h2", { children: "Wrong file type" }),
|
|
283
|
+
/* @__PURE__ */ a("p", { children: "Please upload a PNG or JPG file." })
|
|
284
|
+
] }) : /* @__PURE__ */ n(u, { children: [
|
|
285
|
+
/* @__PURE__ */ a(D, { open: S }),
|
|
286
|
+
/* @__PURE__ */ a("p", { className: "pco-org-avatar__instructions-sub", children: "Use a high-quality image (up to 20mb) with a transparent background." })
|
|
287
|
+
] })
|
|
264
288
|
] })
|
|
265
|
-
] })
|
|
289
|
+
] }),
|
|
290
|
+
(i || f) && /* @__PURE__ */ a(D, { open: S })
|
|
266
291
|
] });
|
|
267
292
|
}
|
|
268
293
|
}
|
|
269
294
|
)
|
|
270
295
|
] }),
|
|
271
296
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar__dialog-actions", children: [
|
|
272
|
-
|
|
273
|
-
|
|
297
|
+
e && h === "light" && /* @__PURE__ */ a(
|
|
298
|
+
k,
|
|
299
|
+
{
|
|
300
|
+
label: "Remove logo",
|
|
301
|
+
kind: "secondary-delete",
|
|
302
|
+
onClick: x,
|
|
303
|
+
loading: c,
|
|
304
|
+
disabled: c || d,
|
|
305
|
+
className: "pco-org-avatar__dialog-delete"
|
|
306
|
+
}
|
|
307
|
+
),
|
|
308
|
+
e && h === "dark" && /* @__PURE__ */ a(
|
|
309
|
+
k,
|
|
274
310
|
{
|
|
275
|
-
label: "
|
|
276
|
-
kind: "
|
|
277
|
-
onClick:
|
|
278
|
-
loading:
|
|
279
|
-
disabled:
|
|
311
|
+
label: "Use light mode logo",
|
|
312
|
+
kind: "secondary",
|
|
313
|
+
onClick: x,
|
|
314
|
+
loading: c,
|
|
315
|
+
disabled: c || d,
|
|
280
316
|
className: "pco-org-avatar__dialog-delete"
|
|
281
317
|
}
|
|
282
318
|
),
|
|
283
|
-
/* @__PURE__ */
|
|
284
|
-
|
|
319
|
+
/* @__PURE__ */ a(
|
|
320
|
+
k,
|
|
285
321
|
{
|
|
286
322
|
type: "button",
|
|
287
323
|
label: "Cancel",
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
disabled: s || h
|
|
324
|
+
onClick: () => v.current?.close(),
|
|
325
|
+
disabled: d || c
|
|
291
326
|
}
|
|
292
327
|
),
|
|
293
|
-
/* @__PURE__ */
|
|
294
|
-
|
|
328
|
+
/* @__PURE__ */ a(
|
|
329
|
+
k,
|
|
295
330
|
{
|
|
296
331
|
type: "submit",
|
|
297
332
|
label: "Update logo",
|
|
298
333
|
kind: "primary",
|
|
299
|
-
loading:
|
|
300
|
-
disabled: !
|
|
334
|
+
loading: d,
|
|
335
|
+
disabled: !i || d || c
|
|
301
336
|
}
|
|
302
337
|
)
|
|
303
338
|
] })
|
|
@@ -308,45 +343,46 @@ function D({
|
|
|
308
343
|
)
|
|
309
344
|
] });
|
|
310
345
|
}
|
|
311
|
-
function
|
|
312
|
-
avatarUrl:
|
|
346
|
+
function ga({
|
|
347
|
+
avatarUrl: e,
|
|
313
348
|
darkModeAvatarUrl: o,
|
|
314
349
|
orgName: r,
|
|
315
350
|
onAvatarUpdate: t,
|
|
316
|
-
pcoEnv:
|
|
317
|
-
readOnly:
|
|
318
|
-
showDarkModeAvatar:
|
|
351
|
+
pcoEnv: s,
|
|
352
|
+
readOnly: y,
|
|
353
|
+
showDarkModeAvatar: R = !1
|
|
319
354
|
}) {
|
|
320
|
-
const [
|
|
355
|
+
const [i, w] = b(e), [d, C] = b(
|
|
321
356
|
o
|
|
322
|
-
),
|
|
323
|
-
|
|
357
|
+
), c = (m, g) => {
|
|
358
|
+
m === "avatar" ? (w(g), t?.("avatar", g)) : m === "dark_mode_avatar" && (C(g), t?.("dark_mode_avatar", g));
|
|
324
359
|
};
|
|
325
360
|
return /* @__PURE__ */ n("div", { className: "pco-org-avatars", children: [
|
|
326
|
-
/* @__PURE__ */
|
|
327
|
-
|
|
361
|
+
/* @__PURE__ */ a(
|
|
362
|
+
F,
|
|
328
363
|
{
|
|
329
|
-
avatarUrl:
|
|
364
|
+
avatarUrl: i,
|
|
330
365
|
organization: r,
|
|
331
366
|
mode: "avatar",
|
|
332
|
-
pcoEnv:
|
|
333
|
-
readOnly:
|
|
334
|
-
onAvatarUpdate:
|
|
367
|
+
pcoEnv: s,
|
|
368
|
+
readOnly: y,
|
|
369
|
+
onAvatarUpdate: c
|
|
335
370
|
}
|
|
336
371
|
),
|
|
337
|
-
|
|
338
|
-
|
|
372
|
+
R && /* @__PURE__ */ a(
|
|
373
|
+
F,
|
|
339
374
|
{
|
|
340
|
-
avatarUrl:
|
|
375
|
+
avatarUrl: d,
|
|
341
376
|
organization: r,
|
|
342
377
|
mode: "dark_mode_avatar",
|
|
343
|
-
pcoEnv:
|
|
344
|
-
readOnly:
|
|
345
|
-
onAvatarUpdate:
|
|
378
|
+
pcoEnv: s,
|
|
379
|
+
readOnly: y,
|
|
380
|
+
onAvatarUpdate: c,
|
|
381
|
+
fallbackAvatarUrl: i
|
|
346
382
|
}
|
|
347
383
|
)
|
|
348
384
|
] });
|
|
349
385
|
}
|
|
350
386
|
export {
|
|
351
|
-
|
|
387
|
+
ga as OrganizationAvatars
|
|
352
388
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { OrganizationAvatarProps } from "./types";
|
|
2
|
-
export declare function OrganizationAvatar({ avatarUrl, organization, mode, pcoEnv, readOnly, onAvatarUpdate, }: OrganizationAvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function OrganizationAvatar({ avatarUrl, organization, mode, pcoEnv, readOnly, onAvatarUpdate, fallbackAvatarUrl, }: OrganizationAvatarProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/style.css
CHANGED
|
@@ -178,19 +178,6 @@
|
|
|
178
178
|
fill: var(--t-icon-color-status-info);
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
.pco-org-avatar__dialog-dropzone h2 {
|
|
182
|
-
color: var(--t-text-color-headline);
|
|
183
|
-
font-size: var(--t-font-size-md);
|
|
184
|
-
font-weight: var(--t-font-weight-normal);
|
|
185
|
-
margin: 0;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
.pco-org-avatar__dialog-dropzone p {
|
|
189
|
-
color: var(--t-text-color-placeholder);
|
|
190
|
-
font-size: var(--t-font-size-sm);
|
|
191
|
-
margin: 0;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
181
|
.pco-org-avatar__dialog-dropzone img {
|
|
195
182
|
max-height: 100%;
|
|
196
183
|
max-width: 100%;
|
|
@@ -222,11 +209,25 @@
|
|
|
222
209
|
fill: var(--t-fill-color-status-error);
|
|
223
210
|
}
|
|
224
211
|
|
|
225
|
-
|
|
212
|
+
.pco-org-avatar__instructions {
|
|
213
|
+
font-size: var(--t-font-size-md);
|
|
214
|
+
font-weight: var(--t-font-weight-normal);
|
|
215
|
+
margin: var(--t-spacing-2) 0 0;
|
|
216
|
+
text-align: center;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.pco-org-avatar__instructions-sub {
|
|
220
|
+
color: var(--t-text-color-secondary);
|
|
221
|
+
font-size: var(--t-font-size-sm);
|
|
222
|
+
margin: 0;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Light/dark colors/backgrounds are hardcoded to match the avatar preview context,
|
|
226
226
|
regardless of the UI theme or whether an avatar is uploaded */
|
|
227
|
+
|
|
227
228
|
.pco-org-avatar__button--light,
|
|
228
229
|
.pco-org-avatar__dialog-dropzone--light {
|
|
229
|
-
background: hsl(0, 0%,
|
|
230
|
+
background: hsl(0, 0%, 97%);
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
.pco-org-avatar__button--light:has(img),
|
|
@@ -243,3 +244,11 @@
|
|
|
243
244
|
.pco-org-avatar__dialog-dropzone--dark:has(img) {
|
|
244
245
|
border-color: transparent;
|
|
245
246
|
}
|
|
247
|
+
|
|
248
|
+
.pco-org-avatar__dialog-dropzone--light .pco-org-avatar__instructions {
|
|
249
|
+
color: hsl(0, 0%, 12%);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.pco-org-avatar__dialog-dropzone--dark .pco-org-avatar__instructions {
|
|
253
|
+
color: hsl(0, 0%, 94%);
|
|
254
|
+
}
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/organization-avatars",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Organization avatar upload components for Planning Center apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "yarn@1.22.22",
|
|
@@ -31,14 +31,19 @@
|
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@planningcenter/icons": "^15.29.1",
|
|
34
|
+
"@planningcenter/sweetest-alert": "^1.0.1",
|
|
34
35
|
"@planningcenter/tapestry": "^2.10.1",
|
|
35
36
|
"@planningcenter/url": "^3.2.0",
|
|
36
37
|
"react": "^18.3.0",
|
|
37
38
|
"react-dom": "^18.3.0",
|
|
38
39
|
"react-dropzone": "^14.0.0"
|
|
39
40
|
},
|
|
41
|
+
"prettier": {
|
|
42
|
+
"semi": false
|
|
43
|
+
},
|
|
40
44
|
"devDependencies": {
|
|
41
45
|
"@planningcenter/icons": "^15.29.1",
|
|
46
|
+
"@planningcenter/sweetest-alert": "^1.0.1",
|
|
42
47
|
"@planningcenter/tapestry": "^2.10.1",
|
|
43
48
|
"@planningcenter/url": "^3.2.0",
|
|
44
49
|
"@types/react": "^18.3.0",
|