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