@finsweet/webflow-apps-utils 1.0.25 → 1.0.26

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.
@@ -0,0 +1,45 @@
1
+ import type { StoryObj } from '@storybook/sveltekit';
2
+ import type { ButtonGroupProps } from './types.js';
3
+ declare const meta: {
4
+ title: string;
5
+ component: import("svelte").Component<ButtonGroupProps, {}, "selected">;
6
+ parameters: {
7
+ layout: string;
8
+ docs: {
9
+ description: {
10
+ component: string;
11
+ };
12
+ };
13
+ };
14
+ tags: string[];
15
+ argTypes: {
16
+ buttons: {
17
+ control: "object";
18
+ description: string;
19
+ };
20
+ selected: {
21
+ control: "text";
22
+ description: string;
23
+ };
24
+ disabled: {
25
+ control: "boolean";
26
+ description: string;
27
+ };
28
+ id: {
29
+ control: "text";
30
+ description: string;
31
+ };
32
+ onselect: {
33
+ action: string;
34
+ description: string;
35
+ };
36
+ };
37
+ };
38
+ export default meta;
39
+ type Story = StoryObj<typeof meta>;
40
+ export declare const Default: Story;
41
+ export declare const WithoutSelection: Story;
42
+ export declare const Disabled: Story;
43
+ export declare const LongLabels: Story;
44
+ export declare const ManyOptions: Story;
45
+ export declare const Interactive: Story;
@@ -1,13 +1,13 @@
1
1
  <script lang="ts">
2
- interface Props {
3
- id?: string;
4
- buttons?: { name: string; value: string }[];
5
- selected?: string;
6
- disabled?: boolean;
7
- onselect?: (value: string) => void;
8
- }
2
+ import type { ButtonGroupProps } from './types.js';
9
3
 
10
- let { id, buttons = [], selected = $bindable(), disabled = false, onselect }: Props = $props();
4
+ let {
5
+ id,
6
+ buttons = [],
7
+ selected = $bindable(),
8
+ disabled = false,
9
+ onselect
10
+ }: ButtonGroupProps = $props();
11
11
 
12
12
  /**
13
13
  * Sets selected value and dispatches the select event.
@@ -1,13 +1,4 @@
1
- interface Props {
2
- id?: string;
3
- buttons?: {
4
- name: string;
5
- value: string;
6
- }[];
7
- selected?: string;
8
- disabled?: boolean;
9
- onselect?: (value: string) => void;
10
- }
11
- declare const ButtonGroup: import("svelte").Component<Props, {}, "selected">;
1
+ import type { ButtonGroupProps } from './types.js';
2
+ declare const ButtonGroup: import("svelte").Component<ButtonGroupProps, {}, "selected">;
12
3
  type ButtonGroup = ReturnType<typeof ButtonGroup>;
13
4
  export default ButtonGroup;
@@ -1,7 +1,6 @@
1
1
  <script lang="ts">
2
- import ClipboardJS from 'clipboard';
2
+ import copy from 'copy-text-to-clipboard';
3
3
  import type { Snippet } from 'svelte';
4
- import { onDestroy } from 'svelte';
5
4
  import type { HTMLAttributes } from 'svelte/elements';
6
5
 
7
6
  import { CopyIcon, EyeIcon } from '../../icons';
@@ -30,7 +29,6 @@
30
29
  let isCopied = $state(false);
31
30
  let isCooldown = $state(false);
32
31
  let copyButtonElement: HTMLDivElement | undefined = $state();
33
- let clipboard: ClipboardJS | null = null;
34
32
 
35
33
  function getProcessedContent() {
36
34
  if (raw) {
@@ -63,50 +61,45 @@
63
61
  }
64
62
  };
65
63
 
66
- // Initialize ClipboardJS when the element is available and not disabled
67
- $effect(() => {
68
- // Cleanup previous instance
69
- clipboard?.destroy();
70
- clipboard = null;
71
-
72
- if (copyButtonElement && !disabled) {
73
- clipboard = new ClipboardJS(copyButtonElement, {
74
- text: () => {
75
- if (disabled) {
76
- const errorMessage = 'Copy is disabled';
77
- handleNotification('Error', errorMessage);
78
- onError?.(errorMessage);
79
- return '';
80
- }
81
-
82
- return getProcessedContent();
83
- }
84
- });
85
-
86
- clipboard.on('success', (e) => {
87
- const copiedText = getProcessedContent();
88
- isCopied = true;
89
- handleNotification('Success', 'Copied to clipboard!');
90
- onCopy?.(copiedText);
91
- e.clearSelection();
92
-
93
- // Reset copied state after 2 seconds
94
- setTimeout(() => {
95
- isCopied = false;
96
- }, 2000);
97
- });
98
-
99
- clipboard.on('error', () => {
100
- const errorMessage = 'Failed to copy. Please try again.';
101
- handleNotification('Error', errorMessage);
102
- onError?.(errorMessage);
103
- });
64
+ /**
65
+ * Handles copying text to clipboard
66
+ */
67
+ const handleCopy = () => {
68
+ if (disabled) {
69
+ const errorMessage = 'Copy is disabled';
70
+ handleNotification('Error', errorMessage);
71
+ onError?.(errorMessage);
72
+ return;
73
+ }
74
+
75
+ const contentToCopy = getProcessedContent();
76
+ const success = copy(contentToCopy);
77
+
78
+ if (success) {
79
+ isCopied = true;
80
+ handleNotification('Success', 'Copied to clipboard!');
81
+ onCopy?.(contentToCopy);
82
+
83
+ // Reset copied state after 2 seconds
84
+ setTimeout(() => {
85
+ isCopied = false;
86
+ }, 2000);
87
+ } else {
88
+ const errorMessage = 'Failed to copy. Please try again.';
89
+ handleNotification('Error', errorMessage);
90
+ onError?.(errorMessage);
104
91
  }
105
- });
92
+ };
106
93
 
