@ulu/frontend-vue 0.1.0-beta.1
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/LICENSE +21 -0
- package/README.md +9 -0
- package/dist/breakpoints-ClT9bfZm.js +211 -0
- package/dist/frontend-vue.css +1 -0
- package/dist/frontend-vue.js +82 -0
- package/dist/frontend-vue.umd.cjs +561 -0
- package/dist/index-P5Rwl_Dl.js +7263 -0
- package/dist/index.es-HlG3u0J5.js +3134 -0
- package/lib/_index.scss +14 -0
- package/lib/components/_index.scss +6 -0
- package/lib/components/collapsible/UluAccordion.vue +82 -0
- package/lib/components/collapsible/UluCollapsibleRegion.vue +278 -0
- package/lib/components/collapsible/UluDropdown.vue +42 -0
- package/lib/components/collapsible/UluModal.vue +384 -0
- package/lib/components/collapsible/UluOverflowPopover.vue +52 -0
- package/lib/components/collapsible/UluTab.vue +9 -0
- package/lib/components/collapsible/UluTabGroup.vue +31 -0
- package/lib/components/collapsible/UluTabList.vue +9 -0
- package/lib/components/collapsible/UluTabPanel.vue +9 -0
- package/lib/components/collapsible/UluTabPanels.vue +9 -0
- package/lib/components/elements/UluAlert.vue +81 -0
- package/lib/components/elements/UluBadge.vue +58 -0
- package/lib/components/elements/UluBadgeStack.vue +27 -0
- package/lib/components/elements/UluButton.vue +161 -0
- package/lib/components/elements/UluCallout.vue +30 -0
- package/lib/components/elements/UluCard.vue +241 -0
- package/lib/components/elements/UluDefinitionList.vue +40 -0
- package/lib/components/elements/UluExternalLink.vue +47 -0
- package/lib/components/elements/UluIcon.vue +108 -0
- package/lib/components/elements/UluList.vue +87 -0
- package/lib/components/elements/UluMain.vue +5 -0
- package/lib/components/elements/UluSpokeSpinner.vue +25 -0
- package/lib/components/elements/UluTag.vue +53 -0
- package/lib/components/forms/UluCheckboxMenu.vue +36 -0
- package/lib/components/forms/UluFileDisplay.vue +39 -0
- package/lib/components/forms/UluFormDropzone.vue +62 -0
- package/lib/components/forms/UluFormFile.vue +47 -0
- package/lib/components/forms/UluFormMessage.vue +20 -0
- package/lib/components/forms/UluFormSelect.vue +37 -0
- package/lib/components/forms/UluFormText.vue +32 -0
- package/lib/components/forms/UluSearchForm.vue +31 -0
- package/lib/components/index.js +54 -0
- package/lib/components/layout/UluAdaptiveLayout.vue +11 -0
- package/lib/components/layout/UluDataGrid.vue +41 -0
- package/lib/components/layout/UluTitleRail.vue +56 -0
- package/lib/components/layout/UluWhenBreakpoint.vue +86 -0
- package/lib/components/navigation/UluBreadcrumb.vue +72 -0
- package/lib/components/navigation/UluMenu.vue +105 -0
- package/lib/components/navigation/UluMenuStack.vue +49 -0
- package/lib/components/navigation/UluNavStrip.vue +48 -0
- package/lib/components/navigation/UluSkipLink.vue +5 -0
- package/lib/components/systems/facets/UluFacets.vue +380 -0
- package/lib/components/systems/facets/UluFacetsList.vue +39 -0
- package/lib/components/systems/facets/UluFacetsSearch.vue +67 -0
- package/lib/components/systems/facets/_facets.scss +64 -0
- package/lib/components/systems/index.js +17 -0
- package/lib/components/systems/scroll-anchors/UluScrollAnchors.vue +152 -0
- package/lib/components/systems/scroll-anchors/UluScrollAnchorsNav.vue +37 -0
- package/lib/components/systems/scroll-anchors/UluScrollAnchorsNavAnimated.vue +124 -0
- package/lib/components/systems/scroll-anchors/UluScrollAnchorsSection.vue +63 -0
- package/lib/components/systems/scroll-anchors/symbols.js +6 -0
- package/lib/components/systems/skeleton/UluShowSkeleton.vue +13 -0
- package/lib/components/systems/skeleton/UluSkeletonContent.vue +60 -0
- package/lib/components/systems/skeleton/UluSkeletonMedia.vue +11 -0
- package/lib/components/systems/skeleton/UluSkeletonTextInline.vue +9 -0
- package/lib/components/systems/slider/UluImageSlideShow.vue +75 -0
- package/lib/components/systems/slider/UluSlideShow.vue +331 -0
- package/lib/components/systems/slider/UluSlideShowSlide.vue +25 -0
- package/lib/components/systems/table-sticky/UluTableSticky.vue +793 -0
- package/lib/components/systems/table-sticky/UluTableStickyRows.vue +73 -0
- package/lib/components/systems/table-sticky/UluTableStickyTable.vue +237 -0
- package/lib/components/systems/table-sticky/_table-sticky.scss +185 -0
- package/lib/components/utils/UluCondText.vue +28 -0
- package/lib/components/utils/UluEmpty.vue +3 -0
- package/lib/components/utils/UluEmptyView.vue +3 -0
- package/lib/components/utils/UluPlaceholderImage.vue +53 -0
- package/lib/components/utils/UluPlaceholderText.vue +25 -0
- package/lib/components/utils/UluRouteAnnouncer.vue +83 -0
- package/lib/components/visualizations/UluAnimateNumber.vue +32 -0
- package/lib/components/visualizations/UluProgressBar.vue +94 -0
- package/lib/components/visualizations/UluProgressDonut.vue +97 -0
- package/lib/composables/index.js +10 -0
- package/lib/composables/useBreakpointManager.js +68 -0
- package/lib/composables/useIcon.js +62 -0
- package/lib/composables/useModifiers.js +93 -0
- package/lib/composables/useWindowResize.js +64 -0
- package/lib/index.js +10 -0
- package/lib/plugins/_index.scss +7 -0
- package/lib/plugins/breakpoints/index.js +47 -0
- package/lib/plugins/index.js +11 -0
- package/lib/plugins/modals/UluModalsDisplay.vue +59 -0
- package/lib/plugins/modals/api.js +76 -0
- package/lib/plugins/modals/index.js +60 -0
- package/lib/plugins/modals/useModals.js +9 -0
- package/lib/plugins/popovers/UluPopover.vue +189 -0
- package/lib/plugins/popovers/UluTooltipDisplay.vue +15 -0
- package/lib/plugins/popovers/UluTooltipPopover.vue +83 -0
- package/lib/plugins/popovers/defaults.js +108 -0
- package/lib/plugins/popovers/directive.js +95 -0
- package/lib/plugins/popovers/index.js +18 -0
- package/lib/plugins/popovers/manager.js +54 -0
- package/lib/plugins/popovers/useFollow.js +80 -0
- package/lib/plugins/popovers/utils.js +5 -0
- package/lib/plugins/toast/UluToast.vue +87 -0
- package/lib/plugins/toast/UluToastDisplay.vue +35 -0
- package/lib/plugins/toast/_toast.scss +198 -0
- package/lib/plugins/toast/defaults.js +30 -0
- package/lib/plugins/toast/index.js +17 -0
- package/lib/plugins/toast/store.js +71 -0
- package/lib/plugins/toast/useToast.js +18 -0
- package/lib/settings.js +119 -0
- package/lib/utils/dom.js +14 -0
- package/lib/utils/placeholder.js +6 -0
- package/lib/utils/vue-router.js +219 -0
- package/package.json +75 -0
package/lib/settings.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module settings
|
|
3
|
+
* @description Manages shared configuration for the library.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { reactive } from 'vue';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Default settings
|
|
10
|
+
* @typedef {object} Defaults
|
|
11
|
+
* @property {string} fontAwesomeStatic - Whether the default UluIcon should use fontawesome vue or fontawesome CSS classes (static)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @type {Defaults}
|
|
16
|
+
*/
|
|
17
|
+
const defaults = {
|
|
18
|
+
/**
|
|
19
|
+
* If set UluIcon will use global css classes instead of Font Awesome vue component
|
|
20
|
+
*/
|
|
21
|
+
fontAwesomeStatic: false,
|
|
22
|
+
/**
|
|
23
|
+
* Use a different icon component (if using a library other than Font Awesome)
|
|
24
|
+
* - Need to have this component map (iconsByType) to it's implementation
|
|
25
|
+
* - All components internally use type, so only user defined components change definitions
|
|
26
|
+
* - So you should only need to create definitions for the default types to replace this for the library
|
|
27
|
+
*/
|
|
28
|
+
iconComponent: null,
|
|
29
|
+
/**
|
|
30
|
+
* Which prop in iconComponent should receive the resolved definition
|
|
31
|
+
*/
|
|
32
|
+
iconPropResolver: (definition) => ({ icon: definition }),
|
|
33
|
+
/**
|
|
34
|
+
* Default icons by type
|
|
35
|
+
*/
|
|
36
|
+
iconsByType: {
|
|
37
|
+
danger: "fas fa-triangle-exclamation",
|
|
38
|
+
warning: "fas fa-circle-exclamation",
|
|
39
|
+
info: "fas fa-circle-info",
|
|
40
|
+
success: "fas fa-circle-check",
|
|
41
|
+
externalLink: "fas fa-arrow-up-right-from-square",
|
|
42
|
+
close: "fas fa-xmark",
|
|
43
|
+
expand: "fas fa-plus",
|
|
44
|
+
collapse: "fas fa-minus",
|
|
45
|
+
resizeHorizontal: "fas fa-grip-lines-vertical",
|
|
46
|
+
resizeVertical: "fas fa-grip-lines",
|
|
47
|
+
resizeBoth: "fas fa-grip",
|
|
48
|
+
ellipsis: "fas fa-ellipsis",
|
|
49
|
+
pathSeparator: "fas fa-chevron-right"
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Current configuration, initialized with defaults and made reactive
|
|
54
|
+
// We wrap `defaults` in `reactive` so `currentSettings` becomes a reactive object.
|
|
55
|
+
let currentSettings = reactive({ ...defaults });
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Retrieves a copy of the default settings.
|
|
59
|
+
* @returns {object} A copy of the default settings object.
|
|
60
|
+
*/
|
|
61
|
+
export function getDefaultSettings() {
|
|
62
|
+
// Return a non-reactive copy of defaults
|
|
63
|
+
return { ...defaults };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Updates multiple configuration settings.
|
|
68
|
+
* @param {object} changes An object containing the settings to update.
|
|
69
|
+
*/
|
|
70
|
+
export function updateSettings(changes) {
|
|
71
|
+
Object.assign(currentSettings, changes);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Retrieves a copy of the current configuration settings.
|
|
76
|
+
* @returns {object} A copy of the current settings object (vue reactive object)
|
|
77
|
+
*/
|
|
78
|
+
export function getSettings() {
|
|
79
|
+
return currentSettings;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Retrieves a specific configuration setting by key.
|
|
84
|
+
* @param {string} key The key of the setting to retrieve.
|
|
85
|
+
* @returns {*} The value of the setting, or undefined if not found.
|
|
86
|
+
*/
|
|
87
|
+
export function getSetting(key) {
|
|
88
|
+
if (!currentSettings.hasOwnProperty(key)) {
|
|
89
|
+
console.warn(`Attempted to access non-existent setting: ${key}`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
return currentSettings[key];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Updates a specific configuration setting.
|
|
97
|
+
* @param {string} key The key of the setting to update.
|
|
98
|
+
* @param {*} value The new value for the setting.
|
|
99
|
+
*/
|
|
100
|
+
export function updateSetting(key, value) {
|
|
101
|
+
if (typeof key !== "string") {
|
|
102
|
+
throw new Error("Expected key to be string");
|
|
103
|
+
}
|
|
104
|
+
currentSettings[key] = value;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Retrieves the icon definition by type
|
|
109
|
+
* @param {string} type - The type of icon to retrieve (e.g., 'error', 'info').
|
|
110
|
+
* @returns {string} The icon definition
|
|
111
|
+
* @throws {Error} If the specified icon type is not found
|
|
112
|
+
*/
|
|
113
|
+
export function getIconByType(type) {
|
|
114
|
+
const icons = currentSettings.iconsByType;
|
|
115
|
+
if (!icons[type]) {
|
|
116
|
+
throw new Error(`Icon type "${ type }" not found!`);
|
|
117
|
+
}
|
|
118
|
+
return icons[type];
|
|
119
|
+
}
|
package/lib/utils/dom.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a Vue template ref's unwrapped value to its underlying DOM element
|
|
3
|
+
*
|
|
4
|
+
* @param {HTMLElement|Object} value - The unwrapped value from a template ref (e.g., `this.$refs.myElement` or `this.$refs.myComponent`)
|
|
5
|
+
* @returns {HTMLElement} The HTMLElement or undefined if not found/resolved.
|
|
6
|
+
*/
|
|
7
|
+
export function refToElement(value) {
|
|
8
|
+
if (!value) return;
|
|
9
|
+
if (value instanceof HTMLElement) {
|
|
10
|
+
return value;
|
|
11
|
+
} else if (typeof value === 'object' && '$el' in value) {
|
|
12
|
+
return value.$el;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam commodo felis nisi, nec pretium justo varius sit amet. Vestibulum vitae quam in velit scelerisque tincidunt et vitae mauris. Fusce aliquet, ipsum sit amet lacinia euismod, est risus rhoncus ligula, eget egestas urna ligula nec enim. Fusce vulputate ornare ligula ut tempus. Sed accumsan orci sed turpis iaculis, at aliquam nibh rhoncus. Maecenas porta lorem a sem tincidunt, sed tristique ex laoreet. Nullam accumsan metus at lobortis interdum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam sagittis sem erat, quis fermentum lectus ultrices quis.",
|
|
3
|
+
textSmall: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam commodo felis nisi, nec pretium justo varius sit amet.",
|
|
4
|
+
paragraph: "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam commodo felis nisi, nec pretium justo varius sit amet. Vestibulum vitae quam in velit scelerisque tincidunt et vitae mauris. Fusce aliquet, ipsum sit amet lacinia euismod, est risus rhoncus ligula, eget egestas urna ligula nec enim. Fusce vulputate ornare ligula ut tempus. Sed accumsan orci sed turpis iaculis, at aliquam nibh rhoncus. Maecenas porta lorem a sem tincidunt, sed tristique ex laoreet. Nullam accumsan metus at lobortis interdum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam sagittis sem erat, quis fermentum lectus ultrices quis.</p>",
|
|
5
|
+
paragraphSmall: "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam commodo felis nisi, nec pretium justo varius sit amet. Vestibulum vitae quam in velit scelerisque tincidunt et vitae mauris. </p>"
|
|
6
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Module Creates Menus from route or router config
|
|
3
|
+
* - Note: Functions prefixed with "$" work with $route objects (running application, provided by vue-router ie $router, useRoute, etc),
|
|
4
|
+
* @module utils/router-utils
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Route Menu Item
|
|
9
|
+
* @typedef {Object} RouteMenuItem
|
|
10
|
+
* @property {String} path - Menu item route path
|
|
11
|
+
* @property {String} title - Menu item title
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get root/base static routes as menu items
|
|
16
|
+
* @param {*} routes Routes to build menu from (not router instance)
|
|
17
|
+
* @param {Object} options Options
|
|
18
|
+
* @param {Object} options.qualifier Callback to qualify as a base route (defaults to isStaticBaseRoute)
|
|
19
|
+
* @param {Object} options.item Options for createMenuItem
|
|
20
|
+
* @returns {Array.<RouteMenuItem>} Array of menu items
|
|
21
|
+
*/
|
|
22
|
+
export function createBaseMenu(routes, options) {
|
|
23
|
+
const defaults = {
|
|
24
|
+
qualifier: isStaticBaseRoute,
|
|
25
|
+
sort: sortByWeight,
|
|
26
|
+
item: {}
|
|
27
|
+
};
|
|
28
|
+
const opts = Object.assign({}, defaults, options);
|
|
29
|
+
return routes
|
|
30
|
+
.filter(opts.qualifier)
|
|
31
|
+
.map(r => {
|
|
32
|
+
// Need to grab meta from child but use the parent path
|
|
33
|
+
const menuRoute = r.children ? getChildIndexRoute(r.children) : r;
|
|
34
|
+
return createMenuItem(menuRoute, r.path, opts.item);
|
|
35
|
+
})
|
|
36
|
+
.sort(opts.sort);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Print out a section's menu based on path
|
|
41
|
+
* @param {*} routes All routes
|
|
42
|
+
* @param {*} sectionPath Path for section to create menu
|
|
43
|
+
* @param {Object} options Options
|
|
44
|
+
* @param {Boolean} options.includeIndex Include the parent/index in the menu items ie ({ path: "" })
|
|
45
|
+
* @param {Object} options.item Options to be passed to createMenuItem
|
|
46
|
+
* @returns {Array.<RouteMenuItem>} Array of menu items
|
|
47
|
+
*/
|
|
48
|
+
export function createSectionMenu(routes, sectionPath, options) {
|
|
49
|
+
const defaults = {
|
|
50
|
+
includeIndex: false,
|
|
51
|
+
item: {},
|
|
52
|
+
sort: sortByWeight
|
|
53
|
+
};
|
|
54
|
+
const opts = Object.assign({}, defaults, options);
|
|
55
|
+
const base = routes.find(r => r.path !== "/" && sectionPath.includes(r.path));
|
|
56
|
+
// Go through each item and
|
|
57
|
+
const getSection = (current, previous, path) => {
|
|
58
|
+
if (current.children) {
|
|
59
|
+
const child = current.children.find(c => c.path.includes(sectionPath));
|
|
60
|
+
if (child) {
|
|
61
|
+
return getSection(child, current, path + child.path);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { route: previous, path };
|
|
65
|
+
};
|
|
66
|
+
const { route, path } = getSection(base, base, base.path);
|
|
67
|
+
if (!route.children) {
|
|
68
|
+
console.warn("Unable to build menu for:", sectionPath);
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
return route.children
|
|
72
|
+
.filter(includeIndex(opts.includeIndex))
|
|
73
|
+
.map(r => createMenuItem(r, `${ path }/${ r.path }`, opts.item))
|
|
74
|
+
.sort(opts.sort);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* For a given route this will return the route that renders. For routes without
|
|
79
|
+
* children this is the route itself for those with children (first child with empty path)
|
|
80
|
+
* @param {Object} route Route object to resolve
|
|
81
|
+
* @returns {Object} Resolved route
|
|
82
|
+
*/
|
|
83
|
+
// export function resolveRouteIndex(route) {
|
|
84
|
+
// if (route.children) {
|
|
85
|
+
// return getChildIndexRoute(route.children);
|
|
86
|
+
// } else {
|
|
87
|
+
// return route;
|
|
88
|
+
// }
|
|
89
|
+
// }
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* For a given array of child routes return the index
|
|
93
|
+
* @param {Array} children Children array of routes
|
|
94
|
+
* @returns {Object} Route
|
|
95
|
+
*/
|
|
96
|
+
export function getChildIndexRoute(children) {
|
|
97
|
+
return children.find(r => r.path === "");
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Creates common menu item structure from route, pulls title and weight from meta (on route or index child)
|
|
101
|
+
* @param {Object} route Route
|
|
102
|
+
* @param {Object} routePath The final path for the menu item
|
|
103
|
+
* @param {Object} options Function to allow alterering the menu item (adding meta, etc)
|
|
104
|
+
* @param {Function} options.modify Function to allow alterering the menu item (adding meta, etc) (args: item, route)
|
|
105
|
+
* @param {Function} options.indexMeta Include the routes index child's meta (merged on top of route meta)
|
|
106
|
+
* @returns {RouteMenuItem} Menu item
|
|
107
|
+
*/
|
|
108
|
+
export function createMenuItem(route, routePath = route.path, options) {
|
|
109
|
+
const defaults = {
|
|
110
|
+
indexMeta: true,
|
|
111
|
+
modify: null,
|
|
112
|
+
};
|
|
113
|
+
const opts = Object.assign({}, defaults, options);
|
|
114
|
+
let meta = Object.assign({}, route.meta);
|
|
115
|
+
if (opts.indexMeta && route.children) {
|
|
116
|
+
meta = Object.assign({}, meta, getChildIndexRoute(route.children)?.meta);
|
|
117
|
+
}
|
|
118
|
+
const item = {
|
|
119
|
+
path: routePath,
|
|
120
|
+
title: meta?.title || "Missing Title",
|
|
121
|
+
weight: meta?.weight || 0,
|
|
122
|
+
meta
|
|
123
|
+
};
|
|
124
|
+
if (opts.modify) {
|
|
125
|
+
opts.modify(item, route);
|
|
126
|
+
}
|
|
127
|
+
return item;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Test if route is static (doesn't incude parameters)
|
|
131
|
+
* @param {Object} route Route object to test
|
|
132
|
+
* @returns {Boolean} Whether or not this route is static (not dynamic)
|
|
133
|
+
*/
|
|
134
|
+
export function isStaticRoute(route) {
|
|
135
|
+
return !route.path.includes("/:");
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
*
|
|
139
|
+
* @param {Object} route Route object to test
|
|
140
|
+
* @returns {Boolean} Whether or not this route is a static base route
|
|
141
|
+
*/
|
|
142
|
+
export function isStaticBaseRoute(route) {
|
|
143
|
+
const matches = route.path.match(/\//) || [];
|
|
144
|
+
return isStaticRoute(route) && matches.length === 1;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Function to make normal <a> behave as router links instread of page reload
|
|
148
|
+
* @param {Object} router Router instance (ie src/router) to push routes to
|
|
149
|
+
* @param {Object} event The event object that triggered route change (ie. onclick) pass event object
|
|
150
|
+
*/
|
|
151
|
+
export function nativeLinkRouter(router, event) {
|
|
152
|
+
const { target } = event;
|
|
153
|
+
const link = target.closest("a");
|
|
154
|
+
if (link) {
|
|
155
|
+
let href = link.getAttribute("href");
|
|
156
|
+
if (href.startsWith("/")) {
|
|
157
|
+
router.push(href);
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Returns the child routes for base route
|
|
164
|
+
* @param {Object} route Route Object
|
|
165
|
+
* @returns
|
|
166
|
+
*/
|
|
167
|
+
export function $getRouteChildren(route, parent = $getParentRoute(route)) {
|
|
168
|
+
return parent?.children;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Returns the route's parent
|
|
172
|
+
* @param {Object} route Route Object
|
|
173
|
+
* @param {Object} deepest By default this returns the routes parent, if deepest it will return it's base route (top level parent)
|
|
174
|
+
* @return {Object|Null} Parent route, if there is no parent route for the given route this will return null
|
|
175
|
+
*/
|
|
176
|
+
export function $getParentRoute(route, deepest) {
|
|
177
|
+
const length = route.matched.length;
|
|
178
|
+
const parentIndex = length - 2;
|
|
179
|
+
if (deepest) {
|
|
180
|
+
return length > 1 ? route.matched[0] : null;
|
|
181
|
+
} else {
|
|
182
|
+
return parentIndex < 0 ? null : route.matched[parentIndex];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function includeIndex(include) {
|
|
187
|
+
return r => include || r.path !== "";
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function sortByWeight(a, b) {
|
|
191
|
+
return a?.weight - b?.weight;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* For a given $route will return all it's children as menu items,
|
|
196
|
+
* using the route's meta.title property for the title. This is for sections only (routes with children)
|
|
197
|
+
* - Useful for dynamic menus (menus within some unknown section) where you don't want to write static paths
|
|
198
|
+
* @param {Object} route Actual $route object
|
|
199
|
+
* @param {Object} options Options
|
|
200
|
+
* @param {Object} options.parent Route parent object, defaults to parent of route
|
|
201
|
+
* @param {Boolean} options.includeIndex Include the parent/index in the menu items ie ({ path: "" })
|
|
202
|
+
* @param {Object} options.item Options for createMenuItem
|
|
203
|
+
* @returns {Array.<RouteMenuItem>} Array of menu items
|
|
204
|
+
*/
|
|
205
|
+
export function $createSectionMenu(route, options) {
|
|
206
|
+
const defaults = {
|
|
207
|
+
parent: null,
|
|
208
|
+
includeIndex: false,
|
|
209
|
+
item: {},
|
|
210
|
+
sort: sortByWeight
|
|
211
|
+
};
|
|
212
|
+
const opts = Object.assign({}, defaults, options);
|
|
213
|
+
const parent = opts.parent || $getParentRoute(route);
|
|
214
|
+
const children = ($getRouteChildren(route, parent) || []);
|
|
215
|
+
return children
|
|
216
|
+
.filter(includeIndex(opts.includeIndex))
|
|
217
|
+
.map(r => createMenuItem(r, `${ parent.path }/${ r.path }`, opts.item))
|
|
218
|
+
.sort(opts.sort);
|
|
219
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ulu/frontend-vue",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"description": "Frontend theming library (Vue)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files" : [
|
|
7
|
+
"lib",
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"module": "./lib/index.js",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./lib/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./dist": {
|
|
16
|
+
"import": "./dist/frontend-vue.js"
|
|
17
|
+
},
|
|
18
|
+
"./*": "./lib/*",
|
|
19
|
+
"./scss": "./lib/_index.scss"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/Jscherbe/frontend-vue.git"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dev": "storybook dev -p 6006",
|
|
27
|
+
"docs:build": "storybook build -o docs --docs",
|
|
28
|
+
"build": "vite build",
|
|
29
|
+
"deploy": "npm run build && npm run docs:build"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [],
|
|
32
|
+
"author": "Joseph Scherben <jscherbe@gmail.com>",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/Jscherbe/frontend-vue/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/Jscherbe/frontend-vue#readme",
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@headlessui/vue": "^1.7.23",
|
|
40
|
+
"@ulu/frontend": "^0.1.0-beta.94",
|
|
41
|
+
"vue": "^3.5.17",
|
|
42
|
+
"vue-router": "^4.5.1"
|
|
43
|
+
},
|
|
44
|
+
"optionalDependencies": {
|
|
45
|
+
"gsap": "^3.13.0",
|
|
46
|
+
"fuse.js": "^6.6.2",
|
|
47
|
+
"vue3-dropzone": "^2.2.1"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@floating-ui/vue": "^1.1.8",
|
|
51
|
+
"@ulu/utils": "^0.0.30"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@fortawesome/fontawesome-svg-core": "^6.7.2",
|
|
55
|
+
"@fortawesome/free-solid-svg-icons": "^6.7.2",
|
|
56
|
+
"@fortawesome/vue-fontawesome": "^3.0.8",
|
|
57
|
+
"@storybook/addon-docs": "^9.1.1",
|
|
58
|
+
"@storybook/addon-links": "^9.1.1",
|
|
59
|
+
"@storybook/addon-essentials": "^9.0.0-alpha.12",
|
|
60
|
+
"@storybook/vue3-vite": "^9.1.1",
|
|
61
|
+
"@ulu/frontend": "^0.1.0-beta.94",
|
|
62
|
+
"@vitejs/plugin-vue": "^6.0.0",
|
|
63
|
+
"ollama": "^0.5.16",
|
|
64
|
+
"react": "^19.1.1",
|
|
65
|
+
"react-dom": "^19.1.1",
|
|
66
|
+
"sass-embedded": "^1.89.2",
|
|
67
|
+
"storybook": "^9.1.1",
|
|
68
|
+
"storybook-addon-vue-mdx": "^2.0.2",
|
|
69
|
+
"vite": "^7.0.0",
|
|
70
|
+
"vue-router": "^4.5.1"
|
|
71
|
+
},
|
|
72
|
+
"volta": {
|
|
73
|
+
"node": "22.17.0"
|
|
74
|
+
}
|
|
75
|
+
}
|