From 2c4ff9fae25924e8043b15ef183ca833b6cda142 Mon Sep 17 00:00:00 2001 From: Quinton Jason Date: Fri, 15 May 2026 09:05:49 -0500 Subject: [PATCH 1/5] feat(storybook): add LTR/RTL preview toggle and audit pointer Add a Direction global type with an LTR/RTL toolbar control. The withDirection decorator applies dir on documentElement and body for the active story (and the parent docs frame), matching the consumer contract for RTL surfaces. Update the RTL and localization guide with a How to audit section pointing teams at the toggle. The audit checklist stays intentionally unchecked; rows should be marked off in the PR that proves behavior. --- libs/core/.storybook/preview.js | 38 +++++++++++++++++++ .../guides/rtl-and-localization.docs.mdx | 8 +++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/libs/core/.storybook/preview.js b/libs/core/.storybook/preview.js index 0f01c72cc..648277f97 100644 --- a/libs/core/.storybook/preview.js +++ b/libs/core/.storybook/preview.js @@ -138,10 +138,35 @@ const withTheme = (StoryFn, context) => { return StoryFn(); }; +// Direction decorator that applies `dir` attribute for RTL/LTR previews. +// Pair this with the audit checklist at +// Guides/RTL and localization when verifying component behavior. +const withDirection = (StoryFn, context) => { + const direction = context.globals.direction || 'ltr'; + + document.documentElement.setAttribute('dir', direction); + document.body.setAttribute('dir', direction); + + useEffect(() => { + document.documentElement.setAttribute('dir', direction); + document.body.setAttribute('dir', direction); + + try { + window.parent.document.documentElement.setAttribute('dir', direction); + window.parent.document.body.setAttribute('dir', direction); + } catch (e) { + // Cross-origin access may fail, that's ok + } + }, [direction]); + + return StoryFn(); +}; + const preview = { decorators: [ withCustomEventActions, withTheme, + withDirection, ], globalTypes: { @@ -157,10 +182,23 @@ const preview = { dynamicTitle: true, }, }, + direction: { + description: 'Document direction (LTR or RTL)', + toolbar: { + title: 'Direction', + icon: 'transfer', + items: [ + { value: 'ltr', title: 'LTR', right: 'Left-to-right' }, + { value: 'rtl', title: 'RTL', right: 'Right-to-left' }, + ], + dynamicTitle: true, + }, + }, }, initialGlobals: { theme: 'light', + direction: 'ltr', }, parameters: { diff --git a/libs/core/src/stories/guides/rtl-and-localization.docs.mdx b/libs/core/src/stories/guides/rtl-and-localization.docs.mdx index ffbbf2381..5fbed1768 100644 --- a/libs/core/src/stories/guides/rtl-and-localization.docs.mdx +++ b/libs/core/src/stories/guides/rtl-and-localization.docs.mdx @@ -12,6 +12,10 @@ Pine targets **English-first** Kajabi product surfaces today. Components are bui 2. **Prefer tokens and logical properties** in consuming apps for spacing and alignment that should mirror under RTL. Report gaps in Slack (`#ds-support`). 3. **Strings live in the product**, not inside Pine primitives—pass translated `label`, `aria-label`, and slot content from your app’s i18n layer. -## Storybook tooling +## Verifying in Storybook -**Pending:** The **Direction** toolbar (LTR / RTL) for spot-checking components in Storybook ships in [#739](https://github.com/Kajabi/pine/pull/739). Audit steps and usage notes will live in this guide once that PR merges. +Storybook includes a **Direction** toolbar control (LTR / RTL). Switching it applies `dir` on the preview iframe’s `` and ``, matching the consumer-app contract for RTL surfaces. + +Use the toggle to spot-check components: mirroring, overlay placement, iconography, truncation, keyboard, and screen reader behavior where applicable. + +When you change component layout or positioning, add or update Stencil tests and a short RTL Storybook example where it helps catch regressions in CI. From ca8e690580282d516aee91f452ea9b88dcfbfe59 Mon Sep 17 00:00:00 2001 From: Quinton Jason Date: Fri, 15 May 2026 09:16:53 -0500 Subject: [PATCH 2/5] fix(storybook): use direction icon for RTL toolbar --- libs/core/.storybook/preview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/core/.storybook/preview.js b/libs/core/.storybook/preview.js index 648277f97..8a96014fd 100644 --- a/libs/core/.storybook/preview.js +++ b/libs/core/.storybook/preview.js @@ -186,7 +186,7 @@ const preview = { description: 'Document direction (LTR or RTL)', toolbar: { title: 'Direction', - icon: 'transfer', + icon: 'direction', items: [ { value: 'ltr', title: 'LTR', right: 'Left-to-right' }, { value: 'rtl', title: 'RTL', right: 'Right-to-left' }, From 8a0a3142bf7d695cce7d7de7ce6372f312a8f2f3 Mon Sep 17 00:00:00 2001 From: Quinton Jason Date: Thu, 21 May 2026 14:38:24 -0500 Subject: [PATCH 3/5] fix(storybook): scope RTL dir to preview iframe only --- libs/core/.storybook/preview.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/libs/core/.storybook/preview.js b/libs/core/.storybook/preview.js index 8a96014fd..d208be282 100644 --- a/libs/core/.storybook/preview.js +++ b/libs/core/.storybook/preview.js @@ -138,9 +138,10 @@ const withTheme = (StoryFn, context) => { return StoryFn(); }; -// Direction decorator that applies `dir` attribute for RTL/LTR previews. -// Pair this with the audit checklist at -// Guides/RTL and localization when verifying component behavior. +// Direction decorator that applies `dir` on the preview iframe only. +// Unlike data-theme, `dir` is interpreted by the browser and must not be set on +// window.parent (that would flip Storybook manager/docs chrome). +// Pair with the audit checklist at Guides/RTL and localization. const withDirection = (StoryFn, context) => { const direction = context.globals.direction || 'ltr'; @@ -150,13 +151,6 @@ const withDirection = (StoryFn, context) => { useEffect(() => { document.documentElement.setAttribute('dir', direction); document.body.setAttribute('dir', direction); - - try { - window.parent.document.documentElement.setAttribute('dir', direction); - window.parent.document.body.setAttribute('dir', direction); - } catch (e) { - // Cross-origin access may fail, that's ok - } }, [direction]); return StoryFn(); From d93f441bd7f49faea5679e6a334f441054bc4919 Mon Sep 17 00:00:00 2001 From: Quinton Jason Date: Fri, 22 May 2026 07:47:48 -0500 Subject: [PATCH 4/5] fix(storybook): use valid transfer icon for direction toolbar --- libs/core/.storybook/preview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/core/.storybook/preview.js b/libs/core/.storybook/preview.js index d208be282..4bba93305 100644 --- a/libs/core/.storybook/preview.js +++ b/libs/core/.storybook/preview.js @@ -180,7 +180,7 @@ const preview = { description: 'Document direction (LTR or RTL)', toolbar: { title: 'Direction', - icon: 'direction', + icon: 'transfer', items: [ { value: 'ltr', title: 'LTR', right: 'Left-to-right' }, { value: 'rtl', title: 'RTL', right: 'Right-to-left' }, From ca3e48b3bc11b5dd9c878e93b1edd38d7b93c443 Mon Sep 17 00:00:00 2001 From: Quinton Jason Date: Fri, 22 May 2026 09:28:05 -0500 Subject: [PATCH 5/5] docs(storybook): update RTL guide cross-reference in preview --- libs/core/.storybook/preview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/core/.storybook/preview.js b/libs/core/.storybook/preview.js index 4bba93305..a013d0783 100644 --- a/libs/core/.storybook/preview.js +++ b/libs/core/.storybook/preview.js @@ -141,7 +141,7 @@ const withTheme = (StoryFn, context) => { // Direction decorator that applies `dir` on the preview iframe only. // Unlike data-theme, `dir` is interpreted by the browser and must not be set on // window.parent (that would flip Storybook manager/docs chrome). -// Pair with the audit checklist at Guides/RTL and localization. +// See Guides/RTL and localization for usage. const withDirection = (StoryFn, context) => { const direction = context.globals.direction || 'ltr';