@furystack/shades-common-components 3.6.1 → 4.0.1

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 (149) hide show
  1. package/dist/components/app-bar-link.js +18 -20
  2. package/dist/components/app-bar-link.js.map +1 -1
  3. package/dist/components/app-bar.js +7 -6
  4. package/dist/components/app-bar.js.map +1 -1
  5. package/dist/components/avatar.js +20 -18
  6. package/dist/components/avatar.js.map +1 -1
  7. package/dist/components/button.js +32 -28
  8. package/dist/components/button.js.map +1 -1
  9. package/dist/components/command-palette/command-palette-input.js +24 -29
  10. package/dist/components/command-palette/command-palette-input.js.map +1 -1
  11. package/dist/components/command-palette/command-palette-suggestion-list.js +38 -47
  12. package/dist/components/command-palette/command-palette-suggestion-list.js.map +1 -1
  13. package/dist/components/command-palette/index.js +34 -40
  14. package/dist/components/command-palette/index.js.map +1 -1
  15. package/dist/components/data-grid/body.js +6 -13
  16. package/dist/components/data-grid/body.js.map +1 -1
  17. package/dist/components/data-grid/data-grid-row.js +29 -31
  18. package/dist/components/data-grid/data-grid-row.js.map +1 -1
  19. package/dist/components/data-grid/data-grid.js +4 -8
  20. package/dist/components/data-grid/data-grid.js.map +1 -1
  21. package/dist/components/data-grid/footer.js +8 -13
  22. package/dist/components/data-grid/footer.js.map +1 -1
  23. package/dist/components/data-grid/header.js +19 -18
  24. package/dist/components/data-grid/header.js.map +1 -1
  25. package/dist/components/data-grid/selection-cell.js +9 -23
  26. package/dist/components/data-grid/selection-cell.js.map +1 -1
  27. package/dist/components/fab.js +10 -5
  28. package/dist/components/fab.js.map +1 -1
  29. package/dist/components/grid.js.map +1 -1
  30. package/dist/components/inputs/autocomplete.js +3 -13
  31. package/dist/components/inputs/autocomplete.js.map +1 -1
  32. package/dist/components/inputs/input.js +22 -26
  33. package/dist/components/inputs/input.js.map +1 -1
  34. package/dist/components/inputs/text-area.js +2 -6
  35. package/dist/components/inputs/text-area.js.map +1 -1
  36. package/dist/components/loader.js +9 -5
  37. package/dist/components/loader.js.map +1 -1
  38. package/dist/components/modal.js +7 -17
  39. package/dist/components/modal.js.map +1 -1
  40. package/dist/components/noty-list.js +26 -28
  41. package/dist/components/noty-list.js.map +1 -1
  42. package/dist/components/paper.js +11 -5
  43. package/dist/components/paper.js.map +1 -1
  44. package/dist/components/suggest/index.js +14 -20
  45. package/dist/components/suggest/index.js.map +1 -1
  46. package/dist/components/suggest/suggest-input.js +9 -10
  47. package/dist/components/suggest/suggest-input.js.map +1 -1
  48. package/dist/components/suggest/suggest-manager.js +8 -2
  49. package/dist/components/suggest/suggest-manager.js.map +1 -1
  50. package/dist/components/suggest/suggestion-list.js +27 -30
  51. package/dist/components/suggest/suggestion-list.js.map +1 -1
  52. package/dist/components/tabs.js +32 -36
  53. package/dist/components/tabs.js.map +1 -1
  54. package/dist/components/wizard/index.js +4 -7
  55. package/dist/components/wizard/index.js.map +1 -1
  56. package/dist/services/collection-service.js +68 -56
  57. package/dist/services/collection-service.js.map +1 -1
  58. package/package.json +6 -6
  59. package/src/components/app-bar-link.tsx +27 -30
  60. package/src/components/app-bar.tsx +21 -26
  61. package/src/components/avatar.tsx +40 -36
  62. package/src/components/button.tsx +85 -88
  63. package/src/components/command-palette/command-palette-input.tsx +15 -13
  64. package/src/components/command-palette/command-palette-suggestion-list.tsx +50 -58
  65. package/src/components/command-palette/index.tsx +54 -52
  66. package/src/components/data-grid/body.tsx +10 -22
  67. package/src/components/data-grid/data-grid-row.tsx +64 -63
  68. package/src/components/data-grid/data-grid.tsx +11 -11
  69. package/src/components/data-grid/footer.tsx +13 -16
  70. package/src/components/data-grid/header.tsx +34 -30
  71. package/src/components/data-grid/selection-cell.tsx +9 -19
  72. package/src/components/fab.tsx +21 -23
  73. package/src/components/grid.tsx +1 -1
  74. package/src/components/inputs/autocomplete.tsx +10 -16
  75. package/src/components/inputs/input.tsx +27 -27
  76. package/src/components/inputs/text-area.tsx +3 -11
  77. package/src/components/loader.tsx +20 -5
  78. package/src/components/modal.tsx +9 -17
  79. package/src/components/noty-list.tsx +54 -53
  80. package/src/components/paper.tsx +18 -17
  81. package/src/components/suggest/index.tsx +19 -30
  82. package/src/components/suggest/suggest-input.tsx +22 -15
  83. package/src/components/suggest/suggest-manager.ts +15 -3
  84. package/src/components/suggest/suggestion-list.tsx +90 -85
  85. package/src/components/tabs.tsx +50 -62
  86. package/src/components/wizard/index.tsx +6 -13
  87. package/src/services/collection-service.ts +79 -63
  88. package/tsconfig.json +1 -1
  89. package/tsconfig.tsbuildinfo +1 -1
  90. package/types/components/app-bar-link.d.ts +1 -1
  91. package/types/components/app-bar-link.d.ts.map +1 -1
  92. package/types/components/app-bar.d.ts +1 -1
  93. package/types/components/app-bar.d.ts.map +1 -1
  94. package/types/components/avatar.d.ts +2 -1
  95. package/types/components/avatar.d.ts.map +1 -1
  96. package/types/components/button.d.ts +1 -1
  97. package/types/components/button.d.ts.map +1 -1
  98. package/types/components/command-palette/command-palette-input.d.ts +1 -1
  99. package/types/components/command-palette/command-palette-input.d.ts.map +1 -1
  100. package/types/components/command-palette/command-palette-suggestion-list.d.ts +1 -1
  101. package/types/components/command-palette/command-palette-suggestion-list.d.ts.map +1 -1
  102. package/types/components/command-palette/index.d.ts +1 -5
  103. package/types/components/command-palette/index.d.ts.map +1 -1
  104. package/types/components/data-grid/body.d.ts +1 -5
  105. package/types/components/data-grid/body.d.ts.map +1 -1
  106. package/types/components/data-grid/data-grid-row.d.ts +1 -5
  107. package/types/components/data-grid/data-grid-row.d.ts.map +1 -1
  108. package/types/components/data-grid/data-grid.d.ts +5 -3
  109. package/types/components/data-grid/data-grid.d.ts.map +1 -1
  110. package/types/components/data-grid/footer.d.ts +1 -1
  111. package/types/components/data-grid/footer.d.ts.map +1 -1
  112. package/types/components/data-grid/header.d.ts +1 -1
  113. package/types/components/data-grid/header.d.ts.map +1 -1
  114. package/types/components/data-grid/selection-cell.d.ts +1 -1
  115. package/types/components/data-grid/selection-cell.d.ts.map +1 -1
  116. package/types/components/fab.d.ts +1 -1
  117. package/types/components/fab.d.ts.map +1 -1
  118. package/types/components/grid.d.ts +1 -1
  119. package/types/components/grid.d.ts.map +1 -1
  120. package/types/components/inputs/autocomplete.d.ts +1 -1
  121. package/types/components/inputs/autocomplete.d.ts.map +1 -1
  122. package/types/components/inputs/input.d.ts +1 -1
  123. package/types/components/inputs/input.d.ts.map +1 -1
  124. package/types/components/inputs/text-area.d.ts +1 -4
  125. package/types/components/inputs/text-area.d.ts.map +1 -1
  126. package/types/components/loader.d.ts +9 -1
  127. package/types/components/loader.d.ts.map +1 -1
  128. package/types/components/modal.d.ts +1 -1
  129. package/types/components/modal.d.ts.map +1 -1
  130. package/types/components/noty-list.d.ts +2 -2
  131. package/types/components/noty-list.d.ts.map +1 -1
  132. package/types/components/paper.d.ts +1 -1
  133. package/types/components/paper.d.ts.map +1 -1
  134. package/types/components/skeleton.d.ts +1 -1
  135. package/types/components/skeleton.d.ts.map +1 -1
  136. package/types/components/suggest/index.d.ts +1 -5
  137. package/types/components/suggest/index.d.ts.map +1 -1
  138. package/types/components/suggest/suggest-input.d.ts +1 -1
  139. package/types/components/suggest/suggest-input.d.ts.map +1 -1
  140. package/types/components/suggest/suggest-manager.d.ts +2 -1
  141. package/types/components/suggest/suggest-manager.d.ts.map +1 -1
  142. package/types/components/suggest/suggestion-list.d.ts +1 -1
  143. package/types/components/suggest/suggestion-list.d.ts.map +1 -1
  144. package/types/components/tabs.d.ts +2 -2
  145. package/types/components/tabs.d.ts.map +1 -1
  146. package/types/components/wizard/index.d.ts +2 -2
  147. package/types/components/wizard/index.d.ts.map +1 -1
  148. package/types/services/collection-service.d.ts +4 -0
  149. package/types/services/collection-service.d.ts.map +1 -1
