cozy-ui 111.13.0 → 111.15.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 (32) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/assets/icons/ui/stop.svg +1 -0
  3. package/package.json +1 -1
  4. package/react/BottomSheet/BottomSheet.jsx +5 -1
  5. package/react/BottomSheet/README.md +2 -0
  6. package/react/BottomSheet/helpers.js +2 -0
  7. package/react/BottomSheet/helpers.spec.js +12 -0
  8. package/react/CozyDialogs/Readme.md +8 -1
  9. package/react/CozyDialogs/dialogPropTypes.js +1 -1
  10. package/react/CozyDialogs/useCozyDialog.js +4 -1
  11. package/react/Icon/Readme.md +3 -1
  12. package/react/Icons/Stop.jsx +12 -0
  13. package/react/MuiCozyTheme/overrides/makeLightNormalOverrides.js +4 -0
  14. package/react/SearchBar/Readme.md +56 -3
  15. package/react/SearchBar/index.jsx +105 -27
  16. package/react/SearchBar/locales/en.json +1 -1
  17. package/react/SearchBar/locales/fr.json +1 -1
  18. package/react/providers/DemoProvider.jsx +3 -9
  19. package/transpiled/react/BottomSheet/BottomSheet.js +7 -1
  20. package/transpiled/react/BottomSheet/helpers.js +3 -1
  21. package/transpiled/react/CozyDialogs/dialogPropTypes.js +1 -1
  22. package/transpiled/react/CozyDialogs/useCozyDialog.js +12 -7
  23. package/transpiled/react/Icon/icons-sprite.js +1 -1
  24. package/transpiled/react/Icons/Stop.js +13 -0
  25. package/transpiled/react/MuiCozyTheme/overrides/makeDarkInvertedOverrides.d.ts +4 -0
  26. package/transpiled/react/MuiCozyTheme/overrides/makeDarkNormalOverrides.d.ts +4 -0
  27. package/transpiled/react/MuiCozyTheme/overrides/makeLightInvertedOverrides.d.ts +4 -0
  28. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.d.ts +4 -0
  29. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.js +4 -0
  30. package/transpiled/react/SearchBar/index.js +113 -30
  31. package/transpiled/react/SearchBar/locales/withOnlyLocales.js +2 -2
  32. package/transpiled/react/providers/DemoProvider.js +5 -10
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ # [111.15.0](https://github.com/cozy/cozy-ui/compare/v111.14.0...v111.15.0) (2024-10-09)
2
+
3
+
4
+ ### Features
5
+
6
+ * **Icon:** Add `stop` ([f975a5d](https://github.com/cozy/cozy-ui/commit/f975a5d))
7
+
8
+ # [111.14.0](https://github.com/cozy/cozy-ui/compare/v111.13.0...v111.14.0) (2024-10-03)
9
+
10
+
11
+ ### Features
12
+
13
+ * **BottomSheet:** Add `hasMinHeightOffset` prop ([0e1af92](https://github.com/cozy/cozy-ui/commit/0e1af92))
14
+ * **CozyDialogs:** Add `full` size ([d141068](https://github.com/cozy/cozy-ui/commit/d141068))
15
+ * **CozyDialogs:** We can now propagates props to inner components ([01d9d48](https://github.com/cozy/cozy-ui/commit/01d9d48))
16
+ * **SearchBar:** Add `auto` size and possibility to control it in the app ([038555f](https://github.com/cozy/cozy-ui/commit/038555f))
17
+ * **SearchBar:** Add multiple props to improve component management ([13f8450](https://github.com/cozy/cozy-ui/commit/13f8450))
18
+
1
19
  # [111.13.0](https://github.com/cozy/cozy-ui/compare/v111.12.0...v111.13.0) (2024-09-25)
2
20
 
3
21
 
@@ -0,0 +1 @@
1
+ <svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="M.75 1.5A.75.75 0 0 1 1.5.75h9a.75.75 0 0 1 .75.75v9a.75.75 0 0 1-.75.75h-9a.75.75 0 0 1-.75-.75v-9Z"/></svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "111.13.0",
3
+ "version": "111.15.0",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -129,6 +129,7 @@ export const defaultBottomSheetSpringConfig = {
129
129
  const defaultSettings = {
130
130
  mediumHeightRatio: 0.75,
131
131
  mediumHeight: null,
132
+ hasMinHeightOffset: false,
132
133
  isOpenMin: false
133
134
  }
134
135
 
@@ -142,7 +143,7 @@ const BottomSheet = memo(
142
143
  offset,
143
144
  children
144
145
  }) => {
145
- const { mediumHeightRatio, mediumHeight, isOpenMin } = {
146
+ const { mediumHeightRatio, mediumHeight, isOpenMin, hasMinHeightOffset } = {
146
147
  ...defaultSettings,
147
148
  ...settings
148
149
  }
@@ -244,6 +245,7 @@ const BottomSheet = memo(
244
245
  isClosable,
245
246
  isOpenMin,
246
247
  headerRef,
248
+ offset: hasMinHeightOffset ? offset : 0,
247
249
  actionButtonsHeight,
248
250
  actionButtonsBottomMargin
249
251
  })
@@ -418,6 +420,8 @@ BottomSheet.propTypes = {
418
420
  mediumHeight: PropTypes.number,
419
421
  /** Height of the middle snap point, expressed as a percentage of the viewport height */
420
422
  mediumHeightRatio: PropTypes.number,
423
+ /** To include the offset in the min height value */
424
+ hasMinHeightOffset: PropTypes.bool,
421
425
  /** To open the BottomSheet at the minimum height, if have an header */
422
426
  isOpenMin: PropTypes.bool
423
427
  }),
@@ -46,6 +46,8 @@ import BottomSheet, { BottomSheetItem, BottomSheetTitle } from 'cozy-ui/transp
46
46
  * **settings** : `<object>` – Settings that can be modified
47
47
  * **mediumHeight** : `<number>` – Height in pixel of the middle snap point
48
48
  * **mediumHeightRatio** : `<number>` – Height of the middle snap point, expressed as a percentage of the viewport height
49
+ * **isOpenMin** : `<boolean>` – To open the BottomSheet at the minimum height, if have an header
50
+ * **hasMinHeightOffset** : `<boolean>` – To include the offset in the min height value
49
51
  * **backdrop** : `<boolean>` – To add a backdrop
50
52
  * **skipAnimation** : `<boolean>` – To remove animations
51
53
  * **offset** : `<number>` – Add an offset at the bottom
@@ -57,6 +57,7 @@ export const computeMinHeight = ({
57
57
  isClosable,
58
58
  isOpenMin,
59
59
  headerRef,
60
+ offset = 0,
60
61
  actionButtonsHeight,
61
62
  actionButtonsBottomMargin
62
63
  }) => {
@@ -64,6 +65,7 @@ export const computeMinHeight = ({
64
65
 
65
66
  return (
66
67
  headerRef.current.offsetHeight +
68
+ offset +
67
69
  actionButtonsHeight +
68
70
  actionButtonsBottomMargin +
69
71
  (getFlagshipMetadata().navbarHeight || 0) +
@@ -152,6 +152,18 @@ describe('computeMinHeight', () => {
152
152
 
153
153
  expect(res).toBe(85)
154
154
  })
155
+
156
+ it('should return correct value with offset', () => {
157
+ const res = computeMinHeight({
158
+ isClosable: false,
159
+ headerRef: { current: { offsetHeight: 10 } },
160
+ offset: 10,
161
+ actionButtonsHeight: 20,
162
+ actionButtonsBottomMargin: 30
163
+ })
164
+
165
+ expect(res).toBe(95)
166
+ })
155
167
  })
156
168
 
157
169
  describe('setTopPosition', () => {
@@ -33,7 +33,7 @@ import Button from 'cozy-ui/transpiled/react/Buttons'
33
33
 
34
34
  * **componentsProps** : `<object>` – overriden properties of specific components
35
35
  * **dialogTitle** : `<object>` – DialogTitle component properties
36
- * **size** : `<string>` – Can be "s", "m" (default) or "l"
36
+ * **size** : `<string>` – Can be "small", "medium" (default), "large" or "full"
37
37
  * **open** : `<boolean>` (required) – To open/close the modal
38
38
  * **disableTitleAutoPadding** : `<boolean>` (optional) – Disable title padding calculation that would prevent overlapping with close and back buttons
39
39
  * if set to `true` then you should handle those CSS properties by yourself or title will take 100% of width
@@ -205,6 +205,7 @@ const initialVariants = [{
205
205
  showActions: true,
206
206
  disableGutters: false,
207
207
  hideTitle: false,
208
+ fullScreen: false,
208
209
  withBackground: false
209
210
  }]
210
211
 
@@ -264,6 +265,11 @@ const initialVariants = [{
264
265
  label="Large"
265
266
  control={<Radio />}
266
267
  />
268
+ <FormControlLabel
269
+ value="full"
270
+ label="Full"
271
+ control={<Radio />}
272
+ />
267
273
  </RadioGroup>
268
274
  </FormControl>
269
275
  <div className="u-mt-1">
@@ -283,6 +289,7 @@ const initialVariants = [{
283
289
  {state.modalOpened && (
284
290
  <DialogComponent
285
291
  open
292
+ {...(variant.fullScreen && { fullScreen: true })}
286
293
  size={DialogComponent !== ConfirmDialog ? state.size : undefined}
287
294
  onClose={variant.withCloseButton ? handleClose : undefined}
288
295
  onBack={variant.withBackButton ? handleBack : undefined}
@@ -1,7 +1,7 @@
1
1
  import PropTypes from 'prop-types'
2
2
 
3
3
  export default {
4
- size: PropTypes.oneOf(['small', 'medium', 'large']),
4
+ size: PropTypes.oneOf(['small', 'medium', 'large', 'full']),
5
5
  open: PropTypes.bool.isRequired,
6
6
  disableTitleAutoPadding: PropTypes.bool,
7
7
  background: PropTypes.string,
@@ -6,7 +6,7 @@ import useBreakpoints from '../providers/Breakpoints'
6
6
  import { makeStyles } from '../styles'
7
7
 
8
8
  let globalId = 0
9
- const modalSizes = ['small', 'medium', 'large']
9
+ const modalSizes = ['small', 'medium', 'large', 'full']
10
10
 
11
11
  const useStyles = makeStyles({
12
12
  paper: {
@@ -92,6 +92,7 @@ const useCozyDialog = props => {
92
92
 
93
93
  const dividerClassName = 'divider--dialog'
94
94
  const dividerProps = {
95
+ ...componentsProps?.divider,
95
96
  classes: {
96
97
  root: dividerClassName
97
98
  }
@@ -99,12 +100,14 @@ const useCozyDialog = props => {
99
100
 
100
101
  const dialogActionsClassName = 'cozyDialogActions'
101
102
  const dialogActionsProps = {
103
+ ...componentsProps?.dialogActions,
102
104
  classes: {
103
105
  root: dialogActionsClassName
104
106
  }
105
107
  }
106
108
 
107
109
  const dialogContentProps = {
110
+ ...componentsProps?.dialogContent,
108
111
  classes: {
109
112
  root: cx({
110
113
  disableGutters
@@ -288,6 +288,7 @@ import Stack from 'cozy-ui/transpiled/react/Icons/Stack'
288
288
  import Star from 'cozy-ui/transpiled/react/Icons/Star'
289
289
  import StarOutline from 'cozy-ui/transpiled/react/Icons/StarOutline'
290
290
  import Stats from 'cozy-ui/transpiled/react/Icons/Stats'
291
+ import Stop from 'cozy-ui/transpiled/react/Icons/Stop'
291
292
  import Subway from 'cozy-ui/transpiled/react/Icons/Subway'
292
293
  import Support from 'cozy-ui/transpiled/react/Icons/Support'
293
294
  import Swap from 'cozy-ui/transpiled/react/Icons/Swap'
@@ -550,6 +551,7 @@ const icons = [
550
551
  Star,
551
552
  StarOutline,
552
553
  Stats,
554
+ Stop,
553
555
  Subway,
554
556
  Support,
555
557
  Swap,
@@ -923,7 +925,7 @@ import Typography from 'cozy-ui/transpiled/react/Typography'
923
925
 
924
926
  const colors = ['#297EF2', '#08b442', '#B449E7', '#F52D2D', '#FF962F']
925
927
  let i = 0
926
- const availableIcons = ['album-add','album-remove','album','answer','apple','archive','arrowUp','attachment','attention','bank-check','bank','banking-add','banking','bell','benefit','bike','bill','bottom','browser-brave','browser-chrome','browser-duckduckgo','browser-edge','browser-edge-chromium','browser-firefox','browser-ie','browser-opera','browser-safari','burger','bus','calendar','camera','car','carbonCopy','carpooling','categories','certified','check-circle','check-list','check-square','check','checkbox','chess','child','circle-filled','clock','clock-outline','cloud-happy','cloud','collect','cocktail','comment','company','compare','compass','connector','contract','contrast','copy','cozy-circle','cozy-laugh', 'cozy-lock', 'cozy-text', 'cozy-release', 'credit-card-add','credit-card','credit','crop','cross-circle-outline','cross-circle','cross-medium','cross-small','cross','cube','dash','dashboard','data-control','debit','devices','dots','down','download','drawing-arrow-up','dropdown-close','dropdown-open','dropdown','dropup','electric-bike','electric-car','electric-scooter','email-notification','email','eu','euro','exchange','eye-closed','eye','face-id','file-add','file-duotone','file-new','file-none','file-outline','file','filter','fingerprint','fitness','flag-outlined','flag','flash-auto','flashlight','folder-add','folder-moveto','folder','forbidden','from-user','gear','globe','gouv','graph-circle','grid','group-list','groups','growth','hand','heart','help','help-outlined','history','home','hourglass','image','info-outlined','info','justice','key','label-outlined','laudry','laptop','left','library','lightbulb','lightning','link-out','link','list','list-min','location','lock', 'lock-screen', 'logout','magic-trick','magnet','magnifier','merge','moped','mosaic-min','motorcycle','mountain','movement-in','movement-out','mouvement','moveto','multi-files','music','new','next','note','notification-email','offline','online', 'openapp', 'openwith','palette','paper','paperplane','password','pen','people','percent-circle','percent','personal-data','phone-download','phone-upload','phone','pie-chart','pin','plane','plus-small','plus', 'pop-inside', 'previous','printer','qualify','radio-checked','radio-unchecked','refresh','relationship','remboursement','rename','repare','reply','restaurant','restore-straight','restore','right','rise','rotate-left','rotate-right','sad-cozy','safe','school','scooter','select-all','setting','share-circle','share','shield','shop','sound','spinner','sport-bag','stack','star','star-outline','stats','subway', 'support', 'swap', 'sync-cozy','sync','tag','target','task','team','telecom','telephone','text-info','to-the-cloud','top','train','tram','trash','trophy', 'uncloud', 'unknow','unlink','unlock','up','upload','videos','walk','wallet-add','wallet-new','wallet','warn','warning-circle','warning','water','wrench-circle','work']
928
+ const availableIcons = ['album-add','album-remove','album','answer','apple','archive','arrowUp','attachment','attention','bank-check','bank','banking-add','banking','bell','benefit','bike','bill','bottom','browser-brave','browser-chrome','browser-duckduckgo','browser-edge','browser-edge-chromium','browser-firefox','browser-ie','browser-opera','browser-safari','burger','bus','calendar','camera','car','carbonCopy','carpooling','categories','certified','check-circle','check-list','check-square','check','checkbox','chess','child','circle-filled','clock','clock-outline','cloud-happy','cloud','collect','cocktail','comment','company','compare','compass','connector','contract','contrast','copy','cozy-circle','cozy-laugh', 'cozy-lock', 'cozy-text', 'cozy-release', 'credit-card-add','credit-card','credit','crop','cross-circle-outline','cross-circle','cross-medium','cross-small','cross','cube','dash','dashboard','data-control','debit','devices','dots','down','download','drawing-arrow-up','dropdown-close','dropdown-open','dropdown','dropup','electric-bike','electric-car','electric-scooter','email-notification','email','eu','euro','exchange','eye-closed','eye','face-id','file-add','file-duotone','file-new','file-none','file-outline','file','filter','fingerprint','fitness','flag-outlined','flag','flash-auto','flashlight','folder-add','folder-moveto','folder','forbidden','from-user','gear','globe','gouv','graph-circle','grid','group-list','groups','growth','hand','heart','help','help-outlined','history','home','hourglass','image','info-outlined','info','justice','key','label-outlined','laudry','laptop','left','library','lightbulb','lightning','link-out','link','list','list-min','location','lock', 'lock-screen', 'logout','magic-trick','magnet','magnifier','merge','moped','mosaic-min','motorcycle','mountain','movement-in','movement-out','mouvement','moveto','multi-files','music','new','next','note','notification-email','offline','online', 'openapp', 'openwith','palette','paper','paperplane','password','pen','people','percent-circle','percent','personal-data','phone-download','phone-upload','phone','pie-chart','pin','plane','plus-small','plus', 'pop-inside', 'previous','printer','qualify','radio-checked','radio-unchecked','refresh','relationship','remboursement','rename','repare','reply','restaurant','restore-straight','restore','right','rise','rotate-left','rotate-right','sad-cozy','safe','school','scooter','select-all','setting','share-circle','share','shield','shop','sound','spinner','sport-bag','stack','star','star-outline','stats','stop', 'subway', 'support', 'swap', 'sync-cozy','sync','tag','target','task','team','telecom','telephone','text-info','to-the-cloud','top','train','tram','trash','trophy', 'uncloud', 'unknow','unlink','unlock','up','upload','videos','walk','wallet-add','wallet-new','wallet','warn','warning-circle','warning','water','wrench-circle','work']
927
929
  ;
928
930
  <div style={{ fontSize: '2rem', display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)' }}>
929
931
  <Sprite />
@@ -0,0 +1,12 @@
1
+ // Automatically created, please run `scripts/generate-svgr-icon.sh assets/icons/ui/stop.svg` to regenerate;
2
+ import React from 'react'
3
+
4
+ function SvgStop(props) {
5
+ return (
6
+ <svg viewBox="0 0 12 12" {...props}>
7
+ <path d="M.75 1.5A.75.75 0 011.5.75h9a.75.75 0 01.75.75v9a.75.75 0 01-.75.75h-9a.75.75 0 01-.75-.75v-9z" />
8
+ </svg>
9
+ )
10
+ }
11
+
12
+ export default SvgStop
@@ -455,6 +455,10 @@ export const makeLightNormalOverrides = theme => ({
455
455
  maxWidth: '800px'
456
456
  }
457
457
  },
458
+ '&.full': {
459
+ width: '100%',
460
+ maxWidth: '100%'
461
+ },
458
462
  '&.overflow': {
459
463
  overflowY: 'visible !important', // Allow the icon to overflow the dialog, otherwise it will be cut off,
460
464
  '& .cozyDialogContent': {
@@ -3,8 +3,15 @@ import DemoProvider from 'cozy-ui/docs/components/DemoProvider'
3
3
  import Variants from 'cozy-ui/docs/components/Variants'
4
4
  import SearchBar from 'cozy-ui/transpiled/react/SearchBar'
5
5
  import Typography from 'cozy-ui/transpiled/react/Typography'
6
+ import CloudIcon from 'cozy-ui/transpiled/react/Icons/Cloud'
7
+ import FormControlLabel from 'cozy-ui/transpiled/react/FormControlLabel'
8
+ import RadioGroup from 'cozy-ui/transpiled/react/RadioGroup'
9
+ import Radio from 'cozy-ui/transpiled/react/Radios'
10
+ import FormControl from 'cozy-ui/transpiled/react/FormControl'
11
+ import FormLabel from 'cozy-ui/transpiled/react/FormLabel'
6
12
 
7
- const initialVariants = [{ elevation: true }]
13
+ const initialVariants = [{ elevation: true, button: false, customIcon: false, disabledClear: false }]
14
+ initialState = { size: 'small' }
8
15
 
9
16
  ;
10
17
 
@@ -12,10 +19,56 @@ const initialVariants = [{ elevation: true }]
12
19
  <Variants initialVariants={initialVariants} screenshotAllVariants>
13
20
  {variant => (
14
21
  <>
22
+ <FormControl component="fieldset">
23
+ <FormLabel component="legend">Size</FormLabel>
24
+ <RadioGroup
25
+ aria-label="radio"
26
+ name="size"
27
+ row
28
+ value={state.size}
29
+ onChange={event => { setState({ size: event.target.value }) }}
30
+ >
31
+ <FormControlLabel
32
+ value="small"
33
+ label="Small"
34
+ control={<Radio />}
35
+ />
36
+ <FormControlLabel
37
+ value="medium"
38
+ label="Medium"
39
+ control={<Radio />}
40
+ />
41
+ <FormControlLabel
42
+ value="large"
43
+ label="Large"
44
+ control={<Radio />}
45
+ />
46
+ <FormControlLabel
47
+ value="auto"
48
+ label="Auto"
49
+ control={<Radio />}
50
+ />
51
+ </RadioGroup>
52
+ </FormControl>
15
53
  <Typography className="u-mb-half">Normal</Typography>
16
- <SearchBar className="u-mb-2" elevation={variant.elevation} />
54
+ <SearchBar className="u-mb-2"
55
+ elevation={variant.elevation}
56
+ size={state.size}
57
+ disabledClear={variant.disabledClear}
58
+ type={variant.button ? "button" : "search"}
59
+ icon={variant.customIcon ? CloudIcon : undefined}
60
+ label={variant.button ? <Typography color="primary">This is a label</Typography> : undefined}
61
+ />
17
62
  <Typography className="u-mb-half">Disabled</Typography>
18
- <SearchBar elevation={variant.elevation} disabled />
63
+ <SearchBar
64
+ disabled
65
+ elevation={variant.elevation}
66
+ size={state.size}
67
+ disabledClear={variant.disabledClear}
68
+ type={variant.button ? "button" : "search"}
69
+ icon={variant.customIcon ? CloudIcon : undefined}
70
+ label={variant.button ? <Typography color="primary">This is a label</Typography> : undefined}
71
+ />
19
72
  </>
20
73
  )}
21
74
  </Variants>
@@ -3,25 +3,42 @@ import debounce from 'lodash/debounce'
3
3
  import PropTypes from 'prop-types'
4
4
  import React, { forwardRef, useState, useMemo } from 'react'
5
5
 
6
- import withOnlyLocales from './locales/withOnlyLocales'
6
+ import { locales } from './locales/withOnlyLocales'
7
+ import ButtonBase from '../ButtonBase'
7
8
  import Icon from '../Icon'
9
+ import { iconPropType } from '../Icon'
8
10
  import IconButton from '../IconButton'
9
11
  import CrossCircleIcon from '../Icons/CrossCircle'
10
12
  import MagnifierIcon from '../Icons/Magnifier'
11
13
  import InputBase from '../InputBase'
12
14
  import Paper from '../Paper'
13
- import { useI18n } from '../providers/I18n'
15
+ import Typography from '../Typography'
16
+ import { useI18n, useExtendI18n } from '../providers/I18n'
14
17
  import { makeStyles } from '../styles'
15
18
 
19
+ const sizeToPixel = {
20
+ small: 40,
21
+ medium: 48,
22
+ large: 56,
23
+ auto: 'auto'
24
+ }
25
+
26
+ const radiusBySize = {
27
+ small: 20,
28
+ medium: 24,
29
+ large: 28,
30
+ auto: 24
31
+ }
32
+
16
33
  const useStyles = makeStyles(theme => ({
17
34
  root: {
18
35
  display: 'flex',
19
36
  boxSizing: 'border-box',
20
37
  position: 'relative',
21
38
  alignItems: 'center',
22
- height: 40,
39
+ height: ({ size }) => sizeToPixel[size],
23
40
  flex: 1,
24
- borderRadius: 99,
41
+ borderRadius: ({ size }) => radiusBySize[size],
25
42
  borderStyle: 'solid',
26
43
  borderWidth: 1,
27
44
  borderColor: 'transparent',
@@ -37,7 +54,19 @@ const useStyles = makeStyles(theme => ({
37
54
  backgroundColor: theme.palette.background.contrast
38
55
  },
39
56
  inputBase: {
40
- flex: 1
57
+ flex: 1,
58
+ paddingLeft: ({ icon }) => !icon && '1rem'
59
+ },
60
+ buttonBase: {
61
+ flex: 1,
62
+ justifyContent: 'start',
63
+ height: '100%',
64
+ borderRadius: 99
65
+ },
66
+ typography: {
67
+ color: 'currentColor',
68
+ opacity: 0.42,
69
+ paddingLeft: ({ icon }) => !icon && '1rem'
41
70
  },
42
71
  icon: {
43
72
  color: theme.palette.text.secondary,
@@ -81,8 +110,15 @@ const SearchBar = forwardRef(
81
110
  (
82
111
  {
83
112
  placeholder: placeholderProp,
113
+ icon,
114
+ size,
115
+ type,
116
+ label: labelProp,
117
+ componentsProps,
118
+ disabledClear,
84
119
  className,
85
120
  defaultValue,
121
+ value,
86
122
  elevation,
87
123
  disabled,
88
124
  onChange,
@@ -93,23 +129,25 @@ const SearchBar = forwardRef(
93
129
  ref
94
130
  ) => {
95
131
  const { t } = useI18n()
96
- const classes = useStyles()
132
+ const classes = useStyles({ size, type, icon })
97
133
  const [currentValue, setCurrentValue] = useState(defaultValue)
98
134
  const [isFocused, setIsFocused] = useState(false)
99
135
 
100
- const placeholder = placeholderProp || t('search.placeholder')
136
+ const placeholder = placeholderProp || t('SearchBar.placeholder')
137
+ const label = labelProp || t('SearchBar.placeholder')
138
+ const spreadValue = value || currentValue
139
+ const isSelfControlledComp = typeof value === 'undefined'
101
140
 
102
- const delayedOnChange = useMemo(
103
- () => debounce(event => onChange(event), 375),
104
- [onChange]
105
- )
141
+ const delayedOnChange = useMemo(() => debounce(onChange, 375), [onChange])
106
142
 
107
143
  const handleChange = ev => {
108
- const value = ev.target.value
144
+ if (!isSelfControlledComp) return onChange(ev)
109
145
 
110
- if (value.length >= 1) {
146
+ const _value = ev.target.value
147
+
148
+ if (_value.length >= 1) {
111
149
  delayedOnChange(ev)
112
- setCurrentValue(value)
150
+ setCurrentValue(_value)
113
151
  } else {
114
152
  handleClear(ev)
115
153
  }
@@ -143,18 +181,32 @@ const SearchBar = forwardRef(
143
181
  ref={ref}
144
182
  {...props}
145
183
  >
146
- <Icon className={classes.icon} icon={MagnifierIcon} />
147
- <InputBase
148
- className={classes.inputBase}
149
- placeholder={disabled ? null : placeholder}
150
- value={disabled ? placeholder : currentValue}
151
- disabled={disabled}
152
- aria-label={placeholder}
153
- onChange={handleChange}
154
- onFocus={handleFocus}
155
- onBlur={handleBlur}
156
- />
157
- {currentValue && (
184
+ {type === 'button' ? (
185
+ <ButtonBase className={classes.buttonBase}>
186
+ {icon && <Icon className={classes.icon} icon={icon} />}
187
+ {typeof label === 'string' ? (
188
+ <Typography className={classes.typography}>{label}</Typography>
189
+ ) : (
190
+ label
191
+ )}
192
+ </ButtonBase>
193
+ ) : (
194
+ <>
195
+ {icon && <Icon className={classes.icon} icon={icon} />}
196
+ <InputBase
197
+ {...componentsProps?.inputBase}
198
+ className={classes.inputBase}
199
+ placeholder={disabled ? null : placeholder}
200
+ value={disabled ? placeholder : spreadValue}
201
+ disabled={disabled}
202
+ aria-label={placeholder}
203
+ onChange={handleChange}
204
+ onFocus={handleFocus}
205
+ onBlur={handleBlur}
206
+ />
207
+ </>
208
+ )}
209
+ {spreadValue && !disabledClear && (
158
210
  <IconButton size="medium" onClick={handleClear}>
159
211
  <Icon icon={CrossCircleIcon} />
160
212
  </IconButton>
@@ -174,6 +226,10 @@ SearchBar.displayName = 'SearchBar'
174
226
 
175
227
  SearchBar.defaultProps = {
176
228
  elevation: true,
229
+ icon: MagnifierIcon,
230
+ size: 'small',
231
+ type: 'search',
232
+ disabledClear: false,
177
233
  defaultValue: '',
178
234
  onChange: () => {},
179
235
  onFocus: () => {},
@@ -182,13 +238,35 @@ SearchBar.defaultProps = {
182
238
 
183
239
  SearchBar.propTypes = {
184
240
  className: PropTypes.string,
241
+ type: PropTypes.oneOf(['button', 'search']),
242
+ icon: iconPropType,
243
+ size: PropTypes.oneOf(['small', 'medium', 'large', 'auto']),
244
+ componentsProps: PropTypes.shape({
245
+ /** Props spread to InputBase component */
246
+ inputBase: PropTypes.object
247
+ }),
248
+ /** Used to control the component outside of it */
249
+ value: PropTypes.string,
250
+ /** Used only with self-controlled component */
185
251
  defaultValue: PropTypes.string,
252
+ disabledClear: PropTypes.bool,
186
253
  elevation: PropTypes.bool,
187
254
  placeholder: PropTypes.string,
255
+ label: PropTypes.oneOfType([
256
+ PropTypes.string,
257
+ PropTypes.func,
258
+ PropTypes.object
259
+ ]),
188
260
  disabled: PropTypes.bool,
189
261
  onChange: PropTypes.func,
190
262
  onFocus: PropTypes.func,
191
263
  onBlur: PropTypes.func
192
264
  }
193
265
 
194
- export default withOnlyLocales(SearchBar)
266
+ const SearchBarWithLocales = props => {
267
+ useExtendI18n(locales)
268
+
269
+ return <SearchBar {...props} />
270
+ }
271
+
272
+ export default SearchBarWithLocales
@@ -1,5 +1,5 @@
1
1
  {
2
- "search": {
2
+ "SearchBar": {
3
3
  "placeholder": "Search"
4
4
  }
5
5
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "search": {
2
+ "SearchBar": {
3
3
  "placeholder": "Rechercher"
4
4
  }
5
5
  }
@@ -4,7 +4,7 @@ import { CozyProvider } from 'cozy-client'
4
4
 
5
5
  import { BreakpointsProvider } from './Breakpoints'
6
6
  import CozyTheme from './CozyTheme'
7
- import { I18nContext } from '../providers/I18n'
7
+ import I18n from '../providers/I18n'
8
8
 
9
9
  const defaultClient = {
10
10
  plugins: {
@@ -28,15 +28,9 @@ const DemoProvider = ({ client, variant, children }) => {
28
28
  return (
29
29
  <CozyProvider client={client || defaultClient}>
30
30
  <BreakpointsProvider>
31
- <I18nContext.Provider
32
- value={{
33
- t: x => x,
34
- f: () => '01 Jan. 2022',
35
- lang
36
- }}
37
- >
31
+ <I18n lang={lang} dictRequire={() => ({})}>
38
32
  <CozyTheme variant={variant}>{children}</CozyTheme>
39
- </I18nContext.Provider>
33
+ </I18n>
40
34
  </BreakpointsProvider>
41
35
  </CozyProvider>
42
36
  )
@@ -126,6 +126,7 @@ export var defaultBottomSheetSpringConfig = {
126
126
  var defaultSettings = {
127
127
  mediumHeightRatio: 0.75,
128
128
  mediumHeight: null,
129
+ hasMinHeightOffset: false,
129
130
  isOpenMin: false
130
131
  };
131
132
  var BottomSheet = /*#__PURE__*/memo(function (_ref3) {
@@ -140,7 +141,8 @@ var BottomSheet = /*#__PURE__*/memo(function (_ref3) {
140
141
  var _defaultSettings$sett = _objectSpread(_objectSpread({}, defaultSettings), settings),
141
142
  mediumHeightRatio = _defaultSettings$sett.mediumHeightRatio,
142
143
  mediumHeight = _defaultSettings$sett.mediumHeight,
143
- isOpenMin = _defaultSettings$sett.isOpenMin;
144
+ isOpenMin = _defaultSettings$sett.isOpenMin,
145
+ hasMinHeightOffset = _defaultSettings$sett.hasMinHeightOffset;
144
146
 
145
147
  var innerContentRef = useRef();
146
148
  var headerRef = useRef();
@@ -269,6 +271,7 @@ var BottomSheet = /*#__PURE__*/memo(function (_ref3) {
269
271
  isClosable: isClosable,
270
272
  isOpenMin: isOpenMin,
271
273
  headerRef: headerRef,
274
+ offset: hasMinHeightOffset ? offset : 0,
272
275
  actionButtonsHeight: actionButtonsHeight,
273
276
  actionButtonsBottomMargin: actionButtonsBottomMargin
274
277
  });
@@ -409,6 +412,9 @@ BottomSheet.propTypes = {
409
412
  /** Height of the middle snap point, expressed as a percentage of the viewport height */
410
413
  mediumHeightRatio: PropTypes.number,
411
414
 
415
+ /** To include the offset in the min height value */
416
+ hasMinHeightOffset: PropTypes.bool,
417
+
412
418
  /** To open the BottomSheet at the minimum height, if have an header */
413
419
  isOpenMin: PropTypes.bool
414
420
  }),
@@ -45,10 +45,12 @@ export var computeMinHeight = function computeMinHeight(_ref2) {
45
45
  var isClosable = _ref2.isClosable,
46
46
  isOpenMin = _ref2.isOpenMin,
47
47
  headerRef = _ref2.headerRef,
48
+ _ref2$offset = _ref2.offset,
49
+ offset = _ref2$offset === void 0 ? 0 : _ref2$offset,
48
50
  actionButtonsHeight = _ref2.actionButtonsHeight,
49
51
  actionButtonsBottomMargin = _ref2.actionButtonsBottomMargin;
50
52
  if (isClosable && !isOpenMin) return 0;
51
- return headerRef.current.offsetHeight + actionButtonsHeight + actionButtonsBottomMargin + (getFlagshipMetadata().navbarHeight || 0) + getSafeAreaValue('bottom');
53
+ return headerRef.current.offsetHeight + offset + actionButtonsHeight + actionButtonsBottomMargin + (getFlagshipMetadata().navbarHeight || 0) + getSafeAreaValue('bottom');
52
54
  };
53
55
  export var makeOverridenChildren = function makeOverridenChildren(children, headerContentRef) {
54
56
  return React.Children.map(children, function (child) {
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  export default {
3
- size: PropTypes.oneOf(['small', 'medium', 'large']),
3
+ size: PropTypes.oneOf(['small', 'medium', 'large', 'full']),
4
4
  open: PropTypes.bool.isRequired,
5
5
  disableTitleAutoPadding: PropTypes.bool,
6
6
  background: PropTypes.string,