Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General Updates 2 #3

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
31 changes: 31 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export { default as Button } from "./Button/Button.svelte";
export { default as Checkbox } from "./Checkbox/Checkbox.svelte";
export { default as ToggleSwitch } from "./ToggleSwitch/ToggleSwitch.svelte";
export { default as RadioButton } from "./RadioButton/RadioButton.svelte";
export { default as ProgressRing } from "./ProgressRing/ProgressRing.svelte";
export { default as ProgressBar } from "./ProgressBar/ProgressBar.svelte";
export { default as ComboBox } from "./ComboBox/ComboBox.svelte";
export { default as InfoBadge } from "./InfoBadge/InfoBadge.svelte";
export { default as Flyout } from "./Flyout/FlyoutWrapper.svelte";
export { default as InfoBar } from "./InfoBar/InfoBar.svelte";
export { default as TextBox } from "./TextBox/TextBox.svelte";
export { default as TextBoxButton } from "./TextBox/TextBoxButton.svelte";
export { default as NumberBox } from "./NumberBox/NumberBox.svelte";
export { default as AutoSuggestBox } from "./AutoSuggestBox/AutoSuggestBox.svelte";
export { default as Slider } from "./Slider/Slider.svelte";
export { default as PersonPicture } from "./PersonPicture/PersonPicture.svelte";
export { default as Tooltip } from "./Tooltip/TooltipWrapper.svelte";
export { default as ContentDialog } from "./ContentDialog/ContentDialog.svelte";
export { default as Expander } from "./Expander/Expander.svelte";
export { default as TextBlock } from "./TextBlock/TextBlock.svelte";
export { default as IconButton } from "./IconButton/IconButton.svelte";
export { default as ListItem } from "./ListItem/ListItem.svelte";
export { default as MenuBar } from "./MenuBar/MenuBar.svelte";
export { default as MenuBarItem } from "./MenuBar/MenuBarItem.svelte";
export { default as MenuFlyout } from "./MenuFlyout/MenuFlyoutWrapper.svelte";
export { default as MenuFlyoutItem } from "./MenuFlyout/MenuFlyoutItem.svelte";
export { default as MenuFlyoutDivider } from "./MenuFlyout/MenuFlyoutDivider.svelte";
export { default as ContextMenu } from "./ContextMenu/ContextMenu.svelte";
export { default as CalendarView } from "./CalendarView/CalendarView.svelte";
export { default as CalendarDatePicker } from "./CalendarDatePicker/CalendarDatePicker.svelte";
export { default as NavigationView } from "./NavigationView/NavigationView.svelte";
File renamed without changes.
210 changes: 210 additions & 0 deletions internal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
import { bubble, listen } from "svelte/internal";

import { tabbable } from "tabbable";
import { createFocusTrap } from "focus-trap";

export { default as ComboBoxItem } from "./ComboBox/ComboBoxItem.svelte";
export { default as FlyoutSurface } from "./Flyout/FlyoutSurface.svelte";
export { default as TooltipSurface } from "./Tooltip/TooltipSurface.svelte";
export { default as MenuFlyoutSurface } from "./MenuFlyout/MenuFlyoutSurface.svelte";
export { default as CalendarViewItem } from "./CalendarView/CalendarViewItem.svelte";

// Svelte action for handling outer mouse
interface ExternalMouseEventOptions {
type?: string;
stopPropagation?: boolean;
}
export function externalMouseEvents(
node: HTMLElement,
options: ExternalMouseEventOptions = { type: "click", stopPropagation: false }
) {
const { type, stopPropagation } = options;
const handleEvent = (event: MouseEvent) => {
if (stopPropagation) event.stopPropagation();
if (node && !node.contains(event.target as HTMLElement) && !event.defaultPrevented) {
node.dispatchEvent(
new CustomEvent(`outer${type}`, {
detail: event
})
);
}
};

document.addEventListener(type, handleEvent, true);

return {
destroy() {
document.removeEventListener(type, handleEvent, true);
}
};
}

// Basic wrapper action around focus-trap
export function focusTrap(node: HTMLElement, options?: FocusTrapOptions) {
const trap = createFocusTrap(node, (options = { ...options, fallbackFocus: node }));
trap.activate();

return {
destroy() {
trap.deactivate();
}
};
}

// ID generator for handling WAI-ARIA related attributes
export function uid(prefix: string) {
return (
prefix +
String.fromCharCode(Math.floor(Math.random() * 26) + 97) +
Math.random().toString(16).slice(2) +
Date.now().toString(16).split(".")[0]
);
}

interface ArrowNavigationOptions {
preventTab?: boolean;
stopPropagation?: boolean;
}

