@perspective-dev/viewer 4.2.0 → 4.4.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 (240) hide show
  1. package/dist/cdn/perspective-viewer.js +2 -2
  2. package/dist/cdn/perspective-viewer.js.map +4 -4
  3. package/dist/css/botanical.css +1 -0
  4. package/dist/css/dracula.css +1 -1
  5. package/dist/css/gruvbox-dark.css +1 -1
  6. package/dist/css/gruvbox.css +1 -1
  7. package/dist/css/icons.css +1 -1
  8. package/dist/css/intl/de.css +1 -1
  9. package/dist/css/intl/es.css +1 -1
  10. package/dist/css/intl/fr.css +1 -1
  11. package/dist/css/intl/ja.css +1 -1
  12. package/dist/css/intl/pt.css +1 -1
  13. package/dist/css/intl/zh.css +1 -1
  14. package/dist/css/intl.css +1 -1
  15. package/dist/css/monokai.css +1 -1
  16. package/dist/css/pro-dark.css +1 -1
  17. package/dist/css/pro.css +1 -1
  18. package/dist/css/solarized-dark.css +1 -1
  19. package/dist/css/solarized.css +1 -1
  20. package/dist/css/themes.css +1 -1
  21. package/dist/css/vaporwave.css +1 -1
  22. package/dist/esm/extensions.d.ts +32 -1
  23. package/dist/esm/perspective-viewer.d.ts +1 -0
  24. package/dist/esm/perspective-viewer.inline.js +2 -2
  25. package/dist/esm/perspective-viewer.inline.js.map +4 -4
  26. package/dist/esm/perspective-viewer.js +2 -2
  27. package/dist/esm/perspective-viewer.js.map +4 -4
  28. package/dist/esm/ts-rs/GroupRollupMode.d.ts +1 -0
  29. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +2 -0
  30. package/dist/wasm/perspective-viewer.d.ts +57 -53
  31. package/dist/wasm/perspective-viewer.js +197 -164
  32. package/dist/wasm/perspective-viewer.wasm +0 -0
  33. package/dist/wasm/perspective-viewer.wasm.d.ts +17 -18
  34. package/package.json +9 -6
  35. package/src/{less/aggregate-selector.less → css/aggregate-selector.css} +23 -20
  36. package/src/css/column-dropdown.css +109 -0
  37. package/src/{less/column-selector.less → css/column-selector.css} +161 -159
  38. package/src/{less/column-settings-panel.less → css/column-settings-panel.css} +69 -59
  39. package/src/{less/column-style.less → css/column-style.css} +52 -66
  40. package/src/{less/column-symbol-attributes.less → css/column-symbol-attributes.css} +15 -14
  41. package/src/css/config-selector.css +441 -0
  42. package/src/{less/containers/dropdown-menu.less → css/containers/dropdown-menu.css} +20 -19
  43. package/src/{less/containers/pairs-list.less → css/containers/pairs-list.css} +13 -12
  44. package/src/{themes/variables.less → css/containers/scroll-panel.css} +25 -22
  45. package/src/{less/containers/split-panel.less → css/containers/split-panel.css} +15 -14
  46. package/src/{less/containers/tabs.less → css/containers/tabs.css} +17 -19
  47. package/src/css/dom/checkbox.css +102 -0
  48. package/src/css/dom/scrollbar.css +35 -0
  49. package/src/{less/dom/select.less → css/dom/select.css} +17 -18
  50. package/src/{less/empty-column.less → css/empty-column.css} +19 -18
  51. package/src/{less/expression-editor.less → css/expression-editor.css} +19 -18
  52. package/src/{less/filter-dropdown.less → css/filter-dropdown.css} +12 -11
  53. package/src/{less/filter-item.less → css/filter-item.css} +16 -15
  54. package/src/{less/form/code-editor.less → css/form/code-editor.css} +26 -30
  55. package/src/{less/form/debug.less → css/form/debug.css} +19 -18
  56. package/src/{less/function-dropdown.less → css/function-dropdown.css} +12 -11
  57. package/src/css/plugin-selector.css +261 -0
  58. package/src/{less/render-warning.less → css/render-warning.css} +18 -17
  59. package/src/{less/status-bar.less → css/status-bar.css} +156 -144
  60. package/src/css/type-icon.css +116 -0
  61. package/src/{less/viewer.less → css/viewer.css} +112 -146
  62. package/src/rust/components/column_dropdown.rs +229 -119
  63. package/src/rust/components/column_selector/active_column.rs +81 -62
  64. package/src/rust/components/column_selector/add_expression_button.rs +1 -0
  65. package/src/rust/components/column_selector/aggregate_selector.rs +25 -15
  66. package/src/rust/components/column_selector/config_selector.rs +374 -185
  67. package/src/rust/components/column_selector/empty_column.rs +2 -2
  68. package/src/rust/components/column_selector/expr_edit_button.rs +8 -2
  69. package/src/rust/components/column_selector/filter_column.rs +37 -26
  70. package/src/rust/components/column_selector/inactive_column.rs +41 -29
  71. package/src/rust/components/column_selector/invalid_column.rs +7 -18
  72. package/src/rust/components/column_selector/pivot_column.rs +21 -10
  73. package/src/rust/components/column_selector/sort_column.rs +23 -13
  74. package/src/rust/components/column_selector.rs +189 -100
  75. package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +1 -1
  76. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +3 -2
  77. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs_item.rs +3 -2
  78. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_selector.rs +2 -3
  79. package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +7 -1
  80. package/src/rust/components/column_settings_sidebar/style_tab.rs +153 -112
  81. package/src/rust/components/column_settings_sidebar.rs +91 -53
  82. package/src/rust/components/containers/dragdrop_list.rs +29 -7
  83. package/src/rust/components/containers/scroll_panel.rs +8 -1
  84. package/src/rust/components/containers/select.rs +3 -3
  85. package/src/rust/components/containers/sidebar_close_button.rs +1 -1
  86. package/src/rust/components/containers/split_panel.rs +3 -2
  87. package/src/rust/components/containers/tab_list.rs +1 -1
  88. package/src/rust/components/copy_dropdown.rs +7 -28
  89. package/src/rust/components/datetime_column_style/custom.rs +2 -2
  90. package/src/rust/components/datetime_column_style/simple.rs +2 -2
  91. package/src/rust/components/datetime_column_style.rs +4 -2
  92. package/src/rust/components/editable_header.rs +7 -4
  93. package/src/rust/components/empty_row.rs +1 -1
  94. package/src/rust/components/export_dropdown.rs +4 -30
  95. package/src/rust/components/expression_editor.rs +19 -10
  96. package/src/rust/components/filter_dropdown.rs +246 -102
  97. package/src/rust/components/font_loader.rs +11 -28
  98. package/src/rust/components/form/code_editor.rs +17 -2
  99. package/src/rust/components/form/color_range_selector.rs +19 -6
  100. package/src/rust/components/form/debug.rs +30 -13
  101. package/src/rust/components/function_dropdown.rs +186 -113
  102. package/src/rust/components/main_panel.rs +71 -89
  103. package/src/rust/components/mod.rs +1 -1
  104. package/src/rust/components/modal.rs +7 -1
  105. package/src/rust/components/number_column_style.rs +22 -7
  106. package/src/rust/components/plugin_selector.rs +34 -92
  107. package/src/rust/components/portal.rs +274 -0
  108. package/src/rust/components/render_warning.rs +72 -123
  109. package/src/rust/components/settings_panel.rs +115 -11
  110. package/src/rust/components/status_bar.rs +222 -98
  111. package/src/rust/components/status_bar_counter.rs +8 -20
  112. package/src/rust/components/status_indicator.rs +64 -111
  113. package/src/rust/components/string_column_style.rs +2 -2
  114. package/src/rust/components/style/style_cache.rs +5 -1
  115. package/src/rust/components/viewer.rs +391 -39
  116. package/src/rust/custom_elements/copy_dropdown.rs +102 -21
  117. package/src/rust/custom_elements/export_dropdown.rs +102 -20
  118. package/src/rust/custom_elements/mod.rs +0 -7
  119. package/src/rust/custom_elements/modal.rs +7 -103
  120. package/src/rust/custom_elements/viewer.rs +99 -35
  121. package/src/rust/custom_events.rs +23 -2
  122. package/src/rust/dragdrop.rs +149 -10
  123. package/src/{less/containers/scroll-panel.less → rust/engines.rs} +15 -13
  124. package/src/rust/js/plugin.rs +20 -1
  125. package/src/rust/lib.rs +5 -4
  126. package/src/rust/presentation/props.rs +39 -0
  127. package/src/rust/presentation/sheets.rs +3 -3
  128. package/src/rust/presentation.rs +44 -8
  129. package/src/rust/renderer/limits.rs +32 -3
  130. package/src/{less/dom/scrollbar.less → rust/renderer/props.rs} +18 -19
  131. package/src/rust/renderer/registry.rs +8 -1
  132. package/src/rust/renderer.rs +83 -9
  133. package/src/rust/session/column_defaults_update.rs +18 -0
  134. package/src/rust/session/metadata.rs +23 -2
  135. package/src/rust/session/props.rs +178 -0
  136. package/src/rust/session/replace_expression_update.rs +1 -0
  137. package/src/rust/session.rs +124 -117
  138. package/src/rust/tasks/column_locator.rs +133 -0
  139. package/src/rust/{model → tasks}/columns_iter_set.rs +14 -23
  140. package/src/rust/{model → tasks}/edit_expression.rs +34 -10
  141. package/src/rust/{model → tasks}/eject.rs +2 -2
  142. package/src/rust/{model → tasks}/get_viewer_config.rs +0 -11
  143. package/src/rust/{model → tasks}/intersection_observer.rs +22 -4
  144. package/src/{less/containers/radio-list.less → rust/tasks/is_invalid_drop.rs} +21 -14
  145. package/src/rust/tasks/mod.rs +52 -0
  146. package/src/rust/{model → tasks}/plugin_column_styles.rs +69 -46
  147. package/src/rust/{model → tasks}/resize_observer.rs +39 -6
  148. package/src/rust/{model → tasks}/send_plugin_config.rs +1 -1
  149. package/src/rust/tasks/structural.rs +53 -0
  150. package/src/rust/utils/mod.rs +4 -0
  151. package/src/rust/utils/modal_position.rs +110 -0
  152. package/src/rust/utils/ptr_eq_rc.rs +74 -0
  153. package/src/rust/utils/pubsub.rs +11 -1
  154. package/src/svg/bg-pattern.png +0 -0
  155. package/src/svg/close-icon.svg +1 -1
  156. package/src/svg/expression.svg +1 -1
  157. package/src/svg/mega-menu-icons-candlestick.svg +1 -1
  158. package/src/svg/mega-menu-icons-datagrid.svg +1 -2
  159. package/src/svg/mega-menu-icons-heatmap.svg +1 -1
  160. package/src/svg/mega-menu-icons-map-scatter.svg +1 -1
  161. package/src/svg/mega-menu-icons-ohlc.svg +1 -1
  162. package/src/svg/mega-menu-icons-sunburst.svg +1 -1
  163. package/src/svg/mega-menu-icons-treemap.svg +1 -1
  164. package/src/svg/mega-menu-icons-x-bar.svg +1 -1
  165. package/src/svg/mega-menu-icons-x-y-line.svg +1 -1
  166. package/src/svg/mega-menu-icons-x-y-scatter.svg +1 -1
  167. package/src/svg/mega-menu-icons-y-area.svg +1 -1
  168. package/src/svg/mega-menu-icons-y-bar.svg +1 -1
  169. package/src/svg/mega-menu-icons-y-line.svg +1 -1
  170. package/src/svg/mega-menu-icons-y-scatter.svg +1 -1
  171. package/src/svg/radio-hover.svg +1 -1
  172. package/src/svg/radio-off.svg +1 -1
  173. package/src/svg/radio-on.svg +1 -1
  174. package/src/themes/botanical.css +157 -0
  175. package/src/themes/defaults.css +139 -0
  176. package/src/themes/dracula.css +233 -0
  177. package/src/themes/gruvbox-dark.css +255 -0
  178. package/src/themes/gruvbox.css +134 -0
  179. package/src/themes/icons.css +124 -0
  180. package/src/themes/intl/de.css +102 -0
  181. package/src/themes/intl/es.css +102 -0
  182. package/src/themes/intl/fr.css +102 -0
  183. package/src/themes/intl/ja.css +102 -0
  184. package/src/themes/intl/pt.css +102 -0
  185. package/src/themes/intl/zh.css +102 -0
  186. package/src/themes/intl.css +102 -0
  187. package/src/themes/monokai.css +233 -0
  188. package/src/themes/pro-dark.css +158 -0
  189. package/src/themes/{themes.less → pro.css} +17 -20
  190. package/src/themes/solarized-dark.css +135 -0
  191. package/src/themes/solarized.css +95 -0
  192. package/src/themes/themes.css +22 -0
  193. package/src/themes/vaporwave.css +256 -0
  194. package/src/ts/extensions.ts +73 -2
  195. package/src/ts/perspective-viewer.ts +1 -0
  196. package/src/ts/ts-rs/GroupRollupMode.ts +3 -0
  197. package/src/ts/ts-rs/ViewerConfigUpdate.ts +2 -1
  198. package/tsconfig.json +1 -0
  199. package/dist/css/variables.css +0 -0
  200. package/src/less/column-dropdown.less +0 -95
  201. package/src/less/config-selector.less +0 -363
  202. package/src/less/dom/checkbox.less +0 -100
  203. package/src/less/plugin-selector.less +0 -183
  204. package/src/less/type-icon.less +0 -68
  205. package/src/rust/components/error_message.rs +0 -56
  206. package/src/rust/custom_elements/column_dropdown.rs +0 -123
  207. package/src/rust/custom_elements/filter_dropdown.rs +0 -179
  208. package/src/rust/custom_elements/function_dropdown.rs +0 -115
  209. package/src/rust/model/column_locator.rs +0 -82
  210. package/src/rust/model/is_invalid_drop.rs +0 -36
  211. package/src/rust/model/mod.rs +0 -100
  212. package/src/rust/model/reset_all.rs +0 -38
  213. package/src/rust/model/structural.rs +0 -244
  214. package/src/themes/dracula.less +0 -101
  215. package/src/themes/gruvbox-dark.less +0 -116
  216. package/src/themes/gruvbox.less +0 -152
  217. package/src/themes/icons.less +0 -130
  218. package/src/themes/intl/de.less +0 -102
  219. package/src/themes/intl/es.less +0 -102
  220. package/src/themes/intl/fr.less +0 -102
  221. package/src/themes/intl/ja.less +0 -102
  222. package/src/themes/intl/pt.less +0 -102
  223. package/src/themes/intl/zh.less +0 -102
  224. package/src/themes/intl.less +0 -102
  225. package/src/themes/monokai.less +0 -107
  226. package/src/themes/pro-dark.less +0 -147
  227. package/src/themes/pro.less +0 -186
  228. package/src/themes/solarized-dark.less +0 -78
  229. package/src/themes/solarized.less +0 -102
  230. package/src/themes/vaporwave.less +0 -145
  231. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline0.js +0 -0
  232. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline1.js +0 -0
  233. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline2.js +0 -0
  234. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline3.js +0 -0
  235. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline4.js +0 -0
  236. /package/src/rust/{model → tasks}/copy_export.rs +0 -0
  237. /package/src/rust/{model → tasks}/export_app.rs +0 -0
  238. /package/src/rust/{model → tasks}/export_method.rs +0 -0
  239. /package/src/rust/{model → tasks}/restore_and_render.rs +0 -0
  240. /package/src/rust/{model → tasks}/update_and_render.rs +0 -0
