cozy-ui 124.2.0 → 125.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/cozy-ui.min.css +1 -1
  3. package/package.json +1 -1
  4. package/react/AppTitle/index.jsx +2 -2
  5. package/react/CozyDialogs/useCozyDialog.js +7 -0
  6. package/react/Layout/Layout.jsx +89 -26
  7. package/react/Layout/styles.styl +5 -8
  8. package/react/MuiCozyTheme/overrides/makeLightNormalOverrides.js +12 -10
  9. package/react/Sidebar/Readme.md +3 -1
  10. package/react/Sidebar/index.jsx +1 -5
  11. package/react/helpers/breakpoints.js +10 -2
  12. package/react/providers/Breakpoints/Readme.md +2 -0
  13. package/react/providers/Breakpoints/index.jsx +23 -9
  14. package/react/providers/Breakpoints/useIframeConnection.jsx +31 -0
  15. package/react/providers/Breakpoints/useIframeToSendWidth.jsx +33 -0
  16. package/react/providers/Breakpoints/useParentBreakpoints.jsx +36 -0
  17. package/stylus/objects/layouts.styl +74 -87
  18. package/stylus/objects/sidebar.styl +9 -4
  19. package/transpiled/react/AppTitle/index.js +2 -2
  20. package/transpiled/react/CozyDialogs/useCozyDialog.js +6 -1
  21. package/transpiled/react/Layout/Layout.d.ts +5 -31
  22. package/transpiled/react/Layout/Layout.js +78 -50
  23. package/transpiled/react/MuiCozyTheme/overrides/makeDarkInvertedOverrides.d.ts +12 -10
  24. package/transpiled/react/MuiCozyTheme/overrides/makeDarkNormalOverrides.d.ts +12 -10
  25. package/transpiled/react/MuiCozyTheme/overrides/makeLightInvertedOverrides.d.ts +12 -10
  26. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.d.ts +12 -10
  27. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.js +14 -8
  28. package/transpiled/react/Sidebar/index.js +2 -3
  29. package/transpiled/react/helpers/breakpoints.d.ts +2 -1
  30. package/transpiled/react/helpers/breakpoints.js +9 -2
  31. package/transpiled/react/providers/Breakpoints/index.d.ts +12 -1
  32. package/transpiled/react/providers/Breakpoints/index.js +31 -10
  33. package/transpiled/react/providers/Breakpoints/useIframeConnection.d.ts +5 -0
  34. package/transpiled/react/providers/Breakpoints/useIframeConnection.js +35 -0
  35. package/transpiled/react/providers/Breakpoints/useIframeToSendWidth.d.ts +3 -0
  36. package/transpiled/react/providers/Breakpoints/useIframeToSendWidth.js +32 -0
  37. package/transpiled/react/providers/Breakpoints/useParentBreakpoints.d.ts +5 -0
  38. package/transpiled/react/providers/Breakpoints/useParentBreakpoints.js +34 -0
  39. package/transpiled/react/stylesheet.css +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "124.2.0",
3
+ "version": "125.1.0",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -16,10 +16,10 @@ import NotesIcon from '../Icons/Notes'
16
16
  import NotesTextIcon from '../Icons/NotesText'
17
17
  import PassIcon from '../Icons/Pass'
18
18
  import PassTextIcon from '../Icons/PassText'
19
- import StoreIcon from '../Icons/Store'
20
- import StoreTextIcon from '../Icons/StoreText'
21
19
  import PhotosIcon from '../Icons/Photos'
22
20
  import PhotosTextIcon from '../Icons/PhotosText'
21
+ import StoreIcon from '../Icons/Store'
22
+ import StoreTextIcon from '../Icons/StoreText'
23
23
  import TwakeTextIcon from '../Icons/TwakeText'
24
24
  import TwakeWorkplaceIcon from '../Icons/TwakeWorkplace'
25
25
  import WorkplaceTextIcon from '../Icons/WorkplaceText'
