@coyalabs/bts-style 1.3.15 → 1.3.18

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.
@@ -6,10 +6,18 @@ type InputBox = SvelteComponent<{
6
6
  borderRadiusBottomLeft?: string | undefined;
7
7
  borderRadiusBottomRight?: string | undefined;
8
8
  icon?: string | null | undefined;
9
+ blur?: (() => void) | undefined;
10
+ focus?: (() => void) | undefined;
11
+ resize?: "none" | "both" | "horizontal" | "vertical" | undefined;
9
12
  iconSize?: string | undefined;
13
+ disabled?: boolean | undefined;
10
14
  value?: string | undefined;
11
15
  placeholder?: string | undefined;
12
16
  type?: string | undefined;
17
+ multiline?: boolean | undefined;
18
+ rows?: number | undefined;
19
+ expandOnNewline?: boolean | undefined;
20
+ newlineOnCtrlEnter?: boolean | undefined;
13
21
  autofocus?: boolean | undefined;
14
22
  }, {
15
23
  input: Event;
@@ -21,6 +29,9 @@ type InputBox = SvelteComponent<{
21
29
  [evt: string]: CustomEvent<any>;
22
30
  }, {}> & {
23
31
  $$bindings?: string | undefined;
32
+ } & {
33
+ focus: () => void;
34
+ blur: () => void;
24
35
  };
25
36
  declare const InputBox: $$__sveltets_2_IsomorphicComponent<{
26
37
  theme?: import("../Base/variantTypes.js").BaseContainerVariant | undefined;
@@ -29,10 +40,18 @@ declare const InputBox: $$__sveltets_2_IsomorphicComponent<{
29
40
  borderRadiusBottomLeft?: string | undefined;
30
41
  borderRadiusBottomRight?: string | undefined;
31
42
  icon?: string | null | undefined;
43
+ blur?: (() => void) | undefined;
44
+ focus?: (() => void) | undefined;
45
+ resize?: "none" | "both" | "horizontal" | "vertical" | undefined;
32
46
  iconSize?: string | undefined;
47
+ disabled?: boolean | undefined;
33
48
  value?: string | undefined;
34
49
  placeholder?: string | undefined;
35
50
  type?: string | undefined;
51
+ multiline?: boolean | undefined;
52
+ rows?: number | undefined;
53
+ expandOnNewline?: boolean | undefined;
54
+ newlineOnCtrlEnter?: boolean | undefined;
36
55
  autofocus?: boolean | undefined;
37
56
  }, {
38
57
  input: Event;
@@ -42,7 +61,10 @@ declare const InputBox: $$__sveltets_2_IsomorphicComponent<{
42
61
  keydown: KeyboardEvent;
43
62
  } & {
44
63
  [evt: string]: CustomEvent<any>;
45
- }, {}, {}, string>;
64
+ }, {}, {
65
+ focus: () => void;
66
+ blur: () => void;
67
+ }, string>;
46
68
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
47
69
  new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
48
70
  $$bindings?: Bindings;
@@ -14,6 +14,14 @@
14
14
  onOk();
15
15
  popupStore.close();
16
16
  }
17
+
18
+ export function confirm() {
19
+ handleOk();
20
+ }
21
+
22
+ export function cancel() {
23
+ popupStore.close();
24
+ }
17
25
  </script>
18
26
 
19
27
  <div class="buttons">
@@ -1,18 +1,28 @@
1
1
  export default AlertPopup;
2
2
  type AlertPopup = SvelteComponent<{
3
+ cancel?: (() => void) | undefined;
4
+ confirm?: (() => void) | undefined;
3
5
  onOk?: (() => void) | undefined;
4
6
  okText?: string | undefined;
5
7
  }, {
6
8
  [evt: string]: CustomEvent<any>;
7
9
  }, {}> & {
8
10
  $$bindings?: string | undefined;
11
+ } & {
12
+ confirm: () => void;
13
+ cancel: () => void;
9
14
  };
10
15
  declare const AlertPopup: $$__sveltets_2_IsomorphicComponent<{
16
+ cancel?: (() => void) | undefined;
17
+ confirm?: (() => void) | undefined;
11
18
  onOk?: (() => void) | undefined;
12
19
  okText?: string | undefined;
13
20
  }, {
14
21
  [evt: string]: CustomEvent<any>;
15
- }, {}, {}, string>;
22
+ }, {}, {
23
+ confirm: () => void;
24
+ cancel: () => void;
25
+ }, string>;
16
26
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
17
27
  new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
