## Summary
This PR applies **lossless compression** to all SVG and JPG/PNG assets
across Kibana using:
- [`svgo`](https://github.com/svg/svgo) — for optimizing SVGs
- [`image-optimize`](https://www.npmjs.com/package/image-optimize) — for
JPG/PNG compression
‼️**Please scroll to ''Unknown metric groups" accordion to see what's
the gain for your code.**
<img width="542" alt="Screenshot 2025-06-18 at 13 24 20"
src="https://github.com/user-attachments/assets/191afb28-44fc-4551-9026-756a8385c66a"
/>
The goal is to reduce asset size and improve load performance without
compromising visual quality.
This PR achieves a **23 MB** reduction in asset size across all images
bundled in Kibana’s running code—meaning these compressed images
directly impact what ships in Kibana.
Some assets get bundled into chunks due to our bundling strategy but
might not actually be requested at runtime.
Additionally, I ran the same optimization script on the docs assets as a
harmless extra step, but those savings aren’t included in the 23 MB
total.
---
## Why
While working on Emotion rewrites, I noticed some SVGs seemed
unnecessarily heavy. That led to a broader investigation into our image
assets, and it turns out we’re not consistently optimizing them during
development or build.
---
## Notes
- Visual fidelity of optimized assets has been manually verified — no
visible differences
- The optimization is **lossless**, meaning no quality degradation
- Some assets (like large background images) could benefit further from
**lossy compression**
---
## Follow-ups / Ideas
1. **Automate compression in the dev/build pipeline**
- e.g. add `svgo` as a pre-commit or CI step for SVGs
2. **Improve CI reporting**
- Currently, bundle size diffs for images are hidden under "Unknown
metric groups" in the GitHub CI comment. We may want to make these more
visible.
-
3. **Audit large assets manually** — apply lossy compression where
appropriate
4. **Avoid redundant image loading**
- e.g. background images on the login page are loaded again on the space
selector page since they’re bundled twice. I’m working on a separate PR
to address that.
## Snippets I used to apply the compression
```
# Find SVG files
find . -type f -iname "*.svg" \
-not -path "*/node_modules/*" \
-not -path "*/functional/*" > svg-files.txt
# Compress SVGs
while IFS= read -r file; do
svgo "$file"
done < svg-files.txt
```
This snippet has been used for png and jpg, but the example below is for
png:
```
# Find PNG files
find . -type f -iname "*.png \
-not -path "*/node_modules/*" \
-not -path "*/functional/*" > png-files.txt
# Compress PNGs
while IFS= read -r file; do
image-optimize -f jpg "$file"
done < png-files.txt
```
## Summary
This PR adjusts the approach introduced in #214861 to ensure state
updates work consistently across tabs, even after switching tabs during
async operations. The `currentTabId` prop has been removed from the
central state since it can't be relied on in actions, and instead tab
IDs are injected using a `CurrentTabProvider`. This allows selectors to
work the same as they did before, and tab specific actions have been
updated to use a standard `TabAction` interface that accepts a tab ID
and prevents leaking state changes.
This approach is safer but adds some complexity, so for actions
dispatched from React components, a `useCurrentTabAction` hook has been
added to handle injecting the current tab ID. We also still need to
access tab state within `DiscoverStateContainer` for now, so two utility
methods (`injectCurrentTab` and `getCurrentTab`) have been added to make
this easier. Since `DiscoverStateContainer` is scoped to a single tab,
this should be safe, and ideally temporary until we get rid of it
completely.
Resolves#215398.
### Checklist
- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [ ] This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary
**Reviewers: Please test the code paths affected by this PR. See the
"Risks" section below.**
Part of work for enabling "high contrast mode" in Kibana. See
https://github.com/elastic/kibana/issues/176219.
**Background:**
Kibana will soon have a user profile setting to allow users to enable
"high contrast mode." This setting will activate a flag with
`<EuiProvider>` that causes EUI components to render with higher
contrast visual elements. Consumer plugins and packages need to be
updated selected places where `<EuiProvider>` is wrapped, to pass the
`UserProfileService` service dependency from the CoreStart contract.
**NOTE:** **EUI currently does not yet support the high-contrast mode
flag**, but support for that is expected to come in around 2 weeks.
These first PRs are simply preparing the code by wiring up the
`UserProvideService`.
### Checklist
Check the PR satisfies following conditions.
Reviewers should verify this PR satisfies this list as well.
- [X] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [X] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
### Risks
Does this PR introduce any risks? For example, consider risks like hard
to test bugs, performance regression, potential of data loss.
Describe the risk, its severity, and mitigation for each identified
risk. Invite stakeholders and evaluate how to proceed before merging.
- [ ] [medium/high] The implementor of this change did not manually test
the affected code paths and relied on type-checking and functional tests
to drive the changes. Code owners for this PR need to manually test the
affected code paths.
- [ ] [medium] The `UserProfileService` dependency comes from the
CoreStart contract. If acquiring the service causes synchronous code to
become asynchronous, check for race conditions or errors in rendering
React components. Code owners for this PR need to manually test the
affected code paths.
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Part of https://github.com/elastic/kibana/issues/192005
Closes https://github.com/elastic/kibana/issues/176533
## Summary
This PR represents the first major cleanup task for the control group
embeddable refactor. The tasks included in this PR can be loosely
summarized as follows:
1. This PR removes the old, non-React version of controls
- Note that the new controls are still included under the
`react_controls` folder - I will address this in a follow up PR.
2. This PR removes **all** types associated with the old embeddable
system; i.e. any `*input*` or `*output*` types.
- As part of cleaning up these types, some of the types included in the
`public/react_controls` folder had to be moved to `common` to make them
available to server-side code.
- This resulted in an... unfortunate number of import changes 🫠 Hence
the rather large file change count. I took this opportunity to organize
the imports, too - so a significant chunk of these files are simply
import changes.
3. This PR removes the controls Storybook and all related mocks
- Since the controls storybooks have been broken for awhile, and since
we had plans to remove them but never got around to it, I just decided
to delete them as part of this PR and close
https://github.com/elastic/kibana/issues/176533 rather than spending
time to fix the types for non-operational stories
### Checklist
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Closes https://github.com/elastic/kibana/issues/189820
### Summary
This PR converts the `ControlGroupRenderer` to use the new control group
embeddable, which is built on the new React embeddable framework. With
this conversion, there should not be **any** changes in user-facing
behaviour - therefore, testing of this PR should be focused on ensuring
that no behaviour is changed and/or broken with this refactor.
**Notes to Solution Reviewers:**
- There should be minimal changes to your uses of `ControlGroupRenderer`
- our goal here was to keep the exposed API more-or-less consistent with
this refactor. Therefore, most changes are simply renames + changes of
imports.
- That being said, `updateInput` and `getInput$` are **very much** tied
to the old embeddable infrastructure - so while they will continue to
work for now, they have been deprecated in favour of adding
setters/getters for the parts of the control group state that you need
to update / respond to.
**Notes to Presentation Reviewer:**
- The bundle size was originally being increased by this PR, so I
decided to remove a bunch of the public exports that are no longer
necessary as a final cleanup - this resulted in changes to imports in a
few files, but it was worth doing in this PR IMO so that we didn't have
to increase the Controls bundle limit. Now, this PR shrinks the bundle
size 🎉
- I fixed a small bug with the default value of `showApplySelections` in
this PR - since it was a one-line change, if felt like overkill to
separate it out. See
https://github.com/elastic/kibana/pull/190561/files#r1733253015
### Checklist
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary
Fixes needed for getting CI to pass when EUI throws an error if
attempting to render a component without the EuiProvider in the render
tree.
## Detailed description
In https://github.com/elastic/kibana/pull/180819, I will deliver a
change that will cause EUI components to throw an error if the
EuiProvider context is missing. This PR comes in as part of the final
work to get all functional tests passing in an environment where EUI
will throw the error. The tied to the ["Fix 'dark mode' inconsistencies
in Kibana" Epic](https://github.com/elastic/kibana-team/issues/805) has
so far been in preparation for this.
**Reviewers: Please interact with critical paths through the UI
components touched in this PR, ESPECIALLY in terms of testing dark mode
and i18n.**
<img width="1107" alt="image"
src="c0d2ce08-ac35-45a7-8192-0b2256fceb0e">
### Checklist
Delete any items that are not applicable to this PR.
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [ ] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
`v90.0.0`⏩`v91.0.0-backport.0`
⚠️ While this upgrade pings many teams and has a large code diff, **the
majority of the changes are snapshots or tests-related** and do not
touch source code, so should theoretically only need a code review and
not dedicated QA.
The changes in EUI that required a large swathe of these updates are:
- **EuiPopover** removed an extra unnecessary `<div>` wrapper on its
anchors, which affected many snapshots and a few CSS overrides, which
should have been updated
- **EuiButtonGroup** now renders `<button>` elements instead of `<input
type="radio">` elements for single selection, which affected both
snapshots and E2E tests
- **EuiSuperDatePicker**'s absolute date input now requires an `Enter`
keypress when parsing dates (affected E2E tests)
- **EuiComboBox**, when rendered with `singleSelection={{ plainText:
'true' }}`, no longer renders a pill (i.e. text). This combobox type now
behaves more like an `EuiFieldText`, where the selection is rendered via
input `value` instead. This affected a high amount of E2E tests (both
FTR and Cypress), both in terms of updating assertions and changing
selections, but should **not** significantly affect user experience -
see https://github.com/elastic/eui/pull/7332 for more.
---
##
[`v91.0.0-backport.0`](https://github.com/elastic/eui/tree/v91.0.0-backport.0)
**This is a backport release only intended for use by Kibana.**
- Added `esqlVis`, `pipeBreaks`, and `pipeNoBreaks` icon glyphs.
- `EuiSelectable` now allows configurable text truncation via
`listProps.truncationProps`
([#7388](https://github.com/elastic/eui/pull/7388))
- `EuiTextTruncate` now supports a new `calculationDelayMs` prop for
working around font loading or layout shifting scenarios
([#7388](https://github.com/elastic/eui/pull/7388))
**Bug fixes**
- Fixed a bug with `EuiSelectable`s with custom `truncationProps`, where
scrollbar widths were not being accounted for
([#7392](https://github.com/elastic/eui/pull/7392))
## [`91.0.0`](https://github.com/elastic/eui/tree/v91.0.0)
- Updated the background color of `EuiPopover`s in dark mode to increase
visibility & contrast against other page/panel backgrounds
([#7310](https://github.com/elastic/eui/pull/7310))
- Memoized `EuiDataGrid` to prevent unneeded re-renders
([#7324](https://github.com/elastic/eui/pull/7324))
- Added a configurable `role` prop to `EuiAccordion`
([#7326](https://github.com/elastic/eui/pull/7326))
- Added a configurable `role` prop to `EuiGlobalToastList`
([#7328](https://github.com/elastic/eui/pull/7328))
- For greater flexibility, `EuiSuperDatePicker` now allows users to
paste ISO 8601, RFC 2822, and Unix timestamps in the `Absolute` tab
input, in addition to timestamps in the `dateFormat` prop
([#7331](https://github.com/elastic/eui/pull/7331))
- Plain text `EuiComboBox`es now behave more like a normal text
field/input. Backspacing will no longer delete the entire value, and
selected values can now be double clicked and copied.
([#7332](https://github.com/elastic/eui/pull/7332))
- `EuiDataGrid`'s display settings popover now allows users to clear the
"Lines per row" input before typing in a new number
([#7338](https://github.com/elastic/eui/pull/7338))
- Improved the UX of `EuiSuperDatePicker`'s Absolute tab for users
manually typing in timestamps
([#7341](https://github.com/elastic/eui/pull/7341))
- Updated `EuiI18n`s with multiple `tokens` to accept dynamic `values`
([#7341](https://github.com/elastic/eui/pull/7341))
**Bug fixes**
- Fixed `EuiComboBox`'s `onSearchChange` callback to pass the correct
`hasMatchingOptions` value
([#7334](https://github.com/elastic/eui/pull/7334))
- Fixed an `EuiSelectableTemplateSitewide` bug where the `popoverButton`
behavior would break if passed a non-DOM React wrapper
([#7339](https://github.com/elastic/eui/pull/7339))
**Deprecations**
- `EuiPopover`: deprecated `anchorClassName`. Use `className` instead
([#7311](https://github.com/elastic/eui/pull/7311))
- `EuiPopover`: deprecated `buttonRef`. Use `popoverRef` instead
([#7311](https://github.com/elastic/eui/pull/7311))
- `EuiPopover`: removed extra `.euiPopover__anchor` div wrapper. Target
`.euiPopover` instead if necessary
([#7311](https://github.com/elastic/eui/pull/7311))
- Deprecated `EuiButtonGroup`'s `name` prop. This can safely be removed.
([#7325](https://github.com/elastic/eui/pull/7325))
**Breaking changes**
- Removed deprecated `euiPaletteComplimentary` - use
`euiPaletteComplementary` Instead
([#7333](https://github.com/elastic/eui/pull/7333))
**Accessibility**
- Updated `type="single"` `EuiButtonGroup`s to render standard buttons
instead of radio buttons under the hood, per recent a11y recommendations
([#7325](https://github.com/elastic/eui/pull/7325))
- `EuiAccordion` now defaults to a less screenreader-noisy `group` role
instead of `region`. If your accordion contains significant enough
content to be a document landmark role, you may re-configure it back to
`region`. ([#7326](https://github.com/elastic/eui/pull/7326))
- Reduced screen reader noisiness when sorting `EuiDataGrid` columns via
toolbar ([#7327](https://github.com/elastic/eui/pull/7327))
- `EuiGlobalToastList` now defaults to a `log` role. If your toasts will
always require immediate user action, consider (with caution) using the
`alert` role instead.
([#7328](https://github.com/elastic/eui/pull/7328))
**CSS-in-JS conversions**
- Updated `$euiFontFamily` and `$euiCodeFontFamily` to match Emotion
fonts ([#7332](https://github.com/elastic/eui/pull/7332))
---------
Co-authored-by: Cee Chen <constance.chen@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Cee Chen <549407+cee-chen@users.noreply.github.com>
Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
closes https://github.com/elastic/kibana/issues/158561
## 📝 Summary
This PR adds a new customization point to allow for prepending custom
filter controls to the search bar.
At the moment we are only showing a default namespace filter, once this
is ready we will then check how to provide curated filters per
integration.
## ✅ Testing
1. Make sure to have some documents to different data sets with
different namespace, you can use [this
document](https://www.elastic.co/guide/en/elasticsearch/reference/current/set-up-a-data-stream.html)
as an example
2. Navigate to Discover with the log-explorer profile, `/p/log-explorer`
3. Validate that the new filter control is there
4. Filter using this new control and make sure documents are filtered
out
## 🎥 Demo
6828f62f-dd09-42bd-930c-dd7eaf94958b
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>