107
- onDestroy(() => {
108
- clipboard?.destroy();
109
- });
94
+ /**
95
+ * Handle keyboard events for accessibility
96
+ */
97
+ const handleKeydown = (event: KeyboardEvent) => {
98
+ if (event.key === 'Enter' || event.key === ' ') {
99
+ event.preventDefault();
100
+ handleCopy();
101
+ }
102
+ };
110
103
  </script>
111
104
 
112
105
  {#if !hidden}
@@ -128,6 +121,8 @@
128
121
  tabindex="0"
129
122
  aria-label={disabled ? 'Copy disabled' : tooltip}
130
123
  title={tooltip}
124
+ onclick={handleCopy}
125
+ onkeydown={handleKeydown}
131
126
  >
132
127
  <div class="copy-button__content" id="copy-content">
133
128
  {getProcessedContent()}
@@ -32,7 +32,7 @@
32
32
  },
33
33
  scrollable: {
34
34
  control: 'boolean',
35
- description: 'Enable scrollable content with OverlayScrollbars'
35
+ description: 'Enable scrollable content with native browser scrollbars'
36
36
  },
37
37
  class: {
38
38
  control: 'text',
@@ -1,9 +1,4 @@
1
1
  <script lang="ts">
2
- import 'overlayscrollbars/overlayscrollbars.css';
3
-
4
- import type { PartialOptions } from 'overlayscrollbars';
5
- import { OverlayScrollbarsComponent } from 'overlayscrollbars-svelte';
6
-
7
2
  import { WarningCircleOutlineIcon } from '../../icons';
8
3
  import { Tooltip } from '../tooltip';
9
4
  import type { SectionProps } from './types.js';
@@ -128,20 +123,6 @@
128
123
  disabledMessage ||
129
124
  `This option is disabled in edit mode. If you want to change it, please generate a new Component.`
130
125
  );
131
-
132
- // OverlayScrollbars options
133
- let overlayScrollbarsOptions: PartialOptions = {
134
- overflow: {
135
- x: 'hidden',
136
- y: 'scroll'
137
- },
138
- scrollbars: {
139
- theme: 'os-theme-dark',
140
- visibility: 'auto',
141
- autoHide: 'leave',
142
- autoHideDelay: 800
143
- }
144
- };
145
126
  </script>