// Controls the focus of a list of elements by using the arrow keys
export function arrowNavigation(
node: HTMLElement,
options: ArrowNavigationOptions = { preventTab: false, stopPropagation: false }
) {
const handleKeyDown = (event: KeyboardEvent) => {
const { key } = event;
const { activeElement } = document;

let tabOrder = <HTMLElement[]>tabbable(node);
// if (directChildren) tabOrder = tabOrder.filter(child => child.parentElement === node);
const activeIndex = tabOrder.indexOf(document.activeElement as HTMLElement);

if (tabOrder.length < 0) return;
if (
key === "ArrowUp" ||
key === "ArrowDown" ||
key === "Home" ||
key === "End" ||
(key === "Tab" && options.preventTab)
) {
event.preventDefault();
if (options.stopPropagation) event.stopPropagation();
}

if (key === "ArrowUp") {
if (tabOrder[0] === activeElement) {
tabOrder[tabOrder.length - 1].focus();
} else if (tabOrder.includes(<HTMLElement>activeElement)) {
tabOrder[activeIndex - 1].focus();
}
} else if (key === "ArrowDown") {
if (tabOrder[tabOrder.length - 1] === activeElement) {
tabOrder[0].focus();
} else if (tabOrder.includes(<HTMLElement>activeElement)) {
tabOrder[activeIndex + 1].focus();
}
} else if (key === "Home") {
tabOrder[0].focus();
} else if (key === "End") {
tabOrder[tabOrder.length - 1].focus();
}
};

node.addEventListener("keydown", handleKeyDown);

return {
destroy: () => node.removeEventListener("keydown", handleKeyDown)
};
}

// Returns a number representing the duration of a specified CSS custom property in ms
export function getCSSDuration(property) {
const duration = window.getComputedStyle(document.documentElement).getPropertyValue(property);

return parseFloat(duration) * (/\ds$/.test(duration) ? 1000 : 1) || 0;
}

// Function for forwarding DOM events to the component's declaration
// Adapted from rgossiaux/svelte-headlessui which is modified from hperrin/svelte-material-ui
export function createEventForwarder(component: SvelteComponent, exclude: string[] = []) {
type EventCallback = (event: any) => void;

// This is our pseudo $on function. It is defined on component mount.
let $on: (eventType: string, callback: EventCallback) => () => void;

// This is a list of events bound before mount.
let events: [string, EventCallback][] = [];

// Monkeypatch SvelteComponent.$on with our own forward-compatible version
component.$on = (eventType: string, callback: EventCallback) => {
let destructor = () => {};
if (exclude.includes(eventType)) {
// Bail out of the event forwarding and run the normal Svelte $on() code
const callbacks =
component.$$.callbacks[eventType] || (component.$$.callbacks[eventType] = []);
callbacks.push(callback);
return () => {
const index = callbacks.indexOf(callback);
if (index !== -1) callbacks.splice(index, 1);
};
}
if ($on) {
destructor = $on(eventType, callback); // The event was bound programmatically.
} else {
events.push([eventType, callback]); // The event was bound before mount by Svelte.
}
return () => destructor();
};

return (node: HTMLElement | SVGElement) => {
const destructors: (() => void)[] = [];
const forwardDestructors: { [k: string]: () => void } = {};
const forward = (e: Event) => bubble(component, e);

// This function is responsible for listening and forwarding
// all bound events.
$on = (eventType, callback) => {
let handler = callback;
// DOM addEventListener options argument.
let options: boolean | AddEventListenerOptions = false;

// Listen for the event directly, with the given options.
const off = listen(node, eventType, handler, options);
const destructor = () => {
off();
const idx = destructors.indexOf(destructor);
if (idx > -1) {
destructors.splice(idx, 1);
}
};

destructors.push(destructor);

// Forward the event from Svelte.
if (!(eventType in forwardDestructors)) {
forwardDestructors[eventType] = listen(node, eventType, forward);
}

return destructor;
};

// Listen to all the events added before mount.
for (const event of events) {
$on(event[0], event[1]);
}

return {
destroy: () => {
// Remove all event listeners.
for (const destructor of destructors) {
destructor();
}

// Remove all event forwarders.
for (let entry of Object.entries(forwardDestructors)) {
entry[1]();
}
}
};
};
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@riversidevalley/fluid",
"version": "1.7.0",
"version": "1.8.0",
"description": "A UI framework for web based on Microsoft Fluent UI 🎨🏗️",
"homepage": "https://github.com/RiversideValley/Fluid.Framework",
"license": "MIT",
Expand Down
12 changes: 0 additions & 12 deletions src/app.html

This file was deleted.

1 change: 0 additions & 1 deletion src/global.d.ts

This file was deleted.

48 changes: 0 additions & 48 deletions src/routes/__layout.svelte

This file was deleted.

Loading