@twentyfirstmedia/ui-core 0.4.0 → 0.6.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 (154) hide show
  1. package/ICONS-LICENSE +175 -0
  2. package/dist/components/admin.d.ts.map +1 -1
  3. package/dist/components/admin.js +31 -21
  4. package/dist/components/admin.js.map +1 -1
  5. package/dist/components/agents.d.ts.map +1 -1
  6. package/dist/components/agents.js +21 -18
  7. package/dist/components/agents.js.map +1 -1
  8. package/dist/components/app-chrome.d.ts.map +1 -1
  9. package/dist/components/app-chrome.js +5 -5
  10. package/dist/components/app-chrome.js.map +1 -1
  11. package/dist/components/approvals.d.ts.map +1 -1
  12. package/dist/components/approvals.js +2 -2
  13. package/dist/components/approvals.js.map +1 -1
  14. package/dist/components/building-blocks.d.ts.map +1 -1
  15. package/dist/components/building-blocks.js +13 -10
  16. package/dist/components/building-blocks.js.map +1 -1
  17. package/dist/components/charts.d.ts +2 -2
  18. package/dist/components/charts.d.ts.map +1 -1
  19. package/dist/components/charts.js +14 -11
  20. package/dist/components/charts.js.map +1 -1
  21. package/dist/components/chat.d.ts +2 -2
  22. package/dist/components/chat.d.ts.map +1 -1
  23. package/dist/components/chat.js +22 -18
  24. package/dist/components/chat.js.map +1 -1
  25. package/dist/components/commerce.d.ts.map +1 -1
  26. package/dist/components/commerce.js +20 -16
  27. package/dist/components/commerce.js.map +1 -1
  28. package/dist/components/data-display.d.ts +0 -5
  29. package/dist/components/data-display.d.ts.map +1 -1
  30. package/dist/components/data-display.js +41 -22
  31. package/dist/components/data-display.js.map +1 -1
  32. package/dist/components/data-table.d.ts +2 -2
  33. package/dist/components/data-table.d.ts.map +1 -1
  34. package/dist/components/data-table.js +3 -3
  35. package/dist/components/data-table.js.map +1 -1
  36. package/dist/components/developer.d.ts.map +1 -1
  37. package/dist/components/developer.js +7 -6
  38. package/dist/components/developer.js.map +1 -1
  39. package/dist/components/feedback.d.ts.map +1 -1
  40. package/dist/components/feedback.js +5 -4
  41. package/dist/components/feedback.js.map +1 -1
  42. package/dist/components/forms.d.ts.map +1 -1
  43. package/dist/components/forms.js +63 -21
  44. package/dist/components/forms.js.map +1 -1
  45. package/dist/components/foundation.d.ts.map +1 -1
  46. package/dist/components/foundation.js +13 -9
  47. package/dist/components/foundation.js.map +1 -1
  48. package/dist/components/index.d.ts +2 -1
  49. package/dist/components/index.d.ts.map +1 -1
  50. package/dist/components/index.js +2 -1
  51. package/dist/components/index.js.map +1 -1
  52. package/dist/components/inputs.d.ts.map +1 -1
  53. package/dist/components/inputs.js +33 -8
  54. package/dist/components/inputs.js.map +1 -1
  55. package/dist/components/mail.d.ts.map +1 -1
  56. package/dist/components/mail.js +5 -5
  57. package/dist/components/mail.js.map +1 -1
  58. package/dist/components/media.d.ts.map +1 -1
  59. package/dist/components/media.js +62 -11
  60. package/dist/components/media.js.map +1 -1
  61. package/dist/components/navigation.d.ts +3 -1
  62. package/dist/components/navigation.d.ts.map +1 -1
  63. package/dist/components/navigation.js +287 -20
  64. package/dist/components/navigation.js.map +1 -1
  65. package/dist/components/operations.d.ts.map +1 -1
  66. package/dist/components/operations.js +10 -10
  67. package/dist/components/operations.js.map +1 -1
  68. package/dist/components/overlays.d.ts.map +1 -1
  69. package/dist/components/overlays.js +2 -2
  70. package/dist/components/overlays.js.map +1 -1
  71. package/dist/components/previews.js +2 -2
  72. package/dist/components/previews.js.map +1 -1
  73. package/dist/components/primitives.js +2 -2
  74. package/dist/components/primitives.js.map +1 -1
  75. package/dist/components/qr-code.d.ts +8 -0
  76. package/dist/components/qr-code.d.ts.map +1 -0
  77. package/dist/components/qr-code.js +18 -0
  78. package/dist/components/qr-code.js.map +1 -0
  79. package/dist/components/real-estate.d.ts.map +1 -1
  80. package/dist/components/real-estate.js +5 -5
  81. package/dist/components/real-estate.js.map +1 -1
  82. package/dist/components/rich-text-editor.d.ts.map +1 -1
  83. package/dist/components/rich-text-editor.js +1 -1
  84. package/dist/components/rich-text-editor.js.map +1 -1
  85. package/dist/components/select-menu.js +1 -1
  86. package/dist/components/select-menu.js.map +1 -1
  87. package/dist/components/shell.d.ts +0 -4
  88. package/dist/components/shell.d.ts.map +1 -1
  89. package/dist/components/shell.js +100 -7
  90. package/dist/components/shell.js.map +1 -1
  91. package/dist/components/site.d.ts.map +1 -1
  92. package/dist/components/site.js +8 -6
  93. package/dist/components/site.js.map +1 -1
  94. package/dist/components/status.d.ts.map +1 -1
  95. package/dist/components/status.js +2 -2
  96. package/dist/components/status.js.map +1 -1
  97. package/dist/components/system.d.ts.map +1 -1
  98. package/dist/components/system.js +3 -2
  99. package/dist/components/system.js.map +1 -1
  100. package/dist/components/types.d.ts +257 -18
  101. package/dist/components/types.d.ts.map +1 -1
  102. package/dist/components/workspace.d.ts.map +1 -1
  103. package/dist/components/workspace.js +15 -12
  104. package/dist/components/workspace.js.map +1 -1
  105. package/dist/icon-library.d.ts +254 -3
  106. package/dist/icon-library.d.ts.map +1 -1
  107. package/dist/icon-library.js +518 -14
  108. package/dist/icon-library.js.map +1 -1
  109. package/dist/qr.d.ts +14 -0
  110. package/dist/qr.d.ts.map +1 -0
  111. package/dist/qr.js +298 -0
  112. package/dist/qr.js.map +1 -0
  113. package/dist/strings.d.ts +30 -4
  114. package/dist/strings.d.ts.map +1 -1
  115. package/dist/strings.js +15 -0
  116. package/dist/strings.js.map +1 -1
  117. package/dist/themes.css +2345 -176
  118. package/package.json +2 -1
  119. package/src/components/admin.tsx +66 -23
  120. package/src/components/agents.tsx +22 -20
  121. package/src/components/app-chrome.tsx +9 -5
  122. package/src/components/approvals.tsx +3 -1
  123. package/src/components/building-blocks.tsx +24 -13
  124. package/src/components/charts.tsx +17 -12
  125. package/src/components/chat.tsx +54 -31
  126. package/src/components/commerce.tsx +58 -24
  127. package/src/components/data-display.tsx +106 -38
  128. package/src/components/data-table.tsx +11 -7
  129. package/src/components/developer.tsx +15 -6
  130. package/src/components/feedback.tsx +5 -3
  131. package/src/components/forms.tsx +101 -23
  132. package/src/components/foundation.tsx +9 -5
  133. package/src/components/index.ts +10 -1
  134. package/src/components/inputs.tsx +44 -7
  135. package/src/components/mail.tsx +7 -3
  136. package/src/components/media.tsx +88 -16
  137. package/src/components/navigation.tsx +651 -71
  138. package/src/components/operations.tsx +17 -8
  139. package/src/components/overlays.tsx +7 -2
  140. package/src/components/previews.tsx +2 -2
  141. package/src/components/primitives.tsx +2 -2
  142. package/src/components/qr-code.tsx +30 -0
  143. package/src/components/real-estate.tsx +7 -4
  144. package/src/components/rich-text-editor.tsx +7 -1
  145. package/src/components/select-menu.tsx +1 -1
  146. package/src/components/shell.tsx +237 -11
  147. package/src/components/site.tsx +18 -4
  148. package/src/components/status.tsx +2 -0
  149. package/src/components/system.tsx +3 -2
  150. package/src/components/types.ts +261 -18
  151. package/src/components/workspace.tsx +37 -15
  152. package/src/icon-library.ts +523 -18
  153. package/src/qr.ts +300 -0
  154. package/src/strings.ts +56 -1
