@quaffui/quaff 0.1.0-prealpha8 → 0.1.0-prealpha9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/button/QBtn.svelte +16 -6
- package/dist/components/button/QBtn.svelte.d.ts +0 -1
- package/dist/components/button/index.scss +18 -1
- package/dist/components/dialog/QDialog.svelte +28 -13
- package/dist/components/dialog/QDialog.svelte.d.ts +0 -1
- package/dist/components/drawer/QDrawer.svelte +48 -37
- package/dist/components/drawer/index.scss +11 -8
- package/dist/components/footer/QFooter.svelte +9 -5
- package/dist/components/footer/QFooter.svelte.d.ts +2 -2
- package/dist/components/footer/index.scss +23 -0
- package/dist/components/footer/props.d.ts +2 -2
- package/dist/components/header/QHeader.svelte +28 -0
- package/dist/components/header/QHeader.svelte.d.ts +24 -0
- package/dist/components/header/props.d.ts +15 -0
- package/dist/components/header/props.js +1 -0
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.js +2 -1
- package/dist/components/layout/index.scss +89 -75
- package/dist/components/list/index.scss +1 -0
- package/dist/components/private/QApi.svelte +3 -1
- package/dist/components/railbar/QRailbar.svelte +47 -29
- package/dist/components/railbar/index.scss +39 -0
- package/dist/components/tabs/QTab.svelte +44 -16
- package/dist/components/tabs/QTab.svelte.d.ts +1 -3
- package/dist/components/tabs/QTabs.svelte +3 -7
- package/dist/components/tabs/index.scss +40 -9
- package/dist/components/toolbar/QToolbar.svelte +5 -22
- package/dist/components/toolbar/QToolbar.svelte.d.ts +2 -0
- package/dist/components/toolbar/index.scss +8 -0
- package/dist/components/toolbar/props.d.ts +8 -0
- package/dist/css/index.css +1 -1
- package/dist/css/index.scss +2 -1
- package/dist/css/mixins.scss +1 -3
- package/dist/css/ripple.scss +42 -0
- package/dist/css/states.scss +6 -2
- package/dist/helpers/ripple.d.ts +10 -0
- package/dist/helpers/ripple.js +75 -0
- package/dist/helpers/version.d.ts +1 -1
- package/dist/helpers/version.js +1 -1
- package/dist/utils/dom.d.ts +8 -0
- package/dist/utils/dom.js +71 -0
- package/dist/utils/events.d.ts +13 -0
- package/dist/utils/events.js +13 -0
- package/dist/utils/props.d.ts +1 -1
- package/dist/utils/props.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const triggerEvents = ["pointerdown", "touchstart", "keydown"];
|
|
2
|
+
const cancelEvents = ["mouseleave", "dragleave", "touchmove", "touchcancel", "pointerup", "keyup"];
|
|
3
|
+
export function ripple(el, options = {}) {
|
|
4
|
+
function addClasses(center) {
|
|
5
|
+
let shouldBeCentered = center || options.center;
|
|
6
|
+
if (!el.classList.contains("q-ripple--effect")) {
|
|
7
|
+
el.classList.add("q-ripple--effect");
|
|
8
|
+
}
|
|
9
|
+
if (!shouldBeCentered && el.classList.contains("q-ripple--center")) {
|
|
10
|
+
el.classList.remove("q-ripple--center");
|
|
11
|
+
}
|
|
12
|
+
shouldBeCentered && el.classList.add("q-ripple--center");
|
|
13
|
+
}
|
|
14
|
+
function setOptions(options) {
|
|
15
|
+
if (options.duration && options.duration < 0) {
|
|
16
|
+
options.duration = undefined;
|
|
17
|
+
}
|
|
18
|
+
if (options.color) {
|
|
19
|
+
el.style.setProperty("--ripple-color", options.color);
|
|
20
|
+
}
|
|
21
|
+
if (options.duration) {
|
|
22
|
+
el.style.setProperty("--ripple-duration", `${options.duration}ms`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
addClasses();
|
|
26
|
+
setOptions(options);
|
|
27
|
+
function createRipple(e, center) {
|
|
28
|
+
if (el.hasAttribute("aria-disabled"))
|
|
29
|
+
return;
|
|
30
|
+
if (e instanceof KeyboardEvent) {
|
|
31
|
+
if (!["Enter", "Space"].includes(e.code) || e.repeat) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
e.preventDefault();
|
|
35
|
+
const click = new PointerEvent("pointerdown");
|
|
36
|
+
createRipple(click, true);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
addClasses(center);
|
|
40
|
+
const rect = el.getBoundingClientRect();
|
|
41
|
+
const clientX = e instanceof TouchEvent ? e.touches[0].clientX : e.clientX;
|
|
42
|
+
const clientY = e instanceof TouchEvent ? e.touches[0].clientY : e.clientY;
|
|
43
|
+
const x = clientX - rect.left > el.offsetWidth / 2 ? 0 : el.offsetWidth;
|
|
44
|
+
const y = clientY - rect.top > el.offsetHeight / 2 ? 0 : el.offsetHeight;
|
|
45
|
+
const radius = Math.hypot(x - (clientX - rect.left), y - (clientY - rect.top));
|
|
46
|
+
const ripple = document.createElement("div");
|
|
47
|
+
ripple.classList.add("q-ripple");
|
|
48
|
+
ripple.style.left = `${clientX - rect.left - radius}px`;
|
|
49
|
+
ripple.style.top = `${clientY - rect.top - radius}px`;
|
|
50
|
+
ripple.style.width = ripple.style.height = `${radius * 2}px`;
|
|
51
|
+
el.appendChild(ripple);
|
|
52
|
+
function removeRipple() {
|
|
53
|
+
if (ripple === null)
|
|
54
|
+
return;
|
|
55
|
+
ripple.style.opacity = "0";
|
|
56
|
+
setTimeout(() => {
|
|
57
|
+
ripple.remove();
|
|
58
|
+
}, options.duration || 1000);
|
|
59
|
+
cancelEvents.forEach((event) => el.removeEventListener(event, removeRipple));
|
|
60
|
+
}
|
|
61
|
+
cancelEvents.forEach((event) => el.addEventListener(event, removeRipple));
|
|
62
|
+
}
|
|
63
|
+
triggerEvents.forEach((event) => el.addEventListener(event, createRipple, { passive: event === "touchstart" }));
|
|
64
|
+
return {
|
|
65
|
+
destroy() {
|
|
66
|
+
triggerEvents.forEach((event) => {
|
|
67
|
+
el.removeEventListener(event, createRipple);
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
update(newOptions) {
|
|
71
|
+
options = newOptions;
|
|
72
|
+
setOptions(newOptions);
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "0.1.0-
|
|
1
|
+
declare const _default: "0.1.0-prealpha9";
|
|
2
2
|
export default _default;
|
package/dist/helpers/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default "0.1.0-
|
|
1
|
+
export default "0.1.0-prealpha9";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Direction } from "./events";
|
|
2
|
+
export declare function getParentElement(el: HTMLElement): HTMLElement;
|
|
3
|
+
export declare function getAllChildren(el: HTMLElement): HTMLElement[];
|
|
4
|
+
export declare function isFocusable(el: HTMLElement): boolean;
|
|
5
|
+
export declare function getFocusableChildren<T extends HTMLElement>(el: T): T[];
|
|
6
|
+
export declare function getClosestFocusableChild(el: HTMLElement): HTMLElement;
|
|
7
|
+
export declare function getClosestFocusableSibling<T extends HTMLElement>(el: T, direction: Direction): HTMLElement;
|
|
8
|
+
export declare function getClosestFocusableBlock(el: HTMLElement, direction: Direction): HTMLElement;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export function getParentElement(el) {
|
|
2
|
+
let parent = el.parentNode;
|
|
3
|
+
while (parent && parent.nodeType !== 1) {
|
|
4
|
+
parent = parent.parentNode;
|
|
5
|
+
}
|
|
6
|
+
return parent;
|
|
7
|
+
}
|
|
8
|
+
export function getAllChildren(el) {
|
|
9
|
+
return Array.from(el.querySelectorAll("*"));
|
|
10
|
+
}
|
|
11
|
+
// Focus utils
|
|
12
|
+
const focusableElements = ':is(a, button, input, [tabindex]:not([tabindex="-1"])):not([disabled], [aria-disabled="true"])';
|
|
13
|
+
export function isFocusable(el) {
|
|
14
|
+
return (el.offsetWidth > 0 &&
|
|
15
|
+
el.offsetHeight > 0 &&
|
|
16
|
+
(el.style.opacity === "" || +el.style.opacity > 0) &&
|
|
17
|
+
el.style.display !== "none" &&
|
|
18
|
+
el.tabIndex >= 0);
|
|
19
|
+
}
|
|
20
|
+
export function getFocusableChildren(el) {
|
|
21
|
+
return Array.from(el.querySelectorAll(focusableElements));
|
|
22
|
+
}
|
|
23
|
+
export function getClosestFocusableChild(el) {
|
|
24
|
+
let children = Array.from(el.querySelectorAll(focusableElements));
|
|
25
|
+
const focusableChildren = children.filter(isFocusable);
|
|
26
|
+
return focusableChildren[0] || null;
|
|
27
|
+
}
|
|
28
|
+
export function getClosestFocusableSibling(el, direction) {
|
|
29
|
+
const parent = getParentElement(el);
|
|
30
|
+
const allSiblings = Array.from(parent.childNodes);
|
|
31
|
+
let filtered = allSiblings.filter(isFocusable);
|
|
32
|
+
const indexOfEl = filtered.indexOf(el);
|
|
33
|
+
if (direction === "next") {
|
|
34
|
+
const i = indexOfEl + 1 === filtered.length ? 0 : indexOfEl + 1;
|
|
35
|
+
if (filtered[i].hasAttribute("aria-current")) {
|
|
36
|
+
// The target element is active, it shouldn't have focus
|
|
37
|
+
return i + 1 === filtered.length ? filtered[0] : filtered[i + 1];
|
|
38
|
+
}
|
|
39
|
+
return filtered[i];
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const i = indexOfEl - 1 === -1 ? filtered.length - 1 : indexOfEl - 1;
|
|
43
|
+
if (filtered[i].hasAttribute("aria-current")) {
|
|
44
|
+
// The target element is active, it shouldn't have focus
|
|
45
|
+
return i - 1 === -1 ? filtered.at(-1) : filtered[i - 1];
|
|
46
|
+
}
|
|
47
|
+
return filtered[i];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function getClosestFocusableBlock(el, direction) {
|
|
51
|
+
let parent = getParentElement(el);
|
|
52
|
+
let parentFocusableChildren = getFocusableChildren(parent);
|
|
53
|
+
function getNextFocusableBlock(parentBlock) {
|
|
54
|
+
const grandParent = getParentElement(parentBlock);
|
|
55
|
+
const grandParentChildren = getAllChildren(grandParent);
|
|
56
|
+
const indexOfEl = grandParentChildren.indexOf(el);
|
|
57
|
+
const sliced = direction === "next"
|
|
58
|
+
? grandParentChildren.slice(indexOfEl)
|
|
59
|
+
: grandParentChildren.slice(0, indexOfEl);
|
|
60
|
+
const filtered = sliced.filter((element) => isFocusable(element) && !parentFocusableChildren.includes(element));
|
|
61
|
+
if (!filtered.length) {
|
|
62
|
+
return getNextFocusableBlock(grandParent);
|
|
63
|
+
}
|
|
64
|
+
return direction === "next" ? filtered[0] : filtered.at(-1);
|
|
65
|
+
}
|
|
66
|
+
let targetBlock = getNextFocusableBlock(parent);
|
|
67
|
+
if (targetBlock.hasAttribute("aria-current")) {
|
|
68
|
+
targetBlock = getClosestFocusableSibling(targetBlock, direction);
|
|
69
|
+
}
|
|
70
|
+
return targetBlock;
|
|
71
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type Direction = "previous" | "next";
|
|
2
|
+
export declare function isActivationKey(e: KeyboardEvent): e is KeyboardEvent & {
|
|
3
|
+
code: "Enter" | "Space";
|
|
4
|
+
};
|
|
5
|
+
export declare function isArrowKey(e: KeyboardEvent): e is KeyboardEvent & {
|
|
6
|
+
code: "ArrowUp" | "ArrowDown" | "ArrowLeft" | "ArrowRight";
|
|
7
|
+
};
|
|
8
|
+
export declare function isTabKey(e: KeyboardEvent): e is KeyboardEvent & {
|
|
9
|
+
code: "Tab";
|
|
10
|
+
};
|
|
11
|
+
export declare function getDirection(e: KeyboardEvent & {
|
|
12
|
+
code: "ArrowUp" | "ArrowDown" | "ArrowLeft" | "ArrowRight";
|
|
13
|
+
}): Direction;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Keyboard events
|
|
2
|
+
export function isActivationKey(e) {
|
|
3
|
+
return e.code === "Enter" || e.code === "Space";
|
|
4
|
+
}
|
|
5
|
+
export function isArrowKey(e) {
|
|
6
|
+
return e.code.startsWith("Arrow");
|
|
7
|
+
}
|
|
8
|
+
export function isTabKey(e) {
|
|
9
|
+
return e.code === "Tab";
|
|
10
|
+
}
|
|
11
|
+
export function getDirection(e) {
|
|
12
|
+
return ["ArrowDown", "ArrowRight"].includes(e.code) ? "next" : "previous";
|
|
13
|
+
}
|
package/dist/utils/props.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function createStyles(styleObj: Record<string, string | number | null | undefined>, userStyles?: string): string | null;
|
|
1
|
+
export declare function createStyles(styleObj: Record<string, string | number | boolean | null | undefined>, userStyles?: string): string | null;
|
|
2
2
|
interface CreateClassesOptions {
|
|
3
3
|
component?: string;
|
|
4
4
|
element?: string;
|
package/dist/utils/props.js
CHANGED
|
@@ -3,7 +3,7 @@ export function createStyles(styleObj, userStyles) {
|
|
|
3
3
|
const stylesArray = Object.entries(styleObj);
|
|
4
4
|
const toJoin = [];
|
|
5
5
|
for (let [styleName, styleVal] of stylesArray) {
|
|
6
|
-
if (styleVal === undefined || styleVal === null) {
|
|
6
|
+
if (styleVal === undefined || styleVal === null || styleVal === false) {
|
|
7
7
|
continue;
|
|
8
8
|
}
|
|
9
9
|
styleName = convertCase(styleName, "camel", "kebab");
|