jvetrau-ds 0.1.31 → 0.1.33

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.
@@ -7,6 +7,9 @@ var classnames = require('../helpers/classnames');
7
7
  function isImageAttach(item) {
8
8
  return item.mimeType?.startsWith("image/") ?? false;
9
9
  }
10
+ function isLinkAttach(item) {
11
+ return item.kind === "link";
12
+ }
10
13
  function formatFileSize(sizeBytes) {
11
14
  if (sizeBytes === void 0) {
12
15
  return "Size unknown";
@@ -19,6 +22,13 @@ function formatFileSize(sizeBytes) {
19
22
  }
20
23
  return `${(sizeBytes / 1024 / 1024).toFixed(1)} MB`;
21
24
  }
25
+ function getLinkHostname(url) {
26
+ try {
27
+ return new URL(url).hostname.replace(/^www\./u, "");
28
+ } catch {
29
+ return url;
30
+ }
31
+ }
22
32
  const Attach = ({
23
33
  items,
24
34
  onRemove,
@@ -37,11 +47,18 @@ const Attach = ({
37
47
  className: classes,
38
48
  ...props,
39
49
  children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "attach__list", children: items.map((item) => {
40
- const isImage = isImageAttach(item);
50
+ const isLink = isLinkAttach(item);
51
+ const isImage = !isLink && isImageAttach(item);
52
+ const itemClasses = classnames.classnames("attach__item", {
53
+ "attach__item--link": isLink,
54
+ "attach__item--image": isImage,
55
+ "attach__item--file": !isLink && !isImage
56
+ });
57
+ const meta = isLink ? getLinkHostname(item.url) : formatFileSize(item.sizeBytes);
41
58
  return /* @__PURE__ */ jsxRuntime.jsxs(
42
59
  "li",
43
60
  {
44
- className: "attach__item",
61
+ className: itemClasses,
45
62
  children: [
46
63
  /* @__PURE__ */ jsxRuntime.jsx(
47
64
  "a",
@@ -59,7 +76,7 @@ const Attach = ({
59
76
  }
60
77
  ) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "attach__file", children: [
61
78
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "attach__name", children: item.name }),
62
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "attach__size", children: formatFileSize(item.sizeBytes) })
79
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "attach__meta", children: meta })
63
80
  ] })
64
81
  }
65
82
  ),
@@ -68,7 +85,7 @@ const Attach = ({
68
85
  {
69
86
  className: "attach__remove",
70
87
  type: "button",
71
- "aria-label": `${removeLabel} \u0444\u0430\u0439\u043B ${item.name}`,
88
+ "aria-label": `${removeLabel}: ${item.name}`,
72
89
  onClick: () => onRemove(item.id),
73
90
  children: removeLabel
74
91
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/attach/attach.tsx"],"names":["classnames","jsx","jsxs"],"mappings":"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","file":"attach.cjs","sourcesContent":["import React from 'react';\nimport './attach.css';\nimport { classnames } from '../helpers/classnames';\n\nexport interface AttachItem {\n id: string;\n name: string;\n url: string;\n mimeType?: string;\n sizeBytes?: number;\n}\n\nexport interface AttachProps\n extends React.HTMLAttributes<HTMLDivElement> {\n items: AttachItem[];\n onRemove?: (id: string) => void;\n removeLabel?: string;\n emptyLabel?: string;\n}\n\nfunction isImageAttach(item: AttachItem) {\n return item.mimeType?.startsWith('image/') ?? false;\n}\n\nfunction formatFileSize(sizeBytes?: number) {\n if (sizeBytes === undefined) {\n return 'Size unknown';\n }\n\n if (sizeBytes < 1024) {\n return `${sizeBytes} B`;\n }\n\n if (sizeBytes < 1024 * 1024) {\n return `${Math.round(sizeBytes / 1024)} KB`;\n }\n\n return `${(sizeBytes / 1024 / 1024).toFixed(1)} MB`;\n}\n\nconst Attach: React.FC<AttachProps> = ({\n items,\n onRemove,\n removeLabel = 'Удалить',\n emptyLabel,\n className = '',\n ...props\n}) => {\n if (items.length === 0) {\n return null;\n }\n\n const classes = classnames('attach', className, {});\n\n return (\n <div\n className={classes}\n {...props}\n >\n <ul className=\"attach__list\">\n {items.map((item) => {\n const isImage = isImageAttach(item);\n\n return (\n <li\n key={item.id}\n className=\"attach__item\"\n >\n <a\n className=\"attach__link\"\n href={item.url}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {isImage ? (\n <img\n className=\"attach__preview\"\n src={item.url}\n alt={item.name}\n />\n ) : (\n <span className=\"attach__file\">\n <span className=\"attach__name\">\n {item.name}\n </span>\n\n <span className=\"attach__size\">\n {formatFileSize(item.sizeBytes)}\n </span>\n </span>\n )}\n </a>\n\n {onRemove && (\n <button\n className=\"attach__remove\"\n type=\"button\"\n aria-label={`${removeLabel} файл ${item.name}`}\n onClick={() => onRemove(item.id)}\n >\n {removeLabel}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n </div>\n );\n};\n\nexport default Attach;"]}
1
+ {"version":3,"sources":["../../../src/components/attach/attach.tsx"],"names":["classnames","jsx","jsxs"],"mappings":"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","file":"attach.cjs","sourcesContent":["import React from 'react';\nimport './attach.css';\nimport { classnames } from '../helpers/classnames';\n\nexport type AttachItemKind = 'file' | 'link';\n\nexport interface AttachItem {\n id: string;\n name: string;\n url: string;\n kind?: AttachItemKind;\n mimeType?: string;\n sizeBytes?: number;\n}\n\nexport interface AttachProps\n extends React.HTMLAttributes<HTMLDivElement> {\n items: AttachItem[];\n onRemove?: (id: string) => void;\n removeLabel?: string;\n emptyLabel?: string;\n}\n\nfunction isImageAttach(item: AttachItem) {\n return item.mimeType?.startsWith('image/') ?? false;\n}\n\nfunction isLinkAttach(item: AttachItem) {\n return item.kind === 'link';\n}\n\nfunction formatFileSize(sizeBytes?: number) {\n if (sizeBytes === undefined) {\n return 'Size unknown';\n }\n\n if (sizeBytes < 1024) {\n return `${sizeBytes} B`;\n }\n\n if (sizeBytes < 1024 * 1024) {\n return `${Math.round(sizeBytes / 1024)} KB`;\n }\n\n return `${(sizeBytes / 1024 / 1024).toFixed(1)} MB`;\n}\n\nfunction getLinkHostname(url: string) {\n try {\n return new URL(url).hostname.replace(/^www\\./u, '');\n } catch {\n return url;\n }\n}\n\nconst Attach: React.FC<AttachProps> = ({\n items,\n onRemove,\n removeLabel = 'Удалить',\n emptyLabel,\n className = '',\n ...props\n}) => {\n if (items.length === 0) {\n return null;\n }\n\n const classes = classnames('attach', className, {});\n\n return (\n <div\n className={classes}\n {...props}\n >\n <ul className=\"attach__list\">\n {items.map((item) => {\n const isLink = isLinkAttach(item);\n const isImage = !isLink && isImageAttach(item);\n\n const itemClasses = classnames('attach__item', {\n 'attach__item--link': isLink,\n 'attach__item--image': isImage,\n 'attach__item--file': !isLink && !isImage,\n });\n\n const meta = isLink\n ? getLinkHostname(item.url)\n : formatFileSize(item.sizeBytes);\n\n return (\n <li\n key={item.id}\n className={itemClasses}\n >\n <a\n className=\"attach__link\"\n href={item.url}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {isImage ? (\n <img\n className=\"attach__preview\"\n src={item.url}\n alt={item.name}\n />\n ) : (\n <span className=\"attach__file\">\n <span className=\"attach__name\">\n {item.name}\n </span>\n\n <span className=\"attach__meta\">\n {meta}\n </span>\n </span>\n )}\n </a>\n\n {onRemove && (\n <button\n className=\"attach__remove\"\n type=\"button\"\n aria-label={`${removeLabel}: ${item.name}`}\n onClick={() => onRemove(item.id)}\n >\n {removeLabel}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n </div>\n );\n};\n\nexport default Attach;"]}
@@ -2,8 +2,9 @@
2
2
  /* color */
3
3
  --attachment-color: var(--color-text);
4
4
  --attachment-item-bg: var(--color-control);
5
+ --attachment-item-color: var(--color-text-control);
5
6
  --attachment-border-color: var(--color-line);
6
- --attachment-size-color: var(--color-text-note);
7
+ --attachment-item-meta-color: var(--color-text-note);
7
8
 
8
9
  color: var(--attachment-color);
9
10
 
@@ -37,6 +38,10 @@
37
38
  }
38
39
 
39
40
  .attach__list {
41
+ /* color */
42
+
43
+ /* typography */
44
+
40
45
  /* size */
41
46
  display: flex;
42
47
  flex-direction: column;
@@ -46,11 +51,18 @@
46
51
 
47
52
  /* border */
48
53
  list-style: none;
54
+
55
+ /* depth */
56
+
57
+ /* motion */
49
58
  }
50
59
 
51
60
  .attach__item {
52
61
  /* color */
53
62
  background: var(--attachment-item-bg);
63
+ color: var(--attachment-item-color);
64
+
65
+ /* typography */
54
66
 
55
67
  /* size */
56
68
  display: flex;
@@ -65,24 +77,49 @@
65
77
  solid
66
78
  var(--attachment-border-color);
67
79
  border-radius: var(--attachment-radius);
80
+
81
+ /* depth */
82
+
83
+ /* motion */
68
84
  }
69
85
 
70
86
  .attach__link {
71
87
  /* color */
72
88
  color: inherit;
73
89
 
90
+ /* typography */
91
+ text-decoration: none;
92
+
74
93
  /* size */
75
94
  min-width: 0;
76
95
 
77
- /* typography */
78
- text-decoration: none;
96
+ /* border */
97
+
98
+ /* depth */
99
+
100
+ /* motion */
79
101
  }
80
102
 
81
103
  .attach__link:hover .attach__name {
104
+ /* color */
105
+
106
+ /* typography */
82
107
  text-decoration: underline;
108
+
109
+ /* size */
110
+
111
+ /* border */
112
+
113
+ /* depth */
114
+
115
+ /* motion */
83
116
  }
84
117
 
85
118
  .attach__preview {
119
+ /* color */
120
+
121
+ /* typography */
122
+
86
123
  /* size */
87
124
  display: block;
88
125
  max-width: var(--attachment-preview-max-width);
@@ -91,30 +128,60 @@
91
128
 
92
129
  /* border */
93
130
  border-radius: var(--attachment-radius);
131
+
132
+ /* depth */
133
+
134
+ /* motion */
94
135
  }
95
136
 
96
137
  .attach__file {
138
+ /* color */
139
+
140
+ /* typography */
141
+
97
142
  /* size */
98
143
  display: flex;
99
144
  flex-direction: column;
100
145
  min-width: 0;
146
+
147
+ /* border */
148
+
149
+ /* depth */
150
+
151
+ /* motion */
101
152
  }
102
153
 
103
154
  .attach__name {
104
- /* size */
105
- overflow: hidden;
155
+ /* color */
106
156
 
107
157
  /* typography */
108
158
  text-overflow: ellipsis;
109
159
  white-space: nowrap;
160
+
161
+ /* size */
162
+ overflow: hidden;
163
+
164
+ /* border */
165
+
166
+ /* depth */
167
+
168
+ /* motion */
110
169
  }
111
170
 
112
- .attach__size {
171
+ .attach__meta {
113
172
  /* color */
114
- color: var(--attachment-size-color);
173
+ color: var(--attachment-item-meta-color);
115
174
 
116
175
  /* typography */
117
176
  font-size: 0.85em;
177
+
178
+ /* size */
179
+
180
+ /* border */
181
+
182
+ /* depth */
183
+
184
+ /* motion */
118
185
  }
119
186
 
120
187
  .attach__remove {
@@ -132,10 +199,23 @@
132
199
  /* border */
133
200
  border: 0;
134
201
 
202
+ /* depth */
203
+
135
204
  /* motion */
136
205
  cursor: pointer;
137
206
  }
138
207
 
139
208
  .attach__remove:hover {
209
+ /* color */
210
+
211
+ /* typography */
140
212
  text-decoration: underline;
213
+
214
+ /* size */
215
+
216
+ /* border */
217
+
218
+ /* depth */
219
+
220
+ /* motion */
141
221
  }
@@ -1,9 +1,11 @@
1
1
  import React from 'react';
2
2
 
3
+ type AttachItemKind = 'file' | 'link';
3
4
  interface AttachItem {
4
5
  id: string;
5
6
  name: string;
6
7
  url: string;
8
+ kind?: AttachItemKind;
7
9
  mimeType?: string;
8
10
  sizeBytes?: number;
9
11
  }
@@ -15,4 +17,4 @@ interface AttachProps extends React.HTMLAttributes<HTMLDivElement> {
15
17
  }
16
18
  declare const Attach: React.FC<AttachProps>;
17
19
 
18
- export { type AttachItem, type AttachProps, Attach as default };
20
+ export { type AttachItem, type AttachItemKind, type AttachProps, Attach as default };
@@ -1,9 +1,11 @@
1
1
  import React from 'react';
2
2
 
3
+ type AttachItemKind = 'file' | 'link';
3
4
  interface AttachItem {
4
5
  id: string;
5
6
  name: string;
6
7
  url: string;
8
+ kind?: AttachItemKind;
7
9
  mimeType?: string;
8
10
  sizeBytes?: number;
9
11
  }
@@ -15,4 +17,4 @@ interface AttachProps extends React.HTMLAttributes<HTMLDivElement> {
15
17
  }
16
18
  declare const Attach: React.FC<AttachProps>;
17
19
 
18
- export { type AttachItem, type AttachProps, Attach as default };
20
+ export { type AttachItem, type AttachItemKind, type AttachProps, Attach as default };
@@ -5,6 +5,9 @@ import { classnames } from '../helpers/classnames';
5
5
  function isImageAttach(item) {
6
6
  return item.mimeType?.startsWith("image/") ?? false;
7
7
  }
8
+ function isLinkAttach(item) {
9
+ return item.kind === "link";
10
+ }
8
11
  function formatFileSize(sizeBytes) {
9
12
  if (sizeBytes === void 0) {
10
13
  return "Size unknown";
@@ -17,6 +20,13 @@ function formatFileSize(sizeBytes) {
17
20
  }
18
21
  return `${(sizeBytes / 1024 / 1024).toFixed(1)} MB`;
19
22
  }
23
+ function getLinkHostname(url) {
24
+ try {
25
+ return new URL(url).hostname.replace(/^www\./u, "");
26
+ } catch {
27
+ return url;
28
+ }
29
+ }
20
30
  const Attach = ({
21
31
  items,
22
32
  onRemove,
@@ -35,11 +45,18 @@ const Attach = ({
35
45
  className: classes,
36
46
  ...props,
37
47
  children: /* @__PURE__ */ jsx("ul", { className: "attach__list", children: items.map((item) => {
38
- const isImage = isImageAttach(item);
48
+ const isLink = isLinkAttach(item);
49
+ const isImage = !isLink && isImageAttach(item);
50
+ const itemClasses = classnames("attach__item", {
51
+ "attach__item--link": isLink,
52
+ "attach__item--image": isImage,
53
+ "attach__item--file": !isLink && !isImage
54
+ });
55
+ const meta = isLink ? getLinkHostname(item.url) : formatFileSize(item.sizeBytes);
39
56
  return /* @__PURE__ */ jsxs(
40
57
  "li",
41
58
  {
42
- className: "attach__item",
59
+ className: itemClasses,
43
60
  children: [
44
61
  /* @__PURE__ */ jsx(
45
62
  "a",
@@ -57,7 +74,7 @@ const Attach = ({
57
74
  }
58
75
  ) : /* @__PURE__ */ jsxs("span", { className: "attach__file", children: [
59
76
  /* @__PURE__ */ jsx("span", { className: "attach__name", children: item.name }),
60
- /* @__PURE__ */ jsx("span", { className: "attach__size", children: formatFileSize(item.sizeBytes) })
77
+ /* @__PURE__ */ jsx("span", { className: "attach__meta", children: meta })
61
78
  ] })
62
79
  }
63
80
  ),
@@ -66,7 +83,7 @@ const Attach = ({
66
83
  {
67
84
  className: "attach__remove",
68
85
  type: "button",
69
- "aria-label": `${removeLabel} \u0444\u0430\u0439\u043B ${item.name}`,
86
+ "aria-label": `${removeLabel}: ${item.name}`,
70
87
  onClick: () => onRemove(item.id),
71
88
  children: removeLabel
72
89
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/attach/attach.tsx"],"names":[],"mappings":"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","file":"attach.js","sourcesContent":["import React from 'react';\nimport './attach.css';\nimport { classnames } from '../helpers/classnames';\n\nexport interface AttachItem {\n id: string;\n name: string;\n url: string;\n mimeType?: string;\n sizeBytes?: number;\n}\n\nexport interface AttachProps\n extends React.HTMLAttributes<HTMLDivElement> {\n items: AttachItem[];\n onRemove?: (id: string) => void;\n removeLabel?: string;\n emptyLabel?: string;\n}\n\nfunction isImageAttach(item: AttachItem) {\n return item.mimeType?.startsWith('image/') ?? false;\n}\n\nfunction formatFileSize(sizeBytes?: number) {\n if (sizeBytes === undefined) {\n return 'Size unknown';\n }\n\n if (sizeBytes < 1024) {\n return `${sizeBytes} B`;\n }\n\n if (sizeBytes < 1024 * 1024) {\n return `${Math.round(sizeBytes / 1024)} KB`;\n }\n\n return `${(sizeBytes / 1024 / 1024).toFixed(1)} MB`;\n}\n\nconst Attach: React.FC<AttachProps> = ({\n items,\n onRemove,\n removeLabel = 'Удалить',\n emptyLabel,\n className = '',\n ...props\n}) => {\n if (items.length === 0) {\n return null;\n }\n\n const classes = classnames('attach', className, {});\n\n return (\n <div\n className={classes}\n {...props}\n >\n <ul className=\"attach__list\">\n {items.map((item) => {\n const isImage = isImageAttach(item);\n\n return (\n <li\n key={item.id}\n className=\"attach__item\"\n >\n <a\n className=\"attach__link\"\n href={item.url}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {isImage ? (\n <img\n className=\"attach__preview\"\n src={item.url}\n alt={item.name}\n />\n ) : (\n <span className=\"attach__file\">\n <span className=\"attach__name\">\n {item.name}\n </span>\n\n <span className=\"attach__size\">\n {formatFileSize(item.sizeBytes)}\n </span>\n </span>\n )}\n </a>\n\n {onRemove && (\n <button\n className=\"attach__remove\"\n type=\"button\"\n aria-label={`${removeLabel} файл ${item.name}`}\n onClick={() => onRemove(item.id)}\n >\n {removeLabel}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n </div>\n );\n};\n\nexport default Attach;"]}
1
+ {"version":3,"sources":["../../../src/components/attach/attach.tsx"],"names":[],"mappings":";;;;AAuBA,SAAS,cAAc,IAAA,EAAkB;AACvC,EAAA,OAAO,IAAA,CAAK,QAAA,EAAU,UAAA,CAAW,QAAQ,CAAA,IAAK,KAAA;AAChD;AAEA,SAAS,aAAa,IAAA,EAAkB;AACtC,EAAA,OAAO,KAAK,IAAA,KAAS,MAAA;AACvB;AAEA,SAAS,eAAe,SAAA,EAAoB;AAC1C,EAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,IAAA,OAAO,cAAA;AAAA,EACT;AAEA,EAAA,IAAI,YAAY,IAAA,EAAM;AACpB,IAAA,OAAO,GAAG,SAAS,CAAA,EAAA,CAAA;AAAA,EACrB;AAEA,EAAA,IAAI,SAAA,GAAY,OAAO,IAAA,EAAM;AAC3B,IAAA,OAAO,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,IAAI,CAAC,CAAA,GAAA,CAAA;AAAA,EACxC;AAEA,EAAA,OAAO,IAAI,SAAA,GAAY,IAAA,GAAO,IAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,CAAA;AAChD;AAEA,SAAS,gBAAgB,GAAA,EAAa;AACpC,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,GAAA,CAAI,GAAG,EAAE,QAAA,CAAS,OAAA,CAAQ,WAAW,EAAE,CAAA;AAAA,EACpD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,GAAA;AAAA,EACT;AACF;AAEA,MAAM,SAAgC,CAAC;AAAA,EACrC,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,4CAAA;AAAA,EACd,UAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,QAAA,EAAU,SAAA,EAAW,EAAE,CAAA;AAElD,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,OAAA;AAAA,MACV,GAAG,KAAA;AAAA,MAEJ,8BAAC,IAAA,EAAA,EAAG,SAAA,EAAU,gBACX,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACnB,QAAA,MAAM,MAAA,GAAS,aAAa,IAAI,CAAA;AAChC,QAAA,MAAM,OAAA,GAAU,CAAC,MAAA,IAAU,aAAA,CAAc,IAAI,CAAA;AAE7C,QAAA,MAAM,WAAA,GAAc,WAAW,cAAA,EAAgB;AAAA,UAC7C,oBAAA,EAAsB,MAAA;AAAA,UACtB,qBAAA,EAAuB,OAAA;AAAA,UACvB,oBAAA,EAAsB,CAAC,MAAA,IAAU,CAAC;AAAA,SACnC,CAAA;AAED,QAAA,MAAM,IAAA,GAAO,SACT,eAAA,CAAgB,IAAA,CAAK,GAAG,CAAA,GACxB,cAAA,CAAe,KAAK,SAAS,CAAA;AAEjC,QAAA,uBACE,IAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YAEC,SAAA,EAAW,WAAA;AAAA,YAEX,QAAA,EAAA;AAAA,8BAAA,GAAA;AAAA,gBAAC,GAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,cAAA;AAAA,kBACV,MAAM,IAAA,CAAK,GAAA;AAAA,kBACX,MAAA,EAAO,QAAA;AAAA,kBACP,GAAA,EAAI,YAAA;AAAA,kBAEH,QAAA,EAAA,OAAA,mBACC,GAAA;AAAA,oBAAC,KAAA;AAAA,oBAAA;AAAA,sBACC,SAAA,EAAU,iBAAA;AAAA,sBACV,KAAK,IAAA,CAAK,GAAA;AAAA,sBACV,KAAK,IAAA,CAAK;AAAA;AAAA,mBACZ,mBAEA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,cAAA,EACd,QAAA,EAAA;AAAA,oCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,cAAA,EACb,QAAA,EAAA,IAAA,CAAK,IAAA,EACR,CAAA;AAAA,oCAEA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,cAAA,EACb,QAAA,EAAA,IAAA,EACH;AAAA,mBAAA,EACF;AAAA;AAAA,eAEJ;AAAA,cAEC,QAAA,oBACC,GAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,gBAAA;AAAA,kBACV,IAAA,EAAK,QAAA;AAAA,kBACL,YAAA,EAAY,CAAA,EAAG,WAAW,CAAA,EAAA,EAAK,KAAK,IAAI,CAAA,CAAA;AAAA,kBACxC,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA,CAAK,EAAE,CAAA;AAAA,kBAE9B,QAAA,EAAA;AAAA;AAAA;AACH;AAAA,WAAA;AAAA,UApCG,IAAA,CAAK;AAAA,SAsCZ;AAAA,MAEJ,CAAC,CAAA,EACH;AAAA;AAAA,GACF;AAEJ,CAAA;AAEA,IAAO,cAAA,GAAQ","file":"attach.js","sourcesContent":["import React from 'react';\nimport './attach.css';\nimport { classnames } from '../helpers/classnames';\n\nexport type AttachItemKind = 'file' | 'link';\n\nexport interface AttachItem {\n id: string;\n name: string;\n url: string;\n kind?: AttachItemKind;\n mimeType?: string;\n sizeBytes?: number;\n}\n\nexport interface AttachProps\n extends React.HTMLAttributes<HTMLDivElement> {\n items: AttachItem[];\n onRemove?: (id: string) => void;\n removeLabel?: string;\n emptyLabel?: string;\n}\n\nfunction isImageAttach(item: AttachItem) {\n return item.mimeType?.startsWith('image/') ?? false;\n}\n\nfunction isLinkAttach(item: AttachItem) {\n return item.kind === 'link';\n}\n\nfunction formatFileSize(sizeBytes?: number) {\n if (sizeBytes === undefined) {\n return 'Size unknown';\n }\n\n if (sizeBytes < 1024) {\n return `${sizeBytes} B`;\n }\n\n if (sizeBytes < 1024 * 1024) {\n return `${Math.round(sizeBytes / 1024)} KB`;\n }\n\n return `${(sizeBytes / 1024 / 1024).toFixed(1)} MB`;\n}\n\nfunction getLinkHostname(url: string) {\n try {\n return new URL(url).hostname.replace(/^www\\./u, '');\n } catch {\n return url;\n }\n}\n\nconst Attach: React.FC<AttachProps> = ({\n items,\n onRemove,\n removeLabel = 'Удалить',\n emptyLabel,\n className = '',\n ...props\n}) => {\n if (items.length === 0) {\n return null;\n }\n\n const classes = classnames('attach', className, {});\n\n return (\n <div\n className={classes}\n {...props}\n >\n <ul className=\"attach__list\">\n {items.map((item) => {\n const isLink = isLinkAttach(item);\n const isImage = !isLink && isImageAttach(item);\n\n const itemClasses = classnames('attach__item', {\n 'attach__item--link': isLink,\n 'attach__item--image': isImage,\n 'attach__item--file': !isLink && !isImage,\n });\n\n const meta = isLink\n ? getLinkHostname(item.url)\n : formatFileSize(item.sizeBytes);\n\n return (\n <li\n key={item.id}\n className={itemClasses}\n >\n <a\n className=\"attach__link\"\n href={item.url}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {isImage ? (\n <img\n className=\"attach__preview\"\n src={item.url}\n alt={item.name}\n />\n ) : (\n <span className=\"attach__file\">\n <span className=\"attach__name\">\n {item.name}\n </span>\n\n <span className=\"attach__meta\">\n {meta}\n </span>\n </span>\n )}\n </a>\n\n {onRemove && (\n <button\n className=\"attach__remove\"\n type=\"button\"\n aria-label={`${removeLabel}: ${item.name}`}\n onClick={() => onRemove(item.id)}\n >\n {removeLabel}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n </div>\n );\n};\n\nexport default Attach;"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jvetrau-ds",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Multi-brand React design system with semantic tokens",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
package/styles.css CHANGED
@@ -31,8 +31,9 @@
31
31
  /* color */
32
32
  --attachment-color: var(--color-text);
33
33
  --attachment-item-bg: var(--color-control);
34
+ --attachment-item-color: var(--color-text-control);
34
35
  --attachment-border-color: var(--color-line);
35
- --attachment-size-color: var(--color-text-note);
36
+ --attachment-item-meta-color: var(--color-text-note);
36
37
 
37
38
  color: var(--attachment-color);
38
39
 
@@ -66,6 +67,10 @@
66
67
  }
67
68
 
68
69
  .attach__list {
70
+ /* color */
71
+
72
+ /* typography */
73
+
69
74
  /* size */
70
75
  display: flex;
71
76
  flex-direction: column;
@@ -75,11 +80,18 @@
75
80
 
76
81
  /* border */
77
82
  list-style: none;
83
+
84
+ /* depth */
85
+
86
+ /* motion */
78
87
  }
79
88
 
80
89
  .attach__item {
81
90
  /* color */
82
91
  background: var(--attachment-item-bg);
92
+ color: var(--attachment-item-color);
93
+
94
+ /* typography */
83
95
 
84
96
  /* size */
85
97
  display: flex;
@@ -94,24 +106,49 @@
94
106
  solid
95
107
  var(--attachment-border-color);
96
108
  border-radius: var(--attachment-radius);
109
+
110
+ /* depth */
111
+
112
+ /* motion */
97
113
  }
98
114
 
99
115
  .attach__link {
100
116
  /* color */
101
117
  color: inherit;
102
118
 
119
+ /* typography */
120
+ text-decoration: none;
121
+
103
122
  /* size */
104
123
  min-width: 0;
105
124
 
106
- /* typography */
107
- text-decoration: none;
125
+ /* border */
126
+
127
+ /* depth */
128
+
129
+ /* motion */
108
130
  }
109
131
 
110
132
  .attach__link:hover .attach__name {
133
+ /* color */
134
+
135
+ /* typography */
111
136
  text-decoration: underline;
137
+
138
+ /* size */
139
+
140
+ /* border */
141
+
142
+ /* depth */
143
+
144
+ /* motion */
112
145
  }
113
146
 
114
147
  .attach__preview {
148
+ /* color */
149
+
150
+ /* typography */
151
+
115
152
  /* size */
116
153
  display: block;
117
154
  max-width: var(--attachment-preview-max-width);
@@ -120,30 +157,60 @@
120
157
 
121
158
  /* border */
122
159
  border-radius: var(--attachment-radius);
160
+
161
+ /* depth */
162
+
163
+ /* motion */
123
164
  }
124
165
 
125
166
  .attach__file {
167
+ /* color */
168
+
169
+ /* typography */
170
+
126
171
  /* size */
127
172
  display: flex;
128
173
  flex-direction: column;
129
174
  min-width: 0;
175
+
176
+ /* border */
177
+
178
+ /* depth */
179
+
180
+ /* motion */
130
181
  }
131
182
 
132
183
  .attach__name {
133
- /* size */
134
- overflow: hidden;
184
+ /* color */
135
185
 
136
186
  /* typography */
137
187
  text-overflow: ellipsis;
138
188
  white-space: nowrap;
189
+
190
+ /* size */
191
+ overflow: hidden;
192
+
193
+ /* border */
194
+
195
+ /* depth */
196
+
197
+ /* motion */
139
198
  }
140
199
 
141
- .attach__size {
200
+ .attach__meta {
142
201
  /* color */
143
- color: var(--attachment-size-color);
202
+ color: var(--attachment-item-meta-color);
144
203
 
145
204
  /* typography */
146
205
  font-size: 0.85em;
206
+
207
+ /* size */
208
+
209
+ /* border */
210
+
211
+ /* depth */
212
+
213
+ /* motion */
147
214
  }
148
215
 
149
216
  .attach__remove {
@@ -161,12 +228,25 @@
161
228
  /* border */
162
229
  border: 0;
163
230
 
231
+ /* depth */
232
+
164
233
  /* motion */
165
234
  cursor: pointer;
166
235
  }
167
236
 
168
237
  .attach__remove:hover {
238
+ /* color */
239
+
240
+ /* typography */
169
241
  text-decoration: underline;
242
+
243
+ /* size */
244
+
245
+ /* border */
246
+
247
+ /* depth */
248
+
249
+ /* motion */
170
250
  }
171
251
 
172
252
  /* src/components/avatar/avatar.css */