orio-ui 0.1.0
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 +237 -0
- package/dist/module.cjs +5 -0
- package/dist/module.d.mts +3 -0
- package/dist/module.d.ts +3 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +16 -0
- package/dist/runtime/assets/css/animation.css +1 -0
- package/dist/runtime/assets/css/colors.css +1 -0
- package/dist/runtime/assets/css/cool-gradient-hover.css +23 -0
- package/dist/runtime/assets/css/main.css +1 -0
- package/dist/runtime/assets/css/scroll.css +1 -0
- package/dist/runtime/components/Button.vue +102 -0
- package/dist/runtime/components/CheckBox.vue +93 -0
- package/dist/runtime/components/ControlElement.vue +39 -0
- package/dist/runtime/components/DashedContainer.vue +59 -0
- package/dist/runtime/components/DatePicker.vue +30 -0
- package/dist/runtime/components/DateRangePicker.vue +73 -0
- package/dist/runtime/components/EmptyState.vue +81 -0
- package/dist/runtime/components/Icon.vue +40 -0
- package/dist/runtime/components/Input.vue +48 -0
- package/dist/runtime/components/LoadingSpinner.vue +6 -0
- package/dist/runtime/components/Modal.vue +69 -0
- package/dist/runtime/components/Popover.vue +249 -0
- package/dist/runtime/components/Selector.vue +208 -0
- package/dist/runtime/components/Tag.vue +21 -0
- package/dist/runtime/components/Textarea.vue +53 -0
- package/dist/runtime/components/view/Dates.vue +59 -0
- package/dist/runtime/components/view/Separator.vue +26 -0
- package/dist/runtime/components/view/Text.vue +79 -0
- package/dist/runtime/composables/index.d.ts +4 -0
- package/dist/runtime/composables/index.js +4 -0
- package/dist/runtime/composables/useApi.d.ts +10 -0
- package/dist/runtime/composables/useApi.js +9 -0
- package/dist/runtime/composables/useFuzzySearch.d.ts +10 -0
- package/dist/runtime/composables/useFuzzySearch.js +22 -0
- package/dist/runtime/composables/useModal.d.ts +15 -0
- package/dist/runtime/composables/useModal.js +28 -0
- package/dist/runtime/composables/useTheme.d.ts +6 -0
- package/dist/runtime/composables/useTheme.js +23 -0
- package/dist/runtime/index.d.ts +20 -0
- package/dist/runtime/index.js +20 -0
- package/dist/runtime/utils/icon-registry.d.ts +2 -0
- package/dist/runtime/utils/icon-registry.js +26 -0
- package/dist/types.d.mts +7 -0
- package/dist/types.d.ts +7 -0
- package/nuxt.config.ts +38 -0
- package/package.json +99 -0
- package/src/module.ts +16 -0
- package/src/runtime/assets/css/animation.css +88 -0
- package/src/runtime/assets/css/colors.css +142 -0
- package/src/runtime/assets/css/cool-gradient-hover.scss +33 -0
- package/src/runtime/assets/css/main.css +11 -0
- package/src/runtime/assets/css/scroll.css +46 -0
- package/src/runtime/components/Button.vue +110 -0
- package/src/runtime/components/CheckBox.vue +103 -0
- package/src/runtime/components/ControlElement.vue +42 -0
- package/src/runtime/components/DashedContainer.vue +60 -0
- package/src/runtime/components/DatePicker.vue +84 -0
- package/src/runtime/components/DateRangePicker.vue +74 -0
- package/src/runtime/components/EmptyState.vue +87 -0
- package/src/runtime/components/Icon.vue +51 -0
- package/src/runtime/components/Input.vue +54 -0
- package/src/runtime/components/LoadingSpinner.vue +6 -0
- package/src/runtime/components/Modal.vue +111 -0
- package/src/runtime/components/Popover.vue +249 -0
- package/src/runtime/components/Selector.vue +224 -0
- package/src/runtime/components/Tag.vue +45 -0
- package/src/runtime/components/Textarea.vue +59 -0
- package/src/runtime/components/view/Dates.vue +61 -0
- package/src/runtime/components/view/Separator.vue +30 -0
- package/src/runtime/components/view/Text.vue +83 -0
- package/src/runtime/composables/index.ts +4 -0
- package/src/runtime/composables/useApi.ts +26 -0
- package/src/runtime/composables/useFuzzySearch.ts +51 -0
- package/src/runtime/composables/useModal.ts +47 -0
- package/src/runtime/composables/useTheme.ts +31 -0
- package/src/runtime/index.ts +25 -0
- package/src/runtime/utils/icon-registry.ts +41 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, useAttrs } from 'vue';
|
|
3
|
+
|
|
4
|
+
export type TextTypes = 'text' | 'title' | 'subtitle' | 'italics';
|
|
5
|
+
|
|
6
|
+
export interface TextProps {
|
|
7
|
+
type?: TextTypes;
|
|
8
|
+
size?: 'small' | 'medium' | 'large' | 'extra-large';
|
|
9
|
+
uppercase?: boolean;
|
|
10
|
+
icon?: string | null;
|
|
11
|
+
lineClamp?: number | string;
|
|
12
|
+
}
|
|
13
|
+
const props = withDefaults(defineProps<TextProps>(), {
|
|
14
|
+
type: 'text',
|
|
15
|
+
size: 'medium',
|
|
16
|
+
uppercase: false,
|
|
17
|
+
icon: null,
|
|
18
|
+
lineClamp: undefined,
|
|
19
|
+
});
|
|
20
|
+
const attrs = useAttrs();
|
|
21
|
+
const modelValue = defineModel<string>();
|
|
22
|
+
|
|
23
|
+
const clampLines = computed(() => Number(props.lineClamp ?? 1));
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<div :class="[type, size, { uppercase, clamp: !!lineClamp }]" v-bind="attrs">
|
|
28
|
+
<orio-icon v-if="icon" :name="icon" />
|
|
29
|
+
<slot>
|
|
30
|
+
{{ modelValue }}
|
|
31
|
+
</slot>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<style lang="scss" scoped>
|
|
36
|
+
div {
|
|
37
|
+
white-space: pre-wrap;
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
gap: 0.25rem;
|
|
41
|
+
|
|
42
|
+
&.clamp {
|
|
43
|
+
display: -webkit-box;
|
|
44
|
+
overflow: hidden;
|
|
45
|
+
line-clamp: v-bind(clampLines);
|
|
46
|
+
-webkit-line-clamp: v-bind(clampLines);
|
|
47
|
+
-webkit-box-orient: vertical;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&.uppercase {
|
|
51
|
+
text-transform: uppercase;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.text {
|
|
55
|
+
color: var(--color-text);
|
|
56
|
+
}
|
|
57
|
+
&.title {
|
|
58
|
+
font-weight: bold;
|
|
59
|
+
color: var(--color-text);
|
|
60
|
+
}
|
|
61
|
+
&.subtitle {
|
|
62
|
+
font-weight: semi-bold;
|
|
63
|
+
color: var(--color-muted);
|
|
64
|
+
}
|
|
65
|
+
&.italics {
|
|
66
|
+
font-style: italic;
|
|
67
|
+
color: var(--color-muted);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&.small {
|
|
71
|
+
font-size: 0.75rem;
|
|
72
|
+
}
|
|
73
|
+
&.medium {
|
|
74
|
+
font-size: 0.875rem;
|
|
75
|
+
}
|
|
76
|
+
&.large {
|
|
77
|
+
font-size: 1.25rem;
|
|
78
|
+
}
|
|
79
|
+
&.extra-large {
|
|
80
|
+
font-size: 1.75rem;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { $fetch } from 'ofetch';
|
|
2
|
+
|
|
3
|
+
export type RequestBody = Record<string, unknown>;
|
|
4
|
+
export type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
5
|
+
|
|
6
|
+
export interface ApiOptions {
|
|
7
|
+
method?: RequestMethod;
|
|
8
|
+
body?: RequestBody;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
query?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Overload 1: Just URL (GET request)
|
|
14
|
+
export async function useApi<T = unknown>(url: string): Promise<T>;
|
|
15
|
+
|
|
16
|
+
// Overload 2: URL + options
|
|
17
|
+
export async function useApi<T = unknown>(url: string, options: ApiOptions): Promise<T>;
|
|
18
|
+
|
|
19
|
+
export async function useApi<T = unknown>(url: string, options?: ApiOptions): Promise<T> {
|
|
20
|
+
return (await $fetch(url, {
|
|
21
|
+
method: options?.method || 'GET',
|
|
22
|
+
body: options?.body,
|
|
23
|
+
signal: options?.signal,
|
|
24
|
+
query: options?.query,
|
|
25
|
+
})) as T;
|
|
26
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { computed, unref, type MaybeRef } from 'vue';
|
|
2
|
+
import { useFuse, type FuseOptions } from '@vueuse/integrations/useFuse';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Search using Fuse.js fuzzy search
|
|
6
|
+
* @param dataSource - Array of strings or objects to search
|
|
7
|
+
* @param search - Search query string
|
|
8
|
+
* @param options - Fuse.js options (e.g., { keys: ['name'] })
|
|
9
|
+
*/
|
|
10
|
+
export function useFuzzySearch(
|
|
11
|
+
dataSource: MaybeRef<string[]>,
|
|
12
|
+
search: MaybeRef<string>
|
|
13
|
+
): ReturnType<typeof useFuse>;
|
|
14
|
+
|
|
15
|
+
export function useFuzzySearch<T extends object>(
|
|
16
|
+
dataSource: MaybeRef<T[]>,
|
|
17
|
+
search: MaybeRef<string>,
|
|
18
|
+
options: FuseOptions<T>
|
|
19
|
+
): ReturnType<typeof useFuse>;
|
|
20
|
+
|
|
21
|
+
export function useFuzzySearch<T extends object>(
|
|
22
|
+
dataSource: MaybeRef<string[] | T[]>,
|
|
23
|
+
search: MaybeRef<string>,
|
|
24
|
+
options?: FuseOptions<T>
|
|
25
|
+
) {
|
|
26
|
+
// If options are provided, treat as object array; otherwise string array
|
|
27
|
+
const isObjectArray = !!options;
|
|
28
|
+
|
|
29
|
+
if (!isObjectArray) {
|
|
30
|
+
// String array handling
|
|
31
|
+
const wrappedData = computed(() => {
|
|
32
|
+
const data = unref(dataSource) as string[];
|
|
33
|
+
return data.map((str) => ({ value: str }));
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const { results } = useFuse(search, wrappedData, {
|
|
37
|
+
fuseOptions: { keys: ['value'] },
|
|
38
|
+
matchAllWhenSearchEmpty: true,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return computed(() => results.value.map(({ item }) => item.value));
|
|
42
|
+
} else {
|
|
43
|
+
// Object array handling
|
|
44
|
+
const { results } = useFuse(search, dataSource as MaybeRef<T[]>, {
|
|
45
|
+
fuseOptions: options,
|
|
46
|
+
matchAllWhenSearchEmpty: true,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return computed(() => results.value.map(({ item }) => item));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ref } from 'vue';
|
|
2
|
+
|
|
3
|
+
export interface OriginRect {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ModalProps {
|
|
11
|
+
show: Boolean;
|
|
12
|
+
origin: OriginRect | null;
|
|
13
|
+
'onUpdate:show': (state: boolean) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function useModal() {
|
|
17
|
+
const modalProps = ref<ModalProps>({
|
|
18
|
+
show: false,
|
|
19
|
+
origin: null,
|
|
20
|
+
'onUpdate:show': (state: Boolean) => updateShow(state),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
function updateShow(state: Boolean) {
|
|
24
|
+
modalProps.value.show = state;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function openModal(event?: MouseEvent) {
|
|
28
|
+
modalProps.value.origin = null;
|
|
29
|
+
if (!event) {
|
|
30
|
+
modalProps.value.show = true;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const target = event.target as HTMLElement;
|
|
34
|
+
const rect = target.getBoundingClientRect();
|
|
35
|
+
|
|
36
|
+
modalProps.value.origin = {
|
|
37
|
+
x: rect.left,
|
|
38
|
+
y: rect.top,
|
|
39
|
+
width: rect.width,
|
|
40
|
+
height: rect.height,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
modalProps.value.show = true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return { modalProps, openModal };
|
|
47
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { onMounted } from 'vue';
|
|
2
|
+
import { useLocalStorage } from '@vueuse/core';
|
|
3
|
+
|
|
4
|
+
export function useTheme() {
|
|
5
|
+
// Namespace storage keys to avoid conflicts with consumer apps
|
|
6
|
+
const theme = useLocalStorage<string>('orio-theme', 'navy');
|
|
7
|
+
const mode = useLocalStorage<string>('orio-mode', 'dark');
|
|
8
|
+
|
|
9
|
+
function setTheme(name: string) {
|
|
10
|
+
theme.value = name;
|
|
11
|
+
// Only set DOM attributes on client side
|
|
12
|
+
if (typeof document !== 'undefined') {
|
|
13
|
+
document.documentElement.setAttribute('data-theme', name);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function setMode(name: string) {
|
|
18
|
+
mode.value = name;
|
|
19
|
+
// Only set DOM attributes on client side
|
|
20
|
+
if (typeof document !== 'undefined') {
|
|
21
|
+
document.documentElement.setAttribute('data-mode', name);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
onMounted(() => {
|
|
26
|
+
setTheme(theme.value);
|
|
27
|
+
setMode(mode.value);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return { theme, setTheme, mode, setMode };
|
|
31
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Export all components
|
|
2
|
+
export { default as Button } from './components/Button.vue'
|
|
3
|
+
export { default as Input } from './components/Input.vue'
|
|
4
|
+
export { default as Textarea } from './components/Textarea.vue'
|
|
5
|
+
export { default as CheckBox } from './components/CheckBox.vue'
|
|
6
|
+
export { default as DatePicker } from './components/DatePicker.vue'
|
|
7
|
+
export { default as DateRangePicker } from './components/DateRangePicker.vue'
|
|
8
|
+
export { default as Selector } from './components/Selector.vue'
|
|
9
|
+
export { default as Tag } from './components/Tag.vue'
|
|
10
|
+
export { default as Icon } from './components/Icon.vue'
|
|
11
|
+
export { default as LoadingSpinner } from './components/LoadingSpinner.vue'
|
|
12
|
+
export { default as Modal } from './components/Modal.vue'
|
|
13
|
+
export { default as Popover } from './components/Popover.vue'
|
|
14
|
+
export { default as EmptyState } from './components/EmptyState.vue'
|
|
15
|
+
export { default as DashedContainer } from './components/DashedContainer.vue'
|
|
16
|
+
export { default as ControlElement } from './components/ControlElement.vue'
|
|
17
|
+
export { default as ViewText } from './components/view/Text.vue'
|
|
18
|
+
export { default as ViewDates } from './components/view/Dates.vue'
|
|
19
|
+
export { default as ViewSeparator } from './components/view/Separator.vue'
|
|
20
|
+
|
|
21
|
+
// Export all composables
|
|
22
|
+
export * from './composables'
|
|
23
|
+
|
|
24
|
+
// Export utils
|
|
25
|
+
export { iconRegistry, type IconName } from './utils/icon-registry'
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Icon registry with bundled SVG icons
|
|
2
|
+
|
|
3
|
+
export const iconRegistry: Record<string, string> = {
|
|
4
|
+
// Loading spinner (line-md:loading-loop)
|
|
5
|
+
'loading-loop': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="2" r="0"><animate attributeName="r" begin="0" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/></circle><circle cx="12" cy="2" r="0" transform="rotate(45 12 12)"><animate attributeName="r" begin="0.125s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/></circle><circle cx="12" cy="2" r="0" transform="rotate(90 12 12)"><animate attributeName="r" begin="0.25s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/></circle><circle cx="12" cy="2" r="0" transform="rotate(135 12 12)"><animate attributeName="r" begin="0.375s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/></circle><circle cx="12" cy="2" r="0" transform="rotate(180 12 12)"><animate attributeName="r" begin="0.5s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/></circle><circle cx="12" cy="2" r="0" transform="rotate(225 12 12)"><animate attributeName="r" begin="0.625s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/></circle><circle cx="12" cy="2" r="0" transform="rotate(270 12 12)"><animate attributeName="r" begin="0.75s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/></circle><circle cx="12" cy="2" r="0" transform="rotate(315 12 12)"><animate attributeName="r" begin="0.875s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/></circle></svg>`,
|
|
6
|
+
|
|
7
|
+
// Chevron down (mdi-light:chevron-down)
|
|
8
|
+
'chevron-down': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6l-6-6z"/></svg>`,
|
|
9
|
+
|
|
10
|
+
// Chevron up
|
|
11
|
+
'chevron-up': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6l-6 6z"/></svg>`,
|
|
12
|
+
|
|
13
|
+
// Edit (material-symbols:edit-sharp)
|
|
14
|
+
'edit': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M3 21v-4.25L16.2 3.575q.3-.275.663-.425t.762-.15t.775.15t.65.45L20.425 5q.3.275.438.65T21 6.4q0 .4-.137.763t-.438.662L7.25 21zM17.6 7.8L19 6.4L17.6 5l-1.4 1.4z"/></svg>`,
|
|
15
|
+
|
|
16
|
+
// Check / Checkmark
|
|
17
|
+
'check': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19L21 7l-1.41-1.41z"/></svg>`,
|
|
18
|
+
|
|
19
|
+
// Plus / Add
|
|
20
|
+
'plus': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>`,
|
|
21
|
+
|
|
22
|
+
// Calendar
|
|
23
|
+
'calendar': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19 4h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2m0 16H5V10h14zm0-12H5V6h14zM7 12h5v5H7z"/></svg>`,
|
|
24
|
+
|
|
25
|
+
// Close / X
|
|
26
|
+
'close': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z"/></svg>`,
|
|
27
|
+
|
|
28
|
+
// Search / Magnifying glass
|
|
29
|
+
'search': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5A6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5S14 7.01 14 9.5S11.99 14 9.5 14"/></svg>`,
|
|
30
|
+
|
|
31
|
+
// Upload
|
|
32
|
+
'upload': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M9 16h6v-6h4l-7-7l-7 7h4zm-4 2h14v2H5z"/></svg>`,
|
|
33
|
+
|
|
34
|
+
// Download
|
|
35
|
+
'download': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19 9h-4V3H9v6H5l7 7zM5 18v2h14v-2z"/></svg>`,
|
|
36
|
+
|
|
37
|
+
// Delete / Trash
|
|
38
|
+
'delete': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6zm2.46-7.12l1.41-1.41L12 12.59l2.12-2.12l1.41 1.41L13.41 14l2.12 2.12l-1.41 1.41L12 15.41l-2.12 2.12l-1.41-1.41L10.59 14zM15.5 4l-1-1h-5l-1 1H5v2h14V4z"/></svg>`,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type IconName = keyof typeof iconRegistry
|