From 1979441de3f662c01993ddb22109baf3e62de193 Mon Sep 17 00:00:00 2001 From: Lasse Boisen Andersen Date: Thu, 27 Feb 2025 12:36:55 +0100 Subject: [PATCH 01/10] smarter stagger delays based on feature count, make list scrollable for when theres many features --- packages/browser-sdk/src/toolbar/Features.css | 10 +++--- packages/browser-sdk/src/toolbar/Features.tsx | 2 +- packages/browser-sdk/src/toolbar/Toolbar.css | 32 +++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/packages/browser-sdk/src/toolbar/Features.css b/packages/browser-sdk/src/toolbar/Features.css index 0c8927bf..a77ab2de 100644 --- a/packages/browser-sdk/src/toolbar/Features.css +++ b/packages/browser-sdk/src/toolbar/Features.css @@ -15,8 +15,7 @@ width: 8px; height: 8px; margin-left: 10px; - background: - linear-gradient( + background: linear-gradient( 45deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 43%, @@ -44,16 +43,19 @@ } .feature-row { + --transition-speed: 1; opacity: 0; transform: translateY(-7px); transition-property: opacity, transform; - transition-duration: 0.1s; + transition-duration: calc(0.1s * var(--transition-speed)); transition-timing-function: cubic-bezier(0.75, -0.015, 0.565, 1.055); &.show { opacity: 1; transform: translateY(0); - transition-delay: calc(0.01s * var(--i)); + transition-delay: calc( + 0.075s * var(--transition-speed) / var(--n) * var(--i) + ); } } diff --git a/packages/browser-sdk/src/toolbar/Features.tsx b/packages/browser-sdk/src/toolbar/Features.tsx index 67fa7106..ec50bf66 100644 --- a/packages/browser-sdk/src/toolbar/Features.tsx +++ b/packages/browser-sdk/src/toolbar/Features.tsx @@ -19,7 +19,7 @@ export function FeaturesTable({ return
No features found
; } return ( - +
{features.map((feature, index) => ( Date: Thu, 27 Feb 2025 14:07:23 +0100 Subject: [PATCH 02/10] format --- packages/browser-sdk/src/toolbar/Features.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/browser-sdk/src/toolbar/Features.css b/packages/browser-sdk/src/toolbar/Features.css index a77ab2de..4146fc42 100644 --- a/packages/browser-sdk/src/toolbar/Features.css +++ b/packages/browser-sdk/src/toolbar/Features.css @@ -15,7 +15,8 @@ width: 8px; height: 8px; margin-left: 10px; - background: linear-gradient( + background: + linear-gradient( 45deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 43%, From 2086df852b7932115215c32c5a15501b382019cd Mon Sep 17 00:00:00 2001 From: Lasse Boisen Andersen Date: Thu, 27 Feb 2025 14:32:58 +0100 Subject: [PATCH 03/10] cap at max 15 visible features --- packages/browser-sdk/src/toolbar/Toolbar.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/browser-sdk/src/toolbar/Toolbar.css b/packages/browser-sdk/src/toolbar/Toolbar.css index c312066e..90f00a7d 100644 --- a/packages/browser-sdk/src/toolbar/Toolbar.css +++ b/packages/browser-sdk/src/toolbar/Toolbar.css @@ -99,7 +99,12 @@ z-index: 999999; min-width: 200px; padding: 0; - max-height: calc(100vh - 36px - 35px); + + --visible-features: 15; + max-height: min( + calc(100vh - 36px - 35px), + calc(45px + (var(--visible-features) * 27px)) + ); &[open] { display: flex; From e821c157715f46d23275fe52de43125b226c3e2d Mon Sep 17 00:00:00 2001 From: Lasse Boisen Andersen Date: Thu, 27 Feb 2025 15:03:01 +0100 Subject: [PATCH 04/10] sort alphabetically --- packages/browser-sdk/src/toolbar/Toolbar.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/browser-sdk/src/toolbar/Toolbar.tsx b/packages/browser-sdk/src/toolbar/Toolbar.tsx index 9ded8201..5d5a369c 100644 --- a/packages/browser-sdk/src/toolbar/Toolbar.tsx +++ b/packages/browser-sdk/src/toolbar/Toolbar.tsx @@ -76,6 +76,10 @@ export default function Toolbar({ const searchedFeatures = search === null ? features : features.filter((f) => f.key.includes(search)); + const sortedFeatures = searchedFeatures.sort((a, b) => + a.key.localeCompare(b.key), + ); + const appBaseUrl = bucketClient.getConfig().appBaseUrl; const { isOpen, close, toggle } = useDialog(); @@ -108,7 +112,7 @@ export default function Toolbar({ Date: Thu, 27 Feb 2025 15:10:33 +0100 Subject: [PATCH 05/10] tweak colors to be slightly darker, fix border contrast --- packages/browser-sdk/src/toolbar/Toolbar.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/browser-sdk/src/toolbar/Toolbar.css b/packages/browser-sdk/src/toolbar/Toolbar.css index 90f00a7d..08f74ccf 100644 --- a/packages/browser-sdk/src/toolbar/Toolbar.css +++ b/packages/browser-sdk/src/toolbar/Toolbar.css @@ -56,9 +56,9 @@ --gray500: #787c91; --black: #1e1f24; - --bg-color: hsla(230, 9%, 13%, 0.85); - --bg-light-color: hsla(230, 9%, 11%, 0.85); - --border-color: hsl(227, 10%, 18%); + --bg-color: hsla(230, 9%, 8%, 0.85); + --bg-light-color: hsla(230, 9%, 6%, 0.85); + --border-color: hsla(0, 0%, 100%, 0.1); --bg-blur: 3px; --logo-color: white; From e9a807ff56a22727e9550a6b549779c048a8e21a Mon Sep 17 00:00:00 2001 From: Lasse Boisen Andersen Date: Thu, 27 Feb 2025 15:47:13 +0100 Subject: [PATCH 06/10] create new array --- packages/browser-sdk/src/toolbar/Toolbar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/browser-sdk/src/toolbar/Toolbar.tsx b/packages/browser-sdk/src/toolbar/Toolbar.tsx index 5d5a369c..fd602dd5 100644 --- a/packages/browser-sdk/src/toolbar/Toolbar.tsx +++ b/packages/browser-sdk/src/toolbar/Toolbar.tsx @@ -76,7 +76,7 @@ export default function Toolbar({ const searchedFeatures = search === null ? features : features.filter((f) => f.key.includes(search)); - const sortedFeatures = searchedFeatures.sort((a, b) => + const sortedFeatures = [...searchedFeatures].sort((a, b) => a.key.localeCompare(b.key), ); From f437e3f120a5c30d436a86ee33ecc0cb44931e75 Mon Sep 17 00:00:00 2001 From: Lasse Boisen Andersen Date: Fri, 28 Feb 2025 11:04:17 +0100 Subject: [PATCH 07/10] tweak animations further --- packages/browser-sdk/src/toolbar/Features.css | 12 ++++++++---- packages/browser-sdk/src/ui/Dialog.css | 10 +++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/browser-sdk/src/toolbar/Features.css b/packages/browser-sdk/src/toolbar/Features.css index 4146fc42..bb2a49c5 100644 --- a/packages/browser-sdk/src/toolbar/Features.css +++ b/packages/browser-sdk/src/toolbar/Features.css @@ -48,15 +48,19 @@ opacity: 0; transform: translateY(-7px); transition-property: opacity, transform; - transition-duration: calc(0.1s * var(--transition-speed)); + transition-duration: 0.075s; transition-timing-function: cubic-bezier(0.75, -0.015, 0.565, 1.055); &.show { opacity: 1; transform: translateY(0); - transition-delay: calc( - 0.075s * var(--transition-speed) / var(--n) * var(--i) - ); +/* stagger effect where first item (i=0) has no delay, + and delay is based on item count (n) so total animation time always is 509ms */ + transition-delay: calc(0.05s * var(--i) / max(var(--n) - 1, 1)); +} + + &.hide { + visibility: hidden; } } diff --git a/packages/browser-sdk/src/ui/Dialog.css b/packages/browser-sdk/src/ui/Dialog.css index dcb6c24c..b474bc1b 100644 --- a/packages/browser-sdk/src/ui/Dialog.css +++ b/packages/browser-sdk/src/ui/Dialog.css @@ -44,11 +44,11 @@ &[open] { animation: /* easeOutQuint */ - scale 200ms cubic-bezier(0.22, 1, 0.36, 1), - fade 200ms cubic-bezier(0.22, 1, 0.36, 1); + scale 150ms cubic-bezier(0.22, 1, 0.36, 1), + fade 150ms cubic-bezier(0.22, 1, 0.36, 1); &::backdrop { - animation: fade 200ms cubic-bezier(0.22, 1, 0.36, 1); + animation: fade 150ms cubic-bezier(0.22, 1, 0.36, 1); } } } @@ -61,8 +61,8 @@ &[open] { animation: /* easeOutQuint */ - scale 200ms cubic-bezier(0.22, 1, 0.36, 1), - fade 200ms cubic-bezier(0.22, 1, 0.36, 1); + scale 150ms cubic-bezier(0.22, 1, 0.36, 1), + fade 150ms cubic-bezier(0.22, 1, 0.36, 1); } &.bottom { transform-origin: top center; From 2705676714dbdf8f5c11ad6eb0e0b15f9466bfbc Mon Sep 17 00:00:00 2001 From: Lasse Boisen Andersen Date: Fri, 28 Feb 2025 11:21:53 +0100 Subject: [PATCH 08/10] improve keyboard nav, make search results retain dialog size --- packages/browser-sdk/src/toolbar/Features.css | 20 +++++++--- packages/browser-sdk/src/toolbar/Features.tsx | 39 +++++++++++++++---- packages/browser-sdk/src/toolbar/Switch.css | 19 +++++++++ packages/browser-sdk/src/toolbar/Switch.tsx | 2 +- packages/browser-sdk/src/toolbar/Toolbar.tsx | 6 +-- 5 files changed, 68 insertions(+), 18 deletions(-) diff --git a/packages/browser-sdk/src/toolbar/Features.css b/packages/browser-sdk/src/toolbar/Features.css index bb2a49c5..8d724022 100644 --- a/packages/browser-sdk/src/toolbar/Features.css +++ b/packages/browser-sdk/src/toolbar/Features.css @@ -44,22 +44,21 @@ } .feature-row { - --transition-speed: 1; opacity: 0; transform: translateY(-7px); transition-property: opacity, transform; transition-duration: 0.075s; transition-timing-function: cubic-bezier(0.75, -0.015, 0.565, 1.055); - &.show { + &.show-on-open { opacity: 1; transform: translateY(0); -/* stagger effect where first item (i=0) has no delay, + /* stagger effect where first item (i=0) has no delay, and delay is based on item count (n) so total animation time always is 509ms */ transition-delay: calc(0.05s * var(--i) / max(var(--n) - 1, 1)); -} + } - &.hide { + &.not-visible { visibility: hidden; } } @@ -75,7 +74,9 @@ .feature-link { color: var(--text-color); text-decoration: none; - &:hover { + + &:hover, + &:focus-visible { text-decoration: underline; } } @@ -88,6 +89,13 @@ .reset { color: var(--brand300); + + text-decoration: none; + + &:hover, + &:focus-visible { + text-decoration: underline; + } } .feature-switch-cell { diff --git a/packages/browser-sdk/src/toolbar/Features.tsx b/packages/browser-sdk/src/toolbar/Features.tsx index ec50bf66..6dc3edde 100644 --- a/packages/browser-sdk/src/toolbar/Features.tsx +++ b/packages/browser-sdk/src/toolbar/Features.tsx @@ -6,27 +6,40 @@ import { FeatureItem } from "./Toolbar"; export function FeaturesTable({ features, + searchQuery, setEnabledOverride, appBaseUrl, isOpen, }: { features: FeatureItem[]; + searchQuery: string | null; setEnabledOverride: (key: string, value: boolean | null) => void; appBaseUrl: string; isOpen: boolean; }) { - if (features.length === 0) { + const searchedFeatures = + searchQuery === null + ? features + : [...features].sort((a, _b) => (a.key.includes(searchQuery) ? -1 : 1)); + + if (searchedFeatures.length === 0) { return
No features found
; } return ( -
+
- {features.map((feature, index) => ( + {searchedFeatures.map((feature, index) => ( @@ -42,21 +55,27 @@ function FeatureRow({ feature, isOpen, index, + isNotVisible, }: { feature: FeatureItem; appBaseUrl: string; setEnabledOverride: (key: string, value: boolean | null) => void; isOpen: boolean; index: number; + isNotVisible: boolean; }) { - const [show, setShow] = useState(true); + const [showOnOpen, setShowOnOpen] = useState(isOpen); useEffect(() => { - setShow(isOpen); + setShowOnOpen(isOpen); }, [isOpen]); return ( @@ -83,6 +104,7 @@ function FeatureRow({ (feature.localOverride === null && feature.isEnabled) || feature.localOverride === true } + tabIndex={index + 1} onChange={(e) => { const isChecked = e.currentTarget.checked; const isOverridden = isChecked !== feature.isEnabled; @@ -103,6 +125,7 @@ export function FeatureSearch({ onSearch(s.currentTarget.value)} @@ -113,10 +136,11 @@ export function FeatureSearch({ function Reset({ setEnabledOverride, featureKey, + ...props }: { setEnabledOverride: (key: string, value: boolean | null) => void; featureKey: string; -}) { +} & h.JSX.HTMLAttributes) { return ( reset diff --git a/packages/browser-sdk/src/toolbar/Switch.css b/packages/browser-sdk/src/toolbar/Switch.css index 335d1b71..3a4bfd30 100644 --- a/packages/browser-sdk/src/toolbar/Switch.css +++ b/packages/browser-sdk/src/toolbar/Switch.css @@ -1,11 +1,30 @@ .switch { cursor: pointer; + position: relative; +} + +.switch-input { + border: 0px; + clip: rect(0px, 0px, 0px, 0px); + height: 1px; + width: 1px; + margin: -1px; + padding: 0px; + overflow: hidden; + white-space: nowrap; + position: absolute; +} + +.switch-input:focus-visible + .switch-track { + outline: none; + box-shadow: 0 0 0 1px #fff; } .switch-track { position: relative; transition: background 0.1s ease; background: #606476; + border-radius: 999px; } .switch[data-enabled="true"] .switch-track { diff --git a/packages/browser-sdk/src/toolbar/Switch.tsx b/packages/browser-sdk/src/toolbar/Switch.tsx index b58f995d..7ed0c205 100644 --- a/packages/browser-sdk/src/toolbar/Switch.tsx +++ b/packages/browser-sdk/src/toolbar/Switch.tsx @@ -19,8 +19,8 @@ export function Switch({
@@ -64,6 +83,7 @@ function FeatureRow({ class="feature-link" href={`${appBaseUrl}/envs/current/features/by-key/${feature.key}`} rel="noreferrer" + tabIndex={index + 1} target="_blank" > {feature.key} @@ -74,6 +94,7 @@ function FeatureRow({ ) : null}