@@ -56,6 +56,13 @@ const useCozyDialog = props => {
56
56
  }`,
57
57
  scrollPaper: scrollPaperClassName
58
58
  },
59
+ BackdropProps: {
60
+ style: {
61
+ transitionDelay: 50,
62
+ ...otherProps?.BackdropProps?.style
63
+ },
64
+ ...otherProps.BackdropProps
65
+ },
59
66
  TransitionProps: {
60
67
  fullScreen,
61
68
  ...otherProps.TransitionProps
@@ -1,45 +1,108 @@
1
1
  import cx from 'classnames'
2
2
  import PropTypes from 'prop-types'
3
- import React, { Component } from 'react'
3
+ import React, { createContext, forwardRef, useContext, useMemo } from 'react'
4
4
 
5
5
  import styles from './styles.styl'
6
6
 
7
- export const Layout = ({
8
- children,
9
- className,
10
- monoColumn,
11
- withTopBar,
12
- ...rest
13
- }) => {
7
+ export const LayoutContext = createContext()
8
+
9
+ export const useLayout = () => {
10
+ const context = useContext(LayoutContext)
11
+
12
+ if (!context) {
13
+ throw new Error('useLayout must be used within a LayoutContext')
14
+ }
15
+ return context
16
+ }
17
+
18
+ const LayoutProvider = React.memo(({ monoColumn, withTopBar, children }) => {
19
+ const value = useMemo(
20
+ () => ({
21
+ monoColumn,
22
+ withTopBar
23
+ }),
24
+ [monoColumn, withTopBar]
25
+ )
26
+
14
27
  return (
15
- <div
28
+ <LayoutContext.Provider value={value}>{children}</LayoutContext.Provider>
29
+ )
30
+ })
31
+
32
+ LayoutProvider.displayName = 'LayoutProvider'
33
+
34
+ export const Layout = forwardRef(
35
+ ({ children, className, monoColumn, withTopBar, ...props }, ref) => {
36
+ const variant = monoColumn ? 'monocolumn' : '2panes'
37
+
38
+ return (
39
+ <LayoutProvider monoColumn={monoColumn} withTopBar={withTopBar}>
40
+ <div
41
+ ref={ref}
42
+ className={cx(
43
+ className,
44
+ styles['o-layout'],
45
+ styles[`o-layout-${variant}`],
46
+ {
47
+ [styles[`o-layout-topbar`]]: withTopBar
48
+ }
49
+ )}
50
+ {...props}
51
+ >
52
+ {children}
53
+ </div>
54
+ </LayoutProvider>
55
+ )
56
+ }
57
+ )
58
+
59
+ Layout.displayName = 'Layout'
60
+
61
+ export const Main = forwardRef(({ className, children, ...props }, ref) => {
62
+ const { monoColumn, withTopBar } = useLayout()
63
+ const variant = monoColumn ? 'monocolumn' : '2panes'
64
+
65
+ return (
66
+ <main
67
+ ref={ref}
16
68
  className={cx(
17
- monoColumn ? styles['o-layout'] : styles['o-layout-2panes'],
18
69
  className,
70
+ styles['o-layout-main'],
71
+ styles[`o-layout-main-${variant}`],
19
72
  {
20
- [styles[`o-layout${monoColumn ? '' : '-2panes'}--withTopBar`]]:
21
- withTopBar
73
+ [styles[`o-layout-main-${variant}--topbar`]]: withTopBar
22
74
  }
23
75
  )}
24
- {...rest}
76
+ {...props}
25
77
  >
26
78
  {children}
27
- </div>
79
+ </main>
28
80
  )
29
- }
81
+ })
30
82
 
31
- export const Main = ({ children, ...rest }) => <main {...rest}>{children}</main>
83
+ Main.displayName = 'Main'
32
84
 
33
- export class Content extends Component {
34
- render() {
35
- const { children, ...rest } = this.props
36
- return (
37
- <div role="main" {...rest}>
38
- {children}
39
- </div>
40
- )
41
- }
42
- }
85
+ export const Content = forwardRef(({ className, children, ...props }, ref) => {
86
+ const { monoColumn } = useLayout()
87
+ const variant = monoColumn ? 'monocolumn' : '2panes'
88
+
89
+ return (
90
+ <div
91
+ role="main"
92
+ ref={ref}
93
+ className={cx(
94
+ className,
95
+ styles['o-layout-content'],
96
+ styles[`o-layout-content-${variant}`]
97
+ )}
98
+ {...props}
99
+ >
100
+ {children}
101
+ </div>
102
+ )
103
+ })
104
+
105
+ Content.displayName = 'Content'
43
106
 
44
107
  Layout.propTypes = {
45
108
  children: PropTypes.node,
@@ -1,13 +1,10 @@
1
1
  @require '../../stylus/objects/layouts'
2
2
 
3
3
  .o-layout
4
- @extend $app
4
+ @extend $app-layout
5
5
 
6
- .o-layout--withTopBar
7
- @extend $app--withTopBar
6
+ .o-layout-main
7
+ @extend $app-main
8
8
 
9
- .o-layout-2panes
10
- @extend $app-2panes-sticky
11
-
12
- .o-layout-2panes--withTopBar
13
- @extend $app-2panes--withTopBar
9
+ .o-layout-content
10
+ @extend $app-content
@@ -586,8 +586,8 @@ export const makeLightNormalOverrides = theme => ({
586
586
  },
587
587
  MuiDialog: {
588
588
  paper: {
589
+ width: '100%',
589
590
  '&.small': {
590
- width: '480px',
591
591
  maxWidth: '480px',
592
592
  [theme.breakpoints.down('md')]: {
593
593
  margin: '16px',
@@ -602,19 +602,12 @@ export const makeLightNormalOverrides = theme => ({
602
602
  }
603
603
  },
604
604
  '&.medium': {
605
- [theme.breakpoints.up('md')]: {
606
- width: '544px',
607
- maxWidth: '544px'
608
- }
605
+ maxWidth: '544px'
609
606
  },
610
607
  '&.large': {
611
- [theme.breakpoints.up('md')]: {
612
- width: '800px',
613
- maxWidth: '800px'
614
- }
608
+ maxWidth: '800px'
615
609
  },
616
610
  '&.full': {
617
- width: '100%',
618
611
  maxWidth: '100%'
619
612
  }
620
613
  },
@@ -624,6 +617,15 @@ export const makeLightNormalOverrides = theme => ({
624
617
  }
625
618
  },
626
619
  paperFullScreen: {
620
+ '&.small': {
621
+ maxWidth: '100%'
622
+ },
623
+ '&.medium': {
624
+ maxWidth: '100%'
625
+ },
626
+ '&.large': {
627
+ maxWidth: '100%'
628
+ },
627
629
  '& .cozyDialogActions': {
628
630
  paddingBottom: `calc(env(safe-area-inset-bottom) + ${getFlagshipCssVar(
629
631
  'bottom'
@@ -29,11 +29,13 @@ const NavLink = genNavLink(
29
29
  <a className={cx(className, active ? activeClassName : null)}>{children}</a>
30
30
  )
31
31
  )
32
+
33
+ const demoStyle = { position: "initial" }
32
34
  // -->
33
35
 
34
36
  ;
35
37
 
36
- <Sidebar id='sidebar'>
38
+ <Sidebar id='sidebar' style={demoStyle}>
37
39
  <Nav>
38
40
  <NavItem id='nav-item'>
39
41
  <NavLink to="/warn" active>
@@ -25,11 +25,7 @@ const Sidebar = ({ children, className, ...restProps }) => {
25
25
  return (
26
26
  <aside
27
27
  id="sidebar"
28
- className={cx(
29
- styles['o-sidebar'],
30
- [styles['o-sidebar--large']],
31
- className
32
- )}
28
+ className={cx(styles['o-sidebar'], className)}
33
29
  {...restProps}
34
30
  >
35
31
  {children}
@@ -16,12 +16,20 @@ const breakpoints = {
16
16
  isMobile: [0, small]
17
17
  }
18
18
 
19
- export const getBreakpointsStatus = breakpoints => {
20
- const width = window.innerWidth
19
+ export const getBreakpointsStatus = (breakpoints, innerWidth) => {
20
+ const width = innerWidth || window.innerWidth
21
21
  return mapValues(
22
22
  breakpoints,
23
23
  ([min, max]) => width >= min && (max === undefined || width <= max)
24
24
  )
25
25
  }
26
26
 
27
+ export const isInsideIframe = () => {
28
+ try {
29
+ return window.self !== window.top
30
+ } catch (e) {
31
+ return true
32
+ }
33
+ }
34
+
27
35
  export default breakpoints
@@ -15,6 +15,8 @@ completely change the content, the layout, or prune away complete
15
15
  subtrees (useful on mobile where space is at a premium). Here for
16
16
  example, the square contents changes on desktop or mobile.
17
17
 
18
+ By default, using `useBreakpoints` inside an iframe will refere to the iframe inner width. If you use `parentBasedIframe=true` on the provider wrapping the iframe, the breakpoints returned inside the iframe will refere to the parent window inner width instead.
19
+
18
20
  ```jsx
19
21
  import useBreakpoints, { BreakpointsProvider } from 'cozy-ui/transpiled/react/providers/Breakpoints'
20
22
 
@@ -1,20 +1,25 @@
1
1
  import throttle from 'lodash/throttle'
2
+ import PropTypes from 'prop-types'
2
3
  import React, { createContext, useContext, useState, useEffect } from 'react'
3
4
 
4
- import breakpointDefs, {
5
- getBreakpointsStatus as _getBreakpointsStatus
6
- } from '../../helpers/breakpoints'
7
-
8
- const getBreakpointsStatus = () => _getBreakpointsStatus(breakpointDefs)
5
+ import { useIframeConnection } from './useIframeConnection'
6
+ import { useIframeToSendWidth } from './useIframeToSendWidth'
7
+ import { useParentBreakpoints } from './useParentBreakpoints'
8
+ import breakpointDefs, { getBreakpointsStatus } from '../../helpers/breakpoints'
9
9
 
10
10
  const BreakpointsCtx = createContext(null)
11
11
 
12
- export const BreakpointsProvider = ({ children }) => {
13
- const [breakpoints, setBreakpoints] = useState(getBreakpointsStatus())
12
+ export const BreakpointsProvider = ({ parentBasedIframe, children }) => {
13
+ const [breakpoints, setBreakpoints] = useState(
14
+ getBreakpointsStatus(breakpointDefs)
15
+ )
16
+ const { hasIframe } = useIframeConnection({ parentBasedIframe })
17
+ useIframeToSendWidth({ hasIframe })
18
+ const { parentBreakpoints } = useParentBreakpoints({ parentBasedIframe })
14
19
 
15
20
  useEffect(() => {
16
21
  const handleResize = throttle(() => {
17
- setBreakpoints(getBreakpointsStatus())
22
+ setBreakpoints(getBreakpointsStatus(breakpointDefs))
18
23
  }, 100)
19
24
 
20
25
  window.addEventListener('resize', handleResize)
@@ -25,12 +30,21 @@ export const BreakpointsProvider = ({ children }) => {
25
30
  }, [])
26
31
 
27
32
  return (
28
- <BreakpointsCtx.Provider value={breakpoints}>
33
+ <BreakpointsCtx.Provider value={parentBreakpoints || breakpoints}>
29
34
  {children}
30
35
  </BreakpointsCtx.Provider>
31
36
  )
32
37
  }
33
38
 
39
+ BreakpointsProvider.defaultProps = {
40
+ parentBasedIframe: false
41
+ }
42
+
43
+ BreakpointsProvider.propTypes = {
44
+ /** Iframes breakpoints are based on parent window inner width instead of iframe inner width */
45
+ parentBasedIframe: PropTypes.bool
46
+ }
47
+
34
48
  export const useBreakpoints = () => {
35
49
  const v = useContext(BreakpointsCtx)
36
50
  if (v === null) {
@@ -0,0 +1,31 @@
1
+ import { useEffect, useState } from 'react'
2
+
3
+ import { isInsideIframe } from '../../helpers/breakpoints'
4
+
5
+ export const useIframeConnection = ({ parentBasedIframe }) => {
6
+ const [hasIframe, setHasIframe] = useState(false)
7
+
8
+ const isIframe = parentBasedIframe && isInsideIframe()
9
+
10
+ // parent window receives from iframe to give breakpoints
11
+ useEffect(() => {
12
+ const handleMessage = ev => {
13
+ if (ev.data === 'UI-breakpoints-needParentBreakpoints') {
14
+ setHasIframe(true)
15
+ }
16
+ }
17
+
18
+ window.addEventListener('message', handleMessage)
19
+
20
+ return () => window.removeEventListener('message', handleMessage)
21
+ }, [])
22
+
23
+ // iframe send to parent window ask for its breakpoints
24
+ useEffect(() => {
25
+ if (isIframe) {
26
+ window.parent.postMessage('UI-breakpoints-needParentBreakpoints', '*')
27
+ }
28
+ }, [isIframe])
29
+
30
+ return { hasIframe }
31
+ }
@@ -0,0 +1,33 @@
1
+ import throttle from 'lodash/throttle'
2
+ import { useEffect } from 'react'
3
+
4
+ /**
5
+ * To send window innerWidth to first iframe
6
+ * @returns
7
+ */
8
+ const sendWidthToIframe = () =>
9
+ window.frames[1].postMessage(`UI-breakpoints-value:${window.innerWidth}`, '*')
10
+
11
+ export const useIframeToSendWidth = ({ hasIframe }) => {
12
+ // parent window send its innerWidth
13
+ useEffect(() => {
14
+ if (hasIframe) {
15
+ sendWidthToIframe()
16
+ }
17
+ }, [hasIframe])
18
+
19
+ // parent window send its innerWidth on resize
20
+ useEffect(() => {
21
+ const handleResize = throttle(() => {
22
+ if (hasIframe) {
23
+ sendWidthToIframe()
24
+ }
25
+ }, 100)
26
+
27
+ window.addEventListener('resize', handleResize)
28
+
29
+ return () => {
30
+ window.removeEventListener('resize', handleResize)
31
+ }
32
+ }, [hasIframe])
33
+ }
@@ -0,0 +1,36 @@
1
+ import { useState, useEffect } from 'react'
2
+
3
+ import breakpointDefs, {
4
+ getBreakpointsStatus,
5
+ isInsideIframe
6
+ } from '../../helpers/breakpoints'
7
+
8
+ export const useParentBreakpoints = ({ parentBasedIframe }) => {
9
+ const [parentBreakpoints, setParentBreakpoints] = useState()
10
+
11
+ const isIframe = parentBasedIframe && isInsideIframe()
12
+
13
+ // iframe receives breakpoints from parent window
14
+ useEffect(() => {
15
+ const handleMessage = ev => {
16
+ if (!isIframe) return
17
+
18
+ if (
19
+ typeof ev.data === 'string' &&
20
+ ev.data.includes?.('UI-breakpoints-value:')
21
+ ) {
22
+ const parentInnerWidth = ev.data.split(':')[1]
23
+
24
+ setParentBreakpoints(
25
+ getBreakpointsStatus(breakpointDefs, parentInnerWidth)
26
+ )
27
+ }
28
+ }
29
+
30
+ window.addEventListener('message', handleMessage)
31
+
32
+ return () => window.removeEventListener('message', handleMessage)
33
+ }, [isIframe])
34
+
35
+ return { parentBreakpoints }
36
+ }
@@ -50,8 +50,7 @@ $elastic-content
50
50
  $elastic-bar
51
51
  flex 0 0 auto
52
52
 
53
- // One column layout
54
- $app
53
+ $app-layout
55
54
  box-sizing border-box
56
55
  display flex
57
56
  max-width 100%
@@ -60,102 +59,90 @@ $app
60
59
  background-color var(--paperBackgroundColor)
61
60
  color var(--primaryTextColor)
62
61
 
63
- main
64
- display flex
65
- flex-direction column
66
- flex 0 0 auto
67
-
68
- main,
69
- main > [role=contentinfo], // Deprecated
70
- main > [role=main]
71
- position relative
72
- display flex
73
- flex-direction column
74
- flex 1 1 auto
75
- box-sizing border-box
76
- height 100%
77
- overflow-x hidden
78
- overflow-y auto
79
-
80
62
  +medium-screen() // mobile + tablet
81
63
  display block
82
64
 
65
+ &-topbar
66
+ +medium-screen() // mobile + tablet
67
+ // this pseudo-element is "ghost" element replacing bar
68
+ &:before
69
+ content ''
70
+ display block
71
+ height barHeight
72
+
73
+ // When you want a sidebar
74
+ &-2panes
75
+ flex 0 0 100%
76
+ align-items stretch
77
+
78
+ +medium-screen() // mobile + tablet
79
+ // this pseudo-element is "ghost" element replacing nav
80
+ &:after
81
+ content ''
82
+ display block
83
+ height navHeight
84
+
85
+ $app-main
86
+ display flex
87
+ flex-direction column
88
+ position relative
89
+ flex 1 1 auto
90
+ box-sizing border-box
91
+ overflow-x hidden
92
+ overflow-y auto
93
+
94
+ +medium-screen() // mobile + tablet
95
+ display block
96
+ overflow visible
83
97
  // iPhone X environment tweak
84
- main
85
- padding-left env(safe-area-inset-left)
86
- padding-right env(safe-area-inset-right)
87
- padding-bottom env(safe-area-inset-bottom)
88
- min-height 100vh
98
+ padding-left env(safe-area-inset-left)
99
+ padding-right env(safe-area-inset-right)
100
+ padding-bottom env(safe-area-inset-bottom)
89
101
 
90
- main,
91
- main > [role=contentinfo], // Deprecated
92
- main > [role=main]
93
- display block
94
- overflow visible
102
+ &-monocolumn
103
+ height 100%
95
104
 
96
- $app--withTopBar
97
- +medium-screen() // mobile + tablet
98
- main
99
- min-height 'calc(100vh - %s)' % barHeight
100
-
101
- // this pseudo-element is "ghost" element replacing bar
102
- &:before
103
- content ''
104
- display block
105
- height barHeight
106
-
107
- // STICKY layout
108
- // When you want a sidebar and you want it to act like a sticky footer on mobile
109
- $app-2panes-sticky
110
- @extend $app
111
- flex 0 0 100%
112
- align-items stretch
105
+ +medium-screen() // mobile + tablet
106
+ min-height 100vh
113
107
 
114
- & > aside
115
- display flex
116
- flex-direction column
117
- flex 0 0 auto
108
+ &--topbar
109
+ +medium-screen() // mobile + tablet
110
+ min-height 'calc(100vh - %s)' % barHeight
118
111
 
119
- main,
120
- main > [role=contentinfo], // Deprecated
121
- main > [role=main]
112
+ &-2panes
122
113
  height auto
114
+ background-color var(--defaultBackgroundColor)
123
115
 
124
- // rounded effect
125
- +medium-screen('min') // desktop only
126
- main
127
- background-color var(--defaultBackgroundColor)
116
+ +medium-screen() // mobile + tablet
117
+ min-height calc(100vh - var(--sidebarHeight))
118
+ background-color transparent
128
119
 
129
- & > [role=main]
130
- margin 1rem 1rem 1rem 0
131
- border-radius 1rem
132
- background-color var(--paperBackgroundColor)
120
+ &--topbar
121
+ +medium-screen() // mobile + tablet
122
+ min-height 'calc(100vh - var(--sidebarHeight) - %s)' % barHeight
133
123
 
134
- +medium-screen() // mobile + tablet
135
- main
136
- min-height calc(100vh - var(--sidebarHeight))
124
+ $app-content
125
+ position relative
126
+ display flex
127
+ flex-direction column
128
+ flex 1 1 auto
129
+ box-sizing border-box
130
+ overflow-x hidden
131
+ overflow-y auto
132
+ background-color var(--paperBackgroundColor)
137
133
 
138
- // this pseudo-element is "ghost" element replacing nav
139
- &:after
140
- content ''
141
- display block
142
- height navHeight
143
-
144
- > aside
145
- position fixed
146
- bottom 0
147
- left 0
148
- display block
149
- z-index var(--zIndex-nav)
150
- width 100%
151
-
152
- $app-2panes--withTopBar
153
134
  +medium-screen() // mobile + tablet
154
- main
155
- min-height 'calc(100vh - var(--sidebarHeight) - %s)' % barHeight
156
-
157
- // this pseudo-element is "ghost" element replacing bar
158
- &:before
159
- content ''
160
- display block
161
- height barHeight
135
+ display block
136
+ overflow visible
137
+
138
+ &-monocolumn
139
+ height 100%
140
+
141
+ &-2panes
142
+ height auto
143
+ margin 1rem 1rem 1rem 0
144
+ border-radius 1rem
145
+
146
+ +medium-screen() // mobile + tablet
147
+ margin 0
148
+ border-radius 0
@@ -9,22 +9,27 @@
9
9
  --sidebarHeight: rem(52)
10
10
 
11
11
  $sidebar
12
- width rem(220)
12
+ width rem(236)
13
13
  background-color var(--defaultBackgroundColor)
14
14
  overflow-y auto
15
15
  overflow-x hidden
16
+ display flex
17
+ flex-direction column
18
+ flex 0 0 auto
16
19
 
17
20
  &--border
18
21
  border-right rem(1) solid var(--dividerColor)
19
22
 
20
- &--large
21
- width rem(236)
22
-
23
23
  +medium-screen()
24
24
  justify-content space-between
25
25
  border 0
26
26
  border-top rem(1) solid var(--dividerColor)
27
27
  height var(--sidebarHeight)
28
28
  width 100%
29
+ position fixed
30
+ bottom 0
31
+ left 0
32
+ display block
33
+ z-index var(--zIndex-nav)
29
34
  // iPhone X environment tweak
30
35
  padding-bottom env(safe-area-inset-bottom)