kopia lustrzana https://github.com/wagtail/wagtail
Add preview button with eye icon in block chooser
rodzic
d25a67a4b8
commit
77bcbf702d
|
|
@ -77,6 +77,31 @@ $spacing-sm: theme('spacing.5');
|
|||
}
|
||||
}
|
||||
|
||||
.w-combobox__option-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr theme('spacing.6');
|
||||
}
|
||||
|
||||
.w-combobox__option-preview {
|
||||
background: none;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
|
||||
.icon {
|
||||
color: theme('colors.icon-secondary');
|
||||
width: theme('spacing.3');
|
||||
height: theme('spacing.3');
|
||||
}
|
||||
}
|
||||
|
||||
.w-combobox__option-row--col1 {
|
||||
grid-column: 1 / span 1;
|
||||
}
|
||||
|
||||
.w-combobox__option-row--col2 {
|
||||
grid-column: 2 / span 1;
|
||||
}
|
||||
|
||||
.w-combobox__option {
|
||||
display: grid;
|
||||
grid-template-columns: theme('spacing.8') 1fr;
|
||||
|
|
@ -100,14 +125,6 @@ $spacing-sm: theme('spacing.5');
|
|||
}
|
||||
}
|
||||
|
||||
.w-combobox__option--col1 {
|
||||
grid-column: 1 / span 1;
|
||||
}
|
||||
|
||||
.w-combobox__option--col2 {
|
||||
grid-column: 2 / span 1;
|
||||
}
|
||||
|
||||
.w-combobox__option-icon {
|
||||
color: theme('colors.icon-secondary');
|
||||
height: theme('spacing.4');
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ describe('ComboBox', () => {
|
|||
|
||||
it('combines two categories into one, with two columns', () => {
|
||||
expect(wrapper.find('.w-combobox__optgroup-label')).toHaveLength(1);
|
||||
expect(wrapper.find('.w-combobox__option--col1')).toHaveLength(3);
|
||||
expect(wrapper.find('.w-combobox__option--col2')).toHaveLength(2);
|
||||
expect(wrapper.find('.w-combobox__option-row--col1')).toHaveLength(3);
|
||||
expect(wrapper.find('.w-combobox__option-row--col2')).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import findMatches from './findMatches';
|
|||
export const comboBoxTriggerLabel = gettext('Insert a block');
|
||||
export const comboBoxLabel = gettext('Search options…');
|
||||
export const comboBoxNoResults = gettext('No results');
|
||||
const comboBoxPreviewLabel = gettext('Preview');
|
||||
|
||||
export interface ComboBoxCategory<ItemType> {
|
||||
type: string;
|
||||
|
|
@ -23,6 +24,7 @@ export interface ComboBoxItem {
|
|||
description?: string | null;
|
||||
icon?: string | JSX.Element | null;
|
||||
blockDefId?: string;
|
||||
isPreviewable?: boolean;
|
||||
category?: string;
|
||||
render?: (props: { option: ComboBoxItem }) => JSX.Element | string;
|
||||
}
|
||||
|
|
@ -183,7 +185,7 @@ export default function ComboBox<ComboBoxOption extends ComboBoxItem>({
|
|||
setLastHighlightedIndex(highlightedIndex);
|
||||
}
|
||||
|
||||
const selectedBlock =
|
||||
const previewedBlock =
|
||||
inputItems[highlightedIndex] || inputItems[lastHighlightedIndex];
|
||||
|
||||
return (
|
||||
|
|
@ -257,21 +259,36 @@ export default function ComboBox<ComboBoxOption extends ComboBoxItem>({
|
|||
return (
|
||||
<div
|
||||
key={item.type}
|
||||
{...getItemProps({ item, index: itemIndex })}
|
||||
className={`w-combobox__option w-combobox__option--col${itemColumn}`}
|
||||
className={`w-combobox__option-row w-combobox__option-row--col${itemColumn}`}
|
||||
>
|
||||
<div className="w-combobox__option-icon">
|
||||
{icon}
|
||||
{/* Support for rich text options using text as an icon (for example "B" for bold). */}
|
||||
{itemLabel && !hasIcon ? (
|
||||
<span>{itemLabel}</span>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="w-combobox__option-text">
|
||||
{item.render
|
||||
? item.render({ option: item })
|
||||
: description}
|
||||
<div
|
||||
{...getItemProps({ item, index: itemIndex })}
|
||||
className="w-combobox__option"
|
||||
>
|
||||
<div className="w-combobox__option-icon">
|
||||
{icon}
|
||||
{/* Support for rich text options using text as an icon (for example "B" for bold). */}
|
||||
{itemLabel && !hasIcon ? (
|
||||
<span>{itemLabel}</span>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="w-combobox__option-text">
|
||||
{item.render
|
||||
? item.render({ option: item })
|
||||
: description}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{item.isPreviewable ? (
|
||||
<button
|
||||
className="w-combobox__option-preview"
|
||||
aria-label={comboBoxPreviewLabel}
|
||||
type="button"
|
||||
onClick={() => setHighlightedIndex(itemIndex)}
|
||||
>
|
||||
<Icon name="view" />
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
|
@ -280,7 +297,12 @@ export default function ComboBox<ComboBoxOption extends ComboBoxItem>({
|
|||
})}
|
||||
</div>
|
||||
</div>
|
||||
{selectedBlock ? <ComboBoxPreview item={selectedBlock} /> : null}
|
||||
{previewedBlock?.isPreviewable ? (
|
||||
<ComboBoxPreview
|
||||
item={previewedBlock}
|
||||
previewLabel={comboBoxPreviewLabel}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,134 +53,154 @@ exports[`ComboBox rendering matches the snapshot 1`] = `
|
|||
Blocks
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
className="w-combobox__option w-combobox__option--col1"
|
||||
id="downshift-1-item-0"
|
||||
className="w-combobox__option-row w-combobox__option-row--col1"
|
||||
key="blockquote"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
aria-selected="false"
|
||||
className="w-combobox__option"
|
||||
id="downshift-1-item-0"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<Icon
|
||||
name="blockquote"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
Blockquote
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
>
|
||||
<Icon
|
||||
name="blockquote"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
Blockquote
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
className="w-combobox__option w-combobox__option--col1"
|
||||
id="downshift-1-item-1"
|
||||
className="w-combobox__option-row w-combobox__option-row--col1"
|
||||
key="paragraph"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
aria-selected="false"
|
||||
className="w-combobox__option"
|
||||
id="downshift-1-item-1"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<span
|
||||
className="my-icon"
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
>
|
||||
P
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
Paragraph
|
||||
<span
|
||||
className="my-icon"
|
||||
>
|
||||
P
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
Paragraph
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
className="w-combobox__option w-combobox__option--col1"
|
||||
id="downshift-1-item-2"
|
||||
className="w-combobox__option-row w-combobox__option-row--col1"
|
||||
key="heading-one"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
aria-selected="false"
|
||||
className="w-combobox__option"
|
||||
id="downshift-1-item-2"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<Icon
|
||||
name="custom"
|
||||
viewBox="0 0 1024 1024"
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
>
|
||||
<path
|
||||
d="M 83.625 "
|
||||
key="M 83.625 "
|
||||
/>
|
||||
<path
|
||||
d="L 232.535156 "
|
||||
key="L 232.535156 "
|
||||
/>
|
||||
</Icon>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
Heading 1
|
||||
<Icon
|
||||
name="custom"
|
||||
viewBox="0 0 1024 1024"
|
||||
>
|
||||
<path
|
||||
d="M 83.625 "
|
||||
key="M 83.625 "
|
||||
/>
|
||||
<path
|
||||
d="L 232.535156 "
|
||||
key="L 232.535156 "
|
||||
/>
|
||||
</Icon>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
Heading 1
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
className="w-combobox__option w-combobox__option--col2"
|
||||
id="downshift-1-item-3"
|
||||
className="w-combobox__option-row w-combobox__option-row--col2"
|
||||
key="heading-two"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
aria-selected="false"
|
||||
className="w-combobox__option"
|
||||
id="downshift-1-item-3"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<span>
|
||||
H2
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
<span
|
||||
className="custom-text"
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
>
|
||||
H2
|
||||
</span>
|
||||
<span>
|
||||
H2
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
<span
|
||||
className="custom-text"
|
||||
>
|
||||
H2
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
className="w-combobox__option w-combobox__option--col2"
|
||||
id="downshift-1-item-4"
|
||||
className="w-combobox__option-row w-combobox__option-row--col2"
|
||||
key="link"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
aria-selected="false"
|
||||
className="w-combobox__option"
|
||||
id="downshift-1-item-4"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
role="option"
|
||||
>
|
||||
<span>
|
||||
🔗
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
Link
|
||||
<div
|
||||
className="w-combobox__option-icon"
|
||||
>
|
||||
<span>
|
||||
🔗
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="w-combobox__option-text"
|
||||
>
|
||||
Link
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,10 +10,12 @@ interface ComboBoxItem {
|
|||
|
||||
export interface ComboBoxPreviewProps {
|
||||
item: ComboBoxItem;
|
||||
previewLabel: string;
|
||||
}
|
||||
|
||||
export default function ComboBoxPreview({
|
||||
item: { label, description, blockDefId },
|
||||
previewLabel,
|
||||
}: ComboBoxPreviewProps) {
|
||||
const previewURL = blockDefId
|
||||
? new URL(WAGTAIL_CONFIG.ADMIN_URLS.BLOCK_PREVIEW, window.location.href)
|
||||
|
|
@ -23,13 +25,15 @@ export default function ComboBoxPreview({
|
|||
<div className="w-combobox-preview">
|
||||
<iframe
|
||||
className="w-combobox-preview__iframe"
|
||||
title="Preview"
|
||||
title={previewLabel}
|
||||
src={previewURL?.toString()}
|
||||
/>
|
||||
<div className="w-combobox-preview__label">{label}</div>
|
||||
{description ? (
|
||||
<p className="w-combobox-preview__description">{description}</p>
|
||||
) : null}
|
||||
<div className="w-combobox-preview__details">
|
||||
<div className="w-combobox-preview__label">{label}</div>
|
||||
{description ? (
|
||||
<p className="w-combobox-preview__description">{description}</p>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ class StreamBlockMenu extends BaseInsertionControl {
|
|||
description: blockDef.meta.description,
|
||||
icon: blockDef.meta.icon,
|
||||
blockDefId: blockDef.meta.blockDefId,
|
||||
isPreviewable: blockDef.meta.isPreviewable,
|
||||
}));
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -751,7 +751,7 @@ exports[`telepath: wagtail.blocks.StreamBlock it renders menus on opening 1`] =
|
|||
<button type="button" title="Insert a block" class="c-sf-add-button" aria-expanded="true">
|
||||
<svg class="icon icon-plus" aria-hidden="true"><use href="#icon-plus"></use></svg>
|
||||
</button>
|
||||
<div data-tippy-root="" id="tippy-5" style="z-index: 9999; visibility: visible; transition: none; position: absolute; left: 0px; top: 0px; margin: 0px;"><div class="tippy-box" data-state="hidden" tabindex="-1" data-theme="dropdown" data-animation="fade" style="max-width: none; transition-duration: 0ms;" role="tooltip"><div class="tippy-content" data-state="hidden" style="transition-duration: 0ms;"><div><div class="w-combobox-container"><div class="w-combobox"><label id="downshift-0-label" for="downshift-0-input" class="w-sr-only">Search options…</label><div class="w-combobox__field"><input aria-activedescendant="" aria-autocomplete="list" aria-controls="downshift-0-menu" aria-expanded="false" aria-labelledby="downshift-0-label" autocomplete="off" id="downshift-0-input" role="combobox" type="text" placeholder="Search options…" value=""></div><div id="downshift-0-menu" role="listbox" aria-labelledby="downshift-0-label" class="w-combobox__menu"><div class="w-combobox__optgroup"><div role="option" aria-selected="false" id="downshift-0-item-0" class="w-combobox__option w-combobox__option--col1"><div class="w-combobox__option-icon"><svg class="icon icon-placeholder" aria-hidden="true"><use href="#icon-placeholder"></use></svg></div><div class="w-combobox__option-text">Test Block A</div></div><div role="option" aria-selected="false" id="downshift-0-item-1" class="w-combobox__option w-combobox__option--col2"><div class="w-combobox__option-icon"><svg class="icon icon-pilcrow" aria-hidden="true"><use href="#icon-pilcrow"></use></svg></div><div class="w-combobox__option-text">Test Block B</div></div></div></div></div></div></div></div></div></div></div><div data-streamfield-child="" data-contentpath="2">
|
||||
<div data-tippy-root="" id="tippy-5" style="z-index: 9999; visibility: visible; transition: none; position: absolute; left: 0px; top: 0px; margin: 0px;"><div class="tippy-box" data-state="hidden" tabindex="-1" data-theme="dropdown" data-animation="fade" style="max-width: none; transition-duration: 0ms;" role="tooltip"><div class="tippy-content" data-state="hidden" style="transition-duration: 0ms;"><div><div class="w-combobox-container"><div class="w-combobox"><label id="downshift-0-label" for="downshift-0-input" class="w-sr-only">Search options…</label><div class="w-combobox__field"><input aria-activedescendant="" aria-autocomplete="list" aria-controls="downshift-0-menu" aria-expanded="false" aria-labelledby="downshift-0-label" autocomplete="off" id="downshift-0-input" role="combobox" type="text" placeholder="Search options…" value=""></div><div id="downshift-0-menu" role="listbox" aria-labelledby="downshift-0-label" class="w-combobox__menu"><div class="w-combobox__optgroup"><div class="w-combobox__option-row w-combobox__option-row--col1"><div role="option" aria-selected="false" id="downshift-0-item-0" class="w-combobox__option"><div class="w-combobox__option-icon"><svg class="icon icon-placeholder" aria-hidden="true"><use href="#icon-placeholder"></use></svg></div><div class="w-combobox__option-text">Test Block A</div></div></div><div class="w-combobox__option-row w-combobox__option-row--col2"><div role="option" aria-selected="false" id="downshift-0-item-1" class="w-combobox__option"><div class="w-combobox__option-icon"><svg class="icon icon-pilcrow" aria-hidden="true"><use href="#icon-pilcrow"></use></svg></div><div class="w-combobox__option-text">Test Block B</div></div></div></div></div></div></div></div></div></div></div></div><div data-streamfield-child="" data-contentpath="2">
|
||||
<input type="hidden" name="the-prefix-1-deleted" value="">
|
||||
<input type="hidden" name="the-prefix-1-order" value="1">
|
||||
<input type="hidden" name="the-prefix-1-type" value="test_block_b">
|
||||
|
|
@ -974,7 +974,7 @@ exports[`telepath: wagtail.blocks.StreamBlock setError renders error messages 1`
|
|||
</div>"
|
||||
`;
|
||||
|
||||
exports[`telepath: wagtail.blocks.StreamBlock with labels that need escaping it renders correctly 1`] = `"<div class="w-combobox__optgroup"><div role="option" aria-selected="false" id="downshift-2-item-0" class="w-combobox__option w-combobox__option--col1"><div class="w-combobox__option-icon"><svg class="icon icon-placeholder" aria-hidden="true"><use href="#icon-placeholder"></use></svg></div><div class="w-combobox__option-text">Test Block <A></div></div><div role="option" aria-selected="false" id="downshift-2-item-1" class="w-combobox__option w-combobox__option--col2"><div class="w-combobox__option-icon"><svg class="icon icon-pilcrow" aria-hidden="true"><use href="#icon-pilcrow"></use></svg></div><div class="w-combobox__option-text">Test Block <B></div></div></div>"`;
|
||||
exports[`telepath: wagtail.blocks.StreamBlock with labels that need escaping it renders correctly 1`] = `"<div class="w-combobox__optgroup"><div class="w-combobox__option-row w-combobox__option-row--col1"><div role="option" aria-selected="false" id="downshift-2-item-0" class="w-combobox__option"><div class="w-combobox__option-icon"><svg class="icon icon-placeholder" aria-hidden="true"><use href="#icon-placeholder"></use></svg></div><div class="w-combobox__option-text">Test Block <A></div></div></div><div class="w-combobox__option-row w-combobox__option-row--col2"><div role="option" aria-selected="false" id="downshift-2-item-1" class="w-combobox__option"><div class="w-combobox__option-icon"><svg class="icon icon-pilcrow" aria-hidden="true"><use href="#icon-pilcrow"></use></svg></div><div class="w-combobox__option-text">Test Block <B></div></div></div></div>"`;
|
||||
|
||||
exports[`telepath: wagtail.blocks.StreamBlock with unique block type it can add block 1`] = `
|
||||
"<div class="c-sf-help">
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue