@samitouri / QOSami-HFS / commits / 0dab6193

a11y: several improvements

Massimo Melina committed Jan 11, 2024 at 10:53 UTC 0dab6193e68569635dadaeb215126b1f4fccc2b3
8 files changed +17 -9
admin/src/App.ts
+1
@@ -54,6 +54,7 @@ function Routed() {
54 navigate(path || '/')
55 })
56 return h(Fragment, {},
57 + h('h1', { hidden: true }, "Admin-panel"),
58 !large && h(StickyBar, { title, openMenu: () => setOpen(true) }),
59 !large && h(Drawer, { anchor:'left', open, onClose(){ setOpen(false) } },
60 h(MainMenu, {
frontend/src/Breadcrumbs.ts
+4 -3
@@ -16,8 +16,8 @@ export function Breadcrumbs() {
16 const breadcrumbs = currentPath ? currentPath.split('/').map(x => [prev += x + '/', decodeURIComponent(x)]) : []
17 const {t} = useI18N()
18 return h(Fragment, {},
19 - h(Breadcrumb, { label: hIcon('parent', { title: t`parent folder` }), path: parent }),
20 - h(Breadcrumb, { label: hIcon('home', { title: t`home` }), path: base, current: !currentPath }),
19 + h(Breadcrumb, { label: hIcon('parent'), title: t`parent folder`, path: parent }),
20 + h(Breadcrumb, { label: hIcon('home'), title: t`home`, path: base, current: !currentPath }),
21 breadcrumbs.map(([path,label], i) =>
22 h(Breadcrumb, {
23 key: path,
@@ -28,7 +28,7 @@ export function Breadcrumbs() {
28 )
29 }
30
31 -function Breadcrumb({ path, label, current }:{ current?: boolean, path: string, label?: string | ReactElement }) {
31 +function Breadcrumb({ path, label, current, title }:{ current?: boolean, path: string, label?: string | ReactElement, title?: string }) {
32 const PAD = '\u00A0\u00A0' // make small elements easier to tap. Don't use min-width 'cause it requires display-inline that breaks word-wrapping
33 if (typeof label === 'string' && label.length < 3)
34 label = PAD + label + PAD
@@ -38,6 +38,7 @@ function Breadcrumb({ path, label, current }:{ current?: boolean, path: string,
38 return h(Link, {
39 className: 'breadcrumb',
40 to: path || '/',
41 + title,
42 async onClick(ev) {
43 if (!current) return
44 if (typeof label !== 'string')
frontend/src/BrowseFiles.ts
+1
@@ -205,6 +205,7 @@ const Entry = memo(({ entry, midnight, separator }: EntryProps) => {
205 h(CustomCode, { name: 'entry', props: { entry }, ifEmpty: () => h(Fragment, {},
206 showFilter && h(Checkbox, {
207 disabled: isLink,
208 + 'aria-label': entry.name,
209 value: selected[uri],
210 onChange(v){
211 if (v)
frontend/src/FilterBar.ts
+1
@@ -22,6 +22,7 @@ export function FilterBar() {
22 h(Checkbox, {
23 value: all,
24 tabIndex,
25 + 'aria-label': "Select all",
26 onContextMenu(ev) {
27 ev.preventDefault()
28 select(undefined)
frontend/src/dialog.ts
+1
@@ -82,6 +82,7 @@ export function alertDialog(msg: ReactElement | string | Error, type:AlertType='
82 title: t(_.capitalize(type)),
83 icon: '!',
84 onClose: ret.resolve,
85 + dialogProps: { role: 'alertdialog' },
86 Content
87 }))
88
frontend/src/icons.ts
+1 -1
@@ -50,7 +50,7 @@ document.fonts.ready.then(async ()=> {
50 })
51
52 interface IconProps { name:string, className?:string, alt?:string, [rest:string]: any }
53 -export const Icon = memo(({ name, alt, className='', ...props }: IconProps) => {
53 +export const Icon = memo(({ name, alt='', className='', ...props }: IconProps) => {
54 if (!name) return null
55 const [emoji, clazz=name] = SYS_ICONS[name] || []
56 const { iconsReady } = useSnapState()
frontend/src/menu.ts
+4 -3
@@ -40,7 +40,7 @@ export function MenuPanel() {
40 const list = useMemo(() => Object.keys(selected).map(s => s.slice(ofs, s.endsWith('/') ? -1 : Infinity)).join('*'), [selected])
41
42 // avoid useless dom changes while we are still waiting for necessary data
43 - const [changingButton, setChangingButton] = useState('')
43 + const [changingButton, setChangingButton] = useState<'' | 'upload' | 'delete'>('')
44 useEffect(() => {
45 if (can_upload !== undefined)
46 setChangingButton(showFilter && can_delete ? 'delete' : (can_upload || qs.length > 0) ? 'upload' : '')
@@ -68,8 +68,9 @@ export function MenuPanel() {
68 id: 'upload-button',
69 icon: 'upload',
70 label: t`Upload`,
71 - tabIndex: changingButton === 'upload' ? undefined : -1,
72 - className: changingButton === 'upload' ? 'show-sliding ' + (uploading ? 'ani-working' : '') : 'before-sliding',
71 + disabled: !changingButton,
72 + tabIndex: changingButton ? undefined : -1,
73 + className: changingButton ? 'show-sliding ' + (uploading ? 'ani-working' : '') : 'before-sliding',
74 onClick: showUpload,
75 }),
76 h(MenuButton, showFilter && can_delete ? {
shared/dialogs.ts
+4 -2
@@ -101,8 +101,10 @@ function Dialog(d:DialogOptions) {
101 className: 'dialog-icon dialog-closer',
102 onClick() { closeDialog() }
103 }, d.closableContent),
104 - d.icon && h('div', { className: 'dialog-icon dialog-type' + (typeof d.icon === 'string' ? ' dialog-icon-text' : '') },
105 - componentOrNode(d.icon)),
104 + d.icon && h('div', {
105 + className: 'dialog-icon dialog-type' + (typeof d.icon === 'string' ? ' dialog-icon-text' : ''),
106 + 'aria-hidden': true,
107 + }, componentOrNode(d.icon)),
108 h('div', { className: 'dialog-title' }, componentOrNode(d.title)),
109 h('div', { className: 'dialog-content' }, h(d.Content || 'div'))
110 )