tyrell-components 1.0.0-RC13 → 1.0.0-RC15

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 (358) hide show
  1. package/README.md +10 -2
  2. package/css/tyrell-theme.css +192 -180
  3. package/css/tyrell.css +23 -0
  4. package/dist/tyrell-colors-static.css +1 -316
  5. package/dist/tyrell-theme.css +1 -1454
  6. package/dist/tyrell.css +1 -1371
  7. package/dist/tyrell.js +1 -1
  8. package/lib/base/ty-component.d.ts +20 -10
  9. package/lib/base/ty-component.js +196 -319
  10. package/lib/components/button.d.ts +3 -17
  11. package/lib/components/button.js +261 -295
  12. package/lib/components/calendar-month.d.ts +4 -50
  13. package/lib/components/calendar-month.js +443 -582
  14. package/lib/components/calendar-navigation.d.ts +3 -48
  15. package/lib/components/calendar-navigation.js +239 -362
  16. package/lib/components/calendar.d.ts +8 -83
  17. package/lib/components/calendar.js +616 -829
  18. package/lib/components/checkbox.d.ts +5 -72
  19. package/lib/components/checkbox.js +273 -416
  20. package/lib/components/copy.d.ts +4 -57
  21. package/lib/components/copy.js +280 -397
  22. package/lib/components/date-picker.d.ts +21 -163
  23. package/lib/components/date-picker.js +1143 -1674
  24. package/lib/components/file-upload.d.ts +9 -15
  25. package/lib/components/file-upload.js +404 -426
  26. package/lib/components/icon.d.ts +3 -24
  27. package/lib/components/icon.js +141 -230
  28. package/lib/components/input.d.ts +8 -108
  29. package/lib/components/input.js +593 -784
  30. package/lib/components/modal.d.ts +17 -26
  31. package/lib/components/modal.js +340 -484
  32. package/lib/components/option.d.ts +2 -9
  33. package/lib/components/option.js +168 -216
  34. package/lib/components/popup.d.ts +2 -17
  35. package/lib/components/popup.js +249 -380
  36. package/lib/components/radio.d.ts +5 -25
  37. package/lib/components/radio.js +407 -461
  38. package/lib/components/resize-observer.d.ts +3 -30
  39. package/lib/components/resize-observer.js +69 -103
  40. package/lib/components/scroll-container.d.ts +2 -12
  41. package/lib/components/scroll-container.js +293 -338
  42. package/lib/components/select.d.ts +87 -159
  43. package/lib/components/select.js +1609 -2090
  44. package/lib/components/selected-tags.d.ts +5 -48
  45. package/lib/components/selected-tags.js +188 -276
  46. package/lib/components/step.d.ts +1 -6
  47. package/lib/components/step.js +62 -68
  48. package/lib/components/switch.d.ts +1 -12
  49. package/lib/components/switch.js +214 -247
  50. package/lib/components/tab.d.ts +1 -6
  51. package/lib/components/tab.js +62 -69
  52. package/lib/components/tabs.d.ts +6 -63
  53. package/lib/components/tabs.js +545 -777
  54. package/lib/components/tag.d.ts +3 -37
  55. package/lib/components/tag.js +236 -335
  56. package/lib/components/textarea.d.ts +7 -87
  57. package/lib/components/textarea.js +457 -627
  58. package/lib/components/tooltip.d.ts +3 -11
  59. package/lib/components/tooltip.js +307 -443
  60. package/lib/components/wizard.d.ts +6 -54
  61. package/lib/components/wizard.js +405 -618
  62. package/lib/icons/fontawesome/brands.d.ts +0 -1
  63. package/lib/icons/fontawesome/brands.js +0 -8
  64. package/lib/icons/fontawesome/regular.d.ts +0 -1
  65. package/lib/icons/fontawesome/regular.js +0 -8
  66. package/lib/icons/fontawesome/solid.d.ts +0 -1
  67. package/lib/icons/fontawesome/solid.js +0 -8
  68. package/lib/icons/heroicons/micro.d.ts +0 -1
  69. package/lib/icons/heroicons/micro.js +392 -400
  70. package/lib/icons/heroicons/mini.d.ts +0 -1
  71. package/lib/icons/heroicons/mini.js +382 -390
  72. package/lib/icons/heroicons/outline.d.ts +0 -1
  73. package/lib/icons/heroicons/outline.js +337 -345
  74. package/lib/icons/heroicons/solid.d.ts +0 -1
  75. package/lib/icons/heroicons/solid.js +407 -415
  76. package/lib/icons/lucide.d.ts +0 -1
  77. package/lib/icons/lucide.js +24479 -26351
  78. package/lib/icons/material/filled.d.ts +0 -1
  79. package/lib/icons/material/filled.js +9653 -9663
  80. package/lib/icons/material/outlined.d.ts +0 -1
  81. package/lib/icons/material/outlined.js +10271 -10281
  82. package/lib/icons/material/round.d.ts +0 -1
  83. package/lib/icons/material/round.js +10495 -10505
  84. package/lib/icons/material/sharp.d.ts +0 -1
  85. package/lib/icons/material/sharp.js +9905 -9915
  86. package/lib/icons/material/two-tone.d.ts +0 -1
  87. package/lib/icons/material/two-tone.js +12792 -12802
  88. package/lib/index.d.ts +0 -1
  89. package/lib/index.js +21 -41
  90. package/lib/styles/button.d.ts +2 -20
  91. package/lib/styles/button.js +202 -404
  92. package/lib/styles/calendar-month.d.ts +1 -5
  93. package/lib/styles/calendar-month.js +127 -244
  94. package/lib/styles/calendar-navigation.d.ts +2 -6
  95. package/lib/styles/calendar-navigation.js +64 -104
  96. package/lib/styles/calendar.d.ts +1 -2
  97. package/lib/styles/calendar.js +9 -22
  98. package/lib/styles/checkbox.d.ts +0 -1
  99. package/lib/styles/checkbox.js +45 -94
  100. package/lib/styles/copy.d.ts +0 -1
  101. package/lib/styles/copy.js +67 -106
  102. package/lib/styles/custom-scrollbar.d.ts +1 -2
  103. package/lib/styles/custom-scrollbar.js +80 -115
  104. package/lib/styles/date-picker.d.ts +1 -5
  105. package/lib/styles/date-picker.js +261 -335
  106. package/lib/styles/field-size.d.ts +6 -0
  107. package/lib/styles/field-size.js +91 -0
  108. package/lib/styles/file-upload.d.ts +1 -2
  109. package/lib/styles/file-upload.js +143 -188
  110. package/lib/styles/icon.d.ts +2 -6
  111. package/lib/styles/icon.js +92 -170
  112. package/lib/styles/input.d.ts +1 -6
  113. package/lib/styles/input.js +125 -290
  114. package/lib/styles/modal.d.ts +1 -2
  115. package/lib/styles/modal.js +71 -108
  116. package/lib/styles/option.d.ts +2 -6
  117. package/lib/styles/option.js +49 -64
  118. package/lib/styles/popup.d.ts +1 -2
  119. package/lib/styles/popup.js +42 -77
  120. package/lib/styles/radio.d.ts +0 -1
  121. package/lib/styles/radio.js +69 -110
  122. package/lib/styles/resize-observer.d.ts +1 -2
  123. package/lib/styles/resize-observer.js +2 -12
  124. package/lib/styles/scroll-container.d.ts +1 -2
  125. package/lib/styles/scroll-container.js +100 -149
  126. package/lib/styles/select-base.d.ts +0 -1
  127. package/lib/styles/select-base.js +597 -785
  128. package/lib/styles/select.d.ts +1 -2
  129. package/lib/styles/select.js +140 -236
  130. package/lib/styles/step.d.ts +1 -2
  131. package/lib/styles/step.js +22 -33
  132. package/lib/styles/switch.d.ts +0 -1
  133. package/lib/styles/switch.js +34 -73
  134. package/lib/styles/tab.d.ts +1 -2
  135. package/lib/styles/tab.js +22 -34
  136. package/lib/styles/tabs.d.ts +3 -11
  137. package/lib/styles/tabs.js +190 -222
  138. package/lib/styles/tag.d.ts +1 -5
  139. package/lib/styles/tag.js +136 -218
  140. package/lib/styles/textarea.d.ts +1 -2
  141. package/lib/styles/textarea.js +210 -319
  142. package/lib/styles/tooltip.d.ts +0 -1
  143. package/lib/styles/tooltip.js +3 -13
  144. package/lib/styles/wizard.d.ts +5 -21
  145. package/lib/styles/wizard.js +170 -306
  146. package/lib/types/common.d.ts +2 -2
  147. package/lib/types/common.js +6 -17
  148. package/lib/utils/calendar-utils.d.ts +4 -21
  149. package/lib/utils/calendar-utils.js +100 -273
  150. package/lib/utils/custom-scrollbar.d.ts +6 -20
  151. package/lib/utils/custom-scrollbar.js +273 -317
  152. package/lib/utils/flavor-sheet.d.ts +0 -1
  153. package/lib/utils/flavor-sheet.js +14 -37
  154. package/lib/utils/icon-registry.d.ts +0 -2
  155. package/lib/utils/icon-registry.js +137 -243
  156. package/lib/utils/icons.d.ts +0 -1
  157. package/lib/utils/icons.js +0 -9
  158. package/lib/utils/loader-registry.d.ts +0 -1
  159. package/lib/utils/loader-registry.js +3 -35
  160. package/lib/utils/locale.d.ts +2 -23
  161. package/lib/utils/locale.js +34 -120
  162. package/lib/utils/mobile.d.ts +0 -1
  163. package/lib/utils/mobile.js +1 -18
  164. package/lib/utils/number-format.d.ts +6 -3
  165. package/lib/utils/number-format.js +54 -110
  166. package/lib/utils/positioning.d.ts +50 -7
  167. package/lib/utils/positioning.js +224 -234
  168. package/lib/utils/property-capture.d.ts +5 -27
  169. package/lib/utils/property-capture.js +36 -144
  170. package/lib/utils/property-manager.d.ts +0 -1
  171. package/lib/utils/property-manager.js +126 -196
  172. package/lib/utils/resize-observer.d.ts +0 -1
  173. package/lib/utils/resize-observer.js +23 -59
  174. package/lib/utils/scroll-lock.d.ts +4 -11
  175. package/lib/utils/scroll-lock.js +65 -172
  176. package/lib/utils/styles.d.ts +0 -1
  177. package/lib/utils/styles.js +17 -41
  178. package/lib/version.d.ts +1 -2
  179. package/lib/version.js +1 -11
  180. package/package.json +4 -4
  181. package/lib/base/ty-component.d.ts.map +0 -1
  182. package/lib/base/ty-component.js.map +0 -1
  183. package/lib/components/button.d.ts.map +0 -1
  184. package/lib/components/button.js.map +0 -1
  185. package/lib/components/calendar-month.d.ts.map +0 -1
  186. package/lib/components/calendar-month.js.map +0 -1
  187. package/lib/components/calendar-navigation.d.ts.map +0 -1
  188. package/lib/components/calendar-navigation.js.map +0 -1
  189. package/lib/components/calendar.d.ts.map +0 -1
  190. package/lib/components/calendar.js.map +0 -1
  191. package/lib/components/checkbox.d.ts.map +0 -1
  192. package/lib/components/checkbox.js.map +0 -1
  193. package/lib/components/copy.d.ts.map +0 -1
  194. package/lib/components/copy.js.map +0 -1
  195. package/lib/components/date-picker.d.ts.map +0 -1
  196. package/lib/components/date-picker.js.map +0 -1
  197. package/lib/components/file-upload.d.ts.map +0 -1
  198. package/lib/components/file-upload.js.map +0 -1
  199. package/lib/components/icon.d.ts.map +0 -1
  200. package/lib/components/icon.js.map +0 -1
  201. package/lib/components/input.d.ts.map +0 -1
  202. package/lib/components/input.js.map +0 -1
  203. package/lib/components/modal.d.ts.map +0 -1
  204. package/lib/components/modal.js.map +0 -1
  205. package/lib/components/option.d.ts.map +0 -1
  206. package/lib/components/option.js.map +0 -1
  207. package/lib/components/popup.d.ts.map +0 -1
  208. package/lib/components/popup.js.map +0 -1
  209. package/lib/components/radio.d.ts.map +0 -1
  210. package/lib/components/radio.js.map +0 -1
  211. package/lib/components/resize-observer.d.ts.map +0 -1
  212. package/lib/components/resize-observer.js.map +0 -1
  213. package/lib/components/scroll-container.d.ts.map +0 -1
  214. package/lib/components/scroll-container.js.map +0 -1
  215. package/lib/components/select.d.ts.map +0 -1
  216. package/lib/components/select.js.map +0 -1
  217. package/lib/components/selected-tags.d.ts.map +0 -1
  218. package/lib/components/selected-tags.js.map +0 -1
  219. package/lib/components/step.d.ts.map +0 -1
  220. package/lib/components/step.js.map +0 -1
  221. package/lib/components/switch.d.ts.map +0 -1
  222. package/lib/components/switch.js.map +0 -1
  223. package/lib/components/tab.d.ts.map +0 -1
  224. package/lib/components/tab.js.map +0 -1
  225. package/lib/components/tabs.d.ts.map +0 -1
  226. package/lib/components/tabs.js.map +0 -1
  227. package/lib/components/tag.d.ts.map +0 -1
  228. package/lib/components/tag.js.map +0 -1
  229. package/lib/components/textarea.d.ts.map +0 -1
  230. package/lib/components/textarea.js.map +0 -1
  231. package/lib/components/tooltip.d.ts.map +0 -1
  232. package/lib/components/tooltip.js.map +0 -1
  233. package/lib/components/wizard.d.ts.map +0 -1
  234. package/lib/components/wizard.js.map +0 -1
  235. package/lib/icons/fontawesome/brands.d.ts.map +0 -1
  236. package/lib/icons/fontawesome/brands.js.map +0 -1
  237. package/lib/icons/fontawesome/regular.d.ts.map +0 -1
  238. package/lib/icons/fontawesome/regular.js.map +0 -1
  239. package/lib/icons/fontawesome/solid.d.ts.map +0 -1
  240. package/lib/icons/fontawesome/solid.js.map +0 -1
  241. package/lib/icons/heroicons/micro.d.ts.map +0 -1
  242. package/lib/icons/heroicons/micro.js.map +0 -1
  243. package/lib/icons/heroicons/mini.d.ts.map +0 -1
  244. package/lib/icons/heroicons/mini.js.map +0 -1
  245. package/lib/icons/heroicons/outline.d.ts.map +0 -1
  246. package/lib/icons/heroicons/outline.js.map +0 -1
  247. package/lib/icons/heroicons/solid.d.ts.map +0 -1
  248. package/lib/icons/heroicons/solid.js.map +0 -1
  249. package/lib/icons/lucide.d.ts.map +0 -1
  250. package/lib/icons/lucide.js.map +0 -1
  251. package/lib/icons/material/filled.d.ts.map +0 -1
  252. package/lib/icons/material/filled.js.map +0 -1
  253. package/lib/icons/material/outlined.d.ts.map +0 -1
  254. package/lib/icons/material/outlined.js.map +0 -1
  255. package/lib/icons/material/round.d.ts.map +0 -1
  256. package/lib/icons/material/round.js.map +0 -1
  257. package/lib/icons/material/sharp.d.ts.map +0 -1
  258. package/lib/icons/material/sharp.js.map +0 -1
  259. package/lib/icons/material/two-tone.d.ts.map +0 -1
  260. package/lib/icons/material/two-tone.js.map +0 -1
  261. package/lib/index.d.ts.map +0 -1
  262. package/lib/index.js.map +0 -1
  263. package/lib/styles/button.d.ts.map +0 -1
  264. package/lib/styles/button.js.map +0 -1
  265. package/lib/styles/calendar-month.d.ts.map +0 -1
  266. package/lib/styles/calendar-month.js.map +0 -1
  267. package/lib/styles/calendar-navigation.d.ts.map +0 -1
  268. package/lib/styles/calendar-navigation.js.map +0 -1
  269. package/lib/styles/calendar.d.ts.map +0 -1
  270. package/lib/styles/calendar.js.map +0 -1
  271. package/lib/styles/checkbox.d.ts.map +0 -1
  272. package/lib/styles/checkbox.js.map +0 -1
  273. package/lib/styles/copy.d.ts.map +0 -1
  274. package/lib/styles/copy.js.map +0 -1
  275. package/lib/styles/custom-scrollbar.d.ts.map +0 -1
  276. package/lib/styles/custom-scrollbar.js.map +0 -1
  277. package/lib/styles/date-picker.d.ts.map +0 -1
  278. package/lib/styles/date-picker.js.map +0 -1
  279. package/lib/styles/file-upload.d.ts.map +0 -1
  280. package/lib/styles/file-upload.js.map +0 -1
  281. package/lib/styles/icon.d.ts.map +0 -1
  282. package/lib/styles/icon.js.map +0 -1
  283. package/lib/styles/input.d.ts.map +0 -1
  284. package/lib/styles/input.js.map +0 -1
  285. package/lib/styles/modal.d.ts.map +0 -1
  286. package/lib/styles/modal.js.map +0 -1
  287. package/lib/styles/multiselect.d.ts +0 -8
  288. package/lib/styles/multiselect.d.ts.map +0 -1
  289. package/lib/styles/multiselect.js +0 -849
  290. package/lib/styles/multiselect.js.map +0 -1
  291. package/lib/styles/option.d.ts.map +0 -1
  292. package/lib/styles/option.js.map +0 -1
  293. package/lib/styles/popup.d.ts.map +0 -1
  294. package/lib/styles/popup.js.map +0 -1
  295. package/lib/styles/radio.d.ts.map +0 -1
  296. package/lib/styles/radio.js.map +0 -1
  297. package/lib/styles/resize-observer.d.ts.map +0 -1
  298. package/lib/styles/resize-observer.js.map +0 -1
  299. package/lib/styles/scroll-container.d.ts.map +0 -1
  300. package/lib/styles/scroll-container.js.map +0 -1
  301. package/lib/styles/select-base.d.ts.map +0 -1
  302. package/lib/styles/select-base.js.map +0 -1
  303. package/lib/styles/select.d.ts.map +0 -1
  304. package/lib/styles/select.js.map +0 -1
  305. package/lib/styles/step.d.ts.map +0 -1
  306. package/lib/styles/step.js.map +0 -1
  307. package/lib/styles/switch.d.ts.map +0 -1
  308. package/lib/styles/switch.js.map +0 -1
  309. package/lib/styles/tab.d.ts.map +0 -1
  310. package/lib/styles/tab.js.map +0 -1
  311. package/lib/styles/tabs.d.ts.map +0 -1
  312. package/lib/styles/tabs.js.map +0 -1
  313. package/lib/styles/tag.d.ts.map +0 -1
  314. package/lib/styles/tag.js.map +0 -1
  315. package/lib/styles/textarea.d.ts.map +0 -1
  316. package/lib/styles/textarea.js.map +0 -1
  317. package/lib/styles/tooltip.d.ts.map +0 -1
  318. package/lib/styles/tooltip.js.map +0 -1
  319. package/lib/styles/wizard.d.ts.map +0 -1
  320. package/lib/styles/wizard.js.map +0 -1
  321. package/lib/types/common.d.ts.map +0 -1
  322. package/lib/types/common.js.map +0 -1
  323. package/lib/utils/calendar-utils.d.ts.map +0 -1
  324. package/lib/utils/calendar-utils.js.map +0 -1
  325. package/lib/utils/custom-scrollbar.d.ts.map +0 -1
  326. package/lib/utils/custom-scrollbar.js.map +0 -1
  327. package/lib/utils/flavor-sheet.d.ts.map +0 -1
  328. package/lib/utils/flavor-sheet.js.map +0 -1
  329. package/lib/utils/icon-registry.d.ts.map +0 -1
  330. package/lib/utils/icon-registry.js.map +0 -1
  331. package/lib/utils/icons.d.ts.map +0 -1
  332. package/lib/utils/icons.js.map +0 -1
  333. package/lib/utils/loader-registry.d.ts.map +0 -1
  334. package/lib/utils/loader-registry.js.map +0 -1
  335. package/lib/utils/locale.d.ts.map +0 -1
  336. package/lib/utils/locale.js.map +0 -1
  337. package/lib/utils/mobile.d.ts.map +0 -1
  338. package/lib/utils/mobile.js.map +0 -1
  339. package/lib/utils/number-format.d.ts.map +0 -1
  340. package/lib/utils/number-format.js.map +0 -1
  341. package/lib/utils/parse-boolean.d.ts +0 -39
  342. package/lib/utils/parse-boolean.d.ts.map +0 -1
  343. package/lib/utils/parse-boolean.js +0 -58
  344. package/lib/utils/parse-boolean.js.map +0 -1
  345. package/lib/utils/positioning.d.ts.map +0 -1
  346. package/lib/utils/positioning.js.map +0 -1
  347. package/lib/utils/property-capture.d.ts.map +0 -1
  348. package/lib/utils/property-capture.js.map +0 -1
  349. package/lib/utils/property-manager.d.ts.map +0 -1
  350. package/lib/utils/property-manager.js.map +0 -1
  351. package/lib/utils/resize-observer.d.ts.map +0 -1
  352. package/lib/utils/resize-observer.js.map +0 -1
  353. package/lib/utils/scroll-lock.d.ts.map +0 -1
  354. package/lib/utils/scroll-lock.js.map +0 -1
  355. package/lib/utils/styles.d.ts.map +0 -1
  356. package/lib/utils/styles.js.map +0 -1
  357. package/lib/version.d.ts.map +0 -1
  358. package/lib/version.js.map +0 -1