18
28
  $$bindings?: Bindings;
@@ -25,6 +25,14 @@
25
25
  onCancel();
26
26
  popupStore.close();
27
27
  }
28
+
29
+ export function confirm() {
30
+ handleConfirm();
31
+ }
32
+
33
+ export function cancel() {
34
+ handleCancel();
35
+ }
28
36
  </script>
29
37
 
30
38
  <div class="buttons">
@@ -1,22 +1,32 @@
1
1
  export default ConfirmPopup;
2
2
  type ConfirmPopup = SvelteComponent<{
3
+ cancel?: (() => void) | undefined;
3
4
  onConfirm?: (() => void) | undefined;
4
5
  onCancel?: (() => void) | undefined;
5
6
  confirmText?: string | undefined;
6
7
  cancelText?: string | undefined;
8
+ confirm?: (() => void) | undefined;
7
9
  }, {
8
10
  [evt: string]: CustomEvent<any>;
9
11
  }, {}> & {
10
12
  $$bindings?: string | undefined;
13
+ } & {
14
+ confirm: () => void;
15
+ cancel: () => void;
11
16
  };
12
17
  declare const ConfirmPopup: $$__sveltets_2_IsomorphicComponent<{
18
+ cancel?: (() => void) | undefined;
13
19
  onConfirm?: (() => void) | undefined;
14
20
  onCancel?: (() => void) | undefined;
15
21
  confirmText?: string | undefined;
16
22
  cancelText?: string | undefined;
23
+ confirm?: (() => void) | undefined;
17
24
  }, {
18
25
  [evt: string]: CustomEvent<any>;
19
- }, {}, {}, string>;
26
+ }, {}, {
27
+ confirm: () => void;
28
+ cancel: () => void;
29
+ }, string>;
20
30
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
21
31
  new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
22
32
  $$bindings?: Bindings;
@@ -1,4 +1,5 @@
1
1
  <script>
2
+ import { tick } from 'svelte';
2
3
  import { fade, fly } from 'svelte/transition';
3
4
  import { backOut } from 'svelte/easing';
4
5
  import { popupStore } from './popupStore.js';
@@ -9,11 +10,85 @@
9
10
  import { VARIANT_FILLED } from '../../Base/variantTypes.js';
10
11
 
11
12
  // Subscribe to the actual stack
12
- /** @type {Array<{id: string, title: string, subtitle?: string, component: any, props: any}>} */
13
+ /** @type {Array<{id: string, title: string, subtitle?: string, component: any, props: any, widthRatio: number}>} */
13
14
  let popupStack = [];
14
15
  popupStore.stack.subscribe((s) => {
15
16
  popupStack = s;
16
17
  });
