mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 09:34:19 +08:00
feat(split-pane): convert to shadow component, add width, max-width, and min-width vars (#19754)
resolves #17088 Co-authored-by: troyanskiy <roman.rosluk@utopix.ch>
This commit is contained in:
@ -1098,12 +1098,15 @@ ion-spinner,prop,name,"bubbles" | "circles" | "circular" | "crescent" | "dots" |
|
||||
ion-spinner,prop,paused,boolean,false,false,false
|
||||
ion-spinner,css-prop,--color
|
||||
|
||||
ion-split-pane,none
|
||||
ion-split-pane,shadow
|
||||
ion-split-pane,prop,contentId,string | undefined,undefined,false,false
|
||||
ion-split-pane,prop,disabled,boolean,false,false,false
|
||||
ion-split-pane,prop,when,boolean | string,QUERY['lg'],false,false
|
||||
ion-split-pane,event,ionSplitPaneVisible,{ visible: boolean; },true
|
||||
ion-split-pane,css-prop,--border
|
||||
ion-split-pane,css-prop,--side-max-width
|
||||
ion-split-pane,css-prop,--side-min-width
|
||||
ion-split-pane,css-prop,--side-width
|
||||
|
||||
ion-tab,shadow
|
||||
ion-tab,prop,component,Function | HTMLElement | null | string | undefined,undefined,false,false
|
||||
|
@ -126,6 +126,12 @@ ion-backdrop {
|
||||
// Menu Split Pane
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.menu-pane-visible) {
|
||||
width: var(--width);
|
||||
min-width: var(--min-width);
|
||||
max-width: var(--max-width);
|
||||
}
|
||||
|
||||
:host(.menu-pane-visible) .menu-inner {
|
||||
@include position-horizontal(0, 0);
|
||||
|
||||
|
@ -150,8 +150,11 @@ export const SplitPlaneExample: React.SFC<{}> = () => (
|
||||
## CSS Custom Properties
|
||||
|
||||
| Name | Description |
|
||||
| ---------- | -------------------- |
|
||||
| ------------------ | ---------------------------------------------------------------------------- |
|
||||
| `--border` | Border between panes |
|
||||
| `--side-max-width` | Maximum width of the side pane. Does not apply when split pane is collapsed. |
|
||||
| `--side-min-width` | Minimum width of the side pane. Does not apply when split pane is collapsed. |
|
||||
| `--side-width` | Width of the side pane. Does not apply when split pane is collapsed. |
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
|
@ -4,21 +4,23 @@
|
||||
// Split Pane
|
||||
// --------------------------------------------------
|
||||
|
||||
.split-pane-ios {
|
||||
:host {
|
||||
--border: #{$split-pane-ios-border};
|
||||
--side-min-width: #{$split-pane-ios-side-min-width};
|
||||
--side-max-width: #{$split-pane-ios-side-max-width};
|
||||
}
|
||||
|
||||
.split-pane-ios.split-pane-visible > .split-pane-side {
|
||||
min-width: $split-pane-ios-side-min-width;
|
||||
max-width: $split-pane-ios-side-max-width;
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-side) {
|
||||
min-width: var(--side-min-width);
|
||||
max-width: var(--side-max-width);
|
||||
|
||||
border-right: var(--border);
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.split-pane-ios.split-pane-visible > .split-pane-side[side=end] {
|
||||
min-width: $split-pane-ios-side-min-width;
|
||||
max-width: $split-pane-ios-side-max-width;
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-side[side=end]) {
|
||||
min-width: var(--side-min-width);
|
||||
max-width: var(--side-max-width);
|
||||
|
||||
border-right: 0;
|
||||
border-left: var(--border);
|
||||
|
@ -4,21 +4,23 @@
|
||||
// Split Pane
|
||||
// --------------------------------------------------
|
||||
|
||||
.split-pane-md {
|
||||
:host {
|
||||
--border: #{$split-pane-md-border};
|
||||
--side-min-width: #{$split-pane-md-side-min-width};
|
||||
--side-max-width: #{$split-pane-md-side-max-width};
|
||||
}
|
||||
|
||||
.split-pane-md.split-pane-visible > .split-pane-side {
|
||||
min-width: $split-pane-md-side-min-width;
|
||||
max-width: $split-pane-md-side-max-width;
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-side) {
|
||||
min-width: var(--side-min-width);
|
||||
max-width: var(--side-max-width);
|
||||
|
||||
border-right: var(--border);
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.split-pane-md.split-pane-visible > .split-pane-side[side=end] {
|
||||
min-width: $split-pane-md-side-min-width;
|
||||
max-width: $split-pane-md-side-max-width;
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-side[side=end]) {
|
||||
min-width: var(--side-min-width);
|
||||
max-width: var(--side-max-width);
|
||||
|
||||
border-right: 0;
|
||||
border-left: var(--border);
|
||||
|
@ -1,12 +1,17 @@
|
||||
@import "./split-pane.vars";
|
||||
@import "../menu/menu.vars";
|
||||
|
||||
// Split Pane
|
||||
// --------------------------------------------------
|
||||
|
||||
ion-split-pane {
|
||||
:host {
|
||||
/**
|
||||
* @prop --border: Border between panes
|
||||
* @prop --side-min-width: Minimum width of the side pane. Does not apply when split pane is collapsed.
|
||||
* @prop --side-max-width: Maximum width of the side pane. Does not apply when split pane is collapsed.
|
||||
* @prop --side-width: Width of the side pane. Does not apply when split pane is collapsed.
|
||||
*/
|
||||
--side-width: 100%;
|
||||
|
||||
@include position(0, 0, 0, 0);
|
||||
|
||||
@ -19,34 +24,50 @@ ion-split-pane {
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.split-pane-visible > .split-pane-side,
|
||||
.split-pane-visible > .split-pane-main {
|
||||
/**
|
||||
* Do not pass CSS Variables down on larger
|
||||
* screens as we want them to affect the outer
|
||||
* `ion-menu` rather than the inner content
|
||||
*/
|
||||
::slotted(ion-menu.menu-pane-visible) {
|
||||
|
||||
flex: 0 1 auto;
|
||||
|
||||
width: var(--side-width);
|
||||
min-width: var(--side-min-width);
|
||||
max-width: var(--side-max-width);
|
||||
}
|
||||
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-side),
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-main) {
|
||||
@include position(0, 0, 0, 0);
|
||||
|
||||
position: relative;
|
||||
|
||||
flex: 1;
|
||||
|
||||
/* stylelint-disable-next-line declaration-no-important */
|
||||
box-shadow: none !important;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.split-pane-visible > .split-pane-side:not(ion-menu),
|
||||
.split-pane-visible > ion-menu.split-pane-side.menu-enabled {
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-main) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-side:not(ion-menu)),
|
||||
:host(.split-pane-visible) ::slotted(ion-menu.split-pane-side.menu-enabled) {
|
||||
display: flex;
|
||||
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.split-pane-side:not(ion-menu) {
|
||||
::slotted(.split-pane-side:not(ion-menu)) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.split-pane-visible > .split-pane-side {
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-side) {
|
||||
order: -1;
|
||||
}
|
||||
|
||||
.split-pane-visible > .split-pane-side[side=end] {
|
||||
:host(.split-pane-visible) ::slotted(.split-pane-side[side=end]) {
|
||||
order: 1;
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ const QUERY: { [key: string]: string } = {
|
||||
styleUrls: {
|
||||
ios: 'split-pane.ios.scss',
|
||||
md: 'split-pane.md.scss'
|
||||
}
|
||||
},
|
||||
shadow: true
|
||||
})
|
||||
export class SplitPane implements ComponentInterface {
|
||||
|
||||
@ -159,6 +160,7 @@ export class SplitPane implements ComponentInterface {
|
||||
'split-pane-visible': this.visible
|
||||
}}
|
||||
>
|
||||
<slot></slot>
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
@ -5,6 +5,28 @@ test('split-pane: basic', async () => {
|
||||
url: '/src/components/split-pane/test/basic?ionic:_testing=true'
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
const screenshotCompares = [];
|
||||
const MIN_WIDTH = '#side-min-width';
|
||||
const MAX_WIDTH = '#side-max-width';
|
||||
const WIDTH = '#side-width';
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
|
||||
await page.click(MIN_WIDTH);
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
|
||||
await page.click(MIN_WIDTH);
|
||||
await page.click(MAX_WIDTH);
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
|
||||
await page.click(MAX_WIDTH);
|
||||
await page.click(WIDTH);
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
|
||||
for (const screenshotCompare of screenshotCompares) {
|
||||
expect(screenshotCompare).toMatchScreenshot();
|
||||
}
|
||||
});
|
||||
|
@ -69,8 +69,22 @@
|
||||
<f></f>
|
||||
<f></f>
|
||||
<f></f>
|
||||
</ion-content>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Toggle Side Min Width</ion-label>
|
||||
<ion-toggle id="side-min-width"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Toggle Side Max Width</ion-label>
|
||||
<ion-toggle id="side-max-width"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Toggle Side Fixed Width</ion-label>
|
||||
<ion-toggle id="side-width"></ion-toggle>
|
||||
</ion-item>
|
||||
</ion-content>
|
||||
</div>
|
||||
</ion-split-pane>
|
||||
|
||||
@ -78,6 +92,16 @@
|
||||
<ion-menu-controller></ion-menu-controller>
|
||||
|
||||
<script>
|
||||
const sideMinWidth = document.querySelector('ion-toggle#side-min-width');
|
||||
const sideMaxWidth = document.querySelector('ion-toggle#side-max-width');
|
||||
const sideWidth = document.querySelector('ion-toggle#side-width');
|
||||
|
||||
const splitPane = document.querySelector('ion-split-pane');
|
||||
|
||||
sideMinWidth.addEventListener('ionChange', () => splitPane.classList.toggle('side-min-width'));
|
||||
sideMaxWidth.addEventListener('ionChange', () => splitPane.classList.toggle('side-max-width'));
|
||||
sideWidth.addEventListener('ionChange', () => splitPane.classList.toggle('side-width'));
|
||||
|
||||
const menuCtrl = document.querySelector('ion-menu-controller');
|
||||
function openStart() {
|
||||
menuCtrl.open('start');
|
||||
@ -89,6 +113,20 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.side-width {
|
||||
--side-width: 150px;
|
||||
--side-min-width: 150px;
|
||||
}
|
||||
|
||||
.side-min-width {
|
||||
--side-min-width: 500px;
|
||||
}
|
||||
|
||||
.side-max-width {
|
||||
--side-max-width: 75px;
|
||||
--side-min-width: 0px;
|
||||
}
|
||||
|
||||
f {
|
||||
display: block;
|
||||
height: 150px;
|
||||
|
@ -76,6 +76,10 @@ body.backdrop-no-scroll {
|
||||
z-index: $z-index-page-container;
|
||||
}
|
||||
|
||||
.split-pane-visible > .ion-page.split-pane-main {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
ion-route,
|
||||
ion-route-redirect,
|
||||
ion-router,
|
||||
|
Reference in New Issue
Block a user