-
-
Notifications
You must be signed in to change notification settings - Fork 8
feat(tabs): add foldable vertical tab bar #208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
c714d1a
feat(tabs): add explicit adaptive vertical placement
rdlabo 58033c6
fix(tabs): preserve foldable rail beside split pane
rdlabo 16e1109
test: refresh foldable split snapshots for toggle
rdlabo e94839a
fix(tabs): derive foldable rail from app mode
rdlabo 0823996
fix(tabs): preserve overlay tab ownership
rdlabo 39ff308
fix(tabs): show the selected foldable label
rdlabo 566ab56
fix(tabs): match SwiftUI foldable rail metrics
rdlabo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import { expect, test } from '@playwright/test'; | ||
|
|
||
| const enableFoldable = async (page: import('@playwright/test').Page) => { | ||
| const toggle = page.getByText('Foldable Mode').locator('..').locator('ion-toggle'); | ||
| await toggle.click(); | ||
| await expect(page.locator('ion-app')).toHaveClass(/ios-theme-enable-foldable/); | ||
| }; | ||
|
|
||
| test('foldable mode moves tabs into the right rail and reveals labels while dragging', async ({ page }) => { | ||
| await page.setViewportSize({ width: 700, height: 900 }); | ||
| await page.goto('/main/index'); | ||
| await enableFoldable(page); | ||
|
|
||
| const bar = page.locator('#tab-bar-bottom'); | ||
| const buttons = bar.locator('ion-tab-button'); | ||
| const barBox = (await bar.boundingBox())!; | ||
| expect(barBox.x).toBeGreaterThan(620); | ||
| expect(barBox.width).toBeCloseTo(50, 0); | ||
| await expect(buttons.first().locator('ion-label')).toHaveCSS('position', 'absolute'); | ||
| await expect(buttons.nth(1).locator('ion-label')).toHaveCSS('position', 'absolute'); | ||
|
|
||
| const selectedBox = (await buttons.first().boundingBox())!; | ||
| const targetBox = (await buttons.nth(1).boundingBox())!; | ||
| await page.mouse.move(selectedBox.x + selectedBox.width / 2, selectedBox.y + selectedBox.height / 2); | ||
| await page.mouse.down(); | ||
| await page.mouse.move(targetBox.x + targetBox.width / 2, targetBox.y + targetBox.height / 2, { steps: 4 }); | ||
| await expect.poll(() => buttons.first().evaluate((element) => element.matches(':active'))).toBe(true); | ||
|
|
||
| await expect(page).toHaveScreenshot('foldable-tab-drag-labels.png', { animations: 'disabled' }); | ||
| await page.mouse.up(); | ||
|
|
||
| const overlayDirection = await page.evaluate(async () => { | ||
| const menu = document.querySelector('ion-menu')!; | ||
| const tabs = document.createElement('ion-tabs'); | ||
| const overlayBar = document.createElement('ion-tab-bar'); | ||
| overlayBar.mode = 'ios'; | ||
| tabs.append(overlayBar); | ||
| menu.append(tabs); | ||
| await customElements.whenDefined('ion-tab-bar'); | ||
| await new Promise<void>((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))); | ||
| const direction = getComputedStyle(overlayBar).flexDirection; | ||
| tabs.remove(); | ||
| return direction; | ||
| }); | ||
| expect(overlayDirection).toBe('row'); | ||
| }); |
Binary file added
BIN
+43 KB
demo/e2e/adaptive-tab-bar.spec.ts-snapshots/foldable-tab-drag-labels.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 分割ペイン内の下配置タブが指定した物理側に配置されない
開始側メニュー表示中に
slot="bottom"を使うと、メニュー配置が優先されます。両辺が指定され、書字方向によって物理側の指定が無視されるため、バーが予約領域から外れます。Learn more
分割ペインの既存スタイルは、表示中の開始側メニューを避けるため、下側タブバーに
inset-inline-startを設定します。このセレクターは新しい適応型セレクターより詳細度が高いため、ここで設定したleft: autoまたは物理位置より優先されます。絶対配置要素にleft、right、固定幅が同時に残ると、LTR では左、RTL では右が優先されます。その結果、物理右配置は LTR で、物理左配置は RTL で壊れます。Example: LTR の 1024px 幅で開始側メニューが表示され、右配置かつ
slot="bottom"の場合、rightに加えてメニュー由来のleftが残ります。ブラウザーはleftを優先し、タブバーを右側の予約領域ではなくメニュー後方へ置きます。Recommended fix: 適応型の物理配置では論理 inset を明示的にリセットし、分割ペインのメニュールールより確実に優先させてください。左右配置、LTR/RTL、上下スロット、表示中の開始側・終了側メニューを組み合わせたテストも追加してください。
Was this helpful? React with 👍 or 👎 to provide feedback.