Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@featherds/dialog

Package Overview
Dependencies
Maintainers
2
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@featherds/dialog - npm Package Compare versions

Comparing version 0.9.6 to 0.10.0

237

dist/app.es.js

@@ -17,3 +17,4 @@ var __defProp = Object.defineProperty;

};
import { openBlock, createElementBlock, createElementVNode, renderSlot, resolveComponent, normalizeClass, withModifiers, createVNode, toRef, ref, computed, watch, withDirectives, Transition, withCtx, vShow, toDisplayString, createCommentVNode, createBlock } from "vue";
import { defineComponent, ref, toRef, computed, nextTick, openBlock, createElementBlock, createElementVNode, renderSlot, resolveComponent, normalizeClass, withModifiers, createVNode, watch, withDirectives, Transition, withCtx, vShow, toDisplayString, createCommentVNode, createBlock } from "vue";
import { getElements, addLayer, removeLayer } from "@featherds/composables/modal/Layers";
import { FeatherIcon } from "@featherds/icon";

@@ -33,3 +34,3 @@ import Close from "@featherds/icon/navigation/Cancel";

};
const _sfc_main$2 = {
const _sfc_main$2 = defineComponent({
props: {

@@ -39,2 +40,5 @@ enable: {

required: true
},
layer: {
type: Object
}

@@ -44,56 +48,32 @@ },

return {
lastFocus: void 0,
ignoreUtilFocusChanges: false,
rendered: false
};
},
computed: {
ready() {
return this.rendered && this.enable;
}
},
watch: {
ready: {
immediate: true,
handler: "enableTrap"
}
},
methods: {
enableTrap(nv) {
if (nv) {
this.addFocusTrapEvents();
} else {
this.removeFocusTrapEvents();
setup(props) {
const content = ref();
const ignoreUtilFocusChanges = ref(false);
const layer = toRef(props, "layer");
const contentAndLayers = computed(() => {
const result = [];
if (content.value) {
result.push(content.value);
}
},
addFocusTrapEvents() {
document.addEventListener("blur", this.trapFocus, true);
if (this.$refs.content) {
this.attemptToFocusFirst(this.$refs.content);
} else {
this.$nextTick(() => {
if (this.$refs.content) {
this.attemptToFocusFirst(this.$refs.content);
}
});
if (layer.value) {
result.push(...getElements(layer.value).value);
}
},
attemptToFocusFirst(el) {
const firstFocus = el.querySelector("[first-focus]");
if (firstFocus && firstFocus.focus) {
this.$nextTick(() => {
firstFocus.focus();
});
} else {
this.focusFirstDescendant(el);
}
},
removeFocusTrapEvents() {
if (typeof document !== "undefined")
document.removeEventListener("blur", this.trapFocus, true);
},
focusFirstDescendant(element) {
return result;
});
const comparePositionInDOM = (a, b) => {
let result = a.compareDocumentPosition ? a.compareDocumentPosition(b) : a.contains ? (a != b && a.contains(b) && 16) + (a != b && b.contains(a) && 8) + (a.sourceIndex >= 0 && b.sourceIndex >= 0 ? (a.sourceIndex < b.sourceIndex && 4) + (a.sourceIndex > b.sourceIndex && 2) : 1) + 0 : 0;
if (result === 2)
return "before";
if (result === 4)
return "after";
if (result === 10 || result === 12)
return "parent";
};
const focusFirstDescendant = (element) => {
for (var i = 0; i < element.childNodes.length; i++) {
var child = element.childNodes[i];
if (this.attemptFocus(child) || this.focusFirstDescendant(child)) {
if (attemptFocus(child) || focusFirstDescendant(child)) {
return true;

@@ -103,7 +83,7 @@ }

return false;
},
focusLastDescendant(element) {
};
const focusLastDescendant = (element) => {
for (var i = element.childNodes.length - 1; i >= 0; i--) {
var child = element.childNodes[i];
if (this.attemptFocus(child) || this.focusLastDescendant(child)) {
if (attemptFocus(child) || focusLastDescendant(child)) {
return true;

@@ -113,49 +93,15 @@ }

return false;
},
attemptFocus(element) {
if (!this.isFocusable(element)) {
};
const attemptFocus = (element) => {
if (!isFocusable(element)) {
return false;
}
this.ignoreUtilFocusChanges = true;
ignoreUtilFocusChanges.value = true;
if (element.focus) {
element.focus();
}
this.ignoreUtilFocusChanges = false;
ignoreUtilFocusChanges.value = false;
return document.activeElement === element;
},
trapFocus() {
if (this.ignoreUtilFocusChanges) {
return;
}
setTimeout(() => {
var target = document.activeElement;
if (this.$refs.content.contains(target)) {
this.lastFocus = target;
} else {
let position = this.comparePositionInDOM(this.$refs.content, target);
switch (position) {
case "before":
this.focusLastDescendant(this.$refs.content);
break;
case "after":
this.focusFirstDescendant(this.$refs.content);
break;
case "parent":
this.attemptToFocusFirst(this.$refs.content);
break;
}
this.lastFocus = document.activeElement;
}
}, 0);
},
comparePositionInDOM(a, b) {
let result = a.compareDocumentPosition ? a.compareDocumentPosition(b) : a.contains ? (a != b && a.contains(b) && 16) + (a != b && b.contains(a) && 8) + (a.sourceIndex >= 0 && b.sourceIndex >= 0 ? (a.sourceIndex < b.sourceIndex && 4) + (a.sourceIndex > b.sourceIndex && 2) : 1) + 0 : 0;
if (result === 2)
return "before";
if (result === 4)
return "after";
if (result === 10 || result === 12)
return "parent";
},
isFocusable(element) {
};
const isFocusable = (element) => {
if (element.tabIndex > 0 || element.tabIndex === 0 && element.getAttribute("tabIndex") !== null) {

@@ -180,4 +126,87 @@ return true;

}
};
const attemptToFocusFirst = (el) => {
const firstFocus = el.querySelector("[first-focus]");
if (firstFocus && firstFocus.focus) {
nextTick(() => {
firstFocus.focus();
});
} else {
focusFirstDescendant(el);
}
};
const lastFocus = ref();
const trapFocus = () => {
if (ignoreUtilFocusChanges.value) {
return;
}
setTimeout(() => {
var target = document.activeElement;
if (contentAndLayers.value.some((el) => el.contains(target))) {
lastFocus.value = target;
return;
} else {
let position = comparePositionInDOM(content.value, target);
switch (position) {
case "before":
focusLastDescendant(content.value);
break;
case "after":
focusFirstDescendant(content.value);
break;
case "parent":
attemptToFocusFirst(content.value);
break;
}
lastFocus.value = document.activeElement;
}
}, 0);
};
return {
trapFocus,
content,
ignoreUtilFocusChanges,
attemptToFocusFirst,
focusLastDescendant,
focusFirstDescendant,
isFocusable,
lastFocus
};
},
computed: {
ready() {
return this.rendered && this.enable;
}
},
watch: {
ready: {
immediate: true,
handler: "enableTrap"
}
},
methods: {
enableTrap(nv) {
if (nv) {
this.addFocusTrapEvents();
} else {
this.removeFocusTrapEvents();
}
},
addFocusTrapEvents() {
document.addEventListener("blur", this.trapFocus, true);
if (this.content) {
this.attemptToFocusFirst(this.content);
} else {
this.$nextTick(() => {
if (this.content) {
this.attemptToFocusFirst(this.content);
}
});
}
},
removeFocusTrapEvents() {
if (typeof document !== "undefined")
document.removeEventListener("blur", this.trapFocus, true);
}
},
mounted() {

@@ -189,3 +218,3 @@ this.rendered = true;

}
};
});
const _hoisted_1$2 = /* @__PURE__ */ createElementVNode("div", { tabindex: "0" }, null, -1);

@@ -245,3 +274,3 @@ const _hoisted_2$1 = {

}
var DialogClose = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-3998156b"]]);
var DialogClose = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-36f0af5f"]]);
var FeatherDialog_vue_vue_type_style_index_0_scoped_true_lang = "";

@@ -307,10 +336,13 @@ const LABELS = {

const shown = ref(props.modelValue);
const layer = ref();
watch(shown, (v) => {
if (v) {
context.emit("shown");
layer.value = addLayer(element, "modal");
} else {
context.emit("hidden");
removeLayer(layer.value);
}
});
return __spreadValues({ close, hasFooter, headerId, element, shown }, labels);
return __spreadValues({ close, hasFooter, headerId, element, shown, layer }, labels);
},

@@ -341,4 +373,3 @@ components: {

return withDirectives((openBlock(), createElementBlock("div", {
class: normalizeClass(["feather-dialog", { relative: $props.relative }]),
ref: "element"
class: normalizeClass(["feather-dialog", { relative: $props.relative }])
}, [

@@ -361,3 +392,4 @@ createVNode(Transition, { name: "fade" }, {

enable: $setup.shown && $props.modelValue,
class: "trap"
class: "trap",
layer: $setup.layer
}, {

@@ -370,3 +402,4 @@ default: withCtx(() => [

"aria-labelledby": $setup.headerId,
"data-ref-id": "feather-dialog"
"data-ref-id": "feather-dialog",
ref: "element"
}, [

@@ -397,3 +430,3 @@ createElementVNode("div", _hoisted_3, [

_: 3
}, 8, ["enable"]), [
}, 8, ["enable", "layer"]), [
[vShow, $props.modelValue]

@@ -408,3 +441,3 @@ ])

}
var FeatherDialog = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-16089cce"]]);
var FeatherDialog = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-9253336a"]]);
export { DialogClose, FeatherDialog, FocusTrap };
{
"name": "@featherds/dialog",
"version": "0.9.6",
"version": "0.10.0",
"publishConfig": {

@@ -12,6 +12,6 @@ "access": "public"

"dependencies": {
"@featherds/composables": "^0.9.6",
"@featherds/icon": "^0.9.6",
"@featherds/styles": "^0.9.6",
"@featherds/utils": "^0.9.6",
"@featherds/composables": "^0.10.0",
"@featherds/icon": "^0.10.0",
"@featherds/styles": "^0.10.0",
"@featherds/utils": "^0.10.0",
"vue": "^3.1.0-0"

@@ -24,3 +24,3 @@ },

"types": "./src/index.d.ts",
"gitHead": "04a74207e8bfa8d39acc470365e30dd6c90b2e8e"
"gitHead": "9871b17eaedcfc90174b78b21acb0cc06afd594c"
}

@@ -1,6 +0,4 @@

import { mount, config } from "@vue/test-utils";
import { mount } from "@vue/test-utils";
import FocusTrap from "./FocusTrap.vue";
config.renderStubDefaultSlot = true;
const slots = {

@@ -40,3 +38,3 @@ default: {

wrapper = getWrapper({ props: { enable: false }, slots });
const focusFirst = jest.spyOn(wrapper.vm, "focusFirstDescendant");
const focusFirst = jest.spyOn(wrapper.vm, "attemptToFocusFirst");
await wrapper.setProps({ enable: true });

@@ -43,0 +41,0 @@ expect(focusFirst).toHaveBeenCalled();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc