From 03796e7385cce2240b648965f64539b4fac7db21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isaque=20B=C3=B6ck?= Date: Wed, 22 Jul 2026 13:03:52 -0300 Subject: [PATCH 1/3] fix: [Switch] locked state visual and default border (ENG-46737, ENG-46738) From cf9ae2fa6eb30a18c37ad77dbe482b55a5d27ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isaque=20B=C3=B6ck?= Date: Wed, 22 Jul 2026 14:05:55 -0300 Subject: [PATCH 2/3] fix: [Switch] privacy lock icon (on) contrasts against handle, not track (ENG-46737) --- .../inputs/switch/Switch.stories.js | 36 ++++++++++++++++ .../components/inputs/switch/switch.test.ts | 43 +++++++++++++++++++ .../src/components/inputs/switch/switch.vue | 2 +- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/apps/storybook/src/stories/components/inputs/switch/Switch.stories.js b/apps/storybook/src/stories/components/inputs/switch/Switch.stories.js index ded5f9992..ec1fb2ce0 100644 --- a/apps/storybook/src/stories/components/inputs/switch/Switch.stories.js +++ b/apps/storybook/src/stories/components/inputs/switch/Switch.stories.js @@ -145,3 +145,39 @@ export const Types = { } } } + +const PRIVACY_SCRIPT = [ + IMPORT, + "import { ref } from 'vue'", + '', + 'const off = ref(false)', + 'const on = ref(true)' +] + +const PRIVACY_TEMPLATE = `
+ + +
` + +/** @type {import('@storybook/vue3').StoryObj} */ +export const Privacy = { + render: () => ({ + components: { Switch }, + setup() { + const off = ref(false) + const on = ref(true) + return { off, on } + }, + template: PRIVACY_TEMPLATE + }), + parameters: { + docs: { + controls: { disable: true }, + description: { + story: + 'Privacy variant in both states. The off handle carries a closed lock (`pi-lock`) tinted `var(--bg-surface)` against the muted handle; the on handle carries an open lock (`pi-lock-open`) tinted `var(--text-default)` against the canvas handle — so the icon contrasts against the handle rather than blending into the surrounding `var(--success-contrast)` track.' + }, + source: { code: toSfc(PRIVACY_SCRIPT, PRIVACY_TEMPLATE) } + } + } +} diff --git a/packages/webkit/src/components/inputs/switch/switch.test.ts b/packages/webkit/src/components/inputs/switch/switch.test.ts index 10f628902..a9f90b4ee 100644 --- a/packages/webkit/src/components/inputs/switch/switch.test.ts +++ b/packages/webkit/src/components/inputs/switch/switch.test.ts @@ -186,6 +186,49 @@ describe('Switch', () => { }) }) + describe('privacy lock icon', () => { + it('renders no lock icon when kind=default', () => { + const { getByTestId } = render(Switch, { + props: { kind: 'default', modelValue: true }, + attrs: { 'aria-label': 'Toggle setting' } + }) + + const handle = getByTestId('input-switch__handle') + expect(handle.querySelector('i.pi')).toBeNull() + }) + + it('renders pi-lock tinted var(--bg-surface) when privacy is off', () => { + const { getByTestId } = render(Switch, { + props: { kind: 'privacy', modelValue: false }, + attrs: { 'aria-label': 'Toggle setting' } + }) + + const icon = getByTestId('input-switch__handle').querySelector('i.pi') as HTMLElement | null + expect(icon).not.toBeNull() + expect(icon!.classList.contains('pi-lock')).toBe(true) + expect(icon!.classList.contains('pi-lock-open')).toBe(false) + expect(icon!.className).toContain('text-[var(--bg-surface)]') + expect(icon!.getAttribute('aria-hidden')).toBe('true') + }) + + it('renders pi-lock-open tinted var(--text-default) when privacy is on (contrasts against handle, not track)', () => { + const { getByTestId } = render(Switch, { + props: { kind: 'privacy', modelValue: true }, + attrs: { 'aria-label': 'Toggle setting' } + }) + + const icon = getByTestId('input-switch__handle').querySelector('i.pi') as HTMLElement | null + expect(icon).not.toBeNull() + expect(icon!.classList.contains('pi-lock-open')).toBe(true) + expect(icon!.classList.contains('pi-lock')).toBe(false) + // The on icon must NOT reuse --success-contrast (the surrounding track color) + // — that made the icon "blend" into the track visually. It uses --text-default + // so it contrasts against the handle's --bg-canvas fill in both themes. + expect(icon!.className).toContain('text-[var(--text-default)]') + expect(icon!.className).not.toContain('text-[var(--success-contrast)]') + }) + }) + describe('smoke over type variants', () => { it.each([['default'], ['privacy']] as const)('renders data-kind=%s', (type) => { const { getByTestId } = render(Switch, { diff --git a/packages/webkit/src/components/inputs/switch/switch.vue b/packages/webkit/src/components/inputs/switch/switch.vue index 6ff8ed5cf..3183e5c0f 100644 --- a/packages/webkit/src/components/inputs/switch/switch.vue +++ b/packages/webkit/src/components/inputs/switch/switch.vue @@ -72,7 +72,7 @@ const LOCK_ICON_CLASS = 'pi text-body-xxs leading-none' const LOCK_OFF_CLASS = `${LOCK_ICON_CLASS} pi-lock text-[var(--bg-surface)]` - const LOCK_ON_CLASS = `${LOCK_ICON_CLASS} pi-lock-open text-[var(--success-contrast)]` + const LOCK_ON_CLASS = `${LOCK_ICON_CLASS} pi-lock-open text-[var(--text-default)]` const rootClass = computed(() => cn(ROOT_CLASS, attrs.class as string | undefined)) From 036630deb6bbda0a38383e20ebdf266f0dbb4fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isaque=20B=C3=B6ck?= Date: Mon, 27 Jul 2026 17:16:13 -0300 Subject: [PATCH 3/3] test: add visual baselines for the switch privacy story --- ...nents-inputs-switch--privacy--dark-mobile.png | Bin 0 -> 1758 bytes ...nents-inputs-switch--privacy--dark-tablet.png | Bin 0 -> 1756 bytes ...nts-inputs-switch--privacy--light-desktop.png | Bin 0 -> 1714 bytes ...ents-inputs-switch--privacy--light-mobile.png | Bin 0 -> 1717 bytes ...ents-inputs-switch--privacy--light-tablet.png | Bin 0 -> 1750 bytes .../linux/components-inputs-switch--privacy.png | Bin 0 -> 1754 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--dark-mobile.png create mode 100644 apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--dark-tablet.png create mode 100644 apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--light-desktop.png create mode 100644 apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--light-mobile.png create mode 100644 apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--light-tablet.png create mode 100644 apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy.png diff --git a/apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--dark-mobile.png b/apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--dark-mobile.png new file mode 100644 index 0000000000000000000000000000000000000000..aaf67f5399daeaff75f9a089ecf8e709f532b959 GIT binary patch literal 1758 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 literal 0 HcmV?d00001 diff --git a/apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--light-desktop.png b/apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--light-desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..ba3012aea8360f64b522a2a8622a43b34ac5a6cc GIT binary patch literal 1714 zcmV;j22J^iP)ur{PfriX^7r=_i9}!uj z+RcW81=+PNchF=I7rEri{l~*+gdtMMMZ=ADyFD;45bU(IwN+PFKXn6_X1Y5CHnhbA#u*2rS9?J_} ziTe8R$;ep|PZrw(s5sL8_4b?(8@-%@P@u8Croz5n(3~W(t7;o8bxPJ7V zqh*$0iNh*apFDRg`R%xMhrh}x$vF$piEzMP-obE&HXxF=wzig+mk*v5Db{GV%IeQ# zzMr0+mRsBztI@>DhB^_7fo}dyK+uOKpdp0G?bZge*$?Kr1DmvC&)W6HIcFUEZq(nY zxl?~*pY=>$i9ThMw%cxlh7cwsqCo^4=yW=7To%c~qNkc_YYnckzmzB@%fRAQ@W8Os3bw3nV)}9CHJ0D&Ws>vhIG79;<_$DKu)JG1VFcho%dFJh@HOT@Vc z1r$a&KocY*Iy?#y@m=NhUe8caE?6@5ZZToldlMs~QUPZUI5%up%T#<|QnRpBJXQZ_p!5+Dwl> zy?i<=dCQJvWgl)!7?A(~%?fqq@KpH8r2?^^m>`))z6B2n34xtkUS6KTV0b}c*b`=D zW$}*#P}-UI z#~QrdkY-!8Y89w~?A`cco}^MrO3L8+ga@9a5>!i^n|^t!EGQtb@~#eH0`E}quRn_X zL~)Ueg@Uoe!kttqI&dm0bLXM;%hw`&$kU__H~-Hx>G@lik6rkJI8C}EJ_&N9-ZW{; zlZW3|m9%uU=W5e5Z)`?H_>}mEBo3(YCGih6INf*>|Ilp&i;W3+Y)zSZ zLtl?xwsQXR*XAvqD1C~Dfc*^%9oVPflwhJM!9-JniKYY-O$jEN5==BDm}p8c(Uf4K zDZxZjf{CUC6HN&wni5PjCH?^b0RR7zLlh7I000I_L_t&o06WOxBkT5H=>Px#07*qo IM6N<$g2qTNg#Z8m literal 0 HcmV?d00001 diff --git a/apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--light-mobile.png b/apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy--light-mobile.png new file mode 100644 index 0000000000000000000000000000000000000000..27951e1387f79133959a8969e6720e50207ed585 GIT binary patch literal 1717 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 literal 0 HcmV?d00001 diff --git a/apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy.png b/apps/storybook/.storybook/test-visual/__image_snapshots__/linux/components-inputs-switch--privacy.png new file mode 100644 index 0000000000000000000000000000000000000000..ab0b45f7b5a346951d17abdbeb07f1acdae8c335 GIT binary patch literal 1754 zcmV<01||84P)tP_d}ItS`-8F5=?-NVO+#bI1rHs+_fX{MQ9oS>Q6 z7N>mCuqC2%K@)JkvSEzWIf9u23Thb-DW#NWTW*2<+w$m&)1K4jd^*37a__n4o?;o%YwVzF2x!fVjwa*d6RIX#Syj-pVbUX`JEF-87DBK$}bqOk6@n+I)w zcfn78W5?sm%_ukoC@a&i)@1%W^y_5jZbq?^rV_(Y)~B2|%d$Pl+w zgF->yEz_T+RU_?IL<+g+sHmv8xVYirVHk-TjV3QI52UM9D!A0+!Duv^Os2pajPTIc z*EcjYgn~o+ZqAb3uZtoi2p?-h`=hE`L#@3-_swt`wLlrYK&e^(QuIPqXGWa1da#VPRnkg~DpJ2IG3(M!jzT zn+TtAC*O4F^8I7iCdd8%U_qF0LCNyPpRH;9>fFOhBf=*P;RCTktyY5$7{A-MZ_mog z0^QzA{GfGULL}qd%|c;XT3TjiCXDL<#X;nODCB)n0)ITdL}(Ptj&2fi*x$=`xBJ?r zitdX|$S?XyV$w6S6D31;FWu|D+?>9nz;fdOKVV0gkW7XUB0$9W__$7|^TrA{gRPf- zuKJ^s7a^Bye$o4e{3MyXI5{~Ps&#dB1=u(=3ynh;f!{KVP>@q@5QU2oJ{{*8hubWE zg)vJ$Jbt>YNN#gT<+cku*Ka-6eerHinc?>hKcWe|*$8`i2eTHu;1HL!T5Vxr;Z!Ma zHU4_OOZUOXGSFCkszt5O zR&$dNE9(h5!VVqq{q1(Q!la}mpJLvHI1x8>!f`T=H~TKrAQT`RV39{8It38{0s6@o z91bUPdXAi?lZM=r?xXm&-n5N*2or44@J4$_^t3y^(^&P>*_&Ms)UfNiZ_S2p%&QFV z6)%cL_@W_FlY|aZ(Zg-M?q8Dh&EFj_+ma{uxl~k_{_T!UUsRi%(lGX#U}hx~I6?{G*YVyMlf7jGf{+dqzTo9pcCoGRitSkOJ8s)(B@ovj=g&;@jaFd6v2 z2=FZAi=Uf5bU6NV#p!T598&+v1RaG!bO6v1Z6g&OGb=iv$~Fq3VM75~Bsi$Aub;|G z@Vv{#KcT9Ncb9T7NE}cZ;Q(DgM+g(*5v|>jBNTi0IDS*GL@JR=eFnKGLaco!m!Ko; zSObe(n5iNoBP|w7ZEbCFagkmxtExDBo%4$xU^!Y>yh?%4*_s-t9B>cr{XKL+kj#Uf z+d%WwkO3Krw;Es-t^78V)vwE<>GWTN_suhD(x~|fTEo)F=M!%4 zJ>Pz&0TB^w;y)oF0aggaiGO$-;C64~A7TYO9(Y|)C zj-Ek8N>HM`fGO!T9EZ0#fprUP=p7!&g7VXeOpA}#Yvc9v;1kqi-8