18
+
19
+ /** @type {{submit?: () => void, confirm?: () => void, cancel?: () => void, focusInput?: () => void} | null} */
20
+ let activePopupInstance = null;
21
+
22
+ /** @type {HTMLDivElement | null} */
23
+ let activeDialogRef = null;
24
+
25
+ function focusActivePopup() {
26
+ void tick().then(() => {
27
+ if (popupStack.length === 0) {
28
+ return;
29
+ }
30
+
31
+ if (activePopupInstance?.focusInput) {
32
+ activePopupInstance.focusInput();
33
+ return;
34
+ }
35
+
36
+ activeDialogRef?.focus({ preventScroll: true });
37
+ });
38
+ }
39
+
40
+ /**
41
+ * @param {KeyboardEvent} event
42
+ */
43
+ function handlePopupKeydown(event) {
44
+ const textareaAllowsEnterEvents = event.target instanceof HTMLTextAreaElement
45
+ && event.target.dataset.newlineOnCtrlEnter === 'true';
46
+
47
+ if (event.defaultPrevented || event.isComposing || event.altKey || event.ctrlKey || event.metaKey) {
48
+ if (!(textareaAllowsEnterEvents && event.defaultPrevented && !event.ctrlKey && !event.metaKey && !event.altKey && !event.isComposing)) {
49
+ return;
50
+ }
51
+ }
52
+
53
+ if (event.key === 'Escape') {
54
+ event.preventDefault();
55
+ if (activePopupInstance?.cancel) {
56
+ activePopupInstance.cancel();
57
+ } else {
58
+ popupStore.close();
59
+ }
60
+ return;
61
+ }
62
+
63
+ if (event.key !== 'Enter') {
64
+ return;
65
+ }
66
+
67
+ if (event.shiftKey) {
68
+ return;
69
+ }
70
+
71
+ if (event.target instanceof HTMLTextAreaElement && !textareaAllowsEnterEvents) {
72
+ return;
73
+ }
74
+
75
+ if (event.target instanceof Element && event.target.closest('button, a, [role="button"]')) {
76
+ return;
77
+ }
78
+
79
+ event.preventDefault();
80
+
81
+ if (activePopupInstance?.submit) {
82
+ activePopupInstance.submit();
83
+ return;
84
+ }
85
+
86
+ activePopupInstance?.confirm?.();
87
+ }
88
+
89
+ $: if (popupStack.length > 0) {
90
+ focusActivePopup();
91
+ }
17
92
  </script>
18
93
 
