@finsweet/webflow-apps-utils 1.0.9 → 1.0.11

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.
@@ -10,10 +10,14 @@
10
10
  export let raw = false;
11
11
  export let backgroundColor = 'rgba(30, 30, 30, 0.96)';
12
12
  export let spinnerSize = 50;
13
+ export let className: string = '';
13
14
  </script>
14
15
 
15
16
  {#if active}
16
- <div class="loading-screen" style="position:{position}; background-color: {backgroundColor};">
17
+ <div
18
+ class="main-loader {className}"
19
+ style="position:{position}; background-color: {backgroundColor};"
20
+ >
17
21
  <div class="loading-info {error ? 'error' : ''}">
18
22
  {#if error}
19
23
  <WarningTriangleOutlineIcon />
@@ -32,7 +36,7 @@
32
36
  {/if}
33
37
 
34
38
  <style>
35
- .loading-screen {
39
+ .main-loader {
36
40
  top: 0;
37
41
  bottom: 0;
38
42
  left: 0;
@@ -19,6 +19,7 @@ declare const LoadingScreen: $$__sveltets_2_IsomorphicComponent<{
19
19
  raw?: boolean;
20
20
  backgroundColor?: string;
21
21
  spinnerSize?: number;
22
+ className?: string;
22
23
  }, {
23
24
  [evt: string]: CustomEvent<any>;
24
25
  }, {}, {}, string>;
@@ -31,7 +31,7 @@
31
31
  <Switch {disabled} bind:checked={enabled} onchange={handleSwitchChange} />
32
32
  </div>
33
33
 
34
- <div class="content" style="display: {enabled ? 'flex' : 'none'}">
34
+ <div class="breakpoint-content" style="display: {enabled ? 'flex' : 'none'}">
35
35
  <slot />
36
36
  </div>
37
37
  </div>
@@ -46,7 +46,7 @@
46
46
  gap: var(--Spacing-8, 8px);
47
47
  align-self: stretch;
48
48
  }
49
- .content {
49
+ .breakpoint-content {
50
50
  display: flex;
51
51
  flex-direction: column;
52
52
  align-items: flex-start;
@@ -0,0 +1,42 @@
1
+ <script module lang="ts">
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import { fn } from 'storybook/test';
4
+
5
+ import ColorPicker from './ColorPicker.svelte';
6
+
7
+ let controlledColor = $state('#00ff00');
8
+ const handleChange = (color: string) => (controlledColor = color);
9
+
10
+ const { Story } = defineMeta({
11
+ title: 'UI/ColorPicker',
12
+ component: ColorPicker,
13
+ tags: ['autodocs'],
14
+ argTypes: {
15
+ color: {
16
+ control: { type: 'color' },
17
+ description: 'Selected color (hex string or writable store)'
18
+ },
19
+ onchange: { action: 'colorChanged' }
20
+ },
21
+ parameters: {
22
+ layout: 'centered',
23
+ viewport: {
24
+ defaultViewport: 'responsive'
25
+ }
26
+ },
27
+ args: {
28
+ color: '#ff0000',
29
+ onchange: fn()
30
+ }
31
+ });
32
+ </script>
33
+
34
+ <Story name="Default" args={{}} />
35
+
36
+ <Story name="With Initial Color" args={{ color: '#00ff00' }} />
37
+
38
+ <Story name="Store Controlled" args={{ color: controlledColor, onchange: handleChange }} />
39
+
40
+ <Story name="Edge: Invalid Color" args={{ color: '#xyzxyz' }} />
41
+
42
+ <Story name="Edge: No Color" args={{ color: undefined }} />
@@ -0,0 +1,19 @@
1
+ import ColorPicker from './ColorPicker.svelte';
2
+ 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> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const ColorPicker: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
16
+ [evt: string]: CustomEvent<any>;
17
+ }, {}, {}, string>;
18
+ type ColorPicker = InstanceType<typeof ColorPicker>;
19
+ export default ColorPicker;
@@ -0,0 +1,155 @@
1
+ <script lang="ts">
2
+ import Tooltip from '../tooltip/Tooltip.svelte';
3
+ import ColorSelect from './ColorSelect.svelte';
4
+
5
+ let {
6
+ color = $bindable('#fff'),
7
+ onchange,
8
+ width = '80px'
9
+ } = $props<{
10
+ color?: string;
11
+ onchange?: (color: string) => void;
12
+ width?: string;
13
+ }>();
14
+
15
+ function normalizeHex(value: string): string {
16
+ let v = value.trim();
17
+
18
+ if (!v.startsWith('#')) v = `#${v}`;
19
+
20
+ return v.toUpperCase();
21
+ }
22
+
23
+ function isValidColor(value: string): boolean {
24
+ const hexRegex = /^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/;
25
+ return hexRegex.test(value.startsWith('#') ? value.slice(1) : value);
26
+ }
27
+
28
+ function handleInputPaste(event: ClipboardEvent) {
29
+ event.preventDefault();
30
+
31
+ const pastedText = event.clipboardData?.getData('text') || '';
32
+ let cleanText = pastedText.replace(/[^0-9A-Fa-f#]/g, '');
33
+ if (!cleanText.startsWith('#')) cleanText = '#' + cleanText;
34
+
35
+ cleanText = cleanText.substring(0, 9);
36
+
37
+ if (isValidColor(cleanText)) {
38
+ const normalizedValue = normalizeHex(cleanText);
39
+ color = normalizedValue;
40
+ onchange?.(normalizedValue);
41
+ }
42
+ }
43
+
44
+ function handleInputChange(event: Event) {
45
+ const target = event.target as HTMLInputElement;
46
+ const value = target.value.trim();
47
+
48
+ if (isValidColor(value)) {
49
+ const normalizedValue = normalizeHex(value);
50
+
51
+ color = normalizedValue;
52
+
53
+ onchange?.(normalizedValue);
54
+ }
55
+ }
56
+
57
+ function handleInputKeydown(event: KeyboardEvent) {
58
+ if (event.key === 'Enter') {
59
+ (event.target as HTMLInputElement).blur();
60
+ }
61
+ }
62
+
63
+ function handleColorChange(newColor: string) {
64
+ const normalizedValue = normalizeHex(newColor);
65
+
66
+ color = normalizedValue;
67
+ onchange?.(normalizedValue);
68
+ }
69
+ </script>
70
+
71
+ <div class="color-picker">
72
+ <Tooltip
73
+ listener="click"
74
+ listenerout="click"
75
+ showArrow={false}
76
+ padding="0"
77
+ stopPropagation={true}
78
+ width="241px"
79
+ placement="bottom"
80
+ fallbackPlacements={['top-end', 'top', 'bottom-end', 'bottom', 'top-start', 'bottom-start']}
81
+ >
82
+ {#snippet target()}
83
+ <div class="color-picker__swatch" data-testid="color-swatch">
84
+ <div class="color-swatch" style="background-color: {color || '#000000'}"></div>
85
+ </div>
86
+ {/snippet}
87
+ {#snippet tooltipContent()}
88
+ <ColorSelect {color} onchange={handleColorChange} />
89
+ {/snippet}
90
+ </Tooltip>
91
+
92
+ <input
93
+ type="text"
94
+ class="color-picker__input"
95
+ bind:value={color}
96
+ oninput={handleInputChange}
97
+ onkeydown={handleInputKeydown}
98
+ onpaste={handleInputPaste}
99
+ placeholder="#ffffff"
100
+ aria-label="Color hex value"
101
+ style="width: {width}"
102
+ />
103
+ </div>
104
+
105
+ <style>
106
+ .color-picker {
107
+ display: flex;
108
+ align-items: center;
109
+ gap: 4px;
110
+ height: 24px;
111
+ border: 1px solid var(--border1);
112
+ border-radius: 4px;
113
+ overflow: hidden;
114
+ background: var(--background1);
115
+ box-shadow:
116
+ 0px 16px 16px -16px rgba(0, 0, 0, 0.13) inset,
117
+ 0px 12px 12px -12px rgba(0, 0, 0, 0.13) inset,
118
+ 0px 8px 8px -8px rgba(0, 0, 0, 0.17) inset,
119
+ 0px 4px 4px -4px rgba(0, 0, 0, 0.17) inset,
120
+ 0px 3px 3px -3px rgba(0, 0, 0, 0.17) inset,
121
+ 0px 1px 1px -1px rgba(0, 0, 0, 0.13) inset;
122
+ }
123
+
124
+ .color-picker__swatch {
125
+ position: relative;
126
+ width: 24px;
127
+ height: 24px;
128
+ overflow: hidden;
129
+ cursor: pointer;
130
+ }
131
+
132
+ .color-swatch {
133
+ width: 100%;
134
+ height: 100%;
135
+ }
136
+
137
+ .color-picker__input {
138
+ width: 80px;
139
+ padding: 4px 8px 4px 0px;
140
+ border-radius: 4px;
141
+ font-family: monospace;
142
+ font-size: 12px;
143
+ border: none;
144
+ background: transparent;
145
+ }
146
+
147
+ .color-picker:has(.color-picker__input:focus) {
148
+ outline: none;
149
+ border-color: var(--blueBorder);
150
+ }
151
+
152
+ .color-picker:global(:has(.tooltip[aria-hidden='false'])) {
153
+ border-color: var(--blueBorder);
154
+ }
155
+ </style>
@@ -0,0 +1,8 @@
1
+ type $$ComponentProps = {
2
+ color?: string;
3
+ onchange?: (color: string) => void;
4
+ width?: string;
5
+ };
6
+ declare const ColorPicker: import("svelte").Component<$$ComponentProps, {}, "color">;
7
+ type ColorPicker = ReturnType<typeof ColorPicker>;
8
+ export default ColorPicker;
@@ -0,0 +1,61 @@
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import { fn } from 'storybook/test';
4
+
5
+ import ColorSelect from './ColorSelect.svelte';
6
+
7
+ const { Story } = defineMeta({
8
+ title: 'UI/ColorSelect',
9
+ component: ColorSelect,
10
+ tags: ['autodocs'],
11
+ argTypes: {
12
+ color: {
13
+ control: { type: 'color' },
14
+ description: 'Initial color value (hex)'
15
+ },
16
+ onchange: { action: 'colorChanged' }
17
+ },
18
+ args: {
19
+ color: '#ff0000',
20
+ onchange: fn()
21
+ }
22
+ });
23
+ </script>
24
+
25
+ <Story name="Default" args={{}} />
26
+
27
+ <Story name="With Initial Color" args={{ color: '#00ff00' }} />
28
+
29
+ <Story
30
+ name="Alpha Channel"
31
+ args={{ color: '#0000ff' }}
32
+ story={{
33
+ parameters: {
34
+ docs: { description: { story: 'Shows alpha slider and allows changing opacity.' } }
35
+ }
36
+ }}
37
+ />
38
+
39
+ <Story
40
+ name="HSB/RGB Toggle"
41
+ args={{ color: '#ff00ff' }}
42
+ story={{
43
+ parameters: {
44
+ docs: { description: { story: 'Toggle between HSB and RGB modes using the mode switch.' } }
45
+ }
46
+ }}
47
+ />
48
+
49
+ <Story
50
+ name="With EyeDropper"
51
+ args={{ color: '#123456' }}
52
+ story={{
53
+ parameters: {
54
+ docs: {
55
+ description: {
56
+ story: 'Use the EyeDropper button to pick a color from the screen (if supported).'
57
+ }
58
+ }
59
+ }
60
+ }}
61
+ />
@@ -0,0 +1,27 @@
1
+ export default ColorSelect;
2
+ type ColorSelect = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const ColorSelect: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ import ColorSelect from './ColorSelect.svelte';
15
+ 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> {
16
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
17
+ $$bindings?: Bindings;
18
+ } & Exports;
19
+ (internal: unknown, props: {
20
+ $$events?: Events;
21
+ $$slots?: Slots;
22
+ }): Exports & {
23
+ $set?: any;
24
+ $on?: any;
25
+ };
26
+ z_$$bindings?: Bindings;
27
+ }