@brightspot/ui 6.1.1-rc.2 → 6.2.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 (116) hide show
  1. package/dist/storybook/assets/{ActionBar.stories-Q_bdek_N.js → ActionBar.stories-DgLrwInB.js} +1 -1
  2. package/dist/storybook/assets/{ActionItem.stories-Ccyot7vj.js → ActionItem.stories-C-SkWFxc.js} +1 -1
  3. package/dist/storybook/assets/{AiSparkle.stories-Ccapqzcw.js → AiSparkle.stories-BdwXJ4C1.js} +1 -1
  4. package/dist/storybook/assets/{Avatar.stories-CPcQWZtG.js → Avatar.stories-BQrt8GRW.js} +1 -1
  5. package/dist/storybook/assets/{AvatarGroup.stories-Bws-izJt.js → AvatarGroup.stories-BdmsYcGc.js} +1 -1
  6. package/dist/storybook/assets/{Badge.stories-xck9Ke5e.js → Badge.stories-mu4nbODQ.js} +1 -1
  7. package/dist/storybook/assets/{Banner.stories-D3ieqG7F.js → Banner.stories-DMP2OXL9.js} +1 -1
  8. package/dist/storybook/assets/{Button-CQ2ZvHGM.js → Button-xZDsWWL_.js} +1 -1
  9. package/dist/storybook/assets/{Button.stories-BkGox6QF.js → Button.stories-C4jM9Bim.js} +1 -1
  10. package/dist/storybook/assets/{ButtonGroup.stories-BxDNL7ej.js → ButtonGroup.stories-zscaMCvE.js} +1 -1
  11. package/dist/storybook/assets/{Card.stories-BrzAwQwE.js → Card.stories-CsV1xMbI.js} +1 -1
  12. package/dist/storybook/assets/{Celebrate.stories-BFqqbYhp.js → Celebrate.stories-D2mVlrqj.js} +1 -1
  13. package/dist/storybook/assets/{Checkbox.stories-yNb9DH9g.js → Checkbox.stories-CAOPfsPn.js} +1 -1
  14. package/dist/storybook/assets/{CircularProgress.stories--KSA2X4d.js → CircularProgress.stories-Dj44Wy1Q.js} +1 -1
  15. package/dist/storybook/assets/{ClipboardMixin.stories-DT0symyW.js → ClipboardMixin.stories-sMr91AkY.js} +1 -1
  16. package/dist/storybook/assets/{Color-6BZIO3FS-CEpjJcuB.js → Color-6BZIO3FS-Di40DCa8.js} +1 -1
  17. package/dist/storybook/assets/{Colors.stories-BEtjS3CS.js → Colors.stories-nUklULEf.js} +1 -1
  18. package/dist/storybook/assets/{CombinedEffects.stories-DZsO6E1c.js → CombinedEffects.stories-DHteudNU.js} +1 -1
  19. package/dist/storybook/assets/{ComponentStatesMixin-C-G6neuB.js → ComponentStatesMixin-DC5hoSCf.js} +1 -1
  20. package/dist/storybook/assets/{ComponentStatesMixin.stories-D4B2eXzV.js → ComponentStatesMixin.stories-DyZXrUfS.js} +1 -1
  21. package/dist/storybook/assets/{CopyToClipboard.stories-C1wxRcNr.js → CopyToClipboard.stories-DKfUIVB6.js} +1 -1
  22. package/dist/storybook/assets/{Debounce.stories-CEXdiU_4.js → Debounce.stories-C6iPHMJ-.js} +1 -1
  23. package/dist/storybook/assets/{DocsRenderer-LL677BLK-iD6uwWm0.js → DocsRenderer-LL677BLK-BC-DluPS.js} +3 -3
  24. package/dist/storybook/assets/{Dropdown.stories-DzgAKuev.js → Dropdown.stories-DY3LbbOm.js} +1 -1
  25. package/dist/storybook/assets/{EmptyState.stories-8IezRmLe.js → EmptyState.stories-Ec87tfLY.js} +1 -1
  26. package/dist/storybook/assets/{EscaAvatar.stories-CFRMImDC.js → EscaAvatar.stories-ZaaMKZqz.js} +1 -1
  27. package/dist/storybook/assets/{Events.stories-wc_WlNNX.js → Events.stories-DaTVivNG.js} +1 -1
  28. package/dist/storybook/assets/{Heading.stories-CBopc-Ov.js → Heading.stories-B6jRenfp.js} +1 -1
  29. package/dist/storybook/assets/{HueRipple.stories-B1BLaONM.js → HueRipple.stories-CnDz87pe.js} +1 -1
  30. package/dist/storybook/assets/{Icon.stories-Bul1n2nN.js → Icon.stories-DH0mXw3h.js} +1 -1
  31. package/dist/storybook/assets/{IconButton.stories-DDCBKBqw.js → IconButton.stories-CNtEEf3-.js} +1 -1
  32. package/dist/storybook/assets/{LinearProgress.stories-DWroemrV.js → LinearProgress.stories-B7q0qeGc.js} +1 -1
  33. package/dist/storybook/assets/{Message.stories-CfWo8uqR.js → Message.stories--ArrB33R.js} +1 -1
  34. package/dist/storybook/assets/{OnFindMixin.stories-DRr67PU5.js → OnFindMixin.stories-Bu3Et43N.js} +1 -1
  35. package/dist/storybook/assets/{Pagination.stories-CJ0dmE6y.js → Pagination.stories-DL3nv05u.js} +1 -1
  36. package/dist/storybook/assets/{Popover.stories-CFFe2utX.js → Popover.stories-C1xiMRm0.js} +1 -1
  37. package/dist/storybook/assets/{ReadyMixin-euHV5BrF.js → ReadyMixin-CkFGSiXW.js} +1 -1
  38. package/dist/storybook/assets/{RovingTabindexMixin.stories-CcKn8eYu.js → RovingTabindexMixin.stories-DxABagoS.js} +1 -1
  39. package/dist/storybook/assets/{Rtc.stories-B_26leBQ.js → Rtc.stories-DICg80iT.js} +1 -1
  40. package/dist/storybook/assets/{ScrollShadow.stories-COcTqDYx.js → ScrollShadow.stories-YSVPDcG9.js} +1 -1
  41. package/dist/storybook/assets/{Switch.stories-fZAYVOXQ.js → Switch.stories-UQoRYdvu.js} +1 -1
  42. package/dist/storybook/assets/{Tab.stories-ChmYj35a.js → Tab.stories-aO-j5FR7.js} +1 -1
  43. package/dist/storybook/assets/{Tabs.stories-Bgb-44oF.js → Tabs.stories-Vh5fj_rb.js} +1 -1
  44. package/dist/storybook/assets/{Throttle.stories-BP21CM6q.js → Throttle.stories-DqQiG8mr.js} +1 -1
  45. package/dist/storybook/assets/{Tooltip.stories-Ck7XsJKW.js → Tooltip.stories-DykL06JB.js} +1 -1
  46. package/dist/storybook/assets/{Upload.stories-DMedgAwp.js → Upload.stories-BunAEUlO.js} +1 -1
  47. package/dist/storybook/assets/{UploadItem.stories-D1rV5quQ.js → UploadItem.stories-CNR2IKsl.js} +1 -1
  48. package/dist/storybook/assets/{Welcome.stories-DDEhWqOY.js → Welcome.stories-DuKEOEsw.js} +1 -1
  49. package/dist/storybook/assets/{Widget.stories-iTycJQkv.js → Widget.stories-B5WKvF2m.js} +1 -1
  50. package/dist/storybook/assets/{WithTooltip-65CFNBJE-BDmGdT_q.js → WithTooltip-65CFNBJE-KIfM6hV3.js} +1 -1
  51. package/dist/storybook/assets/{blocks-45GMe9mP.js → blocks-BJtylb2_.js} +5 -5
  52. package/dist/storybook/assets/{formatter-EIJCOSYU-Dvxzfjid.js → formatter-EIJCOSYU-DyJPXrAY.js} +1 -1
  53. package/dist/storybook/assets/if-defined-DELMnuB4.js +1 -0
  54. package/dist/storybook/assets/{iframe-CemlMLl9.js → iframe-BoW1X7a_.js} +3 -3
  55. package/dist/storybook/assets/iframe-HDp5BmO_.css +1 -0
  56. package/dist/storybook/assets/{index-Ei3bFG4y.js → index-9YgpSjWr.js} +1 -1
  57. package/dist/storybook/assets/{onFind-96dPwZGj.js → onFind-BWxYoVUv.js} +1 -1
  58. package/dist/storybook/assets/{onFind.stories-DwMmvzD8.js → onFind.stories-30rdWtPx.js} +1 -1
  59. package/dist/storybook/assets/{onRemove.stories-Bw8nC3q8.js → onRemove.stories-B7qKCwA-.js} +1 -1
  60. package/dist/storybook/assets/{onVisible.stories-BZyJ5si2.js → onVisible.stories-_lsloFGV.js} +1 -1
  61. package/dist/storybook/assets/{style-map-BZ1BR1yx.js → style-map-D7rS_uYZ.js} +1 -1
  62. package/dist/storybook/assets/{syntaxhighlighter-ED5Y7EFY-B4dajqNJ.js → syntaxhighlighter-ED5Y7EFY-mLC5--p6.js} +1 -1
  63. package/dist/storybook/iframe.html +2 -2
  64. package/dist/storybook/project.json +1 -1
  65. package/dist/tailwind-plugin-button.js +2 -0
  66. package/dist/tailwind-plugin-button.js.map +1 -1
  67. package/dist/tailwind-plugin-button.ts +2 -0
  68. package/package.json +1 -1
  69. package/src/legacy/tool-ui/src/Admin.css +2 -2
  70. package/src/legacy/tool-ui/src/CIGCluster.css +9 -1
  71. package/src/legacy/tool-ui/src/ChartCompat.ts +1 -1
  72. package/src/legacy/tool-ui/src/Compat.css +6 -0
  73. package/src/legacy/tool-ui/src/ContentEdit.css +19 -12
  74. package/src/legacy/tool-ui/src/ContentEditPanel.ts +26 -12
  75. package/src/legacy/tool-ui/src/ContentInputGroup.css +8 -0
  76. package/src/legacy/tool-ui/src/Conversation.css +19 -7
  77. package/src/legacy/tool-ui/src/EmbeddedInputGroup/index.ts +20 -50
  78. package/src/legacy/tool-ui/src/Enhancement.css +3 -2
  79. package/src/legacy/tool-ui/src/Entry.ts +11 -0
  80. package/src/legacy/tool-ui/src/Global.d.ts +3 -0
  81. package/src/legacy/tool-ui/src/Guide.css +5 -5
  82. package/src/legacy/tool-ui/src/LiveBlog.css +2 -2
  83. package/src/legacy/tool-ui/src/MenuView.css +3 -2
  84. package/src/legacy/tool-ui/src/Message.css +4 -9
  85. package/src/legacy/tool-ui/src/Page.css +3 -3
  86. package/src/legacy/tool-ui/src/ProseMirror.css +1 -1
  87. package/src/legacy/tool-ui/src/RepeatableContentInputGroup.css +5 -5
  88. package/src/legacy/tool-ui/src/Revisions.css +2 -2
  89. package/src/legacy/tool-ui/src/SearchFields.css +2 -2
  90. package/src/legacy/tool-ui/src/TabBar.css +2 -2
  91. package/src/legacy/tool-ui/src/Widget.css +21 -2
  92. package/src/legacy/tool-ui/src/form/FormFilter/index.ts +2 -2
  93. package/src/legacy/tool-ui/src/logVersion.ts +9 -0
  94. package/src/legacy/tool-ui/src/main/webapp/dist/2111.5d43fec84fea624d6371.css +1 -0
  95. package/src/legacy/tool-ui/src/main/webapp/dist/7718.5d43fec84fea624d6371.css +1 -0
  96. package/src/legacy/tool-ui/src/main/webapp/dist/ChartCompat.c7121ea8407d80ee5abe.js +1 -0
  97. package/src/legacy/tool-ui/src/main/webapp/dist/RTEProseMirror.fffd76fefb194ae6889b.js +500 -0
  98. package/src/legacy/tool-ui/src/main/webapp/dist/{v4.0bee83483819ebe74fb5.js → v4.59ef78c7444a26d2fc6e.js} +8 -8
  99. package/src/legacy/tool-ui/src/main/webapp/dist/v4.b1e9f6ac0449331711fc.css +3 -0
  100. package/src/legacy/tool-ui/src/main/webapp/dist/v5.81bcf80e29f5d0b03f40.js +92 -0
  101. package/src/legacy/tool-ui/src/main/webapp/dist/v5.b8a1f40b189e4537117d.css +5 -0
  102. package/src/legacy/tool-ui/src/main/webapp/v4/CIGCluster.less +9 -0
  103. package/src/legacy/tool-ui/src/main/webapp/v4/TabBar.less +4 -0
  104. package/src/legacy/tool-ui/src/v5.ts +49 -6
  105. package/dist/storybook/assets/if-defined-C-mi5lcR.js +0 -1
  106. package/dist/storybook/assets/iframe-abUCrGGI.css +0 -1
  107. package/src/legacy/tool-ui/src/main/webapp/dist/2111.8f1e08a5cc223fd14542.css +0 -1
  108. package/src/legacy/tool-ui/src/main/webapp/dist/7718.8f1e08a5cc223fd14542.css +0 -1
  109. package/src/legacy/tool-ui/src/main/webapp/dist/ChartCompat.4dd096dd030942227ec6.js +0 -1
  110. package/src/legacy/tool-ui/src/main/webapp/dist/RTEProseMirror.55a2d6ccdce502c79815.js +0 -500
  111. package/src/legacy/tool-ui/src/main/webapp/dist/v4.477ad1936f8c04d7b232.css +0 -3
  112. package/src/legacy/tool-ui/src/main/webapp/dist/v5.68bcb9af002dae392057.js +0 -92
  113. package/src/legacy/tool-ui/src/main/webapp/dist/v5.76825523ffff1ad77cdf.css +0 -5
  114. /package/src/legacy/tool-ui/src/main/webapp/dist/{RTEProseMirror.55a2d6ccdce502c79815.js.LICENSE.txt → RTEProseMirror.fffd76fefb194ae6889b.js.LICENSE.txt} +0 -0
  115. /package/src/legacy/tool-ui/src/main/webapp/dist/{v4.0bee83483819ebe74fb5.js.LICENSE.txt → v4.59ef78c7444a26d2fc6e.js.LICENSE.txt} +0 -0
  116. /package/src/legacy/tool-ui/src/main/webapp/dist/{v5.68bcb9af002dae392057.js.LICENSE.txt → v5.81bcf80e29f5d0b03f40.js.LICENSE.txt} +0 -0