@@ -1,37 +1,32 @@
1
- import { Shade, createComponent } from '@furystack/shades'
1
+ import { Shade, createComponent, attachProps } from '@furystack/shades'
2
2
  import { ThemeProviderService } from '../services/theme-provider-service'
3
3
 
4
4
  export const AppBar = Shade({
5
5
  shadowDomName: 'shade-app-bar',
6
6
  constructed: ({ element }) => {
7
- const container = element.children[0] as HTMLElement
8
7
  requestAnimationFrame(() => {
9
- // container.style.padding = '8px 8px'
10
- container.style.opacity = '1'
8
+ element.style.opacity = '1'
11
9
  })
12
10
  },
13
- render: ({ children, injector }) => {
11
+ render: ({ children, injector, element }) => {
14
12
  const { theme } = injector.getInstance(ThemeProviderService)
15
- return (
16
- <div
17
- style={{
18
- width: '100%',
19
- background: 'rgba(128,128,128,0.2)',
20
- backdropFilter: 'blur(15px)',
21
- display: 'flex',
22
- justifyContent: 'flex-start',
23
- alignItems: 'center',
24
- boxShadow: '0 0 12px rgba(0,0,0,0.6)',
25
- transition:
26
- 'opacity .35s cubic-bezier(0.550, 0.085, 0.680, 0.530), padding .2s cubic-bezier(0.550, 0.085, 0.680, 0.530)',
27
- opacity: '0',
28
- position: 'fixed',
29
- zIndex: '1',
30
- color: theme.text.secondary,
31
- }}
32
- >
33
- {children}
34
- </div>
35
- )
13
+ attachProps(element, {
14
+ style: {
15
+ width: '100%',
16
+ background: 'rgba(128,128,128,0.2)',
17
+ backdropFilter: 'blur(15px)',
18
+ display: 'flex',
19
+ justifyContent: 'flex-start',
20
+ alignItems: 'center',
21
+ boxShadow: '0 0 12px rgba(0,0,0,0.6)',
22
+ transition:
23
+ 'opacity .35s cubic-bezier(0.550, 0.085, 0.680, 0.530), padding .2s cubic-bezier(0.550, 0.085, 0.680, 0.530)',
24
+ opacity: '0',
25
+ position: 'fixed',
26
+ zIndex: '1',
27
+ color: theme.text.secondary,
28
+ },
29
+ })
30
+ return <>{children}</>
36
31
  },
37
32
  })
@@ -1,46 +1,50 @@
1
1
  import type { PartialElement } from '@furystack/shades'
2
- import { Shade, createComponent } from '@furystack/shades'
2
+ import { Shade, createComponent, attachProps } from '@furystack/shades'
3
3
 
4
- export type AvatarProps = { avatarUrl: string } & PartialElement<HTMLDivElement>
4
+ export type AvatarProps = { avatarUrl: string; fallback?: JSX.Element } & PartialElement<HTMLDivElement>
5
5
 
6
6
  export const Avatar = Shade<AvatarProps>({
7
7
  shadowDomName: 'shade-avatar',
8
- render: ({ props }) => {
9
- const { ...divProps } = props
8
+ render: ({ props, element }) => {
9
+ const { avatarUrl, ...containerProps } = props
10
+
11
+ attachProps(element, {
12
+ ...containerProps,
13
+ style: {
14
+ width: '128px',
15
+ height: '128px',
16
+ overflow: 'hidden',
17
+ borderRadius: '50%',
18
+ boxShadow: '0px 0px 8px 3px rgba(128,128,128,0.2)',
19
+ backgroundColor: 'rgba(128,128,128,0.3)',
20
+ display: 'flex',
21
+ ...containerProps?.style,
22
+ },
23
+ })
24
+
10
25
  return (
11
- <div
12
- {...divProps}
13
- style={{
14
- width: '100%',
15
- height: '100%',
16
- overflow: 'hidden',
17
- borderRadius: '50%',
18
- boxShadow: '0px 0px 8px 3px rgba(128,128,128,0.2)',
19
- backgroundColor: 'rgba(128,128,128,0.3)',
20
- ...(props.style || {}),
26
+ <img
27
+ style={{ width: '100%', height: '100%', objectFit: 'cover', backgroundPosition: 'center' }}
28
+ alt={'avatar image'}
29
+ src={props.avatarUrl}
30
+ onerror={(ev) => {
31
+ ;((ev as Event).target as HTMLImageElement).replaceWith(
32
+ <div
33
+ style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%' }}
34
+ >
35
+ <div
36
+ style={{
37
+ textAlign: 'center',
38
+ userSelect: 'none',
39
+ fontSize: '32px',
40
+ }}
41
+ >
42
+ {props.fallback || '🛑'}
43
+ </div>
44
+ </div>,
45
+ )
21
46
  }}
22
- >
23
- <img
24
- style={{ width: '100%', height: '100%' }}
25
- alt={'avatar image'}
26
- src={props.avatarUrl}
27
- onerror={(ev) => {
28
- ;((ev as Event).target as HTMLImageElement).replaceWith(
29
- <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
30
- <div
31
- style={{
32
- fontVariant: 'all-petite-caps',
33
- fontSize: '2em',
34
- height: 'calc(100% + 7px)',
35
- cursor: 'default',
36
- userSelect: 'none',
37
- }}
38
- />
39
- </div>,
40
- )
41
- }}
42
- />
43
- </div>
47
+ />
44
48
  )
45
49
  },
46
50
  })
@@ -1,4 +1,5 @@
1
1
  import type { PartialElement } from '@furystack/shades'
2
+ import { attachProps } from '@furystack/shades'
2
3
  import { Shade, createComponent } from '@furystack/shades'
3
4
  import { promisifyAnimation } from '../utils/promisify-animation'
4
5
  import type { Palette, Theme } from '../services/theme-provider-service'
@@ -73,9 +74,9 @@ export const Button = Shade<ButtonProps>({
73
74
  * @param ev The Mouse event
74
75
  */
75
76
  function mouseUp(this: Document, ev: MouseEvent) {
76
- if (ev.target === element.firstElementChild) {
77
+ if (ev.target === element) {
77
78
  promisifyAnimation(
78
- element.firstChild as Element,
79
+ element,
79
80
  [
80
81
  {
81
82
  filter: 'drop-shadow(1px 1px 10px rgba(0,0,0,.5))brightness(1)',
@@ -94,32 +95,28 @@ export const Button = Shade<ButtonProps>({
94
95
  }
95
96
  },
96
97
  shadowDomName: 'shade-button',
97
- resources: ({ injector, element, props }) => {
98
- const tp = injector.getInstance(ThemeProviderService)
99
- return [
100
- ...(props.variant === 'contained'
101
- ? [
102
- Trace.method({
103
- object: tp,
104
- method: tp.set,
105
- onFinished: () => {
106
- const el = element.firstElementChild as HTMLButtonElement
107
- el.style.color = getTextColor(props, tp.theme, () =>
108
- tp.getTextColor(el.style.background || el.style.backgroundColor),
109
- )
110
- },
111
- }),
112
- ]
113
- : []),
114
- ]
115
- },
116
- render: ({ props, children, injector, element }) => {
98
+ render: ({ props, children, injector, element, useDisposable }) => {
117
99
  const mouseDownHandler = props.onmousedown
118
100
  const mouseUpHandler = props.onmouseup
119
101
  const themeProvider = injector.getInstance(ThemeProviderService)
120
102
  const { theme } = themeProvider
121
103
  const background = getBackground(props, theme)
122
104
 
105
+ if (props.variant === 'contained') {
106
+ useDisposable('themeChanged', () =>
107
+ Trace.method({
108
+ object: themeProvider,
109
+ method: themeProvider.set,
110
+ onFinished: () => {
111
+ const el = element
112
+ el.style.color = getTextColor(props, themeProvider.theme, () =>
113
+ themeProvider.getTextColor(el.style.background || el.style.backgroundColor),
114
+ )
115
+ },
116
+ }),
117
+ )
118
+ }
119
+
123
120
  const hoveredBackground = getHoveredBackground(props, theme, () => {
124
121
  const { r, g, b } = themeProvider.getRgbFromColorString(
125
122
  (props.color && theme.palette[props.color].main) || theme.text.primary,
@@ -136,76 +133,76 @@ export const Button = Shade<ButtonProps>({
136
133
  keyframes: PropertyIndexedKeyframes | Keyframe[] | null,
137
134
  options?: number | KeyframeAnimationOptions | undefined,
138
135
  ) => {
139
- const el = element.firstElementChild
136
+ const el = element
140
137
  el && promisifyAnimation(el, keyframes, options)
141
138
  }
142
139
 
143
- return (
144
- <button
145
- onmousedown={function (ev) {
146
- mouseDownHandler?.call(this, ev)
147
- tryAnimate(
148
- [
149
- {
150
- filter: 'drop-shadow(-1px -1px 3px black)brightness(0.5)',
151
- transform: 'scale(0.98)',
152
- },
153
- ],
154
- { duration: 150, fill: 'forwards', easing: 'cubic-bezier(0.230, 1.000, 0.320, 1.000)' },
155
- )
156
- }}
157
- onmouseup={function (ev) {
158
- mouseUpHandler?.call(this, ev)
159
- }}
160
- onmouseenter={() => {
161
- tryAnimate(
162
- [
163
- {
164
- background,
165
- boxShadow,
166
- color: getTextColorInner(),
167
- },
168
- {
169
- background: hoveredBackground,
170
- boxShadow: hoveredBoxShadow,
171
- color: getHoveredTextColorInner(),
172
- },
173
- ],
174
- { duration: 500, fill: 'forwards', easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' },
175
- )
176
- }}
177
- onmouseout={() => {
178
- tryAnimate(
179
- [
180
- { background: hoveredBackground, boxShadow: hoveredBoxShadow, color: getHoveredTextColorInner() },
181
- { background, boxShadow, color: getTextColorInner() },
182
- ],
140
+ attachProps(element, {
141
+ ...props,
142
+ onmousedown(this: HTMLElement, ev: MouseEvent) {
143
+ mouseDownHandler?.call(this, ev)
144
+ tryAnimate(
145
+ [
146
+ {
147
+ filter: 'drop-shadow(-1px -1px 3px black)brightness(0.5)',
148
+ transform: 'scale(0.98)',
149
+ },
150
+ ],
151
+ { duration: 150, fill: 'forwards', easing: 'cubic-bezier(0.230, 1.000, 0.320, 1.000)' },
152
+ )
153
+ },
154
+ onmouseup(this: HTMLElement, ev: MouseEvent) {
155
+ mouseUpHandler?.call(this, ev)
156
+ },
157
+ onmouseenter: () => {
158
+ tryAnimate(
159
+ [
183
160
  {
184
- duration: 500,
185
- fill: 'forwards',
186
- easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)',
161
+ background,
162
+ boxShadow,
163
+ color: getTextColorInner(),
187
164
  },
188
- )
189
- }}
190
- {...props}
191
- style={{
192
- cursor: props.disabled ? 'not-allowed' : 'pointer',
193
- background,
194
- boxShadow,
195
- margin: '8px',
196
- padding: '6px 16px',
197
- border: 'none',
198
- borderRadius: '4px',
199
- textTransform: 'uppercase',
200
- color: getTextColorInner(),
201
- filter: 'drop-shadow(1px 1px 10px rgba(0,0,0,.5))',
202
- backdropFilter: props.variant === 'outlined' ? 'blur(35px)' : undefined,
203
- userSelect: 'none',
204
- ...props.style,
205
- }}
206
- >
207
- {children}
208
- </button>
209
- )
165
+ {
166
+ background: hoveredBackground,
167
+ boxShadow: hoveredBoxShadow,
168
+ color: getHoveredTextColorInner(),
169
+ },
170
+ ],
171
+ { duration: 500, fill: 'forwards', easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' },
172
+ )
173
+ },
174
+ onmouseout: () => {
175
+ tryAnimate(
176
+ [
177
+ { background: hoveredBackground, boxShadow: hoveredBoxShadow, color: getHoveredTextColorInner() },
178
+ { background, boxShadow, color: getTextColorInner() },
179
+ ],
180
+ {
181
+ duration: 500,
182
+ fill: 'forwards',
183
+ easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)',
184
+ },
185
+ )
186
+ },
187
+ ...props,
188
+ style: {
189
+ display: 'inline-flex',
190
+ cursor: props.disabled ? 'not-allowed' : 'pointer',
191
+ background,
192
+ boxShadow,
193
+ margin: '8px',
194
+ padding: '6px 16px',
195
+ border: 'none',
196
+ borderRadius: '4px',
197
+ textTransform: 'uppercase',
198
+ color: getTextColorInner(),
199
+ filter: 'drop-shadow(1px 1px 10px rgba(0,0,0,.5))',
200
+ backdropFilter: props.variant === 'outlined' ? 'blur(35px)' : undefined,
201
+ userSelect: 'none',
202
+ ...props.style,
203
+ },
204
+ })
205
+
206
+ return <>{children}</>
210
207
  },
211
208
  })
@@ -1,13 +1,18 @@
1
1
  import { Shade, createComponent } from '@furystack/shades'
2
+ import { ThemeProviderService } from '../../services'
2
3
  import { promisifyAnimation } from '../../utils/promisify-animation'
3
4
  import type { CommandPaletteManager } from './command-palette-manager'
4
5
 
5
- export const CommandPaletteInput = Shade<{ manager: CommandPaletteManager }, { isOpened: boolean }>({
6
- getInitialState: ({ props }) => ({ isOpened: props.manager.isOpened.getValue() }),
7
- constructed: ({ element, props }) => {
6
+ export const CommandPaletteInput = Shade<{ manager: CommandPaletteManager }>({
7
+ shadowDomName: 'shades-command-palette-input',
8
+ render: ({ element, props, injector, useObservable }) => {
9
+ const { theme } = injector.getInstance(ThemeProviderService)
8
10
  const { manager } = props
9
- const subscriptions = [
10
- manager.isOpened.subscribe(async (isOpened) => {
11
+
12
+ useObservable(
13
+ 'isOpened',
14
+ manager.isOpened,
15
+ async (isOpened) => {
11
16
  const input = element.firstChild as HTMLInputElement
12
17
  if (isOpened) {
13
18
  input.value = ''
@@ -25,20 +30,17 @@ export const CommandPaletteInput = Shade<{ manager: CommandPaletteManager }, { i
25
30
  })
26
31
  input.value = ''
27
32
  }
28
- }),
29
- ]
30
- return () => subscriptions.map((s) => s.dispose())
31
- },
32
- shadowDomName: 'shades-command-palette-input',
33
- render: ({ element, props }) => {
34
- const { manager } = props
33
+ },
34
+ true,
35
+ )
36
+
35
37
  element.style.width = manager.isOpened.getValue() ? '100%' : '0%'
36
38
  element.style.overflow = 'hidden'
37
39
  return (
38
40
  <input
39
41
  autofocus
40
42
  style={{
41
- color: 'white',
43
+ color: theme.text.primary,
42
44
  outline: 'none',
43
45
  padding: '1em',
44
46
  background: 'transparent',
@@ -1,66 +1,57 @@
1
1
  import { Shade, createComponent } from '@furystack/shades'
2
2
  import { promisifyAnimation } from '../../utils/promisify-animation'
3
- import type { CommandPaletteSuggestionResult } from './command-provider'
4
3
  import type { CommandPaletteManager } from './command-palette-manager'
5
4
  import { ThemeProviderService } from '../../services/theme-provider-service'
6
5
 
7
- export const CommandPaletteSuggestionList = Shade<
8
- { manager: CommandPaletteManager; fullScreenSuggestions?: boolean },
9
- { suggestions: CommandPaletteSuggestionResult[] }
10
- >({
6
+ export const CommandPaletteSuggestionList = Shade<{ manager: CommandPaletteManager; fullScreenSuggestions?: boolean }>({
11
7
  shadowDomName: 'shade-command-palette-suggestion-list',
12
- getInitialState: ({ props }) => ({
13
- suggestions: props.manager.currentSuggestions.getValue(),
14
- }),
15
- constructed: ({ updateState, element, props }) => {
8
+ render: ({ element, injector, props, useObservable }) => {
16
9
  const { manager } = props
17
- const subscriptions = [
18
- manager.currentSuggestions.subscribe((suggestions) => {
19
- updateState({ suggestions })
20
- }),
21
- manager.isOpened.subscribe(async (isOpened) => {
22
- const container = element.firstElementChild as HTMLDivElement
23
- if (isOpened) {
24
- container.style.display = 'initial'
25
- container.style.zIndex = '1'
26
- container.style.width = `calc(${Math.round(
27
- element.parentElement?.getBoundingClientRect().width || 200,
28
- )}px - 3em)`
29
- await promisifyAnimation(
30
- container,
31
- [
32
- { opacity: 0, transform: 'translate(0, -50px)' },
33
- { opacity: 1, transform: 'translate(0, 0)' },
34
- ],
35
- { fill: 'forwards', duration: 500 },
36
- )
10
+ const { theme } = injector.getInstance(ThemeProviderService)
11
+
12
+ const [suggestions] = useObservable('suggestions', props.manager.currentSuggestions)
13
+ const [selectedIndex] = useObservable('selectedIndex', props.manager.selectedIndex, (idx) => {
14
+ ;([...element.querySelectorAll('.suggestion-item')] as HTMLDivElement[]).map((s, i) => {
15
+ if (i === idx) {
16
+ s.style.background = theme.background.paper
17
+ s.style.fontWeight = 'bolder'
37
18
  } else {
38
- await promisifyAnimation(
39
- container,
40
- [
41
- { opacity: 1, transform: 'translate(0, 0)' },
42
- { opacity: 0, transform: 'translate(0, -50px)' },
43
- ],
44
- { fill: 'forwards', duration: 200 },
45
- )
46
- container.style.zIndex = '-1'
47
- container.style.display = 'none'
19
+ s.style.background = theme.background.default
20
+ s.style.fontWeight = 'normal'
48
21
  }
49
- }),
50
- manager.selectedIndex.subscribe((idx) => {
51
- ;[...element.querySelectorAll('.suggestion-item')].map((s, i) => {
52
- if (i === idx) {
53
- ;(s as HTMLDivElement).style.background = 'rgba(128,128,128,0.2)'
54
- } else {
55
- ;(s as HTMLDivElement).style.background = 'rgba(96,96,96,0.2)'
56
- }
57
- })
58
- }),
59
- ]
60
- return () => subscriptions.map((s) => s.dispose())
61
- },
62
- render: ({ element, injector, getState, props }) => {
63
- const { manager } = props
22
+ })
23
+ })
24
+
25
+ const [isOpenedAtRender] = useObservable('isOpenedAtRender', props.manager.isOpened, async (isOpened) => {
26
+ const container = element.firstElementChild as HTMLDivElement
27
+ if (isOpened) {
28
+ container.style.display = 'initial'
29
+ container.style.zIndex = '1'
30
+ container.style.width = `calc(${Math.round(
31
+ element.parentElement?.getBoundingClientRect().width || 200,
32
+ )}px - 3em)`
33
+ await promisifyAnimation(
34
+ container,
35
+ [
36
+ { opacity: 0, transform: 'translate(0, -50px)' },
37
+ { opacity: 1, transform: 'translate(0, 0)' },
38
+ ],
39
+ { fill: 'forwards', duration: 500 },
40
+ )
41
+ } else {
42
+ await promisifyAnimation(
43
+ container,
44
+ [
45
+ { opacity: 1, transform: 'translate(0, 0)' },
46
+ { opacity: 0, transform: 'translate(0, -50px)' },
47
+ ],
48
+ { fill: 'forwards', duration: 200 },
49
+ )
50
+ container.style.zIndex = '-1'
51
+ container.style.display = 'none'
52
+ }
53
+ })
54
+
64
55
  return (
65
56
  <div
66
57
  className="suggestion-items-container"
@@ -75,22 +66,23 @@ export const CommandPaletteSuggestionList = Shade<
75
66
  maxHeight: `${window.innerHeight * 0.8}px`,
76
67
  zIndex: '1',
77
68
  left: 'auto',
78
- backgroundColor: injector.getInstance(ThemeProviderService).theme.background.paper,
69
+ backgroundColor: theme.background.paper,
79
70
  boxShadow: '3px 3px 5px rgba(0,0,0,0.3)',
80
71
  width: `calc(${Math.round(element.parentElement?.getBoundingClientRect().width || 200)}px - 3em)`,
81
72
  ...(props.fullScreenSuggestions ? { left: '0', width: 'calc(100% - 42px)' } : {}),
82
73
  }}
83
74
  >
84
- {getState().suggestions.map((s, i) => (
75
+ {suggestions.map((s, i) => (
85
76
  <div
86
77
  className="suggestion-item"
87
78
  onclick={() => {
88
- manager.isOpened.getValue() && manager.selectSuggestion(injector, i)
79
+ isOpenedAtRender && manager.selectSuggestion(injector, i)
89
80
  }}
90
81
  style={{
91
82
  padding: '1em',
92
83
  cursor: 'default',
93
- background: i === manager.selectedIndex.getValue() ? 'rgba(128,128,128,0.2)' : 'transparent',
84
+ background: i === selectedIndex ? theme.background.paper : theme.background.default,
85
+ fontWeight: i === selectedIndex ? 'bolder' : 'normal',
94
86
  }}
95
87
  >
96
88
  {s.element}