@@ -1,415 +1,298 @@
1
- /**
2
- * TyCopy Web Component
3
- *
4
- * Read-only field with copy-to-clipboard functionality
5
- * Perfect for API keys, tokens, URLs, code snippets, etc.
6
- *
7
- * Features:
8
- * - Read-only display (not an input)
9
- * - Copy icon on the right
10
- * - Icon animation on copy (copy → check → copy)
11
- * - Same styling as ty-input for consistency
12
- * - Label support
13
- * - Size and flavor variants
14
- */
1
+ import { DEFAULT_SIZE } from '../types/common.js';
15
2
  import { TyComponent } from '../base/ty-component.js';
16
3
  import { ensureStyles } from '../utils/styles.js';
17
4
  import { syncCustomFlavorSheet } from '../utils/flavor-sheet.js';
18
5
  import { inputStyles } from '../styles/input.js';
19
6
  import { copyStyles, copyCustomFlavorCss } from '../styles/copy.js';
20
- /**
21
- * Copy icon SVG (from Lucide)
22
- */
23
7
  const COPY_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>`;
24
- /**
25
- * Check icon SVG (from Lucide) - shown after successful copy
26
- */
27
8
  const CHECK_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`;
28
- /**
29
- * X icon SVG (from Lucide) - shown on copy failure
30
- */
31
9
  const ERROR_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>`;
32
10
  import { REQUIRED_ICON_SVG } from '../utils/icons.js';
33
- /**
34
- * Ty Copy Field Component
35
- *
36
- * @example
37
- * ```html
38
- * <!-- Basic copy field -->
39
- * <ty-copy
40
- * label="API Key"
41
- * value="sk_live_1234567890abcdef">
42
- * </ty-copy>
43
- *
44
- * <!-- Code format -->
45
- * <ty-copy
46
- * label="Install Command"
47
- * value="npm install tyrell-components"
48
- * format="code">
49
- * </ty-copy>
50
- *
51
- * <!-- Different sizes -->
52
- * <ty-copy size="sm" value="Small field"></ty-copy>
53
- * <ty-copy size="lg" value="Large field"></ty-copy>
54
- *
55
- * <!-- Semantic flavors -->
56
- * <ty-copy flavor="primary" value="Primary"></ty-copy>
57
- * <ty-copy flavor="success" value="Success"></ty-copy>
58
- * ```
59
- */
60
11
  export class TyCopy extends TyComponent {
61
- constructor() {
62
- super(); // TyComponent handles attachInternals() and attachShadow()
63
- // ============================================================================
64
- // INTERNAL STATE - Not managed by PropertyManager
65
- // ============================================================================
66
- this._copyTimeout = null;
67
- this._showingSuccess = false;
68
- this._customFlavorSheet = null;
69
- // Apply both input and copy-specific styles
70
- ensureStyles(this.shadowRoot, { css: inputStyles, id: 'ty-input' });
71
- ensureStyles(this.shadowRoot, { css: copyStyles, id: 'ty-copy' });
72
- }
73
- // observedAttributes auto-generated by TyComponent from properties config
74
- // ============================================================================
75
- // TYCOMPONENT LIFECYCLE HOOKS
76
- // ============================================================================
77
- /**
78
- * Called when component connects to DOM
79
- * TyComponent already handled pre-connection property capture
80
- */
81
- onConnect() {
82
- // TyComponent will call render() automatically after this hook
83
- this._syncCustomFlavor();
84
- }
85
- /** Custom (non-built-in) flavors — see utils/flavor-sheet.ts. */
86
- _syncCustomFlavor() {
87
- this._customFlavorSheet = syncCustomFlavorSheet(this.shadowRoot, this._customFlavorSheet, this.flavor, ({ base }) => copyCustomFlavorCss(base));
88
- }
89
- /**
90
- * Called when component disconnects from DOM
91
- */
92
- onDisconnect() {
93
- // Clear any pending timeout
94
- if (this._copyTimeout !== null) {
95
- clearTimeout(this._copyTimeout);
96
- this._copyTimeout = null;
97
- }
98
- }
99
- /**
100
- * Handle property changes - called BEFORE render
101
- */
102
- onPropertiesChanged(changes) {
103
- if (changes.some((c) => c.name === 'flavor')) {
104
- this._syncCustomFlavor();
105
- }
106
- }
107
- // ============================================================================
108
- // PRIVATE METHODS
109
- // ============================================================================
110
- /**
111
- * Build CSS class list
112
- */
113
- buildClassList() {
114
- const classes = [this.size];
115
- if (this.disabled)
116
- classes.push('disabled');
117
- if (this.required)
118
- classes.push('required');
119
- return classes.join(' ');
120
- }
121
- /**
122
- * Copy value to clipboard
123
- */
124
- async copyToClipboard() {
125
- if (this.disabled || !this.value)
126
- return;
127
- try {
128
- await navigator.clipboard.writeText(this.value);
129
- // Emit success event
130
- this.dispatchEvent(new CustomEvent('copy-success', {
131
- detail: { value: this.value },
132
- bubbles: true,
133
- composed: true
134
- }));
135
- }
136
- catch (err) {
137
- // Fallback for non-secure contexts (non-HTTPS)
138
- try {
139
- const textarea = document.createElement('textarea');
140
- textarea.value = this.value;
141
- textarea.style.position = 'fixed';
142
- textarea.style.opacity = '0';
143
- document.body.appendChild(textarea);
144
- textarea.select();
145
- document.execCommand('copy');
146
- document.body.removeChild(textarea);
147
- this.dispatchEvent(new CustomEvent('copy-success', {
148
- detail: { value: this.value },
149
- bubbles: true,
150
- composed: true
151
- }));
152
- }
153
- catch (fallbackErr) {
154
- console.error('[ty-copy] Failed to copy:', fallbackErr);
155
- this.dispatchEvent(new CustomEvent('copy-error', {
156
- detail: { error: fallbackErr },
157
- bubbles: true,
158
- composed: true
159
- }));
160
- this.showCopyError();
161
- return;
162
- }
163
- }
164
- // Show success animation (after either method succeeds)
165
- this.showCopySuccess();
166
- }
167
- /**
168
- * Show copy success animation
169
- * Uses state flag so render() can show the correct icon
170
- */
171
- showCopySuccess() {
172
- // Clear any existing timeout
173
- if (this._copyTimeout !== null) {
174
- clearTimeout(this._copyTimeout);
175
- }
176
- this._showingSuccess = true;
177
- // Update just the button without full re-render
178
- const copyButton = this.shadowRoot.querySelector('.copy-button');
179
- if (copyButton) {
180
- copyButton.classList.add('success');
181
- copyButton.innerHTML = CHECK_ICON_SVG;
182
- copyButton.setAttribute('aria-label', 'Copied!');
183
- }
184
- // Reset after 2 seconds
185
- this._copyTimeout = window.setTimeout(() => {
186
- this._showingSuccess = false;
187
- const btn = this.shadowRoot.querySelector('.copy-button');
188
- if (btn) {
189
- btn.classList.remove('success');
190
- btn.innerHTML = COPY_ICON_SVG;
191
- btn.setAttribute('aria-label', 'Copy to clipboard');
192
- }
193
- this._copyTimeout = null;
194
- }, 2000);
195
- }
196
- /**
197
- * Show copy error animation
198
- * Swaps copy icon → red X icon → copy icon
199
- */
200
- showCopyError() {
201
- if (this._copyTimeout !== null) {
202
- clearTimeout(this._copyTimeout);
203
- }
204
- this._showingSuccess = false;
205
- const copyButton = this.shadowRoot.querySelector('.copy-button');
206
- if (copyButton) {
207
- copyButton.classList.add('error');
208
- copyButton.innerHTML = ERROR_ICON_SVG;
209
- copyButton.setAttribute('aria-label', 'Copy failed');
210
- }
211
- this._copyTimeout = window.setTimeout(() => {
212
- const btn = this.shadowRoot.querySelector('.copy-button');
213
- if (btn) {
214
- btn.classList.remove('error');
215
- btn.innerHTML = COPY_ICON_SVG;
216
- btn.setAttribute('aria-label', 'Copy to clipboard');
217
- }
218
- this._copyTimeout = null;
219
- }, 2000);
220
- }
221
- /**
222
- * Setup event listeners
223
- */
224
- setupEventListeners() {
225
- const shadow = this.shadowRoot;
226
- const inputWrapper = shadow.querySelector('.input-wrapper');
227
- const copyButton = shadow.querySelector('.copy-button');
228
- // Make entire field clickable for copying
229
- if (inputWrapper && !this.disabled) {
230
- const wrapperEl = inputWrapper;
231
- wrapperEl.addEventListener('click', (e) => {
232
- // Prevent double-triggering if button was clicked
233
- if (e.target === copyButton || e.target.closest('.copy-button')) {
234
- return;
235
- }
236
- this.copyToClipboard();
237
- });
238
- // Add visual feedback - make it look clickable
239
- wrapperEl.style.cursor = 'pointer';
240
- }
241
- // Button click handler
242
- if (copyButton) {
243
- copyButton.addEventListener('click', () => {
244
- this.copyToClipboard();
245
- });
246
- }
247
- }
248
- /**
249
- * Render the component
250
- */
251
- render() {
252
- const shadow = this.shadowRoot;
253
- const classes = this.buildClassList();
254
- // Determine display element based on format, multiline and scroll
255
- const valueClass = [
256
- 'copy-field-value',
257
- this.multiline ? 'multiline' : '',
258
- this.horizontalScroll ? 'horizontal-scroll' : '',
259
- ].filter(Boolean).join(' ');
260
- const displayElement = this.format === 'code'
261
- ? `<code class="${valueClass}">${this.value || ''}</code>`
262
- : `<div class="${valueClass}">${this.value || ''}</div>`;
263
- const labelHtml = this.label ? `
264
- <label class="ty-field-label">
265
- ${this.label}
266
- ${this.required ? `<span class="required-icon">${REQUIRED_ICON_SVG}</span>` : ''}
267
- </label>
268
- ` : '';
269
- shadow.innerHTML = `
270
- <div class="input-container">
271
- ${labelHtml}
272
- <div class="input-wrapper ${classes}">
273
- ${displayElement}
274
- <button class="copy-button${this._showingSuccess ? ' success' : ''}" type="button" aria-label="${this._showingSuccess ? 'Copied!' : 'Copy to clipboard'}" ${this.disabled ? 'disabled' : ''}>
275
- ${this._showingSuccess ? CHECK_ICON_SVG : COPY_ICON_SVG}
276
- </button>
277
- </div>
278
- </div>
279
- `;
280
- // Re-setup event listeners after render
281
- this.setupEventListeners();
282
- }
283
- // ============================================================================
284
- // PROPERTY ACCESSORS - Simple wrappers (no logic!)
285
- // ============================================================================
286
- get value() {
287
- return this.getProperty('value');
288
- }
289
- set value(val) {
290
- this.setProperty('value', val);
291
- }
292
- get label() {
293
- return this.getProperty('label');
294
- }
295
- set label(val) {
296
- this.setProperty('label', val);
297
- }
298
- get size() {
299
- return this.getProperty('size');
300
- }
301
- set size(value) {
302
- this.setProperty('size', value);
303
- }
304
- get flavor() {
305
- return this.getProperty('flavor');
306
- }
307
- set flavor(value) {
308
- this.setProperty('flavor', value);
309
- }
310
- get format() {
311
- return this.getProperty('format');
312
- }
313
- set format(value) {
314
- this.setProperty('format', value);
315
- }
316
- get multiline() {
317
- return this.getProperty('multiline');
318
- }
319
- set multiline(value) {
320
- this.setProperty('multiline', value);
321
- }
322
- get horizontalScroll() {
323
- return this.getProperty('horizontalScroll');
324
- }
325
- set horizontalScroll(value) {
326
- this.setProperty('horizontalScroll', value);
327
- }
328
- get disabled() {
329
- return this.getProperty('disabled');
330
- }
331
- set disabled(value) {
332
- this.setProperty('disabled', value);
333
- }
334
- get required() {
335
- return this.getProperty('required');
336
- }
337
- set required(value) {
338
- this.setProperty('required', value);
339
- }
12
+ constructor() {
13
+ super();
14
+ this._copyTimeout = null;
15
+ this._showingSuccess = false;
16
+ this._customFlavorSheet = null;
17
+ ensureStyles(this.shadowRoot, { css: inputStyles, id: 'ty-input' });
18
+ ensureStyles(this.shadowRoot, { css: copyStyles, id: 'ty-copy' });
19
+ }
20
+ onConnect() {
21
+ this._syncCustomFlavor();
22
+ }
23
+ _syncCustomFlavor() {
24
+ this._customFlavorSheet = syncCustomFlavorSheet(this.shadowRoot, this._customFlavorSheet, this.flavor, ({ base }) => copyCustomFlavorCss(base));
25
+ }
26
+ onDisconnect() {
27
+ if (this._copyTimeout !== null) {
28
+ clearTimeout(this._copyTimeout);
29
+ this._copyTimeout = null;
30
+ }
31
+ }
32
+ onPropertiesChanged(changes) {
33
+ if (changes.some((c) => c.name === 'flavor')) {
34
+ this._syncCustomFlavor();
35
+ }
36
+ }
37
+ buildClassList() {
38
+ const classes = [];
39
+ if (this.disabled)
40
+ classes.push('disabled');
41
+ if (this.required)
42
+ classes.push('required');
43
+ return classes.join(' ');
44
+ }
45
+ async copyToClipboard() {
46
+ if (this.disabled || !this.value)
47
+ return;
48
+ const value = this.value;
49
+ try {
50
+ await navigator.clipboard.writeText(value);
51
+ this.dispatchEvent(new CustomEvent('copy-success', {
52
+ detail: { value },
53
+ bubbles: true,
54
+ composed: true
55
+ }));
56
+ }
57
+ catch (err) {
58
+ try {
59
+ const textarea = document.createElement('textarea');
60
+ textarea.value = value;
61
+ textarea.style.position = 'fixed';
62
+ textarea.style.opacity = '0';
63
+ document.body.appendChild(textarea);
64
+ textarea.select();
65
+ document.execCommand('copy');
66
+ document.body.removeChild(textarea);
67
+ this.dispatchEvent(new CustomEvent('copy-success', {
68
+ detail: { value },
69
+ bubbles: true,
70
+ composed: true
71
+ }));
72
+ }
73
+ catch (fallbackErr) {
74
+ console.error('[ty-copy] Failed to copy:', fallbackErr);
75
+ this.dispatchEvent(new CustomEvent('copy-error', {
76
+ detail: { error: fallbackErr },
77
+ bubbles: true,
78
+ composed: true
79
+ }));
80
+ this.showCopyError();
81
+ return;
82
+ }
83
+ }
84
+ this.showCopySuccess();
85
+ }
86
+ showCopySuccess() {
87
+ if (this._copyTimeout !== null) {
88
+ clearTimeout(this._copyTimeout);
89
+ }
90
+ this._showingSuccess = true;
91
+ const copyButton = this.shadowRoot.querySelector('.copy-button');
92
+ if (copyButton) {
93
+ copyButton.classList.add('success');
94
+ copyButton.innerHTML = CHECK_ICON_SVG;
95
+ copyButton.setAttribute('aria-label', 'Copied!');
96
+ }
97
+ this._copyTimeout = window.setTimeout(() => {
98
+ this._showingSuccess = false;
99
+ const btn = this.shadowRoot.querySelector('.copy-button');
100
+ if (btn) {
101
+ btn.classList.remove('success');
102
+ btn.innerHTML = COPY_ICON_SVG;
103
+ btn.setAttribute('aria-label', 'Copy to clipboard');
104
+ }
105
+ this._copyTimeout = null;
106
+ }, 2000);
107
+ }
108
+ showCopyError() {
109
+ if (this._copyTimeout !== null) {
110
+ clearTimeout(this._copyTimeout);
111
+ }
112
+ this._showingSuccess = false;
113
+ const copyButton = this.shadowRoot.querySelector('.copy-button');
114
+ if (copyButton) {
115
+ copyButton.classList.add('error');
116
+ copyButton.innerHTML = ERROR_ICON_SVG;
117
+ copyButton.setAttribute('aria-label', 'Copy failed');
118
+ }
119
+ this._copyTimeout = window.setTimeout(() => {
120
+ const btn = this.shadowRoot.querySelector('.copy-button');
121
+ if (btn) {
122
+ btn.classList.remove('error');
123
+ btn.innerHTML = COPY_ICON_SVG;
124
+ btn.setAttribute('aria-label', 'Copy to clipboard');
125
+ }
126
+ this._copyTimeout = null;
127
+ }, 2000);
128
+ }
129
+ setupEventListeners() {
130
+ const shadow = this.shadowRoot;
131
+ const inputWrapper = shadow.querySelector('.input-wrapper');
132
+ const copyButton = shadow.querySelector('.copy-button');
133
+ if (inputWrapper && !this.disabled) {
134
+ const wrapperEl = inputWrapper;
135
+ wrapperEl.addEventListener('click', (e) => {
136
+ if (e.target === copyButton || e.target.closest('.copy-button')) {
137
+ return;
138
+ }
139
+ this.copyToClipboard();
140
+ });
141
+ wrapperEl.style.cursor = 'pointer';
142
+ }
143
+ if (copyButton) {
144
+ copyButton.addEventListener('click', () => {
145
+ this.copyToClipboard();
146
+ });
147
+ }
148
+ }
149
+ render() {
150
+ const shadow = this.shadowRoot;
151
+ const classes = this.buildClassList();
152
+ const valueClass = [
153
+ 'copy-field-value',
154
+ this.multiline ? 'multiline' : '',
155
+ this.horizontalScroll ? 'horizontal-scroll' : '',
156
+ ].filter(Boolean).join(' ');
157
+ const displayElement = this.format === 'code'
158
+ ? `<code class="${valueClass}">${this.value || ''}</code>`
159
+ : `<div class="${valueClass}">${this.value || ''}</div>`;
160
+ const labelHtml = this.label ? `
161
+ <label class="ty-field-label">
162
+ ${this.label}
163
+ ${this.required ? `<span class="required-icon">${REQUIRED_ICON_SVG}</span>` : ''}
164
+ </label>
165
+ ` : '';
166
+ shadow.innerHTML = `
167
+ <div class="input-container">
168
+ ${labelHtml}
169
+ <div class="input-wrapper ${classes}">
170
+ ${displayElement}
171
+ <button class="copy-button${this._showingSuccess ? ' success' : ''}" type="button" aria-label="${this._showingSuccess ? 'Copied!' : 'Copy to clipboard'}" ${this.disabled ? 'disabled' : ''}>
172
+ ${this._showingSuccess ? CHECK_ICON_SVG : COPY_ICON_SVG}
173
+ </button>
174
+ </div>
175
+ </div>
176
+ `;
177
+ this.setupEventListeners();
178
+ }
179
+ get value() {
180
+ return this.getProperty('value');
181
+ }
182
+ set value(val) {
183
+ this.setProperty('value', val);
184
+ }
185
+ get label() {
186
+ return this.getProperty('label');
187
+ }
188
+ set label(val) {
189
+ this.setProperty('label', val);
190
+ }
191
+ get size() {
192
+ return this.getProperty('size');
193
+ }
194
+ set size(value) {
195
+ this.setProperty('size', value);
196
+ }
197
+ get flavor() {
198
+ return this.getProperty('flavor');
199
+ }
200
+ set flavor(value) {
201
+ this.setProperty('flavor', value);
202
+ }
203
+ get format() {
204
+ return this.getProperty('format');
205
+ }
206
+ set format(value) {
207
+ this.setProperty('format', value);
208
+ }
209
+ get multiline() {
210
+ return this.getProperty('multiline');
211
+ }
212
+ set multiline(value) {
213
+ this.setProperty('multiline', value);
214
+ }
215
+ get horizontalScroll() {
216
+ return this.getProperty('horizontalScroll');
217
+ }
218
+ set horizontalScroll(value) {
219
+ this.setProperty('horizontalScroll', value);
220
+ }
221
+ get disabled() {
222
+ return this.getProperty('disabled');
223
+ }
224
+ set disabled(value) {
225
+ this.setProperty('disabled', value);
226
+ }
227
+ get required() {
228
+ return this.getProperty('required');
229
+ }
230
+ set required(value) {
231
+ this.setProperty('required', value);
232
+ }
340
233
  }
341
234
  TyCopy.formAssociated = true;
342
- // ============================================================================
343
- // PROPERTY CONFIGURATION - Declarative property lifecycle
344
- // ============================================================================
345
235
  TyCopy.properties = {
346
- value: {
347
- type: 'string',
348
- visual: true,
349
- formValue: true,
350
- default: '',
351
- },
352
- label: {
353
- type: 'string',
354
- visual: true,
355
- default: '',
356
- },
357
- size: {
358
- type: 'string',
359
- visual: true,
360
- default: 'md',
361
- validate: (v) => ['xs', 'sm', 'md', 'lg', 'xl'].includes(v),
362
- coerce: (v) => {
363
- if (!['xs', 'sm', 'md', 'lg', 'xl'].includes(v)) {
364
- console.warn(`[ty-copy] Invalid size '${v}'. Using 'md'.`);
365
- return 'md';
366
- }
367
- return v;
368
- },
369
- },
370
- // Any string is accepted: built-ins get static CSS, other identifiers
371
- // become custom flavors (see _syncCustomFlavor), garbage degrades to
372
- // the default look.
373
- flavor: {
374
- type: 'string',
375
- visual: true,
376
- default: 'neutral',
377
- },
378
- format: {
379
- type: 'string',
380
- visual: true,
381
- default: 'text',
382
- coerce: (v) => (v === 'code' ? 'code' : 'text'),
383
- },
384
- multiline: {
385
- type: 'boolean',
386
- visual: true,
387
- default: false,
388
- },
389
- horizontalScroll: {
390
- type: 'boolean',
391
- visual: true,
392
- default: false,
393
- },
394
- disabled: {
395
- type: 'boolean',
396
- visual: true,
397
- default: false,
398
- },
399
- required: {
400
- type: 'boolean',
401
- visual: true,
402
- default: false,
403
- },
236
+ value: {
237
+ type: 'string',
238
+ visual: true,
239
+ formValue: true,
240
+ default: '',
241
+ },
242
+ label: {
243
+ type: 'string',
244
+ visual: true,
245
+ default: '',
246
+ },
247
+ size: {
248
+ type: 'string',
249
+ visual: true,
250
+ default: DEFAULT_SIZE,
251
+ validate: (v) => ['xs', 'sm', 'md', 'lg', 'xl'].includes(v),
252
+ coerce: (v) => {
253
+ if (!['xs', 'sm', 'md', 'lg', 'xl'].includes(v)) {
254
+ console.warn(`[ty-copy] Invalid size '${v}'. Using '${DEFAULT_SIZE}'.`);
255
+ return DEFAULT_SIZE;
256
+ }
257
+ return v;
258
+ },
259
+ },
260
+ flavor: {
261
+ type: 'string',
262
+ visual: true,
263
+ default: 'neutral',
264
+ },
265
+ format: {
266
+ type: 'string',
267
+ visual: true,
268
+ default: 'text',
269
+ coerce: (v) => (v === 'code' ? 'code' : 'text'),
270
+ },
271
+ multiline: {
272
+ type: 'boolean',
273
+ visual: true,
274
+ default: false,
275
+ },
276
+ horizontalScroll: {
277
+ type: 'boolean',
278
+ visual: true,
279
+ default: false,
280
+ },
281
+ disabled: {
282
+ type: 'boolean',
283
+ visual: true,
284
+ default: false,
285
+ },
286
+ required: {
287
+ type: 'boolean',
288
+ visual: true,
289
+ default: false,
290
+ },
404
291
  };
405
- // Register the custom element
406
292
  if (!customElements.get('ty-copy')) {
407
- customElements.define('ty-copy', TyCopy);
293
+ customElements.define('ty-copy', TyCopy);
408
294
  }
409
- // Also exposed as ty-copy-field — says what it is (a read-only field with a
410
- // copy button). A constructor can only register once, hence the subclass.
411
295
  if (!customElements.get('ty-copy-field')) {
412
- customElements.define('ty-copy-field', class TyCopyField extends TyCopy {
413
- });
296
+ customElements.define('ty-copy-field', class TyCopyField extends TyCopy {
297
+ });
414
298
  }
415
- //# sourceMappingURL=copy.js.map