Skip to content

Commit 6d07b8d

Browse files
authored
Merge pull request #552 from Harbour-Enterprises/feat/high-contrast-mode
HAR-9797 - feat: added initial support for high contrast mode
2 parents 7aae5d8 + 9e3b43b commit 6d07b8d

14 files changed

Lines changed: 424 additions & 347 deletions

File tree

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<script setup>
2+
import { useHighContrastMode } from '../../composables/use-high-contrast-mode';
3+
24
import { toolbarIcons } from './toolbarIcons.js';
35
6+
const { isHighContrastMode } = useHighContrastMode();
47
const emit = defineEmits(['select']);
58
69
const select = (alignment) => {
@@ -9,11 +12,15 @@ const select = (alignment) => {
912
</script>
1013

1114
<template>
12-
<div class="alignment-buttons">
13-
<div class="button-icon" @click="select('left')" v-html="toolbarIcons.alignLeft" data-item="btn-textAlign-option"></div>
14-
<div class="button-icon" @click="select('center')" v-html="toolbarIcons.alignCenter" data-item="btn-textAlign-option"></div>
15-
<div class="button-icon" @click="select('right')" v-html="toolbarIcons.alignRight" data-item="btn-textAlign-option"></div>
16-
<div class="button-icon" @click="select('justify')" v-html="toolbarIcons.alignJustify" data-item="btn-textAlign-option"></div>
15+
<div class="alignment-buttons" :class="{ 'high-contrast': isHighContrastMode }">
16+
<div class="button-icon" @click="select('left')" v-html="toolbarIcons.alignLeft" data-item="btn-textAlign-option">
17+
</div>
18+
<div class="button-icon" @click="select('center')" v-html="toolbarIcons.alignCenter"
19+
data-item="btn-textAlign-option"></div>
20+
<div class="button-icon" @click="select('right')" v-html="toolbarIcons.alignRight" data-item="btn-textAlign-option">
21+
</div>
22+
<div class="button-icon" @click="select('justify')" v-html="toolbarIcons.alignJustify"
23+
data-item="btn-textAlign-option"></div>
1724
</div>
1825
</template>
1926

@@ -24,27 +31,38 @@ const select = (alignment) => {
2431
width: 100%;
2532
padding: 8px;
2633
box-sizing: border-box;
27-
}
28-
.button-icon {
29-
cursor: pointer;
30-
padding: 5px;
31-
font-size: 16px;
32-
width: 25px;
33-
height: 25px;
34-
border-radius: 4px;
35-
display: flex;
36-
justify-content: center;
37-
align-items: center;
38-
box-sizing: border-box;
39-
}
40-
.button-icon:hover {
41-
background-color: #d8dee5;
42-
}
4334
44-
.button-icon :deep(svg) {
45-
width: 100%;
46-
height: 100%;
47-
display: block;
48-
fill: currentColor;
35+
.button-icon {
36+
cursor: pointer;
37+
padding: 5px;
38+
font-size: 16px;
39+
width: 25px;
40+
height: 25px;
41+
border-radius: 4px;
42+
display: flex;
43+
justify-content: center;
44+
align-items: center;
45+
box-sizing: border-box;
46+
47+
&:hover {
48+
background-color: #d8dee5;
49+
}
50+
51+
:deep(svg) {
52+
width: 100%;
53+
height: 100%;
54+
display: block;
55+
fill: currentColor;
56+
}
57+
}
58+
59+
&.high-contrast {
60+
.button-icon {
61+
&:hover {
62+
background-color: #000;
63+
color: #fff;
64+
}
65+
}
66+
}
4967
}
5068
</style>

packages/super-editor/src/components/toolbar/ButtonGroup.vue

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import ToolbarButton from './ToolbarButton.vue';
44
import ToolbarSeparator from './ToolbarSeparator.vue';
55
import OverflowMenu from './OverflowMenu.vue';
66
import { NDropdown, NTooltip, NSelect } from 'naive-ui';
7+
import { useHighContrastMode } from '../../composables/use-high-contrast-mode';
78
89
const emit = defineEmits(['command']);
910
@@ -23,6 +24,7 @@ const props = defineProps({
2324
});
2425
2526
const currentItem = ref(null);
27+
const { isHighContrastMode } = useHighContrastMode();
2628
// Matches media query from SuperDoc.vue
2729
const isMobile = window.matchMedia('(max-width: 768px)').matches;
2830
const styleMap = {
@@ -96,38 +98,23 @@ const handleClickOutside = (e) => {
9698
9799
<template>
98100
<div :style="getPositionStyle" class="button-group">
99-
<div
100-
v-for="item in toolbarItems"
101-
:key="item.id.value"
102-
:class="{
101+
<div v-for="item in toolbarItems" :key="item.id.value" :class="{
103102
narrow: item.isNarrow.value,
104103
wide: item.isWide.value,
105-
}"
106-
class="toolbar-item-ctn"
107-
>
104+
}" class="toolbar-item-ctn">
108105
<!-- toolbar separator -->
109106
<ToolbarSeparator v-if="isSeparator(item)" style="width: 20px" />
110107
111108
<!-- Toolbar button -->
112-
<n-dropdown
113-
v-if="isDropdown(item) && item.nestedOptions?.value?.length"
114-
:options="dropdownOptions(item)"
115-
:trigger="item.disabled.value ? null : 'click'"
116-
:show="item.expand.value"
117-
size="medium"
118-
placement="bottom-start"
119-
class="toolbar-button toolbar-dropdown sd-editor-toolbar-dropdown"
120-
@select="(key, option) => handleSelect(item, option)"
121-
@clickoutside="handleClickOutside"
122-
:style="item.dropdownStyles.value"
123-
>
109+
<n-dropdown v-if="isDropdown(item) && item.nestedOptions?.value?.length" :options="dropdownOptions(item)"
110+
:trigger="item.disabled.value ? null : 'click'" :show="item.expand.value" size="medium" placement="bottom-start"
111+
class="toolbar-button toolbar-dropdown sd-editor-toolbar-dropdown" :class="{ 'high-contrast': isHighContrastMode }"
112+
@select="(key, option) => handleSelect(item, option)" @clickoutside="handleClickOutside"
113+
:style="item.dropdownStyles.value">
124114
<n-tooltip trigger="hover" :disabled="!item.tooltip?.value">
125115
<template #trigger>
126-
<ToolbarButton
127-
:toolbar-item="item"
128-
@textSubmit="handleToolbarButtonTextSubmit(item, $event)"
129-
@buttonClick="handleToolbarButtonClick(item)"
130-
/>
116+
<ToolbarButton :toolbar-item="item" @textSubmit="handleToolbarButtonTextSubmit(item, $event)"
117+
@buttonClick="handleToolbarButtonClick(item)" />
131118
</template>
132119
<div>
133120
{{ item.tooltip }}
@@ -138,11 +125,8 @@ const handleClickOutside = (e) => {
138125
139126
<n-tooltip trigger="hover" v-else-if="isButton(item)" class="sd-editor-toolbar-tooltip">
140127
<template #trigger>
141-
<ToolbarButton
142-
:toolbar-item="item"
143-
@textSubmit="handleToolbarButtonTextSubmit(item, $event)"
144-
@buttonClick="handleToolbarButtonClick(item)"
145-
/>
128+
<ToolbarButton :toolbar-item="item" @textSubmit="handleToolbarButtonTextSubmit(item, $event)"
129+
@buttonClick="handleToolbarButtonClick(item)" />
146130
</template>
147131
<div v-if="item.tooltip">
148132
{{ item.tooltip }}
@@ -151,11 +135,8 @@ const handleClickOutside = (e) => {
151135
</n-tooltip>
152136
153137
<!-- Overflow menu -->
154-
<OverflowMenu
155-
v-if="isOverflow(item) && overflowItems.length"
156-
:toolbar-item="item"
157-
:overflow-items="overflowItems"
158-
/>
138+
<OverflowMenu v-if="isOverflow(item) && overflowItems.length" :toolbar-item="item"
139+
:overflow-items="overflowItems" />
159140
</div>
160141
</div>
161142
</template>
@@ -167,11 +148,32 @@ const handleClickOutside = (e) => {
167148
cursor: pointer;
168149
}
169150
170-
.sd-editor-toolbar-dropdown .n-dropdown-option-body {
171-
&:hover {
172-
&::before,
173-
&::after {
174-
background-color: #d8dee5 !important;
151+
.sd-editor-toolbar-dropdown {
152+
&.high-contrast {
153+
.n-dropdown-option-body {
154+
&:hover {
155+
156+
&::before,
157+
&::after {
158+
background-color: #000 !important;
159+
}
160+
}
161+
162+
&__label {
163+
&:hover {
164+
color: #fff !important;
165+
}
166+
}
167+
}
168+
}
169+
170+
.n-dropdown-option-body {
171+
&:hover {
172+
173+
&::before,
174+
&::after {
175+
background-color: #d8dee5 !important;
176+
}
175177
}
176178
}
177179
}
Lines changed: 61 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
<script setup>
2+
import { ref } from 'vue';
3+
import { useHighContrastMode } from '../../composables/use-high-contrast-mode';
4+
25
const emit = defineEmits(['select']);
6+
7+
const { isHighContrastMode } = useHighContrastMode();
8+
39
const props = defineProps({
410
options: {
511
type: Array,
@@ -12,14 +18,9 @@ const handleClick = (item) => {
1218
</script>
1319

1420
<template>
15-
<div class="document-mode">
16-
<div
17-
class="option-item"
18-
v-for="option in options"
19-
@click="handleClick(option)"
20-
:class="{ disabled: option.disabled }"
21-
data-item="btn-documentMode-option"
22-
>
21+
<div class="document-mode" :class="{ 'high-contrast': isHighContrastMode }">
22+
<div class="option-item" v-for="option in options" @click="handleClick(option)"
23+
:class="{ disabled: option.disabled }" data-item="btn-documentMode-option">
2324
<div class="document-mode-column icon-column">
2425
<div class="icon-column__icon" v-html="option.icon"></div>
2526
</div>
@@ -37,24 +38,19 @@ const handleClick = (item) => {
3738
</template>
3839

3940
<style scoped>
40-
.document-mode :deep(svg) {
41-
width: 100%;
42-
height: 100%;
43-
display: block;
44-
fill: currentColor;
45-
}
46-
47-
.disabled {
48-
opacity: 0.5;
49-
cursor: not-allowed !important;
50-
pointer-events: none;
51-
}
52-
.document-mode {
41+
.document-mode {
5342
display: flex;
5443
flex-direction: column;
5544
padding: 10px;
5645
box-sizing: border-box;
57-
}
46+
47+
:deep(svg) {
48+
width: 100%;
49+
height: 100%;
50+
display: block;
51+
fill: currentColor;
52+
}
53+
5854
.option-item {
5955
display: flex;
6056
flex-direction: row;
@@ -63,11 +59,44 @@ const handleClick = (item) => {
6359
border-radius: 4px;
6460
cursor: pointer;
6561
box-sizing: border-box;
62+
63+
&:hover {
64+
background-color: #c8d0d8;
65+
}
66+
}
67+
68+
&.high-contrast {
69+
.option-item {
70+
&:hover {
71+
background-color: #000;
72+
color: #fff;
73+
74+
.icon-column__icon {
75+
color: #fff;
76+
}
77+
78+
.text-column {
79+
80+
>.document-mode-type,
81+
>.document-mode-description {
82+
color: #fff;
83+
}
84+
}
85+
}
86+
}
87+
}
88+
}
89+
90+
.disabled {
91+
opacity: 0.5;
92+
cursor: not-allowed !important;
93+
pointer-events: none;
6694
}
6795
.document-mode-column {
6896
display: flex;
6997
flex-direction: column;
7098
}
99+
71100
.document-mode-type {
72101
font-weight: 400;
73102
font-size: 15px;
@@ -82,27 +111,25 @@ const handleClick = (item) => {
82111
color: black;
83112
height: 100%;
84113
box-sizing: border-box;
85-
}
86114
87-
.icon-column__icon {
88-
display: inline-flex;
89-
justify-content: center;
90-
align-items: center;
91-
flex-shrink: 0;
92-
height: 18px;
93-
color: #47484a;
115+
&__icon {
116+
display: inline-flex;
117+
justify-content: center;
118+
align-items: center;
119+
flex-shrink: 0;
120+
height: 18px;
121+
color: #47484a;
122+
}
94123
}
95124
96125
.icon-column__icon :deep(svg) {
97-
width: auto; /* needed for safari */
126+
width: auto;
127+
/* needed for safari */
98128
max-height: 18px;
99129
}
100130
101131
.document-mode-description {
102132
font-size: 12px;
103133
color: #666;
104134
}
105-
.option-item:hover {
106-
background-color: #c8d0d8;
107-
}
108135
</style>

0 commit comments

Comments
 (0)