fix: standardize Edra editor placeholder widths and slash command navigation

- Fix slash command keyboard navigation by uncommenting handler
- Update all media placeholders to respect content block margins (2.25rem)
- Refactor placeholder styles to use SCSS variables consistently
- Fix Audio, Gallery, IFrame, Video, Location, and URL embed placeholders
- Fix Image placeholder width to match other placeholders
- Ensure responsive margins on mobile (2rem)
This commit is contained in:
Justin Edmund 2025-06-26 15:37:47 -04:00
parent 22c27a0e64
commit 48cc27770f
8 changed files with 387 additions and 167 deletions

View file

@ -219,8 +219,8 @@ export default (menuList: Component<any, any, ''>): Extension =>
if (props.event.key === 'Enter') return true
// return component.ref?.onKeyDown(props);
return false
return component.ref?.onKeyDown(props);
// return false
},
onExit(props) {

View file

@ -15,16 +15,73 @@
}
</script>
<NodeViewWrapper class="edra-media-placeholder-wrapper" contenteditable="false">
<NodeViewWrapper class="edra-audio-placeholder-wrapper" contenteditable="false">
<!-- svelte-ignore a11y_click_events_have_key_events -->
<span
class="edra-media-placeholder-content"
onclick={handleClick}
tabindex="0"
role="button"
aria-label="Insert An Audio"
>
<AudioLines class="edra-media-placeholder-icon" />
<span class="edra-media-placeholder-text">Insert An Audio</span>
</span>
<div class="edra-audio-placeholder-container">
<button
class="edra-audio-placeholder-content"
onclick={handleClick}
tabindex="0"
aria-label="Insert An Audio"
>
<AudioLines class="edra-audio-placeholder-icon" />
<span class="edra-audio-placeholder-text">Insert An Audio</span>
</button>
</div>
</NodeViewWrapper>
<style lang="scss">
@import '$styles/variables';
.edra-audio-placeholder-wrapper {
width: 100%;
margin-bottom: 1rem;
}
.edra-audio-placeholder-container {
margin-left: 2.25rem;
margin-right: 2.25rem;
@media (max-width: 768px) {
margin-left: 2rem;
margin-right: 2rem;
}
}
.edra-audio-placeholder-content {
width: 100%;
padding: $unit-3x;
background-color: $gray-95;
border: 2px dashed $gray-85;
border-radius: $corner-radius;
display: flex;
align-items: center;
justify-content: center;
gap: $unit-2x;
cursor: pointer;
transition: all 0.2s ease;
color: $gray-50;
&:hover {
background-color: $gray-90;
border-color: $gray-70;
color: $gray-40;
}
&:focus {
outline: none;
border-color: $primary-color;
box-shadow: 0 0 0 3px rgba($primary-color, 0.1);
}
}
:global(.edra-audio-placeholder-icon) {
width: $unit-3x;
height: $unit-3x;
}
.edra-audio-placeholder-text {
font-size: $font-size-small;
font-weight: 500;
}
</style>

View file

@ -224,64 +224,78 @@
/>
</NodeViewWrapper>
<style>
<style lang="scss">
@import '$styles/variables';
.edra-media-placeholder-wrapper {
width: 100%;
margin-bottom: 1rem;
margin-left: 2.25rem;
margin-right: 2.25rem;
@media (max-width: 768px) {
margin-left: 2rem;
margin-right: 2rem;
}
}
.edra-media-placeholder-container {
display: flex;
gap: 12px;
padding: 24px;
border: 2px dashed #e5e7eb;
border-radius: 8px;
background: #f9fafb;
gap: $unit-2x;
padding: $unit-3x;
border: 2px dashed $gray-85;
border-radius: $corner-radius;
background: $gray-95;
transition: all 0.2s ease;
justify-content: center;
align-items: center;
min-height: 80px;
}
.edra-media-placeholder-container:hover {
border-color: #d1d5db;
background: #f3f4f6;
&:hover {
border-color: $gray-70;
background: $gray-90;
}
}
.edra-media-placeholder-option {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 16px 20px;
border: 1px solid #e5e7eb;
border-radius: 6px;
background: white;
gap: $unit;
padding: $unit-2x $unit-3x;
border: 1px solid $gray-85;
border-radius: $corner-radius-sm;
background: $white;
cursor: pointer;
transition: all 0.2s ease;
min-width: 140px;
}
.edra-media-placeholder-option:hover {
border-color: #d1d5db;
background: #f9fafb;
transform: translateY(-1px);
}
&:hover {
border-color: $gray-70;
background: $gray-95;
transform: translateY(-1px);
}
.edra-media-placeholder-option:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
&:focus {
outline: none;
border-color: $primary-color;
box-shadow: 0 0 0 3px rgba($primary-color, 0.1);
}
}
.edra-media-placeholder-uploading {
display: flex;
align-items: center;
gap: 8px;
padding: 20px;
color: #6b7280;
gap: $unit;
padding: $unit-3x;
color: $gray-50;
}
.spinner {
width: 16px;
height: 16px;
border: 2px solid #f3f4f6;
border-top: 2px solid #3b82f6;
width: $unit-2x;
height: $unit-2x;
border: 2px solid $gray-90;
border-top: 2px solid $primary-color;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@ -296,14 +310,14 @@
}
:global(.edra-media-placeholder-icon) {
width: 28px;
height: 28px;
color: #6b7280;
width: $unit-3x + $unit-half;
height: $unit-3x + $unit-half;
color: $gray-50;
}
.edra-media-placeholder-text {
font-size: 14px;
color: #6b7280;
font-size: $font-size-small;
color: $gray-50;
font-weight: 500;
}
</style>