@@ -90,6 +90,8 @@ module.exports = plugin(function ({ addComponents, addUtilities, theme }) {
90
90
  '&:disabled': disabledStyle,
91
91
  '&[disabled]': disabledStyle,
92
92
  textDecoration: 'none',
93
+ // Explicit so re-applying btu-button clears an outline, as it already does background/color.
94
+ outline: 'none',
93
95
  transition: 'scale 150ms ease',
94
96
  '&:hover': {
95
97
  color: 'var(--button-pressed-text-color, var(--button-disabled-text-color, var(--button-text-color)))',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspot/ui",
3
- "version": "6.1.1-rc.2",
3
+ "version": "6.2.0",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "description": "A UI library for building Brightspot CMS components.",
@@ -13,7 +13,7 @@
13
13
  }
14
14
 
15
15
  /* Admin areas side nav styling */
16
- .Admin-nav {
16
+ .Admin .Admin-nav {
17
17
  @apply bg-gray-50;
18
18
 
19
19
  > h2,
@@ -43,7 +43,7 @@
43
43
  }
44
44
 
45
45
  /* These content selectors should just appear as normal ComboInputs */
46
- > form > .ContentSelector-select + .ComboInput {
46
+ > form > .ComboInput {
47
47
  @apply rounded-lg px-4;
48
48
 
49
49
  &:not([aria-expanded='true'], :focus-visible) {
@@ -1,5 +1,13 @@
1
1
  btu-cig-cluster {
2
- @apply blokk flex-grow basis-full contain-layout contain-style;
2
+ --gap: calc(2 * var(--CIG-padding));
3
+
4
+ /* Flex (not block) so narrow .CIG-row children pair up like they do in .CIG. */
5
+ @apply flex flex-grow flex-wrap basis-full gap-x-[--gap] contain-layout contain-style;
6
+ }
7
+
8
+ /* Children run the full row; the narrow modifiers (.is-half etc.) override this to pair up. */
9
+ btu-cig-cluster > * {
10
+ @apply basis-full;
3
11
  }
4
12
 
5
13
  btu-cig-cluster:state(btu-error) {
@@ -247,7 +247,7 @@ Highcharts.theme = {
247
247
  }
248
248
 
249
249
  Highcharts.setOptions(Highcharts.theme)
250
- Highcharts.setOptions({ lang: { noData: 'No Data to Display' } })
250
+ Highcharts.setOptions({ lang: { noData: window.BRIGHTSPOT?.ui?.tooltips?.chartNoData ?? 'No Data to Display' } })
251
251
 
252
252
  const createLabels = (table: HTMLTableElement): string[] => {
253
253
  const labels = []
@@ -202,6 +202,12 @@
202
202
  }
203
203
  }
204
204
 
205
+ /* btu-button is colorless without a variant. :where() keeps this at one class of specificity so
206
+ context rules (ActionBar, etc.) still win. */
207
+ .Button:not(:where(.is-dominant, .is-green, .is-yellow, .Link)) {
208
+ @apply btu-button-gray btu-button-fill-none btu-button-outline;
209
+ }
210
+
205
211
  .Button.is-dominant {
206
212
  @apply btu-button-primary;
207
213
  }
@@ -760,18 +760,29 @@
760
760
  @apply flex flex-nowrap gap-2;
761
761
  }
762
762
 
763
+ /* Lives in the edit grid, not the scrolling form, so a space-taking scrollbar
764
+ can't push the hit target off the panel edge. */
763
765
  .ContentEdit-resizeWrapper {
764
- --resize-hitbox-w: 8px;
765
- @apply pointer-events-none invisible absolute z-20 !col-[fullbleed-end] w-[--resize-hitbox-w] bg-transparent [inset-block-end:0] [inset-block-start:0] [inset-inline-start:calc(100%_-_var(--resize-hitbox-w))] md:pointer-events-auto md:visible md:cursor-col-resize;
766
+ --resize-hitbox-w: 16px;
767
+ margin-inline-end: calc(-1 * var(--resize-hitbox-w));
768
+ @apply pointer-events-none hidden w-[--resize-hitbox-w] justify-self-end bg-transparent [grid-area:left] md:pointer-events-auto md:relative md:z-20 md:cursor-col-resize md:touch-none;
766
769
  }
767
770
 
768
- .ContentEdit-resizeWrapper:hover .ContentEdit-resizeHandle {
771
+ /* Laid out only in the edit grid, since other popups are grids with no `left` area. */
772
+ :is(.Page.is-editing .Page-content, .Popup-content.is-editing)
773
+ > .ContentEdit-resizeWrapper {
774
+ @apply md:blokk;
775
+ }
776
+
777
+ .ContentEdit-resizeWrapper:hover .ContentEdit-resizeHandle,
778
+ .ContentEdit-resizeWrapper:active .ContentEdit-resizeHandle {
769
779
  @apply bg-primary-500;
770
780
  }
771
781
 
772
782
  .ContentEdit-resizeHandle {
773
783
  --resize-handle-w: 2px;
774
- @apply pointer-events-none fixed h-full w-[var(--resize-handle-w)] translate-x-[calc(var(--resize-hitbox-w)_-_var(--resize-handle-w))] transition-all;
784
+ /* Persistently visible so it's discoverable on touch devices (no :hover). */
785
+ @apply pointer-events-none absolute inset-y-0 start-0 w-[var(--resize-handle-w)] bg-primary-100 transition-colors;
775
786
  }
776
787
 
777
788
  /* Banners / Messages styling in Content edit form */
@@ -884,14 +895,10 @@
884
895
  }
885
896
 
886
897
  .ContentEdit-revisionActions {
887
- @apply text-[--Revision-revisionEmphasisColor] max-md:mt-3;
898
+ @apply flex flex-wrap gap-4 text-[--Revision-revisionEmphasisColor] max-md:mt-3;
888
899
 
889
900
  > a {
890
- white-space: nowrap;
891
- }
892
-
893
- > a:not(:first-child) {
894
- margin-left: var(--gap-l);
901
+ @apply whitespace-nowrap;
895
902
  }
896
903
  }
897
904
 
@@ -1015,11 +1022,11 @@
1015
1022
  }
1016
1023
 
1017
1024
  button.ContentEdit-workflowLink {
1018
- @apply btu-button btu-button-fill-none btu-button-primary m-6 !ms-auto btu-button-container-none after:btu-icon after:btu-icon-arrow-right after:ml-2;
1025
+ @apply btu-button btu-button-fill-none btu-button-primary m-6 !ms-auto btu-button-container-none after:btu-icon after:btu-icon-arrow-right rtl:after:btu-icon-arrow-left after:ms-2;
1019
1026
  }
1020
1027
 
1021
1028
  [data-name='publishOverride'] button.ContentEdit-workflowLink {
1022
- @apply !me-auto !ms-6 before:btu-icon before:btu-icon-arrow-left before:mr-2 after:hidden;
1029
+ @apply !me-auto !ms-6 before:btu-icon before:btu-icon-arrow-left rtl:before:btu-icon-arrow-right before:me-2 after:hidden;
1023
1030
  }
1024
1031
 
1025
1032
  /* Hide workflow link when not in publish override mode */
@@ -13,9 +13,9 @@ let panelData: PanelData | null
13
13
  let pointerIsDown = false
14
14
  let pdOriginX = 0 // Pointer down origin x position
15
15
  let gtcOrigin: number[] = [] // Origin Grid Template Columns in pixels
16
- let ogTransProp: undefined | string
17
16
  let isRTL = false // Whether the container has RTL direction
18
17
  let container: HTMLElement | null // The target Page
18
+ let grid: HTMLElement | null // The grid whose columns the drag resizes
19
19
  let panel: HTMLElement | null // The target Panel
20
20
 
21
21
  const updateWidth = (length: string) => {
@@ -47,6 +47,8 @@ const onPointerDown = (e: PointerEvent) => {
47
47
  if (e.target.classList.contains('ContentEdit-resizeWrapper')) {
48
48
  container = e.target.closest<HTMLElement>('.Page-content, .Popup')
49
49
  if (!container) return
50
+ // Capture so a touch/trackpad drag isn't stolen by scroll and lost mid-drag.
51
+ e.target.setPointerCapture(e.pointerId)
50
52
  pointerIsDown = true
51
53
  const isPopup = container.classList.contains('Popup')
52
54
  if (isPopup) {
@@ -57,15 +59,15 @@ const onPointerDown = (e: PointerEvent) => {
57
59
  document.body.style.userSelect = 'none'
58
60
  }
59
61
  pdOriginX = e.screenX
60
- const computedStyle = getComputedStyle(container)
61
- ogTransProp = computedStyle.transitionProperty
62
- isRTL = computedStyle.direction === 'rtl'
63
- container.style.transitionProperty = 'none'
64
- const grid = isPopup
62
+ isRTL = getComputedStyle(container).direction === 'rtl'
63
+ grid = isPopup
65
64
  ? container.querySelector<HTMLElement>('.Popup-content')
66
65
  : container
67
66
  if (!grid) return
68
67
 
68
+ // The transition belongs to the grid, which in a popup is not the container.
69
+ grid.style.transitionProperty = 'none'
70
+
69
71
  gtcOrigin = window
70
72
  .getComputedStyle(grid)
71
73
  .gridTemplateColumns.split(' ')
@@ -101,15 +103,16 @@ const onPointerDown = (e: PointerEvent) => {
101
103
  }
102
104
  }
103
105
 
104
- const onPointerUp = (e: PointerEvent) => {
106
+ const onPointerUp = (e: PointerEvent, save = true) => {
105
107
  panel = null
106
108
  pointerIsDown = false
109
+ if (grid) {
110
+ grid.style.removeProperty('transition-property')
111
+ grid = null
112
+ }
107
113
  if (e.target instanceof HTMLElement) {
108
114
  container = e.target.closest<HTMLElement>('.Page-content, .Popup')
109
115
  }
110
- if (container && ogTransProp) {
111
- container.style.transitionProperty = ogTransProp
112
- }
113
116
  if (container?.classList.contains('Popup')) {
114
117
  container.style.cursor = 'initial'
115
118
  container.style.userSelect = 'unset'
@@ -128,7 +131,9 @@ const onPointerUp = (e: PointerEvent) => {
128
131
  }
129
132
 
130
133
  if (panelData && panelData.width) {
131
- savePreferredWidth(panelData)
134
+ // A cancelled drag (scroll gesture stealing the pointer) shouldn't persist its
135
+ // interrupted width.
136
+ if (save) savePreferredWidth(panelData)
132
137
  panelData = null
133
138
  }
134
139
  }
@@ -156,7 +161,11 @@ const onPointerMove = (e: PointerEvent) => {
156
161
 
157
162
  const initResizablePanel = () => {
158
163
  onFind('.ContentEdit-main', (cl) => {
159
- cl.append(
164
+ // Appended to the grid, not the scrolling form: see ContentEdit.css.
165
+ const grid = cl.closest<HTMLElement>('.Page-content, .Popup-content')
166
+ if (!grid || grid.querySelector(':scope > .ContentEdit-resizeWrapper'))
167
+ return
168
+ grid.append(
160
169
  create(
161
170
  'div',
162
171
  { className: 'ContentEdit-resizeWrapper' },
@@ -167,6 +176,11 @@ const initResizablePanel = () => {
167
176
 
168
177
  document.body.addEventListener('pointerdown', onPointerDown, false)
169
178
  document.body.addEventListener('pointerup', onPointerUp, false)
179
+ document.body.addEventListener(
180
+ 'pointercancel',
181
+ (e) => onPointerUp(e, false),
182
+ false,
183
+ )
170
184
  document.body.addEventListener('pointermove', onPointerMove, false)
171
185
 
172
186
  // Check if there's a preferred width for the content form
@@ -515,6 +515,14 @@
515
515
  @apply pointer-events-auto;
516
516
  }
517
517
 
518
+ .CIG-note :where(a, button, [role='button'], btu-copy-to-clipboard) {
519
+ @apply pointer-events-auto cursor-pointer;
520
+ }
521
+
522
+ .CIG-note a {
523
+ @apply text-primary-600;
524
+ }
525
+
518
526
  .MultiSortable:hover {
519
527
  @apply cursor-[unset];
520
528
  }
@@ -1,5 +1,5 @@
1
1
  .Conversation {
2
- --post-form-h: 198px; /* this magic number is the approx height of the post form to reduce the jittering of the height while the RTE renders. */
2
+ --post-form-h: 136px; /* this magic number is the approx height of the post form to reduce the jittering of the height while the RTE renders. */
3
3
  @apply !col-[fullbleed-start_/_fullbleed-end] grid min-h-0 grid-rows-[minmax(0px,1fr)_minmax(var(--post-form-h),auto)];
4
4
  }
5
5
 
@@ -94,7 +94,7 @@
94
94
  }
95
95
 
96
96
  .Conversation-workflowStateIcon {
97
- @apply flex before:btu-icon before:btu-icon-arrow-right before:font-semibold before:text-gray-500 before:btu-icon-xs;
97
+ @apply flex before:btu-icon before:btu-icon-arrow-right rtl:before:btu-icon-arrow-left before:font-semibold before:text-gray-500 before:btu-icon-xs;
98
98
  }
99
99
 
100
100
  .Conversation-text {
@@ -128,11 +128,19 @@
128
128
 
129
129
  /* TODO: revisit newPost when ProseMirror is styled */
130
130
  .Conversation-newPost {
131
- @apply flex flex-col items-end gap-4 border-t border-t-gray-200 p-4;
131
+ @apply flex flex-row items-end gap-3 border-t border-t-gray-200 p-4;
132
+
133
+ .CIG-small {
134
+ @apply mt-0;
135
+ }
132
136
  }
133
137
 
134
138
  .Conversation-newPost .ProseMirrorContainer {
135
139
  @apply bg-white;
140
+
141
+ .ProseMirror {
142
+ @apply py-4;
143
+ }
136
144
  }
137
145
 
138
146
  .Conversation-newPostButton {
@@ -181,6 +189,10 @@
181
189
  }
182
190
  }
183
191
 
192
+ .Conversation-newPost {
193
+ @apply flex-col;
194
+ }
195
+
184
196
  .Conversation-posts {
185
197
  @apply max-h-[calc(100vh-3.3rem)] overflow-y-auto;
186
198
  }
@@ -212,10 +224,6 @@
212
224
  @apply blokk max-h-[300px] overflow-y-auto;
213
225
  }
214
226
  }
215
-
216
- .Conversation {
217
- @apply flex min-h-max flex-col;
218
- }
219
227
  }
220
228
 
221
229
  .Popup[name='conversation-reply'] {
@@ -225,6 +233,10 @@
225
233
  .Conversation-posts {
226
234
  @apply overflow-y-visible;
227
235
  }
236
+
237
+ .Conversation-newPost {
238
+ @apply flex-col;
239
+ }
228
240
  }
229
241
  }
230
242
 
@@ -13,11 +13,7 @@ export default class EmbeddedInputGroup extends EventEmitterMixin(LitElement) {
13
13
  @queryAsync('.EIG-item')
14
14
  _eigItem?: Promise<HTMLElement>
15
15
 
16
- @queryAsync('.EIG-title')
17
- _title?: Promise<HTMLElement>
18
-
19
- @queryAsync('.removeButton')
20
- _removeButton?: Promise<HTMLElement>
16
+ private _watchingItems = false
21
17
 
22
18
  connectedCallback(): void {
23
19
  super.connectedCallback()
@@ -25,29 +21,6 @@ export default class EmbeddedInputGroup extends EventEmitterMixin(LitElement) {
25
21
  this.initializeEigItem()
26
22
  }
27
23
 
28
- disconnectedCallback(): void {
29
- super.disconnectedCallback()
30
-
31
- this._removeButton?.then((removeButton) => {
32
- removeButton?.removeEventListener('click', (evt) => {
33
- this._removeItem(evt)
34
- })
35
- })
36
-
37
- this._title?.then((title) => {
38
- title?.removeEventListener('click', () => {
39
- this._eigToggle()
40
- })
41
-
42
- title?.removeEventListener('keydown', ({ key }) => {
43
- if (key === 'Enter' || key === 'Space' || key === ' ') {
44
- event?.preventDefault()
45
- this._eigToggle()
46
- }
47
- })
48
- })
49
- }
50
-
51
24
  private _eigToggle = () => {
52
25
  this._eigItem?.then((eigItem) => {
53
26
  if (eigItem) {
@@ -101,6 +74,9 @@ export default class EmbeddedInputGroup extends EventEmitterMixin(LitElement) {
101
74
  if (eigLiveRegion) eigLiveRegion.textContent = tooltips?.restore
102
75
  }
103
76
  }
77
+
78
+ // Fire a change event so the content-state pipeline recomputes and the live preview reflects the removed/restored item.
79
+ eigItem.dispatchEvent(new Event('change', { bubbles: true }))
104
80
  }
105
81
  })
106
82
  }
@@ -114,43 +90,36 @@ export default class EmbeddedInputGroup extends EventEmitterMixin(LitElement) {
114
90
  }
115
91
 
116
92
  initializeEigItem() {
93
+ // Register the watcher once; onFind then binds each .EIG-item's controls exactly once — on initial load, on Add, and when the item is swapped.
94
+ if (!this._watchingItems) {
95
+ this._watchingItems = true
96
+ onFind(this, '.EIG-item', (eigItem: HTMLElement) => {
97
+ const title = eigItem.querySelector<HTMLElement>('.EIG-title')
98
+ const removeButton = eigItem.querySelector<HTMLElement>('.removeButton')
99
+ this.titleAddEventListeners(title)
100
+ this.removeButtonAddEventListeners(removeButton)
101
+ })
102
+ }
103
+
104
+ // Restore the previously-collapsed state.
117
105
  this._eigItem?.then((eigItem) => {
118
106
  if (eigItem) {
119
107
  const associatedDataField = eigItem.closest<HTMLElement>('[data-field]')
120
- const itemClassList = eigItem.classList
121
- let key = null
122
108
 
123
- // Check if item is collapsed previously
124
109
  if (associatedDataField) {
125
- key = getComponentKey(associatedDataField, 'data-field')
110
+ const key = getComponentKey(associatedDataField, 'data-field')
126
111
  if (key && ls.getItem(key)) {
127
- itemClassList.add('is-collapsed')
112
+ eigItem.classList.add('is-collapsed')
128
113
  eigItem.querySelector('.CIG-large')?.setAttribute('hidden', '')
129
114
  }
130
115
  }
131
- } else {
132
- // No EIG item has been added yet (i.e., Add Module) so monitor for it.
133
- onFind(this, '.EIG-item', (eigItem: HTMLElement) => {
134
- const title = eigItem.querySelector<HTMLElement>('.EIG-title')
135
- const removeButton =
136
- eigItem.querySelector<HTMLElement>('.removeButton')
137
- this.titleAddEventListeners(title)
138
- this.removeButtonAddEventListeners(removeButton)
139
- })
140
116
  }
141
117
  })
142
-
143
- this._title?.then((title) => {
144
- this.titleAddEventListeners(title)
145
- })
146
-
147
- this._removeButton?.then((removeButton) => {
148
- this.removeButtonAddEventListeners(removeButton)
149
- })
150
118
  }
151
119
 
152
120
  titleAddEventListeners(title: HTMLElement | null) {
153
121
  if (!title) return
122
+
154
123
  title.addEventListener('click', () => {
155
124
  this._eigToggle()
156
125
  })
@@ -166,6 +135,7 @@ export default class EmbeddedInputGroup extends EventEmitterMixin(LitElement) {
166
135
 
167
136
  removeButtonAddEventListeners(removeButton: HTMLElement | null) {
168
137
  if (!removeButton) return
138
+
169
139
  const eigLiveRegion = create('span', {
170
140
  class: 'screen-reader-only',
171
141
  'aria-live': 'polite',
@@ -10,7 +10,7 @@ html::view-transition-group(prosemirror-enhancement) {
10
10
  }
11
11
 
12
12
  &.block.readOnly {
13
- @apply grid grid-cols-[1fr_auto] gap-2 rounded-lg border p-2 [grid-template-areas:'label_menu''preview_preview'] hover:border-gray-300 hover:bg-gray-50;
13
+ @apply grid h-auto grid-cols-[1fr_auto] gap-2 rounded-lg border p-2 [grid-template-areas:'label_menu''preview_preview'] hover:border-gray-300 hover:bg-gray-50;
14
14
  }
15
15
 
16
16
  &:where(.readOnly.ProseMirror-selectednode) {
@@ -28,7 +28,8 @@ html::view-transition-group(prosemirror-enhancement) {
28
28
  @apply flex gap-2 py-1 text-sm font-medium text-gray-900;
29
29
  }
30
30
 
31
- .Enhancement-preview {
31
+ .Enhancement-preview,
32
+ .Enhancement-initialBody {
32
33
  @apply [grid-area:preview];
33
34
  }
34
35
 
@@ -920,6 +920,17 @@ onFind('.ProfileDropdown-items', (items: HTMLElement) => {
920
920
  items.closest('.Widget')?.classList.add('has-profileDropdown')
921
921
  })
922
922
 
923
+ // Lets Widget.css row out buttons with no ActionBar collecting them, without a :has() on the form.
924
+ onFind(
925
+ ['.Widget > form > .Button', '.Widget > form > .fixedScrollable > .Button'],
926
+ (button: HTMLElement) => {
927
+ const form = button.parentElement
928
+ if (form && !form.querySelector(':scope > .ActionBar')) {
929
+ form.classList.add('has-looseButtons')
930
+ }
931
+ },
932
+ )
933
+
923
934
  onFind('.Widget-controls', (controls: HTMLElement) => {
924
935
  const widget = controls.closest<HTMLElement>('.Widget')
925
936
  if (!widget) return
@@ -87,10 +87,13 @@ declare global {
87
87
  imageHeight: string
88
88
  imageHeightOpen: string
89
89
  imageHeightClose: string
90
+ chartNoData: string
90
91
  fieldSelect: string
91
92
  fieldHide: string
92
93
  filtersHide: string
93
94
  filtersShow: string
95
+ formFilterNoResults: string
96
+ formFilterPlaceholder: string
94
97
  focusTrapHint: string
95
98
  fullScreen: string
96
99
  fullScreenSearch: string
@@ -18,11 +18,11 @@
18
18
  --guide-title-h: calc(var(--guide-edit-icon-size) + theme(padding.6));
19
19
  --guide-controls-w: calc(2 * var(--guide-edit-icon-size) + theme(padding.8));
20
20
 
21
- @apply btu-heading-4 relative h-[var(--guide-title-h)] truncate border-b border-b-gray-200 bg-gray-50 py-3.5 pl-4 pr-[var(--guide-controls-w)] text-gray-900;
21
+ @apply btu-heading-4 relative h-[var(--guide-title-h)] truncate border-b border-b-gray-200 bg-gray-50 py-3.5 ps-4 pe-[var(--guide-controls-w)] text-gray-900;
22
22
  }
23
23
 
24
24
  .Guide-controls {
25
- @apply absolute right-4 top-3 flex items-center gap-2;
25
+ @apply absolute end-4 top-3 flex items-center gap-2;
26
26
  }
27
27
 
28
28
  .Guide-edit {
@@ -104,15 +104,15 @@
104
104
  }
105
105
 
106
106
  .Guide-embedded {
107
- @apply relative ml-2.5 pl-2.5 shadow-[-1px_0_0_theme(colors.gray.300)];
107
+ @apply relative ms-2.5 ps-2.5 shadow-[-1px_0_0_theme(colors.gray.300)] rtl:shadow-[1px_0_0_theme(colors.gray.300)];
108
108
 
109
109
  > .Guide-edit {
110
- @apply absolute right-0 top-[calc(0px-var(--guide-edit-icon-size)-0.5rem-1px)];
110
+ @apply absolute end-0 top-[calc(0px-var(--guide-edit-icon-size)-0.5rem-1px)];
111
111
  }
112
112
 
113
113
  .Guide-field,
114
114
  .Guide-description {
115
- @apply pl-1 pr-0;
115
+ @apply ps-1 pe-0;
116
116
  }
117
117
 
118
118
  .Guide-tabCluster {
@@ -1,5 +1,5 @@
1
1
  .objectId-edit-heading {
2
- @apply btu-button btu-button-fill-none btu-button-primary blokk truncate rounded-none border-b border-solid border-b-primary-200 bg-primary-25 p-4 text-sm font-normal [grid-area:back] focus-visible:ring-primary-100 before:btu-icon before:btu-icon-arrow-left before:me-2 focus:rounded-none focus-visible:ring-4 focus-visible:ring-inset;
2
+ @apply btu-button btu-button-fill-none btu-button-primary blokk truncate rounded-none border-b border-solid border-b-primary-200 bg-primary-25 p-4 text-sm font-normal [grid-area:back] focus-visible:ring-primary-100 before:btu-icon before:btu-icon-arrow-left rtl:before:btu-icon-arrow-right before:me-2 focus:rounded-none focus-visible:ring-4 focus-visible:ring-inset;
3
3
  }
4
4
 
5
5
  .Grid:has(.LiveBlogGrid),
@@ -15,7 +15,7 @@
15
15
  }
16
16
 
17
17
  .LiveBlogPostList-open {
18
- @apply btu-button btu-button-text-hidden btu-button-fill-none btu-button-gray absolute top-[calc(var(--page-broadcast-h)+var(--page-broadcastAlert-h)_+_52px_+_theme(spacing.2))] z-[1] before:btu-icon before:btu-icon-chevron-left md:hidden;
18
+ @apply btu-button btu-button-text-hidden btu-button-fill-none btu-button-gray absolute top-[calc(var(--page-broadcast-h)+var(--page-broadcastAlert-h)_+_52px_+_theme(spacing.2))] z-[1] before:btu-icon before:btu-icon-chevron-left rtl:before:btu-icon-chevron-right md:hidden;
19
19
  }
20
20
 
21
21
  .LiveBlogGrid:not(.is-visible) .LiveBlogPostList-open {
@@ -20,7 +20,7 @@
20
20
  > ul {
21
21
  --ProseMirror-toolbar-h: calc(theme(spacing.4) + theme(lineHeight.6));
22
22
 
23
- @apply relative inline-flex h-[var(--ProseMirror-toolbar-h)] w-full flex-wrap items-center gap-y-3 overflow-clip py-2 pr-[calc(var(--ProseMirrorToolbar-rightControls)+var(--ProseMirror-wordCount)+var(--iconSize-xs))] ps-3;
23
+ @apply relative inline-flex h-[var(--ProseMirror-toolbar-h)] w-full flex-wrap items-center gap-y-3 overflow-clip py-2 pe-[calc(var(--ProseMirrorToolbar-rightControls)+var(--ProseMirror-wordCount)+var(--iconSize-xs))] ps-3;
24
24
 
25
25
  .rte2-toolbar-submenu-2,
26
26
  .rte2-toolbar-separator,
@@ -119,7 +119,8 @@
119
119
  }
120
120
 
121
121
  .CIG-wordCount {
122
- @apply absolute end-3 top-1.5 z-10 opacity-100;
122
+ /* pointer-events-none keeps the status box from swallowing clicks meant for the overflow button beneath it */
123
+ @apply pointer-events-none absolute end-3 top-1.5 z-10 opacity-100;
123
124
 
124
125
  /* Override inline styles from JS */
125
126
  @apply [--ProseMirror-wordCountSpacingWithOneIcon:52px] [--ProseMirror-wordCountSpacingWithThreeIcons:120px] [--ProseMirror-wordCountSpacingWithTwoIcons:85px];
@@ -34,16 +34,11 @@
34
34
  }
35
35
 
36
36
  a {
37
- @apply order-3 ms-auto font-semibold text-[--link-color] decoration-solid decoration-auto max-md:ms-0;
37
+ @apply order-3 font-semibold text-[--link-color] decoration-solid decoration-auto;
38
38
  }
39
39
 
40
- /* The Message-icon is always JS-appended last (see Message.js), so a leading anchor means the
41
- message is just an icon + a bare link (e.g. Book Outline's link, ToolUser's password reset
42
- link) - it should hug the icon now that the bar is full width, not drift to the far end.
43
- Messages with real content before the link (e.g. a heading + a "view results" link) are
44
- unaffected and keep the link pinned to the end. */
45
- > a:first-child {
46
- @apply ms-0;
40
+ .ContentEdit-revisionActions, .WorkInProgressRestoredMessage-actions a, .Message-returnToDashboard {
41
+ @apply ms-auto max-md:ms-0;
47
42
  }
48
43
 
49
44
  .is-emphasis {
@@ -174,7 +169,7 @@
174
169
  }
175
170
 
176
171
  a {
177
- @apply order-[0] ms-0;
172
+ @apply order-[0];
178
173
  }
179
174
 
180
175
  .ComboInput {
@@ -67,7 +67,7 @@
67
67
  }
68
68
 
69
69
  .Page-broadcastAlert {
70
- @apply flex max-h-[--page-broadcastAlert-h] border-b border-b-error-200 bg-error-25 p-4 text-sm leading-4 text-error-600 before:btu-icon before:btu-icon-triangle-alert before:me-4 before:text-[--link-color] more-contrast:text-error-700 more-contrast:[--link-color:theme(colors.error.800)] md:col-span-full;
70
+ @apply flex items-center h-[--page-broadcastAlert-h] border-b border-b-error-200 bg-error-25 px-4 text-sm leading-4 text-error-600 before:btu-icon before:btu-icon-triangle-alert before:me-4 before:text-[--link-color] more-contrast:text-error-700 more-contrast:[--link-color:theme(colors.error.800)] md:col-span-full;
71
71
  }
72
72
 
73
73
  .Page-broadcastAlert a {
@@ -75,7 +75,7 @@
75
75
  }
76
76
 
77
77
  .Page-broadcastAlert-messages {
78
- @apply me-auto overflow-y-hidden overflow-x-scroll;
78
+ @apply me-auto h-full py-4 overflow-y-hidden overflow-x-auto [scrollbar-width:thin];
79
79
  }
80
80
 
81
81
  .Page-broadcastAlert .pagination {
@@ -101,7 +101,7 @@
101
101
  }
102
102
 
103
103
  .Page-broadcast {
104
- @apply max-h-[--page-broadcast-h] overflow-y-hidden overflow-x-scroll border-b border-b-warning-200 bg-warning-25 p-4 text-sm leading-4 text-warning-700 [--link-color:theme(colors.warning.800)] before:btu-icon before:btu-icon-triangle-alert before:me-4 before:text-[--link-color] more-contrast:text-warning-800 md:col-span-full;
104
+ @apply max-h-[--page-broadcast-h] overflow-y-hidden overflow-x-auto [scrollbar-width:thin] border-b border-b-warning-200 bg-warning-25 p-4 text-sm leading-4 text-warning-700 [--link-color:theme(colors.warning.800)] before:btu-icon before:btu-icon-triangle-alert before:me-4 before:text-[--link-color] more-contrast:text-warning-800 md:col-span-full;
105
105
 
106
106
  /*
107
107
  Submitting a form inside a broadcast (Ex: Stop scheduling)
@@ -1,7 +1,7 @@
1
1
  .ProseMirror {
2
2
  --ProseMirror-numLines: 10;
3
3
 
4
- @apply min-h-[calc(var(--ProseMirror-numLines)*theme(lineHeight.4))] whitespace-pre-wrap rounded-b-lg px-4 py-[var(--lineHeight-m)] focus:[box-shadow:none];
4
+ @apply min-h-[calc(var(--ProseMirror-numLines)*theme(lineHeight.4))] whitespace-pre-wrap rounded-b-lg px-4 py-[var(--lineHeight-m)] leading-[normal] focus:[box-shadow:none];
5
5
  }
6
6
 
7
7
  :where(.ProseMirror-fullscreen-container) {