summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/settings/settings_block.vue')
-rw-r--r--app/assets/javascripts/vue_shared/components/settings/settings_block.vue84
1 files changed, 75 insertions, 9 deletions
diff --git a/app/assets/javascripts/vue_shared/components/settings/settings_block.vue b/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
index 92ae4575c52..e75fedbb1d7 100644
--- a/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
+++ b/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
@@ -1,5 +1,7 @@
<script>
import { GlButton } from '@gitlab/ui';
+import { uniqueId } from 'lodash';
+
import { __ } from '~/locale';
export default {
@@ -15,35 +17,99 @@ export default {
default: false,
required: false,
},
+ collapsible: {
+ type: Boolean,
+ default: true,
+ required: false,
+ },
},
data() {
return {
- sectionExpanded: false,
+ // Non-collapsible sections should always be expanded.
+ // For collapsible sections, fall back to defaultExpanded.
+ sectionExpanded: !this.collapsible || this.defaultExpanded,
};
},
computed: {
- expanded() {
- return this.defaultExpanded || this.sectionExpanded;
- },
toggleText() {
- return this.expanded ? __('Collapse') : __('Expand');
+ const { collapseText, expandText } = this.$options.i18n;
+ return this.sectionExpanded ? collapseText : expandText;
+ },
+ settingsContentId() {
+ return uniqueId('settings_content_');
},
+ settingsLabelId() {
+ return uniqueId('settings_label_');
+ },
+ toggleButtonAriaLabel() {
+ const { collapseAriaLabel, expandAriaLabel } = this.$options.i18n;
+ return this.sectionExpanded ? collapseAriaLabel : expandAriaLabel;
+ },
+ ariaExpanded() {
+ return String(this.sectionExpanded);
+ },
+ },
+ methods: {
+ toggleSectionExpanded() {
+ this.sectionExpanded = !this.sectionExpanded;
+
+ if (this.sectionExpanded) {
+ this.$refs.settingsContent.focus();
+ }
+ },
+ },
+ i18n: {
+ collapseText: __('Collapse'),
+ expandText: __('Expand'),
+ collapseAriaLabel: __('Collapse settings section'),
+ expandAriaLabel: __('Expand settings section'),
},
};
</script>
<template>
- <section class="settings" :class="{ 'no-animate': !slideAnimated, expanded }">
+ <section class="settings" :class="{ 'no-animate': !slideAnimated, expanded: sectionExpanded }">
<div class="settings-header">
- <h4><slot name="title"></slot></h4>
- <gl-button @click="sectionExpanded = !sectionExpanded">
+ <h4>
+ <span
+ v-if="collapsible"
+ :id="settingsLabelId"
+ role="button"
+ tabindex="0"
+ class="gl-cursor-pointer"
+ :aria-controls="settingsContentId"
+ :aria-expanded="ariaExpanded"
+ data-testid="section-title-button"
+ @click="toggleSectionExpanded"
+ @keydown.enter.space="toggleSectionExpanded"
+ >
+ <slot name="title"></slot>
+ </span>
+ <template v-else>
+ <slot name="title"></slot>
+ </template>
+ </h4>
+ <gl-button
+ v-if="collapsible"
+ :aria-controls="settingsContentId"
+ :aria-expanded="ariaExpanded"
+ :aria-label="toggleButtonAriaLabel"
+ @click="toggleSectionExpanded"
+ >
{{ toggleText }}
</gl-button>
<p>
<slot name="description"></slot>
</p>
</div>
- <div class="settings-content">
+ <div
+ :id="settingsContentId"
+ ref="settingsContent"
+ :aria-labelledby="settingsLabelId"
+ tabindex="-1"
+ role="region"
+ class="settings-content"
+ >
<slot></slot>
</div>
</section>