Skip to content

Commit

Permalink
feat(UIBuilder): Add accessibility props to ui builder (microsoft#15820)
Browse files Browse the repository at this point in the history
Add accessibility props to ui builder
  • Loading branch information
jurokapsiar committed Nov 4, 2020
1 parent daeda45 commit d493a6b
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 43 deletions.
1 change: 1 addition & 0 deletions packages/fluentui/CHANGELOG.md
Expand Up @@ -77,6 +77,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Added new `borderActive` color design token to `categoryColorScheme` @ling1726 ([#15717](https://github.com/microsoft/fluentui/pull/15717))

### Documentation
- UIBuilder: Add accessibility props panel @jurokapsiar ([#15820](https://github.com/microsoft/fluentui/pull/15820))
- Add VoiceOver issue in known `accessibilityIssues` for `Toolbar` on `menuitemradio` @yuanboxue-amber ([#15203](https://github.com/microsoft/fluentui/pull/15203))
- Fixed icon margins after code change in UI builder @vyhnalekl ([#14859](https://github.com/microsoft/fluentui/pull/14859))
- Fixed image with no height in build mode - UI builder @vyhnalekl ([#14893](https://github.com/microsoft/fluentui/pull/14893))
Expand Down
175 changes: 132 additions & 43 deletions packages/fluentui/react-builder/src/components/Knobs.tsx
@@ -1,7 +1,7 @@
import * as _ from 'lodash';
import * as React from 'react';
import { Header /* Slider */ } from '@fluentui/react-northstar';
import { ComponentInfo } from '../componentInfo/types';
import { Menu, tabListBehavior } from '@fluentui/react-northstar';
import { ComponentInfo, ComponentProp } from '../componentInfo/types';
import { JSONTreeElement } from './types';
import { MultiTypeKnob } from '../config';

Expand Down Expand Up @@ -52,6 +52,82 @@ import { MultiTypeKnob } from '../config';
//
// const rowStyle = { padding: '0.1rem 0.25rem' };

const A11YPROPS: ComponentProp[] = [
{
name: 'id',
required: false,
defaultValue: '',
tags: [],
description: 'ID of an element',
types: [{ name: 'string' }],
},
{
name: 'role',
required: false,
defaultValue: '',
tags: [],
description: 'accessiblerole of an element',
types: [{ name: 'string' }],
},
{
name: 'aria-label',
required: false,
defaultValue: '',
tags: [],
description: 'define a string that labels the current element',
types: [{ name: 'string' }],
},
{
name: 'aria-labelledby',
required: false,
defaultValue: '',
tags: [],
description: 'establishes relationships between objects and their label(s)',
types: [{ name: 'string' }],
},
{
name: 'aria-describedby',
required: false,
defaultValue: '',
tags: [],
description: 'indicates the IDs of the elements that describe the object',
types: [{ name: 'string' }],
},
{
name: 'title',
required: false,
defaultValue: '',
tags: [],
description: 'specifies extra information about an element',
types: [{ name: 'string' }],
},
{
name: 'aria-hidden',
required: false,
defaultValue: false,
tags: [],
description: 'removes the element and all of its children from the accessibility tree',
types: [{ name: 'boolean' }],
},
{
name: 'tabIndex',
required: false,
defaultValue: 0,
tags: [],
description:
'indicates that its element can be focused, and where it participates in sequential keyboard navigation',
types: [{ name: 'number' }],
},
{
name: 'data-is-focusable',
required: false,
defaultValue: false,
tags: [],
description: 'define if data is focusable',
types: [{ name: 'boolean' }],
},
];

type DesignKnobProps = {
onPropChange: ({
jsonTreeElement,
Expand All @@ -67,26 +143,72 @@ type DesignKnobProps = {
};

export const Knobs: React.FunctionComponent<DesignKnobProps> = ({ onPropChange, info, jsonTreeElement }) => {
const [menuActivePane, setMenuActivePane] = React.useState<'props' | 'accessibility'>('props');
return (
<div>
<Header as="h3">Props</Header>
{info.props
// only allow knobs for regular props, not default props
.filter(prop => !/default[A-Z]/.test(prop.name))
.map(prop => {
<Menu
accessibility={tabListBehavior}
defaultActiveIndex={0}
items={[
{
key: 'props',
content: 'Props',
onClick: () => setMenuActivePane('props'),
},
{
key: 'accessibility',
content: 'Accessibility',
onClick: () => setMenuActivePane('accessibility'),
},
]}
underlined
primary
styles={{ marginBottom: '1rem', marginTop: '1.5rem' }}
/>
{menuActivePane === 'props' &&
info.props
// only allow knobs for regular props, not default props
.filter(prop => !/default[A-Z]/.test(prop.name))
.map(prop => {
const propValue = jsonTreeElement.props?.[prop.name];
const types = _.uniq(_.map(prop.types, 'name'));
const isLiteral = _.every(types, name => name === 'literal');
const options = isLiteral ? _.map(prop.types, 'value') : null;

const defaultValues = {
boolean: false,
number: 0,
string: '',
};

const value = typeof propValue !== 'undefined' ? propValue : defaultValues[types[0]];

return (
<MultiTypeKnob
key={prop.name}
label={prop.name}
types={types as any}
literalOptions={options}
value={value}
onChange={value => {
onPropChange({ jsonTreeElement, name: prop.name, value });
}}
/>
);
})}

{menuActivePane === 'accessibility' &&
A11YPROPS.filter(prop => !/default[A-Z]/.test(prop.name)).map(prop => {
const propValue = jsonTreeElement.props?.[prop.name];
const types = _.uniq(_.map(prop.types, 'name'));
const isLiteral = _.every(types, name => name === 'literal');
const options = isLiteral ? _.map(prop.types, 'value') : null;

const defaultValues = {
boolean: false,
number: 0,
string: '',
};

const value = typeof propValue !== 'undefined' ? propValue : defaultValues[types[0]];

return (
<MultiTypeKnob
key={prop.name}
Expand All @@ -100,39 +222,6 @@ export const Knobs: React.FunctionComponent<DesignKnobProps> = ({ onPropChange,
/>
);
})}
{/*
<Header as="h3">Design</Header>
{_.map(knobs, knob => {
const value = jsonTreeElement.props && jsonTreeElement.props.design && jsonTreeElement.props.design[knob.label];
return (
<div key={knob.label} style={{ ...rowStyle, marginBottom: '0.5rem' }}>
{knob.kind === 'slider' ? (
<>
<code style={{ float: 'right' }}>{JSON.stringify(value, null, 2)}</code>
<div>{knob.label}</div>
<Slider
fluid
step={1}
min={0}
max={knob.ramp.length - 1}
{...(value && {
value: jsonTreeElement.props.design[knob.label],
})}
onChange={(e, data) => {
onPropChange({ jsonTreeElement, name: knob.label, value: knob.ramp[+data.value] });
}}
/>
</>
) : knob.kind === 'divider' ? (
<Divider content={knob.label} style={{ width: '100%' }} />
) : (
<div>UNKNOWN</div>
)}
</div>
);
})}
*/}
</div>
);
};

0 comments on commit d493a6b

Please sign in to comment.