Skip to content

Commit

Permalink
feat(palette): add keyboard support for palette entries
Browse files Browse the repository at this point in the history
Closes #503
  • Loading branch information
Niklas Kiefer committed Oct 10, 2023
1 parent feefc13 commit 8690082
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 44 deletions.
8 changes: 8 additions & 0 deletions packages/form-js-editor/assets/form-js-editor-base.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
--cds-border-strong,
var(--cds-border-strong-01, var(--color-grey-225-10-80))
);
--color-palette-field-focus: var(--cds-border-interactive, var(--color-blue-219-100-53));
--color-palette-field-hover-background: var(--cds-background-hover, var(--color-grey-225-10-90));
--cursor-palette-field: grab;
--palette-width: 250px;
Expand Down Expand Up @@ -625,6 +626,8 @@
flex-direction: column;
justify-content: center;
font-size: 11px;
align-items: center;
border: none;
user-select: none;
color: var( --color-palette-field);
background: var(--color-palette-field-background);
Expand All @@ -634,6 +637,11 @@
width: 68px;
}

.fjs-palette-container .fjs-palette-field:focus {
outline: none;
border: solid 1px var(--color-palette-field-focus);
}

.fjs-palette-field .fjs-palette-field-icon {
margin: 0 auto;
}
Expand Down
30 changes: 6 additions & 24 deletions packages/form-js-editor/src/features/palette/components/Palette.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import {

import {
CloseIcon,
iconsByType,
SearchIcon
} from '../../../render/components/icons';

import PaletteEntry from './PaletteEntry';

import { formFields } from '@bpmn-io/form-js-viewer';

export const PALETTE_ENTRIES = formFields.filter(({ config: fieldConfig }) => fieldConfig.type !== 'default').map(({ config: fieldConfig }) => {
Expand Down Expand Up @@ -120,20 +121,11 @@ export default function Palette(props) {
<span class="fjs-palette-group-title">{ label }</span>
<div class="fjs-palette-fields fjs-drag-container fjs-no-drop">
{
entries.map(({ label, type }) => {
const Icon = iconsByType(type);

entries.map(entry => {
return (
<div
class="fjs-palette-field fjs-drag-copy fjs-no-drop"
data-field-type={ type }
title={ `Create ${getIndefiniteArticle(type)} ${label} element` }
>
{
Icon ? <Icon class="fjs-palette-field-icon" width="36" height="36" viewBox="0 0 54 54" /> : null
}
<span class="fjs-palette-field-text">{ label }</span>
</div>
<PaletteEntry
{ ...entry }
/>
);
})
}
Expand Down Expand Up @@ -174,14 +166,4 @@ function groupEntries(entries) {
});

return groups.filter(g => g.entries.length);
}

function getIndefiniteArticle(type) {
if ([
'image'
].includes(type)) {
return 'an';
}

return 'a';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {
iconsByType
} from '../../../render/components/icons';

import { useService } from '../../../render/hooks';

export default function PaletteEntry(props) {
const {
type,
label
} = props;

const modeling = useService('modeling');
const formEditor = useService('formEditor');

const Icon = iconsByType(type);

const onKeyDown = (event) => {
if (event.code === 'Enter') {

const { fieldType: type } = event.target.dataset;

const { schema } = formEditor._getState();

// add new form field to last position
modeling.addFormField({ type }, schema, schema.components.length);
}
};

return (
<button
class="fjs-palette-field fjs-drag-copy fjs-no-drop"
data-field-type={ type }
title={ `Create ${getIndefiniteArticle(type)} ${label} element` }
onKeyDown={ onKeyDown }
>
{
Icon ? <Icon class="fjs-palette-field-icon" width="36" height="36" viewBox="0 0 54 54" /> : null
}
<span class="fjs-palette-field-text">{ label }</span>
</button>
);
}


// helpers ///////////

function getIndefiniteArticle(type) {
if ([
'image'
].includes(type)) {
return 'an';
}

return 'a';
}
82 changes: 62 additions & 20 deletions packages/form-js-editor/test/spec/features/palette/Palette.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,65 @@ describe('palette', function() {
});


describe('keyboard support', function() {


it('should add entry on ENTER', async function() {

// given
const spy = sinon.spy();

const schema = {
components: []
};

const result = createPalette({
container,
modeling: { addFormField: spy },
formEditor: { _getState: () => ({ schema }) }
});

const entry = result.container.querySelector('[data-field-type="textfield"]');

// when
fireEvent.focus(entry);
fireEvent.keyDown(entry, { key: 'Enter', code: 'Enter' });

// then
expect(spy).to.have.been.calledOnceWith({ type: 'textfield' }, schema, 0);
});


it('should add entry to last position', async function() {

// given
const spy = sinon.spy();

const schema = {
components: [ {
type: 'textfield',
id: 'foo'
} ]
};

const result = createPalette({
container,
modeling: { addFormField: spy },
formEditor: { _getState: () => ({ schema }) }
});

const entry = result.container.querySelector('[data-field-type="textfield"]');

// when
fireEvent.focus(entry);
fireEvent.keyDown(entry, { key: 'Enter', code: 'Enter' });

// then
expect(spy).to.have.been.calledOnceWith({ type: 'textfield' }, schema, 1);
});
});


describe('a11y', function() {

it('should have no violations', async function() {
Expand All @@ -183,17 +242,7 @@ describe('palette', function() {
const result = createPalette({ container });

// then
// @Note(pinussilvestrus): the palette entries are currently
// not keyboard accessible, as we need to invest in an overall
// editor keyboard experience
// cf. https://github.com/bpmn-io/form-js/issues/536
await expectNoViolations(result.container, {
rules: {
'scrollable-region-focusable': {
enabled: false
}
}
});
await expectNoViolations(result.container);
});


Expand All @@ -210,15 +259,8 @@ describe('palette', function() {
fireEvent.input(search, { target: { value: 'text' } });

// then
await expectNoViolations(result.container, {
rules: {
'scrollable-region-focusable': {
enabled: false
}
}
});
await expectNoViolations(result.container);
});

});

});
Expand All @@ -230,7 +272,7 @@ function createPalette(options = {}) {
const { container } = options;

return render(
WithFormEditorContext(<Palette />),
WithFormEditorContext(<Palette />, options),
{
container
}
Expand Down

0 comments on commit 8690082

Please sign in to comment.