@brightspot/ui 5.3.2 → 5.4.1

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 (106) hide show
  1. package/README.md +113 -150
  2. package/dist/components/banner/Banner.css +32 -0
  3. package/dist/components/banner/Banner.d.ts +56 -0
  4. package/dist/components/banner/Banner.d.ts.map +1 -0
  5. package/dist/components/banner/Banner.js +94 -0
  6. package/dist/components/banner/Banner.js.map +1 -0
  7. package/dist/components/banner/Message.css +4 -0
  8. package/dist/components/banner/Message.d.ts +103 -0
  9. package/dist/components/banner/Message.d.ts.map +1 -0
  10. package/dist/components/banner/Message.js +235 -0
  11. package/dist/components/banner/Message.js.map +1 -0
  12. package/dist/custom-elements.json +319 -0
  13. package/dist/storybook/assets/{ActionBar.stories-1Iqfy4PV.js → ActionBar.stories-BJcrfF0X.js} +1 -1
  14. package/dist/storybook/assets/{ActionItem.stories-DjKyE7m_.js → ActionItem.stories-xLR-VN2Q.js} +1 -1
  15. package/dist/storybook/assets/{Avatar.stories-Dy36fKQN.js → Avatar.stories-Cj5Q2yEp.js} +1 -1
  16. package/dist/storybook/assets/{AvatarGroup.stories-Bh8TY9-P.js → AvatarGroup.stories-DLWAQHFa.js} +1 -1
  17. package/dist/storybook/assets/{Badge.stories-Bn0aBHka.js → Badge.stories-DGSKAf9D.js} +1 -1
  18. package/dist/storybook/assets/Banner.stories-BZ3LLa4I.js +203 -0
  19. package/dist/storybook/assets/{Button-D8Sr8A-v.js → Button-ffu9dnxC.js} +1 -1
  20. package/dist/storybook/assets/{Button.stories-CtRBI4gv.js → Button.stories-DB-uDcVu.js} +1 -1
  21. package/dist/storybook/assets/{ButtonGroup.stories-CVjQWgMD.js → ButtonGroup.stories-eGya8Uts.js} +1 -1
  22. package/dist/storybook/assets/{Card.stories-DXTqqbXb.js → Card.stories-B_hhKmQB.js} +1 -1
  23. package/dist/storybook/assets/{Celebrate.stories-DwQeQ1VN.js → Celebrate.stories-DqKwiwly.js} +1 -1
  24. package/dist/storybook/assets/{Checkbox.stories-D4AyVy-V.js → Checkbox.stories-Bly8OVzf.js} +1 -1
  25. package/dist/storybook/assets/{CircularProgress.stories-D6dHpD70.js → CircularProgress.stories-BZUNNkMK.js} +1 -1
  26. package/dist/storybook/assets/{ClipboardMixin.stories-CvYj7bwY.js → ClipboardMixin.stories-D2XMhwIg.js} +1 -1
  27. package/dist/storybook/assets/{Color-6BZIO3FS-o6fp9dCO.js → Color-6BZIO3FS-BPcC43iH.js} +1 -1
  28. package/dist/storybook/assets/{Colors.stories-Bg-Xuo05.js → Colors.stories-DveV04we.js} +1 -1
  29. package/dist/storybook/assets/{CombinedEffects.stories-C4SNTP9M.js → CombinedEffects.stories-Dl_MhHhl.js} +1 -1
  30. package/dist/storybook/assets/{ComponentStatesMixin-Dj1V-e8c.js → ComponentStatesMixin-CmZnizKN.js} +1 -1
  31. package/dist/storybook/assets/{ComponentStatesMixin.stories-CUoagWLT.js → ComponentStatesMixin.stories-BrAFoGDu.js} +1 -1
  32. package/dist/storybook/assets/{CopyToClipboard.stories-ynkFni9d.js → CopyToClipboard.stories-CiKbtpBJ.js} +1 -1
  33. package/dist/storybook/assets/{Debounce.stories-xAZ6AOUR.js → Debounce.stories-BQ7W_yTX.js} +1 -1
  34. package/dist/storybook/assets/{DocsRenderer-LL677BLK-DeoiTMLA.js → DocsRenderer-LL677BLK-DiDzi0rZ.js} +3 -3
  35. package/dist/storybook/assets/{Dropdown.stories-BQzwsyHE.js → Dropdown.stories-LYd0-ypG.js} +1 -1
  36. package/dist/storybook/assets/{EmptyState.stories-CrckJlBX.js → EmptyState.stories-DjKyE0h3.js} +1 -1
  37. package/dist/storybook/assets/{EscaAvatar.stories-BikckAep.js → EscaAvatar.stories-D3v91UKv.js} +1 -1
  38. package/dist/storybook/assets/{Events.stories-DC0XMBhF.js → Events.stories-CTe5eZa6.js} +1 -1
  39. package/dist/storybook/assets/{Heading.stories-7YtY0gNK.js → Heading.stories-DKt-wgRB.js} +1 -1
  40. package/dist/storybook/assets/{HueRipple.stories-hRstwRnF.js → HueRipple.stories-B3SVSdL8.js} +1 -1
  41. package/dist/storybook/assets/{Icon.stories-4-2N4UlX.js → Icon.stories-B5tDsd--.js} +1 -1
  42. package/dist/storybook/assets/{IconButton.stories-ClpNoAT9.js → IconButton.stories-DOV4zFAP.js} +1 -1
  43. package/dist/storybook/assets/{LinearProgress.stories-BlH24bsJ.js → LinearProgress.stories-ai3UD-xw.js} +1 -1
  44. package/dist/storybook/assets/Message.stories-CzqIe49h.js +432 -0
  45. package/dist/storybook/assets/{OnFindMixin.stories-CKoPIaks.js → OnFindMixin.stories-CUaE6pX1.js} +1 -1
  46. package/dist/storybook/assets/{Pagination.stories-CER9zwKW.js → Pagination.stories-CXCbChNW.js} +1 -1
  47. package/dist/storybook/assets/{Popover.stories-CO7t4Pl8.js → Popover.stories-DyptvVL3.js} +1 -1
  48. package/dist/storybook/assets/{ReadyMixin-C_H-s0cp.js → ReadyMixin-BUpBkgED.js} +1 -1
  49. package/dist/storybook/assets/{RovingTabindexMixin.stories-0Sny7BQc.js → RovingTabindexMixin.stories-DzEH38Tn.js} +1 -1
  50. package/dist/storybook/assets/{Rtc.stories-Ci7CnFM6.js → Rtc.stories-DxQWkudF.js} +1 -1
  51. package/dist/storybook/assets/{ScrollShadow.stories-CSbM9xdE.js → ScrollShadow.stories-DbMdNLKA.js} +1 -1
  52. package/dist/storybook/assets/{Switch.stories-D-SGY0dL.js → Switch.stories-CvSwuR0Z.js} +1 -1
  53. package/dist/storybook/assets/{Tab.stories-DXeloL5R.js → Tab.stories-CI6m8NXD.js} +1 -1
  54. package/dist/storybook/assets/{Tabs.stories-KGjrQHnj.js → Tabs.stories-BMat3ubI.js} +1 -1
  55. package/dist/storybook/assets/{Throttle.stories-SjszmCVX.js → Throttle.stories-PEUZoXfI.js} +1 -1
  56. package/dist/storybook/assets/{Tooltip.stories-DZty4zmq.js → Tooltip.stories-kDJ5PbGO.js} +1 -1
  57. package/dist/storybook/assets/{Upload.stories-CoM7bgt1.js → Upload.stories-Bb5KBlh7.js} +1 -1
  58. package/dist/storybook/assets/{UploadItem.stories-CRrp-ZTV.js → UploadItem.stories-VZVWc52f.js} +1 -1
  59. package/dist/storybook/assets/{Welcome.stories-lQ_IWtd1.js → Welcome.stories-BgzaFbT1.js} +1 -1
  60. package/dist/storybook/assets/{Widget.stories-rY-A2yAZ.js → Widget.stories-Bbczy09Q.js} +1 -1
  61. package/dist/storybook/assets/{WithTooltip-65CFNBJE-asVkTqyz.js → WithTooltip-65CFNBJE-BoKgPPcr.js} +1 -1
  62. package/dist/storybook/assets/{blocks-D-cAwpi5.js → blocks-j0yzxuDk.js} +5 -5
  63. package/dist/storybook/assets/{formatter-EIJCOSYU-CaSK-GPg.js → formatter-EIJCOSYU-B5-4vV2C.js} +1 -1
  64. package/dist/storybook/assets/if-defined-DBQP12ek.js +1 -0
  65. package/dist/storybook/assets/iframe-Ce3XRnL4.css +1 -0
  66. package/dist/storybook/assets/{iframe-DpPeZoRd.js → iframe-DUmd7GbF.js} +86 -86
  67. package/dist/storybook/assets/{index-Eb_LP-gw.js → index-ACSvfrQi.js} +1 -1
  68. package/dist/storybook/assets/{onFind-D8gPkhwL.js → onFind-t_5Bmfio.js} +1 -1
  69. package/dist/storybook/assets/{onFind.stories-C_2tTxBq.js → onFind.stories-CQWcRPFY.js} +1 -1
  70. package/dist/storybook/assets/{onRemove.stories-D-gjr3kA.js → onRemove.stories-B9_DDB2B.js} +1 -1
  71. package/dist/storybook/assets/{onVisible.stories-DGfzNLoX.js → onVisible.stories-G0qjGum_.js} +1 -1
  72. package/dist/storybook/assets/{style-map-WEdc6AkA.js → style-map-D_jXmlQ4.js} +1 -1
  73. package/dist/storybook/assets/{syntaxhighlighter-ED5Y7EFY-CCM2wmJ3.js → syntaxhighlighter-ED5Y7EFY-7_fYNYDB.js} +1 -1
  74. package/dist/storybook/iframe.html +2 -2
  75. package/dist/storybook/index.json +1 -1
  76. package/dist/storybook/project.json +1 -1
  77. package/dist/tailwind-plugin-message.d.ts +2 -0
  78. package/dist/tailwind-plugin-message.d.ts.map +1 -0
  79. package/dist/tailwind-plugin-message.js +168 -0
  80. package/dist/tailwind-plugin-message.js.map +1 -0
  81. package/dist/tailwind-plugin-message.ts +226 -0
  82. package/dist/tailwind.config.d.ts.map +1 -1
  83. package/dist/tailwind.config.js +2 -0
  84. package/dist/tailwind.config.js.map +1 -1
  85. package/dist/tailwind.config.ts +2 -0
  86. package/dist/util/EventEmitterMixin.d.ts +3 -0
  87. package/dist/util/EventEmitterMixin.d.ts.map +1 -1
  88. package/dist/util/EventEmitterMixin.js.map +1 -1
  89. package/docs/components/Banner.md +49 -0
  90. package/docs/components/Message.md +75 -0
  91. package/docs/components/README.md +2 -0
  92. package/package.json +1 -1
  93. package/src/legacy/tool-ui/src/ContentInputGroup.css +4 -0
  94. package/src/legacy/tool-ui/src/Hierarchy.css +4 -11
  95. package/src/legacy/tool-ui/src/MenuView.css +9 -0
  96. package/src/legacy/tool-ui/src/Page.css +1 -1
  97. package/src/legacy/tool-ui/src/PrePublish.ts +0 -24
  98. package/src/legacy/tool-ui/src/ThemeBundleEditor.css +4 -0
  99. package/src/legacy/tool-ui/src/main/webapp/dist/{v4.da15ce3ce45e85b4880a.js → v4.ba601ff96a3370471a41.js} +3 -3
  100. package/src/legacy/tool-ui/src/main/webapp/dist/{v5.8491d982a282935a3058.js → v5.4cdf07db0213a5d2f97e.js} +3 -3
  101. package/src/legacy/tool-ui/src/main/webapp/dist/v5.553c18f29cb4a71c3577.css +5 -0
  102. package/dist/storybook/assets/if-defined-aps73Iby.js +0 -1
  103. package/dist/storybook/assets/iframe-1F7Ef_8q.css +0 -1
  104. package/src/legacy/tool-ui/src/main/webapp/dist/v5.9b40c96064a0f8a10b53.css +0 -5
  105. /package/src/legacy/tool-ui/src/main/webapp/dist/{v4.da15ce3ce45e85b4880a.js.LICENSE.txt → v4.ba601ff96a3370471a41.js.LICENSE.txt} +0 -0
  106. /package/src/legacy/tool-ui/src/main/webapp/dist/{v5.8491d982a282935a3058.js.LICENSE.txt → v5.4cdf07db0213a5d2f97e.js.LICENSE.txt} +0 -0
package/README.md CHANGED
@@ -1,212 +1,175 @@
1
1
  # Brightspot UI
2
2
 
3
- <a id="readme-top"></a>
3
+ `@brightspot/ui` is a library of ready-made interface pieces — buttons, widgets, icons — plus a full set of colors and styles (light, dark, and high-contrast) for the screens inside the Brightspot CMS.
4
4
 
5
- <div>
6
- <h2 align="center">platform-ui</h2>
7
- <p align="center">
8
- A UI library optimized for rapid, standards-based Brightspot CMS component creation.
9
- <br/>
10
- </p>
11
- </div>
5
+ The CMS's own interface is built from this UI library, and we're gradually moving the rest of it over. It is also published so individual Brightspot projects can use it.
12
6
 
13
- <!-- TOC -->
14
- <details>
15
- <summary>Table of Contents</summary>
16
- <ol>
17
- <li>
18
- <a href="#about">About</a>
19
- </li>
20
- <li>
21
- <a href="#getting-started">Getting Started</a>
22
- </li>
23
- <li><a href="#prerequisites">Prerequisites</a></li>
24
- <li><a href="#installation">Installation</a></li>
25
- <li>
26
- <a href="#using-plugins">Using Plugins</a>
27
- </li>
28
- <li>
29
- <a href="#examples">Examples</a>
30
- </li>
31
- <li>
32
- <a href="#development">Development</a>
33
- </li>
34
- </ol>
35
- </details>
7
+ ## What do you want to do?
36
8
 
