webcoreui 0.8.0 → 0.9.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 (79) hide show
  1. package/README.md +16 -0
  2. package/astro.d.ts +23 -0
  3. package/astro.js +8 -0
  4. package/components/Accordion/accordion.module.scss +1 -0
  5. package/components/Badge/Badge.svelte +1 -1
  6. package/components/Badge/badge.ts +1 -1
  7. package/components/BottomNavigation/BottomNavigation.astro +51 -0
  8. package/components/BottomNavigation/BottomNavigation.svelte +45 -0
  9. package/components/BottomNavigation/BottomNavigation.tsx +63 -0
  10. package/components/BottomNavigation/bottomnavigation.module.scss +70 -0
  11. package/components/BottomNavigation/bottomnavigation.ts +16 -0
  12. package/components/Card/card.module.scss +1 -0
  13. package/components/Checkbox/Checkbox.astro +8 -2
  14. package/components/Checkbox/Checkbox.svelte +1 -0
  15. package/components/Checkbox/Checkbox.tsx +3 -1
  16. package/components/Checkbox/checkbox.ts +1 -0
  17. package/components/Copy/Copy.astro +74 -0
  18. package/components/Copy/Copy.svelte +61 -0
  19. package/components/Copy/Copy.tsx +73 -0
  20. package/components/Copy/copy.module.scss +37 -0
  21. package/components/Copy/copy.ts +14 -0
  22. package/components/DataTable/DataTable.astro +1 -1
  23. package/components/Flex/Flex.astro +34 -0
  24. package/components/Flex/Flex.svelte +27 -0
  25. package/components/Flex/Flex.tsx +30 -0
  26. package/components/Flex/flex.ts +22 -0
  27. package/components/Grid/Grid.astro +32 -0
  28. package/components/Grid/Grid.svelte +25 -0
  29. package/components/Grid/Grid.tsx +28 -0
  30. package/components/Grid/grid.ts +18 -0
  31. package/components/Icon/icon.ts +1 -0
  32. package/components/Icon/map.ts +2 -0
  33. package/components/Input/Input.astro +1 -1
  34. package/components/Input/Input.svelte +4 -2
  35. package/components/Input/Input.tsx +4 -1
  36. package/components/List/list.module.scss +3 -0
  37. package/components/Menu/Menu.svelte +5 -1
  38. package/components/Pagination/Pagination.svelte +1 -0
  39. package/components/Radio/Radio.astro +3 -1
  40. package/components/Radio/Radio.svelte +3 -2
  41. package/components/Radio/Radio.tsx +5 -3
  42. package/components/Radio/radio.ts +1 -0
  43. package/components/Select/Select.astro +34 -1
  44. package/components/Select/Select.svelte +40 -4
  45. package/components/Select/Select.tsx +33 -1
  46. package/components/Select/select.ts +4 -1
  47. package/components/Skeleton/Skeleton.astro +2 -2
  48. package/components/Skeleton/Skeleton.svelte +2 -2
  49. package/components/Skeleton/Skeleton.tsx +2 -2
  50. package/components/Switch/Switch.astro +3 -2
  51. package/components/Switch/Switch.svelte +1 -0
  52. package/components/Switch/Switch.tsx +3 -1
  53. package/components/Switch/switch.ts +1 -0
  54. package/components/Textarea/Textarea.astro +3 -1
  55. package/components/Textarea/Textarea.svelte +48 -47
  56. package/components/Textarea/textarea.ts +19 -18
  57. package/icons/copy.svg +3 -0
  58. package/icons.d.ts +1 -0
  59. package/icons.js +1 -0
  60. package/index.d.ts +74 -2
  61. package/index.js +1 -0
  62. package/package.json +24 -15
  63. package/react.d.ts +23 -0
  64. package/react.js +8 -0
  65. package/scss/config/color-palette.scss +1 -1
  66. package/scss/config/css-values.scss +1 -1
  67. package/scss/config/layout.scss +1 -1
  68. package/scss/config/mixins.scss +1 -1
  69. package/scss/config/typography.scss +1 -1
  70. package/scss/config/variables.scss +1 -1
  71. package/scss/config.scss +1 -1
  72. package/scss/global/utility.scss +48 -3
  73. package/svelte.d.ts +23 -0
  74. package/svelte.js +8 -0
  75. package/utils/DOMUtils.ts +2 -2
  76. package/utils/classNames.ts +1 -1
  77. package/utils/getLayoutClasses.ts +141 -0
  78. package/utils/modal.ts +4 -4
  79. package/utils/popover.ts +30 -4
