@elementor/editor-editing-panel 1.10.0 → 1.11.0

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/index.js +680 -685
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +632 -641
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +18 -15
  7. package/src/components/css-classes/css-class-item.tsx +130 -0
  8. package/src/components/css-classes/css-class-menu.tsx +151 -0
  9. package/src/components/{css-class-selector.tsx → css-classes/css-class-selector.tsx} +23 -154
  10. package/src/components/style-sections/layout-section/display-field.tsx +9 -1
  11. package/src/components/style-sections/layout-section/flex-order-field.tsx +5 -5
  12. package/src/components/style-sections/layout-section/flex-size-field.tsx +1 -1
  13. package/src/components/style-sections/layout-section/gap-control-field.tsx +0 -2
  14. package/src/components/style-sections/position-section/dimensions-field.tsx +1 -1
  15. package/src/components/style-sections/position-section/position-section.tsx +1 -1
  16. package/src/components/style-sections/typography-section/font-weight-field.tsx +9 -5
  17. package/src/components/style-sections/typography-section/text-alignment-field.tsx +16 -8
  18. package/src/components/style-sections/typography-section/transform-field.tsx +12 -3
  19. package/src/components/style-tab.tsx +1 -1
  20. package/src/controls-registry/controls-registry.tsx +3 -1
  21. package/src/controls-registry/settings-field.tsx +8 -1
  22. package/src/dynamics/components/dynamic-selection.tsx +1 -1
  23. package/src/dynamics/dynamic-control.tsx +1 -1
  24. package/src/dynamics/types.ts +2 -2
  25. package/src/dynamics/utils.ts +2 -2
  26. package/src/hooks/use-persist-dynamic-value.ts +1 -1
  27. package/src/hooks/use-styles-fields.ts +113 -9
  28. package/src/index.ts +1 -1
  29. package/src/init.ts +2 -2
  30. package/src/sync/types.ts +4 -3
  31. package/src/components/collapsible-field.tsx +0 -36
  32. package/src/components/css-class-menu.tsx +0 -101
  33. package/src/components/editable-field.tsx +0 -166
  34. package/src/hooks/use-session-storage.ts +0 -46
  35. package/src/sync/enqueue-font.ts +0 -7