View file

@ -163,63 +163,77 @@
/>
</NodeViewWrapper>
<style>
<style lang="scss">
@import '$styles/variables';
.edra-gallery-placeholder-wrapper {
width: 100%;
margin-bottom: 1rem;
margin-left: 2.25rem;
margin-right: 2.25rem;
@media (max-width: 768px) {
margin-left: 2rem;
margin-right: 2rem;
}
}
.edra-gallery-placeholder-container {
display: flex;
gap: 12px;
padding: 24px;
border: 2px dashed #e5e7eb;
border-radius: 8px;
background: #f9fafb;
gap: $unit-2x;
padding: $unit-3x;
border: 2px dashed $gray-85;
border-radius: $corner-radius;
background: $gray-95;
transition: all 0.2s ease;
justify-content: center;
align-items: center;
}
.edra-gallery-placeholder-container:hover {
border-color: #d1d5db;
background: #f3f4f6;
&:hover {
border-color: $gray-70;
background: $gray-90;
}
}
.edra-gallery-placeholder-option {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 16px 20px;
border: 1px solid #e5e7eb;
border-radius: 6px;
background: white;
gap: $unit;
padding: $unit-2x $unit-3x;
border: 1px solid $gray-85;
border-radius: $corner-radius-sm;
background: $white;
cursor: pointer;
transition: all 0.2s ease;
min-width: 140px;
}
.edra-gallery-placeholder-option:hover {
border-color: #d1d5db;
background: #f9fafb;
transform: translateY(-1px);
}
&:hover {
border-color: $gray-70;
background: $gray-95;
transform: translateY(-1px);
}
.edra-gallery-placeholder-option:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
&:focus {
outline: none;
border-color: $primary-color;
box-shadow: 0 0 0 3px rgba($primary-color, 0.1);
}
}
.edra-gallery-placeholder-uploading {
display: flex;
align-items: center;
gap: 8px;
padding: 20px;
color: #6b7280;
gap: $unit;
padding: $unit-3x;
color: $gray-50;
}
.spinner {
width: 16px;
height: 16px;
border: 2px solid #f3f4f6;
border-top: 2px solid #3b82f6;
width: $unit-2x;
height: $unit-2x;
border: 2px solid $gray-90;
border-top: 2px solid $primary-color;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@ -234,14 +248,14 @@
}
:global(.edra-gallery-placeholder-icon) {
width: 28px;
height: 28px;
color: #6b7280;
width: $unit-3x + $unit-half;
height: $unit-3x + $unit-half;
color: $gray-50;
}
.edra-gallery-placeholder-text {
font-size: 14px;
color: #6b7280;
font-size: $font-size-small;
color: $gray-50;
font-weight: 500;
}
</style>

View file

@ -117,49 +117,61 @@
</NodeViewWrapper>
<style lang="scss">
@import '$styles/variables';
:global(.node-geolocationPlaceholder) {
margin-bottom: 1rem;
margin-left: 2.25rem;
margin-right: 2.25rem;
@media (max-width: 768px) {
margin-left: 2rem;
margin-right: 2rem;
}
}
.geolocation-placeholder {
background: #f8f9fa;
border: 2px dashed #e0e0e0;
border-radius: 8px;
padding: 24px;
margin: 16px 0;
background: $gray-95;
border: 2px dashed $gray-85;
border-radius: $corner-radius;
padding: $unit-3x;
text-align: center;
}
.icon {
display: flex;
justify-content: center;
margin-bottom: 16px;
color: #6b7280;
margin-bottom: $unit-2x;
color: $gray-50;
}
.content {
h3 {
margin: 0 0 8px;
font-size: 18px;
margin: 0 0 $unit;
font-size: $font-size-large;
font-weight: 600;
color: #1f2937;
color: $gray-10;
}
p {
margin: 0 0 16px;
color: #6b7280;
margin: 0 0 $unit-2x;
color: $gray-50;
}
}
.configure-btn {
background: #3b82f6;
color: white;
background: $primary-color;
color: $white;
border: none;
border-radius: 6px;
padding: 8px 16px;
font-size: 14px;
border-radius: $corner-radius-sm;
padding: $unit $unit-2x;
font-size: $font-size-small;
font-weight: 500;
cursor: pointer;
transition: background-color 0.2s;
&:hover {
background: #2563eb;
background: darken($primary-color, 10%);
}
}

View file

@ -15,16 +15,73 @@
}
</script>
<NodeViewWrapper class="edra-media-placeholder-wrapper" contenteditable={false} spellcheck={false}>
<NodeViewWrapper class="edra-iframe-placeholder-wrapper" contenteditable={false} spellcheck={false}>
<!-- svelte-ignore a11y_click_events_have_key_events -->
<span
class="edra-media-placeholder-content"
onclick={handleClick}
tabindex="0"
role="button"
aria-label="Insert An Audio"
>
<CodeXML class="edra-media-placeholder-icon" />
<span class="edra-media-placeholder-text">Insert An IFrame</span>
</span>
<div class="edra-iframe-placeholder-container">
<button
class="edra-iframe-placeholder-content"
onclick={handleClick}
tabindex="0"
aria-label="Insert An IFrame"
>
<CodeXML class="edra-iframe-placeholder-icon" />
<span class="edra-iframe-placeholder-text">Insert An IFrame</span>
</button>
</div>
</NodeViewWrapper>
<style lang="scss">
@import '$styles/variables';
.edra-iframe-placeholder-wrapper {
width: 100%;
margin-bottom: 1rem;
}
.edra-iframe-placeholder-container {
margin-left: 2.25rem;
margin-right: 2.25rem;
@media (max-width: 768px) {
margin-left: 2rem;
margin-right: 2rem;
}
}
.edra-iframe-placeholder-content {
width: 100%;
padding: $unit-3x;
background-color: $gray-95;
border: 2px dashed $gray-85;
border-radius: $corner-radius;
display: flex;
align-items: center;
justify-content: center;
gap: $unit-2x;
cursor: pointer;
transition: all 0.2s ease;
color: $gray-50;
&:hover {
background-color: $gray-90;
border-color: $gray-70;
color: $gray-40;
}
&:focus {
outline: none;
border-color: $primary-color;
box-shadow: 0 0 0 3px rgba($primary-color, 0.1);
}
}
:global(.edra-iframe-placeholder-icon) {
width: $unit-3x;
height: $unit-3x;
}
.edra-iframe-placeholder-text {
font-size: $font-size-small;
font-weight: 500;
}
</style>

View file

@ -150,46 +150,55 @@
</NodeViewWrapper>
<style lang="scss">
@import '$styles/variables';
.edra-url-embed-placeholder-wrapper {
margin: 1rem 0;
margin-bottom: 1rem;
margin-left: 2.25rem;
margin-right: 2.25rem;
@media (max-width: 768px) {
margin-left: 2rem;
margin-right: 2rem;
}
}
.url-input-container {
display: flex;
gap: 0.5rem;
padding: 1rem;
background: var(--grey-95, #f8f9fa);
border: 2px solid var(--grey-85, #e9ecef);
border-radius: 8px;
gap: $unit-half;
padding: $unit-2x;
background: $gray-95;
border: 2px solid $gray-85;
border-radius: $corner-radius;
}
.url-input {
flex: 1;
padding: 0.5rem 1rem;
border: 1px solid var(--grey-80, #dee2e6);
border-radius: 6px;
font-size: 0.875rem;
background: white;
padding: $unit $unit-2x;
border: 1px solid $gray-80;
border-radius: $corner-radius-sm;
font-size: $font-size-small;
background: $white;
&:focus {
outline: none;
border-color: var(--primary-color, #3b82f6);
border-color: $primary-color;
}
}
.submit-button {
padding: 0.5rem 1rem;
background: var(--primary-color, #3b82f6);
color: white;
padding: $unit $unit-2x;
background: $primary-color;
color: $white;
border: none;
border-radius: 6px;
font-size: 0.875rem;
border-radius: $corner-radius-sm;
font-size: $font-size-small;
font-weight: 500;
cursor: pointer;
transition: background-color 0.2s;
&:hover:not(:disabled) {
background: var(--primary-hover, #2563eb);
background: darken($primary-color, 10%);
}
&:disabled {
@ -203,17 +212,17 @@
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 2rem;
border: 2px dashed var(--grey-80, #dee2e6);
border-radius: 8px;
background: var(--grey-95, #f8f9fa);
gap: $unit-half;
padding: $unit-3x;
border: 2px dashed $gray-85;
border-radius: $corner-radius;
background: $gray-95;
cursor: pointer;
transition: all 0.2s ease;
&:hover:not(.loading):not(.error) {
border-color: var(--grey-60, #adb5bd);
background: var(--grey-90, #e9ecef);
border-color: $gray-70;
background: $gray-90;
}
&.loading {
@ -221,47 +230,47 @@
}
&.error {
border-color: var(--red-60, #dc3545);
border-color: $red-60;
background: #fee;
cursor: default;
}
}
.placeholder-icon {
width: 32px;
height: 32px;
color: var(--grey-50, #6c757d);
width: $unit-4x;
height: $unit-4x;
color: $gray-50;
}
.error .placeholder-icon {
color: var(--red-60, #dc3545);
color: $red-60;
}
.placeholder-text {
font-size: 0.875rem;
color: var(--grey-30, #495057);
font-size: $font-size-small;
color: $gray-30;
}
.error-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
gap: $unit-half;
}
.retry-button {
padding: 0.25rem 0.75rem;
padding: $unit-half $unit-2x;
background: transparent;
color: var(--red-60, #dc3545);
border: 1px solid var(--red-60, #dc3545);
border-radius: 4px;
font-size: 0.75rem;
color: $red-60;
border: 1px solid $red-60;
border-radius: $corner-radius-xs;
font-size: $font-size-extra-small;
cursor: pointer;
transition: all 0.2s;
&:hover {
background: var(--red-60, #dc3545);
color: white;
background: $red-60;
color: $white;
}
}

View file

@ -15,16 +15,73 @@
}
</script>
<NodeViewWrapper class="edra-media-placeholder-wrapper" contenteditable="false">
<NodeViewWrapper class="edra-video-placeholder-wrapper" contenteditable="false">
<!-- svelte-ignore a11y_click_events_have_key_events -->
<span
class="edra-media-placeholder-content"
onclick={handleClick}
tabindex="0"
role="button"
aria-label="Insert A Video"
>
<Video class="edra-media-placeholder-icon" />
<span class="edra-media-placeholder-text">Insert A Video</span>
</span>
<div class="edra-video-placeholder-container">
<button
class="edra-video-placeholder-content"
onclick={handleClick}
tabindex="0"
aria-label="Insert A Video"
>
<Video class="edra-video-placeholder-icon" />
<span class="edra-video-placeholder-text">Insert A Video</span>
</button>
</div>
</NodeViewWrapper>
<style lang="scss">
@import '$styles/variables';
.edra-video-placeholder-wrapper {
width: 100%;
margin-bottom: 1rem;
}
.edra-video-placeholder-container {
margin-left: 2.25rem;
margin-right: 2.25rem;
@media (max-width: 768px) {
margin-left: 2rem;
margin-right: 2rem;
}
}
.edra-video-placeholder-content {
width: 100%;
padding: $unit-3x;
background-color: $gray-95;
border: 2px dashed $gray-85;
border-radius: $corner-radius;
display: flex;
align-items: center;
justify-content: center;
gap: $unit-2x;
cursor: pointer;
transition: all 0.2s ease;
color: $gray-50;
&:hover {
background-color: $gray-90;
border-color: $gray-70;
color: $gray-40;
}
&:focus {
outline: none;
border-color: $primary-color;
box-shadow: 0 0 0 3px rgba($primary-color, 0.1);
}
}
:global(.edra-video-placeholder-icon) {
width: $unit-3x;
height: $unit-3x;
}
.edra-video-placeholder-text {
font-size: $font-size-small;
font-weight: 500;
}
</style>