Skip to content

Commit 2fc81dc

Browse files
committed
Merge branch 'staging' into rebrand-2025-beta
2 parents 6737b41 + 8c10768 commit 2fc81dc

File tree

26 files changed

+136
-93
lines changed

26 files changed

+136
-93
lines changed

packages/dialtone-css/lib/build/less/components/tooltip.less

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
line-height: var(--tooltip-line-height);
7575
letter-spacing: calc(var(--dt-space-100) * 0.25);
7676
text-align: center;
77+
overflow-wrap: break-word;
7778
background-color: var(--tooltip-color-background);
7879
border-radius: var(--tooltip-border-radius);
7980

packages/dialtone-icons/project.json

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
{
22
"name": "dialtone-icons",
33
"targets": {
4-
"build": {
4+
"pre-build": {
55
"executor": "nx:run-commands",
66
"options": {
77
"cwd": "{projectRoot}",
8-
"commands": [
9-
"pnpm exec gulp",
10-
"nx run-many --target=build --projects=dialtone-icons-vue2,dialtone-icons-vue3 --parallel=2 --output-style=stream"
11-
],
12-
"parallel": false
8+
"command": "pnpm exec gulp"
139
},
1410
"inputs": [
1511
"{projectRoot}/src/**/*",
@@ -19,13 +15,28 @@
1915
"outputs": [
2016
"{projectRoot}/src/icons",
2117
"{projectRoot}/src/illustrations",
22-
"{projectRoot}/dist",
18+
"{projectRoot}/dist"
19+
]
20+
},
21+
"build": {
22+
"dependsOn": ["pre-build"],
23+
"executor": "nx:run-commands",
24+
"options": {
25+
"cwd": "{projectRoot}",
26+
"command": "nx run-many --target=build --projects=dialtone-icons-vue2,dialtone-icons-vue3 --parallel=2 --output-style=stream"
27+
},
28+
"inputs": [
29+
"{projectRoot}/src/**/*",
30+
"{projectRoot}/transformSVGtoVue.cjs",
31+
"{projectRoot}/gulpfile.cjs"
32+
],
33+
"outputs": [
2334
"{projectRoot}/vue2/dist",
2435
"{projectRoot}/vue3/dist"
2536
]
2637
},
2738
"build:android": {
28-
"dependsOn": ["dialtone-icons-android:build"],
39+
"dependsOn": ["pre-build", "dialtone-icons-android:build"],
2940
"executor": "nx:run-commands",
3041
"options": {
3142
"cwd": "{projectRoot}/android",

packages/dialtone-vue3/common/mixins/keyboard_list_navigation.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Dom from './dom';
2+
import { returnFirstEl } from '@/common/utils';
23

34
const ERROR_INVALID_LIST_ELEMENT = (
45
'listElementKey is required or the referenced ' +
@@ -74,7 +75,7 @@ export default ({
7475
// this[listElement]() can return a Vue component, in which case we need to target
7576
// the $el property, or it can simply be an html element.
7677
_getListElement () {
77-
return this[listElementKey]()?.$el || this[listElementKey]();
78+
return returnFirstEl(this[listElementKey]()?.$el) || this[listElementKey]();
7879
},
7980

8081
// Gets the length of all the items in the list, uses the listItemRole param to determine

packages/dialtone-vue3/common/mixins/modal.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { returnFirstEl } from '@/common/utils';
2+
13
const focusableAttrs = ':not(:disabled):not([aria-disabled="true"]):not([role="presentation"])';
24
const tabbableAttrs = `${focusableAttrs}:not([tabindex="-1"])`;
35
const focusableElementsList = `button,[href],input,select,textarea,details,[tabindex]`;
@@ -36,13 +38,13 @@ export default {
3638
* will default to the root node of the vue component
3739
*/
3840
async focusFirstElement (el = this.$el) {
39-
const elToFocus = await this.getFirstFocusableElement(el);
41+
const elToFocus = await this.getFirstFocusableElement(returnFirstEl(el));
4042
elToFocus?.focus({ preventScroll: true });
4143
},
4244

4345
async focusElementById (elementId) {
4446
await this.$nextTick();
45-
const result = this.$el?.querySelector(elementId);
47+
const result = returnFirstEl(this.$el)?.querySelector(elementId);
4648
if (result) {
4749
result.focus();
4850
return;
@@ -83,6 +85,7 @@ export default {
8385
* @param {bool} includeNegativeTabIndex - will include tabindex="-1" in the list of focusable elements.
8486
*/
8587
_getFocusableElements (el = this.$el, includeNegativeTabIndex = false) {
88+
el = returnFirstEl(el);
8689
if (!el) return [];
8790
const focusableContent = [...el.querySelectorAll(focusableElementsList)];
8891
return focusableContent.filter((fc) => {

packages/dialtone-vue3/common/utils/index.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,23 @@ export const extractVueListeners = (attrs) => {
202202
return Object.fromEntries(listeners);
203203
};
204204

205+
/**
206+
* $el works very differently than in vue 2, if the first node in the template is a text node
207+
* such as a comment it will return that instead of the first actual element. This function
208+
* will recursively return the first element in the template instead of the first node.
209+
* @param el
210+
* @returns {HTMLElement} The first element in the template
211+
*/
212+
export const returnFirstEl = (el) => {
213+
if (el?.nodeType === Node.ELEMENT_NODE) {
214+
return el;
215+
} else if (!el?.nodeType) {
216+
return null;
217+
} else {
218+
return returnFirstEl(el?.nextSibling);
219+
}
220+
};
221+
205222
/*
206223
* Set's a global timer to debounce the execution of a function.
207224
* @param { object } func - the function that is going to be called after timeout
@@ -456,6 +473,7 @@ export default {
456473
flushPromises,
457474
kebabCaseToPascalCase,
458475
extractVueListeners,
476+
returnFirstEl,
459477
debounce,
460478
isOutOfViewPort,
461479
getPhoneNumberRegex,

packages/dialtone-vue3/components/datepicker/composables/useCalendar.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { computed, ref, watch, nextTick } from 'vue';
22
import { getWeekDayNames, calculateNextFocusDate, calculatePrevFocusDate } from '@/components/datepicker/utils.js';
33
import { MONTH_FORMAT, WEEK_START } from '@/components/datepicker/datepicker_constants.js';
44
import { format, getYear } from 'date-fns';
5+
import { returnFirstEl } from '@/common/utils';
56

67
export function useCalendar (props, emits) {
78
const selectedDay = ref(null);
@@ -34,13 +35,13 @@ export function useCalendar (props, emits) {
3435
event.preventDefault();
3536
focusDay.value -= 7;
3637
try {
37-
daysRef.value[focusDay.value].el.$el.focus();
38+
returnFirstEl(daysRef.value[focusDay.value].el.$el).focus();
3839
} catch (error) {
3940
const prevFocusDate = calculatePrevFocusDate(daysRef.value[focusDay.value + 7].day.value);
4041
emits('go-to-prev-month');
4142

4243
nextTick(() => {
43-
daysRef.value[prevFocusDate - 1].el.$el.focus();
44+
returnFirstEl(daysRef.value[prevFocusDate - 1].el.$el).focus();
4445
focusDay.value += prevFocusDate - 1;
4546
});
4647
}
@@ -50,13 +51,13 @@ export function useCalendar (props, emits) {
5051
event.preventDefault();
5152
focusDay.value += 7;
5253
try {
53-
daysRef.value[focusDay.value].el.$el.focus();
54+
returnFirstEl(daysRef.value[focusDay.value].el.$el).focus();
5455
} catch (error) {
5556
const nextFocusDate = calculateNextFocusDate(daysRef.value[focusDay.value - 7].day.value);
5657
emits('go-to-next-month');
5758

5859
nextTick(() => {
59-
daysRef.value[nextFocusDate - 1].el.$el.focus();
60+
returnFirstEl(daysRef.value[nextFocusDate - 1].el.$el).focus();
6061
focusDay.value += nextFocusDate - 1;
6162
});
6263
}
@@ -66,7 +67,7 @@ export function useCalendar (props, emits) {
6667
event.preventDefault();
6768
if (focusDay.value > 0) {
6869
focusDay.value -= 1;
69-
daysRef.value[focusDay.value].el.$el.focus();
70+
returnFirstEl(daysRef.value[focusDay.value].el.$el).focus();
7071
} else {
7172
// if we are on month first day, jump to last day of prev month
7273
emits('go-to-prev-month');
@@ -78,7 +79,7 @@ export function useCalendar (props, emits) {
7879
event.preventDefault();
7980
if (focusDay.value < daysRef.value.length - 1) {
8081
focusDay.value += 1;
81-
daysRef.value[focusDay.value].el.$el.focus();
82+
returnFirstEl(daysRef.value[focusDay.value].el.$el).focus();
8283
} else {
8384
// if we are on month last day, jump to first day of next month
8485
emits('go-to-next-month');
@@ -102,14 +103,14 @@ export function useCalendar (props, emits) {
102103
focusDay.value = 0;
103104

104105
nextTick(() => {
105-
daysRef.value[focusDay.value].el.$el.focus();
106+
returnFirstEl(daysRef.value[focusDay.value].el.$el).focus();
106107
});
107108
}
108109

109110
function focusLastDay () {
110111
nextTick(() => {
111112
focusDay.value = daysRef.value.length - 1;
112-
daysRef.value[focusDay.value].el.$el.focus();
113+
returnFirstEl(daysRef.value[focusDay.value].el.$el).focus();
113114
});
114115
}
115116

packages/dialtone-vue3/components/datepicker/composables/useMonthYearPicker.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { computed, ref, watch } from 'vue';
22
import { addMonths, getDate, getMonth, getYear, set, subMonths } from 'date-fns';
33
import { formatMonth, getCalendarDays } from '@/components/datepicker/utils.js';
4+
import { returnFirstEl } from '@/common/utils';
45

56
export function useMonthYearPicker (props, emits) {
67
const selectMonth = ref(getMonth(props.selectedDate));
@@ -34,7 +35,7 @@ export function useMonthYearPicker (props, emits) {
3435
}
3536

3637
function focusMonthYearPicker () {
37-
focusRefs.value[0].$el.focus();
38+
returnFirstEl(focusRefs.value[0].$el).focus();
3839
}
3940

4041
function handleKeyDown (event) {
@@ -43,21 +44,21 @@ export function useMonthYearPicker (props, emits) {
4344
event.preventDefault();
4445
if (focusPicker.value === 0) {
4546
focusPicker.value = 3;
46-
focusRefs.value[focusPicker.value].$el.focus();
47+
returnFirstEl(focusRefs.value[focusPicker.value].$el).focus();
4748
} else {
4849
focusPicker.value--;
49-
focusRefs.value[focusPicker.value].$el.focus();
50+
returnFirstEl(focusRefs.value[focusPicker.value].$el).focus();
5051
}
5152
break;
5253

5354
case 'ArrowRight':
5455
event.preventDefault();
5556
if (focusPicker.value === 3) {
5657
focusPicker.value = 0;
57-
focusRefs.value[focusPicker.value].$el.focus();
58+
returnFirstEl(focusRefs.value[focusPicker.value].$el).focus();
5859
} else {
5960
focusPicker.value++;
60-
focusRefs.value[focusPicker.value].$el.focus();
61+
returnFirstEl(focusRefs.value[focusPicker.value].$el).focus();
6162
}
6263
break;
6364

packages/dialtone-vue3/components/datepicker/datepicker.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@
3737
</template>
3838

3939
<script setup>
40+
import { returnFirstEl, warnIfUnmounted } from '@/common/utils';
4041
import MonthYearPicker from './modules/month-year-picker.vue';
4142
import Calendar from './modules/calendar.vue';
4243
import { DtStack } from '@/components/stack';
4344
4445
import { onMounted, ref, getCurrentInstance } from 'vue';
45-
import { warnIfUnmounted } from '@/common/utils';
4646
4747
defineProps({
4848
/**
@@ -157,6 +157,6 @@ function updateCalendarDays (days) {
157157
158158
onMounted(() => {
159159
const instance = getCurrentInstance();
160-
warnIfUnmounted(instance.proxy.$el, 'datepicker');
160+
warnIfUnmounted(returnFirstEl(instance.proxy.$el), 'datepicker');
161161
});
162162
</script>

packages/dialtone-vue3/components/emoji_picker/modules/emoji_tabset.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<script setup>
3232
import { computed, ref, watch } from 'vue';
3333
import { DtTab, DtTabGroup } from '@/components/tab';
34+
import { returnFirstEl } from '@/common/utils';
3435
import { EMOJI_PICKER_CATEGORIES } from '@/components/emoji_picker/emoji_picker_constants.js';
3536
import {
3637
DtIconClock,
@@ -148,7 +149,7 @@ function selectTabset (id) {
148149
function setTabsetRef (ref) {
149150
// We push the $el, because $el is the button inside the dt-tab component
150151
// and we need the button to focus it
151-
tabsetRef.value.push(ref.$el);
152+
tabsetRef.value.push(returnFirstEl(ref.$el));
152153
}
153154
154155
function focusTabset () {

packages/dialtone-vue3/components/image_viewer/image_viewer.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767

6868
<script>
6969
import Modal from '@/common/mixins/modal';
70+
import { returnFirstEl } from '@/common/utils';
7071
import { EVENT_KEYNAMES } from '@/common/constants';
7172
import { DtIconClose } from '@dialpad/dialtone-icons/vue3';
7273
import { DtButton } from '@/components/button';
@@ -244,7 +245,7 @@ export default {
244245
},
245246
246247
focusAfterOpen () {
247-
this.$refs.closeImage?.$el.focus();
248+
returnFirstEl(this.$refs.closeImage?.$el)?.focus();
248249
},
249250
250251
trapFocus (e) {

0 commit comments

Comments
 (0)