package/ICONS-LICENSE CHANGED
@@ -51,3 +51,178 @@ SOFTWARE.
51
51
  Brand logos (names starting with "brand") are from Simple Icons (https://simpleicons.org),
52
52
  released under CC0 1.0 Universal. The logos themselves are trademarks of their respective
53
53
  owners; use them according to each brand's guidelines.
54
+
55
+ ---
56
+
57
+ The brand logos brandLinkedin, brandMicrosoft, brandWindows, brandSlack, brandSkype, brandAmazon and
58
+ brandOpenai are from Font Awesome Free (https://fontawesome.com), whose icons are licensed under
59
+ CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/); attribution: "Font Awesome Free by
60
+ Fonticons, Inc.". They were rescaled to the kit's 24px grid. The logos are trademarks of their owners.
61
+
62
+ Font Awesome Free license:
63
+
64
+ Fonticons, Inc. (https://fontawesome.com)
65
+
66
+ --------------------------------------------------------------------------------
67
+
68
+ Font Awesome Free License
69
+
70
+ Font Awesome Free is free, open source, and GPL friendly. You can use it for
71
+ commercial projects, open source projects, or really almost whatever you want.
72
+ Full Font Awesome Free license: https://fontawesome.com/license/free.
73
+
74
+ --------------------------------------------------------------------------------
75
+
76
+ # Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)
77
+
78
+ The Font Awesome Free download is licensed under a Creative Commons
79
+ Attribution 4.0 International License and applies to all icons packaged
80
+ as SVG and JS file types.
81
+
82
+ --------------------------------------------------------------------------------
83
+
84
+ # Fonts: SIL OFL 1.1 License
85
+
86
+ In the Font Awesome Free download, the SIL OFL license applies to all icons
87
+ packaged as web and desktop font files.
88
+
89
+ Copyright (c) 2026 Fonticons, Inc. (https://fontawesome.com)
90
+ with Reserved Font Name: "Font Awesome".
91
+
92
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
93
+ This license is copied below, and is also available with a FAQ at:
94
+ http://scripts.sil.org/OFL
95
+
96
+ SIL OPEN FONT LICENSE
97
+ Version 1.1 - 26 February 2007
98
+
99
+ PREAMBLE
100
+ The goals of the Open Font License (OFL) are to stimulate worldwide
101
+ development of collaborative font projects, to support the font creation
102
+ efforts of academic and linguistic communities, and to provide a free and
103
+ open framework in which fonts may be shared and improved in partnership
104
+ with others.
105
+
106
+ The OFL allows the licensed fonts to be used, studied, modified and
107
+ redistributed freely as long as they are not sold by themselves. The
108
+ fonts, including any derivative works, can be bundled, embedded,
109
+ redistributed and/or sold with any software provided that any reserved
110
+ names are not used by derivative works. The fonts and derivatives,
111
+ however, cannot be released under any other type of license. The
112
+ requirement for fonts to remain under this license does not apply
113
+ to any document created using the fonts or their derivatives.
114
+
115
+ DEFINITIONS
116
+ "Font Software" refers to the set of files released by the Copyright
117
+ Holder(s) under this license and clearly marked as such. This may
118
+ include source files, build scripts and documentation.
119
+
120
+ "Reserved Font Name" refers to any names specified as such after the
121
+ copyright statement(s).
122
+
123
+ "Original Version" refers to the collection of Font Software components as
124
+ distributed by the Copyright Holder(s).
125
+
126
+ "Modified Version" refers to any derivative made by adding to, deleting,
127
+ or substituting — in part or in whole — any of the components of the
128
+ Original Version, by changing formats or by porting the Font Software to a
129
+ new environment.
130
+
131
+ "Author" refers to any designer, engineer, programmer, technical
132
+ writer or other person who contributed to the Font Software.
133
+
134
+ PERMISSION & CONDITIONS
135
+ Permission is hereby granted, free of charge, to any person obtaining
136
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
137
+ redistribute, and sell modified and unmodified copies of the Font
138
+ Software, subject to the following conditions:
139
+
140
+ 1) Neither the Font Software nor any of its individual components,
141
+ in Original or Modified Versions, may be sold by itself.
142
+
143
+ 2) Original or Modified Versions of the Font Software may be bundled,
144
+ redistributed and/or sold with any software, provided that each copy
145
+ contains the above copyright notice and this license. These can be
146
+ included either as stand-alone text files, human-readable headers or
147
+ in the appropriate machine-readable metadata fields within text or
148
+ binary files as long as those fields can be easily viewed by the user.
149
+
150
+ 3) No Modified Version of the Font Software may use the Reserved Font
151
+ Name(s) unless explicit written permission is granted by the corresponding
152
+ Copyright Holder. This restriction only applies to the primary font name as
153
+ presented to the users.
154
+
155
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
156
+ Software shall not be used to promote, endorse or advertise any
157
+ Modified Version, except to acknowledge the contribution(s) of the
158
+ Copyright Holder(s) and the Author(s) or with their explicit written
159
+ permission.
160
+
161
+ 5) The Font Software, modified or unmodified, in part or in whole,
162
+ must be distributed entirely under this license, and must not be
163
+ distributed under any other license. The requirement for fonts to
164
+ remain under this license does not apply to any document created
165
+ using the Font Software.
166
+
167
+ TERMINATION
168
+ This license becomes null and void if any of the above conditions are
169
+ not met.
170
+
171
+ DISCLAIMER
172
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
173
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
174
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
175
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
176
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
177
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
178
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
179
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
180
+ OTHER DEALINGS IN THE FONT SOFTWARE.
181
+
182
+ --------------------------------------------------------------------------------
183
+
184
+ # Code: MIT License (https://opensource.org/licenses/MIT)
185
+
186
+ In the Font Awesome Free download, the MIT license applies to all non-font and
187
+ non-icon files.
188
+
189
+ Copyright 2026 Fonticons, Inc.
190
+
191
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
192
+ this software and associated documentation files (the "Software"), to deal in the
193
+ Software without restriction, including without limitation the rights to use, copy,
194
+ modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
195
+ and to permit persons to whom the Software is furnished to do so, subject to the
196
+ following conditions:
197
+
198
+ The above copyright notice and this permission notice shall be included in all
199
+ copies or substantial portions of the Software.
200
+
201
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
202
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
203
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
204
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
205
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
206
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
207
+
208
+ --------------------------------------------------------------------------------
209
+
210
+ # Attribution
211
+
212
+ Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font
213
+ Awesome Free files already contain embedded comments with sufficient
214
+ attribution, so you shouldn't need to do anything additional when using these
215
+ files normally.
216
+
217
+ We've kept attribution comments terse, so we ask that you do not actively work
218
+ to remove them from files, especially code. They're a great way for folks to
219
+ learn about Font Awesome.
220
+
221
+ --------------------------------------------------------------------------------
222
+
223
+ # Brand Icons
224
+
225
+ All brand icons are trademarks of their respective owners. The use of these
226
+ trademarks does not indicate endorsement of the trademark holder by Font
227
+ Awesome, nor vice versa. **Please do not use brand logos for any purpose except
228
+ to represent the company, product, or service to which they refer.**
@@ -1 +1 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/components/admin.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAmB/B,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,eAAe,EACf,eAAe,EAEf,iBAAiB,EAEjB,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EAEnB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,mBAAmB,EAEnB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAGpB,wBAAgB,WAAW,CAAC,CAAC,EAAE,gBAAgB,qBA8F9C;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,YAAY,qBAgDtC;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,iBAAiB,qBA0DhD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBAmE5C;AAGD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,aAAa,qBAkHxC;AAOD,wBAAgB,SAAS,sBAqBxB;AAID,wBAAgB,OAAO,CAAC,CAAC,EAAE,YAAY,qBAuGtC;AAKD,wBAAgB,WAAW,CAAC,CAAC,EAAE,gBAAgB,qBAwE9C;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,mBAAmB,qBAkCpD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBAyC5C;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,oBAAoB,qBA8EtD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBA6C5C;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,cAAc,qBAoE1C;AAKD,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBAqH5C;AAYD,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBA+E5C;AAGD,wBAAgB,WAAW,CAAC,CAAC,EAAE,gBAAgB,qBAiG9C;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,mBAAmB,qBAuGpD;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,sBAAsB,qBAwF1D;AAKD,wBAAgB,YAAY,CAAC,CAAC,EAAE,iBAAiB,4BA+JhD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,mBAAmB,qBAgKpD;AAID,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBA6D5C"}
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/components/admin.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAoB/B,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,eAAe,EACf,eAAe,EAEf,iBAAiB,EAEjB,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EAEnB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,mBAAmB,EAEnB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAGpB,wBAAgB,WAAW,CAAC,CAAC,EAAE,gBAAgB,qBA8F9C;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,YAAY,qBAgDtC;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,iBAAiB,qBA4DhD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBAsE5C;AAGD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,aAAa,qBAkHxC;AAOD,wBAAgB,SAAS,sBAqBxB;AAID,wBAAgB,OAAO,CAAC,CAAC,EAAE,YAAY,qBAwGtC;AAKD,wBAAgB,WAAW,CAAC,CAAC,EAAE,gBAAgB,qBAwE9C;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,mBAAmB,qBAkCpD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBAyC5C;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,oBAAoB,qBA8EtD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBA6C5C;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,cAAc,qBAqE1C;AAKD,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBAwH5C;AAYD,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBA+E5C;AAGD,wBAAgB,WAAW,CAAC,CAAC,EAAE,gBAAgB,qBAwG9C;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,mBAAmB,qBAyGpD;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,sBAAsB,qBAgG1D;AAKD,wBAAgB,YAAY,CAAC,CAAC,EAAE,iBAAiB,4BA+JhD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,mBAAmB,qBA+KpD;AAID,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,qBA6D5C"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { useControlled, useId } from "../hooks.js";
5
5
  import { useFormat, useStrings } from "../context.js";
