jvetrau-ds 0.1.43 → 0.1.45
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/components/avatar/avatar.cjs +12 -2
- package/components/avatar/avatar.cjs.map +1 -1
- package/components/avatar/avatar.js +8 -2
- package/components/avatar/avatar.js.map +1 -1
- package/components/avatar-upload/avatar-upload.cjs +116 -0
- package/components/avatar-upload/avatar-upload.cjs.map +1 -0
- package/components/avatar-upload/avatar-upload.css +89 -0
- package/components/avatar-upload/avatar-upload.d.ts +15 -0
- package/components/avatar-upload/avatar-upload.js +108 -0
- package/components/avatar-upload/avatar-upload.js.map +1 -0
- package/components/avatar-upload/index.cjs +13 -0
- package/components/avatar-upload/index.cjs.map +1 -0
- package/components/avatar-upload/index.d.ts +2 -0
- package/components/avatar-upload/index.js +3 -0
- package/components/avatar-upload/index.js.map +1 -0
- package/components/flip-list/flip-list.cjs +31 -14
- package/components/flip-list/flip-list.cjs.map +1 -1
- package/components/flip-list/flip-list.d.ts +30 -6
- package/components/flip-list/flip-list.js +31 -14
- package/components/flip-list/flip-list.js.map +1 -1
- package/components/index.cjs +6 -0
- package/components/index.d.ts +2 -0
- package/components/index.js +1 -0
- package/index.cjs +6 -0
- package/index.d.ts +2 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/styles.css +91 -0
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
4
5
|
require('./avatar.css');
|
|
5
6
|
var classnames = require('../helpers/classnames');
|
|
6
7
|
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
11
|
+
|
|
7
12
|
const Avatar = ({
|
|
8
13
|
src,
|
|
9
14
|
alt = "",
|
|
@@ -12,16 +17,21 @@ const Avatar = ({
|
|
|
12
17
|
onClick,
|
|
13
18
|
...props
|
|
14
19
|
}) => {
|
|
20
|
+
const [failedSrc, setFailedSrc] = React__default.default.useState();
|
|
15
21
|
const isInteractive = !!onClick;
|
|
22
|
+
const showImage = Boolean(src) && src !== failedSrc;
|
|
16
23
|
const classes = classnames.classnames("avatar", className, {
|
|
17
24
|
"avatar--button": isInteractive
|
|
18
25
|
});
|
|
19
|
-
const content =
|
|
26
|
+
const content = showImage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
20
27
|
"img",
|
|
21
28
|
{
|
|
22
29
|
className: "avatar__image",
|
|
23
30
|
src,
|
|
24
|
-
alt
|
|
31
|
+
alt,
|
|
32
|
+
onError: () => {
|
|
33
|
+
setFailedSrc(src);
|
|
34
|
+
}
|
|
25
35
|
}
|
|
26
36
|
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "avatar__initials", children: initials });
|
|
27
37
|
if (isInteractive) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/avatar/avatar.tsx"],"names":["classnames","jsx"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/components/avatar/avatar.tsx"],"names":["React","classnames","jsx"],"mappings":";;;;;;;;;;;AA2BA,MAAM,SAAgC,CAAC;AAAA,EACrC,GAAA;AAAA,EACA,GAAA,GAAM,EAAA;AAAA,EACN,QAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,OAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAC5BA,uBAAM,QAAA,EAA6B;AAErC,EAAA,MAAM,aAAA,GAAgB,CAAC,CAAC,OAAA;AAExB,EAAA,MAAM,SAAA,GACJ,OAAA,CAAQ,GAAG,CAAA,IAAK,GAAA,KAAQ,SAAA;AAE1B,EAAA,MAAM,OAAA,GAAUC,qBAAA,CAAW,QAAA,EAAU,SAAA,EAAW;AAAA,IAC9C,gBAAA,EAAkB;AAAA,GACnB,CAAA;AAED,EAAA,MAAM,UAAU,SAAA,mBACdC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,eAAA;AAAA,MACV,GAAA;AAAA,MACA,GAAA;AAAA,MACA,SAAS,MAAM;AACb,QAAA,YAAA,CAAa,GAAG,CAAA;AAAA,MAClB;AAAA;AAAA,GACF,mBAEAA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oBACb,QAAA,EAAA,QAAA,EACH,CAAA;AAGF,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,uBACEA,cAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,OAAA;AAAA,QACX,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAY,KAAA,CAAM,YAAY,CAAA,IAAK,GAAA;AAAA,QACnC,OAAA;AAAA,QACC,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AAEA,EAAA,uBACEA,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,OAAA;AAAA,MACX,YAAA,EAAY,GAAA;AAAA,MACX,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ,CAAA;AAEA,IAAO,cAAA,GAAQ","file":"avatar.cjs","sourcesContent":["import React from 'react';\nimport './avatar.css';\nimport { classnames } from '../helpers/classnames';\n\nexport interface AvatarBaseProps\n extends React.HTMLAttributes<HTMLDivElement> {\n src?: string;\n alt?: string;\n initials?: string;\n}\n\ntype AvatarStaticProps =\n AvatarBaseProps &\n React.HTMLAttributes<HTMLDivElement> & {\n onClick?: undefined;\n };\n\ntype AvatarButtonProps =\n AvatarBaseProps &\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n onClick: React.MouseEventHandler<HTMLButtonElement>;\n };\n\nexport type AvatarProps =\n | AvatarStaticProps\n | AvatarButtonProps;\n\nconst Avatar: React.FC<AvatarProps> = ({\n src,\n alt = '',\n initials,\n className = '',\n onClick,\n ...props\n}) => {\n const [failedSrc, setFailedSrc] =\n React.useState<string | undefined>();\n\n const isInteractive = !!onClick;\n\n const showImage =\n Boolean(src) && src !== failedSrc;\n\n const classes = classnames('avatar', className, {\n 'avatar--button': isInteractive,\n });\n\n const content = showImage ? (\n <img\n className=\"avatar__image\"\n src={src}\n alt={alt}\n onError={() => {\n setFailedSrc(src);\n }}\n />\n ) : (\n <span className=\"avatar__initials\">\n {initials}\n </span>\n );\n\n if (isInteractive) {\n return (\n <button\n className={classes}\n type=\"button\"\n aria-label={props['aria-label'] ?? alt}\n onClick={onClick}\n {...props as React.ButtonHTMLAttributes<HTMLButtonElement>}\n >\n {content}\n </button>\n );\n }\n\n return (\n <div\n className={classes}\n aria-label={alt}\n {...props as React.HTMLAttributes<HTMLDivElement>}\n >\n {content}\n </div>\n );\n};\n\nexport default Avatar;\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
2
3
|
import './avatar.css';
|
|
3
4
|
import { classnames } from '../helpers/classnames';
|
|
4
5
|
|
|
@@ -10,16 +11,21 @@ const Avatar = ({
|
|
|
10
11
|
onClick,
|
|
11
12
|
...props
|
|
12
13
|
}) => {
|
|
14
|
+
const [failedSrc, setFailedSrc] = React.useState();
|
|
13
15
|
const isInteractive = !!onClick;
|
|
16
|
+
const showImage = Boolean(src) && src !== failedSrc;
|
|
14
17
|
const classes = classnames("avatar", className, {
|
|
15
18
|
"avatar--button": isInteractive
|
|
16
19
|
});
|
|
17
|
-
const content =
|
|
20
|
+
const content = showImage ? /* @__PURE__ */ jsx(
|
|
18
21
|
"img",
|
|
19
22
|
{
|
|
20
23
|
className: "avatar__image",
|
|
21
24
|
src,
|
|
22
|
-
alt
|
|
25
|
+
alt,
|
|
26
|
+
onError: () => {
|
|
27
|
+
setFailedSrc(src);
|
|
28
|
+
}
|
|
23
29
|
}
|
|
24
30
|
) : /* @__PURE__ */ jsx("span", { className: "avatar__initials", children: initials });
|
|
25
31
|
if (isInteractive) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/avatar/avatar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/components/avatar/avatar.tsx"],"names":[],"mappings":";;;;;AA2BA,MAAM,SAAgC,CAAC;AAAA,EACrC,GAAA;AAAA,EACA,GAAA,GAAM,EAAA;AAAA,EACN,QAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,OAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAC5B,MAAM,QAAA,EAA6B;AAErC,EAAA,MAAM,aAAA,GAAgB,CAAC,CAAC,OAAA;AAExB,EAAA,MAAM,SAAA,GACJ,OAAA,CAAQ,GAAG,CAAA,IAAK,GAAA,KAAQ,SAAA;AAE1B,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,QAAA,EAAU,SAAA,EAAW;AAAA,IAC9C,gBAAA,EAAkB;AAAA,GACnB,CAAA;AAED,EAAA,MAAM,UAAU,SAAA,mBACd,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,eAAA;AAAA,MACV,GAAA;AAAA,MACA,GAAA;AAAA,MACA,SAAS,MAAM;AACb,QAAA,YAAA,CAAa,GAAG,CAAA;AAAA,MAClB;AAAA;AAAA,GACF,mBAEA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oBACb,QAAA,EAAA,QAAA,EACH,CAAA;AAGF,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,OAAA;AAAA,QACX,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAY,KAAA,CAAM,YAAY,CAAA,IAAK,GAAA;AAAA,QACnC,OAAA;AAAA,QACC,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,OAAA;AAAA,MACX,YAAA,EAAY,GAAA;AAAA,MACX,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ,CAAA;AAEA,IAAO,cAAA,GAAQ","file":"avatar.js","sourcesContent":["import React from 'react';\nimport './avatar.css';\nimport { classnames } from '../helpers/classnames';\n\nexport interface AvatarBaseProps\n extends React.HTMLAttributes<HTMLDivElement> {\n src?: string;\n alt?: string;\n initials?: string;\n}\n\ntype AvatarStaticProps =\n AvatarBaseProps &\n React.HTMLAttributes<HTMLDivElement> & {\n onClick?: undefined;\n };\n\ntype AvatarButtonProps =\n AvatarBaseProps &\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n onClick: React.MouseEventHandler<HTMLButtonElement>;\n };\n\nexport type AvatarProps =\n | AvatarStaticProps\n | AvatarButtonProps;\n\nconst Avatar: React.FC<AvatarProps> = ({\n src,\n alt = '',\n initials,\n className = '',\n onClick,\n ...props\n}) => {\n const [failedSrc, setFailedSrc] =\n React.useState<string | undefined>();\n\n const isInteractive = !!onClick;\n\n const showImage =\n Boolean(src) && src !== failedSrc;\n\n const classes = classnames('avatar', className, {\n 'avatar--button': isInteractive,\n });\n\n const content = showImage ? (\n <img\n className=\"avatar__image\"\n src={src}\n alt={alt}\n onError={() => {\n setFailedSrc(src);\n }}\n />\n ) : (\n <span className=\"avatar__initials\">\n {initials}\n </span>\n );\n\n if (isInteractive) {\n return (\n <button\n className={classes}\n type=\"button\"\n aria-label={props['aria-label'] ?? alt}\n onClick={onClick}\n {...props as React.ButtonHTMLAttributes<HTMLButtonElement>}\n >\n {content}\n </button>\n );\n }\n\n return (\n <div\n className={classes}\n aria-label={alt}\n {...props as React.HTMLAttributes<HTMLDivElement>}\n >\n {content}\n </div>\n );\n};\n\nexport default Avatar;\n"]}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
require('./avatar-upload.css');
|
|
6
|
+
var Avatar = require('../avatar/avatar');
|
|
7
|
+
var Button = require('../button/button');
|
|
8
|
+
var classnames = require('../helpers/classnames');
|
|
9
|
+
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
13
|
+
var Avatar__default = /*#__PURE__*/_interopDefault(Avatar);
|
|
14
|
+
var Button__default = /*#__PURE__*/_interopDefault(Button);
|
|
15
|
+
|
|
16
|
+
const AvatarUpload = ({
|
|
17
|
+
src,
|
|
18
|
+
initials,
|
|
19
|
+
alt,
|
|
20
|
+
accept,
|
|
21
|
+
disabled = false,
|
|
22
|
+
loading = false,
|
|
23
|
+
error,
|
|
24
|
+
selectLabel,
|
|
25
|
+
onFileSelect,
|
|
26
|
+
className = "",
|
|
27
|
+
...props
|
|
28
|
+
}) => {
|
|
29
|
+
const inputRef = React__default.default.useRef(
|
|
30
|
+
null
|
|
31
|
+
);
|
|
32
|
+
const reactId = React__default.default.useId();
|
|
33
|
+
const errorId = `${reactId}-error`;
|
|
34
|
+
const hasError = error !== null && error !== void 0;
|
|
35
|
+
const isDisabled = disabled || loading;
|
|
36
|
+
const classes = classnames.classnames(
|
|
37
|
+
"avatar-upload",
|
|
38
|
+
className,
|
|
39
|
+
{
|
|
40
|
+
"avatar-upload--disabled": isDisabled,
|
|
41
|
+
"avatar-upload--loading": loading,
|
|
42
|
+
"avatar-upload--error": hasError
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
const handleSelectClick = () => {
|
|
46
|
+
if (isDisabled) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
inputRef.current?.click();
|
|
50
|
+
};
|
|
51
|
+
const handleFileChange = (event) => {
|
|
52
|
+
const input = event.currentTarget;
|
|
53
|
+
const file = input.files?.[0];
|
|
54
|
+
input.value = "";
|
|
55
|
+
if (!file) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
onFileSelect(file);
|
|
59
|
+
};
|
|
60
|
+
const resolvedAriaBusy = loading ? true : props["aria-busy"];
|
|
61
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
62
|
+
"div",
|
|
63
|
+
{
|
|
64
|
+
...props,
|
|
65
|
+
className: classes,
|
|
66
|
+
"aria-busy": resolvedAriaBusy,
|
|
67
|
+
children: [
|
|
68
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
69
|
+
Avatar__default.default,
|
|
70
|
+
{
|
|
71
|
+
className: "avatar-upload__avatar",
|
|
72
|
+
src,
|
|
73
|
+
initials,
|
|
74
|
+
alt
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
78
|
+
"input",
|
|
79
|
+
{
|
|
80
|
+
ref: inputRef,
|
|
81
|
+
className: "avatar-upload__input",
|
|
82
|
+
type: "file",
|
|
83
|
+
accept,
|
|
84
|
+
disabled: isDisabled,
|
|
85
|
+
onChange: handleFileChange
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
89
|
+
Button__default.default,
|
|
90
|
+
{
|
|
91
|
+
className: "avatar-upload__button",
|
|
92
|
+
type: "button",
|
|
93
|
+
disabled: isDisabled,
|
|
94
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
95
|
+
onClick: handleSelectClick,
|
|
96
|
+
children: selectLabel
|
|
97
|
+
}
|
|
98
|
+
),
|
|
99
|
+
hasError && /* @__PURE__ */ jsxRuntime.jsx(
|
|
100
|
+
"div",
|
|
101
|
+
{
|
|
102
|
+
className: "avatar-upload__error",
|
|
103
|
+
id: errorId,
|
|
104
|
+
role: "alert",
|
|
105
|
+
children: error
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
var avatar_upload_default = AvatarUpload;
|
|
113
|
+
|
|
114
|
+
module.exports = avatar_upload_default;
|
|
115
|
+
//# sourceMappingURL=avatar-upload.cjs.map
|
|
116
|
+
//# sourceMappingURL=avatar-upload.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/avatar-upload/avatar-upload.tsx"],"names":["React","classnames","jsxs","jsx","Avatar","Button"],"mappings":";;;;;;;;;;;;;;;AAuBA,MAAM,eAEF,CAAC;AAAA,EACH,GAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,OAAA,GAAU,KAAA;AAAA,EACV,KAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,WACJA,sBAAA,CAAM,MAAA;AAAA,IACJ;AAAA,GACF;AAEF,EAAA,MAAM,OAAA,GAAUA,uBAAM,KAAA,EAAM;AAE5B,EAAA,MAAM,OAAA,GAAU,GAAG,OAAO,CAAA,MAAA,CAAA;AAE1B,EAAA,MAAM,QAAA,GACJ,KAAA,KAAU,IAAA,IACV,KAAA,KAAU,MAAA;AAEZ,EAAA,MAAM,aACJ,QAAA,IAAY,OAAA;AAEd,EAAA,MAAM,OAAA,GAAUC,qBAAA;AAAA,IACd,eAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,MACE,yBAAA,EACE,UAAA;AAAA,MACF,wBAAA,EACE,OAAA;AAAA,MACF,sBAAA,EACE;AAAA;AACJ,GACF;AAEA,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,IAAI,UAAA,EAAY;AACd,MAAA;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,EAC1B,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,CACvB,KAAA,KACG;AACH,IAAA,MAAM,QAAQ,KAAA,CAAM,aAAA;AACpB,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA;AAO5B,IAAA,KAAA,CAAM,KAAA,GAAQ,EAAA;AAEd,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA;AAAA,IACF;AAEA,IAAA,YAAA,CAAa,IAAI,CAAA;AAAA,EACnB,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,OAAA,GACrB,IAAA,GACA,KAAA,CAAM,WAAW,CAAA;AAErB,EAAA,uBACEC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,SAAA,EAAW,OAAA;AAAA,MACX,WAAA,EAAW,gBAAA;AAAA,MAEX,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAACC,uBAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,uBAAA;AAAA,YACV,GAAA;AAAA,YACA,QAAA;AAAA,YACA;AAAA;AAAA,SACF;AAAA,wBAEAD,cAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAU,sBAAA;AAAA,YACV,IAAA,EAAK,MAAA;AAAA,YACL,MAAA;AAAA,YACA,QAAA,EAAU,UAAA;AAAA,YACV,QAAA,EAAU;AAAA;AAAA,SACZ;AAAA,wBAEAA,cAAA;AAAA,UAACE,uBAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,uBAAA;AAAA,YACV,IAAA,EAAK,QAAA;AAAA,YACL,QAAA,EAAU,UAAA;AAAA,YACV,kBAAA,EACE,WACI,OAAA,GACA,MAAA;AAAA,YAEN,OAAA,EAAS,iBAAA;AAAA,YAER,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QAEC,QAAA,oBACCF,cAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,sBAAA;AAAA,YACV,EAAA,EAAI,OAAA;AAAA,YACJ,IAAA,EAAK,OAAA;AAAA,YAEJ,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,GAEJ;AAEJ,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"avatar-upload.cjs","sourcesContent":["import React from 'react';\n\nimport './avatar-upload.css';\nimport Avatar from '../avatar/avatar';\nimport Button from '../button/button';\nimport { classnames } from '../helpers/classnames';\n\nexport interface AvatarUploadProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n src?: string;\n initials?: string;\n alt?: string;\n accept?: string;\n disabled?: boolean;\n loading?: boolean;\n error?: React.ReactNode;\n selectLabel: React.ReactNode;\n onFileSelect: (file: File) => void;\n}\n\nconst AvatarUpload: React.FC<\n AvatarUploadProps\n> = ({\n src,\n initials,\n alt,\n accept,\n disabled = false,\n loading = false,\n error,\n selectLabel,\n onFileSelect,\n className = '',\n ...props\n}) => {\n const inputRef =\n React.useRef<HTMLInputElement>(\n null,\n );\n\n const reactId = React.useId();\n\n const errorId = `${reactId}-error`;\n\n const hasError =\n error !== null &&\n error !== undefined;\n\n const isDisabled =\n disabled || loading;\n\n const classes = classnames(\n 'avatar-upload',\n className,\n {\n 'avatar-upload--disabled':\n isDisabled,\n 'avatar-upload--loading':\n loading,\n 'avatar-upload--error':\n hasError,\n },\n );\n\n const handleSelectClick = () => {\n if (isDisabled) {\n return;\n }\n\n inputRef.current?.click();\n };\n\n const handleFileChange = (\n event: React.ChangeEvent<HTMLInputElement>,\n ) => {\n const input = event.currentTarget;\n const file = input.files?.[0];\n\n /*\n * Reset the native input after reading\n * the selected file so the same file\n * can be selected again later.\n */\n input.value = '';\n\n if (!file) {\n return;\n }\n\n onFileSelect(file);\n };\n\n const resolvedAriaBusy = loading\n ? true\n : props['aria-busy'];\n\n return (\n <div\n {...props}\n className={classes}\n aria-busy={resolvedAriaBusy}\n >\n <Avatar\n className=\"avatar-upload__avatar\"\n src={src}\n initials={initials}\n alt={alt}\n />\n\n <input\n ref={inputRef}\n className=\"avatar-upload__input\"\n type=\"file\"\n accept={accept}\n disabled={isDisabled}\n onChange={handleFileChange}\n />\n\n <Button\n className=\"avatar-upload__button\"\n type=\"button\"\n disabled={isDisabled}\n aria-describedby={\n hasError\n ? errorId\n : undefined\n }\n onClick={handleSelectClick}\n >\n {selectLabel}\n </Button>\n\n {hasError && (\n <div\n className=\"avatar-upload__error\"\n id={errorId}\n role=\"alert\"\n >\n {error}\n </div>\n )}\n </div>\n );\n};\n\nexport default AvatarUpload;"]}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
.avatar-upload {
|
|
2
|
+
/* color */
|
|
3
|
+
|
|
4
|
+
/* typography */
|
|
5
|
+
|
|
6
|
+
/* size */
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
align-items: flex-start;
|
|
10
|
+
|
|
11
|
+
/* border */
|
|
12
|
+
|
|
13
|
+
/* depth */
|
|
14
|
+
|
|
15
|
+
/* motion */
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.avatar-upload__avatar {
|
|
19
|
+
/* color */
|
|
20
|
+
|
|
21
|
+
/* typography */
|
|
22
|
+
|
|
23
|
+
/* size */
|
|
24
|
+
margin-bottom: var(--margin-control);
|
|
25
|
+
|
|
26
|
+
/* border */
|
|
27
|
+
|
|
28
|
+
/* depth */
|
|
29
|
+
|
|
30
|
+
/* motion */
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.avatar-upload__input {
|
|
34
|
+
/* color */
|
|
35
|
+
|
|
36
|
+
/* typography */
|
|
37
|
+
|
|
38
|
+
/* size */
|
|
39
|
+
position: absolute;
|
|
40
|
+
width: 1px;
|
|
41
|
+
height: 1px;
|
|
42
|
+
padding: 0;
|
|
43
|
+
margin: -1px;
|
|
44
|
+
overflow: hidden;
|
|
45
|
+
|
|
46
|
+
/* border */
|
|
47
|
+
border: 0;
|
|
48
|
+
|
|
49
|
+
/* depth */
|
|
50
|
+
clip: rect(0 0 0 0);
|
|
51
|
+
clip-path: inset(50%);
|
|
52
|
+
|
|
53
|
+
/* motion */
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.avatar-upload__button {
|
|
57
|
+
/* color */
|
|
58
|
+
|
|
59
|
+
/* typography */
|
|
60
|
+
|
|
61
|
+
/* size */
|
|
62
|
+
|
|
63
|
+
/* border */
|
|
64
|
+
|
|
65
|
+
/* depth */
|
|
66
|
+
|
|
67
|
+
/* motion */
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.avatar-upload__error {
|
|
71
|
+
/* color */
|
|
72
|
+
color: var(--color-text-bad);
|
|
73
|
+
|
|
74
|
+
/* typography */
|
|
75
|
+
font-family: var(--font-note-family);
|
|
76
|
+
font-size: var(--font-note);
|
|
77
|
+
font-weight: var(--font-note-weight);
|
|
78
|
+
line-height: var(--font-note-line);
|
|
79
|
+
letter-spacing: var(--font-note-letter-spacing);
|
|
80
|
+
|
|
81
|
+
/* size */
|
|
82
|
+
margin-top: var(--margin-descriptor);
|
|
83
|
+
|
|
84
|
+
/* border */
|
|
85
|
+
|
|
86
|
+
/* depth */
|
|
87
|
+
|
|
88
|
+
/* motion */
|
|
89
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './avatar-upload.css';
|
|
3
|
+
export interface AvatarUploadProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
4
|
+
src?: string;
|
|
5
|
+
initials?: string;
|
|
6
|
+
alt?: string;
|
|
7
|
+
accept?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
loading?: boolean;
|
|
10
|
+
error?: React.ReactNode;
|
|
11
|
+
selectLabel: React.ReactNode;
|
|
12
|
+
onFileSelect: (file: File) => void;
|
|
13
|
+
}
|
|
14
|
+
declare const AvatarUpload: React.FC<AvatarUploadProps>;
|
|
15
|
+
export default AvatarUpload;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import './avatar-upload.css';
|
|
4
|
+
import Avatar from '../avatar/avatar';
|
|
5
|
+
import Button from '../button/button';
|
|
6
|
+
import { classnames } from '../helpers/classnames';
|
|
7
|
+
|
|
8
|
+
const AvatarUpload = ({
|
|
9
|
+
src,
|
|
10
|
+
initials,
|
|
11
|
+
alt,
|
|
12
|
+
accept,
|
|
13
|
+
disabled = false,
|
|
14
|
+
loading = false,
|
|
15
|
+
error,
|
|
16
|
+
selectLabel,
|
|
17
|
+
onFileSelect,
|
|
18
|
+
className = "",
|
|
19
|
+
...props
|
|
20
|
+
}) => {
|
|
21
|
+
const inputRef = React.useRef(
|
|
22
|
+
null
|
|
23
|
+
);
|
|
24
|
+
const reactId = React.useId();
|
|
25
|
+
const errorId = `${reactId}-error`;
|
|
26
|
+
const hasError = error !== null && error !== void 0;
|
|
27
|
+
const isDisabled = disabled || loading;
|
|
28
|
+
const classes = classnames(
|
|
29
|
+
"avatar-upload",
|
|
30
|
+
className,
|
|
31
|
+
{
|
|
32
|
+
"avatar-upload--disabled": isDisabled,
|
|
33
|
+
"avatar-upload--loading": loading,
|
|
34
|
+
"avatar-upload--error": hasError
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
const handleSelectClick = () => {
|
|
38
|
+
if (isDisabled) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
inputRef.current?.click();
|
|
42
|
+
};
|
|
43
|
+
const handleFileChange = (event) => {
|
|
44
|
+
const input = event.currentTarget;
|
|
45
|
+
const file = input.files?.[0];
|
|
46
|
+
input.value = "";
|
|
47
|
+
if (!file) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
onFileSelect(file);
|
|
51
|
+
};
|
|
52
|
+
const resolvedAriaBusy = loading ? true : props["aria-busy"];
|
|
53
|
+
return /* @__PURE__ */ jsxs(
|
|
54
|
+
"div",
|
|
55
|
+
{
|
|
56
|
+
...props,
|
|
57
|
+
className: classes,
|
|
58
|
+
"aria-busy": resolvedAriaBusy,
|
|
59
|
+
children: [
|
|
60
|
+
/* @__PURE__ */ jsx(
|
|
61
|
+
Avatar,
|
|
62
|
+
{
|
|
63
|
+
className: "avatar-upload__avatar",
|
|
64
|
+
src,
|
|
65
|
+
initials,
|
|
66
|
+
alt
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
/* @__PURE__ */ jsx(
|
|
70
|
+
"input",
|
|
71
|
+
{
|
|
72
|
+
ref: inputRef,
|
|
73
|
+
className: "avatar-upload__input",
|
|
74
|
+
type: "file",
|
|
75
|
+
accept,
|
|
76
|
+
disabled: isDisabled,
|
|
77
|
+
onChange: handleFileChange
|
|
78
|
+
}
|
|
79
|
+
),
|
|
80
|
+
/* @__PURE__ */ jsx(
|
|
81
|
+
Button,
|
|
82
|
+
{
|
|
83
|
+
className: "avatar-upload__button",
|
|
84
|
+
type: "button",
|
|
85
|
+
disabled: isDisabled,
|
|
86
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
87
|
+
onClick: handleSelectClick,
|
|
88
|
+
children: selectLabel
|
|
89
|
+
}
|
|
90
|
+
),
|
|
91
|
+
hasError && /* @__PURE__ */ jsx(
|
|
92
|
+
"div",
|
|
93
|
+
{
|
|
94
|
+
className: "avatar-upload__error",
|
|
95
|
+
id: errorId,
|
|
96
|
+
role: "alert",
|
|
97
|
+
children: error
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
var avatar_upload_default = AvatarUpload;
|
|
105
|
+
|
|
106
|
+
export { avatar_upload_default as default };
|
|
107
|
+
//# sourceMappingURL=avatar-upload.js.map
|
|
108
|
+
//# sourceMappingURL=avatar-upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/avatar-upload/avatar-upload.tsx"],"names":[],"mappings":";;;;;;;AAuBA,MAAM,eAEF,CAAC;AAAA,EACH,GAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,OAAA,GAAU,KAAA;AAAA,EACV,KAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,WACJ,KAAA,CAAM,MAAA;AAAA,IACJ;AAAA,GACF;AAEF,EAAA,MAAM,OAAA,GAAU,MAAM,KAAA,EAAM;AAE5B,EAAA,MAAM,OAAA,GAAU,GAAG,OAAO,CAAA,MAAA,CAAA;AAE1B,EAAA,MAAM,QAAA,GACJ,KAAA,KAAU,IAAA,IACV,KAAA,KAAU,MAAA;AAEZ,EAAA,MAAM,aACJ,QAAA,IAAY,OAAA;AAEd,EAAA,MAAM,OAAA,GAAU,UAAA;AAAA,IACd,eAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,MACE,yBAAA,EACE,UAAA;AAAA,MACF,wBAAA,EACE,OAAA;AAAA,MACF,sBAAA,EACE;AAAA;AACJ,GACF;AAEA,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,IAAI,UAAA,EAAY;AACd,MAAA;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,EAC1B,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,CACvB,KAAA,KACG;AACH,IAAA,MAAM,QAAQ,KAAA,CAAM,aAAA;AACpB,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA;AAO5B,IAAA,KAAA,CAAM,KAAA,GAAQ,EAAA;AAEd,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA;AAAA,IACF;AAEA,IAAA,YAAA,CAAa,IAAI,CAAA;AAAA,EACnB,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,OAAA,GACrB,IAAA,GACA,KAAA,CAAM,WAAW,CAAA;AAErB,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,SAAA,EAAW,OAAA;AAAA,MACX,WAAA,EAAW,gBAAA;AAAA,MAEX,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,uBAAA;AAAA,YACV,GAAA;AAAA,YACA,QAAA;AAAA,YACA;AAAA;AAAA,SACF;AAAA,wBAEA,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAU,sBAAA;AAAA,YACV,IAAA,EAAK,MAAA;AAAA,YACL,MAAA;AAAA,YACA,QAAA,EAAU,UAAA;AAAA,YACV,QAAA,EAAU;AAAA;AAAA,SACZ;AAAA,wBAEA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,uBAAA;AAAA,YACV,IAAA,EAAK,QAAA;AAAA,YACL,QAAA,EAAU,UAAA;AAAA,YACV,kBAAA,EACE,WACI,OAAA,GACA,MAAA;AAAA,YAEN,OAAA,EAAS,iBAAA;AAAA,YAER,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QAEC,QAAA,oBACC,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,sBAAA;AAAA,YACV,EAAA,EAAI,OAAA;AAAA,YACJ,IAAA,EAAK,OAAA;AAAA,YAEJ,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,GAEJ;AAEJ,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"avatar-upload.js","sourcesContent":["import React from 'react';\n\nimport './avatar-upload.css';\nimport Avatar from '../avatar/avatar';\nimport Button from '../button/button';\nimport { classnames } from '../helpers/classnames';\n\nexport interface AvatarUploadProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n src?: string;\n initials?: string;\n alt?: string;\n accept?: string;\n disabled?: boolean;\n loading?: boolean;\n error?: React.ReactNode;\n selectLabel: React.ReactNode;\n onFileSelect: (file: File) => void;\n}\n\nconst AvatarUpload: React.FC<\n AvatarUploadProps\n> = ({\n src,\n initials,\n alt,\n accept,\n disabled = false,\n loading = false,\n error,\n selectLabel,\n onFileSelect,\n className = '',\n ...props\n}) => {\n const inputRef =\n React.useRef<HTMLInputElement>(\n null,\n );\n\n const reactId = React.useId();\n\n const errorId = `${reactId}-error`;\n\n const hasError =\n error !== null &&\n error !== undefined;\n\n const isDisabled =\n disabled || loading;\n\n const classes = classnames(\n 'avatar-upload',\n className,\n {\n 'avatar-upload--disabled':\n isDisabled,\n 'avatar-upload--loading':\n loading,\n 'avatar-upload--error':\n hasError,\n },\n );\n\n const handleSelectClick = () => {\n if (isDisabled) {\n return;\n }\n\n inputRef.current?.click();\n };\n\n const handleFileChange = (\n event: React.ChangeEvent<HTMLInputElement>,\n ) => {\n const input = event.currentTarget;\n const file = input.files?.[0];\n\n /*\n * Reset the native input after reading\n * the selected file so the same file\n * can be selected again later.\n */\n input.value = '';\n\n if (!file) {\n return;\n }\n\n onFileSelect(file);\n };\n\n const resolvedAriaBusy = loading\n ? true\n : props['aria-busy'];\n\n return (\n <div\n {...props}\n className={classes}\n aria-busy={resolvedAriaBusy}\n >\n <Avatar\n className=\"avatar-upload__avatar\"\n src={src}\n initials={initials}\n alt={alt}\n />\n\n <input\n ref={inputRef}\n className=\"avatar-upload__input\"\n type=\"file\"\n accept={accept}\n disabled={isDisabled}\n onChange={handleFileChange}\n />\n\n <Button\n className=\"avatar-upload__button\"\n type=\"button\"\n disabled={isDisabled}\n aria-describedby={\n hasError\n ? errorId\n : undefined\n }\n onClick={handleSelectClick}\n >\n {selectLabel}\n </Button>\n\n {hasError && (\n <div\n className=\"avatar-upload__error\"\n id={errorId}\n role=\"alert\"\n >\n {error}\n </div>\n )}\n </div>\n );\n};\n\nexport default AvatarUpload;"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var avatarUpload = require('./avatar-upload');
|
|
4
|
+
|
|
5
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var avatarUpload__default = /*#__PURE__*/_interopDefault(avatarUpload);
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
module.exports = avatarUpload__default.default;
|
|
12
|
+
//# sourceMappingURL=index.cjs.map
|
|
13
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs","sourcesContent":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
|
@@ -12,36 +12,49 @@ var React__default = /*#__PURE__*/_interopDefault(React);
|
|
|
12
12
|
function hasContent(value) {
|
|
13
13
|
return value !== null && value !== void 0;
|
|
14
14
|
}
|
|
15
|
-
function
|
|
16
|
-
if (
|
|
15
|
+
function normalizeOpenItemId(items, openId) {
|
|
16
|
+
if (openId === null || openId === void 0) {
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
19
|
const hasMatchingItem = items.some(
|
|
20
|
-
(item) => item.id ===
|
|
20
|
+
(item) => item.id === openId
|
|
21
21
|
);
|
|
22
|
-
return hasMatchingItem ?
|
|
22
|
+
return hasMatchingItem ? openId : null;
|
|
23
23
|
}
|
|
24
24
|
const FlipList = ({
|
|
25
25
|
items,
|
|
26
|
+
openId,
|
|
26
27
|
defaultOpenId,
|
|
27
|
-
|
|
28
|
+
onOpenChange,
|
|
29
|
+
scrollToInitialOpen = false,
|
|
28
30
|
className = "",
|
|
29
31
|
...props
|
|
30
32
|
}) => {
|
|
31
33
|
const componentId = React__default.default.useId();
|
|
34
|
+
const isControlled = openId !== void 0;
|
|
32
35
|
const initialOpenItemIdRef = React__default.default.useRef(
|
|
33
|
-
|
|
36
|
+
normalizeOpenItemId(
|
|
34
37
|
items,
|
|
35
|
-
defaultOpenId
|
|
38
|
+
isControlled ? openId : defaultOpenId
|
|
36
39
|
)
|
|
37
40
|
);
|
|
38
|
-
const shouldScrollInitiallyRef = React__default.default.useRef(
|
|
41
|
+
const shouldScrollInitiallyRef = React__default.default.useRef(scrollToInitialOpen);
|
|
39
42
|
const initialOpenItemRef = React__default.default.useRef(
|
|
40
43
|
null
|
|
41
44
|
);
|
|
42
45
|
const hasScrolledInitiallyRef = React__default.default.useRef(false);
|
|
43
|
-
const [
|
|
44
|
-
|
|
46
|
+
const [
|
|
47
|
+
uncontrolledOpenItemId,
|
|
48
|
+
setUncontrolledOpenItemId
|
|
49
|
+
] = React__default.default.useState(
|
|
50
|
+
() => normalizeOpenItemId(
|
|
51
|
+
items,
|
|
52
|
+
defaultOpenId
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
const resolvedOpenItemId = normalizeOpenItemId(
|
|
56
|
+
items,
|
|
57
|
+
isControlled ? openId : uncontrolledOpenItemId
|
|
45
58
|
);
|
|
46
59
|
React__default.default.useEffect(() => {
|
|
47
60
|
if (hasScrolledInitiallyRef.current || !shouldScrollInitiallyRef.current || initialOpenItemIdRef.current === null || !initialOpenItemRef.current) {
|
|
@@ -62,9 +75,13 @@ const FlipList = ({
|
|
|
62
75
|
{}
|
|
63
76
|
);
|
|
64
77
|
const toggleItem = (itemId) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
78
|
+
const nextOpenItemId = resolvedOpenItemId === itemId ? null : itemId;
|
|
79
|
+
if (!isControlled) {
|
|
80
|
+
setUncontrolledOpenItemId(
|
|
81
|
+
nextOpenItemId
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
onOpenChange?.(nextOpenItemId);
|
|
68
85
|
};
|
|
69
86
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
70
87
|
"div",
|
|
@@ -72,7 +89,7 @@ const FlipList = ({
|
|
|
72
89
|
className: classes,
|
|
73
90
|
...props,
|
|
74
91
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flip-list__items", children: items.map((item, itemIndex) => {
|
|
75
|
-
const isOpen =
|
|
92
|
+
const isOpen = resolvedOpenItemId === item.id;
|
|
76
93
|
const hasMeta = hasContent(
|
|
77
94
|
item.meta
|
|
78
95
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/flip-list/flip-list.tsx"],"names":["React","classnames","jsx","jsxs"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/flip-list/flip-list.tsx"],"names":["React","classnames","jsx","jsxs"],"mappings":"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","file":"flip-list.cjs","sourcesContent":["import React from 'react';\n\nimport './flip-list.css';\nimport { classnames } from '../helpers/classnames';\n\nexport interface FlipListItem {\n id: React.Key;\n title: React.ReactNode;\n meta?: React.ReactNode;\n content: React.ReactNode;\n}\n\nexport interface FlipListProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n items: FlipListItem[];\n\n /**\n * Currently opened item in controlled mode.\n *\n * `null` means that all items are closed.\n *\n * When this prop is provided, FlipList does not\n * own the opened-item state.\n */\n openId?: React.Key | null;\n\n /**\n * Item opened during the initial render\n * in uncontrolled mode.\n *\n * Later changes to this prop do not control\n * the component state.\n */\n defaultOpenId?: React.Key;\n\n /**\n * Called when the user requests a change\n * of the opened item.\n *\n * Receives the item id when an item is opened,\n * and `null` when the currently opened item\n * is closed.\n */\n onOpenChange?: (\n id: React.Key | null,\n ) => void;\n\n /**\n * Scrolls the item that is open during\n * the initial render into view once.\n *\n * In uncontrolled mode, the initial item comes\n * from `defaultOpenId`.\n *\n * In controlled mode, the initial item comes\n * from `openId`.\n *\n * Later state changes never trigger scrolling.\n */\n scrollToInitialOpen?: boolean;\n}\n\ntype OpenItemId = React.Key | null;\n\nfunction hasContent(\n value: React.ReactNode,\n): value is Exclude<\n React.ReactNode,\n null | undefined\n> {\n return value !== null && value !== undefined;\n}\n\nfunction normalizeOpenItemId(\n items: FlipListItem[],\n openId: OpenItemId | undefined,\n): OpenItemId {\n if (\n openId === null ||\n openId === undefined\n ) {\n return null;\n }\n\n const hasMatchingItem = items.some(\n (item) => item.id === openId,\n );\n\n return hasMatchingItem\n ? openId\n : null;\n}\n\nconst FlipList: React.FC<FlipListProps> = ({\n items,\n openId,\n defaultOpenId,\n onOpenChange,\n scrollToInitialOpen = false,\n className = '',\n ...props\n}) => {\n const componentId = React.useId();\n\n const isControlled =\n openId !== undefined;\n\n const initialOpenItemIdRef =\n React.useRef<OpenItemId>(\n normalizeOpenItemId(\n items,\n isControlled\n ? openId\n : defaultOpenId,\n ),\n );\n\n const shouldScrollInitiallyRef =\n React.useRef(scrollToInitialOpen);\n\n const initialOpenItemRef =\n React.useRef<HTMLDivElement | null>(\n null,\n );\n\n const hasScrolledInitiallyRef =\n React.useRef(false);\n\n const [\n uncontrolledOpenItemId,\n setUncontrolledOpenItemId,\n ] = React.useState<OpenItemId>(() =>\n normalizeOpenItemId(\n items,\n defaultOpenId,\n ),\n );\n\n const resolvedOpenItemId =\n normalizeOpenItemId(\n items,\n isControlled\n ? openId\n : uncontrolledOpenItemId,\n );\n\n React.useEffect(() => {\n if (\n hasScrolledInitiallyRef.current ||\n !shouldScrollInitiallyRef.current ||\n initialOpenItemIdRef.current === null ||\n !initialOpenItemRef.current\n ) {\n return;\n }\n\n hasScrolledInitiallyRef.current = true;\n\n initialOpenItemRef.current.scrollIntoView({\n behavior: 'auto',\n block: 'start',\n });\n }, []);\n\n if (items.length === 0) {\n return null;\n }\n\n const classes = classnames(\n 'flip-list',\n className,\n {},\n );\n\n const toggleItem = (\n itemId: React.Key,\n ) => {\n const nextOpenItemId =\n resolvedOpenItemId === itemId\n ? null\n : itemId;\n\n if (!isControlled) {\n setUncontrolledOpenItemId(\n nextOpenItemId,\n );\n }\n\n onOpenChange?.(nextOpenItemId);\n };\n\n return (\n <div\n className={classes}\n {...props}\n >\n <div className=\"flip-list__items\">\n {items.map((item, itemIndex) => {\n const isOpen =\n resolvedOpenItemId === item.id;\n\n const hasMeta = hasContent(\n item.meta,\n );\n\n const triggerId =\n `${componentId}-trigger-${itemIndex}`;\n\n const contentId =\n `${componentId}-content-${itemIndex}`;\n\n const itemClasses = classnames(\n 'flip-list__item',\n '',\n {\n 'flip-list__item--open':\n isOpen,\n },\n );\n\n return (\n <div\n key={item.id}\n ref={\n item.id ===\n initialOpenItemIdRef.current\n ? initialOpenItemRef\n : undefined\n }\n className={itemClasses}\n >\n <button\n className=\"flip-list__trigger\"\n id={triggerId}\n type=\"button\"\n aria-expanded={isOpen}\n aria-controls={contentId}\n onClick={() =>\n toggleItem(item.id)\n }\n >\n <span className=\"flip-list__title\">\n {item.title}\n </span>\n\n {hasMeta && (\n <span className=\"flip-list__meta\">\n {item.meta}\n </span>\n )}\n </button>\n\n <div\n className=\"flip-list__content\"\n id={contentId}\n aria-labelledby={triggerId}\n hidden={!isOpen}\n >\n {item.content}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n\nexport default FlipList;\n"]}
|
|
@@ -9,20 +9,44 @@ export interface FlipListItem {
|
|
|
9
9
|
export interface FlipListProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
10
10
|
items: FlipListItem[];
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Currently opened item in controlled mode.
|
|
13
|
+
*
|
|
14
|
+
* `null` means that all items are closed.
|
|
15
|
+
*
|
|
16
|
+
* When this prop is provided, FlipList does not
|
|
17
|
+
* own the opened-item state.
|
|
18
|
+
*/
|
|
19
|
+
openId?: React.Key | null;
|
|
20
|
+
/**
|
|
21
|
+
* Item opened during the initial render
|
|
22
|
+
* in uncontrolled mode.
|
|
13
23
|
*
|
|
14
24
|
* Later changes to this prop do not control
|
|
15
25
|
* the component state.
|
|
16
26
|
*/
|
|
17
27
|
defaultOpenId?: React.Key;
|
|
18
28
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
29
|
+
* Called when the user requests a change
|
|
30
|
+
* of the opened item.
|
|
31
|
+
*
|
|
32
|
+
* Receives the item id when an item is opened,
|
|
33
|
+
* and `null` when the currently opened item
|
|
34
|
+
* is closed.
|
|
35
|
+
*/
|
|
36
|
+
onOpenChange?: (id: React.Key | null) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Scrolls the item that is open during
|
|
39
|
+
* the initial render into view once.
|
|
40
|
+
*
|
|
41
|
+
* In uncontrolled mode, the initial item comes
|
|
42
|
+
* from `defaultOpenId`.
|
|
43
|
+
*
|
|
44
|
+
* In controlled mode, the initial item comes
|
|
45
|
+
* from `openId`.
|
|
21
46
|
*
|
|
22
|
-
*
|
|
23
|
-
* Manual item opening never triggers scrolling.
|
|
47
|
+
* Later state changes never trigger scrolling.
|
|
24
48
|
*/
|
|
25
|
-
|
|
49
|
+
scrollToInitialOpen?: boolean;
|
|
26
50
|
}
|
|
27
51
|
declare const FlipList: React.FC<FlipListProps>;
|
|
28
52
|
export default FlipList;
|
|
@@ -6,36 +6,49 @@ import { classnames } from '../helpers/classnames';
|
|
|
6
6
|
function hasContent(value) {
|
|
7
7
|
return value !== null && value !== void 0;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
if (
|
|
9
|
+
function normalizeOpenItemId(items, openId) {
|
|
10
|
+
if (openId === null || openId === void 0) {
|
|
11
11
|
return null;
|
|
12
12
|
}
|
|
13
13
|
const hasMatchingItem = items.some(
|
|
14
|
-
(item) => item.id ===
|
|
14
|
+
(item) => item.id === openId
|
|
15
15
|
);
|
|
16
|
-
return hasMatchingItem ?
|
|
16
|
+
return hasMatchingItem ? openId : null;
|
|
17
17
|
}
|
|
18
18
|
const FlipList = ({
|
|
19
19
|
items,
|
|
20
|
+
openId,
|
|
20
21
|
defaultOpenId,
|
|
21
|
-
|
|
22
|
+
onOpenChange,
|
|
23
|
+
scrollToInitialOpen = false,
|
|
22
24
|
className = "",
|
|
23
25
|
...props
|
|
24
26
|
}) => {
|
|
25
27
|
const componentId = React.useId();
|
|
28
|
+
const isControlled = openId !== void 0;
|
|
26
29
|
const initialOpenItemIdRef = React.useRef(
|
|
27
|
-
|
|
30
|
+
normalizeOpenItemId(
|
|
28
31
|
items,
|
|
29
|
-
defaultOpenId
|
|
32
|
+
isControlled ? openId : defaultOpenId
|
|
30
33
|
)
|
|
31
34
|
);
|
|
32
|
-
const shouldScrollInitiallyRef = React.useRef(
|
|
35
|
+
const shouldScrollInitiallyRef = React.useRef(scrollToInitialOpen);
|
|
33
36
|
const initialOpenItemRef = React.useRef(
|
|
34
37
|
null
|
|
35
38
|
);
|
|
36
39
|
const hasScrolledInitiallyRef = React.useRef(false);
|
|
37
|
-
const [
|
|
38
|
-
|
|
40
|
+
const [
|
|
41
|
+
uncontrolledOpenItemId,
|
|
42
|
+
setUncontrolledOpenItemId
|
|
43
|
+
] = React.useState(
|
|
44
|
+
() => normalizeOpenItemId(
|
|
45
|
+
items,
|
|
46
|
+
defaultOpenId
|
|
47
|
+
)
|
|
48
|
+
);
|
|
49
|
+
const resolvedOpenItemId = normalizeOpenItemId(
|
|
50
|
+
items,
|
|
51
|
+
isControlled ? openId : uncontrolledOpenItemId
|
|
39
52
|
);
|
|
40
53
|
React.useEffect(() => {
|
|
41
54
|
if (hasScrolledInitiallyRef.current || !shouldScrollInitiallyRef.current || initialOpenItemIdRef.current === null || !initialOpenItemRef.current) {
|
|
@@ -56,9 +69,13 @@ const FlipList = ({
|
|
|
56
69
|
{}
|
|
57
70
|
);
|
|
58
71
|
const toggleItem = (itemId) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
const nextOpenItemId = resolvedOpenItemId === itemId ? null : itemId;
|
|
73
|
+
if (!isControlled) {
|
|
74
|
+
setUncontrolledOpenItemId(
|
|
75
|
+
nextOpenItemId
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
onOpenChange?.(nextOpenItemId);
|
|
62
79
|
};
|
|
63
80
|
return /* @__PURE__ */ jsx(
|
|
64
81
|
"div",
|
|
@@ -66,7 +83,7 @@ const FlipList = ({
|
|
|
66
83
|
className: classes,
|
|
67
84
|
...props,
|
|
68
85
|
children: /* @__PURE__ */ jsx("div", { className: "flip-list__items", children: items.map((item, itemIndex) => {
|
|
69
|
-
const isOpen =
|
|
86
|
+
const isOpen = resolvedOpenItemId === item.id;
|
|
70
87
|
const hasMeta = hasContent(
|
|
71
88
|
item.meta
|
|
72
89
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/flip-list/flip-list.tsx"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/flip-list/flip-list.tsx"],"names":[],"mappings":"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","file":"flip-list.js","sourcesContent":["import React from 'react';\n\nimport './flip-list.css';\nimport { classnames } from '../helpers/classnames';\n\nexport interface FlipListItem {\n id: React.Key;\n title: React.ReactNode;\n meta?: React.ReactNode;\n content: React.ReactNode;\n}\n\nexport interface FlipListProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n items: FlipListItem[];\n\n /**\n * Currently opened item in controlled mode.\n *\n * `null` means that all items are closed.\n *\n * When this prop is provided, FlipList does not\n * own the opened-item state.\n */\n openId?: React.Key | null;\n\n /**\n * Item opened during the initial render\n * in uncontrolled mode.\n *\n * Later changes to this prop do not control\n * the component state.\n */\n defaultOpenId?: React.Key;\n\n /**\n * Called when the user requests a change\n * of the opened item.\n *\n * Receives the item id when an item is opened,\n * and `null` when the currently opened item\n * is closed.\n */\n onOpenChange?: (\n id: React.Key | null,\n ) => void;\n\n /**\n * Scrolls the item that is open during\n * the initial render into view once.\n *\n * In uncontrolled mode, the initial item comes\n * from `defaultOpenId`.\n *\n * In controlled mode, the initial item comes\n * from `openId`.\n *\n * Later state changes never trigger scrolling.\n */\n scrollToInitialOpen?: boolean;\n}\n\ntype OpenItemId = React.Key | null;\n\nfunction hasContent(\n value: React.ReactNode,\n): value is Exclude<\n React.ReactNode,\n null | undefined\n> {\n return value !== null && value !== undefined;\n}\n\nfunction normalizeOpenItemId(\n items: FlipListItem[],\n openId: OpenItemId | undefined,\n): OpenItemId {\n if (\n openId === null ||\n openId === undefined\n ) {\n return null;\n }\n\n const hasMatchingItem = items.some(\n (item) => item.id === openId,\n );\n\n return hasMatchingItem\n ? openId\n : null;\n}\n\nconst FlipList: React.FC<FlipListProps> = ({\n items,\n openId,\n defaultOpenId,\n onOpenChange,\n scrollToInitialOpen = false,\n className = '',\n ...props\n}) => {\n const componentId = React.useId();\n\n const isControlled =\n openId !== undefined;\n\n const initialOpenItemIdRef =\n React.useRef<OpenItemId>(\n normalizeOpenItemId(\n items,\n isControlled\n ? openId\n : defaultOpenId,\n ),\n );\n\n const shouldScrollInitiallyRef =\n React.useRef(scrollToInitialOpen);\n\n const initialOpenItemRef =\n React.useRef<HTMLDivElement | null>(\n null,\n );\n\n const hasScrolledInitiallyRef =\n React.useRef(false);\n\n const [\n uncontrolledOpenItemId,\n setUncontrolledOpenItemId,\n ] = React.useState<OpenItemId>(() =>\n normalizeOpenItemId(\n items,\n defaultOpenId,\n ),\n );\n\n const resolvedOpenItemId =\n normalizeOpenItemId(\n items,\n isControlled\n ? openId\n : uncontrolledOpenItemId,\n );\n\n React.useEffect(() => {\n if (\n hasScrolledInitiallyRef.current ||\n !shouldScrollInitiallyRef.current ||\n initialOpenItemIdRef.current === null ||\n !initialOpenItemRef.current\n ) {\n return;\n }\n\n hasScrolledInitiallyRef.current = true;\n\n initialOpenItemRef.current.scrollIntoView({\n behavior: 'auto',\n block: 'start',\n });\n }, []);\n\n if (items.length === 0) {\n return null;\n }\n\n const classes = classnames(\n 'flip-list',\n className,\n {},\n );\n\n const toggleItem = (\n itemId: React.Key,\n ) => {\n const nextOpenItemId =\n resolvedOpenItemId === itemId\n ? null\n : itemId;\n\n if (!isControlled) {\n setUncontrolledOpenItemId(\n nextOpenItemId,\n );\n }\n\n onOpenChange?.(nextOpenItemId);\n };\n\n return (\n <div\n className={classes}\n {...props}\n >\n <div className=\"flip-list__items\">\n {items.map((item, itemIndex) => {\n const isOpen =\n resolvedOpenItemId === item.id;\n\n const hasMeta = hasContent(\n item.meta,\n );\n\n const triggerId =\n `${componentId}-trigger-${itemIndex}`;\n\n const contentId =\n `${componentId}-content-${itemIndex}`;\n\n const itemClasses = classnames(\n 'flip-list__item',\n '',\n {\n 'flip-list__item--open':\n isOpen,\n },\n );\n\n return (\n <div\n key={item.id}\n ref={\n item.id ===\n initialOpenItemIdRef.current\n ? initialOpenItemRef\n : undefined\n }\n className={itemClasses}\n >\n <button\n className=\"flip-list__trigger\"\n id={triggerId}\n type=\"button\"\n aria-expanded={isOpen}\n aria-controls={contentId}\n onClick={() =>\n toggleItem(item.id)\n }\n >\n <span className=\"flip-list__title\">\n {item.title}\n </span>\n\n {hasMeta && (\n <span className=\"flip-list__meta\">\n {item.meta}\n </span>\n )}\n </button>\n\n <div\n className=\"flip-list__content\"\n id={contentId}\n aria-labelledby={triggerId}\n hidden={!isOpen}\n >\n {item.content}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n\nexport default FlipList;\n"]}
|
package/components/index.cjs
CHANGED
|
@@ -28,6 +28,7 @@ var discussion = require('./discussion/discussion');
|
|
|
28
28
|
var courseOutline = require('./course-outline/course-outline');
|
|
29
29
|
var calendarMonth = require('./calendar-month');
|
|
30
30
|
var flipList = require('./flip-list/flip-list');
|
|
31
|
+
var avatarUpload = require('./avatar-upload/avatar-upload');
|
|
31
32
|
|
|
32
33
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
33
34
|
|
|
@@ -58,6 +59,7 @@ var markdown__default = /*#__PURE__*/_interopDefault(markdown);
|
|
|
58
59
|
var discussion__default = /*#__PURE__*/_interopDefault(discussion);
|
|
59
60
|
var courseOutline__default = /*#__PURE__*/_interopDefault(courseOutline);
|
|
60
61
|
var flipList__default = /*#__PURE__*/_interopDefault(flipList);
|
|
62
|
+
var avatarUpload__default = /*#__PURE__*/_interopDefault(avatarUpload);
|
|
61
63
|
|
|
62
64
|
|
|
63
65
|
|
|
@@ -169,6 +171,10 @@ Object.defineProperty(exports, "FlipList", {
|
|
|
169
171
|
enumerable: true,
|
|
170
172
|
get: function () { return flipList__default.default; }
|
|
171
173
|
});
|
|
174
|
+
Object.defineProperty(exports, "AvatarUpload", {
|
|
175
|
+
enumerable: true,
|
|
176
|
+
get: function () { return avatarUpload__default.default; }
|
|
177
|
+
});
|
|
172
178
|
Object.keys(calendarMonth).forEach(function (k) {
|
|
173
179
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
174
180
|
enumerable: true,
|
package/components/index.d.ts
CHANGED
|
@@ -53,3 +53,5 @@ export type { CourseOutlineGroup, CourseOutlineHeadingLevel, CourseOutlineItem,
|
|
|
53
53
|
export * from './calendar-month';
|
|
54
54
|
export { default as FlipList } from './flip-list/flip-list';
|
|
55
55
|
export type { FlipListItem, FlipListProps, } from './flip-list/flip-list';
|
|
56
|
+
export { default as AvatarUpload } from './avatar-upload/avatar-upload';
|
|
57
|
+
export type { AvatarUploadProps, } from './avatar-upload/avatar-upload';
|
package/components/index.js
CHANGED
|
@@ -26,5 +26,6 @@ export { default as Discussion } from './discussion/discussion';
|
|
|
26
26
|
export { default as CourseOutline } from './course-outline/course-outline';
|
|
27
27
|
export * from './calendar-month';
|
|
28
28
|
export { default as FlipList } from './flip-list/flip-list';
|
|
29
|
+
export { default as AvatarUpload } from './avatar-upload/avatar-upload';
|
|
29
30
|
//# sourceMappingURL=index.js.map
|
|
30
31
|
//# sourceMappingURL=index.js.map
|
package/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var discussion = require('./components/discussion');
|
|
|
30
30
|
var courseOutline = require('./components/course-outline');
|
|
31
31
|
var calendarMonth = require('./components/calendar-month');
|
|
32
32
|
var flipList = require('./components/flip-list');
|
|
33
|
+
var avatarUpload = require('./components/avatar-upload');
|
|
33
34
|
var header = require('./patterns/header');
|
|
34
35
|
var footer = require('./patterns/footer');
|
|
35
36
|
var screenHeader = require('./patterns/screen-header');
|
|
@@ -72,6 +73,7 @@ var markdown__default = /*#__PURE__*/_interopDefault(markdown);
|
|
|
72
73
|
var discussion__default = /*#__PURE__*/_interopDefault(discussion);
|
|
73
74
|
var courseOutline__default = /*#__PURE__*/_interopDefault(courseOutline);
|
|
74
75
|
var flipList__default = /*#__PURE__*/_interopDefault(flipList);
|
|
76
|
+
var avatarUpload__default = /*#__PURE__*/_interopDefault(avatarUpload);
|
|
75
77
|
var header__default = /*#__PURE__*/_interopDefault(header);
|
|
76
78
|
var footer__default = /*#__PURE__*/_interopDefault(footer);
|
|
77
79
|
var screenHeader__default = /*#__PURE__*/_interopDefault(screenHeader);
|
|
@@ -201,6 +203,10 @@ Object.defineProperty(exports, "FlipList", {
|
|
|
201
203
|
enumerable: true,
|
|
202
204
|
get: function () { return flipList__default.default; }
|
|
203
205
|
});
|
|
206
|
+
Object.defineProperty(exports, "AvatarUpload", {
|
|
207
|
+
enumerable: true,
|
|
208
|
+
get: function () { return avatarUpload__default.default; }
|
|
209
|
+
});
|
|
204
210
|
Object.defineProperty(exports, "Header", {
|
|
205
211
|
enumerable: true,
|
|
206
212
|
get: function () { return header__default.default; }
|
package/index.d.ts
CHANGED
|
@@ -61,6 +61,8 @@ export type { CourseOutlineGroup, CourseOutlineHeadingLevel, CourseOutlineItem,
|
|
|
61
61
|
export * from './components/calendar-month';
|
|
62
62
|
export { default as FlipList } from './components/flip-list';
|
|
63
63
|
export type { FlipListItem, FlipListProps, } from './components/flip-list';
|
|
64
|
+
export { default as AvatarUpload } from './components/avatar-upload';
|
|
65
|
+
export type { AvatarUploadProps, } from './components/avatar-upload';
|
|
64
66
|
export { default as Header } from './patterns/header';
|
|
65
67
|
export type { HeaderProps } from './patterns/header';
|
|
66
68
|
export { default as Footer } from './patterns/footer';
|
package/index.js
CHANGED
|
@@ -28,6 +28,7 @@ export { default as Discussion } from './components/discussion';
|
|
|
28
28
|
export { default as CourseOutline } from './components/course-outline';
|
|
29
29
|
export * from './components/calendar-month';
|
|
30
30
|
export { default as FlipList } from './components/flip-list';
|
|
31
|
+
export { default as AvatarUpload } from './components/avatar-upload';
|
|
31
32
|
export { default as Header } from './patterns/header';
|
|
32
33
|
export { default as Footer } from './patterns/footer';
|
|
33
34
|
export { default as ScreenHeader } from './patterns/screen-header';
|
package/package.json
CHANGED
package/styles.css
CHANGED
|
@@ -320,6 +320,97 @@
|
|
|
320
320
|
text-transform: uppercase;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
+
/* src/components/avatar-upload/avatar-upload.css */
|
|
324
|
+
.avatar-upload {
|
|
325
|
+
/* color */
|
|
326
|
+
|
|
327
|
+
/* typography */
|
|
328
|
+
|
|
329
|
+
/* size */
|
|
330
|
+
display: flex;
|
|
331
|
+
flex-direction: column;
|
|
332
|
+
align-items: flex-start;
|
|
333
|
+
|
|
334
|
+
/* border */
|
|
335
|
+
|
|
336
|
+
/* depth */
|
|
337
|
+
|
|
338
|
+
/* motion */
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.avatar-upload__avatar {
|
|
342
|
+
/* color */
|
|
343
|
+
|
|
344
|
+
/* typography */
|
|
345
|
+
|
|
346
|
+
/* size */
|
|
347
|
+
margin-bottom: var(--margin-control);
|
|
348
|
+
|
|
349
|
+
/* border */
|
|
350
|
+
|
|
351
|
+
/* depth */
|
|
352
|
+
|
|
353
|
+
/* motion */
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.avatar-upload__input {
|
|
357
|
+
/* color */
|
|
358
|
+
|
|
359
|
+
/* typography */
|
|
360
|
+
|
|
361
|
+
/* size */
|
|
362
|
+
position: absolute;
|
|
363
|
+
width: 1px;
|
|
364
|
+
height: 1px;
|
|
365
|
+
padding: 0;
|
|
366
|
+
margin: -1px;
|
|
367
|
+
overflow: hidden;
|
|
368
|
+
|
|
369
|
+
/* border */
|
|
370
|
+
border: 0;
|
|
371
|
+
|
|
372
|
+
/* depth */
|
|
373
|
+
clip: rect(0 0 0 0);
|
|
374
|
+
clip-path: inset(50%);
|
|
375
|
+
|
|
376
|
+
/* motion */
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.avatar-upload__button {
|
|
380
|
+
/* color */
|
|
381
|
+
|
|
382
|
+
/* typography */
|
|
383
|
+
|
|
384
|
+
/* size */
|
|
385
|
+
|
|
386
|
+
/* border */
|
|
387
|
+
|
|
388
|
+
/* depth */
|
|
389
|
+
|
|
390
|
+
/* motion */
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.avatar-upload__error {
|
|
394
|
+
/* color */
|
|
395
|
+
color: var(--color-text-bad);
|
|
396
|
+
|
|
397
|
+
/* typography */
|
|
398
|
+
font-family: var(--font-note-family);
|
|
399
|
+
font-size: var(--font-note);
|
|
400
|
+
font-weight: var(--font-note-weight);
|
|
401
|
+
line-height: var(--font-note-line);
|
|
402
|
+
letter-spacing: var(--font-note-letter-spacing);
|
|
403
|
+
|
|
404
|
+
/* size */
|
|
405
|
+
margin-top: var(--margin-descriptor);
|
|
406
|
+
|
|
407
|
+
/* border */
|
|
408
|
+
|
|
409
|
+
/* depth */
|
|
410
|
+
|
|
411
|
+
/* motion */
|
|
412
|
+
}
|
|
413
|
+
|
|
323
414
|
/* src/components/breadcrumbs/breadcrumbs.css */
|
|
324
415
|
.breadcrumbs {
|
|
325
416
|
/* color */
|