@twentyfirstmedia/ui-core 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/components/admin.d.ts.map +1 -1
  2. package/dist/components/admin.js +31 -21
  3. package/dist/components/admin.js.map +1 -1
  4. package/dist/components/agents.d.ts.map +1 -1
  5. package/dist/components/agents.js +21 -18
  6. package/dist/components/agents.js.map +1 -1
  7. package/dist/components/app-chrome.d.ts.map +1 -1
  8. package/dist/components/app-chrome.js +5 -5
  9. package/dist/components/app-chrome.js.map +1 -1
  10. package/dist/components/approvals.d.ts.map +1 -1
  11. package/dist/components/approvals.js +2 -2
  12. package/dist/components/approvals.js.map +1 -1
  13. package/dist/components/building-blocks.d.ts.map +1 -1
  14. package/dist/components/building-blocks.js +13 -10
  15. package/dist/components/building-blocks.js.map +1 -1
  16. package/dist/components/charts.d.ts +2 -2
  17. package/dist/components/charts.d.ts.map +1 -1
  18. package/dist/components/charts.js +14 -11
  19. package/dist/components/charts.js.map +1 -1
  20. package/dist/components/chat.d.ts +2 -2
  21. package/dist/components/chat.d.ts.map +1 -1
  22. package/dist/components/chat.js +22 -18
  23. package/dist/components/chat.js.map +1 -1
  24. package/dist/components/commerce.d.ts.map +1 -1
  25. package/dist/components/commerce.js +20 -16
  26. package/dist/components/commerce.js.map +1 -1
  27. package/dist/components/data-display.d.ts +0 -5
  28. package/dist/components/data-display.d.ts.map +1 -1
  29. package/dist/components/data-display.js +41 -22
  30. package/dist/components/data-display.js.map +1 -1
  31. package/dist/components/data-table.d.ts +2 -2
  32. package/dist/components/data-table.d.ts.map +1 -1
  33. package/dist/components/data-table.js +3 -3
  34. package/dist/components/data-table.js.map +1 -1
  35. package/dist/components/developer.d.ts.map +1 -1
  36. package/dist/components/developer.js +7 -6
  37. package/dist/components/developer.js.map +1 -1
  38. package/dist/components/feedback.d.ts.map +1 -1
  39. package/dist/components/feedback.js +5 -4
  40. package/dist/components/feedback.js.map +1 -1
  41. package/dist/components/forms.d.ts.map +1 -1
  42. package/dist/components/forms.js +63 -21
  43. package/dist/components/forms.js.map +1 -1
  44. package/dist/components/foundation.d.ts.map +1 -1
  45. package/dist/components/foundation.js +13 -9
  46. package/dist/components/foundation.js.map +1 -1
  47. package/dist/components/household.d.ts +19 -0
  48. package/dist/components/household.d.ts.map +1 -0
  49. package/dist/components/household.js +137 -0
  50. package/dist/components/household.js.map +1 -0
  51. package/dist/components/index.d.ts +4 -1
  52. package/dist/components/index.d.ts.map +1 -1
  53. package/dist/components/index.js +4 -1
  54. package/dist/components/index.js.map +1 -1
  55. package/dist/components/inputs.d.ts.map +1 -1
  56. package/dist/components/inputs.js +33 -8
  57. package/dist/components/inputs.js.map +1 -1
  58. package/dist/components/life.d.ts +26 -0
  59. package/dist/components/life.d.ts.map +1 -0
  60. package/dist/components/life.js +186 -0
  61. package/dist/components/life.js.map +1 -0
  62. package/dist/components/mail.d.ts.map +1 -1
  63. package/dist/components/mail.js +5 -5
  64. package/dist/components/mail.js.map +1 -1
  65. package/dist/components/media.d.ts.map +1 -1
  66. package/dist/components/media.js +62 -11
  67. package/dist/components/media.js.map +1 -1
  68. package/dist/components/navigation.d.ts +3 -1
  69. package/dist/components/navigation.d.ts.map +1 -1
  70. package/dist/components/navigation.js +287 -20
  71. package/dist/components/navigation.js.map +1 -1
  72. package/dist/components/operations.d.ts.map +1 -1
  73. package/dist/components/operations.js +10 -10
  74. package/dist/components/operations.js.map +1 -1
  75. package/dist/components/overlays.d.ts.map +1 -1
  76. package/dist/components/overlays.js +2 -2
  77. package/dist/components/overlays.js.map +1 -1
  78. package/dist/components/previews.js +2 -2
  79. package/dist/components/previews.js.map +1 -1
  80. package/dist/components/primitives.js +2 -2
  81. package/dist/components/primitives.js.map +1 -1
  82. package/dist/components/qr-code.d.ts +8 -0
  83. package/dist/components/qr-code.d.ts.map +1 -0
  84. package/dist/components/qr-code.js +18 -0
  85. package/dist/components/qr-code.js.map +1 -0
  86. package/dist/components/real-estate.d.ts.map +1 -1
  87. package/dist/components/real-estate.js +5 -5
  88. package/dist/components/real-estate.js.map +1 -1
  89. package/dist/components/rich-text-editor.d.ts.map +1 -1
  90. package/dist/components/rich-text-editor.js +1 -1
  91. package/dist/components/rich-text-editor.js.map +1 -1
  92. package/dist/components/select-menu.js +1 -1
  93. package/dist/components/select-menu.js.map +1 -1
  94. package/dist/components/shell.d.ts +0 -4
  95. package/dist/components/shell.d.ts.map +1 -1
  96. package/dist/components/shell.js +100 -7
  97. package/dist/components/shell.js.map +1 -1
  98. package/dist/components/site.d.ts.map +1 -1
  99. package/dist/components/site.js +8 -6
  100. package/dist/components/site.js.map +1 -1
  101. package/dist/components/status.d.ts.map +1 -1
  102. package/dist/components/status.js +2 -2
  103. package/dist/components/status.js.map +1 -1
  104. package/dist/components/system.d.ts.map +1 -1
  105. package/dist/components/system.js +3 -2
  106. package/dist/components/system.js.map +1 -1
  107. package/dist/components/types.d.ts +589 -18
  108. package/dist/components/types.d.ts.map +1 -1
  109. package/dist/components/workspace.d.ts.map +1 -1
  110. package/dist/components/workspace.js +15 -12
  111. package/dist/components/workspace.js.map +1 -1
  112. package/dist/index.d.ts +1 -1
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +1 -1
  115. package/dist/index.js.map +1 -1
  116. package/dist/qr.d.ts +14 -0
  117. package/dist/qr.d.ts.map +1 -0
  118. package/dist/qr.js +298 -0
  119. package/dist/qr.js.map +1 -0
  120. package/dist/strings.d.ts +126 -4
  121. package/dist/strings.d.ts.map +1 -1
  122. package/dist/strings.js +88 -1
  123. package/dist/strings.js.map +1 -1
  124. package/dist/themes.css +15592 -10463
  125. package/package.json +2 -1
  126. package/src/components/admin.tsx +66 -23
  127. package/src/components/agents.tsx +22 -20
  128. package/src/components/app-chrome.tsx +9 -5
  129. package/src/components/approvals.tsx +3 -1
  130. package/src/components/building-blocks.tsx +24 -13
  131. package/src/components/charts.tsx +17 -12
  132. package/src/components/chat.tsx +54 -31
  133. package/src/components/commerce.tsx +58 -24
  134. package/src/components/data-display.tsx +106 -38
  135. package/src/components/data-table.tsx +11 -7
  136. package/src/components/developer.tsx +15 -6
  137. package/src/components/feedback.tsx +5 -3
  138. package/src/components/forms.tsx +101 -23
  139. package/src/components/foundation.tsx +9 -5
  140. package/src/components/household.tsx +489 -0
  141. package/src/components/index.ts +32 -1
  142. package/src/components/inputs.tsx +44 -7
  143. package/src/components/life.tsx +672 -0
  144. package/src/components/mail.tsx +7 -3
  145. package/src/components/media.tsx +88 -16
  146. package/src/components/navigation.tsx +651 -71
  147. package/src/components/operations.tsx +17 -8
  148. package/src/components/overlays.tsx +7 -2
  149. package/src/components/previews.tsx +2 -2
  150. package/src/components/primitives.tsx +2 -2
  151. package/src/components/qr-code.tsx +30 -0
  152. package/src/components/real-estate.tsx +7 -4
  153. package/src/components/rich-text-editor.tsx +7 -1
  154. package/src/components/select-menu.tsx +1 -1
  155. package/src/components/shell.tsx +237 -11
  156. package/src/components/site.tsx +18 -4
  157. package/src/components/status.tsx +2 -0
  158. package/src/components/system.tsx +3 -2
  159. package/src/components/types.ts +583 -18
  160. package/src/components/workspace.tsx +37 -15
  161. package/src/index.ts +2 -0
  162. package/src/qr.ts +300 -0
  163. package/src/strings.ts +297 -1