146
127
 
147
128
  {#snippet sectionContent()}
@@ -166,11 +147,11 @@
166
147
  {...restProps}
167
148
  >
168
149
  {#if scrollable}
169
- <OverlayScrollbarsComponent options={overlayScrollbarsOptions} defer>
150
+ <div class="scrollable-content">
170
151
  {#if children}
171
152
  {@render children()}
172
153
  {/if}
173
- </OverlayScrollbarsComponent>
154
+ </div>
174
155
  {:else if children}
175
156
  {@render children()}
176
157
  {/if}
@@ -290,38 +271,19 @@
290
271
  transform: none !important;
291
272
  }
292
273
 
293
- .section-wrap.scrollable :global([data-overlayscrollbars-initialize]) {
294
- width: 100% !important;
295
- height: 100% !important;
296
- }
297
-
298
274
  /* Scrollable content styles */
299
275
  .section-wrap.scrollable {
300
- overflow: hidden; /* Let OverlayScrollbars handle the overflow */
301
- }
302
-
303
- /* OverlayScrollbars dark theme customization using design system */
304
- .section-wrap :global(.os-scrollbar) {
305
- --os-size: var(--sb-size);
306
- --os-padding-perpendicular: 2px;
307
- --os-padding-axis: 2px;
276
+ overflow: hidden; /* Parent container hides overflow */
308
277
  }
309
278
 
310
- .section-wrap :global(.os-scrollbar-track) {
311
- background: var(--sb-track-color);
312
- border-radius: 4px;
313
- }
314
-
315
- .section-wrap :global(.os-scrollbar-handle) {
316
- background: var(--sb-thumb-color);
317
- border-radius: 4px;
318
- }
319
-
320
- .section-wrap :global(.os-scrollbar-handle:hover) {
321
- background: var(--background3);
322
- }
323
-
324
- .section-wrap :global(.os-scrollbar-handle:active) {
325
- background: var(--background2);
279
+ .section-wrap.scrollable .scrollable-content {
280
+ width: 100%;
281
+ height: 100%;
282
+ overflow-y: auto;
283
+ overflow-x: hidden;
284
+ /* Enable smooth scrolling */
285
+ scroll-behavior: smooth;
286
+ /* Add scrollbar gutter for consistent layout */
287
+ scrollbar-gutter: stable;
326
288
  }
327
289
  </style>
@@ -1,4 +1,3 @@
1
- import 'overlayscrollbars/overlayscrollbars.css';
2
1
  import type { SectionProps } from './types.js';
3
2
  declare const Section: import("svelte").Component<SectionProps, {}, "">;
4
3
  type Section = ReturnType<typeof Section>;
@@ -1,12 +1,12 @@
1
- export default CmsIcon;
2
- type CmsIcon = SvelteComponent<{
1
+ export default CMSIcon;
2
+ type CMSIcon = SvelteComponent<{
3
3
  [x: string]: never;
4
4
  }, {
5
5
  [evt: string]: CustomEvent<any>;
6
6
  }, {}> & {
7
7
  $$bindings?: string | undefined;
8
8
  };
9
- declare const CmsIcon: $$__sveltets_2_IsomorphicComponent<{
9
+ declare const CMSIcon: $$__sveltets_2_IsomorphicComponent<{
10
10
  [x: string]: never;
11
11
  }, {
12
12
  [evt: string]: CustomEvent<any>;
@@ -1,5 +1,5 @@
1
- export default DomElement;
2
- type DomElement = SvelteComponent<{
1
+ export default DOMElement;
2
+ type DOMElement = SvelteComponent<{
3
3
  width?: number | undefined;
4
4
  height?: number | undefined;
5
5
  }, {
@@ -7,7 +7,7 @@ type DomElement = SvelteComponent<{
7
7
  }, {}> & {
8
8
  $$bindings?: string | undefined;
9
9
  };
10
- declare const DomElement: $$__sveltets_2_IsomorphicComponent<{
10
+ declare const DOMElement: $$__sveltets_2_IsomorphicComponent<{
11
11
  width?: number | undefined;
12
12
  height?: number | undefined;
13
13
  }, {
@@ -11,11 +11,11 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
11
11
  };
12
12
  z_$$bindings?: Bindings;
13
13
  }
14
- declare const Xl: $$__sveltets_2_IsomorphicComponent<{
14
+ declare const XL: $$__sveltets_2_IsomorphicComponent<{
15
15
  width?: number;
16
16
  height?: number;
17
17
  }, {
18
18
  [evt: string]: CustomEvent<any>;
19
19
  }, {}, {}, string>;
20
- type Xl = InstanceType<typeof Xl>;
21
- export default Xl;
20
+ type XL = InstanceType<typeof XL>;
21
+ export default XL;
@@ -11,11 +11,11 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
11
11
  };
12
12
  z_$$bindings?: Bindings;
13
13
  }
14
- declare const Xxl: $$__sveltets_2_IsomorphicComponent<{
14
+ declare const XXL: $$__sveltets_2_IsomorphicComponent<{
15
15
  width?: number;
16
16
  height?: number;
17
17
  }, {
18
18
  [evt: string]: CustomEvent<any>;
19
19
  }, {}, {}, string>;
20
- type Xxl = InstanceType<typeof Xxl>;
21
- export default Xxl;
20
+ type XXL = InstanceType<typeof XXL>;
21
+ export default XXL;
@@ -11,11 +11,11 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
11
11
  };
12
12
  z_$$bindings?: Bindings;
13
13
  }
14
- declare const Xxxl: $$__sveltets_2_IsomorphicComponent<{
14
+ declare const XXXL: $$__sveltets_2_IsomorphicComponent<{
15
15
  width?: number;
16
16
  height?: number;
17
17
  }, {
18
18
  [evt: string]: CustomEvent<any>;
19
19
  }, {}, {}, string>;
20
- type Xxxl = InstanceType<typeof Xxxl>;
21
- export default Xxxl;
20
+ type XXXL = InstanceType<typeof XXXL>;
21
+ export default XXXL;
package/dist/ui/index.css CHANGED
@@ -4,7 +4,7 @@
4
4
  /* custom scrollbar related */
5
5
  --sb-track-color: #1e1e1e;
6
6
  --sb-thumb-color: #373737;
7
- --sb-size: 8px;
7
+ --sb-size: 6px;
8
8
 
9
9
  /* Webflow colors */
10
10
  --background1: #292929;
@@ -272,41 +272,6 @@ label {
272
272
  .not-allowed {
273
273
  cursor: not-allowed !important;
274
274
  }
275
- /* OverlayScrollbars Global Theme */
276
- :root {
277
- /* OverlayScrollbars theme variables using design system colors */
278
- --os-size: var(--sb-size, 6px);
279
- --os-padding-perpendicular: 0px;
280
- --os-padding-axis: 0px;
281
- --os-track-bg: var(--background1);
282
- --os-handle-bg: var(--background4);
283
- --os-handle-bg-hover: var(--background3);
284
- --os-handle-bg-active: var(--background2);
285
- }
286
-
287
- /* OverlayScrollbars global dark theme */
288
- .os-theme-dark .os-scrollbar {
289
- --os-size: var(--sb-size, 6px);
290
- }
291
-
292
- .os-theme-dark .os-scrollbar-track {
293
- background: var(--background1);
294
- border-radius: 4px;
295
- }
296
-
297
- .os-theme-dark .os-scrollbar-handle {
298
- background: var(--background4);
299
- border-radius: 4px;
300
- transition: background-color 0.2s ease;
301
- }
302
-
303
- .os-theme-dark .os-scrollbar-handle:hover {
304
- background: var(--background3);
305
- }
306
-
307
- .os-theme-dark .os-scrollbar-handle:active {
308
- background: var(--background2);
309
- }
310
275
 
311
276
  input {
312
277
  /* Remove default appearance for some browsers */
@@ -503,8 +468,9 @@ input::-webkit-inner-spin-button {
503
468
  align-self: stretch;
504
469
  }
505
470
 
506
- /* Pure CSS Scrollbar */
471
+ /* Modern Native Scrollbar Styles */
507
472
 
473
+ /* Webkit browsers (Chrome, Safari, Edge) */
508
474
  ::-webkit-scrollbar {
509
475
  width: var(--sb-size);
510
476
  height: var(--sb-size);
@@ -518,10 +484,33 @@ input::-webkit-inner-spin-button {
518
484
  ::-webkit-scrollbar-thumb {
519
485
  background: var(--sb-thumb-color);
520
486
  border-radius: 4px;
487
+ transition: background-color 0.2s ease;
488
+ }
489
+
490
+ ::-webkit-scrollbar-thumb:hover {
491
+ background: var(--background3);
492
+ }
493
+
494
+ ::-webkit-scrollbar-thumb:active {
495
+ background: var(--background2);
496
+ }
497
+
498
+ ::-webkit-scrollbar-corner {
499
+ background: var(--sb-track-color);
500
+ }
501
+
502
+ /* Firefox scrollbar styling */
503
+ @supports selector(::-moz-scrollbar-thumb) {
504
+ * {
505
+ scrollbar-color: var(--sb-thumb-color) var(--sb-track-color);
506
+ scrollbar-width: thin;
507
+ }
521
508
  }
522
509
 
510
+ /* Fallback for Firefox without newer scrollbar support */
523
511
  @supports not selector(::-webkit-scrollbar) {
524
- body {
512
+ html {
525
513
  scrollbar-color: var(--sb-thumb-color) var(--sb-track-color);
514
+ scrollbar-width: thin;
526
515
  }
527
516
  }
@@ -1,3 +1,4 @@
1
+ /* eslint-disable svelte/prefer-svelte-reactivity */
1
2
  import { getContext, setContext } from 'svelte';
2
3
  import { createDebouncedUpdate, hasConfiguratorChanged, validateWatchOptions } from './configuratorUtils';
3
4
  const GLOBAL_CONTEXT_KEY = Symbol('global-context');
@@ -1,3 +1,4 @@
1
+ /* eslint-disable svelte/prefer-svelte-reactivity */
1
2
  import { getContext } from 'svelte';
2
3
  /**
3
4
  * Get the router instance from context
@@ -1,3 +1,4 @@
1
+ /* eslint-disable svelte/prefer-svelte-reactivity */
1
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
3
  import { routerStore } from '../../utils/stores';
3
4
  /**
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Copies the provided text to the clipboard.
3
+ */
4
+ export declare const copyText: (text: string) => boolean;
@@ -0,0 +1,7 @@
1
+ import copy from 'copy-text-to-clipboard';
2
+ /**
3
+ * Copies the provided text to the clipboard.
4
+ */
5
+ export const copyText = (text) => {
6
+ return copy(text);
7
+ };
@@ -1,3 +1,4 @@
1
+ export * from './copy';
1
2
  export * from './diff-mapper';
2
3
  export * from './helpers';
3
4
  export * from './color-utils';
@@ -1,3 +1,4 @@
1
+ export * from './copy';
1
2
  export * from './diff-mapper';
2
3
  export * from './helpers';
3
4
  export * from './color-utils';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finsweet/webflow-apps-utils",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "Shared utilities for Webflow apps",
5
5
  "homepage": "https://github.com/finsweet/webflow-apps-utils",
6
6
  "repository": {
@@ -87,7 +87,7 @@
87
87
  "dependencies": {
88
88
  "@floating-ui/dom": "^1.7.1",
89
89
  "cheerio": "^1.1.0",
90
- "clipboard": "^2.0.11",
90
+ "copy-text-to-clipboard": "^3.2.2",
91
91
  "csv-parse": "^5.6.0",
92
92
  "js-cookie": "^3.0.5",
93
93
  "just-debounce": "^1.1.0",
@@ -96,8 +96,6 @@
96
96
  "logrocket": "^10.1.0",
97
97
  "luxon": "^3.6.1",
98
98
  "motion": "^10.18.0",
99
- "overlayscrollbars": "^2.11.4",
100
- "overlayscrollbars-svelte": "^0.5.5",
101
99
  "svelte-routing": "^2.13.0",
102
100
  "swiper": "^11.2.8",
103
101
  "terser": "^5.43.1",