diff --git a/.github/workflows/ci-frontend.yml b/.github/workflows/ci-frontend.yml index 3411304b8795a..d1acc48120962 100644 --- a/.github/workflows/ci-frontend.yml +++ b/.github/workflows/ci-frontend.yml @@ -50,7 +50,10 @@ jobs: run: pnpm prettier:check - name: Lint with ESLint - run: pnpm eslint + run: pnpm lint:js + + - name: Lint with Stylelint + run: pnpm lint:css - name: Generate logic types and run typescript with strict run: pnpm typegen:write && pnpm typescript:check diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 0000000000000..46b4d2996945c --- /dev/null +++ b/.stylelintignore @@ -0,0 +1 @@ +frontend/dist/ diff --git a/.stylelintrc.js b/.stylelintrc.js new file mode 100644 index 0000000000000..5df820f88d8fb --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1,48 @@ +module.exports = { + extends: 'stylelint-config-standard-scss', // TODO: Enable separately, as the diff will be significant + // TODO: Enable separately, as the diff will be significant "plugins": ["stylelint-order"], + rules: { + 'no-descending-specificity': null, + 'number-max-precision': 5, + 'value-keyword-case': [ + 'lower', + { + // CSS Color Module Level 3 says currentColor, Level 4 candidate says currentcolor + // Sticking to Level 3 for now + camelCaseSvgKeywords: true, + }, + ], + // Sadly Safari only started supporting the range syntax of media queries in 2023, so let's switch to that + // ('context' value) in 2024, once support is better https://caniuse.com/?search=range%20context + 'media-feature-range-notation': 'prefix', + 'selector-class-pattern': [ + '^[A-Za-z0-9_-]+(__[A-Za-z0-9_-]+)?(--[A-Za-z0-9-]+)?$', + { + message: 'Expected class selector to match Block__Element--Modifier or plain snake-case', + }, + ], + 'selector-id-pattern': [ + '^[A-Za-z0-9_-]+(__[A-Za-z0-9_-]+)?(--[A-Za-z0-9_-]+)?$', + { + message: 'Expected id selector to match Block__Element--Modifier or plain kebak-case', + }, + ], + 'keyframes-name-pattern': [ + '^[A-Za-z0-9_-]+__[A-Za-z0-9_-]+$', + { + message: 'Expected keyframe name to match Block__Animation', + }, + ], + 'scss/dollar-variable-pattern': [ + '^[A-Za-z_]+[A-Za-z0-9_-]+$', + { + message: 'Expected variable to match kebab-case or snake_case', + }, + ], + 'scss/operator-no-newline-after': null, // Doesn't always play well with prettier + 'scss/at-extend-no-missing-placeholder': null, + 'scss/comment-no-empty': null, + // "order/order": ["dollar-variables", "custom-properties", "declarations", "rules", "at-rules"], + // "order/properties-order": ["width", "height"], + }, +} diff --git a/frontend/src/exporter/ExportedInsight/ExportedInsight.scss b/frontend/src/exporter/ExportedInsight/ExportedInsight.scss index c158e28a7bc55..cab975ef99ae8 100644 --- a/frontend/src/exporter/ExportedInsight/ExportedInsight.scss +++ b/frontend/src/exporter/ExportedInsight/ExportedInsight.scss @@ -25,6 +25,7 @@ flex: 1; position: relative; z-index: 1; + .FunnelBarChart { min-height: 50vw; } @@ -49,6 +50,7 @@ right: 0; top: 0; z-index: 2; + svg { font-size: 0.75rem; margin: 0.25rem; diff --git a/frontend/src/exporter/Exporter.scss b/frontend/src/exporter/Exporter.scss index db6d2acc6a495..17fb7a4e4b3e5 100644 --- a/frontend/src/exporter/Exporter.scss +++ b/frontend/src/exporter/Exporter.scss @@ -1,33 +1,5 @@ @import '../styles/mixins'; -html.export-type-image { - // We don't want scrollbars to show in image captures - ::-webkit-scrollbar { - display: none; - } - - body { - // We put Inter first so that rendered images are the same no matter which platform it is rendered on. - font-family: 'Inter', 'Segoe UI', 'Roboto', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', - 'Segoe UI Symbol'; - } -} - -html.export-type-embed { - overflow: hidden; - overflow-y: auto; - - .Exporter { - padding: 0; - - // Insights can resize to fit any height, whereas dashboards cannot - &--insight { - height: 100vh; - max-height: 100vh; - } - } -} - .Exporter { padding: 1rem; @@ -58,3 +30,31 @@ html.export-type-embed { } } } + +html.export-type-image { + // We don't want scrollbars to show in image captures + ::-webkit-scrollbar { + display: none; + } + + body { + // We put Inter first so that rendered images are the same no matter which platform it is rendered on. + font-family: Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', + 'Segoe UI Symbol'; + } +} + +html.export-type-embed { + overflow: hidden; + overflow-y: auto; + + .Exporter { + padding: 0; + + // Insights can resize to fit any height, whereas dashboards cannot + &--insight { + height: 100vh; + max-height: 100vh; + } + } +} diff --git a/frontend/src/layout/ErrorBoundary/ErrorBoundary.scss b/frontend/src/layout/ErrorBoundary/ErrorBoundary.scss index c98425d731956..be9ac8887a160 100644 --- a/frontend/src/layout/ErrorBoundary/ErrorBoundary.scss +++ b/frontend/src/layout/ErrorBoundary/ErrorBoundary.scss @@ -5,20 +5,24 @@ padding: 0.75rem 1rem 1rem; min-width: 0; height: fit-content; + .main-app-content > & { margin: 1.5rem 0; } + h2 { margin-bottom: 0.75rem; color: var(--danger); font-weight: 600; } + pre { margin-bottom: 0.75rem; background: var(--border-light); border-radius: var(--radius); padding: 0.75rem 1rem; } + .help-button { margin-top: 0.75rem; } diff --git a/frontend/src/layout/navigation-3000/Navigation.scss b/frontend/src/layout/navigation-3000/Navigation.scss index a4c8e0bbffeb4..780a3787f7295 100644 --- a/frontend/src/layout/navigation-3000/Navigation.scss +++ b/frontend/src/layout/navigation-3000/Navigation.scss @@ -22,9 +22,11 @@ position: relative; margin: var(--scene-padding-y) var(--scene-padding-x); min-height: calc(100vh - var(--breadcrumbs-height-full) - var(--scene-padding-y) * 2); + &.Navigation3000__scene--raw { --scene-padding-y: 0px; --scene-padding-x: 0px; + display: flex; flex-direction: column; } @@ -69,9 +71,11 @@ .NavbarButton { position: relative; + .LemonButton__icon { transition: color 100ms ease, transform 100ms ease; } + &.NavbarButton--here { &::after { content: '•'; @@ -84,6 +88,7 @@ line-height: 0.5625rem; color: var(--default); } + .LemonButton__icon { color: var(--default); transform: translateY(-0.25rem); @@ -98,7 +103,9 @@ --sidebar-horizontal-padding: 0.5rem; --sidebar-row-height: 2rem; --sidebar-background: var(--bg-3000); + position: relative; + // This border is just for sizing, the visible border is on the content and slider // Hidden when the sidebar is closed border-right: min(1px, var(--sidebar-width)) solid transparent; @@ -122,23 +129,27 @@ margin: 0; line-height: inherit; } + h3 { font-weight: 600; line-height: 2rem; font-size: 0.75rem; } + h4 { font-weight: 600; line-height: 1.75rem; font-size: 0.6875rem; flex-grow: 1; } + h5 { font-weight: 400; font-size: 0.75rem; text-transform: none; letter-spacing: normal; } + b { font-weight: 700; } @@ -164,6 +175,7 @@ white-space: nowrap; overflow: hidden; background: var(--sidebar-background); + // Extend the border into viewport overscroll border-right: min(1px, var(--sidebar-width)) solid var(--border); @@ -182,8 +194,7 @@ flex-direction: column; align-items: stretch; flex-grow: 1; - overflow-x: hidden; - overflow-y: auto; + overflow: hidden auto; } .Sidebar3000__hint { @@ -206,6 +217,7 @@ right: calc( -1 * var(--sidebar-slider-padding) - min(1px, var(--sidebar-width)) ); // Center around the original sidebar border + width: calc(2 * var(--sidebar-slider-padding) + 1px); // The interactive area is enlarged for easier interaction cursor: col-resize; user-select: none; // Fixes inadvertent selection of scene text when resizing @@ -222,23 +234,28 @@ width: 1px; pointer-events: none; } + &::before { transition: 100ms ease transform; background: var(--border); } + &::after { transition: 100ms ease transform; background: var(--text-3000); opacity: 0; } + &:hover::after, .Sidebar3000--resizing &::after { opacity: 0.25; } + .Sidebar3000--resizing &::before, .Sidebar3000--resizing &::after { transform: scaleX(3); } + .Sidebar3000[aria-hidden='true'] & { cursor: e-resize; } @@ -260,20 +277,25 @@ --accordion-inset-expandable: 1.25rem; --accordion-header-background: var(--accent-3000); --accordion-inset: 0rem; + min-height: var(--accordion-row-height); flex-shrink: 0; flex-basis: 0; display: flex; flex-direction: column; + [theme='dark'] & { --accordion-header-background: var(--bg-3000); } + &[aria-expanded] { // This means: if accordion is expandable --accordion-inset: var(--accordion-inset-expandable); } + &:not([aria-expanded='false']) { flex-grow: 1; + &:not(:last-child) { border-bottom-width: 1px; } @@ -283,10 +305,12 @@ .Accordion[aria-disabled='true'] { .Accordion__header { cursor: default; + &:hover { background: var(--accordion-header-background); } } + &:not([aria-busy='true']) .Accordion__header .LemonIcon { visibility: hidden; } @@ -302,14 +326,17 @@ border-bottom-width: 1px; cursor: pointer; user-select: none; + &:hover { background: var(--border-3000); } + > .LemonIcon { transition: 50ms ease transform; font-size: var(--accordion-arrow-size); flex-shrink: 0; margin-right: calc(var(--accordion-inset-expandable) - var(--accordion-arrow-size)); + .Accordion[aria-expanded='true'] & { transform: rotate(90deg); } @@ -321,6 +348,7 @@ --sidebar-list-item-fold-size: 0.5rem; --sidebar-list-item-ribbon-width: 0.1875rem; --sidebar-list-item-background: var(--sidebar-background); + position: relative; color: var(--muted); line-height: 1.125rem; @@ -333,8 +361,10 @@ &[aria-current='page'], &.SidebarListItem--is-renaming { opacity: 1; + --sidebar-list-item-background: var(--border-3000); } + &:hover, &:focus-within, &[aria-current='page'], @@ -343,14 +373,17 @@ .SidebarListItem__actions { display: flex; } + // Accommodate menu button by moving stuff out of the way &.SidebarListItem--has-menu:not(.SidebarListItem--extended) .SidebarListItem__link { padding-right: calc(var(--sidebar-horizontal-padding) + 1.25rem); } + &.SidebarListItem--has-menu.SidebarListItem--extended { &::after { content: ''; position: absolute; + // Position 1px away so that the :focus-visible border isn't overlaid top: 1px; right: 1px; @@ -377,6 +410,7 @@ z-index: 1; } } + &.SidebarListItem--marker-fold { &::before { width: 0; @@ -385,23 +419,29 @@ border-bottom: var(--sidebar-list-item-fold-size) solid transparent; } } + &.SidebarListItem--marker-ribbon { --sidebar-list-item-marker-offset: var(--sidebar-list-item-ribbon-width); + &::before { width: var(--sidebar-list-item-ribbon-width); height: 100%; background: var(--sidebar-list-item-status-color); } } + &.SidebarListItem--marker-status-success { --sidebar-list-item-status-color: var(--success); } + &.SidebarListItem--marker-status-warning { --sidebar-list-item-status-color: var(--warning); } + &.SidebarListItem--marker-status-danger { --sidebar-list-item-status-color: var(--danger); } + &.SidebarListItem--marker-status-completion { --sidebar-list-item-status-color: var(--purple); } @@ -412,6 +452,7 @@ --sidebar-list-item-inset: calc( var(--accordion-inset, 0px) + var(--sidebar-horizontal-padding) + var(--sidebar-list-item-marker-offset, 0px) ); + position: relative; display: flex; flex-direction: column; @@ -419,13 +460,11 @@ width: 100%; height: 100%; color: inherit; + &:focus-visible::after { content: ''; position: absolute; - top: 0; - left: 0; - bottom: -1px; - right: 0; + inset: 0 0 -1px; border: 1px solid var(--default); pointer-events: none; } @@ -443,6 +482,7 @@ .SidebarListItem__rename { // Pseudo-elements don't work on inputs, so we use a wrapper div background: var(--bg-light); + input { outline: none; height: 100%; @@ -452,15 +492,14 @@ padding: 0 calc(var(--sidebar-horizontal-padding) + 2.5rem) 0 var(--sidebar-list-item-inset); background: none; } + &::after { content: ''; position: absolute; - top: 0; - left: 0; - bottom: -1px; - right: 0; + inset: 0 0 -1px; border: 1px solid var(--default); pointer-events: none; + .SidebarListItem[aria-invalid='true'] & { border-color: var(--danger); } @@ -477,6 +516,7 @@ background: var(--danger); color: #fff; white-space: normal; + &::before { display: block; content: ''; diff --git a/frontend/src/layout/navigation-3000/components/Breadcrumbs.scss b/frontend/src/layout/navigation-3000/components/Breadcrumbs.scss index 10c4b8fc13240..75b3dae2df67d 100644 --- a/frontend/src/layout/navigation-3000/components/Breadcrumbs.scss +++ b/frontend/src/layout/navigation-3000/components/Breadcrumbs.scss @@ -1,5 +1,6 @@ .Breadcrumbs3000 { --breadcrumbs-compaction-rate: 0; + z-index: var(--z-main-nav); position: sticky; top: 0; @@ -48,6 +49,7 @@ font-weight: 700; overflow: hidden; height: calc(1em * 1.2 * (1 - var(--breadcrumbs-compaction-rate))); + > span { position: absolute; bottom: 0; @@ -69,6 +71,7 @@ &.Breadcrumbs3000__breadcrumb--here { cursor: default; + > span { opacity: 1; transform: translateY(calc(100% * (1 - var(--breadcrumbs-compaction-rate)))); @@ -77,6 +80,7 @@ &.Breadcrumbs3000__breadcrumb--actionable { cursor: pointer; + &:hover > span, &.Breadcrumbs3000__breadcrumb--open > span { opacity: 1; @@ -103,6 +107,7 @@ flex-shrink: 0; margin: 0 0.5rem; opacity: 0.5; + &::after { content: '/'; } diff --git a/frontend/src/layout/navigation-3000/components/KeyboardShortcut.scss b/frontend/src/layout/navigation-3000/components/KeyboardShortcut.scss index f868dd473b6b4..6a1645dbcfd0e 100644 --- a/frontend/src/layout/navigation-3000/components/KeyboardShortcut.scss +++ b/frontend/src/layout/navigation-3000/components/KeyboardShortcut.scss @@ -14,15 +14,18 @@ background: var(--accent-3000); color: var(--default); text-transform: capitalize; + .KeyboardShortcut--muted > & { background: none; color: var(--muted); } + .ant-tooltip & { color: #fff; background: rgba(#000, 0.333); border-color: rgba(#fff, 0.333); } + & + .KeyboardShortcut__key { margin-left: 0.25rem; } diff --git a/frontend/src/layout/navigation-3000/sidepanel/SidePanel.scss b/frontend/src/layout/navigation-3000/sidepanel/SidePanel.scss index 4f3d08f139753..30c14c722c8d4 100644 --- a/frontend/src/layout/navigation-3000/sidepanel/SidePanel.scss +++ b/frontend/src/layout/navigation-3000/sidepanel/SidePanel.scss @@ -17,7 +17,7 @@ top: 0; right: 0; max-width: calc(100vw - 3rem); - box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 30px rgb(0 0 0 / 20%); [theme='dark'] & { box-shadow: none; diff --git a/frontend/src/layout/navigation-3000/sidepanel/sidePanelLogic.tsx b/frontend/src/layout/navigation-3000/sidepanel/sidePanelLogic.tsx index b0c46bb1056c5..a8f42f536616c 100644 --- a/frontend/src/layout/navigation-3000/sidepanel/sidePanelLogic.tsx +++ b/frontend/src/layout/navigation-3000/sidepanel/sidePanelLogic.tsx @@ -35,10 +35,7 @@ export const sidePanelLogic = kea([ tabs.push(SidePanelTab.Support) } - if (featureFlags[FEATURE_FLAGS.SIDE_PANEL_DOCS]) { - tabs.push(SidePanelTab.Docs) - } - + tabs.push(SidePanelTab.Docs) tabs.push(SidePanelTab.Settings) tabs.push(SidePanelTab.Activation) diff --git a/frontend/src/layout/navigation/SideBar/SideBar.scss b/frontend/src/layout/navigation/SideBar/SideBar.scss index eb2db9103bb60..32576a7fb18db 100644 --- a/frontend/src/layout/navigation/SideBar/SideBar.scss +++ b/frontend/src/layout/navigation/SideBar/SideBar.scss @@ -31,9 +31,11 @@ // because the sidebar does not affect the rest of the layout on mobile transform: translateX(-15.5rem); } + @include screen($lg) { height: initial; position: relative; + .SideBar--hidden & { margin-left: -15.5rem; } @@ -49,6 +51,7 @@ > ul { overflow: auto; padding: 1rem 0.5rem; + li { margin-top: 1px; } @@ -64,15 +67,15 @@ position: absolute; height: 100%; width: 100%; - background-color: var(--modal-backdrop-color); backdrop-filter: blur(var(--modal-backdrop-blur)); .SideBar--hidden & { background-color: transparent; - backdrop-filter: blur(0px); + backdrop-filter: blur(0); pointer-events: none; } + @include screen($lg) { display: none; } @@ -87,6 +90,7 @@ text-transform: uppercase; letter-spacing: 0.5px; margin-top: 1rem; + &:first-of-type { margin-top: 0; } diff --git a/frontend/src/layout/navigation/TopBar/TopBar.scss b/frontend/src/layout/navigation/TopBar/TopBar.scss index 950c5cfec2565..8e1732a7d2d34 100644 --- a/frontend/src/layout/navigation/TopBar/TopBar.scss +++ b/frontend/src/layout/navigation/TopBar/TopBar.scss @@ -12,6 +12,7 @@ background: var(--bg-bridge); border-bottom: 1px solid var(--border); gap: 1rem; + @include screen($sm) { padding: 0.5rem 1rem; } @@ -63,6 +64,7 @@ .TopBar__lightning-mode-box { background: var(--bridge) !important; + .LemonSwitch__slider { background-color: var(--border) !important; } @@ -112,6 +114,7 @@ cursor: pointer; font-size: 1.25rem; padding: 0.125rem; + @include screen($sm) { right: 1rem; } diff --git a/frontend/src/lib/components/ActivationSidebar/ActivationSidebar.scss b/frontend/src/lib/components/ActivationSidebar/ActivationSidebar.scss index d91b3aee43f33..267ed27a7a08f 100644 --- a/frontend/src/lib/components/ActivationSidebar/ActivationSidebar.scss +++ b/frontend/src/lib/components/ActivationSidebar/ActivationSidebar.scss @@ -28,13 +28,13 @@ right: 0; width: 100%; height: calc(100vh - 3.5rem); - display: flex; flex-direction: column; overflow: scroll; > div > ul { overflow: auto; + li { margin-top: 0.5rem; } diff --git a/frontend/src/lib/components/AddToDashboard/AddToDashboard.scss b/frontend/src/lib/components/AddToDashboard/AddToDashboard.scss deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/frontend/src/lib/components/AddToDashboard/AddToDashboardModal.tsx b/frontend/src/lib/components/AddToDashboard/AddToDashboardModal.tsx index a10f8c35338cc..40303016da557 100644 --- a/frontend/src/lib/components/AddToDashboard/AddToDashboardModal.tsx +++ b/frontend/src/lib/components/AddToDashboard/AddToDashboardModal.tsx @@ -2,7 +2,6 @@ import { Tooltip } from 'lib/lemon-ui/Tooltip' import { useActions, useValues } from 'kea' import { addToDashboardModalLogic } from 'lib/components/AddToDashboard/addToDashboardModalLogic' import { urls } from 'scenes/urls' -import './AddToDashboard.scss' import { IconCottage } from 'lib/lemon-ui/icons' import { LemonInput } from 'lib/lemon-ui/LemonInput/LemonInput' import { List, ListRowProps, ListRowRenderer } from 'react-virtualized/dist/es/List' diff --git a/frontend/src/lib/components/Animation/Animation.scss b/frontend/src/lib/components/Animation/Animation.scss index 3799b7dbf77e2..f60434aba11bb 100644 --- a/frontend/src/lib/components/Animation/Animation.scss +++ b/frontend/src/lib/components/Animation/Animation.scss @@ -1,11 +1,11 @@ .Animation { max-width: 300px; + // A correct aspect-ratio is be passed via a style prop. This is as a fallback. aspect-ratio: 1 / 1; overflow: hidden; opacity: 1; transition: 400ms ease opacity; - display: inline-flex; align-items: center; justify-content: center; @@ -18,6 +18,7 @@ display: block; width: 100%; height: 100%; + svg { display: block; } diff --git a/frontend/src/lib/components/AnnotationsOverlay/AnnotationsOverlay.scss b/frontend/src/lib/components/AnnotationsOverlay/AnnotationsOverlay.scss index 65ee0e5fade2a..51423b115d892 100644 --- a/frontend/src/lib/components/AnnotationsOverlay/AnnotationsOverlay.scss +++ b/frontend/src/lib/components/AnnotationsOverlay/AnnotationsOverlay.scss @@ -19,7 +19,7 @@ background: none; transform: translate(-50%, -50%); cursor: pointer; - -webkit-appearance: none !important; + appearance: none !important; > .LemonBadge { transition: transform 200ms ease; // Same as LemonBadge's transition @@ -31,6 +31,7 @@ .AnnotationsPopover { --annotations-popover-width: 30rem; + transition: left 200ms ease, opacity 100ms ease, transform 100ms ease; z-index: var(--z-annotation-popover) !important; @@ -55,6 +56,7 @@ .profile-package { vertical-align: bottom; } + h5 { margin: 0; } diff --git a/frontend/src/lib/components/BridgePage/BridgePage.scss b/frontend/src/lib/components/BridgePage/BridgePage.scss index e44d8333cf4a7..fca0fc8ef9599 100644 --- a/frontend/src/lib/components/BridgePage/BridgePage.scss +++ b/frontend/src/lib/components/BridgePage/BridgePage.scss @@ -7,9 +7,11 @@ flex-direction: column; flex: 1; overflow: scroll; + &::-webkit-scrollbar { width: 0 !important; } + -ms-overflow-style: none; .BridgePage__main { @@ -83,7 +85,7 @@ font-size: 0.8em; font-weight: 600; - &:after { + &::after { position: absolute; top: 100%; left: 20px; @@ -104,7 +106,7 @@ &.BridgePage__left__message--enter-active, &.BridgePage__left__message--enter-done { opacity: 1; - transform: translateY(0px) rotate(5deg) scale(1); + transform: translateY(0) rotate(5deg) scale(1); transition: 200ms opacity, 200ms transform; } @@ -126,13 +128,16 @@ .BridgePage__header-logo { &.mobile { display: block; + @include screen($md) { display: none; } } + .header-logo { padding-bottom: 3rem; text-align: center; + img { height: 24px; } diff --git a/frontend/src/lib/components/Cards/CardMeta.scss b/frontend/src/lib/components/Cards/CardMeta.scss index ae3d46fb9efd9..779e07abfc0d5 100644 --- a/frontend/src/lib/components/Cards/CardMeta.scss +++ b/frontend/src/lib/components/Cards/CardMeta.scss @@ -9,19 +9,24 @@ height: 100%; pointer-events: none; z-index: var(--z-raised); + &.horizontal { svg { transform: rotate(90deg) translateX(0.75rem); } } + &.vertical { flex-direction: column; + svg { transform: translateX(0.5rem); } } + &.corner { justify-content: flex-end; + svg { transform: translate(0.5rem, 0.5rem); } @@ -41,11 +46,13 @@ z-index: 101; // Elevate above viz overflow: hidden; border-radius: var(--radius); + h5 { color: var(--muted); line-height: 1.5rem; margin-bottom: 0; } + h4 { overflow: hidden; text-overflow: ellipsis; @@ -59,6 +66,7 @@ .CardMeta--with-details { padding: 1rem; + .CardMeta__top { // Reduced height so that, considering the padding set above, CardMeta__top doesn't have too much margin height: 1.5rem; @@ -71,16 +79,19 @@ .CardMeta--expansion-exit { transition: box-shadow 200ms ease, height 200ms ease; } + .CardMeta--expansion-exit.CardMeta--expansion-exit-active, .CardMeta--expansion-exit-done, .CardMeta--expansion-enter { box-shadow: none; } + .CardMeta--expansion-enter.CardMeta--expansion-enter-active, .CardMeta--expansion-enter-done, .CardMeta--expansion-exit { box-shadow: var(--shadow-elevation); } + .CardMeta--expansion-enter-done { overflow: auto; } @@ -100,12 +111,15 @@ &.blue { background: var(--blue); } + &.purple { background: var(--purple); } + &.green { background: var(--green); } + &.black { background: var(--black); } @@ -118,6 +132,7 @@ width: 100%; height: fit-content; min-height: 2rem; + > * { max-width: 100%; // Make sure that horizontal overflow is capped, so that ellipsis on insight name works } diff --git a/frontend/src/lib/components/Cards/InsightCard/InsightCard.scss b/frontend/src/lib/components/Cards/InsightCard/InsightCard.scss index 8176646fac6e3..8ab685214c862 100644 --- a/frontend/src/lib/components/Cards/InsightCard/InsightCard.scss +++ b/frontend/src/lib/components/Cards/InsightCard/InsightCard.scss @@ -8,10 +8,12 @@ border: 1px solid var(--border); z-index: 3; background: var(--bg-light); + &--highlighted { border-color: var(--primary); outline: 1px solid var(--primary); } + .ant-alert { margin: 1rem; width: 100%; @@ -29,19 +31,23 @@ min-height: 0; width: 100%; overflow: auto; + .LineGraph, .AnnotationsOverlay { padding: 1rem; } + .insight-empty-state { height: 100%; // Fix wonkiness when SpinnerOverlay is shown font-size: 0.875rem; // Reduce font size padding-top: 0; padding-bottom: 0; } + > :first-child { margin-top: auto; } + > :last-child { margin-bottom: auto; } @@ -50,12 +56,15 @@ .InsightDetails { font-size: 0.8125rem; line-height: 1.5rem; + h5 { margin-bottom: 0.125rem; } + section:not(:last-child) { margin-bottom: 0.5rem; } + .LemonRow { min-height: 2rem; font-size: inherit; @@ -67,6 +76,7 @@ padding: 0.5rem; border-radius: var(--radius); background: var(--side); + .LemonRow { padding-left: 0; padding-right: 0; @@ -82,9 +92,11 @@ .InsightDetails__series { margin: -0.125rem 0; + &:not(:first-child) { margin-top: 0.5rem; } + .LemonDivider { width: calc(100% - 1.5rem); margin-left: 1.5rem; @@ -104,13 +116,16 @@ .InsightDetails__footer { display: grid; grid-template-columns: repeat(2, 1fr); + .profile-package { vertical-align: middle; } + .tz-label { line-height: normal; vertical-align: middle; } + .taxonomic-breakdown-filter.tag-pill { font-size: 0.8125rem; padding: 0; @@ -136,9 +151,11 @@ font-size: 0.6875rem; font-weight: 600; line-height: 1rem; + &.SeriesDisplay__raw-name--action, &.SeriesDisplay__raw-name--event { padding: 0.25rem; + &::before { display: inline-block; flex-shrink: 0; @@ -153,9 +170,11 @@ font-weight: 700; } } + &.SeriesDisplay__raw-name--action::before { content: 'A'; } + &.SeriesDisplay__raw-name--event::before { content: 'E'; } diff --git a/frontend/src/lib/components/CodeSnippet/CodeSnippet.scss b/frontend/src/lib/components/CodeSnippet/CodeSnippet.scss index f7d40aaf1a9b5..4fb411ba56520 100644 --- a/frontend/src/lib/components/CodeSnippet/CodeSnippet.scss +++ b/frontend/src/lib/components/CodeSnippet/CodeSnippet.scss @@ -1,19 +1,23 @@ .CodeSnippet { position: relative; font-size: 0.875rem; + &.CodeSnippet--compact { font-size: 0.8125rem; + .CodeSnippet__actions { top: 0.375rem; right: 0.375rem; } } + .CodeSnippet__actions { position: absolute; display: flex; top: 0.25rem; right: 0.25rem; gap: 0.5rem; + .LemonButton .LemonIcon { color: #fff; } diff --git a/frontend/src/lib/components/CommandPalette/CommandPalette.scss b/frontend/src/lib/components/CommandPalette/CommandPalette.scss index 1ef01681263c1..0972ea918e81e 100644 --- a/frontend/src/lib/components/CommandPalette/CommandPalette.scss +++ b/frontend/src/lib/components/CommandPalette/CommandPalette.scss @@ -29,6 +29,7 @@ max-height: 80%; width: 100%; } + @media (max-height: 500px) { top: 0%; max-height: 100%; @@ -84,6 +85,7 @@ .palette__result--focused { background: var(--default-dark); + &::before, &::after { content: ''; @@ -93,24 +95,27 @@ bottom: 0; width: 0.375rem; } + &::before { - background: hsla(210, 10%, 19%, 1) !important; + background: hsl(210deg 10% 19% / 100%) !important; } + &::after { - background: rgba(255, 255, 255, 0.1); + background: rgb(255 255 255 / 10%); } } .palette__result--executable { cursor: pointer; + &::after { background: var(--primary); } } .palette__scope { - background-color: rgba(255, 255, 255, 0.1); - color: rgba(255, 255, 255, 0.8); + background-color: rgb(255 255 255 / 10%); + color: rgb(255 255 255 / 80%); } .palette__icon { diff --git a/frontend/src/lib/components/CompactList/CompactList.scss b/frontend/src/lib/components/CompactList/CompactList.scss index 13dfe6b0dd1b2..cd329a1d8e4f7 100644 --- a/frontend/src/lib/components/CompactList/CompactList.scss +++ b/frontend/src/lib/components/CompactList/CompactList.scss @@ -13,6 +13,7 @@ display: flex; align-items: center; justify-content: space-between; + h3 { margin-bottom: 0; font-weight: 600; @@ -27,8 +28,7 @@ .scrollable-list { flex: 1; - overflow-y: auto; - overflow-x: auto; + overflow: auto auto; padding: 0 0.5rem 0.5rem; } } diff --git a/frontend/src/lib/components/CompareFilter/CompareFilter.tsx b/frontend/src/lib/components/CompareFilter/CompareFilter.tsx index e3ecfa66a82ab..02d2ad2e91f4b 100644 --- a/frontend/src/lib/components/CompareFilter/CompareFilter.tsx +++ b/frontend/src/lib/components/CompareFilter/CompareFilter.tsx @@ -1,12 +1,15 @@ import { useValues, useActions } from 'kea' -import { compareFilterLogic } from './compareFilterLogic' import { insightLogic } from 'scenes/insights/insightLogic' import { LemonCheckbox } from '@posthog/lemon-ui' +import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic' export function CompareFilter(): JSX.Element | null { - const { insightProps } = useValues(insightLogic) - const { compare, disabled } = useValues(compareFilterLogic(insightProps)) - const { setCompare } = useActions(compareFilterLogic(insightProps)) + const { insightProps, canEditInsight } = useValues(insightLogic) + + const { compare, supportsCompare } = useValues(insightVizDataLogic(insightProps)) + const { updateInsightFilter } = useActions(insightVizDataLogic(insightProps)) + + const disabled: boolean = !canEditInsight || !supportsCompare // Hide compare filter control when disabled to avoid states where control is "disabled but checked" if (disabled) { @@ -15,9 +18,10 @@ export function CompareFilter(): JSX.Element | null { return ( { + updateInsightFilter({ compare }) + }} checked={!!compare} - disabled={disabled} label={Compare to previous period} bordered size="small" diff --git a/frontend/src/lib/components/CompareFilter/compareFilterLogic.ts b/frontend/src/lib/components/CompareFilter/compareFilterLogic.ts deleted file mode 100644 index 899d545987442..0000000000000 --- a/frontend/src/lib/components/CompareFilter/compareFilterLogic.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { kea, props, key, path, connect, actions, selectors, listeners } from 'kea' -import { ChartDisplayType, InsightLogicProps } from '~/types' -import type { compareFilterLogicType } from './compareFilterLogicType' -import { keyForInsightLogicProps } from 'scenes/insights/sharedUtils' -import { insightLogic } from 'scenes/insights/insightLogic' -import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic' - -export const compareFilterLogic = kea([ - props({} as InsightLogicProps), - key(keyForInsightLogicProps('new')), - path((key) => ['lib', 'components', 'CompareFilter', 'compareFilterLogic', key]), - connect((props: InsightLogicProps) => ({ - values: [ - insightLogic(props), - ['canEditInsight'], - insightVizDataLogic(props), - ['compare', 'display', 'insightFilter', 'isLifecycle', 'dateRange'], - ], - actions: [insightVizDataLogic(props), ['updateInsightFilter']], - })), - actions(() => ({ - setCompare: (compare: boolean) => ({ compare }), - toggleCompare: true, - })), - selectors({ - disabled: [ - (s) => [s.canEditInsight, s.isLifecycle, s.display, s.dateRange], - (canEditInsight, isLifecycle, display, dateRange) => - !canEditInsight || - isLifecycle || - display === ChartDisplayType.WorldMap || - dateRange?.date_from === 'all', - ], - }), - listeners(({ values, actions }) => ({ - setCompare: ({ compare }) => { - actions.updateInsightFilter({ compare }) - }, - toggleCompare: () => { - actions.setCompare(!values.compare) - }, - })), -]) diff --git a/frontend/src/lib/components/DateFilter/RollingDateRangeFilter.scss b/frontend/src/lib/components/DateFilter/RollingDateRangeFilter.scss index 99352b932cb9c..8f99bb64c0bde 100644 --- a/frontend/src/lib/components/DateFilter/RollingDateRangeFilter.scss +++ b/frontend/src/lib/components/DateFilter/RollingDateRangeFilter.scss @@ -17,13 +17,13 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { - -webkit-appearance: none; + appearance: none; margin: 0; } /* Firefox */ input[type='number'] { - -moz-appearance: textfield; + appearance: textfield; } } @@ -40,8 +40,6 @@ border-radius: 0.25rem; background-color: var(--bg-light); box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; margin-right: 0.25rem; margin-left: 0.25rem; line-height: 1.25rem; @@ -56,6 +54,7 @@ margin: 0 0.25rem; border-radius: var(--radius); padding: 0.25rem; + &:hover { background-color: var(--primary-highlight); } diff --git a/frontend/src/lib/components/DatePicker.scss b/frontend/src/lib/components/DatePicker.scss index 0ac7693630d02..21ec676273bc1 100644 --- a/frontend/src/lib/components/DatePicker.scss +++ b/frontend/src/lib/components/DatePicker.scss @@ -7,25 +7,34 @@ color: var(--default); background: var(--secondary-3000); border-color: transparent; + .ant-picker-suffix { color: var(--default); } } + .ant-picker-panel-container { color: var(--default); background: var(--bg-3000); border: 1px solid var(--border); + * { border-color: var(--border); } } + .ant-picker-time-panel-column > li.ant-picker-time-panel-cell-selected .ant-picker-time-panel-cell-inner { background: var(--primary-3000); } + .ant-picker-cell:hover:not(.ant-picker-cell-in-view) .ant-picker-cell-inner, - .ant-picker-cell:hover:not(.ant-picker-cell-selected):not(.ant-picker-cell-range-start):not( - .ant-picker-cell-range-end - ):not(.ant-picker-cell-range-hover-start):not(.ant-picker-cell-range-hover-end) + .ant-picker-cell:hover:not( + .ant-picker-cell-selected, + .ant-picker-cell-range-start, + .ant-picker-cell-range-end, + .ant-picker-cell-range-hover-start, + .ant-picker-cell-range-hover-end + ) .ant-picker-cell-inner, .ant-picker-time-panel-column > li.ant-picker-time-panel-cell .ant-picker-time-panel-cell-inner:hover { background: var(--secondary-3000); diff --git a/frontend/src/lib/components/DefinitionPopover/DefinitionPopover.scss b/frontend/src/lib/components/DefinitionPopover/DefinitionPopover.scss index fa50237972939..664020d434acf 100644 --- a/frontend/src/lib/components/DefinitionPopover/DefinitionPopover.scss +++ b/frontend/src/lib/components/DefinitionPopover/DefinitionPopover.scss @@ -1,6 +1,6 @@ .definition-popover { width: 20rem; - padding: 0.5rem 0.75rem 0.75rem 0.75rem; + padding: 0.5rem 0.75rem 0.75rem; .definition-popover-header { display: flex; @@ -94,6 +94,7 @@ .definition-popover-timemeta-user { display: inline-flex; } + .definition-popover-timemeta-spacer { margin-right: 0.5rem; } diff --git a/frontend/src/lib/components/EditableField/EditableField.scss b/frontend/src/lib/components/EditableField/EditableField.scss index e853c9c625741..c58f63e9d2114 100644 --- a/frontend/src/lib/components/EditableField/EditableField.scss +++ b/frontend/src/lib/components/EditableField/EditableField.scss @@ -2,17 +2,21 @@ display: flex; align-items: center; max-width: 100%; + &:not(.EditableField--multiline) { line-height: 2rem; } + i { color: var(--muted); } + .EditableField__notice { font-size: 1.5rem; color: var(--muted); margin-left: 0.5rem; } + .EditableField__highlight { display: flex; flex-direction: row; @@ -25,6 +29,7 @@ white-space: pre-wrap; overflow: auto; } + &--editing .EditableField__highlight { flex-grow: 1; align-items: flex-end; @@ -33,10 +38,12 @@ outline: 1px solid var(--border); border-radius: var(--radius); } + .EditableField__autosize { align-self: center; min-width: 0; } + .EditableField__autosize__sizer { position: absolute; top: 0; @@ -46,6 +53,7 @@ overflow: scroll; white-space: pre; } + .EditableField__actions { flex-shrink: 0; display: flex; @@ -53,6 +61,7 @@ gap: 0.5rem; margin-left: 0.5rem; } + input, textarea { max-width: 100%; @@ -63,6 +72,7 @@ outline: none; padding: 0; } + textarea { align-self: center; width: 100%; diff --git a/frontend/src/lib/components/EmptyMessage/EmptyMessage.scss b/frontend/src/lib/components/EmptyMessage/EmptyMessage.scss index a338a5a94800c..beebb4188566a 100644 --- a/frontend/src/lib/components/EmptyMessage/EmptyMessage.scss +++ b/frontend/src/lib/components/EmptyMessage/EmptyMessage.scss @@ -8,6 +8,7 @@ .title { text-align: center; } + .description { text-align: center; } diff --git a/frontend/src/lib/components/Fade/Fade.scss b/frontend/src/lib/components/Fade/Fade.scss index ae50db416ae05..3a37304c0f8e1 100644 --- a/frontend/src/lib/components/Fade/Fade.scss +++ b/frontend/src/lib/components/Fade/Fade.scss @@ -1,16 +1,18 @@ -@keyframes fadeComponentFadeIn { +@keyframes Fade__fade-in { 0% { opacity: 0; } + 100% { opacity: 1; } } -@keyframes fadeComponentFadeOut { +@keyframes Fade__fade-out { 0% { opacity: 1; } + 100% { opacity: 0; } diff --git a/frontend/src/lib/components/Fade/Fade.tsx b/frontend/src/lib/components/Fade/Fade.tsx index d611ead1591a0..cc4637bb26957 100644 --- a/frontend/src/lib/components/Fade/Fade.tsx +++ b/frontend/src/lib/components/Fade/Fade.tsx @@ -31,7 +31,7 @@ export function Fade({
diff --git a/frontend/src/lib/components/HTMLElementsDisplay/SelectableElement.scss b/frontend/src/lib/components/HTMLElementsDisplay/SelectableElement.scss index 8221fb35faf4d..17b0dded01c1d 100644 --- a/frontend/src/lib/components/HTMLElementsDisplay/SelectableElement.scss +++ b/frontend/src/lib/components/HTMLElementsDisplay/SelectableElement.scss @@ -6,9 +6,11 @@ &.SelectableElement--selected { background: var(--primary); } + &:hover { background: var(--primary-light); } + &:active { background: var(--primary-dark); } diff --git a/frontend/src/lib/components/HedgehogBuddy/HedgehogBuddy.scss b/frontend/src/lib/components/HedgehogBuddy/HedgehogBuddy.scss index 8c9452943f1f3..a16ea6a598aae 100644 --- a/frontend/src/lib/components/HedgehogBuddy/HedgehogBuddy.scss +++ b/frontend/src/lib/components/HedgehogBuddy/HedgehogBuddy.scss @@ -4,7 +4,7 @@ cursor: pointer; margin: 0; - &:after { + &::after { // Hack for preloading images position: absolute; width: 0; diff --git a/frontend/src/lib/components/InsightLabel/InsightLabel.scss b/frontend/src/lib/components/InsightLabel/InsightLabel.scss index dfc7d94f59df0..811e8e1456c8e 100644 --- a/frontend/src/lib/components/InsightLabel/InsightLabel.scss +++ b/frontend/src/lib/components/InsightLabel/InsightLabel.scss @@ -25,7 +25,7 @@ border-radius: 50%; margin-left: 2px; margin-right: 6px; - border: 2px solid #ffffff; + border: 2px solid #fff; box-sizing: border-box; } } diff --git a/frontend/src/lib/components/Map/Maplibre.scss b/frontend/src/lib/components/Map/Maplibre.scss index 27a9336e839ca..f4c4cdeb2fda7 100644 --- a/frontend/src/lib/components/Map/Maplibre.scss +++ b/frontend/src/lib/components/Map/Maplibre.scss @@ -11,6 +11,7 @@ .maplibregl-ctrl-attrib .maplibregl-ctrl-attrib-button { background-color: var(--bg-3000); + [theme='dark'] & { background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='white' width='24' height='24' fill-rule='evenodd' viewBox='0 0 20 20'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E"); } @@ -18,6 +19,7 @@ .maplibregl-ctrl-attrib.maplibregl-compact-show .maplibregl-ctrl-attrib-button { background-color: var(--bg-3000); + [theme='dark'] & { background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='white' width='24' height='24' fill-rule='evenodd' viewBox='0 0 20 20'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E"); } diff --git a/frontend/src/lib/components/NotFound/NotFound.scss b/frontend/src/lib/components/NotFound/NotFound.scss index d9a3d97ced82f..1d8d678a36110 100644 --- a/frontend/src/lib/components/NotFound/NotFound.scss +++ b/frontend/src/lib/components/NotFound/NotFound.scss @@ -1,6 +1,5 @@ .NotFoundComponent { text-align: center; - margin-top: 2rem; margin: 6rem auto; max-width: 600px; diff --git a/frontend/src/lib/components/PropertiesTable/PropertiesTable.scss b/frontend/src/lib/components/PropertiesTable/PropertiesTable.scss index fcf66fec67796..2ec1fd268b87f 100644 --- a/frontend/src/lib/components/PropertiesTable/PropertiesTable.scss +++ b/frontend/src/lib/components/PropertiesTable/PropertiesTable.scss @@ -20,6 +20,7 @@ text-transform: uppercase; white-space: nowrap; cursor: default; + &:not(:first-child) { margin-left: 0.25rem; } @@ -35,6 +36,7 @@ > * { vertical-align: middle; } + > svg { margin-left: 0.25rem; font-size: 1rem; diff --git a/frontend/src/lib/components/PropertyFilters/PropertyFilters.scss b/frontend/src/lib/components/PropertyFilters/PropertyFilters.scss index 0470d5da983f5..51a33cfeeec3e 100644 --- a/frontend/src/lib/components/PropertyFilters/PropertyFilters.scss +++ b/frontend/src/lib/components/PropertyFilters/PropertyFilters.scss @@ -14,7 +14,7 @@ color: #c4c4c4; font-size: 18px; user-select: none; - padding: 0px 5px; + padding: 0 5px; } .logical-row-divider { @@ -23,7 +23,7 @@ text-transform: uppercase; align-items: flex-start; margin-top: 0.5rem; - margin-bottom: 0px; + margin-bottom: 0; &::before, &::after { diff --git a/frontend/src/lib/components/PropertyFilters/components/PropertyValue.scss b/frontend/src/lib/components/PropertyFilters/components/PropertyValue.scss index 7834113d53f3f..0a33bc26c1aae 100644 --- a/frontend/src/lib/components/PropertyFilters/components/PropertyValue.scss +++ b/frontend/src/lib/components/PropertyFilters/components/PropertyValue.scss @@ -29,7 +29,7 @@ background-color: inherit; .ant-select-selection-search { - padding-left: 0px !important; + padding-left: 0 !important; } .ant-select-selection-placeholder { diff --git a/frontend/src/lib/components/PropertyGroupFilters/PropertyGroupFilters.scss b/frontend/src/lib/components/PropertyGroupFilters/PropertyGroupFilters.scss index 6bfa3e13ada30..b30e128738345 100644 --- a/frontend/src/lib/components/PropertyGroupFilters/PropertyGroupFilters.scss +++ b/frontend/src/lib/components/PropertyGroupFilters/PropertyGroupFilters.scss @@ -7,12 +7,12 @@ .property-group-and-or-separator { color: var(--primary-alt); - padding: 0.5rem 0px; + padding: 0.5rem 0; font-size: 12px; font-weight: 600; position: relative; - &:before { + &::before { position: absolute; left: 17px; top: 0; diff --git a/frontend/src/lib/components/PropertyKeyInfo.scss b/frontend/src/lib/components/PropertyKeyInfo.scss index 23a2e43a5e18c..693cc701c17ea 100644 --- a/frontend/src/lib/components/PropertyKeyInfo.scss +++ b/frontend/src/lib/components/PropertyKeyInfo.scss @@ -31,8 +31,10 @@ .PropertyKeyInfo__overlay { padding: 0.25rem; + p { margin-bottom: 0.25rem; + &:last-child { margin-bottom: 0; } diff --git a/frontend/src/lib/components/Resizer/Resizer.scss b/frontend/src/lib/components/Resizer/Resizer.scss index 4fa7711683239..52df99380745f 100644 --- a/frontend/src/lib/components/Resizer/Resizer.scss +++ b/frontend/src/lib/components/Resizer/Resizer.scss @@ -1,5 +1,6 @@ .Resizer { --resizer-width: 8px; + position: absolute; top: 0; bottom: 0; @@ -17,8 +18,8 @@ .Resizer__handle { position: absolute; left: calc(var(--resizer-width) / 2); - top: 0px; - bottom: 0px; + top: 0; + bottom: 0; width: 1px; &::before, @@ -35,6 +36,7 @@ transition: 100ms ease transform; background: var(--border); } + &::after { transition: 100ms ease transform; background: var(--text-3000); @@ -43,19 +45,20 @@ } &--left { - left: 0px; + left: 0; transform: translateX(calc(var(--resizer-width) / 2 * -1)); } &--right { - right: 0px; - transform: translateX(calc(var(--resizer-width) / 2 * +1)); + right: 0; + transform: translateX(calc(var(--resizer-width) / 2 * 1)); } &:hover .Resizer__handle::after, &--resizing .Resizer__handle::after { opacity: 0.25; } + &--resizing .Resizer__handle::before, &--resizing .Resizer__handle::after { transform: scaleX(3); diff --git a/frontend/src/lib/components/SelectGradientOverflow.scss b/frontend/src/lib/components/SelectGradientOverflow.scss index c1c81e4405e4f..c583519744598 100644 --- a/frontend/src/lib/components/SelectGradientOverflow.scss +++ b/frontend/src/lib/components/SelectGradientOverflow.scss @@ -3,10 +3,12 @@ .ant-select-dropdown { .scrollable-above::after { @extend %mixin-gradient-overlay; - background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)); + + background: linear-gradient(to bottom, rgb(255 255 255 / 100%), rgb(255 255 255 / 0%)); bottom: unset; top: 0; } + .scrollable-below::after { @extend %mixin-gradient-overlay; } @@ -17,9 +19,7 @@ margin: 1px 4px 1px 0; display: flex; align-items: center; - flex-basis: auto; - flex-grow: 0; - flex-shrink: 0; + flex: 0 0 auto; overflow: hidden; padding: 0 4px 0 8px; font-size: inherit; @@ -27,17 +27,21 @@ background: #f5f5f5; border: 1px solid #f0f0f0; user-select: none; + .label { overflow: hidden; text-overflow: ellipsis; } + .btn-close { font-size: 10px; margin-left: 4px; + .anticon-close { - color: rgba(0, 0, 0, 0.45); + color: rgb(0 0 0 / 45%); + & :hover { - color: rgba(0, 0, 0, 0.75); + color: rgb(0 0 0 / 75%); } } } diff --git a/frontend/src/lib/components/TaxonomicFilter/TaxonomicFilter.scss b/frontend/src/lib/components/TaxonomicFilter/TaxonomicFilter.scss index 11bf7380ce829..98f01dd22f7c5 100644 --- a/frontend/src/lib/components/TaxonomicFilter/TaxonomicFilter.scss +++ b/frontend/src/lib/components/TaxonomicFilter/TaxonomicFilter.scss @@ -30,6 +30,7 @@ padding-top: 10px; padding-left: 10px; font-weight: 600; + &.with-border { border-top: 1px solid var(--border-light); } @@ -48,10 +49,12 @@ color: var(--link); background: var(--side); border-color: var(--side); + &.taxonomic-count-zero { color: var(--muted); cursor: not-allowed; } + &.taxonomic-pill-active { color: #fff; background: var(--link); diff --git a/frontend/src/lib/components/TimelineSeekbar/TimelineSeekbar.scss b/frontend/src/lib/components/TimelineSeekbar/TimelineSeekbar.scss index 4774449703e18..d0ac9a6fe4220 100644 --- a/frontend/src/lib/components/TimelineSeekbar/TimelineSeekbar.scss +++ b/frontend/src/lib/components/TimelineSeekbar/TimelineSeekbar.scss @@ -2,6 +2,7 @@ --timeline-seekbar-thickness: 0.125rem; --timeline-seekbar-arrow-width: 0.5rem; --timeline-seekbar-arrow-height: 0.75rem; + margin: 0.75rem 0.5rem; } @@ -27,9 +28,11 @@ line-height: 1.25rem; font-size: 0.75rem; font-weight: 500; + &::selection { background: var(--primary-light); // Default selection background is invisible on primary } + .Spinner { margin-right: 0.25rem; } @@ -48,6 +51,7 @@ top: 0; left: calc(var(--timeline-seekbar-thickness) * 2); width: calc(100% - var(--timeline-seekbar-arrow-width) - var(--timeline-seekbar-thickness) * 3 - 1.25rem); + .LemonBadge:not(.LemonBadge--active) { // Connect each badge to the line rightward to signal the direction in which the badge is applicable border-right-color: transparent; @@ -61,6 +65,7 @@ left: calc(var(--timeline-seekbar-section-progress-current) - var(--timeline-seekbar-thickness)); width: var(--timeline-seekbar-section-progress-next); border-left: var(--timeline-seekbar-thickness) solid var(--bg-light); + &:last-child { width: calc(var(--timeline-seekbar-section-progress-next) + 1.25rem); } @@ -80,6 +85,7 @@ position: absolute; top: calc(var(--timeline-seekbar-thickness) / 2 - 0.625rem); height: 1.25rem; + &::before { content: ''; display: block; @@ -98,6 +104,7 @@ left: 100%; width: var(--timeline-seekbar-arrow-width); cursor: pointer; + &::before { clip-path: polygon(0 0, 100% 50%, 0 100%); } diff --git a/frontend/src/lib/components/UniversalSearch/UniversalSearch.scss b/frontend/src/lib/components/UniversalSearch/UniversalSearch.scss index a135232f9a8a8..64f84a90265df 100644 --- a/frontend/src/lib/components/UniversalSearch/UniversalSearch.scss +++ b/frontend/src/lib/components/UniversalSearch/UniversalSearch.scss @@ -4,8 +4,8 @@ max-width: 15rem; height: 100%; cursor: pointer; - transition: 200ms ease margin; + .ant-input-affix-wrapper, input { background: var(--bg-bridge); diff --git a/frontend/src/lib/constants.tsx b/frontend/src/lib/constants.tsx index 4e12e485db46e..be9079da1ad3f 100644 --- a/frontend/src/lib/constants.tsx +++ b/frontend/src/lib/constants.tsx @@ -173,7 +173,6 @@ export const FEATURE_FLAGS = { NOTEBOOK_CANVASES: 'notebook-canvases', // owner: #team-monitoring SESSION_RECORDING_SAMPLING: 'session-recording-sampling', // owner: #team-monitoring PERSON_FEED_CANVAS: 'person-feed-canvas', // owner: #project-canvas - SIDE_PANEL_DOCS: 'side-panel-docs', // owner: #noteforce-3000 MULTI_PROJECT_FEATURE_FLAGS: 'multi-project-feature-flags', // owner: @jurajmajerik #team-feature-success NETWORK_PAYLOAD_CAPTURE: 'network-payload-capture', // owner: #team-monitoring } as const diff --git a/frontend/src/lib/lemon-ui/LemonActionableTooltip/LemonActionableTooltip.scss b/frontend/src/lib/lemon-ui/LemonActionableTooltip/LemonActionableTooltip.scss index 46fc8856b62d6..7a5d1c1db4b74 100644 --- a/frontend/src/lib/lemon-ui/LemonActionableTooltip/LemonActionableTooltip.scss +++ b/frontend/src/lib/lemon-ui/LemonActionableTooltip/LemonActionableTooltip.scss @@ -1,58 +1,71 @@ .LemonActionableTooltip { max-width: var(--in-app-prompts-width); padding: 0.5rem; + > * + * { margin-top: 0.5rem; } + .LemonActionableTooltip__header { display: flex; justify-content: space-between; + > * + * { margin-left: 0.5rem; } } + .LemonActionableTooltip__title { font-size: 1.125rem; font-weight: 500; line-height: 1.75rem; } + .LemonActionableTooltip__icon { color: var(--primary); display: flex; align-items: center; width: 1.5rem; height: 1.5rem; + > svg { width: 100%; height: 100%; } } + .LemonActionableTooltip__body { > * + * { margin-top: 0.5rem; } } + .LemonActionableTooltip__footer { display: flex; justify-content: space-between; margin-top: 1rem; } + .LemonActionableTooltip__url-buttons { display: flex; width: 100%; flex-direction: column; + > * + * { margin-top: 0.25rem; } } + .LemonActionableTooltip__action-buttons { display: flex; width: 100%; flex-direction: column; + > * + * { margin-top: 0.25rem; } } + .LemonActionableTooltip__navigation { color: var(--muted); display: flex; diff --git a/frontend/src/lib/lemon-ui/LemonBadge/LemonBadge.scss b/frontend/src/lib/lemon-ui/LemonBadge/LemonBadge.scss index f3737f96455cb..186df996abe84 100644 --- a/frontend/src/lib/lemon-ui/LemonBadge/LemonBadge.scss +++ b/frontend/src/lib/lemon-ui/LemonBadge/LemonBadge.scss @@ -17,6 +17,7 @@ height: var(--lemon-badge-size); font-size: var(--lemon-badge-font-size); line-height: var(--lemon-badge-size); + // Just enough so the overall size is unaffected with a single digit (i.e. badge stays round) padding: calc(var(--lemon-badge-size) / 8); border-radius: calc(var(--lemon-badge-size) / 2); diff --git a/frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss b/frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss index 6c1b7ea66fb3e..d683e23796f6f 100644 --- a/frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss +++ b/frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss @@ -1,5 +1,6 @@ .LemonButton { --lemon-button-height: 2.5rem; + position: relative; transition: background-color 200ms ease, color 200ms ease, border 200ms ease, opacity 200ms ease, transform 100ms ease; @@ -20,7 +21,7 @@ font-weight: 500; cursor: pointer; user-select: none; - -webkit-appearance: none !important; // Important as this gets overridden by Ant styles... + appearance: none !important; // Important as this gets overridden by Ant styles... .LemonButton__content { flex: 1; @@ -51,6 +52,7 @@ &.LemonButton--centered { justify-content: center; + .LemonButton__content { flex: initial; text-align: center; @@ -60,6 +62,7 @@ &.LemonButton--has-icon { padding-left: 0.5rem; } + &.LemonButton--has-side-icon { padding-right: 0.5rem; } @@ -71,6 +74,7 @@ &.LemonButton--xsmall { --lemon-button-height: 1.5rem; + padding: 0.125rem 0.375rem; gap: 0.25rem; font-size: 0.75rem; @@ -93,6 +97,7 @@ &.LemonButton--small, .Breadcrumbs3000 & { --lemon-button-height: 2rem; + padding: 0.125rem 0.5rem; gap: 0.25rem; @@ -113,6 +118,7 @@ &.LemonButton--large { --lemon-button-height: 3.5rem; + padding: 0.5rem 1rem; gap: 0.75rem; font-size: 1rem; @@ -204,8 +210,10 @@ &.LemonButton--active { background: var(--#{$status}-highlight, var(--primary-highlight)); } + &:not([aria-disabled='true']):active { color: var(--#{$status}-dark, var(--primary-dark)); + .LemonButton__icon { color: var(--#{$status}-dark, var(--primary-dark)); } @@ -219,6 +227,7 @@ &.LemonButton--primary { color: #fff; background: var(--#{$status}); + .LemonButton__icon { color: #fff; } @@ -227,13 +236,16 @@ &.LemonButton--active { color: #fff; background: var(--#{$status}-light, var(--#{$status})); + .LemonButton__icon { color: #fff; } } + &:not([aria-disabled='true']):active { background: var(--#{$status}-dark, var(--#{$status})); color: #fff; + .LemonButton__icon { color: #fff; } @@ -261,11 +273,13 @@ .ant-tooltip & { // Buttons have an overriden style in tooltips, as they are always dark &:hover { - background: rgba(255, 255, 255, 0.15) !important; + background: rgb(255 255 255 / 15%) !important; } + &:active { - background: rgba(255, 255, 255, 0.2) !important; + background: rgb(255 255 255 / 20%) !important; } + .LemonButton__icon { color: #fff !important; } @@ -290,11 +304,13 @@ &.LemonButton--primary { color: #fff; background: var(--primary-3000); + &:not([aria-disabled='true']):hover, &.LemonButton--active { background: var(--primary-3000-hover); color: #fff; } + .LemonButton__icon { color: #fff; } @@ -303,11 +319,13 @@ &.LemonButton--secondary { color: var(--default); background: var(--secondary-3000); + &:not([aria-disabled='true']):hover, &.LemonButton--active { background: var(--secondary-3000-hover); color: var(--default); } + .LemonButton__icon { color: var(--default); } @@ -317,6 +335,7 @@ &.LemonButton--active { color: var(--default); background: var(--border); + .LemonButton__icon { color: var(--default); } diff --git a/frontend/src/lib/lemon-ui/LemonCalendar/LemonCalendar.scss b/frontend/src/lib/lemon-ui/LemonCalendar/LemonCalendar.scss index 8d115c78884c6..8df6f4fc1166c 100644 --- a/frontend/src/lib/lemon-ui/LemonCalendar/LemonCalendar.scss +++ b/frontend/src/lib/lemon-ui/LemonCalendar/LemonCalendar.scss @@ -17,17 +17,20 @@ .LemonCalendar__month tr { .LemonButton { &.rounded-none { - border-radius: 0px; + border-radius: 0; } + &.rounded-r-none { - border-top-right-radius: 0px; - border-bottom-right-radius: 0px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; } + &.rounded-l-none { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; } } + .LemonCalendar__today { position: relative; @@ -39,7 +42,7 @@ border-radius: 100%; width: calc(var(--lemon-calendar-today-radius) * 2); height: calc(var(--lemon-calendar-today-radius) * 2); - background: currentcolor; + background: currentColor; } } } diff --git a/frontend/src/lib/lemon-ui/LemonCard/LemonCard.scss b/frontend/src/lib/lemon-ui/LemonCard/LemonCard.scss index 044e7b9f25603..f5fd7cf2493a4 100644 --- a/frontend/src/lib/lemon-ui/LemonCard/LemonCard.scss +++ b/frontend/src/lib/lemon-ui/LemonCard/LemonCard.scss @@ -1,5 +1,6 @@ .LemonCard { transition: 200ms ease; + &.LemonCard--hoverEffect { &:hover { transform: scale(1.01); diff --git a/frontend/src/lib/lemon-ui/LemonCheckbox/LemonCheckbox.scss b/frontend/src/lib/lemon-ui/LemonCheckbox/LemonCheckbox.scss index 560b2ce2c48a3..8ffed36ab0d40 100644 --- a/frontend/src/lib/lemon-ui/LemonCheckbox/LemonCheckbox.scss +++ b/frontend/src/lib/lemon-ui/LemonCheckbox/LemonCheckbox.scss @@ -14,6 +14,7 @@ label { --tick-length: 12.73; // Approximation of tick length, which is (3 + 6) * sqrt(2) --box-color: var(--primary); + display: flex; align-items: center; cursor: pointer; @@ -45,6 +46,7 @@ &.LemonCheckbox--full-width { width: 100%; + label { width: 100%; } @@ -61,7 +63,6 @@ .LemonCheckbox__box { border-color: var(--box-color); - border-color: var(--box-color); } } } @@ -70,10 +71,6 @@ --box-color: var(--primary-dark); } - &.LemonCheckbox--full-width label { - width: 100%; - } - &.LemonCheckbox--checked { label { .LemonCheckbox__box { diff --git a/frontend/src/lib/lemon-ui/LemonCollapse/LemonCollapse.scss b/frontend/src/lib/lemon-ui/LemonCollapse/LemonCollapse.scss index 08c6f340c44bf..7d86dc8538262 100644 --- a/frontend/src/lib/lemon-ui/LemonCollapse/LemonCollapse.scss +++ b/frontend/src/lib/lemon-ui/LemonCollapse/LemonCollapse.scss @@ -12,6 +12,7 @@ display: flex; flex-direction: column; align-items: stretch; + &:not(:last-child) { border-bottom-width: 1px; } diff --git a/frontend/src/lib/lemon-ui/LemonFileInput/LemonFileInput.scss b/frontend/src/lib/lemon-ui/LemonFileInput/LemonFileInput.scss index bba49b00e27b7..1a266d6ba5b08 100644 --- a/frontend/src/lib/lemon-ui/LemonFileInput/LemonFileInput.scss +++ b/frontend/src/lib/lemon-ui/LemonFileInput/LemonFileInput.scss @@ -4,6 +4,7 @@ .FileDropTarget--active::after { --file-drop-target-padding: 0.5rem; + content: ''; position: absolute; top: calc(-1 * var(--file-drop-target-padding)); diff --git a/frontend/src/lib/lemon-ui/LemonInput/LemonInput.scss b/frontend/src/lib/lemon-ui/LemonInput/LemonInput.scss index 30eeee4083802..03943ad9f9bf1 100644 --- a/frontend/src/lib/lemon-ui/LemonInput/LemonInput.scss +++ b/frontend/src/lib/lemon-ui/LemonInput/LemonInput.scss @@ -19,6 +19,7 @@ &:hover:not([aria-disabled='true']) { border-color: var(--primary-light); } + &.LemonInput--focused:not([aria-disabled='true']) { border-color: var(--primary); } @@ -74,6 +75,7 @@ // NOTE Design: Search inputs are given a specific small width max-width: 240px; } + &.LemonInput--full-width { width: 100%; max-width: 100%; diff --git a/frontend/src/lib/lemon-ui/LemonMarkdown/LemonMarkdown.scss b/frontend/src/lib/lemon-ui/LemonMarkdown/LemonMarkdown.scss index 1858e38e78e92..f8ae353f277ac 100644 --- a/frontend/src/lib/lemon-ui/LemonMarkdown/LemonMarkdown.scss +++ b/frontend/src/lib/lemon-ui/LemonMarkdown/LemonMarkdown.scss @@ -1,28 +1,35 @@ .LemonMarkdown { > * { - margin: 0 0 0.5em 0; + margin: 0 0 0.5em; + &:last-child { margin-bottom: 0; } } + ol, ul, dl { padding-left: 1.5em; } + ol { list-style-type: decimal; } + ul { list-style-type: disc; } + strong[level] { // Low-key headings display: block; } + hr { margin: 1em 0; } + h1 { margin-bottom: 0.25em; font-weight: 600; diff --git a/frontend/src/lib/lemon-ui/LemonModal/LemonModal.scss b/frontend/src/lib/lemon-ui/LemonModal/LemonModal.scss index a3f0cae016830..3f99c8ea0f9c5 100644 --- a/frontend/src/lib/lemon-ui/LemonModal/LemonModal.scss +++ b/frontend/src/lib/lemon-ui/LemonModal/LemonModal.scss @@ -1,14 +1,9 @@ .LemonModal__overlay { position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - + inset: 0; transition: background-color var(--modal-transition-time) ease-out, backdrop-filter var(--modal-transition-time) ease-out; z-index: var(--z-modal); - display: flex; align-items: center; justify-content: center; @@ -24,7 +19,7 @@ &.ReactModal__Overlay--before-close { background-color: transparent; - backdrop-filter: blur(0px); + backdrop-filter: blur(0); } } @@ -62,13 +57,15 @@ transform: scale(1); opacity: 1; } + .LemonModal__close { position: absolute; top: 1.25rem; right: 1.25rem; z-index: 1; + &.LemonModal__close--highlighted { - animation: tilt-shake 400ms; + animation: LemonModal__tilt-shake 400ms; } } @@ -132,19 +129,23 @@ border-top: none; } -@keyframes tilt-shake { +@keyframes LemonModal__tilt-shake { 0% { transform: rotate(0deg); } + 16.666% { transform: rotate(12deg); } + 50% { transform: rotate(-10deg); } + 83.333% { transform: rotate(8deg); } + 100% { transform: rotate(0deg); } diff --git a/frontend/src/lib/lemon-ui/LemonRow/LemonRow.scss b/frontend/src/lib/lemon-ui/LemonRow/LemonRow.scss index a1b6d8c5c03c8..f847cc3127765 100644 --- a/frontend/src/lib/lemon-ui/LemonRow/LemonRow.scss +++ b/frontend/src/lib/lemon-ui/LemonRow/LemonRow.scss @@ -117,6 +117,7 @@ .LemonRow--large { @extend .LemonRow--tall; + font-size: 1rem; .LemonRow__icon { diff --git a/frontend/src/lib/lemon-ui/LemonSegmentedButton/LemonSegmentedButton.scss b/frontend/src/lib/lemon-ui/LemonSegmentedButton/LemonSegmentedButton.scss index 44f4c12cd5cab..291b5ffa77646 100644 --- a/frontend/src/lib/lemon-ui/LemonSegmentedButton/LemonSegmentedButton.scss +++ b/frontend/src/lib/lemon-ui/LemonSegmentedButton/LemonSegmentedButton.scss @@ -5,6 +5,7 @@ background: var(--bg-light); border-radius: var(--radius); border: 1px solid var(--border); + > ul { z-index: 1; // Place above slider list-style: none; @@ -26,14 +27,17 @@ width: calc(var(--lemon-segmented-button-slider-width) + 2px); // 1px of border (left + right) transform: translateX(var(--lemon-segmented-button-slider-offset)); background: var(--primary); + &.LemonSegmentedButton__slider--first { border-top-left-radius: var(--radius); border-bottom-left-radius: var(--radius); } + &.LemonSegmentedButton__slider--last { border-top-right-radius: var(--radius); border-bottom-right-radius: var(--radius); } + .LemonSegmentedButton--transitioning & { transition: width 200ms ease, transform 200ms ease, border-radius 200ms ease; will-change: width, transform, border-radius; @@ -43,6 +47,7 @@ .LemonSegmentedButton__option { display: flex; flex: 1; + .LemonButton { // Original transition with outline added transition: background-color 200ms ease, color 200ms ease, border 200ms ease, opacity 200ms ease, @@ -51,32 +56,39 @@ border-radius: 0; min-height: calc(var(--lemon-button-height) - 2px); } + &:first-child, &:first-child .LemonButton { border-top-left-radius: var(--radius); border-bottom-left-radius: var(--radius); } + &:last-child, &:last-child .LemonButton { border-top-right-radius: var(--radius); border-bottom-right-radius: var(--radius); } + &:not(:last-child) { border-right: 1px solid var(--border); } - &:not(.LemonSegmentedButton__option--disabled):not(.LemonSegmentedButton__option--selected) { + + &:not(.LemonSegmentedButton__option--disabled, .LemonSegmentedButton__option--selected) { &:hover .LemonButton { outline-color: var(--primary); } + &:active .LemonButton { outline-color: var(--primary-dark); } } + &.LemonSegmentedButton__option--selected { .LemonButton, .LemonButton__icon { color: #fff; } + .LemonButton { &:hover, &:active { diff --git a/frontend/src/lib/lemon-ui/LemonSelectMultiple/LemonSelectMultiple.scss b/frontend/src/lib/lemon-ui/LemonSelectMultiple/LemonSelectMultiple.scss index 81162b59129b2..a382503f15b58 100644 --- a/frontend/src/lib/lemon-ui/LemonSelectMultiple/LemonSelectMultiple.scss +++ b/frontend/src/lib/lemon-ui/LemonSelectMultiple/LemonSelectMultiple.scss @@ -1,6 +1,7 @@ .LemonSelectMultiple { .ant-select { width: 100%; + .ant-select-selector, &.ant-select-single .ant-select-selector { min-height: 40px; @@ -9,7 +10,6 @@ font-size: 0.875rem; text-align: left; line-height: 1.25rem; - border: 1px solid var(--border); background: var(--bg-light); @@ -27,6 +27,7 @@ box-shadow: none; } } + &:not(.ant-select-disabled):active { .ant-select-selector { color: var(--primary-active); @@ -67,12 +68,13 @@ padding: 0.5rem; border-radius: var(--radius); border: 1px solid var(--primary); - margin: -4px 0px; // Counteract antd wrapper + margin: -4px 0; // Counteract antd wrapper .ant-select-item { - padding: 0px; + padding: 0; background: none; padding-bottom: 0.2rem; + .ant-select-item-option-content { height: 40px; cursor: pointer; @@ -91,13 +93,14 @@ background: var(--primary-bg-active); } } + .ant-select-item-option-state { display: none; } } .ant-select-item-empty { - padding: 0px; + padding: 0; } .ant-select-item-option-content { @@ -110,6 +113,6 @@ align-items: center; gap: 0.5rem; height: 40px; - padding: 0px 0.25rem; + padding: 0 0.25rem; } } diff --git a/frontend/src/lib/lemon-ui/LemonSkeleton/LemonSkeleton.scss b/frontend/src/lib/lemon-ui/LemonSkeleton/LemonSkeleton.scss index bbd07691933a2..29095c2aac936 100644 --- a/frontend/src/lib/lemon-ui/LemonSkeleton/LemonSkeleton.scss +++ b/frontend/src/lib/lemon-ui/LemonSkeleton/LemonSkeleton.scss @@ -4,12 +4,12 @@ background: linear-gradient( 90deg, - rgba(190, 190, 190, 0.2) 25%, - rgba(129, 129, 129, 0.24) 45%, - rgba(190, 190, 190, 0.2) 65% + rgb(190 190 190 / 20%) 25%, + rgb(129 129 129 / 24%) 45%, + rgb(190 190 190 / 20%) 65% ); background-size: 400% 100%; - animation: lemon-skeleton-loading 2s ease infinite; + animation: LemonSkeleton__shimmer 2s ease infinite; @media (prefers-reduced-motion) { animation: none; @@ -30,7 +30,7 @@ } } -@keyframes lemon-skeleton-loading { +@keyframes LemonSkeleton__shimmer { 0% { background-position: 100% 50%; } diff --git a/frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.scss b/frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.scss index e3bc0a676f39e..6ce695c71a252 100644 --- a/frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.scss +++ b/frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.scss @@ -74,6 +74,7 @@ border-radius: 0.625rem; background-color: var(--border); transition: background-color 100ms ease; + .LemonSwitch--checked & { background-color: var(--primary-highlight); } @@ -99,9 +100,11 @@ background-color: var(--primary); border-color: var(--primary); } + .LemonSwitch--active & { transform: scale(1.1); } + .LemonSwitch--active.LemonSwitch--checked & { transform: translateX(1rem) scale(1.1); } diff --git a/frontend/src/lib/lemon-ui/LemonTable/LemonTable.scss b/frontend/src/lib/lemon-ui/LemonTable/LemonTable.scss index fe0a5e5cda011..2a911f8ef6bb0 100644 --- a/frontend/src/lib/lemon-ui/LemonTable/LemonTable.scss +++ b/frontend/src/lib/lemon-ui/LemonTable/LemonTable.scss @@ -6,12 +6,16 @@ border: 1px solid var(--border); overflow: hidden; flex: 1; + --row-base-height: 3rem; --row-horizontal-padding: 1rem; + &.LemonTable--with-ribbon { --row-ribbon-width: 0.25rem; + .LemonTable__content > table > tbody > tr > :first-child { position: relative; + &::after { content: ''; position: absolute; @@ -23,52 +27,64 @@ } } } + &--xs { --row-base-height: 2rem; + .LemonTable__content > table > tbody > tr > td { padding-top: 0.25rem; padding-bottom: 0.25rem; } } + &--small { --row-base-height: 2.5rem; } + &--embedded { border: none; border-radius: 0; background: none; } + &--borderless-rows { tr { border: none !important; } } + &--stealth { border: none; border-radius: 0; background: none; + .LemonTable__content > table > thead { background: none; border: none; } } + &.LemonTable--inset { --row-horizontal-padding: 0.5rem; } + .PaginationControl { height: var(--row-base-height); padding: 0.5rem; border-top: 1px solid var(--border); } + .row-name { display: flex; align-items: center; font-size: 0.875rem; font-weight: 600; + &:not(:last-child) { margin-bottom: 0.125rem; } } + .row-description { display: inline-block; max-width: 30rem; @@ -80,6 +96,7 @@ width: 100%; border-collapse: collapse; border-spacing: 0; + > thead { position: relative; border-bottom: 1px solid var(--border); @@ -87,64 +104,79 @@ font-size: 0.75rem; letter-spacing: 0.03125rem; text-transform: uppercase; + > tr { > th { font-weight: 700; text-align: left; } + &.LemonTable__row--grouping { --row-base-height: 2.5rem; // Make group headers smaller for better hierarchy } } } + > tbody { > tr { &.LemonTable__expansion { position: relative; background: var(--side); + > td { // Disable padding inside the expansion for better tailored placement of contents padding: 0 !important; } } + &.LemonTable__row--status-highlighted { background: var(--primary-bg-hover); color: var(--default); font-weight: 600; } + > td { padding-top: 0.5rem; padding-bottom: 0.5rem; } } } + > thead, > tbody { > tr { height: var(--row-base-height); + &:not(:first-child) { border-top: 1px solid var(--border); } + > th, > td { padding-right: var(--row-horizontal-padding); overflow: hidden; text-overflow: ellipsis; + &:first-child { padding-left: calc(var(--row-horizontal-padding) + var(--row-ribbon-width, 0px)); } + &.LemonTable__boundary:not(:first-child) { padding-left: var(--row-horizontal-padding); } + &.LemonTable__boundary:not(:first-of-type) { border-left: 1px solid var(--border); } + &.LemonTable__toggle { padding-right: 0; } + &.LemonTable__toggle + * { border-left: none !important; } + &[colspan='0'] { // Hidden cells should not affect the width of the table padding-left: 0 !important; @@ -170,6 +202,7 @@ opacity: 0; pointer-events: none; z-index: 2; + .LemonTable--loading & { opacity: 0.5; pointer-events: auto; @@ -178,6 +211,7 @@ .LemonTable__header { cursor: default; + &.LemonTable__header--actionable { cursor: pointer; } @@ -203,6 +237,7 @@ body:not(.storybook-test-runner) { left: 0; z-index: 1; overflow: visible !important; + // Replicate .scrollable style for sticky cells &::before { transition: box-shadow 200ms ease; @@ -217,19 +252,23 @@ body:not(.storybook-test-runner) { box-shadow: -16px 0 16px 16px transparent; } } + .LemonTable__cell--sticky::before { background: var(--bg-light); } + tr.LemonTable__row--status-highlighted .LemonTable__cell--sticky::before { background: #e8ecff; // TRICKY: This is a one-off opaque form of --primary-bg-hover, keep in sync with source } + .LemonTable__header--sticky::before { background: var(--mid); } + .scrollable--left { .LemonTable__cell--sticky::before, .LemonTable__header--sticky::before { - box-shadow: -16px 0 16px 16px rgba(0, 0, 0, 0.25); + box-shadow: -16px 0 16px 16px rgb(0 0 0 / 25%); } } } diff --git a/frontend/src/lib/lemon-ui/LemonTable/LemonTableLoader.scss b/frontend/src/lib/lemon-ui/LemonTable/LemonTableLoader.scss index 30844284a9cd8..314f0e2806528 100644 --- a/frontend/src/lib/lemon-ui/LemonTable/LemonTableLoader.scss +++ b/frontend/src/lib/lemon-ui/LemonTable/LemonTableLoader.scss @@ -10,6 +10,7 @@ background: var(--primary-bg-active); border: none !important; overflow: hidden; + &::after { content: ''; position: absolute; @@ -17,24 +18,27 @@ top: 0; width: 50%; height: 100%; - animation: loading-bar 1.5s linear infinite; + animation: LemonTableLoader__swooping 1.5s linear infinite; background: var(--primary); } + &.LemonTableLoader--enter-active, &.LemonTableLoader--enter-done { height: 0.25rem; } } -@keyframes loading-bar { +@keyframes LemonTableLoader__swooping { 0% { left: 0; width: 33.333%; transform: translateX(-100%); } + 50% { width: 50%; } + 100% { left: 100%; width: 33.333%; diff --git a/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.scss b/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.scss index a5b58dcd27935..4ff742148785c 100644 --- a/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.scss +++ b/frontend/src/lib/lemon-ui/LemonTabs/LemonTabs.scss @@ -3,6 +3,7 @@ display: flex; flex-direction: column; align-self: stretch; + .Navigation3000__scene > &:first-child, .Navigation3000__scene > :first-child > &:first-child { margin-top: -0.75rem; @@ -18,6 +19,7 @@ flex-direction: row; align-items: stretch; overflow-x: auto; + &::before { // The bottom border content: ''; @@ -28,6 +30,7 @@ width: 100%; background: var(--border); } + &::after { // The active tab slider content: ''; @@ -38,6 +41,7 @@ width: var(--lemon-tabs-slider-width); transform: translateX(var(--lemon-tabs-slider-offset)); background: var(--link); + .LemonTabs--transitioning & { transition: width 200ms ease, transform 200ms ease; } @@ -48,19 +52,24 @@ .LemonTabs--transitioning & { transition: color 200ms ease; } + &:not(:last-child) { margin-right: 2rem; } + &:hover { color: var(--link); } + &:active { color: var(--primary-dark); } + &.LemonTabs__tab--active { color: var(--link); text-shadow: 0 0 0.25px currentColor; // Simulate increased weight without affecting width } + a { // Make tab labels that are links the same colors as regular tab labels text-decoration: none; diff --git a/frontend/src/lib/lemon-ui/LemonTag/LemonTag.scss b/frontend/src/lib/lemon-ui/LemonTag/LemonTag.scss index 055db35a70146..6b8dce12a4432 100644 --- a/frontend/src/lib/lemon-ui/LemonTag/LemonTag.scss +++ b/frontend/src/lib/lemon-ui/LemonTag/LemonTag.scss @@ -63,6 +63,6 @@ .LemonTag__right-button { margin-left: 0.25rem; min-height: 1.5rem; - padding: 0.125rem 0.125rem !important; + padding: 0.125rem !important; } } diff --git a/frontend/src/lib/lemon-ui/Link/Link.scss b/frontend/src/lib/lemon-ui/Link/Link.scss index a07b371b26d90..7b4702499c601 100644 --- a/frontend/src/lib/lemon-ui/Link/Link.scss +++ b/frontend/src/lib/lemon-ui/Link/Link.scss @@ -12,10 +12,12 @@ &:hover { color: var(--primary-light); } + &:active { color: var(--primary-dark); } } + &:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; diff --git a/frontend/src/lib/lemon-ui/Link/Link.tsx b/frontend/src/lib/lemon-ui/Link/Link.tsx index 12c1c9e966a47..5365eb5213073 100644 --- a/frontend/src/lib/lemon-ui/Link/Link.tsx +++ b/frontend/src/lib/lemon-ui/Link/Link.tsx @@ -82,7 +82,6 @@ export const Link: React.FC> = Reac href: typeof to === 'string' ? to : undefined, }) - const docsPanelEnabled = useFeatureFlag('SIDE_PANEL_DOCS') const is3000 = useFeatureFlag('POSTHOG_3000') const { openDocsPage } = useActions(sidePanelDocsLogic) @@ -99,7 +98,7 @@ export const Link: React.FC> = Reac return } - if (typeof to === 'string' && is3000 && docsPanelEnabled && isPostHogComDomain(to)) { + if (typeof to === 'string' && is3000 && isPostHogComDomain(to)) { event.preventDefault() openDocsPage(to) return diff --git a/frontend/src/lib/lemon-ui/Popover/Popover.scss b/frontend/src/lib/lemon-ui/Popover/Popover.scss index 3e53c125cfb19..f989f61f3f5bb 100644 --- a/frontend/src/lib/lemon-ui/Popover/Popover.scss +++ b/frontend/src/lib/lemon-ui/Popover/Popover.scss @@ -8,9 +8,11 @@ h5 { margin: 0.25rem 0.5rem; } + p:last-child { margin-bottom: 0; } + &[data-floating-placement^='top'] { perspective-origin: bottom; } @@ -45,7 +47,9 @@ .Popover[data-placement^='bottom'] & { transform-origin: top; margin-top: 0.25rem; + transform: rotateX(-6deg); } + .Popover[data-placement^='bottom'].Popover--with-arrow & { margin-top: 0.5rem; } @@ -53,7 +57,9 @@ .Popover[data-placement^='top'] & { transform-origin: bottom; margin-bottom: 0.25rem; + transform: rotateX(6deg); } + .Popover[data-placement^='top'].Popover--with-arrow & { margin-bottom: 0.5rem; } @@ -61,7 +67,9 @@ .Popover[data-placement^='left'] & { transform-origin: right; margin-right: 0.25rem; + transform: rotateY(-6deg); } + .Popover[data-placement^='left'].Popover--with-arrow & { margin-right: 0.5rem; } @@ -69,27 +77,13 @@ .Popover[data-placement^='right'] & { transform-origin: left; margin-left: 0.25rem; + transform: rotateY(6deg); } + .Popover[data-placement^='right'].Popover--with-arrow & { margin-left: 0.5rem; } - .Popover[data-placement^='bottom'] & { - transform: rotateX(-6deg); - } - - .Popover[data-placement^='top'] & { - transform: rotateX(6deg); - } - - .Popover[data-placement^='left'] & { - transform: rotateY(-6deg); - } - - .Popover[data-placement^='right'] & { - transform: rotateY(6deg); - } - .Popover.Popover--enter-active &, .Popover.Popover--enter-done & { opacity: 1; @@ -104,6 +98,7 @@ background: var(--bg-3000); padding: 0.25rem; } + .posthog-3000 .Popover--actionable & { border-color: var(--border); } diff --git a/frontend/src/lib/lemon-ui/ProfilePicture/ProfilePicture.scss b/frontend/src/lib/lemon-ui/ProfilePicture/ProfilePicture.scss index 9185ae635f9a8..9e5a327867146 100644 --- a/frontend/src/lib/lemon-ui/ProfilePicture/ProfilePicture.scss +++ b/frontend/src/lib/lemon-ui/ProfilePicture/ProfilePicture.scss @@ -1,6 +1,7 @@ .profile-package { display: inline-flex; align-items: center; + &:not(:first-child) { margin-left: 0.375rem; } @@ -75,9 +76,11 @@ .ProfileBubbles { display: flex; align-items: center; + > * { outline: 0.125rem solid var(--bg-light); } + > :not(:first-child) { margin-left: -0.125rem; } diff --git a/frontend/src/lib/lemon-ui/Spinner/Spinner.scss b/frontend/src/lib/lemon-ui/Spinner/Spinner.scss index 2e817a93317e0..9504dd20eb1c4 100644 --- a/frontend/src/lib/lemon-ui/Spinner/Spinner.scss +++ b/frontend/src/lib/lemon-ui/Spinner/Spinner.scss @@ -4,7 +4,9 @@ width: 1em; height: 1em; flex-shrink: 0; + --spinner-color: var(--brand-blue); + &.Spinner--textColored { --spinner-color: currentColor; } @@ -12,6 +14,7 @@ .Spinner__layer { transform-origin: center; + > circle { display: block; fill: transparent; @@ -20,23 +23,27 @@ stroke: var(--spinner-color); stroke-linecap: round; } + &:nth-child(1) { opacity: 0.333; } + &:nth-child(2) { animation: spin 1s infinite linear; + > circle { - animation: writhe 1.5s infinite ease both; + animation: Spinner__writhe 1.5s infinite ease both; } } } -@keyframes writhe { +@keyframes Spinner__writhe { 0%, 100% { stroke-dashoffset: -60; stroke-dasharray: 70; } + 50% { stroke-dashoffset: -30; stroke-dasharray: 70; @@ -46,33 +53,31 @@ .SpinnerOverlay { transition: opacity 0.2s ease; position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; + inset: 0; text-align: center; min-height: 6rem; z-index: var(--z-content-overlay); display: flex; align-items: center; justify-content: center; + &[aria-hidden='true'] { opacity: 0; pointer-events: none; } + &::before { content: ''; position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; + inset: 0; background: var(--bg-light); opacity: 0.5; } + .Spinner { position: relative; } + .posthog-3000 &.SpinnerOverlay--scene-level::before { background: var(--bg-3000); } diff --git a/frontend/src/lib/lemon-ui/Splotch/Splotch.scss b/frontend/src/lib/lemon-ui/Splotch/Splotch.scss index 5f1a03bd642e2..f183e17b5a6d8 100644 --- a/frontend/src/lib/lemon-ui/Splotch/Splotch.scss +++ b/frontend/src/lib/lemon-ui/Splotch/Splotch.scss @@ -8,18 +8,23 @@ width: 1rem; height: 1rem; border-radius: var(--radius); + .Splotch--blue & { background: var(--blue); } + .Splotch--purple & { background: var(--purple); } + .Splotch--green & { background: var(--green); } + .Splotch--black & { background: var(--black); } + .Splotch--white & { background: #fff; border: 1px solid var(--border); diff --git a/frontend/src/lib/logic/newPrompt/prompt.scss b/frontend/src/lib/logic/newPrompt/prompt.scss index 095bddaadcbfc..355cb23c9af2e 100644 --- a/frontend/src/lib/logic/newPrompt/prompt.scss +++ b/frontend/src/lib/logic/newPrompt/prompt.scss @@ -5,7 +5,6 @@ z-index: 2000; flex-direction: column; background: white; - border: 1px solid #f0f0f0; border-radius: 8px; padding-top: 5px; min-width: 300px; diff --git a/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.scss b/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.scss index 89ce0aff2b6ed..bc1db304a1058 100644 --- a/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.scss +++ b/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.scss @@ -3,6 +3,7 @@ width: 700px; display: flex; column-gap: 1rem; + @media (max-width: 960px) { display: block; width: auto; @@ -15,6 +16,7 @@ .HalfColumn { width: 50%; + @media (max-width: 960px) { width: 100%; } diff --git a/frontend/src/queries/nodes/DataTable/DataTable.scss b/frontend/src/queries/nodes/DataTable/DataTable.scss index 60f05bbd38eda..ea5d0bf3de23e 100644 --- a/frontend/src/queries/nodes/DataTable/DataTable.scss +++ b/frontend/src/queries/nodes/DataTable/DataTable.scss @@ -3,17 +3,18 @@ max-width: 20rem; } - @keyframes DataTable--highlight { + @keyframes DataTable__highlight { 0% { background-color: var(--mark); } + 100% { background-color: initial; } } .DataTable__row--highlight_once { - animation: DataTable--highlight 2000ms ease-out; + animation: DataTable__highlight 2000ms ease-out; } .DataTable__row--category_row { diff --git a/frontend/src/queries/nodes/InsightViz/EditorFilters.scss b/frontend/src/queries/nodes/InsightViz/EditorFilters.scss index de26425709f08..01e9016fb7aa1 100644 --- a/frontend/src/queries/nodes/InsightViz/EditorFilters.scss +++ b/frontend/src/queries/nodes/InsightViz/EditorFilters.scss @@ -35,7 +35,7 @@ &.EditorFiltersWrapper--singlecolumn { border: none; background: none; - padding: 0px; + padding: 0; margin-right: 1rem; container-type: normal; @@ -51,7 +51,7 @@ .EditorFilters { flex-direction: column; - gap: 0rem; + gap: 0; .EditorFilterGroup { width: auto; @@ -64,12 +64,12 @@ } &.EditorFiltersWrapper--embedded { - margin-right: 0rem; + margin-right: 0; @include screen($xl) { .EditorFilters { width: 100%; - padding-right: 0rem; + padding-right: 0; } } } diff --git a/frontend/src/queries/nodes/InsightViz/InsightDisplayConfig.tsx b/frontend/src/queries/nodes/InsightViz/InsightDisplayConfig.tsx index 12a3a2adc2209..07e9d8b7e701a 100644 --- a/frontend/src/queries/nodes/InsightViz/InsightDisplayConfig.tsx +++ b/frontend/src/queries/nodes/InsightViz/InsightDisplayConfig.tsx @@ -2,7 +2,6 @@ import { ReactNode } from 'react' import { useValues } from 'kea' import { insightLogic } from 'scenes/insights/insightLogic' -import { insightDisplayConfigLogic } from './insightDisplayConfigLogic' import { InsightDateFilter } from 'scenes/insights/filters/InsightDateFilter' import { IntervalFilter } from 'lib/components/IntervalFilter' @@ -23,47 +22,63 @@ import { LemonButton } from '@posthog/lemon-ui' import { axisLabel } from 'scenes/insights/aggregationAxisFormat' import { ChartDisplayType } from '~/types' import { ShowLegendFilter } from 'scenes/insights/EditorFilters/ShowLegendFilter' +import { FEATURE_FLAGS, NON_TIME_SERIES_DISPLAY_TYPES } from 'lib/constants' +import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic' +import { funnelDataLogic } from 'scenes/funnels/funnelDataLogic' +import { featureFlagLogic } from 'lib/logic/featureFlagLogic' export function InsightDisplayConfig(): JSX.Element { const { insightProps } = useValues(insightLogic) + const { featureFlags } = useValues(featureFlagLogic) + const { - showDateRange, - disableDateRange, - showCompare, - showValueOnSeries, - showPercentStackView, - showUnit, - showChart, - showInterval, - showSmoothing, - showRetention, - showPaths, - showFunnelDisplayLayout, - showFunnelBins, + isTrends, + isFunnels, + isRetention, + isPaths, + isStickiness, + isLifecycle, + supportsDisplay, display, + breakdown, trendsFilter, hasLegend, showLegend, - } = useValues(insightDisplayConfigLogic(insightProps)) - - const { showPercentStackView: isPercentStackViewOn, showValueOnSeries: isValueOnSeriesOn } = useValues( - trendsDataLogic(insightProps) + supportsValueOnSeries, + showPercentStackView, + } = useValues(insightVizDataLogic(insightProps)) + const { isTrendsFunnel, isStepsFunnel, isTimeToConvertFunnel, isEmptyFunnel } = useValues( + funnelDataLogic(insightProps) ) + const showCompare = (isTrends && display !== ChartDisplayType.ActionsAreaGraph) || isStickiness + const showInterval = + isTrendsFunnel || + isLifecycle || + ((isTrends || isStickiness) && !(display && NON_TIME_SERIES_DISPLAY_TYPES.includes(display))) + const showSmoothing = + isTrends && + !breakdown?.breakdown_type && + !trendsFilter?.compare && + (!display || display === ChartDisplayType.ActionsLineGraph) && + featureFlags[FEATURE_FLAGS.SMOOTHING_INTERVAL] + + const { showPercentStackView: isPercentStackViewOn, showValueOnSeries } = useValues(trendsDataLogic(insightProps)) + const advancedOptions: LemonMenuItems = [ - ...(showValueOnSeries || showPercentStackView || hasLegend + ...(supportsValueOnSeries || showPercentStackView || hasLegend ? [ { title: 'Display', items: [ - ...(showValueOnSeries ? [{ label: () => }] : []), + ...(supportsValueOnSeries ? [{ label: () => }] : []), ...(showPercentStackView ? [{ label: () => }] : []), ...(hasLegend ? [{ label: () => }] : []), ], }, ] : []), - ...(!isPercentStackViewOn && showUnit + ...(!isPercentStackViewOn && isTrends ? [ { title: axisLabel(display || ChartDisplayType.ActionsLineGraph), @@ -73,10 +88,10 @@ export function InsightDisplayConfig(): JSX.Element { : []), ] const advancedOptionsCount: number = - (showValueOnSeries && isValueOnSeriesOn ? 1 : 0) + + (supportsValueOnSeries && showValueOnSeries ? 1 : 0) + (showPercentStackView && isPercentStackViewOn ? 1 : 0) + (!isPercentStackViewOn && - showUnit && + isTrends && trendsFilter?.aggregation_axis_format && trendsFilter.aggregation_axis_format !== 'numeric' ? 1 @@ -86,9 +101,9 @@ export function InsightDisplayConfig(): JSX.Element { return (
- {showDateRange && ( + {!isRetention && ( - + )} @@ -104,14 +119,14 @@ export function InsightDisplayConfig(): JSX.Element { )} - {showRetention && ( + {!!isRetention && ( )} - {showPaths && ( + {!!isPaths && ( @@ -133,17 +148,17 @@ export function InsightDisplayConfig(): JSX.Element { )} - {showChart && ( + {supportsDisplay && ( )} - {showFunnelDisplayLayout && ( + {!!isStepsFunnel && ( )} - {showFunnelBins && ( + {!!isTimeToConvertFunnel && ( diff --git a/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/PropertyGroupFilters.scss b/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/PropertyGroupFilters.scss index 746da0a960300..0c2b080492e42 100644 --- a/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/PropertyGroupFilters.scss +++ b/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/PropertyGroupFilters.scss @@ -7,12 +7,12 @@ .property-group-and-or-separator { color: var(--primary-alt); - padding: 0.5rem 0px; + padding: 0.5rem 0; font-size: 12px; font-weight: 600; position: relative; - &:before { + &::before { position: absolute; left: 17px; top: 0; diff --git a/frontend/src/queries/nodes/InsightViz/insightDisplayConfigLogic.ts b/frontend/src/queries/nodes/InsightViz/insightDisplayConfigLogic.ts deleted file mode 100644 index 784b56ef7429b..0000000000000 --- a/frontend/src/queries/nodes/InsightViz/insightDisplayConfigLogic.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { kea, props, key, path, selectors, connect } from 'kea' -import { ChartDisplayType, InsightLogicProps } from '~/types' -import { keyForInsightLogicProps } from 'scenes/insights/sharedUtils' - -import { featureFlagLogic } from 'lib/logic/featureFlagLogic' -import { funnelDataLogic } from 'scenes/funnels/funnelDataLogic' -import { FEATURE_FLAGS, NON_TIME_SERIES_DISPLAY_TYPES, NON_VALUES_ON_SERIES_DISPLAY_TYPES } from 'lib/constants' - -import type { insightDisplayConfigLogicType } from './insightDisplayConfigLogicType' -import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic' - -export const insightDisplayConfigLogic = kea([ - props({} as InsightLogicProps), - key(keyForInsightLogicProps('new')), - path((key) => ['queries', 'nodes', 'InsightViz', 'insightDisplayConfigLogic', key]), - - connect((props: InsightLogicProps) => ({ - values: [ - featureFlagLogic, - ['featureFlags'], - insightVizDataLogic(props), - [ - 'isTrends', - 'isFunnels', - 'isRetention', - 'isPaths', - 'isStickiness', - 'isLifecycle', - 'supportsDisplay', - 'supportsPercentStackView as showPercentStackView', - 'display', - 'compare', - 'breakdown', - 'trendsFilter', - 'hasLegend', - 'showLegend', - ], - funnelDataLogic(props), - ['isEmptyFunnel', 'isStepsFunnel', 'isTimeToConvertFunnel', 'isTrendsFunnel'], - ], - })), - - selectors({ - showDateRange: [(s) => [s.isRetention], (isRetention) => !isRetention], - disableDateRange: [ - (s) => [s.isFunnels, s.isEmptyFunnel], - (isFunnels, isEmptyFunnel) => isFunnels && !!isEmptyFunnel, - ], - showCompare: [ - (s) => [s.isTrends, s.isStickiness, s.display], - (isTrends, isStickiness, display) => - (isTrends && display !== ChartDisplayType.ActionsAreaGraph) || isStickiness, - ], - showValueOnSeries: [ - (s) => [s.isTrends, s.isStickiness, s.isLifecycle, s.display], - (isTrends, isStickiness, isLifecycle, display) => { - if (isTrends || isStickiness) { - return !NON_VALUES_ON_SERIES_DISPLAY_TYPES.includes(display || ChartDisplayType.ActionsLineGraph) - } else if (isLifecycle) { - return true - } else { - return false - } - }, - ], - showUnit: [(s) => [s.supportsDisplay, s.isTrends], (supportsDisplay, isTrends) => supportsDisplay && isTrends], - showChart: [(s) => [s.supportsDisplay], (supportsDisplay) => supportsDisplay], - showInterval: [ - (s) => [s.isTrends, s.isStickiness, s.isLifecycle, s.isTrendsFunnel, s.display], - (isTrends, isStickiness, isLifecycle, isTrendsFunnel, display) => - isTrendsFunnel || - isLifecycle || - ((isTrends || isStickiness) && !(display && NON_TIME_SERIES_DISPLAY_TYPES.includes(display))), - ], - showSmoothing: [ - (s) => [s.isTrends, s.breakdown, s.display, s.trendsFilter, s.featureFlags], - (isTrends, breakdown, display, trendsFilter, featureFlags) => - isTrends && - !breakdown?.breakdown_type && - !trendsFilter?.compare && - (!display || display === ChartDisplayType.ActionsLineGraph) && - featureFlags[FEATURE_FLAGS.SMOOTHING_INTERVAL], - ], - showRetention: [(s) => [s.isRetention], (isRetention) => !!isRetention], - showPaths: [(s) => [s.isPaths], (isPaths) => !!isPaths], - showFunnelDisplayLayout: [(s) => [s.isStepsFunnel], (isStepsFunnel) => !!isStepsFunnel], - showFunnelBins: [(s) => [s.isTimeToConvertFunnel], (isTimeToConvertFunnel) => !!isTimeToConvertFunnel], - }), -]) diff --git a/frontend/src/scenes/PreflightCheck/PreflightCheck.scss b/frontend/src/scenes/PreflightCheck/PreflightCheck.scss index 21859e46108bb..2b83263873c2e 100644 --- a/frontend/src/scenes/PreflightCheck/PreflightCheck.scss +++ b/frontend/src/scenes/PreflightCheck/PreflightCheck.scss @@ -1,6 +1,7 @@ .Preflight { max-width: 400px; padding: 1rem; + .Preflight__header { p { margin-bottom: 0.5rem; diff --git a/frontend/src/scenes/batch_exports/BatchExports.scss b/frontend/src/scenes/batch_exports/BatchExports.scss index da0646417ab23..835ed19de7ec9 100644 --- a/frontend/src/scenes/batch_exports/BatchExports.scss +++ b/frontend/src/scenes/batch_exports/BatchExports.scss @@ -1,18 +1,20 @@ .BatchExportRunIcon--pulse { outline: 2px solid transparent; outline-offset: 0; - animation: pulse 2s infinite ease-out; + animation: BatchExportRunIcon__pulse 2s infinite ease-out; } -@keyframes pulse { +@keyframes BatchExportRunIcon__pulse { 0% { outline-offset: 0; outline-color: var(--primary-light); } + 80% { outline-offset: 20px; outline-color: transparent; } + 100% { outline-offset: 20px; outline-color: transparent; diff --git a/frontend/src/scenes/billing/Billing.scss b/frontend/src/scenes/billing/Billing.scss index 6960ebc6e4a07..8088a048cf769 100644 --- a/frontend/src/scenes/billing/Billing.scss +++ b/frontend/src/scenes/billing/Billing.scss @@ -1,6 +1,7 @@ .BillingPlan { max-width: 500px; flex-grow: 1; + .BillingPlan__description { ol, ul { @@ -8,10 +9,12 @@ padding-left: 0; list-style: none; text-align: center; + li { line-height: 1.2rem; margin-bottom: 1rem; } + .disclaimer { font-size: 10px; font-weight: bold; diff --git a/frontend/src/scenes/billing/BillingGauge.scss b/frontend/src/scenes/billing/BillingGauge.scss index 37ebdc11bbd20..b9c73a13291f6 100644 --- a/frontend/src/scenes/billing/BillingGauge.scss +++ b/frontend/src/scenes/billing/BillingGauge.scss @@ -1,5 +1,5 @@ .BillingGaugeItem { - animation: billing-gauge-item-expand 800ms cubic-bezier(0.15, 0.15, 0.2, 1) forwards; + animation: BillingGaugeItem__expand 800ms cubic-bezier(0.15, 0.15, 0.2, 1) forwards; .BillingGaugeItem__info { position: absolute; @@ -9,15 +9,14 @@ margin-left: -1px; font-size: 0.8rem; background: var(--bg-light); - bottom: 100%; - padding: 0 0.25rem 0.5rem 0.25rem; + padding: 0 0.25rem 0.5rem; line-height: 1rem; &--bottom { top: 100%; bottom: auto; - padding: 0.5rem 0.25rem 0 0.25rem; + padding: 0.5rem 0.25rem 0; } &:hover { @@ -26,10 +25,11 @@ } } -@keyframes billing-gauge-item-expand { +@keyframes BillingGaugeItem__expand { 0% { width: 0%; } + 100% { width: var(--billing-gauge-item-width); } diff --git a/frontend/src/scenes/billing/PlanComparison.scss b/frontend/src/scenes/billing/PlanComparison.scss index fbda341b032a6..57c4ed6bd6d63 100644 --- a/frontend/src/scenes/billing/PlanComparison.scss +++ b/frontend/src/scenes/billing/PlanComparison.scss @@ -1,8 +1,10 @@ .PlanComparisonModal { max-width: 900px; } + table.PlanComparison { table-layout: fixed; + td { vertical-align: top; padding: 0.75rem 1.25rem; @@ -12,14 +14,15 @@ table.PlanComparison { padding-bottom: 1rem; } } + th { vertical-align: top; - padding: 0.75rem 1.25rem 0.75rem; + padding: 0.75rem 1.25rem; font-weight: 600; text-align: left; &.PlanTable__th__section { - padding: 0.25rem 1.25rem 0.25rem; + padding: 0.25rem 1.25rem; font-weight: 500; } @@ -37,6 +40,7 @@ table.PlanComparison { } } } + .PlanTable__tr__border { - border-bottom: 3px rgba(0, 0, 0, 0.07) dotted; + border-bottom: 3px rgb(0 0 0 / 7%) dotted; } diff --git a/frontend/src/scenes/billing/PlanTable.scss b/frontend/src/scenes/billing/PlanTable.scss index 2f66ee15b7e22..af301e35f3114 100644 --- a/frontend/src/scenes/billing/PlanTable.scss +++ b/frontend/src/scenes/billing/PlanTable.scss @@ -1,11 +1,14 @@ .PlanTable { max-width: 1200px; + table { table-layout: fixed; + td { vertical-align: top; padding: 1.25rem; } + th { vertical-align: top; padding: 1.25rem; @@ -13,7 +16,7 @@ text-align: left; &.PlanTable__th__section { - padding: 0.25rem 1.25rem 0.25rem; + padding: 0.25rem 1.25rem; font-weight: 500; } @@ -27,7 +30,8 @@ } } } + .PlanTable__tr__border { - border-bottom: 3px rgba(0, 0, 0, 0.07) dotted; + border-bottom: 3px rgb(0 0 0 / 7%) dotted; } } diff --git a/frontend/src/scenes/cohorts/CohortFilters/CohortField.scss b/frontend/src/scenes/cohorts/CohortFilters/CohortField.scss index fd1b5d9585fbe..075dda92dc0d9 100644 --- a/frontend/src/scenes/cohorts/CohortFilters/CohortField.scss +++ b/frontend/src/scenes/cohorts/CohortFilters/CohortField.scss @@ -47,7 +47,7 @@ background-color: inherit; .ant-select-selection-search { - padding-left: 0px !important; + padding-left: 0 !important; } .ant-select-selection-placeholder { diff --git a/frontend/src/scenes/cohorts/Cohorts.scss b/frontend/src/scenes/cohorts/Cohorts.scss index a5e797a1d45eb..8dd6ee18eeee8 100644 --- a/frontend/src/scenes/cohorts/Cohorts.scss +++ b/frontend/src/scenes/cohorts/Cohorts.scss @@ -8,6 +8,7 @@ padding: 0.5rem 1rem; margin-top: 1rem; border-radius: var(--radius); + .ant-spin-spinning { margin-right: 0.375rem; } @@ -35,7 +36,7 @@ .ant-upload-text { font-weight: 600; font-size: 1rem !important; - margin: 8px 0 0 0 !important; + margin: 8px 0 0 !important; } } } diff --git a/frontend/src/scenes/dashboard/Dashboard.scss b/frontend/src/scenes/dashboard/Dashboard.scss index 8af88d8d63b37..f35d1decb41af 100644 --- a/frontend/src/scenes/dashboard/Dashboard.scss +++ b/frontend/src/scenes/dashboard/Dashboard.scss @@ -14,11 +14,14 @@ white-space: nowrap; display: flex; align-items: center; + .ant-btn { .anticon { vertical-align: baseline; } + margin-left: 10px; + &.button-box { padding: 4px 8px; } @@ -27,6 +30,7 @@ @media (max-width: 768px) { flex-direction: column; + .dashboard-meta { padding-top: 1rem; justify-content: flex-end; diff --git a/frontend/src/scenes/dashboard/DashboardItems.scss b/frontend/src/scenes/dashboard/DashboardItems.scss index cac3b9299bac4..7cf51ba05a33f 100644 --- a/frontend/src/scenes/dashboard/DashboardItems.scss +++ b/frontend/src/scenes/dashboard/DashboardItems.scss @@ -13,13 +13,11 @@ transition: border-color 100ms ease; } } -.react-grid-item { - transition: all 100ms ease; - transition-property: left, top; -} + .react-grid-item.cssTransforms { transition-property: transform; } + .react-grid-item.resizing { z-index: 1; will-change: width, height; @@ -49,10 +47,15 @@ z-index: 2; user-select: none; } + .react-resizable-hide > .react-resizable-handle { display: none; } + .react-grid-item { + transition: all 100ms ease; + transition-property: left, top; + & > .react-resizable-handle { position: absolute; width: 2rem; @@ -62,15 +65,18 @@ cursor: se-resize; z-index: 10; } + & > .react-resizable-handle.react-resizable-handle-se { cursor: se-resize; } + & > .react-resizable-handle.react-resizable-handle-e { top: 0; bottom: 2rem; height: auto; cursor: ew-resize; } + & > .react-resizable-handle.react-resizable-handle-s { left: 0; right: 2rem; diff --git a/frontend/src/scenes/dashboard/EmptyDashboardComponent.scss b/frontend/src/scenes/dashboard/EmptyDashboardComponent.scss index 8f5e80394144f..bf4a7f6f3db78 100644 --- a/frontend/src/scenes/dashboard/EmptyDashboardComponent.scss +++ b/frontend/src/scenes/dashboard/EmptyDashboardComponent.scss @@ -14,7 +14,9 @@ .posthog-3000 & { --bg-light: var(--bg-3000); // Make the fade blend in with the 3000 background smoothly } + @extend %mixin-gradient-overlay; + width: 100%; height: 150px; } diff --git a/frontend/src/scenes/dashboard/NewDashboardModal.scss b/frontend/src/scenes/dashboard/NewDashboardModal.scss index 76aaa50b48d80..b14c650aecaa0 100644 --- a/frontend/src/scenes/dashboard/NewDashboardModal.scss +++ b/frontend/src/scenes/dashboard/NewDashboardModal.scss @@ -2,8 +2,7 @@ .DashboardTemplateChooser { max-width: 780px; grid-template-columns: repeat(3, 1fr); - column-gap: 0.5em; - row-gap: 0.5em; + gap: 0.5em 0.5em; display: grid; } diff --git a/frontend/src/scenes/data-management/definition/Definition.scss b/frontend/src/scenes/data-management/definition/Definition.scss index 263df84497a47..4e708a8082ee9 100644 --- a/frontend/src/scenes/data-management/definition/Definition.scss +++ b/frontend/src/scenes/data-management/definition/Definition.scss @@ -80,13 +80,10 @@ position: relative; overflow: visible; - &:before { + &::before { content: ''; position: absolute; - top: -5px; - bottom: -5px; - left: -10px; - right: -50px; + inset: -5px -50px -5px -10px; height: 22px; } } @@ -110,8 +107,9 @@ .definition-matching-events-header { font-weight: 600; } + .definition-matching-events-subtext { - margin: 0 0 1rem 0; + margin: 0 0 1rem; } } } diff --git a/frontend/src/scenes/data-management/events/EventDefinitionsTable.scss b/frontend/src/scenes/data-management/events/EventDefinitionsTable.scss index b5054393c9116..6f510e589a9c7 100644 --- a/frontend/src/scenes/data-management/events/EventDefinitionsTable.scss +++ b/frontend/src/scenes/data-management/events/EventDefinitionsTable.scss @@ -42,13 +42,10 @@ position: relative; overflow: visible; - &:before { + &::before { content: ''; position: absolute; - top: -5px; - bottom: -5px; - left: -10px; - right: -50px; + inset: -5px -50px -5px -10px; height: 22px; } } @@ -81,6 +78,7 @@ .LemonTable__expansion { .event-properties-wrapper { padding: 1rem 0 1rem 1rem; + .event-properties-header { font-weight: 600; } diff --git a/frontend/src/scenes/data-management/properties/PropertyDefinitionsTable.scss b/frontend/src/scenes/data-management/properties/PropertyDefinitionsTable.scss index 5a697e0c2c1ca..50b3d7bfb9394 100644 --- a/frontend/src/scenes/data-management/properties/PropertyDefinitionsTable.scss +++ b/frontend/src/scenes/data-management/properties/PropertyDefinitionsTable.scss @@ -35,11 +35,10 @@ font-weight: 600; cursor: pointer; - &:before { + &::before { content: ''; position: absolute; top: -5px; - //bottom: -5px; left: -10px; right: -50px; height: 22px; diff --git a/frontend/src/scenes/events/EventDetails.scss b/frontend/src/scenes/events/EventDetails.scss index 2e54eda04b0d1..ac55e6ab55136 100644 --- a/frontend/src/scenes/events/EventDetails.scss +++ b/frontend/src/scenes/events/EventDetails.scss @@ -1,3 +1,3 @@ .LemonTabs[data-attr='event-details'] ul { - padding: 0px 0.75rem; + padding: 0 0.75rem; } diff --git a/frontend/src/scenes/experiments/Experiment.scss b/frontend/src/scenes/experiments/Experiment.scss index dd965da7de551..762e1ad83b78a 100644 --- a/frontend/src/scenes/experiments/Experiment.scss +++ b/frontend/src/scenes/experiments/Experiment.scss @@ -2,7 +2,6 @@ .metrics-selection { border-top: 1px solid var(--border); padding-top: 1rem; - width: 100%; } @@ -75,6 +74,7 @@ .variants { margin-top: 0.5rem; padding-bottom: 1rem; + .ant-form-horizontal { min-height: 32px; } @@ -92,7 +92,7 @@ .feature-flag-variant { display: flex; align-items: center; - padding: 0.5rem 0.5rem; + padding: 0.5rem; background: var(--bg-light); border-width: 1px; border-color: var(--border); @@ -111,7 +111,7 @@ justify-content: center; align-items: center; border-radius: 4px; - color: #ffffff; + color: #fff; min-width: 52px; padding: 2px 6px; margin-right: 8px; @@ -151,6 +151,7 @@ .participants { background-color: white; + .ant-collapse-header { padding-top: 0.5rem; padding-bottom: 0.5rem; @@ -162,10 +163,12 @@ li { display: inline; } - li:after { + + li::after { content: ', '; } - li:last-child:after { + + li:last-child::after { content: ''; } } @@ -209,9 +212,7 @@ min-height: 320px; font-size: 24px; } -} -.view-experiment { .computation-time-and-sampling-notice { margin-top: 8px; } @@ -231,6 +232,7 @@ border-bottom: 1px solid var(--border); padding-bottom: 1rem; margin-bottom: 1rem; + &:last-child { border-bottom: none; padding-bottom: 0; diff --git a/frontend/src/scenes/feature-flags/FeatureFlag.scss b/frontend/src/scenes/feature-flags/FeatureFlag.scss index a793ab541a7fe..730181e4ad083 100644 --- a/frontend/src/scenes/feature-flags/FeatureFlag.scss +++ b/frontend/src/scenes/feature-flags/FeatureFlag.scss @@ -23,9 +23,8 @@ .feature-flag-property-display { display: flex; - flex-direction: row; + flex-flow: row wrap; align-items: center; - flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; diff --git a/frontend/src/scenes/feature-flags/JSONEditorInput.scss b/frontend/src/scenes/feature-flags/JSONEditorInput.scss index 2ca0c2c3907a3..1ad4102fca3c7 100644 --- a/frontend/src/scenes/feature-flags/JSONEditorInput.scss +++ b/frontend/src/scenes/feature-flags/JSONEditorInput.scss @@ -1,14 +1,18 @@ .JsonEditorInput { position: relative; + .border { border-radius: var(--radius); + .monaco-editor { border-radius: inherit; + .overflow-guard { border-radius: inherit; } } } + .placeholder { position: absolute; top: 0; diff --git a/frontend/src/scenes/feedback/Feedback.scss b/frontend/src/scenes/feedback/Feedback.scss deleted file mode 100644 index b644140412e4a..0000000000000 --- a/frontend/src/scenes/feedback/Feedback.scss +++ /dev/null @@ -1,2 +0,0 @@ -.Feedback { -} diff --git a/frontend/src/scenes/feedback/Feedback.tsx b/frontend/src/scenes/feedback/Feedback.tsx index 8646f01e82186..e697b5003f08d 100644 --- a/frontend/src/scenes/feedback/Feedback.tsx +++ b/frontend/src/scenes/feedback/Feedback.tsx @@ -1,10 +1,7 @@ import { LemonTag } from '@posthog/lemon-ui' import { PageHeader } from 'lib/components/PageHeader' import { SceneExport } from 'scenes/sceneTypes' - import { feedbackLogic } from './feedbackLogic' - -import './Feedback.scss' import { LemonTabs } from 'lib/lemon-ui/LemonTabs' import { InAppFeedback, InAppFeedbackHeaderButtons } from './InAppFeedback' import { UserInterviewScheduler, UserInterviewSchedulerHeaderButtons } from './UserInterviewScheduler' diff --git a/frontend/src/scenes/feedback/InAppFeedback.tsx b/frontend/src/scenes/feedback/InAppFeedback.tsx index 126ca7111f5f9..bdb1347715ecd 100644 --- a/frontend/src/scenes/feedback/InAppFeedback.tsx +++ b/frontend/src/scenes/feedback/InAppFeedback.tsx @@ -1,11 +1,8 @@ import { LemonButton, LemonCollapse, LemonDivider, LemonModal, Link } from '@posthog/lemon-ui' - import { urls } from '@posthog/apps-common' import { useActions, useValues } from 'kea' import { inAppFeedbackLogic } from './inAppFeedbackLogic' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' - -import './Feedback.scss' import { IconHelpOutline } from 'lib/lemon-ui/icons' import { Query } from '~/queries/Query/Query' diff --git a/frontend/src/scenes/funnels/FunnelBarChart/FunnelBarChart.scss b/frontend/src/scenes/funnels/FunnelBarChart/FunnelBarChart.scss index faf5e1edb7938..79df64b8138d7 100644 --- a/frontend/src/scenes/funnels/FunnelBarChart/FunnelBarChart.scss +++ b/frontend/src/scenes/funnels/FunnelBarChart/FunnelBarChart.scss @@ -5,26 +5,33 @@ width: 100%; height: 26rem; overflow: hidden; + .InsightCard & { height: 100%; + table { margin: 0.5rem 0 0; } } + table { --bar-width: 0.5rem; // This should be overriden from React --bar-row-height: 18rem; + margin: 0.5rem 1rem 0; width: 100%; + > tbody { > tr { &:first-child { border-bottom: 1px solid var(--border); + > td { padding: 1.5rem 0; padding-top: 1rem; } } + > td { // Sneaky hack to make height: 100% work in .StepLegend. The wonders of CSS - there's NO other way! height: 1px; @@ -49,6 +56,7 @@ .StepBarLabels__segment { flex-grow: 1; padding: 0 0.5rem; + &:first-child { flex-grow: 0; height: 0; @@ -69,6 +77,7 @@ border-bottom: 1px solid var(--border); height: calc(var(--bar-row-height) - 3rem); padding: 0 1rem; + &:not(.StepBars--first) { border-left: 1px dashed var(--border); } @@ -87,6 +96,7 @@ .StepBars__gridline { flex-grow: 1; + &.StepBars__gridline--horizontal { border-top: 1px dashed var(--border); } @@ -95,14 +105,17 @@ .StepBar { --series-color: #000; // This should be overriden from React --conversion-rate: 100%; // This should be overriden from React + position: relative; border-radius: var(--radius); width: calc(var(--bar-width) / 2); // We need to conserve space in narrow viewports flex-shrink: 0; height: 100%; + @include screen($lg) { width: var(--bar-width); } + .InsightCard & { width: calc(var(--bar-width) / 2) !important; // Also need to conserve space in cards } @@ -116,10 +129,12 @@ width: 100%; border-radius: var(--radius); cursor: pointer; + .InsightCard & { cursor: default; } } + .StepBar__unclickable { .StepBar__backdrop, .StepBar__fill { @@ -134,14 +149,16 @@ -22.5deg, transparent, transparent 0.5rem, - rgba(255, 255, 255, 0.5) 0.5rem, - rgba(255, 255, 255, 0.5) 1rem + rgb(255 255 255 / 50%) 0.5rem, + rgb(255 255 255 / 50%) 1rem ), var(--series-color); opacity: 0.125; + &:hover { opacity: 0.2; } + &:active { opacity: 0.25; } @@ -151,9 +168,11 @@ transition: filter 200ms ease; background: var(--series-color); height: var(--conversion-rate); + &:hover { filter: brightness(0.9); } + &:active { filter: brightness(0.85); } @@ -163,17 +182,20 @@ border-left: 1px solid var(--border); white-space: nowrap; height: 100%; + > .LemonRow { min-height: 1.5rem; padding: 0 0.5rem; font-weight: 500; margin-top: 0.25rem; + &:first-child { width: fit-content; font-weight: 600; margin-top: 0; } } + .funnel-inspect-button { line-height: 1.5rem; font-weight: inherit; @@ -182,23 +204,28 @@ .FunnelTooltip { width: 20rem; + table { width: 100%; border-collapse: collapse; border-spacing: 0; } + tr { height: 1.75rem; } + td:first-child { padding: 0 0.5rem; font-weight: 500; } + td:last-child { padding-right: 0.5rem; font-weight: 600; text-align: right; } + .table-subtext { padding-bottom: 0.25rem; } diff --git a/frontend/src/scenes/funnels/FunnelBarGraph/FunnelBarGraph.scss b/frontend/src/scenes/funnels/FunnelBarGraph/FunnelBarGraph.scss index f1662dd783db1..e234468e940d1 100644 --- a/frontend/src/scenes/funnels/FunnelBarGraph/FunnelBarGraph.scss +++ b/frontend/src/scenes/funnels/FunnelBarGraph/FunnelBarGraph.scss @@ -18,6 +18,7 @@ $glyph_height: 23px; // Based on .funnel-step-glyph .funnel-step { position: relative; padding-left: $series_container_width + 0.5rem; + &:not(:first-child) { &, .funnel-series-container { @@ -36,6 +37,7 @@ $glyph_height: 23px; // Based on .funnel-step-glyph .funnel-inspect-button { line-height: 1.5rem; + .value-inspector-button-icon { font-size: 1.5rem; margin-right: 0.25rem; @@ -99,6 +101,7 @@ $glyph_height: 23px; // Based on .funnel-step-glyph .funnel-step-title { @extend %mixin-text-ellipsis; + font-weight: bold; } diff --git a/frontend/src/scenes/ingestion/panels/InstructionsPanel.scss b/frontend/src/scenes/ingestion/panels/InstructionsPanel.scss index 005ff0d4af187..5d7b1c7ce4408 100644 --- a/frontend/src/scenes/ingestion/panels/InstructionsPanel.scss +++ b/frontend/src/scenes/ingestion/panels/InstructionsPanel.scss @@ -1,11 +1,13 @@ .InstructionsPanel { max-width: 50rem; + h1 { font-size: 28px; font-weight: 800; line-height: 40px; letter-spacing: -0.02em; } + h2 { font-size: 20px; font-weight: 800; @@ -13,13 +15,15 @@ letter-spacing: -0.02em; margin-top: 0.5rem; } + h3 { font-size: 16px; font-weight: 700; line-height: 24px; - letter-spacing: 0em; + letter-spacing: 0; margin-top: 0.5rem; } + ol { padding-left: 1rem; } diff --git a/frontend/src/scenes/insights/EmptyStates/EmptyStates.scss b/frontend/src/scenes/insights/EmptyStates/EmptyStates.scss index a7ec2f0af4c9d..abb96d022d645 100644 --- a/frontend/src/scenes/insights/EmptyStates/EmptyStates.scss +++ b/frontend/src/scenes/insights/EmptyStates/EmptyStates.scss @@ -3,8 +3,6 @@ flex-direction: column; justify-content: center; align-items: center; - padding-top: 2rem; - padding-bottom: 2rem; color: var(--muted); padding: 1rem; font-size: 1.1em; @@ -58,8 +56,10 @@ .ant-empty { height: 6rem; margin: 0; + .ant-empty-image { height: 100%; + svg { width: 4rem; } diff --git a/frontend/src/scenes/insights/Insight.scss b/frontend/src/scenes/insights/Insight.scss index fafdd2c177116..5ac69e14f709c 100644 --- a/frontend/src/scenes/insights/Insight.scss +++ b/frontend/src/scenes/insights/Insight.scss @@ -4,6 +4,7 @@ .insight-wrapper { &.insight-wrapper--singlecolumn { position: relative; + @include screen($xl) { display: flex; overflow: hidden; diff --git a/frontend/src/scenes/insights/InsightTooltip/InsightTooltip.scss b/frontend/src/scenes/insights/InsightTooltip/InsightTooltip.scss index 2dba11b4efb7e..df45e9cdac85b 100644 --- a/frontend/src/scenes/insights/InsightTooltip/InsightTooltip.scss +++ b/frontend/src/scenes/insights/InsightTooltip/InsightTooltip.scss @@ -24,6 +24,7 @@ border: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; + &:not(:last-child) { border-bottom: 1px solid var(--border); } @@ -41,23 +42,28 @@ width: 100%; overflow: hidden; } + .LemonTable__content > table > thead { letter-spacing: 0; + .datum-column { .LemonTable__header-content { white-space: nowrap; } } } + .LemonTable__content > table { .datum-label-column { font-weight: 600; display: flex; align-items: center; } + .series-data-cell { font-weight: 600; } + .tag-pill { background-color: var(--border-3000); margin-right: 0; diff --git a/frontend/src/scenes/insights/InsightTooltip/LEGACY_InsightTooltip.scss b/frontend/src/scenes/insights/InsightTooltip/LEGACY_InsightTooltip.scss index 9c105fcc2632a..996dd47bb8056 100644 --- a/frontend/src/scenes/insights/InsightTooltip/LEGACY_InsightTooltip.scss +++ b/frontend/src/scenes/insights/InsightTooltip/LEGACY_InsightTooltip.scss @@ -1,12 +1,9 @@ .legacy-ph-graph-tooltip { - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + box-shadow: 0 4px 12px rgb(0 0 0 / 10%); font-size: 14px; overflow-x: hidden; z-index: var(--z-graph-tooltip); transition: all 0.4s; -} - -.legacy-ph-graph-tooltip { max-width: 480px; padding: 8px 12px; border: 1px solid var(--border); @@ -41,6 +38,7 @@ display: flex; justify-content: center; align-items: center; + svg { font-size: 1.4em; margin-right: 4px; @@ -56,6 +54,7 @@ align-items: center; margin-top: 2px; font-style: italic; + svg { margin-left: 2px; margin-right: 6px; diff --git a/frontend/src/scenes/insights/filters/ActionFilter/ActionFilter.scss b/frontend/src/scenes/insights/filters/ActionFilter/ActionFilter.scss index 78ef6f4aa2e32..129c9a28765eb 100644 --- a/frontend/src/scenes/insights/filters/ActionFilter/ActionFilter.scss +++ b/frontend/src/scenes/insights/filters/ActionFilter/ActionFilter.scss @@ -16,7 +16,7 @@ margin-top: 0; .ActionFilterRow-content { - margin-bottom: 0px; + margin-bottom: 0; padding: 1rem; border-bottom: 1px solid var(--border); } diff --git a/frontend/src/scenes/insights/insightCommandLogic.ts b/frontend/src/scenes/insights/insightCommandLogic.ts index c94449d881249..e31060d552d85 100644 --- a/frontend/src/scenes/insights/insightCommandLogic.ts +++ b/frontend/src/scenes/insights/insightCommandLogic.ts @@ -1,7 +1,6 @@ import { Command, commandPaletteLogic } from 'lib/components/CommandPalette/commandPaletteLogic' import { kea, props, key, path, connect, events } from 'kea' import type { insightCommandLogicType } from './insightCommandLogicType' -import { compareFilterLogic } from 'lib/components/CompareFilter/compareFilterLogic' import { dateMapping } from 'lib/utils' import { InsightLogicProps } from '~/types' import { keyForInsightLogicProps } from 'scenes/insights/sharedUtils' @@ -15,7 +14,7 @@ export const insightCommandLogic = kea([ key(keyForInsightLogicProps('new')), path((key) => ['scenes', 'insights', 'insightCommandLogic', key]), - connect((props: InsightLogicProps) => [commandPaletteLogic, compareFilterLogic(props), insightVizDataLogic(props)]), + connect((props: InsightLogicProps) => [commandPaletteLogic, insightVizDataLogic(props)]), events(({ props }) => ({ afterMount: () => { const funnelCommands: Command[] = [ @@ -26,7 +25,8 @@ export const insightCommandLogic = kea([ icon: IconTrendingUp, display: 'Toggle "Compare Previous" on Graph', executor: () => { - compareFilterLogic(props).actions.toggleCompare() + const compare = insightVizDataLogic(props).values.compare + insightVizDataLogic(props).actions.updateInsightFilter({ compare: !compare }) }, }, ...dateMapping.map(({ key, values }) => ({ diff --git a/frontend/src/scenes/insights/insightVizDataLogic.ts b/frontend/src/scenes/insights/insightVizDataLogic.ts index c5540a155b360..62fd9dddc8c5a 100644 --- a/frontend/src/scenes/insights/insightVizDataLogic.ts +++ b/frontend/src/scenes/insights/insightVizDataLogic.ts @@ -39,7 +39,11 @@ import { isTrendsQuery, nodeKindToFilterProperty, } from '~/queries/utils' -import { NON_TIME_SERIES_DISPLAY_TYPES, PERCENT_STACK_VIEW_DISPLAY_TYPE } from 'lib/constants' +import { + NON_TIME_SERIES_DISPLAY_TYPES, + NON_VALUES_ON_SERIES_DISPLAY_TYPES, + PERCENT_STACK_VIEW_DISPLAY_TYPE, +} from 'lib/constants' import { getBreakdown, getCompare, @@ -127,13 +131,31 @@ export const insightVizDataLogic = kea([ isLifecycle: [(s) => [s.querySource], (q) => isLifecycleQuery(q)], isTrendsLike: [(s) => [s.querySource], (q) => isTrendsQuery(q) || isLifecycleQuery(q) || isStickinessQuery(q)], supportsDisplay: [(s) => [s.querySource], (q) => isTrendsQuery(q) || isStickinessQuery(q)], - supportsCompare: [(s) => [s.querySource], (q) => isTrendsQuery(q) || isStickinessQuery(q)], + supportsCompare: [ + (s) => [s.querySource, s.display, s.dateRange], + (q, display, dateRange) => + (isTrendsQuery(q) || isStickinessQuery(q)) && + display !== ChartDisplayType.WorldMap && + dateRange?.date_from !== 'all', + ], supportsPercentStackView: [ (s) => [s.querySource, s.display], (q, display) => isTrendsQuery(q) && PERCENT_STACK_VIEW_DISPLAY_TYPE.includes(display || ChartDisplayType.ActionsLineGraph), ], + supportsValueOnSeries: [ + (s) => [s.isTrends, s.isStickiness, s.isLifecycle, s.display], + (isTrends, isStickiness, isLifecycle, display) => { + if (isTrends || isStickiness) { + return !NON_VALUES_ON_SERIES_DISPLAY_TYPES.includes(display || ChartDisplayType.ActionsLineGraph) + } else if (isLifecycle) { + return true + } else { + return false + } + }, + ], dateRange: [(s) => [s.querySource], (q) => (q ? q.dateRange : null)], breakdown: [(s) => [s.querySource], (q) => (q ? getBreakdown(q) : null)], diff --git a/frontend/src/scenes/insights/views/BoldNumber/BoldNumber.scss b/frontend/src/scenes/insights/views/BoldNumber/BoldNumber.scss index d16bb9a54d8c6..b43f8c6bb0712 100644 --- a/frontend/src/scenes/insights/views/BoldNumber/BoldNumber.scss +++ b/frontend/src/scenes/insights/views/BoldNumber/BoldNumber.scss @@ -7,6 +7,7 @@ @include screen($md) { padding: 3rem 0 5rem; + .InsightCard & { padding: 2rem 0; } @@ -28,6 +29,7 @@ @include screen($md) { padding: 0 5rem; + .InsightCard & { padding: 0 2rem; } diff --git a/frontend/src/scenes/insights/views/Funnels/CorrelationMatrix.scss b/frontend/src/scenes/insights/views/Funnels/CorrelationMatrix.scss index e6a802681fce9..a315676b55406 100644 --- a/frontend/src/scenes/insights/views/Funnels/CorrelationMatrix.scss +++ b/frontend/src/scenes/insights/views/Funnels/CorrelationMatrix.scss @@ -3,12 +3,13 @@ display: flex; justify-content: center; } + .correlation-table-wrapper { table { border-radius: var(--radius); border: 1px solid var(--border); border-collapse: separate; - border-spacing: 0px; + border-spacing: 0; margin: 0 auto; td { @@ -21,6 +22,7 @@ font-weight: bold; padding-bottom: 0.25rem; } + &:first-child { border-left: none; } @@ -28,6 +30,7 @@ .table-title { color: var(--muted-alt); + td { border-top: none; } diff --git a/frontend/src/scenes/insights/views/Funnels/FunnelCorrelationTable.scss b/frontend/src/scenes/insights/views/Funnels/FunnelCorrelationTable.scss index e7e5a26f6c823..41934f4a6aa43 100644 --- a/frontend/src/scenes/insights/views/Funnels/FunnelCorrelationTable.scss +++ b/frontend/src/scenes/insights/views/Funnels/FunnelCorrelationTable.scss @@ -16,8 +16,7 @@ align-items: center; align-self: stretch; padding: 0.25rem 0.5rem; - justify-content: space-between; - align-content: space-between; + place-content: space-between space-between; border-top-left-radius: var(--radius); border-top-right-radius: var(--radius); @@ -45,6 +44,7 @@ font-weight: 600; font-size: 11px; line-height: 16px; + /* identical to box height, or 145% */ display: flex; @@ -52,7 +52,6 @@ letter-spacing: 0.02em; text-transform: uppercase; margin: 5px; - color: var(--muted); } @@ -60,6 +59,7 @@ border-radius: var(--radius) 0 0 var(--radius); border-right: none; } + .LemonCheckbox:last-child label { border-radius: 0 var(--radius) var(--radius) 0; } @@ -76,6 +76,7 @@ margin: 1rem; border: 1px solid var(--border); border-radius: var(--radius); + thead th { border-bottom: 1px solid var(--border); } diff --git a/frontend/src/scenes/insights/views/Histogram/Histogram.scss b/frontend/src/scenes/insights/views/Histogram/Histogram.scss index 27bac7fe2ab0d..e6d3138958889 100644 --- a/frontend/src/scenes/insights/views/Histogram/Histogram.scss +++ b/frontend/src/scenes/insights/views/Histogram/Histogram.scss @@ -69,9 +69,9 @@ // same as chart-js font-size: 12px; font-weight: normal; - font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; - + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; fill: var(--white); + &.outside { fill: #0f0f0f; } diff --git a/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.scss b/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.scss index be47ead478a54..2d59cd226cc7a 100644 --- a/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.scss +++ b/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.scss @@ -1,6 +1,7 @@ .insights-table.LemonTable--embedded { border-top: 1px solid var(--border); } + .InsightCard .insights-table { min-height: 100%; border-top: none; @@ -19,6 +20,7 @@ .insights-label { &.editable { cursor: pointer; + .EntityFilterInfo { color: var(--primary); font-weight: 500; diff --git a/frontend/src/scenes/insights/views/WorldMap/WorldMap.scss b/frontend/src/scenes/insights/views/WorldMap/WorldMap.scss index aca29481c5b97..d8f9bffe605e7 100644 --- a/frontend/src/scenes/insights/views/WorldMap/WorldMap.scss +++ b/frontend/src/scenes/insights/views/WorldMap/WorldMap.scss @@ -2,11 +2,13 @@ padding: 1rem 0; width: 100%; color: var(--border); + .landxx { fill: currentColor; stroke: var(--bg-light); stroke-width: 0.125rem; fill-rule: evenodd; + &:hover { color: var(--primary-dark) !important; } diff --git a/frontend/src/scenes/instance/SystemStatus/index.scss b/frontend/src/scenes/instance/SystemStatus/index.scss index d837403778489..b824861294f47 100644 --- a/frontend/src/scenes/instance/SystemStatus/index.scss +++ b/frontend/src/scenes/instance/SystemStatus/index.scss @@ -1,5 +1,6 @@ .system-status-scene { margin-bottom: 64px; + .metric-column { @media (min-width: 750px) { width: 33%; diff --git a/frontend/src/scenes/notebooks/Nodes/NodeWrapper.scss b/frontend/src/scenes/notebooks/Nodes/NodeWrapper.scss index a3b1acc1db115..179f475205dbf 100644 --- a/frontend/src/scenes/notebooks/Nodes/NodeWrapper.scss +++ b/frontend/src/scenes/notebooks/Nodes/NodeWrapper.scss @@ -77,6 +77,7 @@ &:hover, &.NotebookNode--selected { border-color: var(--border-color); + .NotebookNode__meta { pointer-events: all; visibility: visible; @@ -108,6 +109,7 @@ &--editable { border-radius: var(--radius); transition: background-color 150ms linear; + &:hover { background-color: var(--border); } diff --git a/frontend/src/scenes/notebooks/Notebook/Notebook.scss b/frontend/src/scenes/notebooks/Notebook/Notebook.scss index cd63e10b35fbe..5f7893e770de2 100644 --- a/frontend/src/scenes/notebooks/Notebook/Notebook.scss +++ b/frontend/src/scenes/notebooks/Notebook/Notebook.scss @@ -30,10 +30,12 @@ > .is-empty::before { content: attr(data-placeholder); float: left; - color: rgba(0, 0, 0, 0.2); + color: rgb(0 0 0 / 20%); + [theme='dark'] & { - color: rgba(255, 255, 255, 0.2); + color: rgb(255 255 255 / 20%); } + pointer-events: none; height: 0; } @@ -48,7 +50,7 @@ > ul[data-type='taskList'] { list-style-type: none; - padding-left: 0px; + padding-left: 0; li { display: flex; @@ -86,7 +88,7 @@ } > pre { - background-color: rgba(0, 0, 0, 0.05); + background-color: rgb(0 0 0 / 5%); border-radius: var(--radius); overflow-x: auto; margin-bottom: 0.5rem; @@ -95,7 +97,7 @@ > code, > p code { - background-color: rgba(0, 0, 0, 0.05); + background-color: rgb(0 0 0 / 5%); border-radius: var(--radius); padding: 0.2rem; } @@ -155,7 +157,7 @@ .NotebookColumn { position: relative; - width: 0px; + width: 0; transition: width var(--notebook-popover-transition-properties); --notebook-sidebar-height: calc(100vh - 9rem); @@ -163,8 +165,7 @@ .NotebookColumn__content { position: sticky; align-self: flex-start; - top: 0px; - + top: 0; transform: translateX(-100%); transition: transform var(--notebook-popover-transition-properties); } @@ -227,11 +228,11 @@ .NotebookInlineMenu { margin-bottom: -0.2rem; - box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.1); + box-shadow: 0 4px 10px 0 rgb(0 0 0 / 10%); .LemonInput { - border: 0px; - min-height: 0px; + border: 0; + min-height: 0; } } diff --git a/frontend/src/scenes/notebooks/NotebookPanel/NotebookPanel.scss b/frontend/src/scenes/notebooks/NotebookPanel/NotebookPanel.scss index c23308bf2eadf..d4a2460692e24 100644 --- a/frontend/src/scenes/notebooks/NotebookPanel/NotebookPanel.scss +++ b/frontend/src/scenes/notebooks/NotebookPanel/NotebookPanel.scss @@ -52,7 +52,6 @@ border: none; height: 100%; margin: 1rem; - justify-content: flex-start; align-items: initial; } diff --git a/frontend/src/scenes/notebooks/NotebookPanel/NotebookPopover.scss b/frontend/src/scenes/notebooks/NotebookPanel/NotebookPopover.scss index 1c8b49d798561..ba0ab7a664877 100644 --- a/frontend/src/scenes/notebooks/NotebookPanel/NotebookPopover.scss +++ b/frontend/src/scenes/notebooks/NotebookPanel/NotebookPopover.scss @@ -2,21 +2,15 @@ .NotebookPopover { position: fixed; - top: 0px; - right: 0px; - bottom: 0px; - left: 0px; + inset: 0; z-index: var(--z-modal); pointer-events: none; .NotebookPopover__backdrop { position: absolute; - top: 0px; - right: 0px; - bottom: 0px; - left: 0px; + inset: 0; z-index: 1; - background-color: rgba(0, 0, 0, 0.1); + background-color: rgb(0 0 0 / 10%); pointer-events: none; opacity: 0; transition: opacity 200ms ease-out; @@ -47,7 +41,7 @@ border-radius: var(--radius); background-color: var(--bg-3000); border: 1px solid var(--border-3000); - box-shadow: 0px 16px 16px rgba(0, 0, 0, 0); + box-shadow: 0 16px 16px rgb(0 0 0 / 0%); transition: box-shadow 150ms linear; overflow: hidden; } @@ -61,8 +55,9 @@ .NotebookPopover__content { transform: translateX(0); + .NotebookPopover__content__card { - box-shadow: 0px 16px 16px rgba(0, 0, 0, 0.15); + box-shadow: 0 16px 16px rgb(0 0 0 / 15%); } } } @@ -71,8 +66,9 @@ .NotebookPopover__content { transition: none; // NOTE: This shouldn't be none as it affects other transitions transform: translateX(calc(100% - 5rem)); + .NotebookPopover__content__card { - box-shadow: 0px 16px 16px rgba(0, 0, 0, 0.15); + box-shadow: 0 16px 16px rgb(0 0 0 / 15%); } } } @@ -91,10 +87,9 @@ } .NotebookPanelDropzone { - box-shadow: 0px 16px 16px rgba(0, 0, 0, 0.15); + box-shadow: 0 16px 16px rgb(0 0 0 / 15%); border: 2px dashed var(--border-3000); border-radius: var(--radius); - transition: all 150ms; height: 4rem; margin-bottom: 1rem; diff --git a/frontend/src/scenes/notebooks/NotebookScene.scss b/frontend/src/scenes/notebooks/NotebookScene.scss index d3c9b8e85811b..596dcd4efbed7 100644 --- a/frontend/src/scenes/notebooks/NotebookScene.scss +++ b/frontend/src/scenes/notebooks/NotebookScene.scss @@ -1,10 +1,7 @@ .NotebookScene { .Navigation3000 & { position: absolute; - left: 0; - top: 0; - bottom: 0; - right: 0; + inset: 0; overflow-y: auto; padding: 0 1rem; } diff --git a/frontend/src/scenes/persons/PersonDisplay.scss b/frontend/src/scenes/persons/PersonDisplay.scss index 9d65707aabd8d..1a4c0a82b7a14 100644 --- a/frontend/src/scenes/persons/PersonDisplay.scss +++ b/frontend/src/scenes/persons/PersonDisplay.scss @@ -1,9 +1,11 @@ .PersonDisplay { display: inline; + .ProfilePicture { transition: opacity 200ms ease; margin-right: 0.5rem; } + a:hover { .ProfilePicture { opacity: 0.75; diff --git a/frontend/src/scenes/persons/PersonScene.scss b/frontend/src/scenes/persons/PersonScene.scss index b96d0e15713e2..b22eea07f7361 100644 --- a/frontend/src/scenes/persons/PersonScene.scss +++ b/frontend/src/scenes/persons/PersonScene.scss @@ -7,6 +7,7 @@ padding: 0 0.25rem 0 0.375rem; color: var(--primary); cursor: pointer; + svg { margin-left: 0.25rem; } diff --git a/frontend/src/scenes/plugins/plugin/styles/metrics-drawer.scss b/frontend/src/scenes/plugins/plugin/styles/metrics-drawer.scss index 8ae94920b061e..b158af5a74892 100644 --- a/frontend/src/scenes/plugins/plugin/styles/metrics-drawer.scss +++ b/frontend/src/scenes/plugins/plugin/styles/metrics-drawer.scss @@ -1,10 +1,12 @@ .metrics-drawer { z-index: var(--z-drawer); + .metrics-chart-wrapper { canvas { max-width: 90%; max-height: 80%; } + canvas:hover { cursor: default !important; } diff --git a/frontend/src/scenes/project-homepage/ProjectHomepage.scss b/frontend/src/scenes/project-homepage/ProjectHomepage.scss index b8062e75dda4b..3066991290387 100644 --- a/frontend/src/scenes/project-homepage/ProjectHomepage.scss +++ b/frontend/src/scenes/project-homepage/ProjectHomepage.scss @@ -25,8 +25,9 @@ .top-list { margin-bottom: 1.5rem; + .posthog-3000 & { - margin-bottom: 0px; + margin-bottom: 0; } width: 33%; diff --git a/frontend/src/scenes/retention/RetentionTable.scss b/frontend/src/scenes/retention/RetentionTable.scss index afc444248fb4e..7e10b09fb8173 100644 --- a/frontend/src/scenes/retention/RetentionTable.scss +++ b/frontend/src/scenes/retention/RetentionTable.scss @@ -8,10 +8,11 @@ white-space: nowrap; font-weight: 500; border-left: 1px solid var(--border); - padding: 0rem 0.5rem; + padding: 0 0.5rem; border-top: 10px solid transparent; border-bottom: 10px solid transparent; text-align: left; + &:first-of-type { border-left: none; } @@ -30,7 +31,7 @@ } .RetentionTable__TextTab { - padding: 0rem 1rem 0rem 0.5rem; + padding: 0 1rem 0 0.5rem; white-space: nowrap; } @@ -63,6 +64,7 @@ .RetentionTable__Tab { cursor: initial; + &:hover { transform: none; } diff --git a/frontend/src/scenes/saved-insights/SavedInsights.scss b/frontend/src/scenes/saved-insights/SavedInsights.scss index 73ff3ab53d0fb..a9e79b54a7ba8 100644 --- a/frontend/src/scenes/saved-insights/SavedInsights.scss +++ b/frontend/src/scenes/saved-insights/SavedInsights.scss @@ -4,6 +4,7 @@ > .LemonTable td { padding-bottom: 0.75rem !important; padding-top: 0.75rem !important; + &.icon-column .LemonSkeleton { height: 2rem; width: 2rem; @@ -67,11 +68,13 @@ .insight-type-icon-wrapper { display: flex; align-items: center; + .icon-container { height: 22px; width: 22px; margin-right: 8px; position: relative; + .icon-container-inner { font-size: 22px; margin-left: -2px; @@ -83,9 +86,11 @@ position: relative; display: grid; grid-gap: 1rem; + @include screen($xl) { grid-template-columns: repeat(2, 1fr); } + @include screen($xxl) { grid-template-columns: repeat(3, 1fr); } diff --git a/frontend/src/scenes/session-recordings/player/PlayerFrame.scss b/frontend/src/scenes/session-recordings/player/PlayerFrame.scss index 78bbe50f457d0..28a6555789e01 100644 --- a/frontend/src/scenes/session-recordings/player/PlayerFrame.scss +++ b/frontend/src/scenes/session-recordings/player/PlayerFrame.scss @@ -14,7 +14,7 @@ position: absolute; iframe { - border: 0px; + border: 0; background-color: white; } @@ -40,14 +40,14 @@ display: inline-block; width: 20px; height: 20px; - background: rgb(73, 80, 246); + background: rgb(73 80 246); border-radius: 100%; transform: translate(-50%, -50%); opacity: 0.3; } .replayer-mouse.active::after { - animation: click 0.2s ease-in-out 1; + animation: PlayerFrame__click 0.2s ease-in-out 1; } .replayer-mouse.touch-device { @@ -59,12 +59,12 @@ border-radius: 100%; margin-left: -37px; margin-top: -37px; - border-color: rgba(73, 80, 246, 0); + border-color: rgb(73 80 246 / 0%); transition: left 0s linear, top 0s linear, border-color 0.2s ease-in-out; } .replayer-mouse.touch-device.touch-active { - border-color: rgba(73, 80, 246, 1); + border-color: rgb(73 80 246 / 100%); transition: left 0.25s linear, top 0.25s linear, border-color 0.2s ease-in-out; } @@ -73,7 +73,7 @@ } .replayer-mouse.touch-device.active::after { - animation: touch-click 0.2s ease-in-out 1; + animation: PlayerFrame__touch-click 0.2s ease-in-out 1; } .replayer-mouse-tail { @@ -81,12 +81,13 @@ pointer-events: none; } - @keyframes click { + @keyframes PlayerFrame__click { 0% { opacity: 0.3; width: 20px; height: 20px; } + 50% { opacity: 0.5; width: 10px; @@ -94,12 +95,13 @@ } } - @keyframes touch-click { + @keyframes PlayerFrame__touch-click { 0% { opacity: 0; width: 20px; height: 20px; } + 50% { opacity: 0.5; width: 10px; diff --git a/frontend/src/scenes/session-recordings/player/PlayerFrameOverlay.scss b/frontend/src/scenes/session-recordings/player/PlayerFrameOverlay.scss index 4ff8665202c6b..ad3bc2a5ae2bf 100644 --- a/frontend/src/scenes/session-recordings/player/PlayerFrameOverlay.scss +++ b/frontend/src/scenes/session-recordings/player/PlayerFrameOverlay.scss @@ -1,25 +1,17 @@ .PlayerFrameOverlay { position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; + inset: 0; z-index: 10; .PlayerFrameOverlay__content { position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - + inset: 0; display: flex; justify-content: center; align-items: center; z-index: 1; - transition: opacity 100ms; - background-color: rgba(0, 0, 0, 0.15); + background-color: rgb(0 0 0 / 15%); opacity: 0.8; &:hover { diff --git a/frontend/src/scenes/session-recordings/player/PlayerMeta.scss b/frontend/src/scenes/session-recordings/player/PlayerMeta.scss index 1864a9b8b3660..3312579e0b711 100644 --- a/frontend/src/scenes/session-recordings/player/PlayerMeta.scss +++ b/frontend/src/scenes/session-recordings/player/PlayerMeta.scss @@ -18,7 +18,7 @@ transition: 200ms height ease-out, 200ms border-bottom-color ease-out; &--enter { - height: 0px; + height: 0; } &--enter-active, @@ -33,7 +33,7 @@ } &--exit-active { - height: 0px; + height: 0; } } @@ -53,7 +53,7 @@ .PlayerMetaPersonProperties { position: fixed; top: 48px; - left: 0px; + left: 0; bottom: 97px; // NOTE: This isn't perfect but for now hardcoded to match the bottom area size. z-index: 1; max-width: 40rem; diff --git a/frontend/src/scenes/session-recordings/player/PlayerUpNext.scss b/frontend/src/scenes/session-recordings/player/PlayerUpNext.scss index 63f82f57f5fe9..850ac5880448f 100644 --- a/frontend/src/scenes/session-recordings/player/PlayerUpNext.scss +++ b/frontend/src/scenes/session-recordings/player/PlayerUpNext.scss @@ -30,21 +30,20 @@ line-height: 1.5rem; min-height: 2.5rem; padding: 0.25rem 0.75rem; - border-radius: var(--radius); box-shadow: var(--shadow-elevation); - background-color: rgba(255, 255, 255, 0.75); + background-color: rgb(255 255 255 / 75%); backdrop-filter: blur(5px); font-weight: 600; cursor: pointer; overflow: hidden; - border: 1px solid rgba(0, 0, 0, 0.5); + border: 1px solid rgb(0 0 0 / 50%); .PlayerUpNextButtonBackground { position: absolute; - left: 0px; - top: 0px; - bottom: 0px; + left: 0; + top: 0; + bottom: 0; width: 0; background-color: var(--bg-light); color: var(--primary-alt); @@ -52,7 +51,7 @@ &.PlayerUpNextButton--animating { .PlayerUpNextButtonBackground { - animation: PlayerUpNextButtonBackgroundAnimation 3s linear forwards; + animation: PlayerUpNextButtonBackground__expand 3s linear forwards; } } @@ -64,10 +63,11 @@ } } -@keyframes PlayerUpNextButtonBackgroundAnimation { +@keyframes PlayerUpNextButtonBackground__expand { 0% { width: 0; } + 100% { width: 100%; } diff --git a/frontend/src/scenes/session-recordings/player/SessionRecordingPlayer.scss b/frontend/src/scenes/session-recordings/player/SessionRecordingPlayer.scss index 7d5471d26e345..f57dc4c405164 100644 --- a/frontend/src/scenes/session-recordings/player/SessionRecordingPlayer.scss +++ b/frontend/src/scenes/session-recordings/player/SessionRecordingPlayer.scss @@ -16,7 +16,7 @@ &--no-border { border: none; - border-radius: 0px; + border-radius: 0; } .SessionRecordingPlayer__body { @@ -30,23 +30,21 @@ .SessionRecordingPlayer__main { flex: 1; + padding-right: var(--inspector-peek-width); } &--fullscreen { position: fixed; - left: 0px; - top: 0px; - right: 0px; - bottom: 0px; + inset: 0; overflow-y: auto; background-color: var(--bg-light); z-index: var(--z-modal); border: none; - border-radius: 0px; + border-radius: 0; .SessionRecordingPlayer__body { height: 100%; - margin: 0rem; + margin: 0; border-radius: 0; } } @@ -64,14 +62,9 @@ } } - .SessionRecordingPlayer__main { - padding-right: var(--inspector-peek-width); - } - .SessionRecordingPlayer__inspector { flex-shrink: 0; border-left: 1px solid var(--border); - position: absolute; right: 0; top: 0; @@ -79,17 +72,13 @@ z-index: 10; width: var(--inspector-width); max-width: 95%; - transform: translateX(calc(100% - var(--inspector-peek-width))); transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1); + box-shadow: 0 0 5px rgb(0 0 0 / 10%); .PlayerInspectorPreview { position: absolute; - left: 0; - right: 0; - bottom: 0; - top: 0; + inset: 0; z-index: 1; pointer-events: none; transition: opacity 0.2s ease-in-out; @@ -99,7 +88,7 @@ &--inspector-focus { .SessionRecordingPlayer__inspector { transform: translateX(0); - box-shadow: -10px 0px 20px rgba(0, 0, 0, 0.2); + box-shadow: -10px 0 20px rgb(0 0 0 / 20%); .PlayerInspectorPreview { opacity: 0; @@ -112,7 +101,7 @@ .SessionRecordingPlayer__main { padding-right: 0; } - .SessionRecordingPlayer__inspector, + .SessionRecordingPlayer__inspector { min-width: 30%; width: 40%; @@ -148,10 +137,7 @@ font-size: 6px; font-weight: bold; text-align: center; - left: 0; - right: 0; - top: 0; - bottom: 0; + inset: 0; display: flex; align-items: center; justify-content: center; diff --git a/frontend/src/scenes/session-recordings/player/controller/Seekbar.scss b/frontend/src/scenes/session-recordings/player/controller/Seekbar.scss index ca0ef9bd77843..1ee0c5586e7d0 100644 --- a/frontend/src/scenes/session-recordings/player/controller/Seekbar.scss +++ b/frontend/src/scenes/session-recordings/player/controller/Seekbar.scss @@ -11,17 +11,20 @@ &:hover, &--scrubbing { --bar-height: 8px; + + .PlayerSeekBarPreview { + opacity: 1; + } } .PlayerSeekbar__slider { z-index: 2; - position: relative; height: var(--bar-height); background-color: var(--border-light); border-radius: var(--bar-height); position: absolute; - left: 0px; - right: 0px; + left: 0; + right: 0; top: calc((var(--slider-height) - var(--bar-height)) / 2); transition: height 150ms ease-in-out, top 150ms ease-in-out; cursor: pointer; @@ -29,12 +32,11 @@ .PlayerSeekbar__bufferbar, .PlayerSeekbar__currentbar, .PlayerSeekbar__segments { - width: 100%; position: absolute; height: 100%; - left: 0px; - top: 0px; - width: 0px; + left: 0; + top: 0; + width: 0; } .PlayerSeekbar__bufferbar { @@ -102,19 +104,11 @@ font-weight: 600; color: #fff; background-color: var(--muted-dark); - transform: translateX(-50%); margin-bottom: 0.5rem; } } } - - &:hover, - &--scrubbing { - .PlayerSeekBarPreview { - opacity: 1; - } - } } .PlayerSeekbarTicks { @@ -130,7 +124,7 @@ cursor: pointer; position: absolute; height: 100%; - top: 0px; + top: 0; transition: transform 150ms ease-in-out; &--warning { @@ -179,6 +173,7 @@ opacity: 1; visibility: visible; } + .PlayerSeekbarTick__line { opacity: 1; } diff --git a/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorList.scss b/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorList.scss index e9d183d550ee8..b821b4b8d4c21 100644 --- a/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorList.scss +++ b/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorList.scss @@ -8,7 +8,7 @@ height: 0.5rem; margin-top: 0.25rem; background-color: var(--primary); - border-radius: var(--radius) 0px 0px var(--radius); + border-radius: var(--radius) 0 0 var(--radius); transition: transform 200ms linear; will-change: transform; } diff --git a/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.scss b/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.scss index afdbf12c51d5c..455928f1dad82 100644 --- a/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.scss +++ b/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.scss @@ -5,7 +5,6 @@ display: flex; flex-direction: row; justify-content: flex-start; - align-items: flex-start; overflow: hidden; border: 1px solid var(--border); diff --git a/frontend/src/scenes/settings/Settings.scss b/frontend/src/scenes/settings/Settings.scss index 84bc262bb7016..ac3e09d44c3e1 100644 --- a/frontend/src/scenes/settings/Settings.scss +++ b/frontend/src/scenes/settings/Settings.scss @@ -22,7 +22,6 @@ &--compact { gap: 0; - flex-direction: column; .Settings__sections { diff --git a/frontend/src/scenes/surveys/SurveyAppearance.scss b/frontend/src/scenes/surveys/SurveyAppearance.scss index 640e99ec703e0..32ee384fc1d83 100644 --- a/frontend/src/scenes/surveys/SurveyAppearance.scss +++ b/frontend/src/scenes/surveys/SurveyAppearance.scss @@ -1,12 +1,12 @@ .survey-form { - margin: 0px; + margin: 0; color: black; font-weight: normal; - font-family: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', 'Roboto', Helvetica, Arial, sans-serif, + font-family: -apple-system, BlinkMacSystemFont, Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; text-align: left; width: 320px; - border-bottom: 0px; + border-bottom: 0; flex-direction: column; box-shadow: -6px 0 16px -8px rgb(0 0 0 / 8%), -9px 0 28px 0 rgb(0 0 0 / 5%), -12px 0 48px 16px rgb(0 0 0 / 3%); border-radius: 10px; @@ -14,15 +14,16 @@ position: relative; box-sizing: border-box; } + .form-submit[disabled] { opacity: 0.6; filter: grayscale(100%); cursor: not-allowed; } + .survey-form textarea { - color: #2d2d2d; font-size: 14px; - font-family: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', 'Roboto', Helvetica, Arial, sans-serif, + font-family: -apple-system, BlinkMacSystemFont, Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background: white; color: black; @@ -33,6 +34,7 @@ border-radius: 6px; margin-top: 14px; } + .form-submit { box-sizing: border-box; margin: 0; @@ -52,16 +54,18 @@ font-size: 14px; border-radius: 6px; outline: 0; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12); - box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045); + text-shadow: 0 -1px 0 rgb(0 0 0 / 12%); + box-shadow: 0 2px 0 rgb(0 0 0 / 4.5%); width: 100%; } + .form-cancel { float: right; border: none; background: none; cursor: pointer; } + .cancel-btn-wrapper { position: absolute; width: 35px; @@ -75,13 +79,16 @@ justify-content: center; align-items: center; } + .bolded { font-weight: 600; } + .buttons { display: flex; justify-content: center; } + .footer-branding { font-size: 11px; margin-top: 10px; @@ -94,59 +101,73 @@ text-decoration: none; color: inherit !important; } + .survey-box { padding: 20px 25px 10px; display: flex; flex-direction: column; } + .survey-question { font-weight: 500; font-size: 14px; } + .question-textarea-wrapper { display: flex; flex-direction: column; } + .description { font-size: 13px; margin-top: 5px; opacity: 0.6; } + .ratings-number { font-size: 14px; - padding: 8px 0px; + padding: 8px 0; border: none; } + .ratings-number:hover { cursor: pointer; } + .rating-options { margin-top: 14px; } + .rating-options-buttons { display: grid; border-radius: 6px; overflow: hidden; } + .rating-options-buttons > .ratings-number { border-right: 1px solid; } + .rating-options-buttons > .ratings-number:last-of-type { - border-right: 0px !important; + border-right: 0 !important; } + .rating-options-emoji { display: flex; justify-content: space-between; } + .ratings-emoji { font-size: 16px; background-color: transparent; border: none; - padding: 0px; + padding: 0; } + .ratings-emoji:hover { cursor: pointer; } + .rating-text { display: flex; flex-direction: row; @@ -155,11 +176,13 @@ margin-top: 6px; opacity: 0.6; } + .multiple-choice-options { margin-top: 13px; font-size: 14px; color: black; } + .multiple-choice-options .choice-option { display: flex; align-items: center; @@ -169,8 +192,9 @@ margin-bottom: 5px; position: relative; } + .multiple-choice-options > .choice-option:last-of-type { - margin-bottom: 0px; + margin-bottom: 0; } .multiple-choice-options input { @@ -181,41 +205,49 @@ height: 100%; inset: 0; } + .choice-check { position: absolute; right: 10px; background: white; } + .choice-check svg { display: none; } + .multiple-choice-options .choice-option:hover .choice-check svg { display: inline-block; opacity: 0.25; } + .multiple-choice-options input:checked + label + .choice-check svg { display: inline-block; - opacity: 100% !important; + opacity: 1 !important; } + .multiple-choice-options input[type='checkbox']:checked + label { font-weight: bold; } + .multiple-choice-options input:checked + label { - border: 1.5px solid rgba(0, 0, 0); + border: 1.5px solid rgb(0 0 0); } + .multiple-choice-options label { width: 100%; cursor: pointer; padding: 10px; - border: 1.5px solid rgba(0, 0, 0, 0.25); + border: 1.5px solid rgb(0 0 0 / 25%); border-radius: 4px; background: white; } + .thank-you-message { position: relative; - bottom: 0px; + bottom: 0; box-shadow: -6px 0 16px -8px rgb(0 0 0 / 8%), -9px 0 28px 0 rgb(0 0 0 / 5%), -12px 0 48px 16px rgb(0 0 0 / 3%); - font-family: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', 'Roboto', Helvetica, Arial, sans-serif, + font-family: -apple-system, BlinkMacSystemFont, Inter, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; border-radius: 10px; padding: 20px 25px 10px; @@ -225,23 +257,28 @@ line-height: 1.4; box-sizing: border-box; } + .thank-you-message-body { margin-top: 6px; font-size: 14px; } + .thank-you-message-header { - margin: 10px 0px 0px; + margin: 10px 0 0; font-weight: bold; font-size: 19px; color: inherit; } + .thank-you-message-container .form-submit { margin-top: 20px; margin-bottom: 10px; } + .thank-you-message-countdown { margin-left: 6px; } + .bottom-section { margin-top: 14px; } diff --git a/frontend/src/scenes/surveys/SurveyTemplates.scss b/frontend/src/scenes/surveys/SurveyTemplates.scss index 9d950ef65b1c3..e0706c96e65df 100644 --- a/frontend/src/scenes/surveys/SurveyTemplates.scss +++ b/frontend/src/scenes/surveys/SurveyTemplates.scss @@ -15,8 +15,6 @@ } .SurveyTemplate { - -ms-transform: scale(0.8, 0.8); /* IE 9 */ - -webkit-transform: scale(0.8, 0.8); /* Safari */ transform: scale(0.8, 0.8); } } diff --git a/frontend/src/scenes/surveys/SurveyView.scss b/frontend/src/scenes/surveys/SurveyView.scss index 173960fa70e1f..40c0cf169a8ab 100644 --- a/frontend/src/scenes/surveys/SurveyView.scss +++ b/frontend/src/scenes/surveys/SurveyView.scss @@ -15,9 +15,7 @@ grid-template-rows: 1fr auto; margin-bottom: 10px; break-inside: avoid; - box-sizing: border-box; /* add this */ - -moz-box-sizing: border-box; /* Firefox */ - -webkit-box-sizing: border-box; /* Older Webkit browsers */ + box-sizing: border-box; } .masonry-item-text { diff --git a/frontend/src/scenes/trends/viz/ActionsPie.scss b/frontend/src/scenes/trends/viz/ActionsPie.scss index f333b07b09e89..779ebf8864291 100644 --- a/frontend/src/scenes/trends/viz/ActionsPie.scss +++ b/frontend/src/scenes/trends/viz/ActionsPie.scss @@ -1,6 +1,7 @@ .actions-pie-component { min-width: 33%; height: 100%; + // No padding at the top because usually there's whitespace between "Computed ..." and "Show legend" // More padding at the bottom to give the number some breathing room padding: 0 1rem 2rem; diff --git a/frontend/src/styles/fonts.scss b/frontend/src/styles/fonts.scss index acda559f9d01b..9633ed07675ee 100644 --- a/frontend/src/styles/fonts.scss +++ b/frontend/src/styles/fonts.scss @@ -1,6 +1,6 @@ /* Inter; bold (700); latin */ @font-face { - font-family: 'Inter'; + font-family: Inter; font-style: normal; font-weight: 700; font-display: swap; @@ -10,7 +10,7 @@ } @font-face { - font-family: 'Inter'; + font-family: Inter; font-style: normal; font-weight: 500; font-display: swap; @@ -21,7 +21,7 @@ /* Inter; normal (400); latin */ @font-face { - font-family: 'Inter'; + font-family: Inter; font-style: normal; font-weight: 400; font-display: swap; diff --git a/frontend/src/styles/functions.scss b/frontend/src/styles/functions.scss index d3b9636f804ff..4fdd8c8d0b7dc 100644 --- a/frontend/src/styles/functions.scss +++ b/frontend/src/styles/functions.scss @@ -1,11 +1,16 @@ +@use 'sass:math'; + @function escape-number($value) { - $int: floor($value); + $int: math.floor($value); $fract: $value - $int; - @if ($fract == 0) { + + @if $fract == 0 { @return $int; } - @while ($fract != floor($fract)) { + + @while $fract != math.floor($fract) { $fract: $fract * 10; } - @return $int + '\\.'+ $fract; + + @return $int + '\\.'+ $fract; /* stylelint-disable-line scss/operator-no-unspaced */ } diff --git a/frontend/src/styles/global.scss b/frontend/src/styles/global.scss index f7e1274cc469d..2c35db1562c61 100644 --- a/frontend/src/styles/global.scss +++ b/frontend/src/styles/global.scss @@ -7,6 +7,8 @@ Only 400 (`normal`), 500 (`var(--font-medium)`), 600 (`var(--font-semibold)`), o */ +@use 'sass:map'; + // Global components @import '../../../node_modules/react-toastify/dist/ReactToastify'; @import 'fonts'; @@ -26,10 +28,6 @@ body strong { font-weight: 600; } -.main-app-content { - background-color: var(--bg-light); -} - // Disable default styling for ul ul { margin-bottom: 0; @@ -75,8 +73,10 @@ ul { .page-caption { @extend .text-sm; + max-width: 48rem; margin-bottom: 1rem; + &.tabbed { margin-bottom: 0.5rem; } @@ -144,6 +144,7 @@ input::-ms-clear { // Highlight background blink +/* stylelint-disable-next-line keyframes-name-pattern */ @keyframes highlight { 0% { background-color: var(--mark); @@ -156,6 +157,7 @@ input::-ms-clear { // Generic 360 spin +/* stylelint-disable-next-line keyframes-name-pattern */ @keyframes spin { 0% { transform: rotateZ(0deg); @@ -188,6 +190,7 @@ input::-ms-clear { .Toastify__toast-body { @extend .text-sm; @extend .text-default; + font-weight: 500; padding: 0; @@ -243,11 +246,11 @@ input::-ms-clear { } &::before { - box-shadow: 16px 0 16px -16px rgba(0, 0, 0, 0.25) inset; + box-shadow: 16px 0 16px -16px rgb(0 0 0 / 25%) inset; } &::after { - box-shadow: -16px 0 16px -16px rgba(0, 0, 0, 0.25) inset; + box-shadow: -16px 0 16px -16px rgb(0 0 0 / 25%) inset; } &.scrollable--right::after, @@ -270,11 +273,13 @@ input::-ms-clear { label { font-weight: bold; + @extend .text-sm; } .caption { color: var(--muted); + @extend .text-sm; } @@ -466,8 +471,8 @@ input::-ms-clear { .overlay--danger & { background: repeating-linear-gradient( -45deg, - rgba(255, 255, 255, 0.5), - rgba(255, 255, 255, 0.5) 0.75rem, + rgb(255 255 255 / 50%), + rgb(255 255 255 / 50%) 0.75rem, var(--danger) 0.5rem, var(--danger) 20px ); @@ -497,6 +502,7 @@ input::-ms-clear { width: 100%; padding: 0 1rem 1rem; flex: 1; + background-color: var(--bg-light); @include screen($sm) { padding: 0 1rem 2rem; @@ -583,6 +589,7 @@ body { --border-bold: var(--border-bold-3000); --mid: var(--bg-3000); --side: var(--bg-3000); + background: var(--bg-3000); overflow: hidden; // Each area handles scrolling individually (e.g. navbar, scene, side panel) @@ -591,12 +598,15 @@ body { width: 0.5rem; height: 0.5rem; } + ::-webkit-scrollbar-track { background: var(--accent-3000); } + ::-webkit-scrollbar-thumb { border-radius: 0.25rem; background: var(--trace-3000); + &:hover { background: var(--muted-3000); } @@ -659,12 +669,15 @@ body { .ant-modal-mask { z-index: var(--z-ant-modal-mask); } + .ant-modal-wrap { z-index: var(--z-ant-modal-wrap); } + .ant-message { z-index: var(--z-ant-message); } + .ant-select-dropdown { z-index: var(--z-ant-select-dropdown); background-color: var(--bg-3000); @@ -730,6 +743,7 @@ body { .ant-table-small .ant-table-thead > tr > th { background: var(--mid); } + .ant-table-tbody > tr > td { border-bottom-color: var(--border); } @@ -749,6 +763,7 @@ body { animation-duration: 0ms !important; animation-iteration-count: 1 !important; } + // Hide some parts of the UI that were causing flakiness ::-webkit-scrollbar, // Scrollbar in WebKit/Blink browsers .LemonTabs__bar::after, // Active tab slider diff --git a/frontend/src/styles/mixins.scss b/frontend/src/styles/mixins.scss index b55a6e3feb337..6fb6db7db668a 100644 --- a/frontend/src/styles/mixins.scss +++ b/frontend/src/styles/mixins.scss @@ -28,7 +28,7 @@ } @mixin screen($breakpoint) { - @if $breakpoint == null { + @if not $breakpoint { @content; } @else { @media screen and (min-width: $breakpoint) { diff --git a/frontend/src/styles/utilities.scss b/frontend/src/styles/utilities.scss index 0f26bf65d4b11..0e33b9b17b2c1 100644 --- a/frontend/src/styles/utilities.scss +++ b/frontend/src/styles/utilities.scss @@ -1,5 +1,4 @@ @use 'sass:string'; - @import 'vars'; @import 'mixins'; @@ -83,10 +82,7 @@ } .inset-#{escape-number($space)} { - top: #{$space * 0.25}rem; - right: #{$space * 0.25}rem; - bottom: #{$space * 0.25}rem; - left: #{$space * 0.25}rem; + inset: #{$space * 0.25}rem #{$space * 0.25}rem #{$space * 0.25}rem #{$space * 0.25}rem; } .inset-x-#{escape-number($space)} { @@ -115,15 +111,15 @@ } @each $side in $sides { - .m#{str-slice($side, 0, 1)}-#{escape-number($space)} { + .m#{string.slice($side, 0, 1)}-#{escape-number($space)} { margin-#{$side}: #{$space * 0.25}rem; } - .-m#{str-slice($side, 0, 1)}-#{escape-number($space)} { + .-m#{string.slice($side, 0, 1)}-#{escape-number($space)} { margin-#{$side}: #{-$space * 0.25}rem; } - .p#{str-slice($side, 0, 1)}-#{escape-number($space)} { + .p#{string.slice($side, 0, 1)}-#{escape-number($space)} { padding-#{$side}: #{$space * 0.25}rem; } } @@ -132,18 +128,23 @@ .w-px { width: 1px; } + .h-px { height: 1px; } + .min-w-px { min-width: 1px; } + .max-w-px { max-width: 1px; } + .min-h-px { min-height: 1px; } + .max-h-px { max-height: 1px; } @@ -212,7 +213,7 @@ // Margins/padding @each $kind in ('margin', 'padding') { - $char: str-slice($kind, 0, 1); + $char: string.slice($kind, 0, 1); .#{$char}-auto { #{$kind}: auto; @@ -241,11 +242,11 @@ } @each $side in $sides { - .#{$char}#{str-slice($side, 0, 1)}-auto { + .#{$char}#{string.slice($side, 0, 1)}-auto { #{$kind}-#{$side}: auto; } - .#{$char}#{str-slice($side, 0, 1)}-px { + .#{$char}#{string.slice($side, 0, 1)}-px { #{$kind}-#{$side}: 1px; } } @@ -257,89 +258,117 @@ // Border .border-0 { - border-width: 0px; + border-width: 0; } + .border-2 { border-width: 2px; } + .border-4 { border-width: 4px; } + .border-6 { border-width: 6px; } + .border-8 { border-width: 8px; } + .border-t-0 { - border-top-width: 0px; + border-top-width: 0; } + .border-t-2 { border-top-width: 2px; } + .border-t-4 { border-top-width: 4px; } + .border-t-6 { border-top-width: 6px; } + .border-t-8 { border-top-width: 8px; } + .border-t { border-top-width: 1px; } + .border-r-0 { - border-right-width: 0px; + border-right-width: 0; } + .border-r-2 { border-right-width: 2px; } + .border-r-4 { border-right-width: 4px; } + .border-r-6 { border-right-width: 6px; } + .border-r-8 { border-right-width: 8px; } + .border-r { border-right-width: 1px; } + .border-b-0 { - border-bottom-width: 0px; + border-bottom-width: 0; } + .border-b-2 { border-bottom-width: 2px; } + .border-b-4 { border-bottom-width: 4px; } + .border-b-6 { border-bottom-width: 6px; } + .border-b-8 { border-bottom-width: 8px; } + .border-b { border-bottom-width: 1px; } + .border-l-0 { - border-left-width: 0px; + border-left-width: 0; } + .border-l-2 { border-left-width: 2px; } + .border-l-4 { border-left-width: 4px; } + .border-l-6 { border-left-width: 6px; } + .border-l-8 { border-left-width: 8px; } + .border-l { border-left-width: 1px; } @@ -347,23 +376,29 @@ .border-solid { border-style: solid; } + .border-dashed { border-style: dashed; } + .border-dotted { border-style: dotted; } + .border-double { border-style: double; } + .border-hidden { border-style: hidden; } + .border-none { border-style: none; } $decorations: underline, overline, line-through, no-underline; + @each $decoration in $decorations { .#{$decoration} { text-decoration-line: $decoration; @@ -376,9 +411,11 @@ $decorations: underline, overline, line-through, no-underline; .decoration-inherit { text-decoration-color: inherit; } + .decoration-current { text-decoration-color: currentColor; } + .decoration-transparent { text-decoration-color: transparent; } @@ -429,7 +466,7 @@ $decorations: underline, overline, line-through, no-underline; // Widths / heights @each $kind in ('width', 'height') { - $char: str-slice($kind, 1, 1); + $char: string.slice($kind, 1, 1); .#{$char}-auto { #{$kind}: auto; } @@ -437,7 +474,7 @@ $decorations: underline, overline, line-through, no-underline; #{$kind}: 100%; } .#{$char}-screen { - #{$kind}: unquote('100v' + $char); + #{$kind}: string.unquote('100v' + $char); } .#{$char}-min { #{$kind}: min-content; @@ -453,14 +490,14 @@ $decorations: underline, overline, line-through, no-underline; min-#{$kind}: 100%; } .min-#{$char}-screen { - min-#{$kind}: unquote('100v' + $char); + min-#{$kind}: string.unquote('100v' + $char); } .max-#{$char}-full { max-#{$kind}: 100%; } .max-#{$char}-screen { - max-#{$kind}: unquote('100v' + $char); + max-#{$kind}: string.unquote('100v' + $char); } @each $variant in ('', 'max-', 'min-') { @@ -469,11 +506,11 @@ $decorations: underline, overline, line-through, no-underline; } .#{$variant}#{$char}-1\/3 { - #{$variant}#{$kind}: 33.333333%; + #{$variant}#{$kind}: 33.3333%; } .#{$variant}#{$char}-2\/3 { - #{$variant}#{$kind}: 66.666667%; + #{$variant}#{$kind}: 66.6667%; } .#{$variant}#{$char}-1\/4 { @@ -640,18 +677,23 @@ $decorations: underline, overline, line-through, no-underline; .justify-start { justify-content: flex-start; } + .justify-end { justify-content: flex-end; } + .justify-center { justify-content: center; } + .justify-between { justify-content: space-between; } + .justify-around { justify-content: space-around; } + .justify-evenly { justify-content: space-evenly; } @@ -659,15 +701,19 @@ $decorations: underline, overline, line-through, no-underline; .items-start { align-items: flex-start; } + .items-end { align-items: flex-end; } + .items-center { align-items: center; } + .items-baseline { align-items: baseline; } + .items-stretch { align-items: stretch; } @@ -675,18 +721,23 @@ $decorations: underline, overline, line-through, no-underline; .self-auto { align-self: auto; } + .self-start { align-self: flex-start; } + .self-end { align-self: flex-end; } + .self-center { align-self: center; } + .self-stretch { align-self: stretch; } + .self-baseline { align-self: baseline; } @@ -805,33 +856,43 @@ $decorations: underline, overline, line-through, no-underline; .font-thin { font-weight: 100; } + .font-extralight { font-weight: 200; } + .font-light { font-weight: 300; } + .font-normal { font-weight: 400; } + .font-medium { font-weight: 500; } + .font-semibold { font-weight: 600; } + .font-bold { font-weight: 700; } + .font-extrabold { font-weight: 800; } + .font-black { font-weight: 900; } + .italic { font-style: italic; } + .not-italic { font-style: normal; } @@ -852,15 +913,19 @@ $decorations: underline, overline, line-through, no-underline; .whitespace-normal { white-space: normal; } + .whitespace-nowrap { white-space: nowrap; } + .whitespace-pre { white-space: pre; } + .whitespace-pre-line { white-space: pre-line; } + .whitespace-pre-wrap { white-space: pre-wrap; } @@ -869,54 +934,67 @@ $decorations: underline, overline, line-through, no-underline; font-size: 0.625rem; /* 10px */ line-height: 0.75rem; /* 12px */ } + .text-xs { font-size: 0.75rem; /* 12px */ line-height: 1rem; /* 16px */ } + .text-sm { font-size: 0.875rem; /* 14px */ line-height: 1.25rem; /* 20px */ } + .text-base { font-size: 1rem; /* 16px */ line-height: 1.5rem; /* 24px */ } + .text-lg { font-size: 1.125rem; /* 18px */ line-height: 1.75rem; /* 28px */ } + .text-xl { font-size: 1.25rem; /* 20px */ line-height: 1.75rem; /* 28px */ } + .text-2xl { font-size: 1.5rem; /* 24px */ line-height: 2rem; /* 32px */ } + .text-3xl { font-size: 1.875rem; /* 30px */ line-height: 2.25rem; /* 36px */ } + .text-4xl { font-size: 2.25rem; /* 36px */ line-height: 2.5rem; /* 40px */ } + .text-5xl { font-size: 3rem; /* 48px */ line-height: 1; } + .text-6xl { font-size: 3.75rem; /* 60px */ line-height: 1; } + .text-7xl { font-size: 4.5rem; /* 72px */ line-height: 1; } + .text-8xl { font-size: 6rem; /* 96px */ line-height: 1; } + .text-9xl { font-size: 8rem; /* 128px */ line-height: 1; @@ -931,18 +1009,22 @@ $decorations: underline, overline, line-through, no-underline; .rounded { border-radius: var(--radius); /* 4px */ } + .rounded-l { border-top-left-radius: var(--radius); /* 4px */ border-bottom-left-radius: var(--radius); /* 4px */ } + .rounded-r { border-top-right-radius: var(--radius); /* 4px */ border-bottom-right-radius: var(--radius); /* 4px */ } + .rounded-t { border-top-left-radius: var(--radius); /* 4px */ border-top-right-radius: var(--radius); /* 4px */ } + .rounded-b { border-bottom-left-radius: var(--radius); /* 4px */ border-bottom-right-radius: var(--radius); /* 4px */ @@ -951,10 +1033,12 @@ $decorations: underline, overline, line-through, no-underline; .rounded-none { border-radius: 0; } + .rounded-r-none { border-top-right-radius: 0; border-bottom-right-radius: 0; } + .rounded-l-none { border-top-left-radius: 0; border-bottom-left-radius: 0; @@ -967,21 +1051,27 @@ $decorations: underline, overline, line-through, no-underline; .rounded-md { border-radius: calc(var(--radius) * 1.5); /* 6px */ } + .rounded-lg { border-radius: calc(var(--radius) * 2); /* 8px */ } + .rounded-xl { border-radius: calc(var(--radius) * 3); /* 12px */ } + .rounded-2xl { border-radius: calc(var(--radius) * 4); /* 16px */ } + .rounded-3xl { border-radius: calc(var(--radius) * 6); /* 24px */ } + .rounded-4xl { border-radius: calc(var(--radius) * 8); /* 32px */ } + .rounded-full { border-radius: 1000rem; } @@ -989,30 +1079,39 @@ $decorations: underline, overline, line-through, no-underline; .overflow-auto { overflow: auto; } + .overflow-hidden { overflow: hidden; } + .overflow-clip { overflow: clip; } + .overflow-visible { overflow: visible; } + .overflow-scroll { overflow: scroll; } + .overflow-x-scroll { overflow-x: scroll; } + .overflow-y-scroll { overflow-y: scroll; } + .overflow-x-auto { overflow-x: auto; } + .overflow-y-auto { overflow-y: auto; } + .overflow-x-hidden { overflow-x: hidden; } @@ -1028,45 +1127,59 @@ $decorations: underline, overline, line-through, no-underline; .opacity-0 { opacity: 0; } + .opacity-5 { opacity: 0.05; } + .opacity-10 { opacity: 0.1; } + .opacity-20 { opacity: 0.2; } + .opacity-25 { opacity: 0.25; } + .opacity-30 { opacity: 0.3; } + .opacity-40 { opacity: 0.4; } + .opacity-50 { opacity: 0.5; } + .opacity-60 { opacity: 0.6; } + .opacity-70 { opacity: 0.7; } + .opacity-75 { opacity: 0.75; } + .opacity-80 { opacity: 0.8; } + .opacity-90 { opacity: 0.9; } + .opacity-95 { opacity: 0.95; } + .opacity-100 { opacity: 1; } @@ -1074,6 +1187,7 @@ $decorations: underline, overline, line-through, no-underline; .pointer-events-none { pointer-events: none; } + .pointer-events-auto { pointer-events: auto; } @@ -1083,9 +1197,11 @@ $decorations: underline, overline, line-through, no-underline; text-overflow: ellipsis; white-space: nowrap; } + .text-ellipsis { text-overflow: ellipsis; } + .text-clip { text-overflow: clip; } @@ -1105,6 +1221,7 @@ $decorations: underline, overline, line-through, no-underline; .list-inside { list-style-position: inside; } + .list-outside { list-style-position: outside; } @@ -1125,18 +1242,23 @@ $decorations: underline, overline, line-through, no-underline; .tracking-tighter { letter-spacing: -0.05em; } + .tracking-tight { letter-spacing: -0.025em; } + .tracking-normal { - letter-spacing: 0em; + letter-spacing: 0; } + .tracking-wide { letter-spacing: 0.025em; } + .tracking-wider { letter-spacing: 0.05em; } + .tracking-widest { letter-spacing: 0.1em; } @@ -1144,12 +1266,15 @@ $decorations: underline, overline, line-through, no-underline; .select-none { user-select: none; } + .select-text { user-select: text; } + .select-all { user-select: all; } + .select-auto { user-select: auto; } @@ -1157,6 +1282,7 @@ $decorations: underline, overline, line-through, no-underline; .rotate-90 { transform: rotate(90deg); } + .rotate-180 { transform: rotate(180deg); } diff --git a/frontend/src/styles/vars.scss b/frontend/src/styles/vars.scss index b5121d692e541..419862be8bbe3 100644 --- a/frontend/src/styles/vars.scss +++ b/frontend/src/styles/vars.scss @@ -1,11 +1,12 @@ @use 'sass:list'; +@use 'sass:map'; +@use 'sass:color'; $sm: 576px; $md: 768px; $lg: 992px; $xl: 1200px; $xxl: 1600px; - $screens: ( 'sm': $sm, 'md': $md, @@ -13,13 +14,13 @@ $screens: ( 'xl': $xl, 'xxl': $xxl, ); - $tiny_spaces: 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20; $humongous_spaces: 24, 30, 32, 40, 50, 60, 80, 100, 120, 140, 160, 180, 200; $all_spaces: list.join($tiny_spaces, $humongous_spaces); $flex_sizes: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10; $leadings: 3, 4, 5, 6, 7, 8, 9, 10; $sides: 'top', 'right', 'bottom', 'left'; + // CSS cursors from https://tailwindcss.com/docs/cursor $cursors: ( 'auto', @@ -59,6 +60,7 @@ $cursors: ( 'zoom-in', 'zoom-out' ); + // CSS list style types from https://tailwindcss.com/docs/list-style-type $list_style_types: 'none', 'disc', 'decimal'; @@ -96,10 +98,10 @@ $colors: ( 'bg-light': #fff, 'side': #fafaf9, 'mid': #f2f2f2, - 'border': rgba(0, 0, 0, 0.15), - 'border-light': rgba(0, 0, 0, 0.08), - 'border-bold': rgba(0, 0, 0, 0.24), - 'border-active': rgba(0, 0, 0, 0.36), + 'border': rgb(0 0 0 / 15%), + 'border-light': rgb(0 0 0 / 8%), + 'border-bold': rgb(0 0 0 / 24%), + 'border-active': rgb(0 0 0 / 36%), 'transparent': transparent, 'link': var(--link), // Colors of the PostHog logo @@ -137,7 +139,7 @@ $colors: ( 'border-bold-3000-dark': #3f4046, 'glass-bg-3000-dark': #1d1f27b3, 'glass-border-3000-dark': var(--border-3000-dark), - 'link-3000-dark': rgb(47, 129, 247), + 'link-3000-dark': rgb(47 129 247), // The derived colors 'text-3000': var(--text-3000), 'muted-3000': var(--muted-3000), @@ -157,9 +159,9 @@ $colors: ( ); // These vars are modified via SCSS for legacy reasons (e.g. darken/lighten), so keeping as SCSS vars for now. -$_primary: map-get($colors, 'primary'); -$_success: map-get($colors, 'success'); -$_danger: map-get($colors, 'danger'); +$_primary: map.get($colors, 'primary'); +$_success: map.get($colors, 'success'); +$_danger: map.get($colors, 'danger'); $_primary_bg_hover: rgba($_primary, 0.1); $_primary_bg_active: rgba($_primary, 0.2); $_lifecycle_new: $_primary; @@ -175,20 +177,19 @@ $_lifecycle_dormant: $_danger; --#{$name}: #{$hex}; } - //TODO: Remove the primary-bg... + // TODO: Remove the primary-bg... --primary-bg-hover: var(--primary-highlight); --primary-bg-active: #{$_primary_bg_active}; - --bg-charcoal: #2d2d2d; --bg-bridge: #ebece8; // Non-color vars --radius: 4px; - --shadow-elevation: 0px 16px 16px -16px rgba(0, 0, 0, 0.35); + --shadow-elevation: 0px 16px 16px -16px rgb(0 0 0 / 35%); --opacity-disabled: 0.6; --font-medium: 500; --font-semibold: 600; - --font-sans: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', 'Roboto', 'Helvetica Neue', Helvetica, Arial, + --font-sans: -apple-system, blinkmacsystemfont, 'Inter', 'Segoe UI', 'Roboto', 'Helvetica Neue', helvetica, arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; --font-mono: ui-monospace, 'SFMono-Regular', 'SF Mono', 'Menlo', 'Consolas', 'Liberation Mono', monospace; @@ -222,10 +223,10 @@ $_lifecycle_dormant: $_danger; --lifecycle-returning: #{$_lifecycle_returning}; --lifecycle-resurrecting: #{$_lifecycle_resurrecting}; --lifecycle-dormant: #{$_lifecycle_dormant}; - --lifecycle-new-hover: #{darken($_lifecycle_new, 20%)}; - --lifecycle-returning-hover: #{darken($_lifecycle_returning, 20%)}; - --lifecycle-resurrecting-hover: #{darken($_lifecycle_resurrecting, 20%)}; - --lifecycle-dormant-hover: #{darken($_lifecycle_dormant, 20%)}; + --lifecycle-new-hover: #{color.adjust($_lifecycle_new, $lightness: -20%)}; + --lifecycle-returning-hover: #{color.adjust($_lifecycle_returning, $lightness: -20%)}; + --lifecycle-resurrecting-hover: #{color.adjust($_lifecycle_resurrecting, $lightness: -20%)}; + --lifecycle-dormant-hover: #{color.adjust($_lifecycle_dormant, $lightness: -20%)}; // Funnels // TODO: unify with lib/colors.ts, getGraphColors() @@ -293,9 +294,8 @@ $_lifecycle_dormant: $_danger; --toastify-color-progress-warning: var(--toastify-color-warning); --toastify-color-progress-error: var(--toastify-color-error); - //In App Prompts + // In-app prompts --in-app-prompts-width: 26rem; - --lettermark-1-bg: #dcb1e3; --lettermark-1-text: #572e5e; --lettermark-2-bg: #ffc4b2; @@ -312,12 +312,10 @@ $_lifecycle_dormant: $_danger; --lettermark-7-text: #35416b; --lettermark-8-bg: #ff906e; --lettermark-8-text: #2a3d65; - --lettermark-8-bg: #e8edff; - --lettermark-8-text: #35416b; // Modals --modal-backdrop-blur: 5px; // Half the value in Figma as blur is calculated differently there it seems - --modal-backdrop-color: rgba(0, 0, 0, 0.2); + --modal-backdrop-color: rgb(0 0 0 / 20%); --modal-transition-time: 200ms; // Notebooks diff --git a/frontend/src/toolbar/actions/ActionsTab.scss b/frontend/src/toolbar/actions/ActionsTab.scss index 1ab083acc90a9..6a6a0f8866ec5 100644 --- a/frontend/src/toolbar/actions/ActionsTab.scss +++ b/frontend/src/toolbar/actions/ActionsTab.scss @@ -8,9 +8,11 @@ .action-section { &.highlight { - background: hsla(228, 14%, 96%, 1); + background: hsl(228deg 14% 96% / 100%); + &:nth-child(even) { background: white; + &:last-child { padding-bottom: 10px; } @@ -28,7 +30,7 @@ .action-field-caption { font-size: 0.8em; - color: rgba(0, 0, 0, 0.5); + color: rgb(0 0 0 / 50%); padding: 8px 0; } } diff --git a/frontend/src/toolbar/button/ToolbarButton.scss b/frontend/src/toolbar/button/ToolbarButton.scss index a082973bbdfda..2ea811c6abdaf 100644 --- a/frontend/src/toolbar/button/ToolbarButton.scss +++ b/frontend/src/toolbar/button/ToolbarButton.scss @@ -8,22 +8,20 @@ .circle-button { transition: box-shadow 0.2s ease; - box-shadow: 0 0.3px 0.7px rgba(0, 0, 0, 0.25), 0 0.8px 1.7px rgba(0, 0, 0, 0.18), - 0 1.5px 3.1px rgba(0, 0, 0, 0.149), 0 2.7px 5.4px rgba(0, 0, 0, 0.125), 0 5px 10px rgba(0, 0, 0, 0.101), - 0 12px 24px rgba(0, 0, 0, 0.07); + box-shadow: 0 0.3px 0.7px rgb(0 0 0 / 25%), 0 0.8px 1.7px rgb(0 0 0 / 18%), 0 1.5px 3.1px rgb(0 0 0 / 14.9%), + 0 2.7px 5.4px rgb(0 0 0 / 12.5%), 0 5px 10px rgb(0 0 0 / 10.1%), 0 12px 24px rgb(0 0 0 / 7%); &:hover { - box-shadow: 0 1.3px 2.7px rgba(0, 0, 0, 0.25), 0 3.2px 6.4px rgba(0, 0, 0, 0.18), - 0 6px 12px rgba(0, 0, 0, 0.149), 0 10.7px 21.4px rgba(0, 0, 0, 0.125), - 0 20.1px 40.1px rgba(0, 0, 0, 0.101), 0 48px 96px rgba(0, 0, 0, 0.07); + box-shadow: 0 1.3px 2.7px rgb(0 0 0 / 25%), 0 3.2px 6.4px rgb(0 0 0 / 18%), 0 6px 12px rgb(0 0 0 / 14.9%), + 0 10.7px 21.4px rgb(0 0 0 / 12.5%), 0 20.1px 40.1px rgb(0 0 0 / 10.1%), 0 48px 96px rgb(0 0 0 / 7%); } } .circle-label { font-weight: bold; - text-shadow: black 0 0 1px, black 0 0 2px, rgba(0, 0, 0, 0.25) 0 0.3px 0.7px, rgba(0, 0, 0, 0.18) 0 0.8px 1.6px, - rgba(0, 0, 0, 0.15) 0 1.5px 3px, rgba(0, 0, 0, 0.125) 0 2.7px 5.4px, rgba(0, 0, 0, 0.1) 0 5px 10px, - rgba(0, 0, 0, 0.07) 0 12px 24px; + text-shadow: black 0 0 1px, black 0 0 2px, rgb(0 0 0 / 25%) 0 0.3px 0.7px, rgb(0 0 0 / 18%) 0 0.8px 1.6px, + rgb(0 0 0 / 15%) 0 1.5px 3px, rgb(0 0 0 / 12.5%) 0 2.7px 5.4px, rgb(0 0 0 / 10%) 0 5px 10px, + rgb(0 0 0 / 7%) 0 12px 24px; } & + .HedgehogBuddy { @@ -37,11 +35,11 @@ left: 0; top: 0; z-index: 2147483020; - box-shadow: 0 0.3px 0.7px rgba(0, 0, 0, 0.25), 0 0.8px 1.7px rgba(0, 0, 0, 0.18), 0 1.5px 3.1px rgba(0, 0, 0, 0.149), - 0 2.7px 5.4px rgba(0, 0, 0, 0.125), 0 5px 10px rgba(0, 0, 0, 0.101), 0 12px 24px rgba(0, 0, 0, 0.07); + box-shadow: 0 0.3px 0.7px rgb(0 0 0 / 25%), 0 0.8px 1.7px rgb(0 0 0 / 18%), 0 1.5px 3.1px rgb(0 0 0 / 14.9%), + 0 2.7px 5.4px rgb(0 0 0 / 12.5%), 0 5px 10px rgb(0 0 0 / 10.1%), 0 12px 24px rgb(0 0 0 / 7%); opacity: 1; transition: opacity ease 0.5s; - background-color: rgba(255, 255, 255); + background-color: rgb(255 255 255); border-radius: 4px; border: 1px solid var(--border); @@ -54,17 +52,16 @@ line-height: 26px; display: flex; align-items: center; - margin: 0 8px 0 8px; + margin: 0 8px; border-bottom: 1px solid var(--border); .toolbar-info-window-draggable { - cursor: move; flex: 1; display: flex; width: 100%; align-items: center; cursor: move; - padding: 15px 0 15px 0; + padding: 15px 0; .window-label { font-size: 14px; @@ -77,11 +74,11 @@ .close-button { cursor: pointer; padding: 8px; - color: rgba(0, 0, 0, 0.6); + color: rgb(0 0 0 / 60%); transition: color 0.1s ease-in-out; &:hover { - color: rgb(0, 0, 0); + color: rgb(0 0 0); } } } diff --git a/frontend/src/toolbar/button/icons/Fire.scss b/frontend/src/toolbar/button/icons/Fire.scss index 46596648187a6..4b13e407b311a 100644 --- a/frontend/src/toolbar/button/icons/Fire.scss +++ b/frontend/src/toolbar/button/icons/Fire.scss @@ -1,55 +1,66 @@ svg.posthog-toolbar-icon-fire.animated { path:nth-child(1) { - animation: posthHogToolbarIconOnFire1 0.5s infinite; + animation: Toolbar__fire-1 0.5s infinite; } + path:nth-child(2) { - animation: posthHogToolbarIconOnFire2 0.5s infinite; + animation: Toolbar__fire-2 0.5s infinite; } + path:nth-child(3) { - animation: posthHogToolbarIconOnFire3 0.5s infinite; + animation: Toolbar__fire-3 0.5s infinite; } } -@keyframes posthHogToolbarIconOnFire1 { +@keyframes Toolbar__fire-1 { 0% { fill: #fb4f0e; } + 33.3% { fill: #fe6d37; } + 66.6% { fill: #fcb811; } + 100% { fill: #fb4f0e; } } -@keyframes posthHogToolbarIconOnFire2 { +@keyframes Toolbar__fire-2 { 0% { fill: #fe6d37; } + 33.3% { fill: #fcb811; } + 66.6% { fill: #fb4f0e; } + 100% { fill: #fe6d37; } } -@keyframes posthHogToolbarIconOnFire3 { +@keyframes Toolbar__fire-3 { 0% { fill: #fcb811; } + 33.3% { fill: #fb4f0e; } + 66.6% { fill: #fe6d37; } + 100% { fill: #fcb811; } diff --git a/frontend/src/toolbar/button/icons/Flag.scss b/frontend/src/toolbar/button/icons/Flag.scss index 0ef3a9549e7d7..92a0749cf20b0 100644 --- a/frontend/src/toolbar/button/icons/Flag.scss +++ b/frontend/src/toolbar/button/icons/Flag.scss @@ -1,55 +1,66 @@ svg.posthog-toolbar-icon-flag.animated { path.color1 { - animation: posthHogToolbarIconOnFlag1 0.5s infinite; + animation: Toolbar__flag-1 0.5s infinite; } + path.color2 { - animation: posthHogToolbarIconOnFlag2 0.5s infinite; + animation: Toolbar__flag-2 0.5s infinite; } + path.color3 { - animation: posthHogToolbarIconOnFlag3 0.5s infinite; + animation: Toolbar__flag-3 0.5s infinite; } } -@keyframes posthHogToolbarIconOnFlag1 { +@keyframes Toolbar__flag-1 { 0% { fill: #70aa54; } + 33.3% { fill: #527940; } + 66.6% { fill: #415e32; } + 100% { fill: #70aa54; } } -@keyframes posthHogToolbarIconOnFlag2 { +@keyframes Toolbar__flag-2 { 0% { fill: #527940; } + 33.3% { fill: #415e32; } + 66.6% { fill: #70aa54; } + 100% { fill: #527940; } } -@keyframes posthHogToolbarIconOnFlag3 { +@keyframes Toolbar__flag-3 { 0% { fill: #415e32; } + 33.3% { fill: #70aa54; } + 66.6% { fill: #527940; } + 100% { fill: #415e32; } diff --git a/frontend/src/toolbar/elements/Elements.scss b/frontend/src/toolbar/elements/Elements.scss index a3972935ddee7..a558e6b375ec1 100644 --- a/frontend/src/toolbar/elements/Elements.scss +++ b/frontend/src/toolbar/elements/Elements.scss @@ -1,5 +1,5 @@ #posthog-toolbar-elements, #posthog-infowindow-container { - color: #333333; + color: #333; pointer-events: none; } diff --git a/frontend/src/toolbar/flags/featureFlags.scss b/frontend/src/toolbar/flags/featureFlags.scss index efe87c03b0595..e4f8b80d567a9 100644 --- a/frontend/src/toolbar/flags/featureFlags.scss +++ b/frontend/src/toolbar/flags/featureFlags.scss @@ -1,25 +1,31 @@ .flags-button-window { width: min(350px, 100vw); } + .toolbar-block { .feature-flag-row { .feature-flag-row-header { background-color: #fafafa; min-height: 38px; + > * { margin: 0 5px; } + .feature-flag-title { font-size: 13px; } + .feature-flag-external-link { - color: rgba(0, 0, 0, 0.5); + color: rgb(0 0 0 / 50%); line-height: normal; + &:hover { - color: rgba(0, 0, 0, 0.8); + color: rgb(0 0 0 / 80%); } } } + .feature-flag-row-header.overridden { background-color: var(--mark); } @@ -27,10 +33,12 @@ .variant-radio-group { border-left: 2px solid #fafafa; } + .variant-radio-group.overridden { border-left-color: var(--mark); } } + .local-feature-flag-override-note { color: var(--default); background-color: #fafafa; diff --git a/frontend/src/toolbar/styles.scss b/frontend/src/toolbar/styles.scss index 11dbbc6e5b881..9e23aa050b7d8 100644 --- a/frontend/src/toolbar/styles.scss +++ b/frontend/src/toolbar/styles.scss @@ -2,8 +2,8 @@ // was inherited from antd.less before removing that *, -*:before, -*:after { +*::before, +*::after { box-sizing: border-box; } @@ -35,7 +35,7 @@ font-size: 12px; text-transform: uppercase; font-weight: bold; - color: hsla(220, 15%, 49%, 1); + color: hsl(220deg 15% 49% / 100%); margin-bottom: 10px; } @@ -50,10 +50,7 @@ .toolbar-global-fade-container { position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; + inset: 0; pointer-events: none; > * { diff --git a/package.json b/package.json index 68051ba75de02..b08c1c590a617 100644 --- a/package.json +++ b/package.json @@ -49,14 +49,15 @@ "prettier": "prettier --write \"./**/*.{js,mjs,ts,tsx,json,yaml,yml,css,scss}\"", "prettier:check": "prettier --check \"frontend/**/*.{js,mjs,ts,tsx,json,yaml,yml,css,scss}\"", "typescript:check": "tsc --noEmit && echo \"No errors reported by tsc.\"", - "eslint": "eslint frontend/src", + "lint:js": "eslint frontend/src", + "lint:css": "stylelint \"frontend/**/*.{css,scss}\"", + "format:backend": "ruff --exclude posthog/hogql/grammar .", + "format:frontend": "pnpm lint:js --fix && pnpm lint:css --fix && pnpm prettier", + "format": "pnpm format:backend && pnpm format:frontend", "typegen:write": "kea-typegen write --delete --show-ts-errors", "typegen:check": "kea-typegen check", "typegen:watch": "kea-typegen watch --delete --show-ts-errors", "typegen:clean": "find frontend/src -type f -name '*Type.ts' -delete", - "format:python": "ruff --exclude posthog/hogql/grammar .", - "format:js": "pnpm prettier && pnpm eslint --fix", - "format": "pnpm format:python && pnpm format:js", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", "dev:migrate:postgres": "export DEBUG=1 && source env/bin/activate && python manage.py migrate", @@ -278,6 +279,9 @@ "storybook": "^7.5.1", "storybook-addon-pseudo-states": "2.1.2", "style-loader": "^2.0.0", + "stylelint": "^15.11.0", + "stylelint-config-standard-scss": "^11.1.0", + "stylelint-order": "^6.0.3", "sucrase": "^3.29.0", "timekeeper": "^2.2.0", "ts-json-schema-generator": "^1.2.0", @@ -291,7 +295,11 @@ "fsevents": "^2.3.2" }, "lint-staged": { - "*.{json,yaml,yml,css,scss}": "prettier --write", + "*.{json,yaml,yml}": "prettier --write", + "*.{css,scss}": [ + "stylelint --fix", + "prettier --write" + ], "(!(plugin-server)/**).{js,jsx,mjs,ts,tsx}": [ "eslint -c .eslintrc.js --fix", "prettier --write" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cbba46296db6e..b5effe3cb21c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -639,6 +639,15 @@ devDependencies: style-loader: specifier: ^2.0.0 version: 2.0.0(webpack@5.88.2) + stylelint: + specifier: ^15.11.0 + version: 15.11.0(typescript@4.9.5) + stylelint-config-standard-scss: + specifier: ^11.1.0 + version: 11.1.0(postcss@8.4.31)(stylelint@15.11.0) + stylelint-order: + specifier: ^6.0.3 + version: 6.0.3(stylelint@15.11.0) sucrase: specifier: ^3.29.0 version: 3.29.0 @@ -2144,6 +2153,40 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: true + /@csstools/css-parser-algorithms@2.3.2(@csstools/css-tokenizer@2.2.1): + resolution: {integrity: sha512-sLYGdAdEY2x7TSw9FtmdaTrh2wFtRJO5VMbBrA8tEqEod7GEggFmxTSK9XqExib3yMuYNcvcTdCZIP6ukdjAIA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-tokenizer': ^2.2.1 + dependencies: + '@csstools/css-tokenizer': 2.2.1 + dev: true + + /@csstools/css-tokenizer@2.2.1: + resolution: {integrity: sha512-Zmsf2f/CaEPWEVgw29odOj+WEVoiJy9s9NOv5GgNY9mZ1CZ7394By6wONrONrTsnNDv6F9hR02nvFihrGVGHBg==} + engines: {node: ^14 || ^16 || >=18} + dev: true + + /@csstools/media-query-list-parser@2.1.5(@csstools/css-parser-algorithms@2.3.2)(@csstools/css-tokenizer@2.2.1): + resolution: {integrity: sha512-IxVBdYzR8pYe89JiyXQuYk4aVVoCPhMJkz6ElRwlVysjwURTsTk/bmY/z4FfeRE+CRBMlykPwXEVUg8lThv7AQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-parser-algorithms': ^2.3.2 + '@csstools/css-tokenizer': ^2.2.1 + dependencies: + '@csstools/css-parser-algorithms': 2.3.2(@csstools/css-tokenizer@2.2.1) + '@csstools/css-tokenizer': 2.2.1 + dev: true + + /@csstools/selector-specificity@3.0.0(postcss-selector-parser@6.0.13): + resolution: {integrity: sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss-selector-parser: ^6.0.13 + dependencies: + postcss-selector-parser: 6.0.13 + dev: true + /@ctrl/tinycolor@3.4.1: resolution: {integrity: sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==} engines: {node: '>=10'} @@ -5068,7 +5111,7 @@ packages: debug: 4.3.4(supports-color@8.1.1) endent: 2.1.0 find-cache-dir: 3.3.2 - flat-cache: 3.0.4 + flat-cache: 3.2.0 micromatch: 4.0.5 react-docgen-typescript: 2.2.2(typescript@4.9.5) tslib: 2.6.2 @@ -5909,7 +5952,7 @@ packages: resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} dependencies: '@types/connect': 3.4.38 - '@types/node': 18.11.9 + '@types/node': 18.18.4 dev: true /@types/chart.js@2.9.37: @@ -5937,7 +5980,7 @@ packages: /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 18.11.9 + '@types/node': 18.18.4 dev: true /@types/cookie@0.4.1: @@ -6215,7 +6258,7 @@ packages: /@types/express-serve-static-core@4.17.41: resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==} dependencies: - '@types/node': 18.11.9 + '@types/node': 18.18.4 '@types/qs': 6.9.10 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -6381,6 +6424,10 @@ packages: resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} dev: true + /@types/minimist@1.2.5: + resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + dev: true + /@types/ms@0.7.31: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: true @@ -6545,7 +6592,7 @@ packages: resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} dependencies: '@types/mime': 1.3.5 - '@types/node': 18.11.9 + '@types/node': 18.18.4 dev: true /@types/serve-static@1.15.4: @@ -6561,7 +6608,7 @@ packages: dependencies: '@types/http-errors': 2.0.4 '@types/mime': 3.0.4 - '@types/node': 18.11.9 + '@types/node': 18.18.4 dev: true /@types/set-cookie-parser@2.4.2: @@ -7434,6 +7481,11 @@ packages: is-shared-array-buffer: 1.0.2 dev: true + /arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + dev: true + /asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} dev: false @@ -7784,6 +7836,10 @@ packages: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true + /balanced-match@2.0.0: + resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} + dev: true + /base16@1.0.0: resolution: {integrity: sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==} dev: false @@ -7999,7 +8055,7 @@ packages: /call-bind@1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 get-intrinsic: 1.2.2 /call-bind@1.0.5: @@ -8048,7 +8104,6 @@ packages: map-obj: 4.3.0 quick-lru: 5.1.1 type-fest: 1.4.0 - dev: false /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} @@ -8384,6 +8439,10 @@ packages: color-string: 1.9.1 dev: true + /colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + dev: true + /colorette@2.0.19: resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} dev: true @@ -8611,6 +8670,22 @@ packages: yaml: 1.10.2 dev: true + /cosmiconfig@8.3.6(typescript@4.9.5): + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + typescript: 4.9.5 + dev: true + /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true @@ -8657,6 +8732,11 @@ packages: timsort: 0.3.0 dev: true + /css-functions-list@3.2.1: + resolution: {integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==} + engines: {node: '>=12 || >=16'} + dev: true + /css-loader@3.6.0(webpack@5.88.2): resolution: {integrity: sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==} engines: {node: '>= 8.9.0'} @@ -8735,6 +8815,14 @@ packages: source-map: 0.6.1 dev: true + /css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.0.2 + dev: true + /css-what@3.4.2: resolution: {integrity: sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==} engines: {node: '>= 6'} @@ -9266,11 +9354,24 @@ packages: ms: 2.1.2 supports-color: 8.1.1 + /decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 + dev: true + /decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} dev: true + /decamelize@5.0.1: + resolution: {integrity: sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==} + engines: {node: '>=10'} + dev: true + /decimal.js@10.4.2: resolution: {integrity: sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==} dev: true @@ -9761,7 +9862,7 @@ packages: dependencies: call-bind: 1.0.2 es-to-primitive: 1.2.1 - function-bind: 1.1.1 + function-bind: 1.1.2 function.prototype.name: 1.1.5 get-intrinsic: 1.2.2 get-symbol-description: 1.0.0 @@ -9854,7 +9955,7 @@ packages: define-properties: 1.2.1 es-abstract: 1.22.3 es-set-tostringtag: 2.0.2 - function-bind: 1.1.1 + function-bind: 1.1.2 get-intrinsic: 1.2.2 globalthis: 1.0.3 has-property-descriptors: 1.0.0 @@ -10657,17 +10758,6 @@ packages: resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} dev: true - /fast-glob@3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - /fast-glob@3.3.1: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} @@ -10772,7 +10862,14 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flat-cache: 3.0.4 + flat-cache: 3.2.0 + dev: true + + /file-entry-cache@7.0.1: + resolution: {integrity: sha512-uLfFktPmRetVCbHe5UPuekWrQ6hENufnA46qEGbfACkK5drjTTdQYUragRgMjHldcbYG+nslUerqMPjbBSHXjQ==} + engines: {node: '>=12.0.0'} + dependencies: + flat-cache: 3.2.0 dev: true /file-loader@6.2.0(webpack@5.88.2): @@ -10902,16 +10999,17 @@ packages: path-exists: 5.0.0 dev: true - /flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flatted: 3.2.7 + flatted: 3.2.9 + keyv: 4.5.4 rimraf: 3.0.2 dev: true - /flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + /flatted@3.2.9: + resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} dev: true /flow-parser@0.214.0: @@ -11094,9 +11192,6 @@ packages: requiresBuild: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -11144,7 +11239,7 @@ packages: /get-intrinsic@1.1.3: resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 has: 1.0.3 has-symbols: 1.0.3 @@ -11325,6 +11420,13 @@ packages: is-windows: 0.2.0 dev: true + /global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + dependencies: + global-prefix: 3.0.0 + dev: true + /global-prefix@0.1.5: resolution: {integrity: sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==} engines: {node: '>=0.10.0'} @@ -11342,7 +11444,6 @@ packages: ini: 1.3.8 kind-of: 6.0.3 which: 1.3.1 - dev: false /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -11368,12 +11469,16 @@ packages: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.2.12 + fast-glob: 3.3.1 ignore: 5.2.4 merge2: 1.4.1 slash: 3.0.0 dev: true + /globjoin@0.1.4: + resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} + dev: true + /glur@1.1.2: resolution: {integrity: sha512-l+8esYHTKOx2G/Aao4lEQ0bnHWg4fWtJbVoZZT9Knxi01pB8C80BR85nONLFwkkQoFRCmXY+BUcGZN3yZ2QsRA==} @@ -11419,6 +11524,11 @@ packages: uglify-js: 3.17.4 dev: true + /hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + dev: true + /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -11525,6 +11635,13 @@ packages: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true + /hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + dependencies: + lru-cache: 6.0.0 + dev: true + /hsl-regex@1.0.0: resolution: {integrity: sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==} dev: true @@ -11567,6 +11684,11 @@ packages: engines: {node: '>=8'} dev: true + /html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + dev: true + /html-to-react@1.5.0: resolution: {integrity: sha512-tjihXBgaJZRRYzmkrJZ/Qf9jFayilFYcb+sJxXXE2BVLk2XsNrGeuNCVvhXmvREULZb9dz6NFTBC96DTR/lQCQ==} dependencies: @@ -11772,6 +11894,11 @@ packages: resolve-from: 4.0.0 dev: true + /import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + dev: true + /import-local@3.1.0: resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} engines: {node: '>=8'} @@ -11791,6 +11918,11 @@ packages: engines: {node: '>=8'} dev: true + /indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + dev: true + /indexes-of@1.0.1: resolution: {integrity: sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==} dev: true @@ -12144,6 +12276,11 @@ packages: engines: {node: '>=8'} dev: true + /is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + dev: true + /is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} @@ -13542,6 +13679,10 @@ packages: engines: {node: '>=4'} hasBin: true + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + /json-parse-better-errors@1.0.2: resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} dev: true @@ -13718,6 +13859,12 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -13732,6 +13879,10 @@ packages: engines: {node: '>= 8'} dev: true + /known-css-properties@0.29.0: + resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} + dev: true + /lazy-ass@1.6.0: resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} engines: {node: '> 0.8'} @@ -13967,6 +14118,10 @@ packages: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} dev: true + /lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + dev: true + /lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} dev: true @@ -14059,10 +14214,14 @@ packages: tmpl: 1.0.5 dev: true + /map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + dev: true + /map-obj@4.3.0: resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} engines: {node: '>=8'} - dev: false /map-or-similar@1.5.0: resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} @@ -14119,6 +14278,10 @@ packages: react: 18.2.0 dev: true + /mathml-tag-names@2.1.3: + resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} + dev: true + /maxmind@4.3.8: resolution: {integrity: sha512-HrfxEu5yPBPtTy/OT+W5bPQwEfLUX0EHqe2EbJiB47xQMumHqXvSP7PAwzV8Z++NRCmQwy4moQrTSt0+dH+Jmg==} engines: {node: '>=12', npm: '>=6'} @@ -14171,6 +14334,10 @@ packages: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} dev: true + /mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + dev: true + /mdn-data@2.0.4: resolution: {integrity: sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==} dev: true @@ -14196,6 +14363,24 @@ packages: map-or-similar: 1.5.0 dev: true + /meow@10.1.5: + resolution: {integrity: sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + '@types/minimist': 1.2.5 + camelcase-keys: 7.0.2 + decamelize: 5.0.1 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 8.0.0 + redent: 4.0.0 + trim-newlines: 4.1.1 + type-fest: 1.4.0 + yargs-parser: 20.2.9 + dev: true + /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} @@ -14285,6 +14470,15 @@ packages: brace-expansion: 2.0.1 dev: true + /minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 + dev: true + /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -14533,6 +14727,16 @@ packages: validate-npm-package-license: 3.0.4 dev: true + /normalize-package-data@3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} + engines: {node: '>=10'} + dependencies: + hosted-git-info: 4.1.0 + is-core-module: 2.11.0 + semver: 7.5.4 + validate-npm-package-license: 3.0.4 + dev: true + /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -15168,7 +15372,7 @@ packages: resolution: {integrity: sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==} dependencies: postcss: 7.0.39 - postcss-selector-parser: 6.0.10 + postcss-selector-parser: 6.0.13 postcss-value-parser: 4.2.0 dev: true @@ -15235,6 +15439,10 @@ packages: webpack: 5.88.2(@swc/core@1.3.93)(esbuild@0.14.54)(webpack-cli@5.1.4) dev: true + /postcss-media-query-parser@0.2.3: + resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} + dev: true + /postcss-merge-longhand@4.0.11: resolution: {integrity: sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==} engines: {node: '>=6.9.0'} @@ -15319,7 +15527,7 @@ packages: dependencies: icss-utils: 4.1.1 postcss: 7.0.39 - postcss-selector-parser: 6.0.10 + postcss-selector-parser: 6.0.13 postcss-value-parser: 4.2.0 dev: true @@ -15331,7 +15539,7 @@ packages: dependencies: icss-utils: 5.1.0(postcss@8.4.31) postcss: 8.4.31 - postcss-selector-parser: 6.0.10 + postcss-selector-parser: 6.0.13 postcss-value-parser: 4.2.0 dev: true @@ -15340,7 +15548,7 @@ packages: engines: {node: '>= 6'} dependencies: postcss: 7.0.39 - postcss-selector-parser: 6.0.10 + postcss-selector-parser: 6.0.13 dev: true /postcss-modules-scope@3.0.0(postcss@8.4.31): @@ -15350,7 +15558,7 @@ packages: postcss: ^8.1.0 dependencies: postcss: 8.4.31 - postcss-selector-parser: 6.0.10 + postcss-selector-parser: 6.0.13 dev: true /postcss-modules-values@3.0.0: @@ -15480,6 +15688,28 @@ packages: postcss-value-parser: 3.3.1 dev: true + /postcss-resolve-nested-selector@0.1.1: + resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==} + dev: true + + /postcss-safe-parser@6.0.0(postcss@8.4.31): + resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.3.3 + dependencies: + postcss: 8.4.31 + dev: true + + /postcss-scss@4.0.9(postcss@8.4.31): + resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.29 + dependencies: + postcss: 8.4.31 + dev: true + /postcss-selector-parser@3.1.2: resolution: {integrity: sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==} engines: {node: '>=8'} @@ -15489,14 +15719,22 @@ packages: uniq: 1.0.1 dev: true - /postcss-selector-parser@6.0.10: - resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + /postcss-selector-parser@6.0.13: + resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} engines: {node: '>=4'} dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 dev: true + /postcss-sorting@8.0.2(postcss@8.4.31): + resolution: {integrity: sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==} + peerDependencies: + postcss: ^8.4.20 + dependencies: + postcss: 8.4.31 + dev: true + /postcss-svgo@4.0.3: resolution: {integrity: sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==} engines: {node: '>=6.9.0'} @@ -15936,7 +16174,6 @@ packages: /quick-lru@5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} - dev: false /quickselect@2.0.0: resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==} @@ -16834,6 +17071,15 @@ packages: type-fest: 0.8.1 dev: true + /read-pkg-up@8.0.0: + resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==} + engines: {node: '>=12'} + dependencies: + find-up: 5.0.0 + read-pkg: 6.0.0 + type-fest: 1.4.0 + dev: true + /read-pkg@4.0.1: resolution: {integrity: sha512-+UBirHHDm5J+3WDmLBZYSklRYg82nMlz+enn+GMZ22nSR2f4bzxmhso6rzQW/3mT2PVzpzDTiYIZahk8UmZ44w==} engines: {node: '>=6'} @@ -16853,6 +17099,16 @@ packages: type-fest: 0.6.0 dev: true + /read-pkg@6.0.0: + resolution: {integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==} + engines: {node: '>=12'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 3.0.3 + parse-json: 5.2.0 + type-fest: 1.4.0 + dev: true + /readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} dependencies: @@ -16916,6 +17172,14 @@ packages: strip-indent: 3.0.0 dev: true + /redent@4.0.0: + resolution: {integrity: sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==} + engines: {node: '>=12'} + dependencies: + indent-string: 5.0.0 + strip-indent: 4.0.0 + dev: true + /redux@4.2.0: resolution: {integrity: sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==} dependencies: @@ -17928,6 +18192,13 @@ packages: min-indent: 1.0.1 dev: true + /strip-indent@4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + dependencies: + min-indent: 1.0.1 + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -17953,6 +18224,10 @@ packages: webpack: 5.88.2(@swc/core@1.3.93)(esbuild@0.14.54)(webpack-cli@5.1.4) dev: true + /style-search@0.1.0: + resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} + dev: true + /stylehacks@4.0.3: resolution: {integrity: sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==} engines: {node: '>=6.9.0'} @@ -17962,6 +18237,129 @@ packages: postcss-selector-parser: 3.1.2 dev: true + /stylelint-config-recommended-scss@13.1.0(postcss@8.4.31)(stylelint@15.11.0): + resolution: {integrity: sha512-8L5nDfd+YH6AOoBGKmhH8pLWF1dpfY816JtGMePcBqqSsLU+Ysawx44fQSlMOJ2xTfI9yTGpup5JU77c17w1Ww==} + peerDependencies: + postcss: ^8.3.3 + stylelint: ^15.10.0 + peerDependenciesMeta: + postcss: + optional: true + dependencies: + postcss: 8.4.31 + postcss-scss: 4.0.9(postcss@8.4.31) + stylelint: 15.11.0(typescript@4.9.5) + stylelint-config-recommended: 13.0.0(stylelint@15.11.0) + stylelint-scss: 5.3.1(stylelint@15.11.0) + dev: true + + /stylelint-config-recommended@13.0.0(stylelint@15.11.0): + resolution: {integrity: sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==} + engines: {node: ^14.13.1 || >=16.0.0} + peerDependencies: + stylelint: ^15.10.0 + dependencies: + stylelint: 15.11.0(typescript@4.9.5) + dev: true + + /stylelint-config-standard-scss@11.1.0(postcss@8.4.31)(stylelint@15.11.0): + resolution: {integrity: sha512-5gnBgeNTgRVdchMwiFQPuBOtj9QefYtfXiddrOMJA2pI22zxt6ddI2s+e5Oh7/6QYl7QLJujGnaUR5YyGq72ow==} + peerDependencies: + postcss: ^8.3.3 + stylelint: ^15.10.0 + peerDependenciesMeta: + postcss: + optional: true + dependencies: + postcss: 8.4.31 + stylelint: 15.11.0(typescript@4.9.5) + stylelint-config-recommended-scss: 13.1.0(postcss@8.4.31)(stylelint@15.11.0) + stylelint-config-standard: 34.0.0(stylelint@15.11.0) + dev: true + + /stylelint-config-standard@34.0.0(stylelint@15.11.0): + resolution: {integrity: sha512-u0VSZnVyW9VSryBG2LSO+OQTjN7zF9XJaAJRX/4EwkmU0R2jYwmBSN10acqZisDitS0CLiEiGjX7+Hrq8TAhfQ==} + engines: {node: ^14.13.1 || >=16.0.0} + peerDependencies: + stylelint: ^15.10.0 + dependencies: + stylelint: 15.11.0(typescript@4.9.5) + stylelint-config-recommended: 13.0.0(stylelint@15.11.0) + dev: true + + /stylelint-order@6.0.3(stylelint@15.11.0): + resolution: {integrity: sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==} + peerDependencies: + stylelint: ^14.0.0 || ^15.0.0 + dependencies: + postcss: 8.4.31 + postcss-sorting: 8.0.2(postcss@8.4.31) + stylelint: 15.11.0(typescript@4.9.5) + dev: true + + /stylelint-scss@5.3.1(stylelint@15.11.0): + resolution: {integrity: sha512-5I9ZDIm77BZrjOccma5WyW2nJEKjXDd4Ca8Kk+oBapSO4pewSlno3n+OyimcyVJJujQZkBN2D+xuMkIamSc6hA==} + peerDependencies: + stylelint: ^14.5.1 || ^15.0.0 + dependencies: + known-css-properties: 0.29.0 + postcss-media-query-parser: 0.2.3 + postcss-resolve-nested-selector: 0.1.1 + postcss-selector-parser: 6.0.13 + postcss-value-parser: 4.2.0 + stylelint: 15.11.0(typescript@4.9.5) + dev: true + + /stylelint@15.11.0(typescript@4.9.5): + resolution: {integrity: sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + dependencies: + '@csstools/css-parser-algorithms': 2.3.2(@csstools/css-tokenizer@2.2.1) + '@csstools/css-tokenizer': 2.2.1 + '@csstools/media-query-list-parser': 2.1.5(@csstools/css-parser-algorithms@2.3.2)(@csstools/css-tokenizer@2.2.1) + '@csstools/selector-specificity': 3.0.0(postcss-selector-parser@6.0.13) + balanced-match: 2.0.0 + colord: 2.9.3 + cosmiconfig: 8.3.6(typescript@4.9.5) + css-functions-list: 3.2.1 + css-tree: 2.3.1 + debug: 4.3.4(supports-color@8.1.1) + fast-glob: 3.3.1 + fastest-levenshtein: 1.0.16 + file-entry-cache: 7.0.1 + global-modules: 2.0.0 + globby: 11.1.0 + globjoin: 0.1.4 + html-tags: 3.3.1 + ignore: 5.2.4 + import-lazy: 4.0.0 + imurmurhash: 0.1.4 + is-plain-object: 5.0.0 + known-css-properties: 0.29.0 + mathml-tag-names: 2.1.3 + meow: 10.1.5 + micromatch: 4.0.5 + normalize-path: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.31 + postcss-resolve-nested-selector: 0.1.1 + postcss-safe-parser: 6.0.0(postcss@8.4.31) + postcss-selector-parser: 6.0.13 + postcss-value-parser: 4.2.0 + resolve-from: 5.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + style-search: 0.1.0 + supports-hyperlinks: 3.0.0 + svg-tags: 1.0.0 + table: 6.8.1 + write-file-atomic: 5.0.1 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + /sucrase@3.29.0: resolution: {integrity: sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==} engines: {node: '>=8'} @@ -18014,10 +18412,22 @@ packages: supports-color: 7.2.0 dev: true + /supports-hyperlinks@3.0.0: + resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + engines: {node: '>=14.18'} + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: true + /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + /svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + dev: true + /svgo@1.3.2: resolution: {integrity: sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==} engines: {node: '>=4.0.0'} @@ -18069,6 +18479,17 @@ packages: resolution: {integrity: sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==} dev: false + /table@6.8.1: + resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} + engines: {node: '>=10.0.0'} + dependencies: + ajv: 8.11.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} @@ -18323,6 +18744,11 @@ packages: hasBin: true dev: true + /trim-newlines@4.1.1: + resolution: {integrity: sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==} + engines: {node: '>=12'} + dev: true + /trough@1.0.5: resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} dev: false @@ -18476,7 +18902,6 @@ packages: /type-fest@1.4.0: resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} engines: {node: '>=10'} - dev: false /type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} @@ -19321,6 +19746,14 @@ packages: signal-exit: 3.0.7 dev: true + /write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + dev: true + /ws@6.2.2: resolution: {integrity: sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==} peerDependencies: diff --git a/posthog/api/test/batch_exports/test_log_entry.py b/posthog/api/test/batch_exports/test_log_entry.py index 23d59b68e924a..8012766464ffd 100644 --- a/posthog/api/test/batch_exports/test_log_entry.py +++ b/posthog/api/test/batch_exports/test_log_entry.py @@ -171,6 +171,54 @@ def test_log_level_filter(batch_export, team, level): assert results[1].batch_export_id == str(batch_export["id"]) +@pytest.mark.django_db +@pytest.mark.parametrize( + "level", + [ + BatchExportLogEntryLevel.INFO, + BatchExportLogEntryLevel.WARNING, + BatchExportLogEntryLevel.ERROR, + BatchExportLogEntryLevel.DEBUG, + ], +) +def test_log_level_filter_with_lowercase(batch_export, team, level): + """Test fetching a batch export log entries of a particular level.""" + with freeze_time("2023-09-22 01:00:00"): + for message in ("Test log 1", "Test log 2"): + create_batch_export_log_entry( + team_id=team.pk, + batch_export_id=str(batch_export["id"]), + run_id=None, + message=message, + level=level.lower(), + ) + + results = [] + timeout = 10 + start = dt.datetime.utcnow() + + while not results: + results = fetch_batch_export_log_entries( + team_id=team.pk, + batch_export_id=batch_export["id"], + level_filter=[level], + after=dt.datetime(2023, 9, 22, 0, 59, 59), + before=dt.datetime(2023, 9, 22, 1, 0, 1), + ) + if (dt.datetime.utcnow() - start) > dt.timedelta(seconds=timeout): + break + + results.sort(key=lambda record: record.message) + + assert len(results) == 2 + assert results[0].message == "Test log 1" + assert results[0].level == level + assert results[0].batch_export_id == str(batch_export["id"]) + assert results[1].message == "Test log 2" + assert results[1].level == level + assert results[1].batch_export_id == str(batch_export["id"]) + + @pytest.mark.django_db def test_batch_export_log_api(client, batch_export, team): """Test fetching batch export log entries using the API.""" diff --git a/posthog/batch_exports/models.py b/posthog/batch_exports/models.py index 30ad08bc13c86..ab1a7b8b80db0 100644 --- a/posthog/batch_exports/models.py +++ b/posthog/batch_exports/models.py @@ -242,11 +242,11 @@ def fetch_batch_export_log_entries( clickhouse_where_parts.append("message ILIKE %(search)s") clickhouse_kwargs["search"] = f"%{search}%" if len(level_filter) > 0: - clickhouse_where_parts.append("level in %(levels)s") + clickhouse_where_parts.append("upper(level) in %(levels)s") clickhouse_kwargs["levels"] = level_filter clickhouse_query = f""" - SELECT team_id, log_source_id AS batch_export_id, instance_id AS run_id, timestamp, level, message FROM log_entries + SELECT team_id, log_source_id AS batch_export_id, instance_id AS run_id, timestamp, upper(level) as level, message FROM log_entries WHERE {' AND '.join(clickhouse_where_parts)} ORDER BY timestamp DESC {f'LIMIT {limit}' if limit else ''} """