19
94
  {#if popupStack.length > 0}
@@ -24,15 +99,18 @@
24
99
  <div
25
100
  class="dialog"
26
101
  class:background={!isTop}
102
+ bind:this={activeDialogRef}
27
103
  style="
28
104
  --scale: {isTop ? 1 : Math.max(0.85, 1 - depth * 0.08)};
29
105
  --brightness: {isTop ? 1 : Math.max(0.4, 1 - depth * 0.3)};
30
106
  --y-offset: {isTop ? 0 : -depth * 20}px;
107
+ --popup-width-ratio: {popup.widthRatio || 1};
31
108
  z-index: {index};
32
109
  "
33
110
  in:fly|global={{ y: 40, duration: 350, easing: backOut }}
34
111
  out:fly|global={{ y: 20, duration: 200 }}
35
112
  on:click|stopPropagation
113
+ on:keydown={handlePopupKeydown}
36
114
  on:keydown|stopPropagation
37
115
  role="dialog"
38
116
  tabindex="-1"
@@ -45,7 +123,7 @@
45
123
  </div>
46
124
  </header>
47
125
  <main>
48
- <svelte:component this={popup.component} {...popup.props} />
126
+ <svelte:component bind:this={activePopupInstance} this={popup.component} {...popup.props} />
49
127
  </main>
50
128
  </BaseContainer>
51
129
  </div>
@@ -66,7 +144,11 @@
66
144
 
67
145
  .dialog {
68
146
  position: absolute;
69
- width: min(90%, 600px);
147
+ width: min(
148
+ calc(100vw - 2rem),
149
+ calc(90vw * var(--popup-width-ratio)),
150
+ calc(600px * var(--popup-width-ratio))
151
+ );
70
152
  max-height: 80vh;
71
153
  zoom: 0.92;
72
154
  display: flex;
@@ -76,6 +158,11 @@
76
158
  transition: transform 0.3s ease, filter 0.3s ease;
77
159
  }
78
160
 
161
+ .dialog:focus,
162
+ .dialog:focus-visible {
163
+ outline: none;
164
+ }
165
+
79
166
  .dialog.background {
80
167
  pointer-events: none;
81
168
  }
@@ -26,6 +26,9 @@
26
26
 
27
27
  let value = '';
28
28
 
29
+ /** @type {import('../InputBox.svelte').default | null} */
30
+ let inputRef = null;
31
+
29
32
  function handleSubmit() {
30
33
  onSubmit(value);
31
34
  popupStore.close();
@@ -35,13 +38,25 @@
35
38
  onCancel();
36
39
  popupStore.close();
37
40
  }
41
+
42
+ export function submit() {
43
+ handleSubmit();
44
+ }
45
+
46
+ export function cancel() {
47
+ handleCancel();
48
+ }
49
+
50
+ export function focusInput() {
51
+ inputRef?.focus();
52
+ }
38
53
  </script>
39
54
 
40
55
  <div class="prompt">
41
56
  {#if label}
42
57
  <BaseText variant="content">{label}</BaseText>
43
58
  {/if}
44
- <InputBox bind:value {placeholder} autofocus={true} />
59
+ <InputBox bind:this={inputRef} bind:value {placeholder} autofocus={true} />
45
60
  <div class="buttons">
46
61
  <Button theme={VARIANT_PRIMARY} actionIcon={icons.check} on:click={handleSubmit}>{submitText}</Button>
47
62
  <Button theme={VARIANT_SECONDARY} actionIcon={icons.crossb} on:click={handleCancel}>{cancelText}</Button>
@@ -1,26 +1,40 @@
1
1
  export default PromptPopup;
2
2
  type PromptPopup = SvelteComponent<{
3
3
  label?: string | undefined;
4
+ cancel?: (() => void) | undefined;
5
+ submit?: (() => void) | undefined;
4
6
  placeholder?: string | undefined;
5
7
  onCancel?: (() => void) | undefined;
6
8
  cancelText?: string | undefined;
7
9
  onSubmit?: ((value: string) => void) | undefined;
8
10
  submitText?: string | undefined;
11
+ focusInput?: (() => void) | undefined;
9
12
  }, {
10
13
  [evt: string]: CustomEvent<any>;
11
14
  }, {}> & {
12
15
  $$bindings?: string | undefined;
16
+ } & {
17
+ submit: () => void;
18
+ cancel: () => void;
19
+ focusInput: () => void;
13
20
  };
14
21
  declare const PromptPopup: $$__sveltets_2_IsomorphicComponent<{
15
22
  label?: string | undefined;
23
+ cancel?: (() => void) | undefined;
24
+ submit?: (() => void) | undefined;
16
25
  placeholder?: string | undefined;
17
26
  onCancel?: (() => void) | undefined;
18
27
  cancelText?: string | undefined;
19
28
  onSubmit?: ((value: string) => void) | undefined;
20
29
  submitText?: string | undefined;
30
+ focusInput?: (() => void) | undefined;
21
31
  }, {
22
32
  [evt: string]: CustomEvent<any>;
23
- }, {}, {}, string>;
33
+ }, {}, {
34
+ submit: () => void;
35
+ cancel: () => void;
36
+ focusInput: () => void;
37
+ }, string>;
24
38
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
25
39
  new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
26
40
  $$bindings?: Bindings;
@@ -1,10 +1,18 @@
1
1
  export namespace popupStore {
2
2
  let subscribe: (this: void, run: import("svelte/store").Subscriber<{
3
+ isOpen: boolean;
4
+ title: string;
5
+ subtitle: string;
6
+ component: any;
7
+ props: {};
8
+ widthRatio?: undefined;
9
+ } | {
3
10
  isOpen: boolean;
4
11
  title: string;
5
12
  subtitle: string;
6
13
  component: any;
7
14
  props: any;
15
+ widthRatio: number;
8
16
  }>, invalidate?: () => void) => import("svelte/store").Unsubscriber;
9
17
  namespace stack {
10
18
  let subscribe_1: (this: void, run: import("svelte/store").Subscriber<PopupState[]>, invalidate?: () => void) => import("svelte/store").Unsubscriber;
@@ -18,10 +26,12 @@ export namespace popupStore {
18
26
  onCancel?: (() => void) | undefined;
19
27
  confirmText?: string | undefined;
20
28
  cancelText?: string | undefined;
29
+ popupWidthRatio?: number | undefined;
21
30
  }): void;
22
31
  function alert(title: string, message: string, options?: {
23
32
  onOk?: (() => void) | undefined;
24
33
  okText?: string | undefined;
34
+ popupWidthRatio?: number | undefined;
25
35
  }): void;
26
36
  function prompt(title: string, message: string, options?: {
27
37
  onSubmit?: ((value: string) => void) | undefined;
@@ -30,6 +40,7 @@ export namespace popupStore {
30
40
  submitText?: string | undefined;
31
41
  cancelText?: string | undefined;
32
42
  label?: string | undefined;
43
+ popupWidthRatio?: number | undefined;
33
44
  }): void;
34
45
  }
35
46
  export type PopupState = {
@@ -38,4 +49,5 @@ export type PopupState = {
38
49
  component: any;
39
50
  props: any;
40
51
  id: string;
52
+ widthRatio: number;
41
53
  };
@@ -10,8 +10,56 @@ import PromptPopup from './PromptPopup.svelte';
10
10
  * @property {any} component
11
11
  * @property {any} props
12
12
  * @property {string} id
13
+ * @property {number} widthRatio
13
14
  */
14
15
 
16
+ /**
17
+ * @param {unknown} value
18
+ */
19
+ function normalizePopupWidthRatio(value) {
20
+ const ratio = Number(value);
21
+ return Number.isFinite(ratio) && ratio > 0 ? ratio : 1;
22
+ }
23
+
24
+ /**
25
+ * @param {any} rawProps
26
+ */
27
+ function splitPopupProps(rawProps = {}) {
28
+ if (!rawProps || typeof rawProps !== 'object' || Array.isArray(rawProps)) {
29
+ return {
30
+ props: {},
31
+ widthRatio: 1
32
+ };
33
+ }
34
+
35
+ const { popupWidthRatio, ...props } = rawProps;
36
+
37
+ return {
38
+ props,
39
+ widthRatio: normalizePopupWidthRatio(popupWidthRatio)
40
+ };
41
+ }
42
+
43
+ /**
44
+ * @param {string} title
45
+ * @param {string} subtitle
46
+ * @param {any} component
47
+ * @param {any} rawProps
48
+ * @returns {PopupState}
49
+ */
50
+ function createPopupEntry(title, subtitle, component, rawProps = {}) {
51
+ const { props, widthRatio } = splitPopupProps(rawProps);
52
+
53
+ return {
54
+ id: crypto.randomUUID(),
55
+ title,
56
+ subtitle,
57
+ component,
58
+ props,
59
+ widthRatio
60
+ };
61
+ }
62
+
15
63
  function createPopupStore() {
16
64
  /** @type {import('svelte/store').Writable<PopupState[]>} */
17
65
  const stack = writable([]);
@@ -33,7 +81,8 @@ function createPopupStore() {
33
81
  title: top.title,
34
82
  subtitle: top.subtitle || '',
35
83
  component: top.component,
36
- props: top.props
84
+ props: top.props,
85
+ widthRatio: top.widthRatio
37
86
  };
38
87
  });
39
88
 
@@ -44,13 +93,7 @@ function createPopupStore() {
44
93
  stack: { subscribe: stack.subscribe },
45
94
 
46
95
  open: (/** @type {string} */ title, /** @type {any} */ component, props = {}, subtitle = '') => {
47
- stack.update(s => [...s, {
48
- id: crypto.randomUUID(),
49
- title,
50
- subtitle,
51
- component,
52
- props
53
- }]);
96
+ stack.update(s => [...s, createPopupEntry(title, subtitle, component, props)]);
54
97
  },
55
98
 
56
99
  close: () => {
@@ -70,15 +113,10 @@ function createPopupStore() {
70
113
  * @param {() => void} [options.onCancel]
71
114
  * @param {string} [options.confirmText]
72
115
  * @param {string} [options.cancelText]
116
+ * @param {number} [options.popupWidthRatio]
73
117
  */
74
118
  confirm: (title, message, options = {}) => {
75
- stack.update(s => [...s, {
76
- id: crypto.randomUUID(),
77
- title,
78
- subtitle: message,
79
- component: ConfirmPopup,
80
- props: options
81
- }]);
119
+ stack.update(s => [...s, createPopupEntry(title, message, ConfirmPopup, options)]);
82
120
  },
83
121
 
84
122
  /**
@@ -88,15 +126,10 @@ function createPopupStore() {
88
126
  * @param {Object} options
89
127
  * @param {() => void} [options.onOk]
90
128
  * @param {string} [options.okText]
129
+ * @param {number} [options.popupWidthRatio]
91
130
  */
92
131
  alert: (title, message, options = {}) => {
93
- stack.update(s => [...s, {
94
- id: crypto.randomUUID(),
95
- title,
96
- subtitle: message,
97
- component: AlertPopup,
98
- props: options
99
- }]);
132
+ stack.update(s => [...s, createPopupEntry(title, message, AlertPopup, options)]);
100
133
  },
101
134
 
102
135
  /**
@@ -110,15 +143,10 @@ function createPopupStore() {
110
143
  * @param {string} [options.submitText]
111
144
  * @param {string} [options.cancelText]
112
145
  * @param {string} [options.label]
146
+ * @param {number} [options.popupWidthRatio]
113
147
  */
114
148
  prompt: (title, message, options = {}) => {
115
- stack.update(s => [...s, {
116
- id: crypto.randomUUID(),
117
- title,
118
- subtitle: message,
119
- component: PromptPopup,
120
- props: options
121
- }]);
149
+ stack.update(s => [...s, createPopupEntry(title, message, PromptPopup, options)]);
122
150
  }
123
151
  };
124
152
  }
@@ -1,4 +1,6 @@
1
1
  <script>
2
+ import { onMount, tick } from 'svelte';
3
+
2
4
  /**
3
5
  * @type {'auto' | 'scroll' | 'hidden' | 'visible'}
4
6
  */
@@ -53,11 +55,74 @@
53
55
  * @type {string}
54
56
  */
55
57
  export let borderRadius = '4px';
58
+
59
+ /**
60
+ * Hide scrollbars until the container has been scrolled away from its initial position.
61
+ * @type {boolean}
62
+ */
63
+ export let hideScrollbarUntilScroll = false;
64
+
65
+ /** @type {HTMLDivElement | null} */
66
+ let containerRef = null;
67
+
68
+ let hasBeenScrolled = false;
69
+
70
+ $: scrollbarsHidden = hideScrollbarUntilScroll && !hasBeenScrolled;
71
+
72
+ function updateScrolledState() {
73
+ if (!hideScrollbarUntilScroll || !containerRef) {
74
+ return;
75
+ }
76
+
77
+ if (containerRef.scrollTop > 0 || containerRef.scrollLeft > 0) {
78
+ hasBeenScrolled = true;
79
+ }
80
+ }
81
+
82
+ function handleScroll() {
83
+ updateScrolledState();
84
+ }
85
+
86
+ /**
87
+ * Reveal the scrollbars and replay the first wheel delta so the first scroll
88
+ * interaction still moves content even though overflow starts hidden.
89
+ * @param {WheelEvent} event
90
+ */
91
+ function handleInitialWheel(event) {
92
+ if (!scrollbarsHidden || !containerRef) {
93
+ return;
94
+ }
95
+
96
+ if (event.deltaX === 0 && event.deltaY === 0) {
97
+ return;
98
+ }
99
+
100
+ event.preventDefault();
101
+ hasBeenScrolled = true;
102
+
103
+ void tick().then(() => {
104
+ containerRef?.scrollBy({ left: event.deltaX, top: event.deltaY });
105
+ });
106
+ }
107
+
108
+ onMount(() => {
109
+ void tick().then(() => {
110
+ updateScrolledState();
111
+ });
112
+ });
113
+
114
+ $: if (!hideScrollbarUntilScroll) {
115
+ hasBeenScrolled = false;
116
+ }
56
117
  </script>
57
118
 
58
119
  <div
59
120
  class="scroll-container"
60
- style="--overflow-x: {overflowX}; --overflow-y: {overflowY}; --width: {width}; --height: {height}; --max-width: {maxWidth}; --max-height: {maxHeight}; --scrollbar-size: {scrollbarSize}; --scroll-track-color: {trackColor}; --scroll-thumb-color: {thumbColor}; --scroll-thumb-hover-color: {thumbHoverColor}; --scroll-radius: {borderRadius};"
121
+ class:hidden-scrollbar-until-scroll={scrollbarsHidden}
122
+ bind:this={containerRef}
123
+ on:scroll={handleScroll}
124
+ on:wheel={handleInitialWheel}
125
+ style="--effective-overflow-x: {scrollbarsHidden ? 'hidden' : overflowX}; --effective-overflow-y: {scrollbarsHidden ? 'hidden' : overflowY}; --width: {width}; --height: {height}; --max-width: {maxWidth}; --max-height: {maxHeight}; --scrollbar-size: {scrollbarSize}; --scroll-track-color: {trackColor}; --scroll-thumb-color: {thumbColor}; --scroll-thumb-hover-color: {thumbHoverColor}; --scroll-radius: {borderRadius};"
61
126
  >
62
127
  <slot />
63
128
  </div>
@@ -68,17 +133,37 @@
68
133
  height: var(--height);
69
134
  max-width: var(--max-width);
70
135
  max-height: var(--max-height);
71
- overflow-x: var(--overflow-x);
72
- overflow-y: var(--overflow-y);
136
+ overflow-x: var(--effective-overflow-x);
137
+ overflow-y: var(--effective-overflow-y);
73
138
  scrollbar-color: var(--scroll-thumb-color) var(--scroll-track-color);
74
139
  scrollbar-width: thin;
75
140
  }
76
141
 
142
+ .scroll-container.hidden-scrollbar-until-scroll {
143
+ scrollbar-width: none;
144
+ -ms-overflow-style: none;
145
+ scrollbar-color: transparent transparent;
146
+ }
147
+
77
148
  .scroll-container::-webkit-scrollbar {
78
149
  width: var(--scrollbar-size);
79
150
  height: var(--scrollbar-size);
80
151
  }
81
152
 
153
+ .scroll-container.hidden-scrollbar-until-scroll::-webkit-scrollbar {
154
+ display: none;
155
+ width: 0;
156
+ height: 0;
157
+ background: transparent;
158
+ }
159
+
160
+ .scroll-container.hidden-scrollbar-until-scroll::-webkit-scrollbar-track,
161
+ .scroll-container.hidden-scrollbar-until-scroll::-webkit-scrollbar-thumb,
162
+ .scroll-container.hidden-scrollbar-until-scroll::-webkit-scrollbar-corner {
163
+ background: transparent;
164
+ border-radius: 0;
165
+ }
166
+
82
167
  .scroll-container::-webkit-scrollbar-track {
83
168
  background: var(--scroll-track-color);
84
169
  border-radius: var(--scroll-radius);
@@ -11,6 +11,7 @@ type ScrollContainer = SvelteComponent<$$__sveltets_2_PropsWithChildren<{
11
11
  thumbColor?: string | undefined;
12
12
  thumbHoverColor?: string | undefined;
13
13
  borderRadius?: string | undefined;
14
+ hideScrollbarUntilScroll?: boolean | undefined;
14
15
  }, {
15
16
  default: {};
16
17
  }>, {
@@ -32,6 +33,7 @@ declare const ScrollContainer: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2
32
33
  thumbColor?: string | undefined;
33
34
  thumbHoverColor?: string | undefined;
34
35
  borderRadius?: string | undefined;
36
+ hideScrollbarUntilScroll?: boolean | undefined;
35
37
  }, {
36
38
  default: {};
37
39
  }>, {