37
- ## About
9
+ - [Fix or change the CMS UI](#fix-or-change-the-cms-ui)
10
+ - [Use the UI library in a project](#use-the-ui-library-in-a-project)
11
+ - [Improve the UI library itself](#improve-the-ui-library-itself)
38
12
 
39
- Brightspot UI is a package of custom web components and styles to provide a basis for building new CMS components. It uses [TailwindCSS](https://v3.tailwindcss.com/) for styling and [LitElement](https://lit.dev/) for web components.
13
+ ---
40
14
 
41
- If you're developing a Brightspot CMS plugin or creating custom CMS UI for your project, then you've come to the right place!
15
+ ## Fix or change the CMS UI
42
16
 
43
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
17
+ The CMS interface lives in `src/legacy/tool-ui/`. Edit files there and preview them in a running CMS one of two ways.
44
18
 
45
- ## Getting Started
19
+ **You'll need:** Node 22 (`nvm use 22`), Yarn 1, a local `brightspot` checkout, and `yarn install` run once here.
46
20
 
47
- _Note:_ To get the best developer experience we recommend using VSCode editor. The marketplace of extensions that are available provide code formatting and intellisense for all the TailwindCSS classnames and our plugins, etc. The VSCode setup is documented [here](https://github.com/perfectsense/brightspot/tree/release/5.0/cms/tool-ui#visual-studio-code).
21
+ > **Editor tip:** In VSCode, the recommended extensions autocomplete the `btu-*` classes as you type. See the [VSCode setup notes](src/legacy/tool-ui/README.md#visual-studio-code).
48
22
 
49
- ### Prerequisites
23
+ ### Fast way — live preview (for everyday edits)
50
24
 
51
- Your codebase needs to be compatible with
25
+ 1. Start the CMS backend (in your `brightspot/` folder):
52
26
 
53
- - TailwindCSS **v3**
54
-
55
- ### Installation
56
-
57
- 1. Install the Brightspot ui node module as a devDependency
58
27
  ```sh
59
- yarn add -D @brightspot/ui
60
- ```
61
- 2. Create a `tailwind.config` file and add Brightspot ui as a preset. More on TWCSS presets [here](https://v3.tailwindcss.com/docs/presets#presets).
62
- ```ts
63
- // (Typescript example) contents of tailwind.config.ts
64
- export default {
65
- ...
66
- presets: [require('@brightspot/ui')],
67
- ...
68
- }
69
- ```
70
- ```js
71
- // (Javascript example) contents of tailwind.config.js
72
- export default {
73
- ...
74
- presets: [require('@brightspot/ui/dist/tailwind.config.js')],
75
- ...
76
- }
28
+ docker compose up -d
77
29
  ```
78
- 3. Build your frontend
79
30
 
80
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
31
+ 2. Start the live preview (here):
81
32
 
82
- ## Using Plugins
83
-
84
- Brightspot UI comes with a variety of TailwindCSS plugins to make styling simpler and declarative. Visit the Storybook to see the available plugins.
33
+ ```sh
34
+ cd src/legacy/tool-ui
35
+ yarn server:local
36
+ ```
85
37
 
86
- To use our plugins, include them in your TailwindCSS config as usual. Plugin files are provided in both Typescript and Javascript variants and are available under the `dist` path in the platform-ui module.
38
+ 3. Open the dev server note the **`:8080`**, not plain `localhost`:
87
39
 
88
- An example of including a plugin:
40
+ ```
41
+ https://localhost:8080/cms/
42
+ ```
89
43
 
90
- ```ts
91
- // your tailwind.config.ts
92
- ...
93
- plugins: [
94
- require('@brightspot/ui/dist/tailwind-plugin-theme.ts'),
95
- ...
96
- ```
44
+ Click through the certificate warning (local cert — normal).
97
45
 
98
- ## Web Components
46
+ Now edit anything in `src/legacy/tool-ui/src/` and the browser updates on its own — no rebuilding.
99
47
 
100
- Brightspot UI includes custom web components built with LitElement. FOUC (Flash of Unstyled Content) prevention is handled automatically when you import the components.
48
+ _Seeing `502` errors? The CMS backend isn't reachable check the docker step._
101
49
 
102
- Import components in your JavaScript/TypeScript:
50
+ ### Full way build the real package (for a final check only)
103
51
 
104
- ```ts
105
- import '@brightspot/ui/dist/components/widget/Widget'
106
- ```
52
+ Slower, but produces the actual file the CMS ships. Needs two temporary edits in `brightspot` — **don't commit them**.
107
53
 
108
- See the Storybook documentation for detailed usage examples and API references.
54
+ 1. Build the package (here):
109
55
 
110
- ## Examples
111
-
112
- We use [Storybook](https://storybook.js.org/) for interactive previewing of our ui components. Launch that in the browser by running:
113
-
114
- ```sh
115
- yarn storybook
116
- ```
56
+ ```sh
57
+ ./gradlew publishToMavenLocal
58
+ ```
117
59
 
118
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
60
+ 2. Point `brightspot` at your build:
61
+ - `site/build.gradle` — add `mavenLocal()` under `repositories`
62
+ - `platform/brightspot-dependencies/build.gradle` — change the cms-tool-ui line to:
119
63
 
120
- ## Development
64
+ ```groovy
65
+ api 'com.brightspot.ui:cms-tool-ui:9999-SNAPSHOT'
66
+ ```
121
67
 
122
- ### Prerequisites
68
+ 3. Rebuild and run (in `brightspot/`):
123
69
 
124
- - Node.js v22+
125
- - Yarn 1 (classic)
70
+ ```sh
71
+ ./gradlew docker
72
+ ```
126
73
 
127
- ### Layout
74
+ 4. Check it at https://localhost/cms/, then undo the two edits when done.
128
75
 
129
- This repo ships two surfaces inside one published `@brightspot/ui` npm package:
76
+ ---
130
77
 
131
- - `src/` the modern design system (web components, Tailwind plugins, presets). Built by `yarn build` into `dist/`.
132
- - `src/legacy/tool-ui/` — the brightspot CMS frontend (JS, CSS, webpack, tests). Has its own `package.json`. Built by `(cd src/legacy/tool-ui && yarn build)` into `src/legacy/tool-ui/src/main/webapp/dist/`.
78
+ ## Use the UI library in a project
133
79
 
134
- The publish flow (`yarn prepack`) builds both.
80
+ > Starting a new frontend package? [`@brightspot/ui-builder`](https://www.npmjs.com/package/@brightspot/ui-builder) scaffolds the build (Vite) and wires up this preset for you. The steps below are for adding the library to a build you already have.
135
81
 
136
- ### Component-only work (no CMS needed)
82
+ **You'll need:** a frontend using TailwindCSS v3.
137
83
 
138
84
  ```sh
139
- yarn storybook
85
+ yarn add -D @brightspot/ui
140
86
  ```
141
87
 
142
- Opens Storybook at http://localhost:6006. Iterate on `src/` components and Tailwind plugins without booting the CMS.
143
-
144
- ### CMS integration work
145
-
146
- The brightspot CMS consumes `@brightspot/ui` from npm. Two workflows for local iteration:
147
-
148
- #### Fast loop: webpack-dev-server (recommended for JS/CSS edits)
88
+ If you don't already have one, create a Tailwind config file at the root of your frontend — `tailwind.config.mjs`:
149
89
 
150
- 1. Start the CMS in docker as usual (from `brightspot/`):
151
-
152
- ```sh
153
- ./gradlew docker
154
- ```
90
+ ```js
91
+ // tailwind.config.mjs
92
+ export default {
93
+ content: ['./src/**/*.{js,ts,html}'], // wherever your markup lives
94
+ }
95
+ ```
155
96
 
156
- 2. Start the dev server (from `platform-ui/src/legacy/tool-ui/`):
97
+ Then add `@brightspot/ui` as a [preset](https://v3.tailwindcss.com/docs/presets). One line pulls in everything — all colors, styles, and components:
157
98
 
158
- ```sh
159
- yarn server:local
160
- ```
99
+ ```js
100
+ // tailwind.config.mjs
101
+ import preset from '@brightspot/ui'
161
102
 
162
- Proxies to `localhost` (or `~/.brightspot/local-url` if set), serves freshly compiled assets at `/cms/dist/`, and injects `x-brightspot-dev: 1` on proxied requests so the CMS returns unhashed asset paths.
103
+ export default {
104
+ presets: [preset],
105
+ content: ['./src/**/*.{js,ts,html}'],
106
+ }
107
+ ```
163
108
 
164
- 3. Open the CMS at the dev-server URL (https://localhost:8080/cms/) instead of the docker URL. Edit files in `src/legacy/tool-ui/src/`; changes hot-reload in the browser.
109
+ Leave `plugins` empty the preset already registers every component's plugin, so listing them again double-registers.
165
110
 
166
- #### Full WAR rebuild (for the modern `src/` surface, or final smoke)
111
+ To use a component, import it (it self-registers its `btu-*` element), then use the tag. Import from the `components/` subpath with the `.js` extension — not the deep `dist/` path:
167
112
 
168
- `yarn server:local` only serves `src/legacy/tool-ui/`. For edits to the modern surface in `src/`, or to validate against the actual WAR build:
113
+ ```ts
114
+ import '@brightspot/ui/components/badge/Badge.js'
115
+ ```
169
116
 
170
- 1. Link the package (once per machine, from `platform-ui/`):
117
+ ```html
118
+ <btu-badge>Draft</btu-badge>
119
+ ```
171
120
 
172
- ```sh
173
- yarn link
174
- ```
121
+ To browse everything available, run the interactive catalog:
175
122
 
176
- 2. Consume the link (in `brightspot/cms/tool-ui/`):
123
+ ```sh
124
+ yarn storybook # opens http://localhost:6006
125
+ ```
177
126
 
178
- ```sh
179
- yarn link @brightspot/ui
180
- ```
127
+ ---
181
128
 
182
- 3. Edit, then rebuild whichever surface changed:
129
+ ## Improve the UI library itself
183
130
 
184
- ```sh
185
- yarn build # for src/ edits
186
- (cd src/legacy/tool-ui && yarn build) # for src/legacy/tool-ui/ edits
187
- ```
131
+ Adding or fixing a component, style, or color.
188
132
 
189
- 4. Rebuild the CMS WAR and roll it into tomcat (from `brightspot/`):
133
+ **You'll need:** Node 22 (`nvm use 22`), Yarn 1.
190
134
 
191
- ```sh
192
- ./gradlew :cms-tool-ui:yarnBuild
193
- ./gradlew docker
194
- ```
135
+ **Where things live:**
195
136
 
196
- 5. Smoke at https://localhost/cms/ (apache, port 443).
137
+ - `src/` the UI library (components, styles, colors); this is what gets published.
138
+ - `src/legacy/tool-ui/` — the CMS interface (see the first section).
139
+ - `tool-ui/` — packaging only.
197
140
 
198
- ### Unlink when done
141
+ Build and preview components in the catalog — no CMS needed:
199
142
 
200
143
  ```sh
201
- # in brightspot/cms/tool-ui:
202
- yarn unlink @brightspot/ui && yarn install --force
203
-
204
- # in platform-ui:
205
- yarn unlink
144
+ yarn storybook
206
145
  ```
207
146
 
208
- ### Releases
147
+ Before committing:
209
148
 
210
- `@brightspot/ui` ships via release-please. For migration-track prereleases (`-cms-ui-migration.N`), bump the version, publish to npm, then update the consumer pin in `brightspot/cms/tool-ui/package.json` and rerun `yarn install` there.
149
+ ```sh
150
+ yarn build # compile everything
151
+ yarn check:conventions # check the rules
152
+ yarn format # tidy formatting
153
+ yarn test:storybook # run tests
154
+ ```
211
155
 
212
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
156
+ **House rules** when you touch one of these areas, read its guide in `.ai/` first:
157
+
158
+ | Area | Guide |
159
+ | ----------------------------------------------- | -------------------------------------- |
160
+ | Naming (sizes, icons, events, CSS vars) | `.ai/LESSONS-NAMING.md` |
161
+ | JSDoc and types | `.ai/LESSONS-JSDOC.md` |
162
+ | Reusing the button primitive | `.ai/LESSONS-BUTTON-REUSE.md` |
163
+ | Keeping plugin styles isolated | `.ai/LESSONS-PLUGIN-ISOLATION.md` |
164
+ | Safelisting classes written at runtime | `.ai/LESSONS-SAFELIST.md` |
165
+ | Preset vs Storybook config; adding a new plugin | `.ai/LESSONS-TAILWIND-CONFIGS.md` |
166
+ | CSS custom properties + Tailwind gotchas | `.ai/LESSONS-CSS-PROPS.md` |
167
+ | Writing Storybook stories | `.ai/LESSONS-STORYBOOK.md` |
168
+ | Anchor positioning / popovers | `.ai/LESSONS-ANCHOR-POSITIONING.md` |
169
+ | Reduced motion | `.ai/LESSONS-REDUCED-MOTION.md` |
170
+ | Roving tabindex | `.ai/LESSONS-ROVING-TABINDEX.md` |
171
+ | Composing components | `.ai/LESSONS-COMPONENT-COMPOSITION.md` |
172
+
173
+ See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for documentation standards.
174
+
175
+ **Releases** are automatic: merge to `main`, and a version is tagged and published for you.
@@ -0,0 +1,32 @@
1
+ /* The base `.btu-banner` rules (display, width, position:relative, z-index) live in
2
+ tailwind-plugin-message.ts so they apply to static/Tailwind markup too. This file
3
+ holds only custom-element upgrade + auto-pagination behavior — the pager overlay
4
+ below relies on the plugin's `position: relative`. */
5
+
6
+ /* FOUC prevention: lay out as a full-width block before the component upgrades
7
+ so the wrapped message doesn't shift when the banner takes over. */
8
+ btu-banner:not(:defined) {
9
+ @apply w-full blokk;
10
+ }
11
+
12
+ /* Auto-pagination. Until the banner has paginated, show only the first message so the
13
+ rest don't flash stacked before `_paginate()` hides them. */
14
+ btu-banner:not([data-paginated]) > btu-message:not(:first-of-type) {
15
+ @apply hidden;
16
+ }
17
+
18
+ /* Once paginated, the pager overlays the right of the active message strip (kept on the
19
+ banner so it never reparents). The message reserves room equal to the pager's width
20
+ plus its inset so content doesn't run under it — keep this in sync with the pager's
21
+ `inset-inline-end` below. */
22
+ btu-banner[data-paginated] > btu-message {
23
+ padding-inline-end: 5rem;
24
+ }
25
+
26
+ btu-banner[data-paginated] > btu-pagination {
27
+ position: absolute;
28
+ inset-block: 0;
29
+ inset-inline-end: 1rem;
30
+ display: flex;
31
+ align-items: center;
32
+ }
@@ -0,0 +1,56 @@
1
+ import { LitElement } from 'lit';
2
+ import '../pagination/Pagination.js';
3
+ import './Banner.css';
4
+ import './Message.js';
5
+ declare const Banner_base: (new (...args: any[]) => import("../../util/EventEmitterMixin.js").EventEmitterMixinInterface) & (new (...args: any[]) => import("../../util/ReadyMixin.js").ReadyMixinInterface) & typeof LitElement;
6
+ /**
7
+ * A full-width container that pins a `<btu-message>` to the top of the CMS or a
8
+ * content edit page. The banner has no content API of its own — compose a
9
+ * `<btu-message>` inside it (or several, e.g. for a paginated banner) and the banner
10
+ * spans each to 100% of the host, rendering it full-bleed (edge-to-edge, bottom
11
+ * border only, no corner rounding).
12
+ *
13
+ * Set the content (variant, label, symbol, dismissible, badge/description/actions
14
+ * slots) on the message itself. The full-width treatment lives on this wrapper, so
15
+ * the message has no `full-width` attribute — the banner owns that.
16
+ *
17
+ * @element btu-banner
18
+ *
19
+ * @slot - One or more `<btu-message>` elements, full-bleed to the host width. With more
20
+ * than one, the banner auto-creates a `<btu-pagination>` and shows one at a time.
21
+ *
22
+ * @fires {CustomEvent} btu-banner-ready - Fired after the banner is first rendered and initialized
23
+ *
24
+ * @cssprop --banner-z-index - Stack order for the banner (default: 100). The banner is
25
+ * `position: relative`, so this always applies; set `position: sticky` to also pin it to the viewport.
26
+ *
27
+ * @example
28
+ * ```html
29
+ * <btu-banner>
30
+ * <btu-message variant="warning" label="API rate limits were updated">
31
+ * <span slot="description">Review your usage dashboard to stay within the new limits.</span>
32
+ * <button slot="actions" type="button">Learn more</button>
33
+ * </btu-message>
34
+ * </btu-banner>
35
+ * ```
36
+ */
37
+ export default class Banner extends Banner_base {
38
+ createRenderRoot(): this;
39
+ connectedCallback(): void;
40
+ firstUpdated(): void;
41
+ /**
42
+ * @internal
43
+ * Create a `<btu-pagination>` on the banner and show one message at a time, toggling
44
+ * `hidden` on page change. Reflects the messages present at first render (not
45
+ * re-evaluated on later add/remove).
46
+ */
47
+ private _paginate;
48
+ render(): import("lit-html").TemplateResult<1>;
49
+ }
50
+ declare global {
51
+ interface HTMLElementTagNameMap {
52
+ 'btu-banner': Banner;
53
+ }
54
+ }
55
+ export {};
56
+ //# sourceMappingURL=Banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.d.ts","sourceRoot":"","sources":["../../../src/components/banner/Banner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,KAAK,CAAA;AAGtC,OAAO,6BAA6B,CAAA;AACpC,OAAO,cAAc,CAAA;AACrB,OAAO,cAAc,CAAA;;AAErB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAyC;IAC3E,gBAAgB;IAIhB,iBAAiB,IAAI,IAAI;IAKzB,YAAY,IAAI,IAAI;IAUpB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IA6BjB,MAAM;CAGP;AAMD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,MAAM,CAAA;KACrB;CACF"}
@@ -0,0 +1,94 @@
1
+ import { LitElement, html } from 'lit';
2
+ import { EventEmitterMixin } from '../../util/EventEmitterMixin.js';
3
+ import { ReadyMixin } from '../../util/ReadyMixin.js';
4
+ import '../pagination/Pagination.js';
5
+ import './Banner.css';
6
+ import './Message.js';
7
+ /**
8
+ * A full-width container that pins a `<btu-message>` to the top of the CMS or a
9
+ * content edit page. The banner has no content API of its own — compose a
10
+ * `<btu-message>` inside it (or several, e.g. for a paginated banner) and the banner
11
+ * spans each to 100% of the host, rendering it full-bleed (edge-to-edge, bottom
12
+ * border only, no corner rounding).
13
+ *
14
+ * Set the content (variant, label, symbol, dismissible, badge/description/actions
15
+ * slots) on the message itself. The full-width treatment lives on this wrapper, so
16
+ * the message has no `full-width` attribute — the banner owns that.
17
+ *
18
+ * @element btu-banner
19
+ *
20
+ * @slot - One or more `<btu-message>` elements, full-bleed to the host width. With more
21
+ * than one, the banner auto-creates a `<btu-pagination>` and shows one at a time.
22
+ *
23
+ * @fires {CustomEvent} btu-banner-ready - Fired after the banner is first rendered and initialized
24
+ *
25
+ * @cssprop --banner-z-index - Stack order for the banner (default: 100). The banner is
26
+ * `position: relative`, so this always applies; set `position: sticky` to also pin it to the viewport.
27
+ *
28
+ * @example
29
+ * ```html
30
+ * <btu-banner>
31
+ * <btu-message variant="warning" label="API rate limits were updated">
32
+ * <span slot="description">Review your usage dashboard to stay within the new limits.</span>
33
+ * <button slot="actions" type="button">Learn more</button>
34
+ * </btu-message>
35
+ * </btu-banner>
36
+ * ```
37
+ */
38
+ export default class Banner extends EventEmitterMixin(ReadyMixin(LitElement)) {
39
+ createRenderRoot() {
40
+ return this;
41
+ }
42
+ connectedCallback() {
43
+ super.connectedCallback();
44
+ this.classList.add('btu-banner');
45
+ }
46
+ firstUpdated() {
47
+ const messages = Array.from(this.querySelectorAll(':scope > btu-message'));
48
+ if (messages.length === 0) {
49
+ console.warn('[btu-banner] Expected at least one <btu-message> child.', this);
50
+ }
51
+ else if (messages.length > 1) {
52
+ this._paginate(messages);
53
+ }
54
+ this.emit('btu-banner-ready');
55
+ }
56
+ /**
57
+ * @internal
58
+ * Create a `<btu-pagination>` on the banner and show one message at a time, toggling
59
+ * `hidden` on page change. Reflects the messages present at first render (not
60
+ * re-evaluated on later add/remove).
61
+ */
62
+ _paginate(messages) {
63
+ const pager = document.createElement('btu-pagination');
64
+ pager.totalItems = messages.length;
65
+ pager.pageSize = 1;
66
+ // pageSize must be a valid option or the component resets it to the first default.
67
+ pager.pageSizeOptions = '1';
68
+ pager.hideTotalCount = true;
69
+ pager.pageSizeChanger = false;
70
+ pager.boundaryButtons = false;
71
+ const showPage = (page) => {
72
+ messages.forEach((message, i) => {
73
+ message.hidden = i !== page - 1;
74
+ });
75
+ };
76
+ pager.addEventListener('btu-pagination-change', e => {
77
+ showPage(e.detail.page);
78
+ });
79
+ showPage(1);
80
+ // Keep the pager on the banner (a stable host) so navigation never reparents it
81
+ // (no reconnect churn, no focus loss). `data-paginated` flips the banner from the
82
+ // pre-init FOUC guard to the paginated layout (both in Banner.css).
83
+ this.dataset.paginated = '';
84
+ this.append(pager);
85
+ }
86
+ // Light DOM: the messages render themselves; the banner only frames them.
87
+ render() {
88
+ return html ``;
89
+ }
90
+ }
91
+ if (!customElements.get('btu-banner')) {
92
+ customElements.define('btu-banner', Banner);
93
+ }
94
+ //# sourceMappingURL=Banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.js","sourceRoot":"","sources":["../../../src/components/banner/Banner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,6BAA6B,CAAA;AACpC,OAAO,cAAc,CAAA;AACrB,OAAO,cAAc,CAAA;AAErB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,iBAAiB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC3E,gBAAgB;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IAED,iBAAiB;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAA;QACzB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IAClC,CAAC;IAED,YAAY;QACV,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAc,sBAAsB,CAAC,CAAC,CAAA;QACvF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,yDAAyD,EAAE,IAAI,CAAC,CAAA;QAC/E,CAAC;aAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAC1B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED;;;;;OAKG;IACK,SAAS,CAAC,QAAuB;QACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAA;QACtD,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAA;QAClC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAA;QAClB,mFAAmF;QACnF,KAAK,CAAC,eAAe,GAAG,GAAG,CAAA;QAC3B,KAAK,CAAC,cAAc,GAAG,IAAI,CAAA;QAC3B,KAAK,CAAC,eAAe,GAAG,KAAK,CAAA;QAC7B,KAAK,CAAC,eAAe,GAAG,KAAK,CAAA;QAE7B,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAQ,EAAE;YACtC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE;gBAC9B,OAAO,CAAC,MAAM,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,CAAA;YACjC,CAAC,CAAC,CAAA;QACJ,CAAC,CAAA;QAED,KAAK,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,CAAC,CAAC,EAAE;YAClD,QAAQ,CAAE,CAAmC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC5D,CAAC,CAAC,CAAA;QAEF,QAAQ,CAAC,CAAC,CAAC,CAAA;QACX,gFAAgF;QAChF,kFAAkF;QAClF,oEAAoE;QACpE,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,EAAE,CAAA;QAC3B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACpB,CAAC;IAED,0EAA0E;IAC1E,MAAM;QACJ,OAAO,IAAI,CAAA,EAAE,CAAA;IACf,CAAC;CACF;AAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;IACtC,cAAc,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;AAC7C,CAAC"}
@@ -0,0 +1,4 @@
1
+ /* FOUC prevention: hide pseudo-slotted content before component upgrades */
2
+ btu-message:not(:defined) > [slot] {
3
+ @apply hidden;
4
+ }
@@ -0,0 +1,103 @@
1
+ import { LitElement, type PropertyValues } from 'lit';
2
+ import '../icon-button/IconButton.js';
3
+ import '../icon/Icon.js';
4
+ import './Message.css';
5
+ export type MessageVariant = 'primary' | 'info' | 'warning' | 'error' | 'success';
6
+ declare const Message_base: (new (...args: any[]) => import("../../util/EventEmitterMixin.js").EventEmitterMixinInterface) & (new (...args: any[]) => import("../../util/ReadyMixin.js").ReadyMixinInterface) & typeof LitElement;
7
+ /**
8
+ * A message for communicating high-visibility content that is not tied to the
9
+ * user's current task — alerts, breaking news, and persistent status. Use it on
10
+ * its own as a contained, bordered card, or place it inside a `<btu-banner>` to
11
+ * span the full width of the page (e.g., pinned above the CMS content area).
12
+ *
13
+ * Messages render a leading icon, an optional badge, a label, an optional
14
+ * description, and an optional dismiss control. The label and description
15
+ * stack vertically in a text column; everything else sits on the same row.
16
+ *
17
+ * @element btu-message
18
+ *
19
+ * @slot badge - Pseudo-slot for a leading status/version tag, typically a
20
+ * `<btu-badge>`. The slotted child is moved into the header row, before the
21
+ * label.
22
+ * @slot description - Pseudo-slot for supporting text rendered directly beneath
23
+ * the label. Slot a single inline element (e.g., `<span slot="description">`)
24
+ * or a block element to enable rich content (links, emphasis).
25
+ * @slot actions - Pseudo-slot for CTA buttons, links, or a `<btu-pagination>`.
26
+ * Children with `slot="actions"` are moved into an internal container on the
27
+ * trailing edge of the body. `.btu-button` children inherit the message's
28
+ * foreground color across all states. The message does not emit an
29
+ * action-click event — attach handlers to your own elements.
30
+ *
31
+ * @fires {CustomEvent} btu-message-ready - Fired after the message is first rendered and initialized
32
+ * @fires {CustomEvent} btu-message-dismiss - Fired when the user clicks the close/dismiss button.
33
+ * Cancelable: the message hides itself (sets `hidden`) unless the listener calls `preventDefault()`.
34
+ *
35
+ * @cssprop --message-color-background - Overrides the background color for the message
36
+ * @cssprop --message-color-foreground - Overrides the text and icon color
37
+ * @cssprop --message-color-border - Overrides the border color (defaults to the variant's 300 shade)
38
+ * @cssprop --message-padding - Overrides the internal padding (default: 1rem)
39
+ * @cssprop --message-border-radius - Overrides the corner rounding (default: 8px)
40
+ *
41
+ * @example
42
+ * ```html
43
+ * <btu-message variant="info" label="New feature available" dismissible></btu-message>
44
+ * ```
45
+ *
46
+ * @example
47
+ * ```html
48
+ * <btu-message variant="error" label="Something went wrong" dismissible>
49
+ * <span slot="description">We couldn't save your changes. Please try again in a moment.</span>
50
+ * </btu-message>
51
+ * ```
52
+ *
53
+ * @example
54
+ * ```html
55
+ * <btu-message variant="info" label="New feature available" dismissible>
56
+ * <btu-badge slot="badge" variant="info" size="sm">v2.4</btu-badge>
57
+ * <span slot="description">The redesigned editor is now available.</span>
58
+ * <button slot="actions" type="button">Learn more</button>
59
+ * </btu-message>
60
+ * ```
61
+ */
62
+ export default class Message extends Message_base {
63
+ /**
64
+ * Visual style and semantic meaning of the message.
65
+ * @attr
66
+ */
67
+ variant: MessageVariant;
68
+ /**
69
+ * The primary message or title text displayed.
70
+ * @attr
71
+ */
72
+ label: string | undefined;
73
+ /**
74
+ * Name of the Lucide icon to display. Defaults to a sensible icon per variant.
75
+ * @attr
76
+ */
77
+ symbol: string | undefined;
78
+ /**
79
+ * If true, a close icon is provided to allow the user to hide the message.
80
+ * @attr
81
+ */
82
+ dismissible: boolean;
83
+ /**
84
+ * @internal
85
+ * Safe, validated variant used for rendering and styling. If the consumer
86
+ * sets an unknown value on `this.variant`, we fall back to `info` here
87
+ * without overwriting the original user input on the element.
88
+ */
89
+ private _safeVariant;
90
+ createRenderRoot(): this;
91
+ connectedCallback(): void;
92
+ willUpdate(changedProperties: PropertyValues<this>): void;
93
+ firstUpdated(): void;
94
+ private _handleDismiss;
95
+ render(): import("lit-html").TemplateResult<1>;
96
+ }
97
+ declare global {
98
+ interface HTMLElementTagNameMap {
99
+ 'btu-message': Message;
100
+ }
101
+ }
102
+ export {};
103
+ //# sourceMappingURL=Message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../src/components/banner/Message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAMpE,OAAO,8BAA8B,CAAA;AACrC,OAAO,iBAAiB,CAAA;AACxB,OAAO,eAAe,CAAA;AAEtB,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAA;;AAqBjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,YAAyC;IAC5E;;;OAGG;IAEH,OAAO,EAAE,cAAc,CAAS;IAEhC;;;OAGG;IAEH,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAEzB;;;OAGG;IAEH,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAE1B;;;OAGG;IAEH,WAAW,UAAQ;IAEnB;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAAyB;IAE7C,gBAAgB;IAIhB,iBAAiB,IAAI,IAAI;IAOzB,UAAU,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAwBzD,YAAY,IAAI,IAAI;IAuCpB,OAAO,CAAC,cAAc;IActB,MAAM;CAkCP;AAMD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,OAAO,CAAA;KACvB;CACF"}