@@ -9,6 +9,7 @@ import { Icon } from "../Icon.js";
9
9
  import { toast } from "../toast-store.js";
10
10
  import { Portal } from "../portal.js";
11
11
  import { DatePicker, FormField, OtpInput, Segmented } from "./forms.js";
12
+ import { QrCode } from "./qr-code.js";
12
13
  import { Popover } from "./overlays.js";
13
14
  import { StatusIndicator, StatusShape } from "./status.js";
14
15
  import { Avatar, Button, Chip, IconButton, TintIcon } from "./foundation.js";
@@ -36,7 +37,7 @@ export function RangeSlider(p) {
36
37
  n = i ? [x, x] : [x, x];
37
38
  v[1](n);
38
39
  }
39
- return (_jsx(FormField, { id: id, label: p.label, hint: p.hint, children: _jsxs("div", { className: "tf-range", children: [_jsxs("div", { className: "tf-range-track", children: [_jsx("span", { style: {
40
+ return (_jsx(FormField, { style: p.style, className: p.className, id: id, label: p.label, hint: p.hint, children: _jsxs("div", { className: "tf-range", children: [_jsxs("div", { className: "tf-range-track", children: [_jsx("span", { style: {
40
41
  left: pc(lo) + "%",
41
42
  width: pc(hi) - pc(lo) + "%",
42
43
  } }), _jsx("input", { type: "range", min: min, max: max, step: step, value: lo, "aria-label": t.minimum, onChange: (e) => {
@@ -52,7 +53,7 @@ export function RangeSlider(p) {
52
53
  export function BarList(p) {
53
54
  const { formatNumber } = useFormat();
54
55
  const items = p.items || [], max = Math.max.apply(null, items.map((i) => i.value).concat([1])), f = p.format || formatNumber;
55
- return (_jsx("div", { className: "tf-barlist", role: "list", "aria-label": p.label, children: items.map((it, i) => (_jsxs("div", { role: "listitem", className: cx("tf-barlist-row", p.onPick && "is-btn"), onClick: p.onPick &&
56
+ return (_jsx("div", { style: p.style, className: cx("tf-barlist", p.className), role: "list", "aria-label": p.label, children: items.map((it, i) => (_jsxs("div", { role: "listitem", className: cx("tf-barlist-row", p.onPick && "is-btn"), onClick: p.onPick &&
56
57
  (() => {
57
58
  p.onPick?.(it);
58
59
  }), children: [_jsx("span", { className: cx("tf-barlist-bar", it.tint && "tf-t-" + it.tint), style: {
@@ -64,7 +65,7 @@ export function BarList(p) {
64
65
  }
65
66
  export function StatusSelect(p) {
66
67
  const opts = p.options || [], v = useControlled(p.value, p.defaultValue != null ? p.defaultValue : opts[0] && opts[0].value, p.onChange), cur = opts.find((o) => o.value === v[0]) || opts[0] || {};
67
- return (_jsx(Popover, { width: p.width || 220, trigger: (s) => (_jsxs("button", { type: "button", className: cx("tf-statussel", p.size === "sm" && "sm"), "aria-haspopup": "listbox", "aria-expanded": s.open, "aria-label": p.label ? `${p.label}: ${cur.label ?? ""}` : undefined, onClick: (e) => {
68
+ return (_jsx(Popover, { style: p.style, className: p.className, width: p.width || 220, trigger: (s) => (_jsxs("button", { type: "button", className: cx("tf-statussel", p.size === "sm" && "sm"), "aria-haspopup": "listbox", "aria-expanded": s.open, "aria-label": p.label ? `${p.label}: ${cur.label ?? ""}` : undefined, onClick: (e) => {
68
69
  e.stopPropagation();
69
70
  s.toggle();
70
71
  }, children: [_jsx(StatusShape, { status: cur.status || "idle" }), _jsx("span", { children: cur.label }), _jsx(Icon, { name: "chevronDown", size: 13 })] })), children: (s) => (_jsx("div", { className: "tf-menu", role: "listbox", "aria-label": p.label, children: opts.map((o) => (_jsxs("button", { type: "button", role: "option", "aria-selected": o.value === v[0], className: cx("tf-menu-item", o.value === v[0] && "on"), onClick: () => {
@@ -85,8 +86,11 @@ export function TilePicker(p) {
85
86
  return v[1](x);
86
87
  v[1](on(x) ? list.filter((y) => y !== x) : list.concat([x]));
87
88
  }
88
- return (_jsx("div", { className: "tf-tiles", role: multi ? "group" : "radiogroup", "aria-label": p.label, style: {
89
- gridTemplateColumns: "repeat(auto-fill, minmax(" + (p.min || 120) + "px, 1fr))",
89
+ return (_jsx("div", { className: cx("tf-tiles", p.layout === "list" && "list", p.className), role: multi ? "group" : "radiogroup", "aria-label": p.label, style: {
90
+ ...(p.layout === "list"
91
+ ? null
92
+ : { gridTemplateColumns: "repeat(auto-fill, minmax(" + (p.min || 120) + "px, 1fr))" }),
93
+ ...p.style,
90
94
  }, children: (p.options || []).map((o) => (_jsxs("button", { type: "button", role: multi ? "checkbox" : "radio", "aria-checked": on(o.value), disabled: o.disabled, className: cx("tf-tile", on(o.value) && "on"), onClick: () => {
91
95
  pick(o.value);
92
96
  }, children: [_jsx("span", { className: cx("tf-tile-art", o.tint && "tf-t-" + o.tint), style: o.color
@@ -105,7 +109,7 @@ export function LiveFeed(p) {
105
109
  const heldItems = held.current;
106
110
  const shown = (paused[0] ? heldItems : p.items || []).filter((it) => !filter[0] || it.type === filter[0]), waiting = paused[0] ? Math.max(0, (p.items || []).length - heldItems.length) : 0;
107
111
  const types = p.types || [];
108
- return (_jsxs("div", { className: "tf-livefeed", children: [_jsxs("div", { className: "tf-livefeed-head", children: [_jsxs("span", { className: cx("tf-live", paused[0] && "off"), children: [_jsx("span", { className: "tf-live-dot", "aria-hidden": true }), paused[0] ? t.paused : t.live] }), types.length > 0 && (_jsxs("div", { className: "tf-row", style: {
112
+ return (_jsxs("div", { style: p.style, className: cx("tf-livefeed", p.className), children: [_jsxs("div", { className: "tf-livefeed-head", children: [_jsxs("span", { className: cx("tf-live", paused[0] && "off"), children: [_jsx("span", { className: "tf-live-dot", "aria-hidden": true }), paused[0] ? t.paused : t.live] }), types.length > 0 && (_jsxs("div", { className: "tf-row", style: {
109
113
  gap: 4,
110
114
  }, children: [_jsx(Chip, { selected: !filter[0], onClick: () => {
111
115
  filter[1](null);
@@ -163,6 +167,7 @@ export function MapView(p) {
163
167
  const cur = pts.find((x) => x.id === sel[0]);
164
168
  return (_jsxs("div", { className: cx("tf-map", p.className), style: {
165
169
  height: Hh,
170
+ ...p.style,
166
171
  }, role: "region", "aria-label": p.label || t.viewMap, children: [p.background || (!p.bounds ? _jsx(WorldDots, {}) : null) || (_jsx("svg", { className: "tf-map-grid", viewBox: "0 0 100 100", preserveAspectRatio: "none", "aria-hidden": true, children: [10, 20, 30, 40, 50, 60, 70, 80, 90].map((g) => (_jsxs("g", { children: [_jsx("line", { x1: g, x2: g, y1: 0, y2: 100 }), _jsx("line", { y1: g, y2: g, x1: 0, x2: 100 })] }, g))) })), pts.map((pt) => {
167
172
  const c = xy(pt), r = p.bubbles ? 10 + Math.sqrt((pt.value || 1) / maxV) * 26 : null;
168
173
  return (_jsx("button", { type: "button", className: cx(p.bubbles ? "tf-map-bubble" : "tf-map-pin", "tf-t-" + (pt.tint || "sky"), sel[0] === pt.id && "on", pt.pulse && "pulse"), style: {
@@ -190,7 +195,7 @@ export function BalanceCard(p) {
190
195
  const t = useStrings(ADMIN_STRINGS);
191
196
  const { formatMoney } = useFormat();
192
197
  const days = p.perDay && p.perDay > 0 ? Math.floor(p.balance / p.perDay) : null, low = p.low != null && p.balance <= p.low, st = p.status || (p.balance <= 0 ? "danger" : low ? "warn" : "ok");
193
- return (_jsxs("div", { className: cx("tf-balance", "is-" + st), children: [_jsxs("div", { className: "tf-balance-head", children: [p.logo || _jsx(TintIcon, { icon: p.icon || "wallet", tint: p.tint || "butter", size: 36 }), _jsxs("div", { className: "tf-option-text", children: [_jsx("b", { children: p.name }), p.sub && _jsx("small", { children: p.sub })] }), _jsx(StatusIndicator, { status: st, label: p.statusLabel || (st === "danger" ? t.balanceEmpty : low ? t.balanceLow : t.balanceOk), size: "sm" })] }), _jsxs("div", { className: "tf-balance-main", children: [_jsxs("div", { className: "tf-col", style: {
198
+ return (_jsxs("div", { style: p.style, className: cx("tf-balance", "is-" + st, p.className), children: [_jsxs("div", { className: "tf-balance-head", children: [p.logo || _jsx(TintIcon, { icon: p.icon || "wallet", tint: p.tint || "butter", size: 36 }), _jsxs("div", { className: "tf-option-text", children: [_jsx("b", { children: p.name }), p.sub && _jsx("small", { children: p.sub })] }), _jsx(StatusIndicator, { status: st, label: p.statusLabel || (st === "danger" ? t.balanceEmpty : low ? t.balanceLow : t.balanceOk), size: "sm" })] }), _jsxs("div", { className: "tf-balance-main", children: [_jsxs("div", { className: "tf-col", style: {
194
199
  gap: 2,
195
200
  }, children: [_jsx("span", { className: "tf-balance-amt", children: formatMoney(p.balance, p.currency, {
196
201
  maximumFractionDigits: 2,
@@ -205,7 +210,7 @@ export function BalanceCard(p) {
205
210
  }
206
211
  export function ServiceMonitor(p) {
207
212
  const { formatNumber } = useFormat();
208
- return (_jsx("div", { className: "tf-svcmon", role: "list", "aria-label": p.label, children: (p.items || []).map((s) => (_jsxs("div", { role: "listitem", className: "tf-svcmon-row", children: [_jsx(StatusShape, { status: s.status }), _jsxs("span", { className: "tf-option-text", children: [_jsx("b", { children: s.name }), _jsx("small", { children: s.statusLabel || s.status })] }), s.history && (_jsx("span", { className: "tf-svcmon-hist", "aria-hidden": true, children: s.history.map((x, i) => (_jsx("i", { className: "tf-st-" + x }, i))) })), _jsx("span", { className: "tf-svcmon-num", children: s.latency != null ? formatNumber(s.latency) + " ms" : "—" }), _jsx("span", { className: cx("tf-svcmon-num", (s.errorRate ?? 0) > 1 && "bad"), children: s.errorRate != null
213
+ return (_jsx("div", { style: p.style, className: cx("tf-svcmon", p.className), role: "list", "aria-label": p.label, children: (p.items || []).map((s) => (_jsxs("div", { role: "listitem", className: "tf-svcmon-row", children: [_jsx(StatusShape, { status: s.status }), _jsxs("span", { className: "tf-option-text", children: [_jsx("b", { children: s.name }), _jsx("small", { children: s.statusLabel || s.status })] }), s.history && (_jsx("span", { className: "tf-svcmon-hist", "aria-hidden": true, children: s.history.map((x, i) => (_jsx("i", { className: "tf-st-" + x }, i))) })), _jsx("span", { className: "tf-svcmon-num", children: s.latency != null ? formatNumber(s.latency) + " ms" : "—" }), _jsx("span", { className: cx("tf-svcmon-num", (s.errorRate ?? 0) > 1 && "bad"), children: s.errorRate != null
209
214
  ? formatNumber(s.errorRate / 100, {
210
215
  style: "percent",
211
216
  maximumFractionDigits: 1,
@@ -215,7 +220,7 @@ export function ServiceMonitor(p) {
215
220
  export function RunHistory(p) {
216
221
  const { formatNumber } = useFormat();
217
222
  const open = React.useState(null);
218
- return (_jsx("div", { className: "tf-runs", role: "list", "aria-label": p.label, children: (p.items || []).map((r) => {
223
+ return (_jsx("div", { style: p.style, className: cx("tf-runs", p.className), role: "list", "aria-label": p.label, children: (p.items || []).map((r) => {
219
224
  const on = open[0] === r.id;
220
225
  return (_jsxs("div", { role: "listitem", className: cx("tf-runs-row", on && "open"), children: [_jsxs("button", { type: "button", className: "tf-runs-main", "aria-expanded": r.detail ? on : undefined, onClick: r.detail
221
226
  ? () => {
@@ -228,7 +233,7 @@ export function WebhookEndpoint(p) {
228
233
  const t = useStrings(ADMIN_STRINGS);
229
234
  const { formatNumber } = useFormat();
230
235
  const open = React.useState(!!p.defaultOpen);
231
- return (_jsxs("div", { className: "tf-hook", children: [_jsxs("div", { className: "tf-hook-head", children: [_jsx(TintIcon, { icon: "webhook", tint: "lilac", size: 36 }), _jsxs("div", { className: "tf-option-text", style: {
236
+ return (_jsxs("div", { style: p.style, className: cx("tf-hook", p.className), children: [_jsxs("div", { className: "tf-hook-head", children: [_jsx(TintIcon, { icon: "webhook", tint: "lilac", size: 36 }), _jsxs("div", { className: "tf-option-text", style: {
232
237
  minWidth: 0,
233
238
  flex: 1,
234
239
  }, children: [_jsx("b", { className: "tf-mono tf-hook-url", children: p.url }), _jsx("small", { children: (p.events || []).join(", ") })] }), _jsx(StatusIndicator, { status: p.status || "ok", label: p.statusLabel, size: "sm" }), p.successRate != null && (_jsx("span", { className: "tf-hook-rate", children: formatNumber(p.successRate / 100, {
@@ -243,7 +248,7 @@ export function WebhookEndpoint(p) {
243
248
  }
244
249
  export function BackupList(p) {
245
250
  const t = useStrings(ADMIN_STRINGS);
246
- return (_jsxs("div", { className: "tf-backups", role: "list", "aria-label": p.label, children: [(p.items || []).map((b) => (_jsxs("div", { role: "listitem", className: "tf-backups-row", children: [_jsx(StatusShape, { status: b.status || "ok" }), _jsxs("span", { className: "tf-option-text", children: [_jsx("b", { children: b.name || b.time }), _jsx("small", { children: [b.kind, b.where, b.retention].filter(Boolean).join(" · ") })] }), _jsx("span", { className: "tf-backups-size", children: b.size }), _jsxs("span", { className: "tf-row", style: {
251
+ return (_jsxs("div", { style: p.style, className: cx("tf-backups", p.className), role: "list", "aria-label": p.label, children: [(p.items || []).map((b) => (_jsxs("div", { role: "listitem", className: "tf-backups-row", children: [_jsx(StatusShape, { status: b.status || "ok" }), _jsxs("span", { className: "tf-option-text", children: [_jsx("b", { children: b.name || b.time }), _jsx("small", { children: [b.kind, b.where, b.retention].filter(Boolean).join(" · ") })] }), _jsx("span", { className: "tf-backups-size", children: b.size }), _jsxs("span", { className: "tf-row", style: {
247
252
  gap: 4,
248
253
  }, children: [p.onDownload && (_jsx(IconButton, { icon: "download", size: "sm", label: t.download, onClick: () => {
249
254
  p.onDownload?.(b);
@@ -255,8 +260,9 @@ export function BlockList(p) {
255
260
  const t = useStrings(ADMIN_STRINGS);
256
261
  const q = React.useState("");
257
262
  const list = (p.items || []).filter((b) => !q[0] || (b.value + " " + (b.reason || "")).toLowerCase().indexOf(q[0].toLowerCase()) > -1);
258
- return (_jsxs("div", { className: "tf-col", style: {
263
+ return (_jsxs("div", { className: cx("tf-col", p.className), style: {
259
264
  gap: 12,
265
+ ...p.style,
260
266
  }, children: [_jsxs("div", { className: "tf-filterbar", children: [_jsx(SearchField, { placeholder: p.searchPlaceholder || t.searchBlocked, value: q[0], onChange: (e) => {
261
267
  q[1](e.target.value);
262
268
  }, style: {
@@ -279,7 +285,7 @@ export function ReviewCard(p) {
279
285
  hidden: ["idle", t.reviewState.hidden],
280
286
  flagged: ["warn", t.reviewState.flagged],
281
287
  }[p.state || "pending"];
282
- return (_jsxs("article", { className: cx("tf-review", "is-" + (p.state || "pending")), children: [_jsxs("div", { className: "tf-review-head", children: [_jsx(Avatar, { name: p.author, size: 36 }), _jsxs("div", { className: "tf-option-text", style: {
288
+ return (_jsxs("article", { style: p.style, className: cx("tf-review", "is-" + (p.state || "pending"), p.className), children: [_jsxs("div", { className: "tf-review-head", children: [_jsx(Avatar, { name: p.author, size: 36 }), _jsxs("div", { className: "tf-option-text", style: {
283
289
  flex: 1,
284
290
  }, children: [_jsxs("b", { children: [p.author, p.verified && (_jsxs("span", { className: "tf-review-ver", children: [" · ", t.verifiedPurchase] }))] }), _jsx("small", { children: [p.product, p.date].filter(Boolean).join(" · ") })] }), _jsx(Rating, { value: p.rating }), _jsx(StatusIndicator, { status: st[0], label: p.stateLabel || st[1], size: "sm" })] }), p.title && _jsx("b", { className: "tf-review-title", children: p.title }), _jsx("p", { className: "tf-review-text", children: p.highlight ? markWords(p.text, p.highlight) : p.text }), p.reply && !reply[0] && (_jsxs("div", { className: "tf-review-reply", children: [_jsx("small", { children: p.replyLabel || t.yourReply }), p.reply] })), reply[0] && (_jsxs("div", { className: "tf-col", style: {
285
291
  gap: 8,
@@ -306,7 +312,7 @@ export function CouponCard(p) {
306
312
  const t = useStrings(ADMIN_STRINGS);
307
313
  const { formatMoney, formatNumber } = useFormat();
308
314
  const used = p.used || 0, st = p.status || (p.limit && used >= p.limit ? "idle" : "ok");
309
- return (_jsxs("div", { className: cx("tf-coupon", st !== "ok" && "off"), children: [_jsxs("div", { className: "tf-coupon-val", children: [_jsx("b", { children: p.kind === "fixed"
315
+ return (_jsxs("div", { style: p.style, className: cx("tf-coupon", st !== "ok" && "off", p.className), children: [_jsxs("div", { className: "tf-coupon-val", children: [_jsx("b", { children: p.kind === "fixed"
310
316
  ? formatMoney(p.value, p.currency)
311
317
  : formatNumber(p.value / 100, {
312
318
  style: "percent",
@@ -345,7 +351,7 @@ export function LocaleField(p) {
345
351
  v[1](n);
346
352
  }
347
353
  const done = locs.filter((l) => (v[0][l.code] || "").trim()).length;
348
- return (_jsx(FormField, { id: id, label: p.label, hint: p.hint, error: p.error, children: _jsxs("div", { className: "tf-locfield", children: [_jsxs("div", { className: "tf-locfield-tabs", role: "tablist", "aria-label": t.languages, children: [locs.map((l) => {
354
+ return (_jsx(FormField, { style: p.style, className: p.className, id: id, label: p.label, hint: p.hint, error: p.error, children: _jsxs("div", { className: "tf-locfield", children: [_jsxs("div", { className: "tf-locfield-tabs", role: "tablist", "aria-label": t.languages, children: [locs.map((l) => {
349
355
  const has = (v[0][l.code] || "").trim();
350
356
  return (_jsxs("button", { type: "button", role: "tab", "aria-selected": cur[0] === l.code, className: cx("tf-locfield-tab", cur[0] === l.code && "on", !has && "missing"), onClick: () => {
351
357
  cur[1](l.code);
@@ -369,7 +375,7 @@ export function LocaleSwitcher(p) {
369
375
  const t = useStrings(ADMIN_STRINGS);
370
376
  const lang = useControlled(p.language, p.languages && p.languages[0] && p.languages[0].code, p.onLanguage), cur = useControlled(p.currency, p.currencies && p.currencies[0], p.onCurrency);
371
377
  const L0 = (p.languages || []).find((l) => l.code === lang[0]) || {};
372
- return (_jsx(Popover, { width: 280, trigger: (s) => (_jsxs("button", { type: "button", className: cx("tf-locsw", p.variant === "frame" && "on-frame"), "aria-haspopup": "dialog", "aria-expanded": s.open, onClick: s.toggle, title: t.languageAndCurrency, children: [L0.flag ? _jsx("span", { children: L0.flag }) : _jsx(Icon, { name: "globe", size: 15 }), _jsx("span", { children: (L0.short || lang[0] || "").toUpperCase() }), cur[0] && _jsx("span", { className: "tf-locsw-cur", children: cur[0] }), _jsx(Icon, { name: "chevronDown", size: 13 })] })), children: () => (_jsxs("div", { className: "tf-col", style: {
378
+ return (_jsx(Popover, { style: p.style, className: p.className, width: 280, trigger: (s) => (_jsxs("button", { type: "button", className: cx("tf-locsw", p.variant === "frame" && "on-frame"), "aria-haspopup": "dialog", "aria-expanded": s.open, onClick: s.toggle, title: t.languageAndCurrency, children: [L0.flag ? _jsx("span", { children: L0.flag }) : _jsx(Icon, { name: "globe", size: 15 }), _jsx("span", { children: (L0.short || lang[0] || "").toUpperCase() }), cur[0] && _jsx("span", { className: "tf-locsw-cur", children: cur[0] }), _jsx(Icon, { name: "chevronDown", size: 13 })] })), children: () => (_jsxs("div", { className: "tf-col", style: {
373
379
  gap: 12,
374
380
  }, children: [p.languages && (_jsxs("div", { className: "tf-col", style: {
375
381
  gap: 4,
@@ -389,8 +395,9 @@ export function LocaleSwitcher(p) {
389
395
  }, children: t.currency }), _jsx(Segmented, { size: "sm", block: true, value: cur[0], onChange: cur[1], options: p.currencies })] }))] })) }));
390
396
  }
391
397
  export function WorkspaceSwitcher(p) {
398
+ const t = useStrings(ADMIN_STRINGS);
392
399
  const items = p.items || [], v = useControlled(p.value, items[0] && items[0].id, p.onChange), cur = items.find((x) => x.id === v[0]) || {};
393
- return (_jsx(Popover, { width: p.width || 300, trigger: (s) => (_jsxs("button", { type: "button", className: cx("tf-wssw", p.variant === "frame" && "on-frame"), "aria-haspopup": "listbox", "aria-expanded": s.open, onClick: s.toggle, children: [cur.logo || (_jsx("span", { className: cx("tf-wssw-mark", "tf-t-" + (cur.tint || "sky")), children: (cur.name || "?").charAt(0) })), _jsxs("span", { className: "tf-option-text", children: [_jsx("b", { children: cur.name }), cur.sub && _jsx("small", { children: cur.sub })] }), _jsx(Icon, { name: "chevronDown", size: 14 })] })), children: (s) => (_jsxs("div", { className: "tf-col", style: {
400
+ return (_jsx(Popover, { style: p.style, className: p.className, width: p.width || 300, trigger: (s) => (_jsxs("button", { type: "button", className: cx("tf-wssw", p.variant === "frame" && "on-frame", p.compact && "compact"), "aria-haspopup": "listbox", "aria-expanded": s.open, "aria-label": p.compact ? `${t.switchWorkspace}: ${cur.name || ""}` : undefined, onClick: s.toggle, children: [cur.logo || (_jsx("span", { className: cx("tf-wssw-mark", "tf-t-" + (cur.tint || "sky")), children: (cur.name || "?").charAt(0) })), !p.compact && (_jsxs(_Fragment, { children: [_jsxs("span", { className: "tf-option-text", children: [_jsx("b", { children: cur.name }), cur.sub && _jsx("small", { children: cur.sub })] }), _jsx(Icon, { name: "chevronDown", size: 14 })] }))] })), children: (s) => (_jsxs("div", { className: "tf-col", style: {
394
401
  gap: 8,
395
402
  }, children: [p.label && (_jsx("span", { className: "tf-menu-label", style: {
396
403
  padding: "0 8px",
@@ -453,7 +460,8 @@ export function TwoFactorSetup(p) {
453
460
  const t = useStrings(ADMIN_STRINGS);
454
461
  const step = React.useState(p.step || 0), err = React.useState(null), saved = React.useState(false);
455
462
  const steps = t.twoFactorSteps;
456
- return (_jsxs("div", { className: "tf-2fa", children: [_jsx("ol", { className: "tf-2fa-steps", children: steps.map((s, i) => (_jsxs("li", { className: cx(i === step[0] && "on", i < step[0] && "done"), children: [_jsx("span", { children: i < step[0] ? _jsx(Icon, { name: "check", size: 12 }) : i + 1 }), s] }, i))) }), step[0] === 0 && (_jsxs("div", { className: "tf-2fa-scan", children: [_jsx("div", { className: "tf-2fa-qr", role: "img", "aria-label": t.qrCode, children: p.qr || _jsx(Icon, { name: "grid", size: 48 }) }), _jsxs("div", { className: "tf-col", style: {
463
+ return (_jsxs("div", { style: p.style, className: cx("tf-2fa", p.className), children: [_jsx("ol", { className: "tf-2fa-steps", children: steps.map((s, i) => (_jsxs("li", { className: cx(i === step[0] && "on", i < step[0] && "done"), children: [_jsx("span", { children: i < step[0] ? _jsx(Icon, { name: "check", size: 12 }) : i + 1 }), s] }, i))) }), step[0] === 0 && (_jsxs("div", { className: "tf-2fa-scan", children: [_jsx("div", { className: "tf-2fa-qr", role: "img", "aria-label": t.qrCode, children: p.qr ||
464
+ (p.qrValue ? (_jsx(QrCode, { value: p.qrValue, quiet: 2, label: t.qrCode })) : (_jsx(Icon, { name: "grid", size: 48 }))) }), _jsxs("div", { className: "tf-col", style: {
457
465
  gap: 12,
458
466
  minWidth: 0,
459
467
  }, children: [_jsx("p", { className: "tf-card-desc", style: {
@@ -473,6 +481,8 @@ export function TwoFactorSetup(p) {
473
481
  }, children: [_jsx("p", { className: "tf-card-desc", style: {
474
482
  margin: 0,
475
483
  }, children: t.enterCode }), _jsx(OtpInput, { error: !!err[0], onComplete: (c) => {
484
+ // a second wrong code turns the error on again, which empties the cells
485
+ err[1](null);
476
486
  Promise.resolve(p.onVerify ? p.onVerify(c) : true).then((ok) => {
477
487
  if (ok) {
478
488
  err[1](null);
@@ -481,7 +491,7 @@ export function TwoFactorSetup(p) {
481
491
  else
482
492
  err[1](t.codeFailed);
483
493
  });
484
- } }), err[0] && _jsx("span", { className: "tf-field-error", children: err[0] }), _jsx("div", { children: _jsx(Button, { variant: "ghost", onClick: () => {
494
+ } }), err[0] && _jsx("span", { className: "tf-field-error", children: err[0] }), p.trustDevice && (_jsx(Checkbox, { defaultChecked: false, onChange: (e) => p.onTrustChange?.(e.currentTarget.checked), children: typeof p.trustDevice === "string" ? p.trustDevice : t.trustDevice })), _jsx("div", { children: _jsx(Button, { variant: "ghost", onClick: () => {
485
495
  step[1](0);
486
496
  }, children: t.back }) })] })), step[0] === 2 && (_jsxs("div", { className: "tf-col", style: {
487
497
  gap: 12,
@@ -515,7 +525,7 @@ export function ColorField(p) {
515
525
  return 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
516
526
  }
517
527
  const a = lum(v[0]), b = lum(p.against || "#ffffff"), ratio = a != null && b != null ? (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05) : null;
518
- return (_jsx(FormField, { id: id, label: p.label, hint: p.hint, children: _jsxs("div", { className: "tf-colorf", children: [_jsx("label", { className: "tf-colorf-sw", style: {
528
+ return (_jsx(FormField, { style: p.style, className: p.className, id: id, label: p.label, hint: p.hint, children: _jsxs("div", { className: "tf-colorf", children: [_jsx("label", { className: "tf-colorf-sw", style: {
519
529
  background: v[0],
520
530
  }, children: _jsx("input", { type: "color", value: /^#[0-9a-f]{6}$/i.test(v[0]) ? v[0] : "#000000", onChange: (e) => {
521
531
  v[1](e.target.value);