|
1 | 1 | <script lang="ts"> |
2 | 2 | import { SETTINGS, type Settings } from '$lib/settings/userSettings'; |
3 | 3 | import { getContextStoreBySymbol } from '@gitbutler/shared/context'; |
4 | | - import { pxToRem } from '@gitbutler/ui/utils/pxToRem'; |
5 | 4 |
|
6 | 5 | interface Props { |
7 | 6 | /** The element that is being resized */ |
8 | 7 | viewport: HTMLElement; |
9 | 8 | /** Sets direction of resizing for viewport */ |
10 | 9 | direction: 'left' | 'right' | 'up' | 'down'; |
11 | | - /** Sets the color of the line */ |
12 | | - defaultLineColor?: string; |
13 | | - defaultLineThickness?: number; |
14 | | - hoverLineThickness?: number; |
15 | | - /** Needed when overflow is hidden */ |
16 | | - sticky?: boolean; |
| 10 | + /** Border radius for cases when the resizable element has rounded corners */ |
| 11 | + borderRadius?: 's' | 'm' | 'ml' | 'l' | 'none'; |
17 | 12 | /** Custom z-index in case of overlapping with other elements */ |
18 | 13 | zIndex?: string; |
| 14 | + /** imitate border */ |
| 15 | + imitateBorder?: boolean; |
| 16 | + imitateBorderColor?: string; |
| 17 | +
|
| 18 | + /** Minimum width for the resizable element */ |
19 | 19 | minWidth?: number; |
20 | 20 | maxWidth?: number; |
21 | 21 | minHeight?: number; |
|
32 | 32 | const { |
33 | 33 | viewport, |
34 | 34 | direction, |
35 | | - defaultLineColor = 'none', |
36 | | - defaultLineThickness = 1, |
37 | | - hoverLineThickness = 2, |
38 | | - sticky = false, |
39 | 35 | zIndex = 'var(--z-lifted)', |
40 | 36 | minWidth = 0, |
41 | 37 | maxWidth = 40, |
42 | 38 | minHeight = 0, |
| 39 | + borderRadius = 'none', |
| 40 | + imitateBorder, |
| 41 | + imitateBorderColor = 'var(--clr-border-2)', |
43 | 42 |
|
44 | 43 | onHeight, |
45 | 44 | onWidth, |
|
133 | 132 | class:down={direction === 'down'} |
134 | 133 | class:left={direction === 'left'} |
135 | 134 | class:right={direction === 'right'} |
136 | | - class:sticky |
137 | 135 | style:z-index={zIndex} |
| 136 | + style:--resizer-border-radius="var(--radius-{borderRadius})" |
| 137 | + style:--border-imitation-color={imitateBorderColor} |
138 | 138 | > |
139 | | - <div |
140 | | - class="resizer-line" |
141 | | - style="--resizer-default-line-color: {defaultLineColor}; --resizer-default-line-thickness: {pxToRem( |
142 | | - defaultLineThickness |
143 | | - )}; --resizer-hover-line-thickness: {pxToRem(hoverLineThickness)}" |
144 | | - ></div> |
| 139 | + <div class="resizer-line"></div> |
| 140 | + |
| 141 | + {#if imitateBorder} |
| 142 | + <div class="border-imitation"></div> |
| 143 | + {/if} |
145 | 144 | </div> |
146 | 145 |
|
147 | 146 | <style lang="postcss"> |
148 | 147 | .resizer { |
149 | | - --resizer-frame-thickness: 4px; |
150 | | - --resizer-default-line-thickness: 2px; |
151 | | - --resizer-hover-line-thickness: 8px; |
152 | | - --resizer-default-line-color: none; |
| 148 | + --resizer-line-thickness: 0; |
| 149 | + --resizer-line-color: transparent; |
| 150 | + /* should be big for large radius */ |
| 151 | + --resizer-line-frame: 20px; |
153 | 152 | position: absolute; |
| 153 | + outline: none; |
| 154 | + /* background-color: rgba(255, 0, 0, 0.2); */ |
154 | 155 |
|
155 | 156 | &:hover, |
156 | 157 | &:focus, |
157 | 158 | &.dragging { |
158 | | - outline: none; |
| 159 | + --resizer-line-color: var(--resizer-color); |
| 160 | + --resizer-line-thickness: 0.15rem; |
159 | 161 |
|
160 | 162 | & .resizer-line { |
161 | 163 | transition-delay: 0.1s; |
162 | | - background-color: var(--resizer-color); |
163 | | - } |
164 | | -
|
165 | | - &:not(.vertical) { |
166 | | - & .resizer-line { |
167 | | - width: var(--resizer-hover-line-thickness); |
168 | | - } |
169 | | - } |
170 | | -
|
171 | | - &:not(.horizontal) { |
172 | | - & .resizer-line { |
173 | | - height: var(--resizer-hover-line-thickness); |
174 | | - } |
175 | 164 | } |
176 | 165 | } |
177 | 166 | } |
| 167 | +
|
178 | 168 | .resizer-line { |
179 | 169 | position: absolute; |
180 | 170 | top: 0; |
181 | 171 | left: 0; |
182 | 172 | right: 0; |
183 | 173 | bottom: 0; |
184 | | - background-color: var(--resizer-default-line-color); |
185 | 174 | pointer-events: none; |
186 | | - transition: |
187 | | - background-color 0.1s ease-out, |
188 | | - width 0.1s ease-out, |
189 | | - height 0.1s ease-out; |
| 175 | + transition: border 0.1s ease; |
190 | 176 | } |
191 | 177 |
|
192 | 178 | .horizontal { |
193 | | - width: 4px; |
| 179 | + width: 8px; |
194 | 180 | height: 100%; |
195 | 181 | cursor: col-resize; |
196 | 182 | top: 0; |
197 | 183 |
|
198 | 184 | & .resizer-line { |
199 | | - width: var(--resizer-default-line-thickness); |
| 185 | + width: var(--resizer-line-frame); |
| 186 | + } |
| 187 | +
|
| 188 | + & .border-imitation { |
| 189 | + width: 1px; |
200 | 190 | } |
201 | 191 | } |
| 192 | +
|
202 | 193 | .vertical { |
203 | 194 | height: 4px; |
204 | 195 | width: 100%; |
205 | 196 | cursor: row-resize; |
206 | 197 | left: 0; |
207 | 198 |
|
208 | 199 | & .resizer-line { |
209 | | - height: var(--resizer-default-line-thickness); |
| 200 | + height: var(--resizer-line-frame); |
| 201 | + } |
| 202 | +
|
| 203 | + & .border-imitation { |
| 204 | + height: 1px; |
210 | 205 | } |
211 | 206 | } |
212 | 207 |
|
|
215 | 210 |
|
216 | 211 | & .resizer-line { |
217 | 212 | left: auto; |
| 213 | + border-right: var(--resizer-line-thickness) solid var(--resizer-line-color); |
| 214 | + border-top-right-radius: var(--resizer-border-radius); |
| 215 | + border-bottom-right-radius: var(--resizer-border-radius); |
| 216 | + } |
| 217 | +
|
| 218 | + & .border-imitation { |
| 219 | + left: auto; |
218 | 220 | } |
219 | 221 | } |
220 | 222 | .left { |
221 | 223 | left: 0; |
222 | 224 |
|
223 | 225 | & .resizer-line { |
224 | 226 | right: auto; |
| 227 | + border-left: var(--resizer-line-thickness) solid var(--resizer-line-color); |
| 228 | + border-top-left-radius: var(--resizer-border-radius); |
| 229 | + border-bottom-left-radius: var(--resizer-border-radius); |
| 230 | + } |
| 231 | +
|
| 232 | + & .border-imitation { |
| 233 | + right: auto; |
225 | 234 | } |
226 | 235 | } |
227 | 236 | .up { |
228 | 237 | top: 0; |
229 | 238 |
|
230 | 239 | & .resizer-line { |
231 | 240 | bottom: auto; |
| 241 | + border-top: var(--resizer-line-thickness) solid var(--resizer-line-color); |
| 242 | + border-top-left-radius: var(--resizer-border-radius); |
| 243 | + border-top-right-radius: var(--resizer-border-radius); |
232 | 244 | } |
233 | 245 | } |
234 | 246 | .down { |
235 | 247 | bottom: 0; |
236 | 248 |
|
237 | 249 | & .resizer-line { |
238 | 250 | top: auto; |
| 251 | + border-bottom: var(--resizer-line-thickness) solid var(--resizer-line-color); |
| 252 | + border-bottom-left-radius: var(--resizer-border-radius); |
| 253 | + border-bottom-right-radius: var(--resizer-border-radius); |
239 | 254 | } |
240 | 255 | } |
241 | 256 |
|
242 | | - .sticky { |
243 | | - position: sticky; |
| 257 | + .border-imitation { |
| 258 | + position: absolute; |
| 259 | + width: 100%; |
| 260 | + height: 100%; |
244 | 261 | top: 0; |
| 262 | + left: 0; |
| 263 | + right: 0; |
| 264 | + bottom: 0; |
| 265 | + background-color: var(--border-imitation-color); |
| 266 | + z-index: -1; |
245 | 267 | } |
246 | 268 | </style> |
0 commit comments