@@ -16,13 +16,13 @@ use wasm_bindgen::prelude::*;
16
16
  use web_sys::*;
17
17
  use yew::prelude::*;
18
18
 
19
- use crate::PerspectiveProperties;
20
19
  use crate::components::viewer::{PerspectiveViewer, PerspectiveViewerMsg};
21
20
  use crate::js::*;
22
- use crate::model::*;
21
+ use crate::presentation::Presentation;
23
22
  use crate::renderer::*;
24
23
  use crate::root::Root;
25
- use crate::session::Session;
24
+ use crate::session::{Session, TableLoadState};
25
+ use crate::tasks::*;
26
26
  use crate::utils::*;
27
27
 
28
28
  pub struct ResizeObserverHandle {
@@ -36,6 +36,7 @@ impl ResizeObserverHandle {
36
36
  elem: &HtmlElement,
37
37
  renderer: &Renderer,
38
38
  session: &Session,
39
+ presentation: &Presentation,
39
40
  root: &Root<PerspectiveViewer>,
40
41
  ) -> Self {
41
42
  let on_resize = root
@@ -48,6 +49,7 @@ impl ResizeObserverHandle {
48
49
  elem: elem.clone(),
49
50
  renderer: renderer.clone(),
50
51
  session: session.clone(),
52
+ presentation: presentation.clone(),
51
53
  width: elem.offset_width(),
52
54
  height: elem.offset_height(),
53
55
  on_resize,
@@ -70,16 +72,43 @@ impl Drop for ResizeObserverHandle {
70
72
  }
71
73
  }
72
74
 
73
- #[derive(PerspectiveProperties!)]
75
+ #[derive(Clone)]
74
76
  struct ResizeObserverState {
75
77
  elem: HtmlElement,
76
78
  renderer: Renderer,
77
79
  session: Session,
80
+ presentation: Presentation,
78
81
  width: i32,
79
82
  height: i32,
80
83
  on_resize: Callback<()>,
81
84
  }
82
85
 
86
+ impl HasRenderer for ResizeObserverState {
87
+ fn renderer(&self) -> &Renderer {
88
+ &self.renderer
89
+ }
90
+ }
91
+
92
+ impl HasSession for ResizeObserverState {
93
+ fn session(&self) -> &Session {
94
+ &self.session
95
+ }
96
+ }
97
+
98
+ impl HasPresentation for ResizeObserverState {
99
+ fn presentation(&self) -> &'_ crate::presentation::Presentation {
100
+ &self.presentation
101
+ }
102
+ }
103
+
104
+ impl StateProvider for ResizeObserverState {
105
+ type State = ResizeObserverState;
106
+
107
+ fn clone_state(&self) -> Self::State {
108
+ self.clone()
109
+ }
110
+ }
111
+
83
112
  impl ResizeObserverState {
84
113
  fn on_resize(&mut self, entries: &js_sys::Array) {
85
114
  let is_visible = self
@@ -97,17 +126,21 @@ impl ResizeObserverState {
97
126
  if resized && is_visible {
98
127
  let state = self.clone_state();
99
128
  clone!(self.on_resize);
100
- ApiFuture::spawn(async move {
129
+ ApiFuture::spawn_throttled(async move {
101
130
  let needs_render = state
102
131
  .renderer()
103
132
  .clone()
104
133
  .with_lock(async {
105
134
  Ok(!state.renderer().is_plugin_activated()?
106
- && state.session().has_table())
135
+ && matches!(
136
+ state.session().has_table(),
137
+ Some(TableLoadState::Loaded)
138
+ ))
107
139
  })
108
140
  .await?;
109
141
 
110
142
  if needs_render {
143
+ state.presentation.reset_attached();
111
144
  state.update_and_render(Default::default())?.await?;
112
145
  } else {
113
146
  state.renderer().resize().await?;
@@ -13,7 +13,7 @@
13
13
  use perspective_js::utils::*;
14
14
 
15
15
  use crate::config::ColumnConfigValueUpdate;
16
- use crate::model::*;
16
+ use crate::tasks::*;
17
17
 
18
18
  pub trait SendPluginConfig {
19
19
  /// Update te urrent plugin with a [`ColumnonfigValueUpdate`]
@@ -0,0 +1,53 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ //! Structural typing traits that allow task methods to be automatically defined
14
+ //! for any struct that holds the necessary state handles.
15
+
16
+ use crate::custom_events::*;
17
+ use crate::dragdrop::*;
18
+ use crate::presentation::*;
19
+ use crate::renderer::*;
20
+ use crate::session::*;
21
+
22
+ pub trait HasCustomEvents {
23
+ fn custom_events(&self) -> &'_ CustomEvents;
24
+ }
25
+
26
+ pub trait HasDragDrop {
27
+ fn dragdrop(&self) -> &'_ DragDrop;
28
+ }
29
+
30
+ pub trait HasPresentation {
31
+ fn presentation(&self) -> &'_ Presentation;
32
+ }
33
+
34
+ pub trait HasRenderer {
35
+ fn renderer(&self) -> &'_ Renderer;
36
+ }
37
+
38
+ pub trait HasSession {
39
+ fn session(&self) -> &'_ Session;
40
+ }
41
+
42
+ impl HasSession for Session {
43
+ fn session(&self) -> &'_ Session {
44
+ self
45
+ }
46
+ }
47
+
48
+ pub trait StateProvider {
49
+ type State: Clone + 'static;
50
+
51
+ /// Clones just the state object fields into a new dedicated state struct.
52
+ fn clone_state(&self) -> Self::State;
53
+ }
@@ -21,7 +21,9 @@ mod custom_element;
21
21
  mod datetime;
22
22
  mod debounce;
23
23
  mod hooks;
24
+ mod modal_position;
24
25
  mod number_format;
26
+ mod ptr_eq_rc;
25
27
  mod pubsub;
26
28
  mod weak_scope;
27
29
 
@@ -33,8 +35,10 @@ pub use custom_element::*;
33
35
  pub use datetime::*;
34
36
  pub use debounce::*;
35
37
  pub use hooks::*;
38
+ pub use modal_position::*;
36
39
  pub use number_format::*;
37
40
  pub use perspective_client::clone;
41
+ pub use ptr_eq_rc::*;
38
42
  pub use pubsub::*;
39
43
  pub use weak_scope::*;
40
44
 
@@ -0,0 +1,110 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ use perspective_js::utils::global;
14
+ use web_sys::*;
15
+
16
+ /// Anchor point enum, `ModalCornerTargetCorner`
17
+ #[derive(Clone, Copy, Debug, Default)]
18
+ pub enum ModalAnchor {
19
+ BottomRightTopLeft,
20
+ BottomRightBottomLeft,
21
+ BottomRightTopRight,
22
+ BottomLeftTopLeft,
23
+ TopRightTopLeft,
24
+ TopRightBottomRight,
25
+
26
+ #[default]
27
+ TopLeftBottomLeft,
28
+ }
29
+
30
+ impl ModalAnchor {
31
+ pub const fn is_rev_vert(&self) -> bool {
32
+ matches!(
33
+ self,
34
+ Self::BottomLeftTopLeft
35
+ | Self::BottomRightBottomLeft
36
+ | Self::BottomRightTopLeft
37
+ | Self::BottomRightTopRight
38
+ )
39
+ }
40
+ }
41
+
42
+ /// Given the bounds of the target element as previously computed, as well as
43
+ /// the browser's viewport and the bounds of the already-connected modal element
44
+ /// itself, determine the best anchor point to keep the element on-screen.
45
+ pub fn calc_relative_position(
46
+ elem: &HtmlElement,
47
+ _top: f64,
48
+ left: f64,
49
+ height: f64,
50
+ width: f64,
51
+ ) -> ModalAnchor {
52
+ let window = global::window();
53
+ let rect = elem.get_bounding_client_rect();
54
+ let inner_width = window.inner_width().unwrap().as_f64().unwrap();
55
+ let inner_height = window.inner_height().unwrap().as_f64().unwrap();
56
+ let rect_top = rect.top();
57
+ let rect_height = rect.height();
58
+ let rect_width = rect.width();
59
+ let rect_left = rect.left();
60
+
61
+ let elem_over_y = inner_height < rect_top + rect_height;
62
+ let elem_over_x = inner_width < rect_left + rect_width;
63
+ let target_over_x = inner_width < rect_left + width;
64
+ let target_over_y = inner_height < rect_top + height;
65
+
66
+ // modal/target
67
+ match (elem_over_y, elem_over_x, target_over_x, target_over_y) {
68
+ (true, _, true, true) => ModalAnchor::BottomRightTopLeft,
69
+ (true, _, true, false) => ModalAnchor::BottomRightBottomLeft,
70
+ (true, true, false, _) => {
71
+ if left + width - rect_width > 0.0 {
72
+ ModalAnchor::BottomRightTopRight
73
+ } else {
74
+ ModalAnchor::BottomLeftTopLeft
75
+ }
76
+ },
77
+ (true, false, false, _) => ModalAnchor::BottomLeftTopLeft,
78
+ (false, true, true, _) => ModalAnchor::TopRightTopLeft,
79
+ (false, true, false, _) => {
80
+ if left + width - rect_width > 0.0 {
81
+ ModalAnchor::TopRightBottomRight
82
+ } else {
83
+ ModalAnchor::TopLeftBottomLeft
84
+ }
85
+ },
86
+ _ => ModalAnchor::TopLeftBottomLeft,
87
+ }
88
+ }
89
+
90
+ /// Calculate the (top, left) position for a modal element given an anchor
91
+ /// point, target element bounding rect, and the modal element's own bounding
92
+ /// rect.
93
+ pub fn calc_anchor_position(anchor: ModalAnchor, target: &DomRect, modal: &DomRect) -> (f64, f64) {
94
+ let height = target.height();
95
+ let width = target.width();
96
+ let top = target.top();
97
+ let left = target.left();
98
+ let rect_height = modal.height();
99
+ let rect_width = modal.width();
100
+
101
+ match anchor {
102
+ ModalAnchor::BottomRightTopLeft => (top - rect_height, left - rect_width + 1.0),
103
+ ModalAnchor::BottomRightBottomLeft => (top - rect_height + height, left - rect_width + 1.0),
104
+ ModalAnchor::BottomRightTopRight => (top - rect_height + 1.0, left + width - rect_width),
105
+ ModalAnchor::BottomLeftTopLeft => (top - rect_height + 1.0, left),
106
+ ModalAnchor::TopRightTopLeft => (top, left - rect_width + 1.0),
107
+ ModalAnchor::TopRightBottomRight => (top + height - 1.0, left + width - rect_width),
108
+ ModalAnchor::TopLeftBottomLeft => (top + height - 1.0, left),
109
+ }
110
+ }
@@ -0,0 +1,74 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ use std::ops::Deref;
14
+ use std::rc::Rc;
15
+
16
+ use yew::html::{ImplicitClone, IntoPropValue};
17
+
18
+ /// A thin wrapper around `Rc<T>` whose `PartialEq` uses pointer identity
19
+ /// (`Rc::ptr_eq`) instead of deep structural comparison. This makes it
20
+ /// suitable for Yew `Properties` fields that hold large, cheaply-shared
21
+ /// snapshots (e.g. `ViewConfig`, `SessionMetadata`, `Vec<String>`).
22
+ pub struct PtrEqRc<T>(Rc<T>);
23
+
24
+ impl<T> PtrEqRc<T> {
25
+ pub fn new(val: T) -> Self {
26
+ Self(Rc::new(val))
27
+ }
28
+ }
29
+
30
+ impl<T> Clone for PtrEqRc<T> {
31
+ fn clone(&self) -> Self {
32
+ Self(Rc::clone(&self.0))
33
+ }
34
+ }
35
+
36
+ impl<T> PartialEq for PtrEqRc<T> {
37
+ fn eq(&self, other: &Self) -> bool {
38
+ Rc::ptr_eq(&self.0, &other.0)
39
+ }
40
+ }
41
+
42
+ impl<T> Deref for PtrEqRc<T> {
43
+ type Target = T;
44
+
45
+ fn deref(&self) -> &T {
46
+ &self.0
47
+ }
48
+ }
49
+
50
+ impl<T> From<T> for PtrEqRc<T> {
51
+ fn from(rc: T) -> Self {
52
+ Self(Rc::new(rc))
53
+ }
54
+ }
55
+
56
+ impl<T: Default> Default for PtrEqRc<T> {
57
+ fn default() -> Self {
58
+ Self(Rc::default())
59
+ }
60
+ }
61
+
62
+ impl<T: std::fmt::Debug> std::fmt::Debug for PtrEqRc<T> {
63
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64
+ self.0.fmt(f)
65
+ }
66
+ }
67
+
68
+ impl<T> ImplicitClone for PtrEqRc<T> {}
69
+
70
+ impl<T> IntoPropValue<PtrEqRc<T>> for Rc<T> {
71
+ fn into_prop_value(self) -> PtrEqRc<T> {
72
+ PtrEqRc(self)
73
+ }
74
+ }
@@ -84,7 +84,9 @@ impl<T: Clone> PubSubInternal<T> {
84
84
  /// publishers, without leaking callbacks as listeners are dropped.
85
85
  ///
86
86
  /// Unlike `mpsc` etc., `PubSub` has no internal queue and is completely
87
- /// synchronous.
87
+ /// synchronous. Explicitly does not implement clone, as this is intended as
88
+ /// RAII, even though the internal data structures are `Clone` because they
89
+ /// need to be sent to listeners.
88
90
  #[derive(Derivative)]
89
91
  #[derivative(Default(bound = ""))]
90
92
  pub struct PubSub<T: Clone>(Rc<PubSubInternal<T>>);
@@ -116,6 +118,14 @@ impl<T: Clone + 'static> PubSub<T> {
116
118
  Callback::from(move |val: T| internal.emit(val))
117
119
  }
118
120
 
121
+ /// Subscribe a `Callback<()>` that fires whenever this PubSub emits,
122
+ /// discarding the emitted value. Useful when the subscriber only
123
+ /// needs a "something changed" notification.
124
+ pub fn add_notify_listener(&self, cb: &Callback<()>) -> Subscription {
125
+ let cb = cb.clone();
126
+ self.add_listener(move |_: T| cb.emit(()))
127
+ }
128
+
119
129
  /// Convert [`PubSub::emit`] to a `Box<dyn Fn(T)>`.
120
130
  #[must_use]
121
131
  pub fn as_boxfn(&self) -> Box<dyn Fn(T) + 'static> {
Binary file
@@ -1,4 +1,4 @@
1
- <svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
1
+ <svg width="20" height="20" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
2
2
  <line y1="-0.5" x2="13.4536" y2="-0.5" transform="matrix(0.668965 0.743294 -0.668965 0.743294 6 6)"
3
3
  stroke="#042121" />
4
4
  <line y1="-0.5" x2="13.4536" y2="-0.5" transform="matrix(-0.668965 0.743294 0.668965 0.743294 16 6)"
@@ -1,4 +1,4 @@
1
- <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
1
+ <svg width="14" height="14" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
2
2
  <defs></defs>
3
3
  <path d="M 15.915 8.555 L 10.213 14.257" stroke-width="1.00491" stroke-linecap="round" style="stroke: #042121">
4
4
  </path>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,6 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
- <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
2
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
3
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
4
  <style type="text/css">
6
5
  .st0{fill:#042121;}
7
6
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve">
4
+ viewBox="0 0 80 70" style="enable-background:new 0 0 80 70;" xml:space="preserve" width="40" height="35">
5
5
  <style type="text/css">
6
6
  .st0{fill:#042121;}
7
7
  </style>
@@ -1,4 +1,4 @@
1
- <svg width="11" height="11" viewBox="0 0 11 11" fill="none" xmlns="http://www.w3.org/2000/svg">
1
+ <svg width="14" height="14" viewBox="0 0 11 11" fill="none" xmlns="http://www.w3.org/2000/svg">
2
2
  <circle cx="5.5" cy="5.5" r="2.5" fill="#3F4343"/>
3
3
  <rect x="0.5" y="0.5" width="10" height="10" rx="5" stroke="#3F4343"/>
4
4
  </svg>
@@ -1,3 +1,3 @@
1
- <svg width="11" height="11" viewBox="0 0 11 11" fill="none" xmlns="http://www.w3.org/2000/svg">
1
+ <svg width="14" height="14" viewBox="0 0 11 11" fill="none" xmlns="http://www.w3.org/2000/svg">
2
2
  <circle cx="5.5" cy="5.5" r="3" stroke="#3F4343" />
3
3
  </svg>
@@ -1,4 +1,4 @@
1
- <svg width="11" height="11" viewBox="0 0 11 11" fill="none" xmlns="http://www.w3.org/2000/svg">
1
+ <svg width="14" height="14" viewBox="0 0 11 11" fill="none" xmlns="http://www.w3.org/2000/svg">
2
2
  <circle cx="5.5" cy="5.5" r="3.5" fill="#3F4343"/>
3
3
  <rect x="0.5" y="0.5" width="10" height="10" rx="5" stroke="#3F4343"/>
4
4
  </svg>