@widgetic/editor 4.0.6 → 4.0.8
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.
- package/README.md +12 -1
- package/dist/components/WidgetPreview.svelte +42 -1
- package/dist/components/WidgetPreview.svelte.d.ts +8 -0
- package/dist/components/editors/EmbedEditor.svelte +101 -530
- package/dist/components/editors/EmbedEditor.svelte.d.ts +7 -17
- package/dist/components/editors/PropsEditor.svelte +328 -142
- package/dist/components/editors/PropsEditor.svelte.d.ts +13 -2
- package/dist/components/ic/AngleInputController.svelte +21 -7
- package/dist/components/ic/AngleInputController.svelte.d.ts +16 -6
- package/dist/components/ic/BrowserInputController.svelte +28 -15
- package/dist/components/ic/BrowserInputController.svelte.d.ts +25 -19
- package/dist/components/ic/CheckboxInputController.svelte +21 -7
- package/dist/components/ic/CheckboxInputController.svelte.d.ts +25 -15
- package/dist/components/ic/ColorPickerInputController.svelte +47 -21
- package/dist/components/ic/ColorPickerInputController.svelte.d.ts +42 -19
- package/dist/components/ic/DateFieldInputController.svelte +21 -7
- package/dist/components/ic/DateFieldInputController.svelte.d.ts +24 -14
- package/dist/components/ic/DatePickerInputController.svelte +25 -8
- package/dist/components/ic/DatePickerInputController.svelte.d.ts +21 -8
- package/dist/components/ic/DropdownInputController.svelte +69 -19
- package/dist/components/ic/DropdownInputController.svelte.d.ts +33 -17
- package/dist/components/ic/FixedPositionInputController.svelte +24 -10
- package/dist/components/ic/FixedPositionInputController.svelte.d.ts +16 -4
- package/dist/components/ic/FontInputController.svelte +53 -18
- package/dist/components/ic/FontInputController.svelte.d.ts +33 -18
- package/dist/components/ic/InputControllerRenderer.svelte +98 -0
- package/dist/components/ic/InputControllerRenderer.svelte.d.ts +40 -0
- package/dist/components/ic/NumberInputController.svelte +23 -9
- package/dist/components/ic/NumberInputController.svelte.d.ts +18 -7
- package/dist/components/ic/PositionInputController.svelte +17 -5
- package/dist/components/ic/PositionInputController.svelte.d.ts +20 -11
- package/dist/components/ic/RadioGroupInputController.svelte +21 -7
- package/dist/components/ic/RadioGroupInputController.svelte.d.ts +22 -12
- package/dist/components/ic/RangeCalendarInputController.svelte +34 -16
- package/dist/components/ic/RangeCalendarInputController.svelte.d.ts +25 -11
- package/dist/components/ic/RoundedCornersInputController.svelte +26 -22
- package/dist/components/ic/RoundedCornersInputController.svelte.d.ts +26 -18
- package/dist/components/ic/SliderInputController.svelte +41 -18
- package/dist/components/ic/SliderInputController.svelte.d.ts +35 -19
- package/dist/components/ic/SliderRangeInputController.svelte +27 -11
- package/dist/components/ic/SliderRangeInputController.svelte.d.ts +22 -9
- package/dist/components/ic/SwitchInputController.svelte +17 -5
- package/dist/components/ic/SwitchInputController.svelte.d.ts +14 -5
- package/dist/components/ic/TagsInputController.svelte +21 -7
- package/dist/components/ic/TagsInputController.svelte.d.ts +16 -6
- package/dist/components/ic/TextAreaInputController.svelte +44 -25
- package/dist/components/ic/TextAreaInputController.svelte.d.ts +6 -4
- package/dist/components/ic/TextAreaPreviewInputController.svelte +21 -7
- package/dist/components/ic/TextAreaPreviewInputController.svelte.d.ts +16 -6
- package/dist/components/ic/TextInputController.svelte +23 -8
- package/dist/components/ic/TextInputController.svelte.d.ts +20 -8
- package/dist/components/ic/TimeInputController.svelte +17 -5
- package/dist/components/ic/TimeInputController.svelte.d.ts +14 -5
- package/dist/components/ic/VectorInputController.svelte +29 -10
- package/dist/components/ic/VectorInputController.svelte.d.ts +33 -18
- package/dist/components/icons/locked.svelte +5 -1
- package/dist/components/icons/locked.svelte.d.ts +11 -24
- package/dist/components/icons/unlocked.svelte +5 -1
- package/dist/components/icons/unlocked.svelte.d.ts +11 -24
- package/dist/index.d.ts +1 -0
- package/dist/schemaViews.d.ts +105 -0
- package/dist/schemaViews.js +11 -0
- package/dist/utils/FontManager.js +11 -4
- package/package.json +16 -12
|
@@ -17,6 +17,23 @@
|
|
|
17
17
|
* - Maintains dropdown state consistency
|
|
18
18
|
-->
|
|
19
19
|
|
|
20
|
+
<script module lang="ts">
|
|
21
|
+
import type { Writable } from 'svelte/store';
|
|
22
|
+
|
|
23
|
+
/** Declared props contract — export lets below are annotated from it so the
|
|
24
|
+
* interface cannot drift from what the component actually reads. */
|
|
25
|
+
export interface DatePickerInputControllerProps {
|
|
26
|
+
label: string;
|
|
27
|
+
value?: any;
|
|
28
|
+
onChange: (newValue: CalendarDate) => void;
|
|
29
|
+
description?: string;
|
|
30
|
+
controllerId: string;
|
|
31
|
+
openDropdowns: Writable<Set<string>>;
|
|
32
|
+
toggleDropdown: (id: string) => void;
|
|
33
|
+
onFocus?: () => void;
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
20
37
|
<script lang="ts">
|
|
21
38
|
// Svelte imports
|
|
22
39
|
import { onMount, onDestroy } from 'svelte';
|
|
@@ -35,14 +52,14 @@
|
|
|
35
52
|
import { IconCalendar } from '@widgetic/design-system/icons';
|
|
36
53
|
|
|
37
54
|
// Component props with TypeScript types
|
|
38
|
-
export let label:
|
|
39
|
-
export let value:
|
|
40
|
-
export let onChange:
|
|
41
|
-
export let description:
|
|
42
|
-
export let controllerId:
|
|
43
|
-
export let openDropdowns:
|
|
44
|
-
export let toggleDropdown:
|
|
45
|
-
export let onFocus:
|
|
55
|
+
export let label: DatePickerInputControllerProps['label'];
|
|
56
|
+
export let value: DatePickerInputControllerProps['value'];
|
|
57
|
+
export let onChange: DatePickerInputControllerProps['onChange'];
|
|
58
|
+
export let description: DatePickerInputControllerProps['description'] = undefined;
|
|
59
|
+
export let controllerId: DatePickerInputControllerProps['controllerId'];
|
|
60
|
+
export let openDropdowns: DatePickerInputControllerProps['openDropdowns'];
|
|
61
|
+
export let toggleDropdown: DatePickerInputControllerProps['toggleDropdown'];
|
|
62
|
+
export let onFocus: DatePickerInputControllerProps['onFocus'] = () => {};
|
|
46
63
|
|
|
47
64
|
// Default to today's date in local timezone for placeholder
|
|
48
65
|
let placeholder = today(getLocalTimeZone());
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
import type { Writable } from 'svelte/store';
|
|
2
|
+
/** Declared props contract — export lets below are annotated from it so the
|
|
3
|
+
* interface cannot drift from what the component actually reads. */
|
|
4
|
+
export interface DatePickerInputControllerProps {
|
|
5
|
+
label: string;
|
|
6
|
+
value?: any;
|
|
7
|
+
onChange: (newValue: CalendarDate) => void;
|
|
8
|
+
description?: string;
|
|
9
|
+
controllerId: string;
|
|
10
|
+
openDropdowns: Writable<Set<string>>;
|
|
11
|
+
toggleDropdown: (id: string) => void;
|
|
12
|
+
onFocus?: () => void;
|
|
13
|
+
}
|
|
1
14
|
import { CalendarDate } from "@internationalized/date";
|
|
2
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> {
|
|
3
16
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
@@ -13,14 +26,14 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
|
|
|
13
26
|
z_$$bindings?: Bindings;
|
|
14
27
|
}
|
|
15
28
|
declare const DatePickerInputController: $$__sveltets_2_IsomorphicComponent<{
|
|
16
|
-
label:
|
|
17
|
-
value:
|
|
18
|
-
onChange:
|
|
19
|
-
description?:
|
|
20
|
-
controllerId:
|
|
21
|
-
openDropdowns:
|
|
22
|
-
toggleDropdown:
|
|
23
|
-
onFocus?:
|
|
29
|
+
label: DatePickerInputControllerProps["label"];
|
|
30
|
+
value: DatePickerInputControllerProps["value"];
|
|
31
|
+
onChange: DatePickerInputControllerProps["onChange"];
|
|
32
|
+
description?: DatePickerInputControllerProps["description"];
|
|
33
|
+
controllerId: DatePickerInputControllerProps["controllerId"];
|
|
34
|
+
openDropdowns: DatePickerInputControllerProps["openDropdowns"];
|
|
35
|
+
toggleDropdown: DatePickerInputControllerProps["toggleDropdown"];
|
|
36
|
+
onFocus?: DatePickerInputControllerProps["onFocus"];
|
|
24
37
|
}, {
|
|
25
38
|
[evt: string]: CustomEvent<any>;
|
|
26
39
|
}, {}, {}, string>;
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import type { Writable } from 'svelte/store';
|
|
3
|
+
import type { InputControllerConfig } from './index';
|
|
4
|
+
|
|
5
|
+
/** Declared props contract — export lets below are annotated from it so the
|
|
6
|
+
* interface cannot drift from what the component actually reads. */
|
|
7
|
+
export interface DropdownInputControllerProps {
|
|
8
|
+
label: string;
|
|
9
|
+
defaultSelectedLabel?: string;
|
|
10
|
+
value: string | { value: string; label: string };
|
|
11
|
+
onChange: (newValue: string) => void;
|
|
12
|
+
config?: InputControllerConfig;
|
|
13
|
+
options?: { value: string; label: string }[];
|
|
14
|
+
description?: string;
|
|
15
|
+
controllerId: string;
|
|
16
|
+
openDropdowns: Writable<Set<string>>;
|
|
17
|
+
toggleDropdown: (id: string) => void;
|
|
18
|
+
onFocus?: () => void;
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
1
22
|
<script lang="ts">
|
|
2
23
|
/**
|
|
3
24
|
* DropdownInputController Component
|
|
@@ -10,7 +31,6 @@
|
|
|
10
31
|
* Required for component setup and cleanup
|
|
11
32
|
*/
|
|
12
33
|
import { onMount, onDestroy } from 'svelte';
|
|
13
|
-
import type { InputControllerConfig } from './index';
|
|
14
34
|
|
|
15
35
|
// Local Components imports
|
|
16
36
|
import { InputControllerHeader } from './index';
|
|
@@ -28,22 +48,22 @@
|
|
|
28
48
|
* Component Props
|
|
29
49
|
* External properties that configure the dropdown's behavior and appearance
|
|
30
50
|
*/
|
|
31
|
-
export let label:
|
|
32
|
-
export let defaultSelectedLabel:
|
|
33
|
-
export let value:
|
|
34
|
-
export let onChange:
|
|
35
|
-
export let config:
|
|
51
|
+
export let label: DropdownInputControllerProps['label'];
|
|
52
|
+
export let defaultSelectedLabel: DropdownInputControllerProps['defaultSelectedLabel'] = "Select an option";
|
|
53
|
+
export let value: DropdownInputControllerProps['value'];
|
|
54
|
+
export let onChange: DropdownInputControllerProps['onChange'];
|
|
55
|
+
export let config: DropdownInputControllerProps['config'] = {};
|
|
36
56
|
|
|
37
57
|
/**
|
|
38
58
|
* Configuration Options
|
|
39
59
|
* Derived from config prop with fallbacks
|
|
40
60
|
*/
|
|
41
|
-
export let options:
|
|
42
|
-
export let description:
|
|
43
|
-
export let controllerId:
|
|
44
|
-
export let openDropdowns:
|
|
45
|
-
export let toggleDropdown:
|
|
46
|
-
export let onFocus:
|
|
61
|
+
export let options: DropdownInputControllerProps['options'] = config.options || [];
|
|
62
|
+
export let description: DropdownInputControllerProps['description'] = undefined;
|
|
63
|
+
export let controllerId: DropdownInputControllerProps['controllerId'];
|
|
64
|
+
export let openDropdowns: DropdownInputControllerProps['openDropdowns'];
|
|
65
|
+
export let toggleDropdown: DropdownInputControllerProps['toggleDropdown'];
|
|
66
|
+
export let onFocus: DropdownInputControllerProps['onFocus'] = () => {};
|
|
47
67
|
|
|
48
68
|
/**
|
|
49
69
|
* Reactive State
|
|
@@ -51,6 +71,10 @@
|
|
|
51
71
|
*/
|
|
52
72
|
$: open = $openDropdowns?.has(controllerId) || false;
|
|
53
73
|
|
|
74
|
+
/** Timestamp of the last open — used to ignore bits-ui's own opening scrolls. */
|
|
75
|
+
let lastOpenTimestamp = 0;
|
|
76
|
+
$: if (open) lastOpenTimestamp = performance.now();
|
|
77
|
+
|
|
54
78
|
/**
|
|
55
79
|
* Closes the dropdown if it's currently open
|
|
56
80
|
* Used for cleanup and external close triggers
|
|
@@ -63,9 +87,25 @@
|
|
|
63
87
|
|
|
64
88
|
/**
|
|
65
89
|
* Scroll Event Handler
|
|
66
|
-
* Closes dropdown when scrolling occurs to prevent floating UI issues
|
|
90
|
+
* Closes dropdown when scrolling occurs to prevent floating UI issues.
|
|
91
|
+
* Guarded: bits-ui may scroll the viewport/list right after opening, and the
|
|
92
|
+
* capture-phase listener would otherwise close the dropdown in the same frame
|
|
93
|
+
* (which looked like "the dropdown never opens" in the Embed overlay).
|
|
67
94
|
*/
|
|
68
|
-
function handleScroll() {
|
|
95
|
+
function handleScroll(event?: Event) {
|
|
96
|
+
if (!open) return;
|
|
97
|
+
// Grace period after opening — ignore self-inflicted scrolls from bits-ui.
|
|
98
|
+
if (performance.now() - lastOpenTimestamp < 300) return;
|
|
99
|
+
// Never close on scrolls that happen inside the dropdown itself or its portal.
|
|
100
|
+
const target = event?.target as Node | null;
|
|
101
|
+
if (
|
|
102
|
+
target instanceof Element &&
|
|
103
|
+
(target.closest('[data-bits-floating-content-wrapper]') ||
|
|
104
|
+
target.closest('[role="listbox"]') ||
|
|
105
|
+
target.closest('.dropdown-ic-content'))
|
|
106
|
+
) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
69
109
|
closeDropdown();
|
|
70
110
|
}
|
|
71
111
|
|
|
@@ -104,7 +144,13 @@
|
|
|
104
144
|
}
|
|
105
145
|
}
|
|
106
146
|
|
|
107
|
-
|
|
147
|
+
/**
|
|
148
|
+
* The option label for the current selection. `value` accepts a bare string
|
|
149
|
+
* or an option object; normalize once instead of re-narrowing at each read.
|
|
150
|
+
*/
|
|
151
|
+
$: selectedValue = typeof value === 'string' ? value : value?.value;
|
|
152
|
+
$: triggerContent =
|
|
153
|
+
options.find((o) => o.value === selectedValue)?.label ?? defaultSelectedLabel;
|
|
108
154
|
</script>
|
|
109
155
|
|
|
110
156
|
<!-- Dropdown Container -->
|
|
@@ -122,7 +168,7 @@
|
|
|
122
168
|
>
|
|
123
169
|
<Select.Root
|
|
124
170
|
type="single"
|
|
125
|
-
value={
|
|
171
|
+
value={selectedValue}
|
|
126
172
|
onValueChange={handleValueChange}
|
|
127
173
|
open={open}
|
|
128
174
|
onOpenChange={handleOpenChange}
|
|
@@ -218,9 +264,13 @@
|
|
|
218
264
|
display: none;
|
|
219
265
|
}
|
|
220
266
|
|
|
221
|
-
/*
|
|
222
|
-
|
|
267
|
+
/* bits-ui portals the Select content to <body> and wraps it in
|
|
268
|
+
[data-bits-floating-content-wrapper]. The floating layer's default z-index
|
|
269
|
+
(50) sat below page overlays — in the composition Embed overlay
|
|
270
|
+
(z-index 100000) the dropdown opened but was painted behind the dark
|
|
271
|
+
backdrop, so it looked like it never opened. Lift the wrapper above any
|
|
272
|
+
app overlay. */
|
|
223
273
|
:global([data-bits-floating-content-wrapper]) {
|
|
224
|
-
z-index:
|
|
274
|
+
z-index: 1000001 !important;
|
|
225
275
|
}
|
|
226
276
|
</style>
|
|
@@ -1,4 +1,26 @@
|
|
|
1
|
+
import type { Writable } from 'svelte/store';
|
|
1
2
|
import type { InputControllerConfig } from './index';
|
|
3
|
+
/** Declared props contract — export lets below are annotated from it so the
|
|
4
|
+
* interface cannot drift from what the component actually reads. */
|
|
5
|
+
export interface DropdownInputControllerProps {
|
|
6
|
+
label: string;
|
|
7
|
+
defaultSelectedLabel?: string;
|
|
8
|
+
value: string | {
|
|
9
|
+
value: string;
|
|
10
|
+
label: string;
|
|
11
|
+
};
|
|
12
|
+
onChange: (newValue: string) => void;
|
|
13
|
+
config?: InputControllerConfig;
|
|
14
|
+
options?: {
|
|
15
|
+
value: string;
|
|
16
|
+
label: string;
|
|
17
|
+
}[];
|
|
18
|
+
description?: string;
|
|
19
|
+
controllerId: string;
|
|
20
|
+
openDropdowns: Writable<Set<string>>;
|
|
21
|
+
toggleDropdown: (id: string) => void;
|
|
22
|
+
onFocus?: () => void;
|
|
23
|
+
}
|
|
2
24
|
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
25
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
26
|
$$bindings?: Bindings;
|
|
@@ -16,26 +38,20 @@ declare const DropdownInputController: $$__sveltets_2_IsomorphicComponent<{
|
|
|
16
38
|
/**
|
|
17
39
|
* Component Props
|
|
18
40
|
* External properties that configure the dropdown's behavior and appearance
|
|
19
|
-
*/ label:
|
|
20
|
-
defaultSelectedLabel?:
|
|
21
|
-
value:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
onChange: (newValue: string) => void;
|
|
26
|
-
config?: InputControllerConfig;
|
|
41
|
+
*/ label: DropdownInputControllerProps["label"];
|
|
42
|
+
defaultSelectedLabel?: DropdownInputControllerProps["defaultSelectedLabel"];
|
|
43
|
+
value: DropdownInputControllerProps["value"];
|
|
44
|
+
onChange: DropdownInputControllerProps["onChange"];
|
|
45
|
+
config?: DropdownInputControllerProps["config"];
|
|
27
46
|
/**
|
|
28
47
|
* Configuration Options
|
|
29
48
|
* Derived from config prop with fallbacks
|
|
30
|
-
*/ options?:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
openDropdowns: any;
|
|
37
|
-
toggleDropdown: (id: string) => void;
|
|
38
|
-
onFocus?: () => void;
|
|
49
|
+
*/ options?: DropdownInputControllerProps["options"];
|
|
50
|
+
description?: DropdownInputControllerProps["description"];
|
|
51
|
+
controllerId: DropdownInputControllerProps["controllerId"];
|
|
52
|
+
openDropdowns: DropdownInputControllerProps["openDropdowns"];
|
|
53
|
+
toggleDropdown: DropdownInputControllerProps["toggleDropdown"];
|
|
54
|
+
onFocus?: DropdownInputControllerProps["onFocus"];
|
|
39
55
|
}, {
|
|
40
56
|
[evt: string]: CustomEvent<any>;
|
|
41
57
|
}, {}, {}, string>;
|
|
@@ -17,6 +17,26 @@
|
|
|
17
17
|
* - Manages dynamic SVG creation and disposal
|
|
18
18
|
-->
|
|
19
19
|
|
|
20
|
+
<script module lang="ts">
|
|
21
|
+
/** The nine grid alignments the controller can select — shared between the
|
|
22
|
+
* props contract above and the instance script below. */
|
|
23
|
+
const positions = [
|
|
24
|
+
'top-left', 'top-center', 'top-right',
|
|
25
|
+
'center-left', 'center-center', 'center-right',
|
|
26
|
+
'bottom-left', 'bottom-center', 'bottom-right'
|
|
27
|
+
] as const;
|
|
28
|
+
type Position = typeof positions[number];
|
|
29
|
+
|
|
30
|
+
/** Declared props contract — export lets below are annotated from it so the
|
|
31
|
+
* interface cannot drift from what the component actually reads. */
|
|
32
|
+
export interface FixedPositionInputControllerProps {
|
|
33
|
+
value?: Position;
|
|
34
|
+
onChange: (newValue: Position) => void;
|
|
35
|
+
onFocus?: () => void;
|
|
36
|
+
id?: string;
|
|
37
|
+
}
|
|
38
|
+
</script>
|
|
39
|
+
|
|
20
40
|
<script lang="ts">
|
|
21
41
|
// Svelte imports
|
|
22
42
|
import { onDestroy } from 'svelte';
|
|
@@ -79,21 +99,15 @@
|
|
|
79
99
|
};
|
|
80
100
|
|
|
81
101
|
// Component props
|
|
82
|
-
export let value:
|
|
83
|
-
export let onChange:
|
|
84
|
-
export let onFocus:
|
|
85
|
-
export let id:
|
|
102
|
+
export let value: FixedPositionInputControllerProps['value'] = 'bottom-right';
|
|
103
|
+
export let onChange: FixedPositionInputControllerProps['onChange'];
|
|
104
|
+
export let onFocus: FixedPositionInputControllerProps['onFocus'] = () => {};
|
|
105
|
+
export let id: FixedPositionInputControllerProps['id'] = undefined;
|
|
86
106
|
|
|
87
107
|
/**
|
|
88
108
|
* Defines all valid position combinations in a 3x3 grid
|
|
89
109
|
* Order matters for visual layout and keyboard navigation
|
|
90
110
|
*/
|
|
91
|
-
const positions = [
|
|
92
|
-
'top-left', 'top-center', 'top-right',
|
|
93
|
-
'center-left', 'center-center', 'center-right',
|
|
94
|
-
'bottom-left', 'bottom-center', 'bottom-right'
|
|
95
|
-
] as const;
|
|
96
|
-
|
|
97
111
|
type Position = typeof positions[number];
|
|
98
112
|
|
|
99
113
|
// Map positions to their corresponding icons
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/** The nine grid alignments the controller can select — shared between the
|
|
2
|
+
* props contract above and the instance script below. */
|
|
3
|
+
declare const positions: readonly ["top-left", "top-center", "top-right", "center-left", "center-center", "center-right", "bottom-left", "bottom-center", "bottom-right"];
|
|
4
|
+
type Position = typeof positions[number];
|
|
5
|
+
/** Declared props contract — export lets below are annotated from it so the
|
|
6
|
+
* interface cannot drift from what the component actually reads. */
|
|
7
|
+
export interface FixedPositionInputControllerProps {
|
|
8
|
+
value?: Position;
|
|
9
|
+
onChange: (newValue: Position) => void;
|
|
10
|
+
onFocus?: () => void;
|
|
11
|
+
id?: string;
|
|
12
|
+
}
|
|
1
13
|
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> {
|
|
2
14
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
15
|
$$bindings?: Bindings;
|
|
@@ -12,10 +24,10 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
|
|
|
12
24
|
z_$$bindings?: Bindings;
|
|
13
25
|
}
|
|
14
26
|
declare const FixedPositionInputController: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
-
value?: "
|
|
16
|
-
onChange:
|
|
17
|
-
onFocus?:
|
|
18
|
-
id?:
|
|
27
|
+
value?: FixedPositionInputControllerProps["value"];
|
|
28
|
+
onChange: FixedPositionInputControllerProps["onChange"];
|
|
29
|
+
onFocus?: FixedPositionInputControllerProps["onFocus"];
|
|
30
|
+
id?: FixedPositionInputControllerProps["id"];
|
|
19
31
|
}, {
|
|
20
32
|
[evt: string]: CustomEvent<any>;
|
|
21
33
|
}, {}, {}, string>;
|
|
@@ -18,6 +18,23 @@
|
|
|
18
18
|
* - Uses font-display: swap for better loading UX
|
|
19
19
|
-->
|
|
20
20
|
|
|
21
|
+
<script module lang="ts">
|
|
22
|
+
/** Declared props contract — export lets below are annotated from it so the
|
|
23
|
+
* interface cannot drift from what the component actually reads. */
|
|
24
|
+
export interface FontInputControllerProps {
|
|
25
|
+
label?: string;
|
|
26
|
+
style?: string;
|
|
27
|
+
value?: { family: string; weight: string; category: string } | string | null;
|
|
28
|
+
onChange?: (newValue: { family: string; weight: string; category: string }) => void;
|
|
29
|
+
description?: string;
|
|
30
|
+
controllerId: string;
|
|
31
|
+
openDropdowns: Writable<Set<string>>;
|
|
32
|
+
toggleDropdown: (id: string) => void;
|
|
33
|
+
hideRecentFromList?: boolean;
|
|
34
|
+
hideTrashIcon?: boolean;
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
37
|
+
|
|
21
38
|
<script lang="ts">
|
|
22
39
|
// Svelte imports
|
|
23
40
|
import { onMount, onDestroy, tick } from 'svelte';
|
|
@@ -46,6 +63,7 @@
|
|
|
46
63
|
import FontManager, { mapGoogleVariantIdsToWeightNames } from '../../utils/FontManager';
|
|
47
64
|
|
|
48
65
|
import { shouldSkipFont } from '../../utils/skipFonts';
|
|
66
|
+
import type { Writable } from 'svelte/store';
|
|
49
67
|
|
|
50
68
|
import { InputControllerHeader } from './index';
|
|
51
69
|
|
|
@@ -77,16 +95,16 @@
|
|
|
77
95
|
* @prop {Function} toggleDropdown - Function to toggle dropdown state
|
|
78
96
|
* @prop {Function} onFocus - Optional focus handler
|
|
79
97
|
*/
|
|
80
|
-
export let label:
|
|
98
|
+
export let label: FontInputControllerProps['label'] = '';
|
|
81
99
|
let className = '';
|
|
82
100
|
export { className as class };
|
|
83
|
-
export let style = '';
|
|
84
|
-
export let value:
|
|
85
|
-
export let onChange:
|
|
86
|
-
export let description:
|
|
87
|
-
export let controllerId:
|
|
88
|
-
export let openDropdowns:
|
|
89
|
-
export let toggleDropdown:
|
|
101
|
+
export let style: FontInputControllerProps['style'] = '';
|
|
102
|
+
export let value: FontInputControllerProps['value'] = null;
|
|
103
|
+
export let onChange: FontInputControllerProps['onChange'] = undefined;
|
|
104
|
+
export let description: FontInputControllerProps['description'] = undefined;
|
|
105
|
+
export let controllerId: FontInputControllerProps['controllerId'];
|
|
106
|
+
export let openDropdowns: FontInputControllerProps['openDropdowns'];
|
|
107
|
+
export let toggleDropdown: FontInputControllerProps['toggleDropdown'];
|
|
90
108
|
|
|
91
109
|
// Initialize timeouts
|
|
92
110
|
let scrollTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
@@ -95,6 +113,7 @@
|
|
|
95
113
|
// Font weight state - remove localStorage check on init
|
|
96
114
|
let selectedWeight = `${controllerId}-Regular`;
|
|
97
115
|
let availableWeights: string[] = ['Regular', 'Medium', 'SemiBold', 'Bold'];
|
|
116
|
+
let fontCatalogFallbackWarned = false;
|
|
98
117
|
|
|
99
118
|
// Font search and filter state
|
|
100
119
|
let allFonts: FontItem[] = [];
|
|
@@ -123,8 +142,8 @@
|
|
|
123
142
|
let isInitialLoading = true; // Start with loading state true
|
|
124
143
|
|
|
125
144
|
// Add new prop for controlling font list behavior
|
|
126
|
-
export let hideRecentFromList:
|
|
127
|
-
export let hideTrashIcon:
|
|
145
|
+
export let hideRecentFromList: FontInputControllerProps['hideRecentFromList'] = false;
|
|
146
|
+
export let hideTrashIcon: FontInputControllerProps['hideTrashIcon'] = true;
|
|
128
147
|
|
|
129
148
|
function updateFamilyPopoverBox() {
|
|
130
149
|
if (!familyTriggerEl || typeof window === 'undefined') return;
|
|
@@ -625,7 +644,7 @@
|
|
|
625
644
|
|
|
626
645
|
// try {
|
|
627
646
|
// // Get the current font's ID if it exists in our custom fonts
|
|
628
|
-
// const selectedId =
|
|
647
|
+
// const selectedId = resolvedFont?.family ?
|
|
629
648
|
// fontManagerInstance?.getCachedFontList()
|
|
630
649
|
// .find(f => f.family === value.family && f.category === 'Mine')?.id
|
|
631
650
|
// : undefined;
|
|
@@ -1360,6 +1379,9 @@
|
|
|
1360
1379
|
*/
|
|
1361
1380
|
async function fetchFontWeights(fontFamily: string) {
|
|
1362
1381
|
try {
|
|
1382
|
+
// Wait for FontManager init — reactive weight fetch can race ahead of onMount.
|
|
1383
|
+
fontManagerInstance = await FontManager.getInstance(appConfig.GOOGLE_FONTS_API_KEY);
|
|
1384
|
+
|
|
1363
1385
|
// First check if it's a custom font using FontManager
|
|
1364
1386
|
if (fontManagerInstance?.isCustomFont(fontFamily)) {
|
|
1365
1387
|
// Get custom font data
|
|
@@ -1397,7 +1419,16 @@
|
|
|
1397
1419
|
}
|
|
1398
1420
|
|
|
1399
1421
|
// Google font: use catalog cached by FontManager (no extra API call per font)
|
|
1400
|
-
|
|
1422
|
+
let variantIds = fontManagerInstance?.getGoogleFontVariantIds(fontFamily);
|
|
1423
|
+
if (!variantIds?.length) {
|
|
1424
|
+
// Catalog may still be empty right after init edge cases — force list load once.
|
|
1425
|
+
try {
|
|
1426
|
+
await fontManagerInstance.getInitialFontList();
|
|
1427
|
+
} catch (catalogError) {
|
|
1428
|
+
console.warn('[FontInput] Catalog refresh failed before weight lookup:', catalogError);
|
|
1429
|
+
}
|
|
1430
|
+
variantIds = fontManagerInstance?.getGoogleFontVariantIds(fontFamily);
|
|
1431
|
+
}
|
|
1401
1432
|
if (variantIds?.length) {
|
|
1402
1433
|
availableWeights = mapGoogleVariantIdsToWeightNames(variantIds);
|
|
1403
1434
|
if (!availableWeights.includes(selectedWeight.replace(`${controllerId}-`, ''))) {
|
|
@@ -1407,7 +1438,11 @@
|
|
|
1407
1438
|
}
|
|
1408
1439
|
|
|
1409
1440
|
// API unavailable (403 / no catalog): sensible defaults, still loads via fonts.googleapis.com CSS
|
|
1410
|
-
|
|
1441
|
+
// Warn once — not on every reactive re-run during catalog race.
|
|
1442
|
+
if (!fontCatalogFallbackWarned) {
|
|
1443
|
+
fontCatalogFallbackWarned = true;
|
|
1444
|
+
console.warn('[FontInput] Using default weights (Google catalog not loaded). Later fonts will use the same fallback silently.');
|
|
1445
|
+
}
|
|
1411
1446
|
availableWeights = ['Regular', 'Bold'];
|
|
1412
1447
|
selectedWeight = `${controllerId}-Regular`;
|
|
1413
1448
|
} catch (error) {
|
|
@@ -1431,7 +1466,7 @@
|
|
|
1431
1466
|
*/
|
|
1432
1467
|
function highlightMatch(name: string, term: string) {
|
|
1433
1468
|
// Check if this font is the selected one
|
|
1434
|
-
const isSelected =
|
|
1469
|
+
const isSelected = resolvedFont?.family === name;
|
|
1435
1470
|
|
|
1436
1471
|
if (!term) {
|
|
1437
1472
|
// If no search term, just return the name with appropriate color
|
|
@@ -1558,7 +1593,7 @@
|
|
|
1558
1593
|
await fontManagerInstance?.removeCustomFont(fontFamily);
|
|
1559
1594
|
|
|
1560
1595
|
// If the removed font was selected, clear the selection
|
|
1561
|
-
if (
|
|
1596
|
+
if (resolvedFont?.family === fontFamily && onChange) {
|
|
1562
1597
|
onChange({
|
|
1563
1598
|
family: '',
|
|
1564
1599
|
weight: 'Regular',
|
|
@@ -1719,7 +1754,7 @@
|
|
|
1719
1754
|
}
|
|
1720
1755
|
}}
|
|
1721
1756
|
>
|
|
1722
|
-
<Popover.Trigger tabindex=
|
|
1757
|
+
<Popover.Trigger tabindex={-1} class="w-full h-full flex items-center border-0 bg-transparent hover:bg-transparent focus:bg-transparent pl-3 pr-[16px] group"
|
|
1723
1758
|
onmouseenter={() => {
|
|
1724
1759
|
// Preload fonts when hovering over the button
|
|
1725
1760
|
// This reduces the delay when actually clicking to open
|
|
@@ -1896,7 +1931,7 @@
|
|
|
1896
1931
|
<div
|
|
1897
1932
|
role="button"
|
|
1898
1933
|
tabindex="-1"
|
|
1899
|
-
class="ml-auto transition-opacity {
|
|
1934
|
+
class="ml-auto transition-opacity {resolvedFont?.family === font.family ? 'opacity-0 pointer-events-none' : 'opacity-0 group-hover:opacity-100'}"
|
|
1900
1935
|
onclick={(e) => {
|
|
1901
1936
|
e.stopPropagation();
|
|
1902
1937
|
e.preventDefault();
|
|
@@ -1939,7 +1974,7 @@
|
|
|
1939
1974
|
}
|
|
1940
1975
|
}}
|
|
1941
1976
|
>
|
|
1942
|
-
<Popover.Trigger tabindex=
|
|
1977
|
+
<Popover.Trigger tabindex={-1} class="w-full h-full flex items-center border-0 bg-transparent hover:bg-transparent focus:bg-transparent pl-3 pr-[16px] group">
|
|
1943
1978
|
<span class="truncate flex-1 text-left subtext text-grey7">
|
|
1944
1979
|
{displayWeight || 'Regular'}
|
|
1945
1980
|
</span>
|
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
/** Declared props contract — export lets below are annotated from it so the
|
|
2
|
+
* interface cannot drift from what the component actually reads. */
|
|
3
|
+
export interface FontInputControllerProps {
|
|
4
|
+
label?: string;
|
|
5
|
+
style?: string;
|
|
6
|
+
value?: {
|
|
7
|
+
family: string;
|
|
8
|
+
weight: string;
|
|
9
|
+
category: string;
|
|
10
|
+
} | string | null;
|
|
11
|
+
onChange?: (newValue: {
|
|
12
|
+
family: string;
|
|
13
|
+
weight: string;
|
|
14
|
+
category: string;
|
|
15
|
+
}) => void;
|
|
16
|
+
description?: string;
|
|
17
|
+
controllerId: string;
|
|
18
|
+
openDropdowns: Writable<Set<string>>;
|
|
19
|
+
toggleDropdown: (id: string) => void;
|
|
20
|
+
hideRecentFromList?: boolean;
|
|
21
|
+
hideTrashIcon?: boolean;
|
|
22
|
+
}
|
|
23
|
+
import type { Writable } from 'svelte/store';
|
|
1
24
|
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> {
|
|
2
25
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
26
|
$$bindings?: Bindings;
|
|
@@ -23,25 +46,17 @@ declare const FontInputController: $$__sveltets_2_IsomorphicComponent<{
|
|
|
23
46
|
* @prop {any} openDropdowns - Store tracking open dropdown states
|
|
24
47
|
* @prop {Function} toggleDropdown - Function to toggle dropdown state
|
|
25
48
|
* @prop {Function} onFocus - Optional focus handler
|
|
26
|
-
*/ label?:
|
|
49
|
+
*/ label?: FontInputControllerProps["label"];
|
|
27
50
|
class?: string;
|
|
28
|
-
style?:
|
|
29
|
-
value?:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
category: string;
|
|
38
|
-
}) => void) | undefined;
|
|
39
|
-
description?: string | undefined;
|
|
40
|
-
controllerId: string;
|
|
41
|
-
openDropdowns: any;
|
|
42
|
-
toggleDropdown: (id: string) => void;
|
|
43
|
-
hideRecentFromList?: boolean;
|
|
44
|
-
hideTrashIcon?: boolean;
|
|
51
|
+
style?: FontInputControllerProps["style"];
|
|
52
|
+
value?: FontInputControllerProps["value"];
|
|
53
|
+
onChange?: FontInputControllerProps["onChange"];
|
|
54
|
+
description?: FontInputControllerProps["description"];
|
|
55
|
+
controllerId: FontInputControllerProps["controllerId"];
|
|
56
|
+
openDropdowns: FontInputControllerProps["openDropdowns"];
|
|
57
|
+
toggleDropdown: FontInputControllerProps["toggleDropdown"];
|
|
58
|
+
hideRecentFromList?: FontInputControllerProps["hideRecentFromList"];
|
|
59
|
+
hideTrashIcon?: FontInputControllerProps["hideTrashIcon"];
|
|
45
60
|
}, {
|
|
46
61
|
[evt: string]: CustomEvent<any>;
|
|
47
62
|
}, {}, {}, string>;
|