@@ -1,166 +0,0 @@
1
- import * as React from 'react';
2
- import { type ComponentProps, createContext, useContext, useEffect, useRef, useState } from 'react';
3
- import { Tooltip } from '@elementor/ui';
4
-
5
- type EditableFieldContext = {
6
- isEditing: boolean;
7
- openEditMode: () => void;
8
- closeEditMode: () => void;
9
- onChange: ( event: React.ChangeEvent< HTMLInputElement > ) => void;
10
- value: string;
11
- error?: string | null;
12
- submit: ( value: string ) => Promise< void >;
13
- editable?: boolean;
14
- submitting: boolean;
15
- };
16
-
17
- const Context = createContext< EditableFieldContext | null >( null );
18
-
19
- export type EditableFieldProviderProps = React.PropsWithChildren< {
20
- value: string;
21
- onSubmit: ( value: string ) => unknown | Promise< unknown >;
22
- validation?: ( value: string ) => string | undefined | null;
23
- editable?: boolean;
24
- } >;
25
-
26
- export const EditableFieldProvider = ( {
27
- children,
28
- value,
29
- onSubmit,
30
- validation,
31
- editable,
32
- }: EditableFieldProviderProps ) => {
33
- const [ isEditing, setIsEditing ] = useState( false );
34
- const [ submitting, setSubmitting ] = useState( false );
35
- const [ error, setError ] = useState< string | null | undefined >( null );
36
-
37
- const openEditMode = () => {
38
- setIsEditing( true );
39
- };
40
-
41
- const closeEditMode = () => {
42
- setError( null );
43
- setIsEditing( false );
44
- };
45
-
46
- const submit = async ( newValue: string ) => {
47
- if ( ! error ) {
48
- setSubmitting( true );
49
-
50
- try {
51
- await onSubmit( newValue );
52
- } finally {
53
- setSubmitting( false );
54
- }
55
- }
56
-
57
- closeEditMode();
58
- };
59
-
60
- const onChange = ( event: React.ChangeEvent< HTMLSpanElement > ) => {
61
- const { innerText: newValue } = event.target;
62
-
63
- if ( validation ) {
64
- setError( validation( newValue ) );
65
- }
66
- };
67
-
68
- return (
69
- <Context.Provider
70
- value={ {
71
- isEditing,
72
- openEditMode,
73
- closeEditMode,
74
- onChange,
75
- value,
76
- error,
77
- submit,
78
- editable,
79
- submitting,
80
- } }
81
- >
82
- { children }
83
- </Context.Provider>
84
- );
85
- };
86
-
87
- type EditableFieldProps = ComponentProps< 'div' >;
88
-
89
- export const EditableField = ( { children, onClick, ...props }: EditableFieldProps ) => {
90
- const ref = useRef< HTMLElement >( null );
91
- const { isEditing, closeEditMode, value, onChange, error, submit, editable } = useEditableField();
92
-
93
- useEffect( () => {
94
- if ( isEditing ) {
95
- ref.current?.focus();
96
- selectAll();
97
- }
98
- }, [ isEditing ] );
99
-
100
- const handleKeyDown = ( event: React.KeyboardEvent ) => {
101
- event.stopPropagation();
102
-
103
- if ( [ 'Escape' ].includes( event.key ) ) {
104
- return closeEditMode();
105
- }
106
-
107
- if ( [ 'Enter' ].includes( event.key ) ) {
108
- event.preventDefault();
109
- return submit( ( event.target as HTMLElement ).innerText );
110
- }
111
- };
112
-
113
- const handleClick = ( event: React.MouseEvent< HTMLDivElement > ) => {
114
- if ( isEditing ) {
115
- event.stopPropagation();
116
- }
117
-
118
- onClick?.( event );
119
- };
120
-
121
- const selectAll = () => {
122
- const selection = getSelection();
123
-
124
- if ( ! selection || ! ref.current ) {
125
- return;
126
- }
127
-
128
- const range = document.createRange();
129
- range.selectNodeContents( ref.current );
130
-
131
- selection.removeAllRanges();
132
- selection.addRange( range );
133
- };
134
-
135
- if ( ! editable ) {
136
- return children;
137
- }
138
-
139
- return (
140
- <Tooltip open={ !! error } title={ error } placement="top">
141
- { /* eslint-disable-next-line jsx-a11y/no-static-element-interactions */ }
142
- <div onKeyDown={ handleKeyDown } onClick={ handleClick } { ...props }>
143
- <span
144
- ref={ ref }
145
- role="textbox"
146
- onInput={ onChange }
147
- contentEditable={ isEditing }
148
- suppressContentEditableWarning
149
- onBlur={ closeEditMode }
150
- >
151
- { isEditing ? value : children }
152
- </span>
153
- </div>
154
- </Tooltip>
155
- );
156
- };
157
-
158
- export const useEditableField = () => {
159
- const contextValue = useContext( Context );
160
-
161
- if ( ! contextValue ) {
162
- throw new Error( 'useEditableField must be used within a EditableFieldProvider' );
163
- }
164
-
165
- return contextValue;
166
- };
@@ -1,46 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
- import { getSessionStorageItem, removeSessionStorageItem, setSessionStorageItem } from '@elementor/utils';
3
-
4
- export const useSessionStorage = < T >( key: string ) => {
5
- const prefixedKey = `elementor/${ key }`;
6
-
7
- const [ value, setValue ] = useState< T | null >();
8
-
9
- useEffect( () => {
10
- return subscribeToSessionStorage< T | null >( prefixedKey, ( newValue ) => {
11
- setValue( newValue ?? null );
12
- } );
13
- }, [ prefixedKey ] );
14
-
15
- const saveValue = ( newValue: T ) => {
16
- setSessionStorageItem( prefixedKey, newValue );
17
- };
18
-
19
- const removeValue = () => {
20
- removeSessionStorageItem( prefixedKey );
21
- };
22
-
23
- return [ value, saveValue, removeValue ] as const;
24
- };
25
-
26
- const subscribeToSessionStorage = < T >( key: string, subscriber: ( value: T ) => void ) => {
27
- subscriber( getSessionStorageItem( key ) as T );
28
-
29
- const abortController = new AbortController();
30
-
31
- window.addEventListener(
32
- 'storage',
33
- ( e ) => {
34
- if ( e.key !== key || e.storageArea !== sessionStorage ) {
35
- return;
36
- }
37
-
38
- subscriber( getSessionStorageItem( key ) as T );
39
- },
40
- { signal: abortController.signal }
41
- );
42
-
43
- return () => {
44
- abortController.abort();
45
- };
46
- };
@@ -1,7 +0,0 @@
1
- import { type EnqueueFont, type ExtendedWindow } from './types';
2
-
3
- export const enqueueFont: EnqueueFont = ( fontFamily, context = 'editor' ) => {
4
- const extendedWindow = window as unknown as ExtendedWindow;
5
-
6
- return extendedWindow.elementor?.helpers?.enqueueFont( fontFamily, context ) ?? null;
7
- };