@skeletonlabs/skeleton
Advanced tools
Comparing version 0.78.0 to 0.80.7
@@ -6,5 +6,13 @@ // Action: Focus Trap | ||
let elemLast; | ||
function onElemLastKeydown(e) { | ||
if (e.code === 'Tab') { | ||
// When the first element is selected, shift+tab pressed, jump to the last selectable item. | ||
function onFirstElemKeydown(e) { | ||
if (e.shiftKey && e.code === 'Tab') { | ||
e.preventDefault(); | ||
elemLast.focus(); | ||
} | ||
} | ||
// When the last item selected, tab pressed, jump to the first selectable item. | ||
function onLastElemKeydown(e) { | ||
if (!e.shiftKey && e.code === 'Tab') { | ||
e.preventDefault(); | ||
elemFirst.focus(); | ||
@@ -24,4 +32,5 @@ } | ||
elemFirst.focus(); | ||
// Listen for keydown on last element | ||
elemLast.addEventListener('keydown', onElemLastKeydown); | ||
// Listen for keydown on first & last element | ||
elemFirst.addEventListener('keydown', onFirstElemKeydown); | ||
elemLast.addEventListener('keydown', onLastElemKeydown); | ||
} | ||
@@ -31,4 +40,6 @@ }; | ||
function onDestory() { | ||
if (elemFirst) | ||
elemFirst.removeEventListener('keydown', onFirstElemKeydown); | ||
if (elemLast) | ||
elemLast.removeEventListener('keydown', onElemLastKeydown); | ||
elemLast.removeEventListener('keydown', onLastElemKeydown); | ||
} | ||
@@ -35,0 +46,0 @@ // Lifecycle |
@@ -8,3 +8,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
background?: string | undefined; | ||
accent?: string | undefined; | ||
active?: string | undefined; | ||
hover?: string | undefined; | ||
width?: string | undefined; | ||
@@ -11,0 +12,0 @@ height?: string | undefined; |
@@ -9,7 +9,7 @@ import { SvelteComponentTyped } from "svelte"; | ||
label?: string | undefined; | ||
background?: string | undefined; | ||
regionIcon?: string | undefined; | ||
regionLabel?: string | undefined; | ||
selected?: Writable<any> | undefined; | ||
accent?: Writable<any> | undefined; | ||
active?: Writable<any> | undefined; | ||
hover?: Writable<any> | undefined; | ||
}; | ||
@@ -16,0 +16,0 @@ events: { |
@@ -6,2 +6,3 @@ import { SvelteComponentTyped } from "svelte"; | ||
files: FileList; | ||
title?: string | undefined; | ||
notes?: string | undefined; | ||
@@ -8,0 +9,0 @@ width?: string | undefined; |
@@ -6,3 +6,3 @@ import { SvelteComponentTyped } from "svelte"; | ||
tag?: string | undefined; | ||
direction?: String | undefined; | ||
direction?: string | undefined; | ||
from?: string | undefined; | ||
@@ -9,0 +9,0 @@ to?: string | undefined; |
@@ -11,2 +11,3 @@ import { SvelteComponentTyped } from "svelte"; | ||
borderColor?: string | undefined; | ||
padding?: string | undefined; | ||
hover?: string | undefined; | ||
@@ -13,0 +14,0 @@ accent?: string | undefined; |
@@ -5,5 +5,7 @@ import { SvelteComponentTyped } from "svelte"; | ||
props: { | ||
/** The item's selection value. */ value?: any; | ||
/** Defines a semantic ARIA label. */ label?: string | undefined; | ||
[x: string]: any; | ||
value?: any; | ||
label?: string | undefined; | ||
selected?: Writable<any> | undefined; | ||
padding?: string | undefined; | ||
hover?: string | undefined; | ||
@@ -10,0 +12,0 @@ accent?: string | undefined; |
@@ -1,1 +0,1 @@ | ||
export declare let icons: any; | ||
export declare const icons: any; |
@@ -6,3 +6,3 @@ /* | ||
*/ | ||
export let icons = { | ||
export const icons = { | ||
// Default Placeholder | ||
@@ -9,0 +9,0 @@ // Source: https://fontawesome.com/icons/image?s=solid |
export type { ConicStop } from './components/ConicGradient/types'; | ||
export type { DrawerSettings } from './utilities/Drawer/types'; | ||
export type { ModalSettings, ModalComponent } from './utilities/Modal/types'; | ||
@@ -6,6 +7,7 @@ export type { ToastSettings } from './utilities/Toast/types'; | ||
export { storeHighlightJs } from './utilities/CodeBlock/stores'; | ||
export { drawerStore } from './utilities/Drawer/stores'; | ||
export { modalStore } from './utilities/Modal/stores'; | ||
export { toastStore } from './utilities/Toast/stores'; | ||
export { storePrefersDarkScheme, storeLightSwitch } from './utilities/LightSwitch/stores'; | ||
export { type DataTableModel, dataTableHandler, dataTableSelect, dataTableSelectAll, dataTableSort, tableInteraction, tableA11y } from './utilities/DataTable/DataTable'; | ||
export { type DataTableModel, type DataTableOptions, createDataTableStore, dataTableHandler, tableInteraction, tableA11y } from './utilities/DataTable/DataTable'; | ||
export { localStorageStore } from './utilities/LocalStorageStore/LocalStorageStore'; | ||
@@ -12,0 +14,0 @@ export { tableSourceMapper, tableSourceValues, tableMapperValues } from './components/Table/utils'; |
// This file defines the short path imports for the package (ex: @skeletonlabs/skeleton/*) | ||
// Stores --- | ||
export { storeHighlightJs } from './utilities/CodeBlock/stores'; | ||
export { drawerStore } from './utilities/Drawer/stores'; | ||
export { modalStore } from './utilities/Modal/stores'; | ||
@@ -10,3 +11,3 @@ export { toastStore } from './utilities/Toast/stores'; | ||
// Utilities | ||
dataTableHandler, dataTableSelect, dataTableSelectAll, dataTableSort, | ||
createDataTableStore, dataTableHandler, | ||
// Svelte Actions | ||
@@ -13,0 +14,0 @@ tableInteraction, tableA11y } from './utilities/DataTable/DataTable'; |
{ | ||
"name": "@skeletonlabs/skeleton", | ||
"version": "0.78.0", | ||
"version": "0.80.7", | ||
"description": "A SvelteKit component library.", | ||
"author": "endigo9740 <csimmons@brainandbonesllc.com>", | ||
"author": "endigo9740 <chris@skeletonlabs.dev>", | ||
"devDependencies": { | ||
"@bobthered/tailwindcss-palette-generator": "^3.1.0", | ||
"@bobthered/tailwindcss-palette-generator": "^3.1.1", | ||
"@sveltejs/adapter-auto": "^1.0.0-next.89", | ||
"@sveltejs/kit": "^1.0.0-next.560", | ||
"@sveltejs/kit": "^1.0.0-next.561", | ||
"@sveltejs/package": "1.0.0-next.5", | ||
@@ -44,2 +44,6 @@ "@tailwindcss/forms": "^0.5.3", | ||
"./package.json": "./package.json", | ||
".": "./src/lib/index.ts", | ||
"./themes/*": "./src/lib/themes/*", | ||
"./styles/*": "./src/lib/styles/*", | ||
"./tailwind/*": "./src/lib/tailwind/*", | ||
"./actions/Clipboard/clipboard": "./actions/Clipboard/clipboard.js", | ||
@@ -92,3 +96,2 @@ "./actions/Filters/filter": "./actions/Filters/filter.js", | ||
"./components/Table/utils": "./components/Table/utils.js", | ||
".": "./index.js", | ||
"./styles/all.css": "./styles/all.css", | ||
@@ -99,2 +102,3 @@ "./styles/core.css": "./styles/core.css", | ||
"./styles/elements/cards.css": "./styles/elements/cards.css", | ||
"./styles/elements/chips.css": "./styles/elements/chips.css", | ||
"./styles/elements/lists.css": "./styles/elements/lists.css", | ||
@@ -110,2 +114,9 @@ "./styles/elements/logo-clouds.css": "./styles/elements/logo-clouds.css", | ||
"./styles/tailwind.css": "./styles/tailwind.css", | ||
"./styles/tokens/backgrounds.css": "./styles/tokens/backgrounds.css", | ||
"./styles/tokens/border-radius.css": "./styles/tokens/border-radius.css", | ||
"./styles/tokens/borders.css": "./styles/tokens/borders.css", | ||
"./styles/tokens/fills.css": "./styles/tokens/fills.css", | ||
"./styles/tokens/misc.css": "./styles/tokens/misc.css", | ||
"./styles/tokens/rings.css": "./styles/tokens/rings.css", | ||
"./styles/tokens/text.css": "./styles/tokens/text.css", | ||
"./styles/tokens.css": "./styles/tokens.css", | ||
@@ -115,3 +126,2 @@ "./styles/typography.css": "./styles/typography.css", | ||
"./tailwind/theme.cjs": "./tailwind/theme.cjs", | ||
"./themes/legacy/theme-skeleton.css": "./themes/legacy/theme-skeleton.css", | ||
"./themes/theme-crimson.css": "./themes/theme-crimson.css", | ||
@@ -133,2 +143,4 @@ "./themes/theme-gold-nouveau.css": "./themes/theme-gold-nouveau.css", | ||
"./utilities/Drawer/Drawer.svelte": "./utilities/Drawer/Drawer.svelte", | ||
"./utilities/Drawer/stores": "./utilities/Drawer/stores.js", | ||
"./utilities/Drawer/types": "./utilities/Drawer/types.js", | ||
"./utilities/LightSwitch/LightSwitch.svelte": "./utilities/LightSwitch/LightSwitch.svelte", | ||
@@ -139,3 +151,2 @@ "./utilities/LightSwitch/stores": "./utilities/LightSwitch/stores.js", | ||
"./utilities/Modal/Modal.svelte": "./utilities/Modal/Modal.svelte", | ||
"./utilities/Modal/Modal": "./utilities/Modal/Modal.js", | ||
"./utilities/Modal/examples/ModalExampleEmbed.svelte": "./utilities/Modal/examples/ModalExampleEmbed.svelte", | ||
@@ -151,3 +162,3 @@ "./utilities/Modal/examples/ModalExampleForm.svelte": "./utilities/Modal/examples/ModalExampleForm.svelte", | ||
}, | ||
"svelte": "./index.js" | ||
"svelte": "./src/lib/index.ts" | ||
} |
@@ -23,2 +23,7 @@ [![Skeleton](https://user-images.githubusercontent.com/1509726/199282306-7454adcb-b765-4618-8438-67655a7dee47.png)](https://www.skeleton.dev/) | ||
## 👍 Sponsor the Project | ||
- [Ko-Fi](https://ko-fi.com/skeletonlabs) | ||
- [Patreon](https://patreon.com/user?u=83786276) | ||
## 🐞 Report an Issue | ||
@@ -25,0 +30,0 @@ |
@@ -1,14 +0,18 @@ | ||
import { type Writable } from 'svelte/store'; | ||
import type { DataTableModel } from './types'; | ||
import type { DataTableModel, DataTableOptions } from './types'; | ||
export * from './types'; | ||
export * from './actions'; | ||
/** Creates the writeable store for the data table */ | ||
export declare function createDataTableStore<T extends Record<PropertyKey, any>>(source: T[], options?: DataTableOptions<T>): { | ||
subscribe: (this: void, run: import("svelte/store").Subscriber<DataTableModel<T>>, invalidate?: ((value?: DataTableModel<T> | undefined) => void) | undefined) => import("svelte/store").Unsubscriber; | ||
set: (this: void, value: DataTableModel<T>) => void; | ||
/** Sets a new data source while maintaining the state of the original source */ | ||
updateSource: (data: T[]) => void; | ||
/** Triggered by the "select all" checkbox to toggle all row selection. */ | ||
selectAll: (checked: boolean) => void; | ||
/** Allows you to dynamically pre-select rows on-demand. */ | ||
select: (key: keyof T, valuesArr: unknown[]) => void; | ||
/** Listens for clicks to a table heading with `data-sort` attribute. Updates `$dataTableModel.sort`. */ | ||
sort: (event: Event) => void; | ||
}; | ||
/** Listens for changes to `$dataTableModel` and triggers: search, selection, sort, and pagination. */ | ||
export declare function dataTableHandler(store: DataTableModel): void; | ||
/** A utility method for updating a select store value. */ | ||
export declare function dataTableStorePut(store: Writable<DataTableModel>, key: string, value: unknown): void; | ||
/** Allows you to dynamically pre-select rows on-demand. */ | ||
export declare function dataTableSelect(store: Writable<DataTableModel>, key: string, valuesArr: any): void; | ||
/** Triggered by the "select all" checkbox to toggle all row selection. */ | ||
export declare function dataTableSelectAll(event: any, store: Writable<DataTableModel>): void; | ||
/** Listens for clicks to a table heading with `data-sort` attribute. Updates `$dataTableModel.sort`. */ | ||
export declare function dataTableSort(event: any, store: Writable<DataTableModel>): void; | ||
export declare function dataTableHandler<T extends Record<PropertyKey, any>>(model: DataTableModel<T>): void; |
// Data Table Utilities | ||
// A set of utility features for local template-driven data tables. | ||
import { get } from 'svelte/store'; | ||
import { writable } from 'svelte/store'; | ||
// Exports | ||
export * from './types'; | ||
export * from './actions'; | ||
/** Creates the writeable store for the data table */ | ||
export function createDataTableStore(source, options = {}) { | ||
// Creates a new source that also adds the `dataTableChecked` property to each row object | ||
const modifiedList = source.map((rowObj) => ({ ...rowObj, dataTableChecked: false })); | ||
// Generate the writable | ||
const { subscribe, set, update } = writable({ | ||
source, | ||
base: modifiedList, | ||
filtered: modifiedList, | ||
sortState: { lastKey: '', asc: true }, | ||
selection: [], | ||
search: options.search ?? '', | ||
sort: options.sort ?? '', | ||
pagination: options.pagination | ||
}); | ||
return { | ||
subscribe, | ||
set, | ||
/** Sets a new data source while maintaining the state of the original source */ | ||
updateSource: (data) => update((model) => { | ||
model.source = data; | ||
model.base = data.map((row, i) => { | ||
return { ...row, dataTableChecked: model.base[i]?.dataTableChecked ?? false }; | ||
}); | ||
return { ...model, filtered: model.base }; | ||
}), | ||
/** Triggered by the "select all" checkbox to toggle all row selection. */ | ||
selectAll: (checked) => { | ||
update((model) => { | ||
// checks/unchecks all of the rows | ||
model.base.forEach((row) => { | ||
row.dataTableChecked = checked; | ||
return row; | ||
}); | ||
return model; | ||
}); | ||
}, | ||
/** Allows you to dynamically pre-select rows on-demand. */ | ||
select: (key, valuesArr) => { | ||
update((model) => { | ||
model.filtered.map((row) => { | ||
if (valuesArr.includes(row[key])) | ||
row.dataTableChecked = true; | ||
return row; | ||
}); | ||
return model; | ||
}); | ||
}, | ||
/** Listens for clicks to a table heading with `data-sort` attribute. Updates `$dataTableModel.sort`. */ | ||
sort: (event) => { | ||
update((model) => { | ||
if (!(event.target instanceof Element)) | ||
return model; | ||
const newSortKey = event.target.getAttribute('data-sort'); | ||
// If same key used repeated, toggle asc/dsc order | ||
if (newSortKey !== '' && newSortKey === model.sortState.lastKey) | ||
model.sortState.asc = !model.sortState.asc; | ||
// Cache the last key used | ||
model.sortState.lastKey = newSortKey; | ||
// Update sort key | ||
model.sort = newSortKey ?? ''; | ||
return model; | ||
}); | ||
} | ||
}; | ||
} | ||
// Data Table Handler | ||
/** Listens for changes to `$dataTableModel` and triggers: search, selection, sort, and pagination. */ | ||
export function dataTableHandler(store) { | ||
// Reset | ||
store.filtered = store.source; | ||
// Then | ||
searchHandler(store); | ||
selectionHandler(store); | ||
sortHandler(store); | ||
paginationHandler(store); | ||
export function dataTableHandler(model) { | ||
searchHandler(model); | ||
selectionHandler(model); | ||
sortHandler(model); | ||
paginationHandler(model); | ||
} | ||
// Utilities --- | ||
/** A utility method for updating a select store value. */ | ||
export function dataTableStorePut(store, key, value) { | ||
let newStore = get(store); | ||
newStore = { ...newStore, [key]: value }; | ||
store.set(newStore); | ||
} | ||
// Search --- | ||
function searchHandler(store) { | ||
store.filtered = store.filtered.filter((rowObj) => { | ||
store.filtered = store.base.filter((rowObj) => { | ||
const formattedSearchTerm = store.search?.toLowerCase() || ''; | ||
@@ -34,34 +90,5 @@ return Object.values(rowObj).join(' ').toLowerCase().includes(formattedSearchTerm); | ||
function selectionHandler(store) { | ||
store.selection = store.filtered.filter((row) => row.dataTableChecked === true); | ||
store.selection = store.base.filter((row) => row.dataTableChecked === true); // ? should this be filtered by source or filter? | ||
} | ||
/** Allows you to dynamically pre-select rows on-demand. */ | ||
export function dataTableSelect(store, key, valuesArr) { | ||
get(store).filtered.map((row) => { | ||
if (valuesArr.includes(row[key])) | ||
row.dataTableChecked = true; | ||
return row; | ||
}); | ||
} | ||
/** Triggered by the "select all" checkbox to toggle all row selection. */ | ||
export function dataTableSelectAll(event, store) { | ||
const isAllChecked = event.target.checked; | ||
const storeFiltered = get(store).source.forEach((row) => (row.dataTableChecked = isAllChecked)); | ||
dataTableStorePut(store, 'filtered', storeFiltered); | ||
} | ||
// Sort --- | ||
const sortState = { lastKey: '', asc: true }; | ||
/** Listens for clicks to a table heading with `data-sort` attribute. Updates `$dataTableModel.sort`. */ | ||
export function dataTableSort(event, store) { | ||
if (!(event.target instanceof Element)) | ||
return; | ||
const newSortKey = event.target.getAttribute('data-sort'); | ||
// If same key used repeated, toggle asc/dsc order | ||
if (newSortKey !== '' && newSortKey === sortState.lastKey) | ||
sortState.asc = !sortState.asc; | ||
// Cache the last key used | ||
sortState.lastKey = newSortKey; | ||
// Update store | ||
if (newSortKey) | ||
dataTableStorePut(store, 'sort', newSortKey); | ||
} | ||
function sortHandler(store) { | ||
@@ -71,7 +98,7 @@ if (!store.sort) | ||
// Sort order based on current sortState.asc value | ||
sortState.asc ? sortOrder('asc', store) : sortOrder('dsc', store); | ||
store.sortState.asc ? sortOrder('asc', store) : sortOrder('dsc', store); | ||
} | ||
function sortOrder(order, store) { | ||
const key = store.sort; | ||
store.filtered.sort((x, y) => { | ||
store.filtered = store.base.sort((x, y) => { | ||
// If descending, swap x/y | ||
@@ -91,11 +118,21 @@ if (order === 'dsc') | ||
function paginationHandler(store) { | ||
// store.sort = ''; // reset | ||
if (store.pagination) { | ||
// Slice for Pagination | ||
store.filtered = store.filtered.slice(store.pagination.offset * store.pagination.limit, // start | ||
const filtered = store.base.slice(store.pagination.offset * store.pagination.limit, // start | ||
store.pagination.offset * store.pagination.limit + store.pagination.limit // end | ||
); | ||
// Set Current Size | ||
store.pagination.size = store.source.length; | ||
// filter by search if currently searching | ||
if (store.search !== '') { | ||
store.filtered = store.filtered.slice(0, store.pagination.limit); | ||
// Set Current Size | ||
store.pagination.size = store.filtered.length; | ||
// Set the current page to the first page | ||
store.pagination.offset = 0; | ||
} | ||
else { | ||
store.filtered = filtered; | ||
// Set Current Size | ||
store.pagination.size = store.base.length; | ||
} | ||
} | ||
} |
import type { PaginationSettings } from '../../components/Paginator/types'; | ||
export interface DataTableModel { | ||
/** The original unfiltered source data. */ | ||
source: any[]; | ||
export interface DataTableModel<T extends Record<PropertyKey, unknown>> { | ||
/** The original source data. */ | ||
source: T[]; | ||
/** The unfiltered, modified source data */ | ||
base: Data<T>; | ||
/** The filtered source data, shown in UI. */ | ||
filtered: any[]; | ||
filtered: Data<T>; | ||
/** An array of selected row objects. */ | ||
selection?: any[]; | ||
selection: Data<T>; | ||
/** The current search term. */ | ||
search: string; | ||
/** The current sort key. */ | ||
sort: keyof T | ''; | ||
/** The current state of the sort key. */ | ||
sortState: { | ||
lastKey: keyof T | '' | null; | ||
asc: boolean; | ||
}; | ||
/** The Paginator component settings. */ | ||
pagination?: PaginationSettings; | ||
} | ||
export interface DataTableOptions<T> { | ||
/** The current search term. */ | ||
search?: string; | ||
/** The current sort key. */ | ||
sort: string; | ||
sort?: keyof T | ''; | ||
/** The Paginator component settings. */ | ||
pagination?: PaginationSettings; | ||
} | ||
export type Data<T> = (T & { | ||
dataTableChecked: boolean; | ||
})[]; |
import { SvelteComponentTyped } from "svelte"; | ||
import { type Writable } from 'svelte/store'; | ||
declare const __propDef: { | ||
props: { | ||
[x: string]: any; | ||
open?: Writable<boolean> | undefined; | ||
position?: string | undefined; | ||
position?: "left" | "top" | "right" | "bottom" | undefined; | ||
duration?: number | undefined; | ||
@@ -9,0 +7,0 @@ bgBackdrop?: string | undefined; |
@@ -8,2 +8,5 @@ // Action: Menu | ||
return; | ||
const elemWhitelist = 'a[href], button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'; | ||
let activeFocusIdx; | ||
let focusableElems; | ||
const onInit = () => { | ||
@@ -15,5 +18,15 @@ autoUpdateOrigin(); | ||
// Menu States --- | ||
const menuOpen = () => { | ||
const menuOpen = (openWithFocus = false) => { | ||
elemMenu.style.display = 'block'; | ||
stateEventHandler(true); | ||
// Create array of all focusable elements, so that we can iterate through them | ||
focusableElems = Array.from(elemMenu.querySelectorAll(elemWhitelist)); | ||
// reset the focus index | ||
activeFocusIdx = -1; | ||
if (openWithFocus) { | ||
// Automatically focus the element if openWithFocus is true (for example if | ||
// the menu was opened with Enter instead of with a click | ||
activeFocusIdx = 0; | ||
focusableElems[0]?.focus(); | ||
} | ||
}; | ||
@@ -30,11 +43,21 @@ const menuClose = () => { | ||
const onTriggerClick = () => { | ||
autoUpdateOrigin(); | ||
menuOpen(); | ||
// When the node is clicked, open the menu if it is closed, otherwise close it | ||
if (elemMenu.style.display === 'none') { | ||
autoUpdateOrigin(); | ||
menuOpen(); | ||
} | ||
else { | ||
menuClose(); | ||
} | ||
}; | ||
const onWindowClick = (event) => { | ||
args.interactive === true ? interactiveClickHandler(event) : standardClickHandler(); | ||
args.interactive === true ? interactiveClickHandler(event) : standardClickHandler(event); | ||
}; | ||
// Interactive FALSE - any click closes the menu | ||
const standardClickHandler = () => { | ||
menuClose(); | ||
const standardClickHandler = (event) => { | ||
// Any click closes the menu, except for when the node is clicked, since onTriggerClick() will take care of closing it in this case. If we don't include this check this function would close the menu when the node is clicked and onTriggerClick reopens it again because display will be 'none' again. | ||
const outsideNode = node && !node.contains(event.target); | ||
if (outsideNode) { | ||
menuClose(); | ||
} | ||
}; | ||
@@ -64,17 +87,41 @@ // Interactive TRUE - clicks outside close menu | ||
const onTriggerKeyDown = (event) => { | ||
if (['Enter', 'Space'].includes(event.code)) { | ||
const key = event.key; | ||
if (key === 'Enter' || key === 'Space') { | ||
event.preventDefault(); | ||
// Trigger Menu | ||
// Toggle menu | ||
onTriggerClick(); | ||
// If menu open, set focus | ||
if (elemMenu.style.display === 'block') { | ||
elemMenu.focus(); | ||
} | ||
} | ||
}; | ||
const onWindowKeyDown = (event) => { | ||
if (['Escape'].includes(event.code)) { | ||
const key = event.key; | ||
if (elemMenu.style.display === 'none') | ||
return; | ||
if (key === 'Escape' || key === 'Tab') { | ||
// Close the menu | ||
event.preventDefault(); | ||
menuClose(); | ||
node.focus(); | ||
} | ||
else if (key === 'ArrowDown') { | ||
event.preventDefault(); | ||
if (activeFocusIdx < focusableElems.length - 1) { | ||
// Move down the menu | ||
activeFocusIdx += 1; | ||
focusableElems[activeFocusIdx]?.focus(); | ||
} | ||
} | ||
else if (key === 'ArrowUp') { | ||
event.preventDefault(); | ||
if (activeFocusIdx > 0) { | ||
// Move up the menu | ||
activeFocusIdx -= 1; | ||
focusableElems[activeFocusIdx]?.focus(); | ||
} | ||
else if (focusableElems.length && activeFocusIdx === -1) { | ||
// Start at the bottom of the menu if first key is arrow up key | ||
event.preventDefault(); | ||
activeFocusIdx = focusableElems.length - 1; | ||
focusableElems[activeFocusIdx]?.focus(); | ||
} | ||
} | ||
}; | ||
@@ -81,0 +128,0 @@ // On Action Init |
@@ -1,1 +0,12 @@ | ||
export declare const modalStore: any; | ||
import type { ModalSettings } from './types'; | ||
export declare const modalStore: { | ||
subscribe: (this: void, run: import("svelte/store").Subscriber<ModalSettings[]>, invalidate?: ((value?: ModalSettings[] | undefined) => void) | undefined) => import("svelte/store").Unsubscriber; | ||
set: (this: void, value: ModalSettings[]) => void; | ||
update: (this: void, updater: import("svelte/store").Updater<ModalSettings[]>) => void; | ||
/** Append to end of queue. */ | ||
trigger: (modal: ModalSettings) => void; | ||
/** Remove first item in queue. */ | ||
close: () => void; | ||
/** Remove all items from queue. */ | ||
clear: () => void; | ||
}; |
@@ -7,2 +7,4 @@ // Modal Store Queue | ||
subscribe, | ||
set, | ||
update, | ||
/** Append to end of queue. */ | ||
@@ -9,0 +11,0 @@ trigger: (modal) => update((mStore) => { |
@@ -5,3 +5,3 @@ export interface ModalComponent { | ||
/** Provide a key/value pairs of component props. */ | ||
props?: Record<string, string>; | ||
props?: Record<string, unknown>; | ||
/** Provide an HTML template literal for the default slot. */ | ||
@@ -8,0 +8,0 @@ slot?: string; |
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
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
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
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
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
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
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
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
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
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
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
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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
317160
182
5665
39