@planningcenter/organization-avatars 1.4.0 → 1.6.2
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 +7 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +161 -144
- package/dist/organization_avatar.d.ts +1 -1
- package/dist/organization_avatars.d.ts +1 -1
- package/dist/style.css +24 -6
- package/dist/types.d.ts +6 -2
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -2,10 +2,16 @@
|
|
|
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/
|
|
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
|
+
## Usage
|
|
6
8
|
|
|
7
9
|
If no `darkModeAvatarUrl` is provided, the `avatarUrl` will be rendered with dark styles in the dark mode avatar's UI slot.
|
|
8
10
|
|
|
9
11
|
The `showDarkModeAvatar` prop gates the rendering of the dark mode avatar UI. It is intended to be controlled by a feature flag, and will eventually be removed when dark mode avatars have been rolled out.
|
|
10
12
|
|
|
11
13
|
To see an example of how this package can be used, 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).
|
|
14
|
+
|
|
15
|
+
## Development
|
|
16
|
+
|
|
17
|
+
`yarn dev` — Start a local demo app at http://localhost:5173 for interactive testing (API is mocked)
|
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"),l=require("react"),B=require("react-dom"),M=require("@planningcenter/url"),C=require("@planningcenter/tapestry"),j=require("@planningcenter/icons/paths/general"),O=require("@planningcenter/icons/paths/services"),P=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 c=a.length;for(o=0;o<c;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 T(){for(var a,o,t=0,r="",c=arguments.length;t<c;t++)(a=arguments[t])&&(o=z(a))&&(r&&(r+=" "),r+=o);return r}function $(){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 L(a){const o=a.split("");return[o.shift()?.toUpperCase(),o.join("")].join("")}const I=a=>a==="dark_mode_avatar"?"dark":"light";function S({avatarUrl:a,organization:o,mode:t,pcoEnv:r,readOnly:c,onAvatarUpdate:v}){const[s,p]=l.useState(null),[d,x]=l.useState(!1),[u,f]=l.useState(!1),[_,h]=l.useState(""),i=l.useId(),k=l.useRef(null),b=I(t),F=g=>{const[n]=g;n&&p(Object.assign(n,{preview:URL.createObjectURL(n)}))};l.useEffect(()=>()=>{s?.preview&&(URL.revokeObjectURL(s.preview),h(""))},[s]);const N=async g=>{const n=await fetch(M.pcoApiUrl("accounts",{env:r}),{method:"PATCH",headers:{"Content-Type":"application/json","X-CSRF-Token":$(),Accept:"application/json"},body:JSON.stringify({data:{attributes:g}})}),m=await n.json();if(!n.ok)throw m;return m},R=async g=>{if(g.preventDefault(),!(!s||d||u)){x(!0);try{const n=new FileReader,m=await new Promise((y,w)=>{n.onloadend=()=>y(n.result),n.onerror=w,n.readAsDataURL(s)}),A=await N({[t]:m,[`${t}_cache`]:""});p(null),v(t,A.data.attributes[t].url),k.current?.close()}catch{h("We were unable to save your avatar.")}finally{x(!1)}}},U=async()=>{if(!(d||u)){f(!0);try{await N({[`remove_${t}`]:"1"}),v(t,""),k.current?.close()}catch{h("We were unable to delete your avatar.")}finally{f(!1)}}},q=()=>{p(null),h("")};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"pco-org-avatar",children:[e.jsx("button",{type:"button",commandfor:i,command:"show-modal",disabled:c,className:`pco-org-avatar__button pco-org-avatar__button--${b}`,children:a?e.jsxs(e.Fragment,{children:[e.jsx("img",{src:a,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:j.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:O.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:j.pencil})})})]})}),e.jsxs("div",{className:"pco-org-avatar__label",children:[L(b)," mode"]})]}),B.createPortal(e.jsx("dialog",{id:i,ref:k,className:"pco-org-avatar__dialog",onClose:q,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 — ",b," mode"]}),e.jsx("button",{type:"button",commandfor:i,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:j.smallX})})})]}),e.jsxs("div",{className:"pco-org-avatar__dialog-body",children:[_&&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:j.exclamationTriangle})}),e.jsx("p",{children:_})]}),e.jsx(P,{accept:{"image/*":[".jpg",".jpeg",".png"]},multiple:!1,onDropAccepted:F,children:({getRootProps:g,getInputProps:n,isFocused:m,isDragAccept:A,isDragReject:y,isDragActive:w})=>{const D=T("pco-org-avatar__dialog-dropzone",`pco-org-avatar__dialog-dropzone--${b}`,{"pco-org-avatar__dialog-dropzone--image":s||a,"pco-org-avatar__dialog-dropzone--focused":m,"pco-org-avatar__dialog-dropzone--accepted":A,"pco-org-avatar__dialog-dropzone--rejected":w&&y});return e.jsxs("div",{...g({className:D}),children:[e.jsx("input",{...n()}),s?e.jsx("img",{src:s.preview,alt:`Church logo for ${o}`}):a?e.jsx("img",{src:a,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:j.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:[a&&e.jsx(C.Button,{label:"Delete logo",kind:"delete",onClick:U,loading:u,disabled:u||d,className:"pco-org-avatar__dialog-delete"}),e.jsx(C.Button,{type:"button",label:"Cancel",commandfor:i,command:"close",disabled:d||u}),e.jsx(C.Button,{type:"submit",label:"Update logo",kind:"primary",loading:d,disabled:!s||d||u})]})]})}),document.body)]})}function E({avatarUrl:a,darkModeAvatarUrl:o,orgName:t,onAvatarUpdate:r,pcoEnv:c,readOnly:v,showDarkModeAvatar:s=!1}){const[p,d]=l.useState(a),[x,u]=l.useState(o),f=(h,i)=>{h==="avatar"?(d(i),r?.("avatar",i)):h==="dark_mode_avatar"&&(u(i),r?.("dark_mode_avatar",i))},_=x||p;return e.jsxs("div",{className:"pco-org-avatars",children:[e.jsx(S,{avatarUrl:p,organization:t,mode:"avatar",pcoEnv:c,readOnly:v,onAvatarUpdate:f}),s&&e.jsx(S,{avatarUrl:_,organization:t,mode:"dark_mode_avatar",pcoEnv:c,readOnly:v,onAvatarUpdate:f})]})}exports.OrganizationAvatars=E;
|
package/dist/index.js
CHANGED
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
import { jsxs as n, Fragment as
|
|
2
|
-
import { useState as
|
|
1
|
+
import { jsxs as n, Fragment as f, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { useState as v, useId as O, useRef as P, useEffect as T } from "react";
|
|
3
3
|
import { createPortal as L } from "react-dom";
|
|
4
4
|
import { pcoApiUrl as I } from "@planningcenter/url";
|
|
5
|
-
import { Button as
|
|
6
|
-
import { pencil as
|
|
7
|
-
import { image as
|
|
8
|
-
import
|
|
9
|
-
function
|
|
5
|
+
import { Button as z } from "@planningcenter/tapestry";
|
|
6
|
+
import { pencil as x, smallX as E, exclamationTriangle as W, toCloudArrow as q } from "@planningcenter/icons/paths/general";
|
|
7
|
+
import { image as G } from "@planningcenter/icons/paths/services";
|
|
8
|
+
import J from "react-dropzone";
|
|
9
|
+
function R(a) {
|
|
10
10
|
var o, r, t = "";
|
|
11
|
-
if (typeof
|
|
12
|
-
else if (typeof
|
|
13
|
-
var
|
|
14
|
-
for (o = 0; o <
|
|
15
|
-
} else for (r in
|
|
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 (o = 0; o < d; o++) a[o] && (r = R(a[o])) && (t && (t += " "), t += r);
|
|
15
|
+
} else for (r in a) a[r] && (t && (t += " "), t += r);
|
|
16
16
|
return t;
|
|
17
17
|
}
|
|
18
|
-
function
|
|
19
|
-
for (var
|
|
18
|
+
function X() {
|
|
19
|
+
for (var a, o, r = 0, t = "", d = arguments.length; r < d; r++) (a = arguments[r]) && (o = R(a)) && (t && (t += " "), t += o);
|
|
20
20
|
return t;
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
const
|
|
24
|
-
if (!
|
|
22
|
+
function H() {
|
|
23
|
+
const a = document.querySelector('meta[name="csrf-token"]');
|
|
24
|
+
if (!a || !a.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
|
|
28
|
+
return a.content;
|
|
29
29
|
}
|
|
30
|
-
function
|
|
31
|
-
const o =
|
|
30
|
+
function K(a) {
|
|
31
|
+
const o = a.split("");
|
|
32
32
|
return [o.shift()?.toUpperCase(), o.join("")].join("");
|
|
33
33
|
}
|
|
34
|
-
const
|
|
35
|
-
function
|
|
36
|
-
avatarUrl:
|
|
34
|
+
const Q = (a) => a === "dark_mode_avatar" ? "dark" : "light";
|
|
35
|
+
function D({
|
|
36
|
+
avatarUrl: a,
|
|
37
37
|
organization: o,
|
|
38
38
|
mode: r,
|
|
39
39
|
pcoEnv: t,
|
|
40
|
-
|
|
40
|
+
readOnly: d,
|
|
41
|
+
onAvatarUpdate: _
|
|
41
42
|
}) {
|
|
42
|
-
const [l,
|
|
43
|
-
const [i] =
|
|
44
|
-
i &&
|
|
43
|
+
const [l, u] = v(null), [s, y] = v(!1), [h, b] = v(!1), [A, p] = v(""), c = O(), N = P(null), w = Q(r), M = (g) => {
|
|
44
|
+
const [i] = g;
|
|
45
|
+
i && u(
|
|
45
46
|
Object.assign(i, {
|
|
46
47
|
preview: URL.createObjectURL(i)
|
|
47
48
|
})
|
|
48
49
|
);
|
|
49
50
|
};
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}, [e]), D(() => () => {
|
|
53
|
-
l?.preview && (URL.revokeObjectURL(l.preview), b(""));
|
|
51
|
+
T(() => () => {
|
|
52
|
+
l?.preview && (URL.revokeObjectURL(l.preview), p(""));
|
|
54
53
|
}, [l]);
|
|
55
|
-
const
|
|
54
|
+
const U = async (g) => {
|
|
56
55
|
const i = await fetch(I("accounts", { env: t }), {
|
|
57
56
|
method: "PATCH",
|
|
58
57
|
headers: {
|
|
59
58
|
"Content-Type": "application/json",
|
|
60
|
-
"X-CSRF-Token":
|
|
59
|
+
"X-CSRF-Token": H(),
|
|
61
60
|
Accept: "application/json"
|
|
62
61
|
},
|
|
63
62
|
body: JSON.stringify({
|
|
64
63
|
data: {
|
|
65
|
-
attributes:
|
|
64
|
+
attributes: g
|
|
66
65
|
}
|
|
67
66
|
})
|
|
68
|
-
}),
|
|
69
|
-
if (!i.ok) throw
|
|
70
|
-
return
|
|
71
|
-
},
|
|
72
|
-
if (
|
|
73
|
-
|
|
67
|
+
}), m = await i.json();
|
|
68
|
+
if (!i.ok) throw m;
|
|
69
|
+
return m;
|
|
70
|
+
}, S = async (g) => {
|
|
71
|
+
if (g.preventDefault(), !(!l || s || h)) {
|
|
72
|
+
y(!0);
|
|
74
73
|
try {
|
|
75
|
-
const i = new FileReader(),
|
|
76
|
-
i.onloadend = () =>
|
|
77
|
-
}),
|
|
78
|
-
[r]:
|
|
74
|
+
const i = new FileReader(), m = await new Promise((k, C) => {
|
|
75
|
+
i.onloadend = () => k(i.result), i.onerror = C, i.readAsDataURL(l);
|
|
76
|
+
}), j = await U({
|
|
77
|
+
[r]: m,
|
|
79
78
|
[`${r}_cache`]: ""
|
|
80
79
|
});
|
|
81
|
-
|
|
80
|
+
u(null), _(r, j.data.attributes[r].url), N.current?.close();
|
|
82
81
|
} catch {
|
|
83
|
-
|
|
82
|
+
p("We were unable to save your avatar.");
|
|
84
83
|
} finally {
|
|
85
|
-
|
|
84
|
+
y(!1);
|
|
86
85
|
}
|
|
87
86
|
}
|
|
88
|
-
},
|
|
89
|
-
if (!(
|
|
90
|
-
|
|
87
|
+
}, F = async () => {
|
|
88
|
+
if (!(s || h)) {
|
|
89
|
+
b(!0);
|
|
91
90
|
try {
|
|
92
|
-
await
|
|
91
|
+
await U({
|
|
93
92
|
[`remove_${r}`]: "1"
|
|
94
|
-
}),
|
|
93
|
+
}), _(r, ""), N.current?.close();
|
|
95
94
|
} catch {
|
|
96
|
-
|
|
95
|
+
p("We were unable to delete your avatar.");
|
|
97
96
|
} finally {
|
|
98
|
-
|
|
97
|
+
b(!1);
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
|
-
},
|
|
102
|
-
|
|
100
|
+
}, B = () => {
|
|
101
|
+
u(null), p("");
|
|
103
102
|
};
|
|
104
|
-
return /* @__PURE__ */ n(
|
|
103
|
+
return /* @__PURE__ */ n(f, { children: [
|
|
105
104
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar", children: [
|
|
106
|
-
/* @__PURE__ */
|
|
105
|
+
/* @__PURE__ */ e(
|
|
107
106
|
"button",
|
|
108
107
|
{
|
|
109
108
|
type: "button",
|
|
110
|
-
commandfor:
|
|
109
|
+
commandfor: c,
|
|
111
110
|
command: "show-modal",
|
|
111
|
+
disabled: d,
|
|
112
112
|
className: `pco-org-avatar__button pco-org-avatar__button--${w}`,
|
|
113
|
-
children:
|
|
114
|
-
/* @__PURE__ */
|
|
115
|
-
/* @__PURE__ */
|
|
113
|
+
children: a ? /* @__PURE__ */ n(f, { children: [
|
|
114
|
+
/* @__PURE__ */ e("img", { src: a, alt: `Church logo for ${o}` }),
|
|
115
|
+
/* @__PURE__ */ e("div", { className: "tds-btn tds-btn--interaction tds-btn--icononly", children: /* @__PURE__ */ e(
|
|
116
116
|
"svg",
|
|
117
117
|
{
|
|
118
118
|
width: "14",
|
|
@@ -120,51 +120,64 @@ function R({
|
|
|
120
120
|
viewBox: "0 0 16 16",
|
|
121
121
|
fill: "currentColor",
|
|
122
122
|
"aria-hidden": "true",
|
|
123
|
-
children: /* @__PURE__ */
|
|
123
|
+
children: /* @__PURE__ */ e("path", { d: x })
|
|
124
124
|
}
|
|
125
125
|
) })
|
|
126
|
-
] }) : /* @__PURE__ */
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
126
|
+
] }) : /* @__PURE__ */ n(f, { children: [
|
|
127
|
+
/* @__PURE__ */ e(
|
|
128
|
+
"svg",
|
|
129
|
+
{
|
|
130
|
+
width: "48",
|
|
131
|
+
height: "48",
|
|
132
|
+
viewBox: "0 0 16 16",
|
|
133
|
+
fill: "currentColor",
|
|
134
|
+
"aria-hidden": "true",
|
|
135
|
+
children: /* @__PURE__ */ e("path", { d: G })
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
/* @__PURE__ */ e("div", { className: "tds-btn tds-btn--interaction tds-btn--icononly", children: /* @__PURE__ */ e(
|
|
139
|
+
"svg",
|
|
140
|
+
{
|
|
141
|
+
width: "14",
|
|
142
|
+
height: "14",
|
|
143
|
+
viewBox: "0 0 16 16",
|
|
144
|
+
fill: "currentColor",
|
|
145
|
+
"aria-hidden": "true",
|
|
146
|
+
children: /* @__PURE__ */ e("path", { d: x })
|
|
147
|
+
}
|
|
148
|
+
) })
|
|
149
|
+
] })
|
|
137
150
|
}
|
|
138
151
|
),
|
|
139
152
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar__label", children: [
|
|
140
|
-
|
|
153
|
+
K(w),
|
|
141
154
|
" mode"
|
|
142
155
|
] })
|
|
143
156
|
] }),
|
|
144
157
|
L(
|
|
145
|
-
/* @__PURE__ */
|
|
158
|
+
/* @__PURE__ */ e(
|
|
146
159
|
"dialog",
|
|
147
160
|
{
|
|
148
|
-
id:
|
|
161
|
+
id: c,
|
|
149
162
|
ref: N,
|
|
150
163
|
className: "pco-org-avatar__dialog",
|
|
151
|
-
onClose:
|
|
152
|
-
children: /* @__PURE__ */ n("form", { onSubmit:
|
|
164
|
+
onClose: B,
|
|
165
|
+
children: /* @__PURE__ */ n("form", { onSubmit: S, children: [
|
|
153
166
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar__dialog-header", children: [
|
|
154
167
|
/* @__PURE__ */ n("h1", { className: "pco-org-avatar__dialog-title", children: [
|
|
155
168
|
"Church logo — ",
|
|
156
169
|
w,
|
|
157
170
|
" mode"
|
|
158
171
|
] }),
|
|
159
|
-
/* @__PURE__ */
|
|
172
|
+
/* @__PURE__ */ e(
|
|
160
173
|
"button",
|
|
161
174
|
{
|
|
162
175
|
type: "button",
|
|
163
|
-
commandfor:
|
|
176
|
+
commandfor: c,
|
|
164
177
|
command: "close",
|
|
165
178
|
className: "pco-org-avatar__dialog-close",
|
|
166
179
|
"aria-label": "Close modal",
|
|
167
|
-
children: /* @__PURE__ */
|
|
180
|
+
children: /* @__PURE__ */ e(
|
|
168
181
|
"svg",
|
|
169
182
|
{
|
|
170
183
|
width: "16",
|
|
@@ -172,15 +185,15 @@ function R({
|
|
|
172
185
|
viewBox: "0 0 16 16",
|
|
173
186
|
fill: "currentColor",
|
|
174
187
|
"aria-hidden": "true",
|
|
175
|
-
children: /* @__PURE__ */
|
|
188
|
+
children: /* @__PURE__ */ e("path", { d: E })
|
|
176
189
|
}
|
|
177
190
|
)
|
|
178
191
|
}
|
|
179
192
|
)
|
|
180
193
|
] }),
|
|
181
194
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar__dialog-body", children: [
|
|
182
|
-
|
|
183
|
-
/* @__PURE__ */
|
|
195
|
+
A && /* @__PURE__ */ n("div", { role: "alert", className: "pco-org-avatar__dialog-alert", children: [
|
|
196
|
+
/* @__PURE__ */ e(
|
|
184
197
|
"svg",
|
|
185
198
|
{
|
|
186
199
|
width: "16",
|
|
@@ -188,66 +201,66 @@ function R({
|
|
|
188
201
|
viewBox: "0 0 16 16",
|
|
189
202
|
className: "symbol",
|
|
190
203
|
"aria-hidden": "true",
|
|
191
|
-
children: /* @__PURE__ */
|
|
204
|
+
children: /* @__PURE__ */ e("path", { d: W })
|
|
192
205
|
}
|
|
193
206
|
),
|
|
194
|
-
/* @__PURE__ */
|
|
207
|
+
/* @__PURE__ */ e("p", { children: A })
|
|
195
208
|
] }),
|
|
196
|
-
/* @__PURE__ */
|
|
197
|
-
|
|
209
|
+
/* @__PURE__ */ e(
|
|
210
|
+
J,
|
|
198
211
|
{
|
|
199
212
|
accept: { "image/*": [".jpg", ".jpeg", ".png"] },
|
|
200
213
|
multiple: !1,
|
|
201
|
-
onDropAccepted:
|
|
214
|
+
onDropAccepted: M,
|
|
202
215
|
children: ({
|
|
203
|
-
getRootProps:
|
|
216
|
+
getRootProps: g,
|
|
204
217
|
getInputProps: i,
|
|
205
|
-
isFocused:
|
|
206
|
-
isDragAccept:
|
|
207
|
-
isDragReject:
|
|
218
|
+
isFocused: m,
|
|
219
|
+
isDragAccept: j,
|
|
220
|
+
isDragReject: k,
|
|
208
221
|
isDragActive: C
|
|
209
222
|
}) => {
|
|
210
|
-
const
|
|
223
|
+
const $ = X(
|
|
211
224
|
"pco-org-avatar__dialog-dropzone",
|
|
212
225
|
`pco-org-avatar__dialog-dropzone--${w}`,
|
|
213
226
|
{
|
|
214
|
-
"pco-org-avatar__dialog-dropzone--image": l ||
|
|
215
|
-
"pco-org-avatar__dialog-dropzone--focused":
|
|
216
|
-
"pco-org-avatar__dialog-dropzone--accepted":
|
|
217
|
-
"pco-org-avatar__dialog-dropzone--rejected": C &&
|
|
227
|
+
"pco-org-avatar__dialog-dropzone--image": l || a,
|
|
228
|
+
"pco-org-avatar__dialog-dropzone--focused": m,
|
|
229
|
+
"pco-org-avatar__dialog-dropzone--accepted": j,
|
|
230
|
+
"pco-org-avatar__dialog-dropzone--rejected": C && k
|
|
218
231
|
}
|
|
219
232
|
);
|
|
220
|
-
return /* @__PURE__ */ n("div", { ...
|
|
221
|
-
/* @__PURE__ */
|
|
222
|
-
l ? /* @__PURE__ */
|
|
233
|
+
return /* @__PURE__ */ n("div", { ...g({ className: $ }), children: [
|
|
234
|
+
/* @__PURE__ */ e("input", { ...i() }),
|
|
235
|
+
l ? /* @__PURE__ */ e(
|
|
223
236
|
"img",
|
|
224
237
|
{
|
|
225
238
|
src: l.preview,
|
|
226
239
|
alt: `Church logo for ${o}`
|
|
227
240
|
}
|
|
228
|
-
) :
|
|
241
|
+
) : a ? /* @__PURE__ */ e(
|
|
229
242
|
"img",
|
|
230
243
|
{
|
|
231
|
-
src:
|
|
244
|
+
src: a,
|
|
232
245
|
alt: `Church logo for ${o}`
|
|
233
246
|
}
|
|
234
|
-
) : /* @__PURE__ */ n(
|
|
235
|
-
/* @__PURE__ */
|
|
247
|
+
) : /* @__PURE__ */ n(f, { children: [
|
|
248
|
+
/* @__PURE__ */ e(
|
|
236
249
|
"svg",
|
|
237
250
|
{
|
|
238
251
|
width: "64",
|
|
239
252
|
height: "64",
|
|
240
253
|
viewBox: "0 0 16 16",
|
|
241
254
|
"aria-hidden": "true",
|
|
242
|
-
children: /* @__PURE__ */
|
|
255
|
+
children: /* @__PURE__ */ e("path", { d: q })
|
|
243
256
|
}
|
|
244
257
|
),
|
|
245
|
-
C &&
|
|
246
|
-
/* @__PURE__ */
|
|
247
|
-
/* @__PURE__ */
|
|
248
|
-
] }) : /* @__PURE__ */ n(
|
|
249
|
-
/* @__PURE__ */
|
|
250
|
-
/* @__PURE__ */
|
|
258
|
+
C && k ? /* @__PURE__ */ n(f, { children: [
|
|
259
|
+
/* @__PURE__ */ e("h2", { children: "Wrong file type" }),
|
|
260
|
+
/* @__PURE__ */ e("p", { children: "Please upload a PNG or JPG file." })
|
|
261
|
+
] }) : /* @__PURE__ */ n(f, { children: [
|
|
262
|
+
/* @__PURE__ */ e("h2", { children: "Add church logo" }),
|
|
263
|
+
/* @__PURE__ */ e("p", { children: "Use a high-quality image (up to 20mb) with a transparent background." })
|
|
251
264
|
] })
|
|
252
265
|
] })
|
|
253
266
|
] });
|
|
@@ -256,35 +269,35 @@ function R({
|
|
|
256
269
|
)
|
|
257
270
|
] }),
|
|
258
271
|
/* @__PURE__ */ n("div", { className: "pco-org-avatar__dialog-actions", children: [
|
|
259
|
-
|
|
260
|
-
|
|
272
|
+
a && /* @__PURE__ */ e(
|
|
273
|
+
z,
|
|
261
274
|
{
|
|
262
275
|
label: "Delete logo",
|
|
263
276
|
kind: "delete",
|
|
264
|
-
onClick:
|
|
265
|
-
loading:
|
|
266
|
-
disabled:
|
|
277
|
+
onClick: F,
|
|
278
|
+
loading: h,
|
|
279
|
+
disabled: h || s,
|
|
267
280
|
className: "pco-org-avatar__dialog-delete"
|
|
268
281
|
}
|
|
269
282
|
),
|
|
270
|
-
/* @__PURE__ */
|
|
271
|
-
|
|
283
|
+
/* @__PURE__ */ e(
|
|
284
|
+
z,
|
|
272
285
|
{
|
|
273
286
|
type: "button",
|
|
274
287
|
label: "Cancel",
|
|
275
|
-
commandfor:
|
|
288
|
+
commandfor: c,
|
|
276
289
|
command: "close",
|
|
277
|
-
disabled:
|
|
290
|
+
disabled: s || h
|
|
278
291
|
}
|
|
279
292
|
),
|
|
280
|
-
/* @__PURE__ */
|
|
281
|
-
|
|
293
|
+
/* @__PURE__ */ e(
|
|
294
|
+
z,
|
|
282
295
|
{
|
|
283
296
|
type: "submit",
|
|
284
297
|
label: "Update logo",
|
|
285
298
|
kind: "primary",
|
|
286
|
-
loading:
|
|
287
|
-
disabled: !l ||
|
|
299
|
+
loading: s,
|
|
300
|
+
disabled: !l || s || h
|
|
288
301
|
}
|
|
289
302
|
)
|
|
290
303
|
] })
|
|
@@ -295,41 +308,45 @@ function R({
|
|
|
295
308
|
)
|
|
296
309
|
] });
|
|
297
310
|
}
|
|
298
|
-
function
|
|
299
|
-
avatarUrl:
|
|
311
|
+
function ne({
|
|
312
|
+
avatarUrl: a,
|
|
300
313
|
darkModeAvatarUrl: o,
|
|
301
314
|
orgName: r,
|
|
302
|
-
|
|
303
|
-
|
|
315
|
+
onAvatarUpdate: t,
|
|
316
|
+
pcoEnv: d,
|
|
317
|
+
readOnly: _,
|
|
318
|
+
showDarkModeAvatar: l = !1
|
|
304
319
|
}) {
|
|
305
|
-
const [
|
|
320
|
+
const [u, s] = v(a), [y, h] = v(
|
|
306
321
|
o
|
|
307
|
-
),
|
|
308
|
-
|
|
322
|
+
), b = (p, c) => {
|
|
323
|
+
p === "avatar" ? (s(c), t?.("avatar", c)) : p === "dark_mode_avatar" && (h(c), t?.("dark_mode_avatar", c));
|
|
309
324
|
};
|
|
310
325
|
return /* @__PURE__ */ n("div", { className: "pco-org-avatars", children: [
|
|
311
|
-
/* @__PURE__ */
|
|
312
|
-
|
|
326
|
+
/* @__PURE__ */ e(
|
|
327
|
+
D,
|
|
313
328
|
{
|
|
314
|
-
avatarUrl:
|
|
329
|
+
avatarUrl: u,
|
|
315
330
|
organization: r,
|
|
316
331
|
mode: "avatar",
|
|
317
|
-
pcoEnv:
|
|
318
|
-
|
|
332
|
+
pcoEnv: d,
|
|
333
|
+
readOnly: _,
|
|
334
|
+
onAvatarUpdate: b
|
|
319
335
|
}
|
|
320
336
|
),
|
|
321
|
-
|
|
322
|
-
|
|
337
|
+
l && /* @__PURE__ */ e(
|
|
338
|
+
D,
|
|
323
339
|
{
|
|
324
|
-
avatarUrl:
|
|
340
|
+
avatarUrl: y || u,
|
|
325
341
|
organization: r,
|
|
326
342
|
mode: "dark_mode_avatar",
|
|
327
|
-
pcoEnv:
|
|
328
|
-
|
|
343
|
+
pcoEnv: d,
|
|
344
|
+
readOnly: _,
|
|
345
|
+
onAvatarUpdate: b
|
|
329
346
|
}
|
|
330
347
|
)
|
|
331
348
|
] });
|
|
332
349
|
}
|
|
333
350
|
export {
|
|
334
|
-
|
|
351
|
+
ne as OrganizationAvatars
|
|
335
352
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { OrganizationAvatarProps } from "./types";
|
|
2
|
-
export declare function OrganizationAvatar({ avatarUrl, organization, mode, pcoEnv, onAvatarUpdate, }: OrganizationAvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function OrganizationAvatar({ avatarUrl, organization, mode, pcoEnv, readOnly, onAvatarUpdate, }: OrganizationAvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { OrganizationAvatarsProps } from "./types";
|
|
2
|
-
export declare function OrganizationAvatars({ avatarUrl: initialAvatarUrl, darkModeAvatarUrl: initialDarkModeAvatarUrl, orgName, pcoEnv, showDarkModeAvatar, }: OrganizationAvatarsProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function OrganizationAvatars({ avatarUrl: initialAvatarUrl, darkModeAvatarUrl: initialDarkModeAvatarUrl, orgName, onAvatarUpdate, pcoEnv, readOnly, showDarkModeAvatar, }: OrganizationAvatarsProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/style.css
CHANGED
|
@@ -38,12 +38,22 @@
|
|
|
38
38
|
visibility: hidden;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
.pco-org-avatar__button:hover div,
|
|
42
|
-
.pco-org-avatar__button:focus-visible div {
|
|
41
|
+
.pco-org-avatar__button:not(:disabled):hover div,
|
|
42
|
+
.pco-org-avatar__button:not(:disabled):focus-visible div {
|
|
43
43
|
opacity: 1;
|
|
44
44
|
visibility: visible;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
.pco-org-avatar__button:not(:has(img)):not(:disabled):hover,
|
|
48
|
+
.pco-org-avatar__button:not(:has(img)):not(:disabled):focus-visible {
|
|
49
|
+
border-color: var(--t-fill-color-interaction);
|
|
50
|
+
border-style: solid;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.pco-org-avatar__button:disabled {
|
|
54
|
+
cursor: not-allowed;
|
|
55
|
+
}
|
|
56
|
+
|
|
47
57
|
.pco-org-avatar__label {
|
|
48
58
|
color: var(--t-text-color-secondary);
|
|
49
59
|
font-size: var(--t-font-size-sm);
|
|
@@ -212,16 +222,24 @@
|
|
|
212
222
|
fill: var(--t-fill-color-status-error);
|
|
213
223
|
}
|
|
214
224
|
|
|
215
|
-
/* Light
|
|
225
|
+
/* Light/dark backgrounds are hardcoded to match the avatar preview context,
|
|
226
|
+
regardless of the UI theme or whether an avatar is uploaded */
|
|
227
|
+
.pco-org-avatar__button--light,
|
|
228
|
+
.pco-org-avatar__dialog-dropzone--light {
|
|
229
|
+
background: hsl(0, 0%, 100%);
|
|
230
|
+
}
|
|
231
|
+
|
|
216
232
|
.pco-org-avatar__button--light:has(img),
|
|
217
233
|
.pco-org-avatar__dialog-dropzone--light:has(img) {
|
|
218
|
-
background: hsl(0, 0%, 100%);
|
|
219
234
|
border-color: transparent;
|
|
220
235
|
}
|
|
221
236
|
|
|
222
|
-
|
|
237
|
+
.pco-org-avatar__button--dark,
|
|
238
|
+
.pco-org-avatar__dialog-dropzone--dark {
|
|
239
|
+
background: hsl(0, 0%, 12%);
|
|
240
|
+
}
|
|
241
|
+
|
|
223
242
|
.pco-org-avatar__button--dark:has(img),
|
|
224
243
|
.pco-org-avatar__dialog-dropzone--dark:has(img) {
|
|
225
|
-
background: hsl(0, 0%, 12%);
|
|
226
244
|
border-color: transparent;
|
|
227
245
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import type { Environment } from "@planningcenter/url";
|
|
2
|
+
export type AvatarMode = "avatar" | "dark_mode_avatar";
|
|
2
3
|
export type OrganizationAvatarsProps = {
|
|
3
4
|
avatarUrl?: string;
|
|
4
5
|
darkModeAvatarUrl?: string;
|
|
5
6
|
orgName: string;
|
|
7
|
+
onAvatarUpdate?: (mode: AvatarMode, newUrl: string) => void;
|
|
6
8
|
pcoEnv?: Environment;
|
|
9
|
+
readOnly?: boolean;
|
|
7
10
|
showDarkModeAvatar?: boolean;
|
|
8
11
|
};
|
|
9
12
|
export type OrganizationAvatarProps = {
|
|
10
13
|
avatarUrl?: string;
|
|
11
14
|
organization: string;
|
|
12
|
-
mode:
|
|
15
|
+
mode: AvatarMode;
|
|
13
16
|
pcoEnv?: Environment;
|
|
14
|
-
|
|
17
|
+
readOnly?: boolean;
|
|
18
|
+
onAvatarUpdate: (attrName: AvatarMode, newUrl: string) => void;
|
|
15
19
|
};
|
|
16
20
|
export type FileWithPreview = File & {
|
|
17
21
|
preview: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/organization-avatars",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Organization avatar upload components for Planning Center apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "yarn@1.22.22",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"README.md"
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
|
+
"dev": "vite --config vite.demo.config.ts",
|
|
23
24
|
"build": "rm -rf dist/ && vite build && tsc && cp src/organization_avatar.css dist/style.css",
|
|
24
25
|
"lint": "eslint src",
|
|
25
26
|
"lint:fix": "eslint src --fix",
|
|
@@ -29,17 +30,17 @@
|
|
|
29
30
|
"clsx": "^2.1.1"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {
|
|
32
|
-
"@planningcenter/icons": "^15.
|
|
33
|
-
"@planningcenter/tapestry": "^2.
|
|
34
|
-
"@planningcenter/url": "^3.
|
|
33
|
+
"@planningcenter/icons": "^15.29.1",
|
|
34
|
+
"@planningcenter/tapestry": "^2.10.1",
|
|
35
|
+
"@planningcenter/url": "^3.2.0",
|
|
35
36
|
"react": "^18.3.0",
|
|
36
37
|
"react-dom": "^18.3.0",
|
|
37
38
|
"react-dropzone": "^14.0.0"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
|
-
"@planningcenter/icons": "^15.
|
|
41
|
-
"@planningcenter/tapestry": "^2.
|
|
42
|
-
"@planningcenter/url": "^3.
|
|
41
|
+
"@planningcenter/icons": "^15.29.1",
|
|
42
|
+
"@planningcenter/tapestry": "^2.10.1",
|
|
43
|
+
"@planningcenter/url": "^3.2.0",
|
|
43
44
|
"@types/react": "^18.3.0",
|
|
44
45
|
"@types/react-dom": "^18.3.0",
|
|
45
46
|
"@typescript-eslint/eslint-plugin": "^8.54.0",
|