@@ -30,6 +30,8 @@ export function AccountSwitcher(p: AccountSwitcherProps) {
30
30
  const cur = (p.accounts || []).find((a) => a.address === p.value);
31
31
  return (
32
32
  <Popover
33
+ style={p.style}
34
+ className={p.className}
33
35
  width={320}
34
36
  trigger={(s) => (
35
37
  <button
@@ -103,7 +105,7 @@ export function AccountSwitcher(p: AccountSwitcherProps) {
103
105
  export function InboxList(p: InboxListProps) {
104
106
  const t = useStrings(MAIL_STRINGS);
105
107
  return (
106
- <div className="tf-inboxlist" role="list">
108
+ <div style={p.style} className={cx("tf-inboxlist", p.className)} role="list">
107
109
  {(p.items || []).map((m) => (
108
110
  <button
109
111
  key={m.id}
@@ -149,7 +151,7 @@ export function MailThread(p: MailThreadProps) {
149
151
  (p.messages || []).length ? [p.messages[p.messages.length - 1].id] : [],
150
152
  );
151
153
  return (
152
- <div className="tf-thread">
154
+ <div style={p.style} className={cx("tf-thread", p.className)}>
153
155
  {p.subject && <h3 className="tf-thread-subject">{p.subject}</h3>}
154
156
  {(p.messages || []).map((m) => {
155
157
  const o = open[0].indexOf(m.id) > -1;
@@ -213,7 +215,7 @@ export function SignatureEditor(p: SignatureEditorProps) {
213
215
  v[1](n);
214
216
  }
215
217
  return (
216
- <div className="tf-sig">
218
+ <div style={p.style} className={cx("tf-sig", p.className)}>
217
219
  <div
218
220
  className="tf-col"
219
221
  style={{
@@ -257,6 +259,8 @@ export function SignatureEditor(p: SignatureEditorProps) {
257
259
  export function AttachmentPreview(p: AttachmentPreviewProps) {
258
260
  return (
259
261
  <Drawer
262
+ style={p.style}
263
+ className={p.className}
260
264
  title={p.name}
261
265
  subtitle={p.meta}
262
266
  onClose={p.onClose}
@@ -2,7 +2,7 @@
2
2
  import * as React from "react";
3
3
  import { useFormat, useStrings } from "../context.js";
4
4
  import { MEDIA_STRINGS } from "../strings.js";
5
- import { useControlled } from "../hooks.js";
5
+ import { moveFocus, useControlled } from "../hooks.js";
6
6
  import { cx } from "../cx.js";
7
7
  import { Icon } from "../Icon.js";
8
8
  import { Portal } from "../portal.js";
@@ -23,7 +23,7 @@ export function ImageVariants(p: ImageVariantsProps) {
23
23
  const sel = useControlled<string | number>(p.selected, p.variants?.[0]?.id ?? "", p.onSelect),
24
24
  cur: Partial<ImageVariant> = (p.variants || []).find((v) => v.id === sel[0]) || {};
25
25
  return (
26
- <div className="tf-imgvar">
26
+ <div style={p.style} className={cx("tf-imgvar", p.className)}>
27
27
  <div
28
28
  className="tf-imgvar-stage"
29
29
  style={
@@ -94,19 +94,52 @@ export function ImageVariants(p: ImageVariantsProps) {
94
94
  export function Gallery(p: GalleryProps) {
95
95
  const t = useStrings(MEDIA_STRINGS);
96
96
  const items = p.items || [],
97
- i = React.useState(p.start || 0),
97
+ i = useControlled(p.index, p.start || 0, p.onIndexChange),
98
98
  full = React.useState(false),
99
99
  n = items.length,
100
100
  cur: GalleryItem = items[i[0]] || {};
101
+ const box = React.useRef<HTMLDivElement>(null),
102
+ thumbs = React.useRef<HTMLDivElement>(null),
103
+ opener = React.useRef<HTMLButtonElement>(null);
101
104
  function go(d: number) {
102
105
  i[1]((i[0] + d + n) % n);
103
106
  }
107
+ const restore = React.useRef(false);
108
+ function close() {
109
+ full[1](false);
110
+ restore.current = true;
111
+ }
112
+ // the full-screen button comes back after the lightbox closes: focus returns to it
113
+ React.useEffect(() => {
114
+ if (!full[0] && restore.current) {
115
+ restore.current = false;
116
+ opener.current?.focus();
117
+ }
118
+ }, [full[0]]);
119
+ // focus moves into the lightbox when it appears (the portal mounts a render later)
120
+ const attachBox = React.useCallback((n: HTMLDivElement | null) => {
121
+ box.current = n;
122
+ n?.querySelector<HTMLElement>("button")?.focus();
123
+ }, []);
104
124
  React.useEffect(() => {
105
125
  if (!full[0]) return;
126
+ const lb = box.current;
106
127
  function k(e: KeyboardEvent) {
107
- if (e.key === "Escape") full[1](false);
128
+ if (e.key === "Escape") close();
108
129
  if (e.key === "ArrowRight") go(1);
109
130
  if (e.key === "ArrowLeft") go(-1);
131
+ if (e.key === "Tab" && lb) {
132
+ const els = Array.from(lb.querySelectorAll<HTMLElement>("button"));
133
+ const a = els[0],
134
+ z = els[els.length - 1];
135
+ if (e.shiftKey && document.activeElement === a) {
136
+ e.preventDefault();
137
+ z?.focus();
138
+ } else if (!e.shiftKey && document.activeElement === z) {
139
+ e.preventDefault();
140
+ a?.focus();
141
+ }
142
+ }
110
143
  }
111
144
  document.addEventListener("keydown", k);
112
145
  return () => {
@@ -132,6 +165,19 @@ export function Gallery(p: GalleryProps) {
132
165
  const stage = (
133
166
  <div
134
167
  className="tf-gallery-stage"
168
+ role="group"
169
+ aria-label={t.imageN(i[0] + 1)}
170
+ tabIndex={n > 1 ? 0 : undefined}
171
+ onKeyDown={(e) => {
172
+ if (e.target !== e.currentTarget) return;
173
+ if (e.key === "ArrowRight") {
174
+ e.preventDefault();
175
+ go(1);
176
+ } else if (e.key === "ArrowLeft") {
177
+ e.preventDefault();
178
+ go(-1);
179
+ }
180
+ }}
135
181
  style={{
136
182
  aspectRatio: p.ratio || "3 / 2",
137
183
  }}
@@ -160,6 +206,7 @@ export function Gallery(p: GalleryProps) {
160
206
  <span className="tf-gallery-count">{i[0] + 1 + " / " + n}</span>
161
207
  {!full[0] && p.fullscreen !== false && (
162
208
  <IconButton
209
+ ref={opener}
163
210
  icon="expand"
164
211
  label={t.fullScreen}
165
212
  className="tf-gallery-full"
@@ -172,16 +219,35 @@ export function Gallery(p: GalleryProps) {
172
219
  </div>
173
220
  );
174
221
  return (
175
- <div className="tf-gallery">
222
+ <div
223
+ style={p.style}
224
+ className={cx("tf-gallery", p.className)}
225
+ role="group"
226
+ aria-label={p.label || t.images}
227
+ >
176
228
  {stage}
177
229
  {p.thumbs !== false && n > 1 && (
178
- <div className="tf-gallery-thumbs" role="tablist" aria-label={t.images}>
230
+ <div
231
+ ref={thumbs}
232
+ className="tf-gallery-thumbs"
233
+ role="tablist"
234
+ aria-label={p.label || t.images}
235
+ onKeyDown={(e) => {
236
+ if (moveFocus(e, thumbs.current, '[role="tab"]', "horizontal")) {
237
+ const k = Array.from(thumbs.current?.querySelectorAll('[role="tab"]') || []).indexOf(
238
+ document.activeElement as Element,
239
+ );
240
+ if (k > -1) i[1](k);
241
+ }
242
+ }}
243
+ >
179
244
  {items.map((it, k) => (
180
245
  <button
181
246
  key={k}
182
247
  type="button"
183
248
  role="tab"
184
249
  aria-selected={k === i[0]}
250
+ tabIndex={k === i[0] ? 0 : -1}
185
251
  className={cx(k === i[0] && "on")}
186
252
  onClick={() => {
187
253
  i[1](k);
@@ -195,15 +261,14 @@ export function Gallery(p: GalleryProps) {
195
261
  )}
196
262
  {full[0] && (
197
263
  <Portal>
198
- <div className="tf-lightbox" role="dialog" aria-modal="true" aria-label={t.images}>
199
- <IconButton
200
- icon="x"
201
- label={t.close}
202
- className="tf-lightbox-close"
203
- onClick={() => {
204
- full[1](false);
205
- }}
206
- />
264
+ <div
265
+ ref={attachBox}
266
+ className="tf-lightbox"
267
+ role="dialog"
268
+ aria-modal="true"
269
+ aria-label={p.label || t.images}
270
+ >
271
+ <IconButton icon="x" label={t.close} className="tf-lightbox-close" onClick={close} />
207
272
  <div className="tf-lightbox-stage">
208
273
  {pic(cur, "tf-gallery-img", "eager")}
209
274
  {n > 1 && (
@@ -268,9 +333,10 @@ export function BeforeAfter(p: BeforeAfterProps) {
268
333
  return (
269
334
  <div
270
335
  ref={ref}
271
- className="tf-ba"
336
+ className={cx("tf-ba", p.className)}
272
337
  style={{
273
338
  aspectRatio: p.ratio || "3 / 2",
339
+ ...p.style,
274
340
  }}
275
341
  onPointerDown={(e) => {
276
342
  drag.current = true;
@@ -283,6 +349,12 @@ export function BeforeAfter(p: BeforeAfterProps) {
283
349
  onPointerUp={() => {
284
350
  drag.current = false;
285
351
  }}
352
+ onPointerCancel={() => {
353
+ drag.current = false;
354
+ }}
355
+ onLostPointerCapture={() => {
356
+ drag.current = false;
357
+ }}
286
358
  >
287
359
  {pane(p.after, "tf-ba-img")}
288
360
  <div