@@ -0,0 +1,73 @@
1
+ import React, { useRef, useState } from 'react'
2
+ import type { ReactCopyProps } from './copy'
3
+
4
+ import Badge from '../Badge/Badge.tsx'
5
+
6
+ import { classNames } from '../../utils/classNames'
7
+
8
+ import circleCheck from '../../icons/circle-check.svg?raw'
9
+ import copy from '../../icons/copy.svg?raw'
10
+
11
+ import styles from './copy.module.scss'
12
+
13
+ const Copy = ({
14
+ tooltip,
15
+ tooltipPosition,
16
+ copyIcon,
17
+ copiedIcon,
18
+ className,
19
+ children,
20
+ ...rest
21
+ }: ReactCopyProps) => {
22
+ const copyButton = useRef<HTMLButtonElement>(null)
23
+ const copiedButton = useRef<HTMLSpanElement>(null)
24
+ const [tooltipText, setTooltipText] = useState(tooltip)
25
+
26
+ const classes = classNames([
27
+ styles.copy,
28
+ className
29
+ ])
30
+
31
+ const copyText = () => {
32
+ const copyButtonElement = copyButton.current as HTMLButtonElement
33
+ const copiedButtonElement = copiedButton.current as HTMLSpanElement
34
+
35
+ const text = copyButtonElement.parentElement?.previousSibling?.textContent?.trim()
36
+ || copyButtonElement.parentElement?.previousElementSibling?.textContent?.trim()
37
+
38
+ copyButtonElement.style.opacity = '0'
39
+ copyButtonElement.style.pointerEvents = 'none'
40
+
41
+ copiedButtonElement.style.opacity = '1'
42
+
43
+ setTooltipText('')
44
+
45
+ navigator.clipboard.writeText(text as string)
46
+ }
47
+
48
+ return (
49
+ <Badge
50
+ {...rest}
51
+ className={classes}
52
+ data-tooltip={tooltipText || undefined}
53
+ data-position={tooltipPosition}
54
+ >
55
+ {children}
56
+ <div className={styles.icons}>
57
+ <button
58
+ className={styles['copy-icon']}
59
+ ref={copyButton}
60
+ onClick={copyText}
61
+ dangerouslySetInnerHTML={{ __html: copyIcon || copy }}
62
+ />
63
+ <span
64
+ className={styles.copied}
65
+ ref={copiedButton}
66
+ dangerouslySetInnerHTML={{ __html: copiedIcon || circleCheck }}
67
+ />
68
+ </div>
69
+ </Badge>
70
+ )
71
+ }
72
+
73
+ export default Copy
@@ -0,0 +1,37 @@
1
+ @use '../../scss/config.scss' as *;
2
+
3
+ .copy {
4
+ @include typography(md);
5
+
6
+ svg {
7
+ @include size(18px);
8
+
9
+ cursor: pointer;
10
+ }
11
+
12
+ .icons {
13
+ @include position(relative);
14
+ @include size(18px);
15
+ }
16
+
17
+ .copy-icon,
18
+ .copied {
19
+ @include position(absolute, t0, l0);
20
+ @include transition(opacity);
21
+ }
22
+
23
+ .copy-icon {
24
+ @include background(transparent);
25
+ @include border(0);
26
+ @include spacing(p0);
27
+
28
+ color: inherit;
29
+ }
30
+
31
+ .copied {
32
+ @include visibility(0);
33
+
34
+ pointer-events: none;
35
+ cursor: auto;
36
+ }
37
+ }
@@ -0,0 +1,14 @@
1
+ import { type BadgeProps } from '../Badge/badge'
2
+ import { type IconProps } from '../Icon/icon'
3
+
4
+ export type CopyProps = {
5
+ tooltip?: string
6
+ tooltipPosition?: 'left' | 'right' | 'bottom' | null
7
+ copyIcon?: IconProps['type'] | string
8
+ copiedIcon?: IconProps['type'] | string
9
+ className?: string
10
+ } & BadgeProps
11
+
12
+ export type ReactCopyProps = {
13
+ children: React.ReactNode
14
+ } & CopyProps
@@ -135,7 +135,7 @@ const hasPagination = data?.length && itemsPerPage
135
135
  {data?.map((row, index) => (
136
136
  <tr
137
137
  data-page={hasPagination ? Math.ceil((index + 1) / itemsPerPage!) : undefined}
138
- data-hidden={hasPagination && index >= itemsPerPage!}
138
+ data-hidden={(hasPagination && index >= itemsPerPage!) ? true : undefined}
139
139
  >
140
140
  {row.map((column, index) => (
141
141
  <td data-name={getColumnName(headings?.[index])}>
@@ -0,0 +1,34 @@
1
+ ---
2
+ import type { FlexProps } from './flex'
3
+
4
+ import { classNames } from '../../utils/classNames'
5
+ import { getLayoutClasses } from '../../utils/getLayoutClasses'
6
+
7
+ interface Props extends FlexProps {}
8
+
9
+ const {
10
+ element = 'div',
11
+ gap,
12
+ alignment,
13
+ direction,
14
+ wrap,
15
+ className,
16
+ ...rest
17
+ } = Astro.props
18
+
19
+ const Component = element
20
+
21
+ const classes = classNames([
22
+ 'flex',
23
+ getLayoutClasses({ gap, alignment, direction, wrap }),
24
+ className
25
+ ])
26
+
27
+ const props = {
28
+ class: classes
29
+ }
30
+ ---
31
+
32
+ <Component {...props} {...rest}>
33
+ <slot />
34
+ </Component>
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ import type { FlexProps } from './flex'
3
+
4
+ import { classNames } from '../../utils/classNames'
5
+ import { getLayoutClasses } from '../../utils/getLayoutClasses'
6
+
7
+ export let element: FlexProps['className'] = 'div'
8
+ export let gap: FlexProps['gap'] = ''
9
+ export let alignment: FlexProps['alignment'] = {}
10
+ export let direction: FlexProps['direction'] = ''
11
+ export let wrap: FlexProps['wrap'] = ''
12
+ export let className: FlexProps['className'] = ''
13
+
14
+ const classes = classNames([
15
+ 'flex',
16
+ getLayoutClasses({ gap, alignment, direction, wrap }),
17
+ className
18
+ ])
19
+
20
+ const props = {
21
+ class: classes
22
+ }
23
+ </script>
24
+
25
+ <svelte:element this={element} {...props} {...$$restProps}>
26
+ <slot />
27
+ </svelte:element>
@@ -0,0 +1,30 @@
1
+ import React from 'react'
2
+ import type { ReactFlexProps } from './flex'
3
+
4
+ import { classNames } from '../../utils/classNames'
5
+ import { getLayoutClasses } from '../../utils/getLayoutClasses'
6
+
7
+ const Flex = ({
8
+ Element = 'div',
9
+ gap,
10
+ alignment,
11
+ direction,
12
+ wrap,
13
+ className,
14
+ children,
15
+ ...rest
16
+ }: ReactFlexProps) => {
17
+ const classes = classNames([
18
+ 'flex',
19
+ getLayoutClasses({ gap, alignment, direction, wrap }),
20
+ className
21
+ ])
22
+
23
+ return (
24
+ <Element className={classes} {...rest}>
25
+ {children}
26
+ </Element>
27
+ )
28
+ }
29
+
30
+ export default Flex
@@ -0,0 +1,22 @@
1
+ import type {
2
+ Alignment,
3
+ Direction,
4
+ Gap,
5
+ Responsive,
6
+ Wrap
7
+ } from '../../utils/getLayoutClasses'
8
+
9
+ export type FlexProps = {
10
+ element?: string
11
+ gap?: Responsive<Gap>
12
+ alignment?: Responsive<Alignment>
13
+ direction?: Responsive<Direction>
14
+ wrap?: Responsive<Wrap>
15
+ className?: string
16
+ [key: string]: any
17
+ }
18
+
19
+ export type ReactFlexProps = {
20
+ Element?: keyof JSX.IntrinsicElements
21
+ children: React.ReactNode
22
+ } & Omit<FlexProps, 'element'>
@@ -0,0 +1,32 @@
1
+ ---
2
+ import type { GridProps } from './grid'
3
+
4
+ import { classNames } from '../../utils/classNames'
5
+ import { getLayoutClasses } from '../../utils/getLayoutClasses'
6
+
7
+ interface Props extends GridProps {}
8
+
9
+ const {
10
+ element = 'div',
11
+ gap,
12
+ column,
13
+ className,
14
+ ...rest
15
+ } = Astro.props
16
+
17
+ const Component = element
18
+
19
+ const classes = classNames([
20
+ 'grid',
21
+ getLayoutClasses({ gap, column }),
22
+ className
23
+ ])
24
+
25
+ const props = {
26
+ class: classes
27
+ }
28
+ ---
29
+
30
+ <Component {...props} {...rest}>
31
+ <slot />
32
+ </Component>
@@ -0,0 +1,25 @@
1
+ <script lang="ts">
2
+ import type { GridProps } from './grid'
3
+
4
+ import { classNames } from '../../utils/classNames'
5
+ import { getLayoutClasses } from '../../utils/getLayoutClasses'
6
+
7
+ export let element: GridProps['className'] = 'div'
8
+ export let gap: GridProps['gap'] = ''
9
+ export let column: GridProps['column'] = null
10
+ export let className: GridProps['className'] = ''
11
+
12
+ const classes = classNames([
13
+ 'grid',
14
+ getLayoutClasses({ gap, column }),
15
+ className
16
+ ])
17
+
18
+ const props = {
19
+ class: classes
20
+ }
21
+ </script>
22
+
23
+ <svelte:element this={element} {...props} {...$$restProps}>
24
+ <slot />
25
+ </svelte:element>
@@ -0,0 +1,28 @@
1
+ import React from 'react'
2
+ import type { ReactGridProps } from './grid'
3
+
4
+ import { classNames } from '../../utils/classNames'
5
+ import { getLayoutClasses } from '../../utils/getLayoutClasses'
6
+
7
+ const Grid = ({
8
+ Element = 'div',
9
+ gap,
10
+ column,
11
+ className,
12
+ children,
13
+ ...rest
14
+ }: ReactGridProps) => {
15
+ const classes = classNames([
16
+ 'grid',
17
+ getLayoutClasses({ gap, column }),
18
+ className
19
+ ])
20
+
21
+ return (
22
+ <Element className={classes} {...rest}>
23
+ {children}
24
+ </Element>
25
+ )
26
+ }
27
+
28
+ export default Grid
@@ -0,0 +1,18 @@
1
+ import type {
2
+ Column,
3
+ Gap,
4
+ Responsive
5
+ } from '../../utils/getLayoutClasses'
6
+
7
+ export type GridProps = {
8
+ element?: string
9
+ gap?: Responsive<Gap>
10
+ column?: Responsive<Column>
11
+ className?: string
12
+ [key: string]: any
13
+ }
14
+
15
+ export type ReactGridProps = {
16
+ Element?: keyof JSX.IntrinsicElements
17
+ children: React.ReactNode
18
+ } & Omit<GridProps, 'element'>
@@ -8,6 +8,7 @@ export type IconProps = {
8
8
  | 'circle-close'
9
9
  | 'close'
10
10
  | 'components'
11
+ | 'copy'
11
12
  | 'file'
12
13
  | 'github'
13
14
  | 'home'
@@ -7,6 +7,7 @@ import CircleCheck from '../../icons/circle-check.svg?raw'
7
7
  import CircleClose from '../../icons/circle-close.svg?raw'
8
8
  import Close from '../../icons/close.svg?raw'
9
9
  import Components from '../../icons/components.svg?raw'
10
+ import Copy from '../../icons/copy.svg?raw'
10
11
  import File from '../../icons/file.svg?raw'
11
12
  import Github from '../../icons/github.svg?raw'
12
13
  import Home from '../../icons/home.svg?raw'
@@ -28,6 +29,7 @@ const iconMap = {
28
29
  'circle-close': CircleClose,
29
30
  'close': Close,
30
31
  'components': Components,
32
+ 'copy': Copy,
31
33
  'file': File,
32
34
  'github': Github,
33
35
  'home': Home,
@@ -34,7 +34,7 @@ const useLabel = !!(label || subText || Astro.slots.has('default'))
34
34
  <ConditionalWrapper condition={useLabel}>
35
35
  <label slot="wrapper" class:list={labelClasses}>
36
36
  {label && (
37
- <div class={styles.label}>{label}</div>
37
+ <div class={styles.label} set:html={label} />
38
38
  )}
39
39
  <ConditionalWrapper condition={Astro.slots.has('default')}>
40
40
  <div class={styles.wrapper} slot="wrapper">
@@ -10,6 +10,7 @@
10
10
  export let type: SvelteInputProps['type'] = 'text'
11
11
  export let theme: SvelteInputProps['theme'] = null
12
12
  export let label: SvelteInputProps['label'] = ''
13
+ export let value: SvelteInputProps['value'] = ''
13
14
  export let subText: SvelteInputProps['subText'] = ''
14
15
  export let className: SvelteInputProps['className'] = ''
15
16
  export let labelClassName: SvelteInputProps['labelClassName'] = ''
@@ -38,7 +39,7 @@
38
39
  class={labelClasses}
39
40
  >
40
41
  {#if label}
41
- <div class={styles.label}>{label}</div>
42
+ <div class={styles.label}>{@html label}</div>
42
43
  {/if}
43
44
  <ConditionalWrapper
44
45
  condition={$$slots.default}
@@ -47,12 +48,13 @@
47
48
  >
48
49
  <slot />
49
50
  <input
50
- type={type}
51
51
  class={classes}
52
+ bind:value
52
53
  on:change={onChange}
53
54
  on:keyup={onKeyUp}
54
55
  on:input={onInput}
55
56
  on:click={onClick}
57
+ {...{ type }}
56
58
  {...$$restProps}
57
59
  />
58
60
  </ConditionalWrapper>
@@ -38,7 +38,10 @@ const Input = ({
38
38
  </label>
39
39
  )}>
40
40
  {label && (
41
- <div className={styles.label}>{label}</div>
41
+ <div
42
+ className={styles.label}
43
+ dangerouslySetInnerHTML={{ __html: label }}
44
+ />
42
45
  )}
43
46
  <ConditionalWrapper condition={!!children} wrapper={children => (
44
47
  <div className={styles.wrapper}>
@@ -50,6 +50,7 @@
50
50
  @include spacing(m0);
51
51
 
52
52
  padding-bottom: 0;
53
+ user-select: none;
53
54
 
54
55
  &:not(:first-child) {
55
56
  @include border(top, primary-50);
@@ -74,7 +75,9 @@
74
75
 
75
76
  span {
76
77
  @include typography(md, primary-20);
78
+
77
79
  pointer-events: none;
80
+ user-select: none;
78
81
  }
79
82
  }
80
83
  }
@@ -68,7 +68,11 @@
68
68
  </ConditionalWrapper>
69
69
 
70
70
  {#if items?.length}
71
- <button class={styles.hamburger} on:click={toggleMenu}>
71
+ <button
72
+ class={styles.hamburger}
73
+ on:click={toggleMenu}
74
+ aria-label="menu"
75
+ >
72
76
  <span class={styles.meat}></span>
73
77
  <span class={styles.meat}></span>
74
78
  <span class={styles.meat}></span>
@@ -74,6 +74,7 @@
74
74
  {#each generatedPages as _, index}
75
75
  <li>
76
76
  <button
77
+ aria-label={`page ${index + 1}`}
77
78
  data-active={calculatedCurrentPage === index + 1 ? 'true' : null}
78
79
  on:click={calculatedCurrentPage !== index + 1
79
80
  ? () => paginate(index + 1)
@@ -12,7 +12,8 @@ const {
12
12
  items,
13
13
  color,
14
14
  inline,
15
- className
15
+ className,
16
+ ...rest
16
17
  } = Astro.props
17
18
 
18
19
  const classes = [
@@ -42,6 +43,7 @@ const style = color
42
43
  value={item.value}
43
44
  checked={item.selected}
44
45
  disabled={item.disabled}
46
+ {...rest}
45
47
  />
46
48
  <span class={styles.icon} />
47
49
  <span class={styles.label}>
@@ -27,10 +27,10 @@
27
27
 
28
28
  <div class={classes} style={style}>
29
29
  {#each items as item}
30
- <label class={[
30
+ <label class={classNames([
31
31
  item.subText && styles.col,
32
32
  item.disabled && styles.disabled
33
- ].filter(Boolean).join(' ')}
33
+ ])}
34
34
  >
35
35
  <ConditionalWrapper
36
36
  condition={!!(item.subText)}
@@ -44,6 +44,7 @@
44
44
  checked={item.selected}
45
45
  disabled={item.disabled}
46
46
  on:change={onChange}
47
+ {...$$restProps}
47
48
  />
48
49
  <span class={styles.icon} />
49
50
  <span class={styles.label}>
@@ -13,7 +13,8 @@ const Radio = ({
13
13
  color,
14
14
  inline,
15
15
  className,
16
- onChange
16
+ onChange,
17
+ ...rest
17
18
  }: ReactRadioProps) => {
18
19
  const classes = classNames([
19
20
  styles.radio,
@@ -28,10 +29,10 @@ const Radio = ({
28
29
  return (
29
30
  <div className={classes} style={style}>
30
31
  {items.map((item, index) => (
31
- <label className={[
32
+ <label className={classNames([
32
33
  item.subText && styles.col,
33
34
  item.disabled && styles.disabled
34
- ].filter(Boolean).join(' ')} key={index}>
35
+ ])} key={index}>
35
36
  <ConditionalWrapper
36
37
  condition={!!(item.subText)}
37
38
  wrapper={children => (
@@ -47,6 +48,7 @@ const Radio = ({
47
48
  defaultChecked={item.selected}
48
49
  disabled={item.disabled}
49
50
  onChange={onChange}
51
+ {...rest}
50
52
  />
51
53
  <span className={styles.icon} />
52
54
  <span
@@ -10,6 +10,7 @@ export type RadioProps = {
10
10
  color?: string
11
11
  inline?: boolean
12
12
  className?: string
13
+ [key: string]: any
13
14
  }
14
15
 
15
16
  export type SvelteRadioProps = {
@@ -32,11 +32,19 @@ const classes = classNames([
32
32
  disabled && styles.disabled,
33
33
  className
34
34
  ])
35
+
36
+ const inferredValue = rest.itemGroups.map(group => group.items)
37
+ .flat()
38
+ .find(item => item.value === value)?.name
39
+
40
+ const inputRestProps = Object.fromEntries(
41
+ Object.entries(rest).filter(([key]) => key.includes('data'))
42
+ )
35
43
  ---
36
44
 
37
45
  <Input
38
46
  type="text"
39
- value={value}
47
+ value={(value && inferredValue) ? inferredValue : value}
40
48
  readonly={true}
41
49
  disabled={disabled}
42
50
  placeholder={placeholder}
@@ -46,6 +54,7 @@ const classes = classNames([
46
54
  data-no-update={!updateValue ? 'true' : undefined}
47
55
  data-position={position}
48
56
  labelClassName={classes}
57
+ {...inputRestProps}
49
58
  >
50
59
  <Fragment set:html={ArrowDown} />
51
60
  </Input>
@@ -67,11 +76,21 @@ const classes = classNames([
67
76
 
68
77
  <script>
69
78
  import { debounce } from '../../utils/debounce'
79
+ import { on } from '../../utils/DOMUtils'
70
80
  import { dispatch, listen } from '../../utils/event'
71
81
  import { modal } from '../../utils/modal'
72
82
  import { closePopover, popover, type PopoverPosition } from '../../utils/popover'
73
83
 
74
84
  const selects = document.querySelectorAll('[data-id^="w-select"]')
85
+ let focusByTab = false
86
+
87
+ on(document, 'keydown', (event: KeyboardEvent) => {
88
+ if (event.key === 'Tab') {
89
+ focusByTab = true
90
+ }
91
+ })
92
+
93
+ on(document, 'mousedown', () => focusByTab = false)
75
94
 
76
95
  Array.from(selects).forEach(select => {
77
96
  const selectElement = select as HTMLElement
@@ -88,6 +107,9 @@ const classes = classNames([
88
107
  if (search) {
89
108
  search.focus()
90
109
  }
110
+ },
111
+ onClose(event) {
112
+ dispatch('selectOnClose', event)
91
113
  }
92
114
  })
93
115
  } else {
@@ -111,10 +133,21 @@ const classes = classNames([
111
133
 
112
134
  if (search) {
113
135
  search.focus()
136
+ } else {
137
+ popover.focus()
114
138
  }
139
+ },
140
+ onClose(event) {
141
+ dispatch('selectOnClose', event)
115
142
  }
116
143
  })
117
144
  }
145
+
146
+ on(selectElement, 'focus', (event: Event) => {
147
+ if (focusByTab) {
148
+ (event.currentTarget as HTMLInputElement).click()
149
+ }
150
+ })
118
151
  })
119
152
 
120
153
  listen('listOnSelect', payload => {