@umbra.ui/core 0.2.0 → 0.4.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/dist/components/controls/InlineDropdown/InlineDropdown.vue +290 -0
- package/dist/components/controls/InlineDropdown/README.md +35 -0
- package/dist/components/controls/InlineDropdown/theme.css +40 -0
- package/dist/components/dialogs/Alert/Alert.vue +122 -11
- package/dist/components/dialogs/Alert/theme.css +20 -0
- package/dist/components/dialogs/Toast/useToast.d.ts +1 -1
- package/dist/components/inputs/AutogrowRichTextView/AutogrowRichTextView.vue +128 -0
- package/dist/components/inputs/AutogrowRichTextView/README.md +86 -0
- package/dist/components/inputs/AutogrowRichTextView/editor.css +211 -0
- package/dist/components/inputs/AutogrowRichTextView/theme.css +28 -0
- package/dist/components/inputs/InputCryptoAddress/InputCryptoAddress.vue +512 -0
- package/dist/components/inputs/InputCryptoAddress/README.md +45 -0
- package/dist/components/inputs/InputCryptoAddress/theme.css +80 -0
- package/dist/components/inputs/Tags/TagBar.vue +7 -4
- package/dist/components/inputs/Tags/theme.css +4 -0
- package/dist/components/inputs/search/README.md +64 -736
- package/dist/components/inputs/search/SearchOverlay.vue +376 -0
- package/dist/components/inputs/search/SearchResultCell.vue +205 -0
- package/dist/components/inputs/search/theme.css +66 -21
- package/dist/components/inputs/search/types.d.ts +27 -5
- package/dist/components/inputs/search/types.d.ts.map +1 -1
- package/dist/components/inputs/search/types.ts +33 -5
- package/dist/components/menus/ActionMenu/ActionMenu.vue +29 -7
- package/dist/components/menus/ActionMenu/theme.css +1 -1
- package/dist/components/menus/ActionMenu/types.d.ts +9 -0
- package/dist/components/menus/ActionMenu/types.d.ts.map +1 -0
- package/dist/components/menus/ActionMenu/types.js +1 -0
- package/dist/components/menus/ActionMenu/types.ts +9 -0
- package/dist/components/models/Popover/Popover.vue +6 -84
- package/dist/css/umbra-ui.css +1 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/package.json +21 -16
- package/src/components/controls/InlineDropdown/InlineDropdown.vue +290 -0
- package/src/components/controls/InlineDropdown/README.md +35 -0
- package/src/components/controls/InlineDropdown/theme.css +40 -0
- package/src/components/dialogs/Alert/Alert.vue +122 -11
- package/src/components/dialogs/Alert/theme.css +20 -0
- package/src/components/inputs/AutogrowRichTextView/AutogrowRichTextView.vue +128 -0
- package/src/components/inputs/AutogrowRichTextView/README.md +86 -0
- package/src/components/inputs/AutogrowRichTextView/editor.css +211 -0
- package/src/components/inputs/AutogrowRichTextView/theme.css +28 -0
- package/src/components/inputs/InputCryptoAddress/InputCryptoAddress.vue +512 -0
- package/src/components/inputs/InputCryptoAddress/README.md +45 -0
- package/src/components/inputs/InputCryptoAddress/theme.css +80 -0
- package/src/components/inputs/Tags/TagBar.vue +7 -4
- package/src/components/inputs/Tags/theme.css +4 -0
- package/src/components/inputs/search/README.md +64 -736
- package/src/components/inputs/search/SearchOverlay.vue +376 -0
- package/src/components/inputs/search/SearchResultCell.vue +205 -0
- package/src/components/inputs/search/theme.css +66 -21
- package/src/components/inputs/search/types.ts +33 -5
- package/src/components/menus/ActionMenu/ActionMenu.vue +29 -7
- package/src/components/menus/ActionMenu/theme.css +1 -1
- package/src/components/menus/ActionMenu/types.ts +9 -0
- package/src/components/models/Popover/Popover.vue +6 -84
- package/src/index.ts +13 -3
- package/src/vue.d.ts +7 -26
- package/src/components/inputs/search/SearchBar.vue +0 -394
- package/src/components/inputs/search/SearchResults.vue +0 -310
|
@@ -1,8 +1,36 @@
|
|
|
1
|
-
export interface
|
|
1
|
+
export interface SearchPathSegment {
|
|
2
2
|
id: string;
|
|
3
|
-
|
|
3
|
+
type: string;
|
|
4
|
+
title: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface SearchOverlayResult {
|
|
8
|
+
id: string;
|
|
9
|
+
path: string;
|
|
10
|
+
pathSegments: SearchPathSegment[];
|
|
4
11
|
title: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
12
|
+
excerpt: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SearchResult extends SearchOverlayResult {
|
|
16
|
+
icon?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
caption?: string;
|
|
19
|
+
footnote?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface SearchQueryOptions {
|
|
23
|
+
limit: number;
|
|
24
|
+
offset: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SearchProvider<
|
|
28
|
+
T extends SearchOverlayResult = SearchOverlayResult
|
|
29
|
+
> {
|
|
30
|
+
search: (
|
|
31
|
+
query: string,
|
|
32
|
+
options: SearchQueryOptions
|
|
33
|
+
) => Promise<{ results: T[]; total: number }>;
|
|
34
|
+
getRecent: () => Promise<T[]>;
|
|
35
|
+
select: (item: T) => Promise<void> | void;
|
|
8
36
|
}
|
|
@@ -9,20 +9,15 @@ import {
|
|
|
9
9
|
autoUpdate,
|
|
10
10
|
} from "@floating-ui/vue";
|
|
11
11
|
import { icons, type IconKey } from "@umbra.ui/icons";
|
|
12
|
+
import type { ActionMenuItem } from "./types";
|
|
12
13
|
import "./theme.css";
|
|
13
14
|
|
|
14
|
-
export interface ActionMenuItem {
|
|
15
|
-
icon?: IconKey;
|
|
16
|
-
title: string;
|
|
17
|
-
action: () => void;
|
|
18
|
-
isDestructive?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
15
|
// Props
|
|
22
16
|
export interface Props {
|
|
23
17
|
items: ActionMenuItem[];
|
|
24
18
|
modelValue?: boolean;
|
|
25
19
|
contextMenu?: boolean;
|
|
20
|
+
title?: string;
|
|
26
21
|
}
|
|
27
22
|
|
|
28
23
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -237,6 +232,9 @@ defineExpose({
|
|
|
237
232
|
@click="handleOverlayClick"
|
|
238
233
|
></div>
|
|
239
234
|
<div v-if="showPopover" :class="$style.popup" ref="popup">
|
|
235
|
+
<div v-if="title" :class="$style.header">
|
|
236
|
+
<p :class="[$style.header_text, 'subheadline']">{{ title }}</p>
|
|
237
|
+
</div>
|
|
240
238
|
<div
|
|
241
239
|
v-for="item in items"
|
|
242
240
|
:key="`action-item-${item.title}`"
|
|
@@ -259,6 +257,9 @@ defineExpose({
|
|
|
259
257
|
>
|
|
260
258
|
{{ item.title }}
|
|
261
259
|
</p>
|
|
260
|
+
<span v-if="item.shortcutLabel" :class="$style.shortcut">
|
|
261
|
+
{{ item.shortcutLabel }}
|
|
262
|
+
</span>
|
|
262
263
|
</div>
|
|
263
264
|
</div>
|
|
264
265
|
</Teleport>
|
|
@@ -303,6 +304,18 @@ defineExpose({
|
|
|
303
304
|
border: var(--actionmenu-popup-border);
|
|
304
305
|
}
|
|
305
306
|
|
|
307
|
+
.header {
|
|
308
|
+
padding: 0.471rem 0.588rem;
|
|
309
|
+
border-bottom: 1px solid var(--actionmenu-item-border);
|
|
310
|
+
background-color: var(--actionmenu-popup-bg);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.header_text {
|
|
314
|
+
margin: 0;
|
|
315
|
+
color: var(--actionmenu-item-text);
|
|
316
|
+
opacity: 0.7;
|
|
317
|
+
}
|
|
318
|
+
|
|
306
319
|
@keyframes popupFadeIn {
|
|
307
320
|
from {
|
|
308
321
|
opacity: 0;
|
|
@@ -338,6 +351,15 @@ defineExpose({
|
|
|
338
351
|
border-bottom: 0;
|
|
339
352
|
}
|
|
340
353
|
|
|
354
|
+
.shortcut {
|
|
355
|
+
margin-left: auto;
|
|
356
|
+
font-size: 0.75rem;
|
|
357
|
+
letter-spacing: 0.04em;
|
|
358
|
+
opacity: 0.6;
|
|
359
|
+
color: var(--actionmenu-item-text);
|
|
360
|
+
font-variant-numeric: tabular-nums;
|
|
361
|
+
}
|
|
362
|
+
|
|
341
363
|
.item_icon {
|
|
342
364
|
width: 1.25rem;
|
|
343
365
|
height: 1.25rem;
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
--actionmenu-item-icon: #eeeeee; /* Original dark mode value */
|
|
80
80
|
|
|
81
81
|
/* ActionMenu destructive colors */
|
|
82
|
-
--actionmenu-destructive-text: #
|
|
82
|
+
--actionmenu-destructive-text: #ec5d5e; /* Original dark mode value */
|
|
83
83
|
--actionmenu-destructive-icon: #e5484d; /* Original dark mode value */
|
|
84
84
|
|
|
85
85
|
/* ActionMenu overlay colors */
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
type Middleware,
|
|
21
21
|
} from "@floating-ui/vue";
|
|
22
22
|
import gsap from "gsap";
|
|
23
|
-
import "./theme.css";
|
|
24
23
|
|
|
25
24
|
export interface PopoverProps {
|
|
26
25
|
/**
|
|
@@ -106,6 +105,10 @@ export interface PopoverProps {
|
|
|
106
105
|
* Background color of the popover
|
|
107
106
|
*/
|
|
108
107
|
popoverBackground?: string;
|
|
108
|
+
/**
|
|
109
|
+
* Popover corner radius
|
|
110
|
+
*/
|
|
111
|
+
popoverCornerRadius?: string;
|
|
109
112
|
}
|
|
110
113
|
|
|
111
114
|
const props = withDefaults(defineProps<PopoverProps>(), {
|
|
@@ -125,6 +128,7 @@ const props = withDefaults(defineProps<PopoverProps>(), {
|
|
|
125
128
|
hoverShowDelay: 0,
|
|
126
129
|
hoverHideDelay: 0,
|
|
127
130
|
popoverBackground: "var(--popover-bg)",
|
|
131
|
+
popoverCornerRadius: "0.353rem",
|
|
128
132
|
});
|
|
129
133
|
|
|
130
134
|
const emit = defineEmits<{
|
|
@@ -153,6 +157,7 @@ const popoverStyles = computed(() => ({
|
|
|
153
157
|
maxHeight: props.maxHeight,
|
|
154
158
|
zIndex: props.zIndex + 1,
|
|
155
159
|
backgroundColor: props.popoverBackground,
|
|
160
|
+
borderRadius: props.popoverCornerRadius,
|
|
156
161
|
}));
|
|
157
162
|
|
|
158
163
|
const overlayStyles = computed(() => ({
|
|
@@ -214,81 +219,6 @@ const updatePosition = async () => {
|
|
|
214
219
|
}
|
|
215
220
|
};
|
|
216
221
|
|
|
217
|
-
const enableSmoothResize = () => {
|
|
218
|
-
if (!popoverRef.value) return;
|
|
219
|
-
|
|
220
|
-
let lastHeight = popoverRef.value.offsetHeight;
|
|
221
|
-
let isFirstRun = true;
|
|
222
|
-
|
|
223
|
-
const resizeObserver = new ResizeObserver((entries) => {
|
|
224
|
-
// Skip the initial observation
|
|
225
|
-
if (isFirstRun) {
|
|
226
|
-
isFirstRun = false;
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
for (const entry of entries) {
|
|
231
|
-
if (!popoverRef.value) continue;
|
|
232
|
-
|
|
233
|
-
// Get the content wrapper's height
|
|
234
|
-
const contentWrapper = popoverRef.value.lastElementChild as HTMLElement;
|
|
235
|
-
if (!contentWrapper) continue;
|
|
236
|
-
|
|
237
|
-
const newContentHeight = contentWrapper.offsetHeight;
|
|
238
|
-
|
|
239
|
-
// Calculate total height including padding/borders
|
|
240
|
-
const computedStyle = window.getComputedStyle(popoverRef.value);
|
|
241
|
-
const paddingTop = parseFloat(computedStyle.paddingTop) || 0;
|
|
242
|
-
const paddingBottom = parseFloat(computedStyle.paddingBottom) || 0;
|
|
243
|
-
const borderTop = parseFloat(computedStyle.borderTopWidth) || 0;
|
|
244
|
-
const borderBottom = parseFloat(computedStyle.borderBottomWidth) || 0;
|
|
245
|
-
|
|
246
|
-
const newHeight =
|
|
247
|
-
newContentHeight +
|
|
248
|
-
paddingTop +
|
|
249
|
-
paddingBottom +
|
|
250
|
-
borderTop +
|
|
251
|
-
borderBottom;
|
|
252
|
-
|
|
253
|
-
// Only animate if height actually changed significantly
|
|
254
|
-
if (Math.abs(lastHeight - newHeight) > 1) {
|
|
255
|
-
// Kill any existing animations on this element
|
|
256
|
-
gsap.killTweensOf(popoverRef.value);
|
|
257
|
-
|
|
258
|
-
// Animate height change
|
|
259
|
-
gsap.fromTo(
|
|
260
|
-
popoverRef.value,
|
|
261
|
-
{
|
|
262
|
-
height: lastHeight,
|
|
263
|
-
},
|
|
264
|
-
{
|
|
265
|
-
height: newHeight,
|
|
266
|
-
duration: 0.3,
|
|
267
|
-
ease: "power2.inOut",
|
|
268
|
-
onComplete: () => {
|
|
269
|
-
lastHeight = newHeight;
|
|
270
|
-
updatePosition();
|
|
271
|
-
},
|
|
272
|
-
}
|
|
273
|
-
);
|
|
274
|
-
|
|
275
|
-
break; // Only process one change at a time
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
// Find the popoverContent div
|
|
281
|
-
const contentWrapper = popoverRef.value.lastElementChild as HTMLElement;
|
|
282
|
-
if (contentWrapper) {
|
|
283
|
-
// Only observe direct children, not the wrapper itself
|
|
284
|
-
Array.from(contentWrapper.children).forEach((child) => {
|
|
285
|
-
resizeObserver.observe(child as HTMLElement);
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return resizeObserver;
|
|
290
|
-
};
|
|
291
|
-
|
|
292
222
|
// Animation functions
|
|
293
223
|
const open = async () => {
|
|
294
224
|
if (isAnimating.value || isVisible.value) return;
|
|
@@ -381,13 +311,6 @@ const open = async () => {
|
|
|
381
311
|
onComplete: () => {
|
|
382
312
|
isAnimating.value = false;
|
|
383
313
|
emit("after-enter");
|
|
384
|
-
|
|
385
|
-
// Set up smooth resizing AFTER animation completes
|
|
386
|
-
if (popoverRef.value) {
|
|
387
|
-
const resizeObserver = enableSmoothResize();
|
|
388
|
-
// Store it for cleanup
|
|
389
|
-
(popoverRef.value as any)._resizeObserver = resizeObserver;
|
|
390
|
-
}
|
|
391
314
|
},
|
|
392
315
|
});
|
|
393
316
|
|
|
@@ -652,7 +575,6 @@ defineExpose({
|
|
|
652
575
|
position: absolute;
|
|
653
576
|
top: 0;
|
|
654
577
|
left: 0;
|
|
655
|
-
border-radius: 0.353rem;
|
|
656
578
|
box-shadow: 0px 1px 0px 0px var(--popover-shadow),
|
|
657
579
|
inset 0px 1px 0px 0px var(--popover-inset-shadow);
|
|
658
580
|
border: var(--popover-border);
|
package/src/index.ts
CHANGED
|
@@ -34,11 +34,13 @@ export { default as SegmentedControl } from "./components/controls/SegmentedCont
|
|
|
34
34
|
export { type ControlItem } from "./components/controls/SegmentedControl/types";
|
|
35
35
|
export { default as Dropdown } from "./components/controls/Dropdown/Dropdown.vue";
|
|
36
36
|
export { type DropdownItem } from "./components/controls/Dropdown/types";
|
|
37
|
+
export { default as InlineDropdown } from "./components/controls/InlineDropdown/InlineDropdown.vue";
|
|
37
38
|
export { default as Radio } from "./components/controls/Radio/Radio.vue";
|
|
38
39
|
export { default as Slider } from "./components/controls/Slider/Slider.vue";
|
|
39
40
|
export { default as RangeSlider } from "./components/controls/RangeSlider/RangeSlider.vue";
|
|
40
41
|
export { default as Stepper } from "./components/controls/Stepper/Stepper.vue";
|
|
41
42
|
export { default as InputText } from "./components/inputs/InputText/InputText.vue";
|
|
43
|
+
export { default as InputCryptoAddress } from "./components/inputs/InputCryptoAddress/InputCryptoAddress.vue";
|
|
42
44
|
export { default as InputSecure } from "./components/inputs/InputSecure/InputSecure.vue";
|
|
43
45
|
export { default as InputPhone } from "./components/inputs/InputPhone/InputPhone.vue";
|
|
44
46
|
export { default as InputNumber } from "./components/inputs/InputNumber/InputNumber.vue";
|
|
@@ -77,8 +79,10 @@ export {
|
|
|
77
79
|
} from "./components/inputs/Tags/types";
|
|
78
80
|
export { type TagBarStyle } from "./components/inputs/Tags/tag-bar-styles";
|
|
79
81
|
export { default as AutogrowTextView } from "./components/inputs/AutogrowTextView/AutogrowTextView.vue";
|
|
82
|
+
export { default as AutogrowRichTextView } from "./components/inputs/AutogrowRichTextView/AutogrowRichTextView.vue";
|
|
80
83
|
export { default as StringCapture } from "./components/inputs/StringCapture/StringCapture.vue";
|
|
81
84
|
export { default as ActionMenu } from "./components/menus/ActionMenu/ActionMenu.vue";
|
|
85
|
+
export { type ActionMenuItem } from "./components/menus/ActionMenu/types";
|
|
82
86
|
export { default as Tooltip } from "./components/indicators/Tooltip/TooltipProvider.vue";
|
|
83
87
|
export { useTooltip } from "./components/indicators/Tooltip/useTooltip";
|
|
84
88
|
export { vTooltip } from "./components/indicators/Tooltip/tooltip";
|
|
@@ -96,9 +100,15 @@ export {
|
|
|
96
100
|
type ToastInstance,
|
|
97
101
|
} from "./components/dialogs/Toast/types";
|
|
98
102
|
export { default as OTP } from "./components/inputs/OTP/OTP.vue";
|
|
99
|
-
export { default as
|
|
100
|
-
export { default as
|
|
101
|
-
export {
|
|
103
|
+
export { default as SearchOverlay } from "./components/inputs/search/SearchOverlay.vue";
|
|
104
|
+
export { default as SearchResultCell } from "./components/inputs/search/SearchResultCell.vue";
|
|
105
|
+
export {
|
|
106
|
+
type SearchOverlayResult,
|
|
107
|
+
type SearchPathSegment,
|
|
108
|
+
type SearchProvider,
|
|
109
|
+
type SearchQueryOptions,
|
|
110
|
+
type SearchResult,
|
|
111
|
+
} from "./components/inputs/search/types";
|
|
102
112
|
export { default as Sheet } from "./components/models/Sheet/Sheet.vue";
|
|
103
113
|
export { default as Sidebar } from "./components/models/Sidebar/Sidebar.vue";
|
|
104
114
|
export { default as Popover } from "./components/models/Popover/Popover.vue";
|
package/src/vue.d.ts
CHANGED
|
@@ -4,32 +4,6 @@ declare module "*.vue" {
|
|
|
4
4
|
export default component;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
declare module "./components/inputs/search/SearchResults.vue" {
|
|
8
|
-
import type { DefineComponent } from "vue";
|
|
9
|
-
import type { BaseSearchResult } from "./components/inputs/search/types";
|
|
10
|
-
|
|
11
|
-
interface SearchResultsSlots<T extends BaseSearchResult> {
|
|
12
|
-
result: (props: {
|
|
13
|
-
item: T;
|
|
14
|
-
index: number;
|
|
15
|
-
highlight: (text: string) => string;
|
|
16
|
-
}) => any;
|
|
17
|
-
empty: () => any;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const component: DefineComponent<
|
|
21
|
-
{},
|
|
22
|
-
{},
|
|
23
|
-
any,
|
|
24
|
-
{},
|
|
25
|
-
{},
|
|
26
|
-
{},
|
|
27
|
-
{},
|
|
28
|
-
SearchResultsSlots<any>
|
|
29
|
-
>;
|
|
30
|
-
export default component;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
7
|
declare module "autosize" {
|
|
34
8
|
function autosize(element: HTMLTextAreaElement): void;
|
|
35
9
|
namespace autosize {
|
|
@@ -43,3 +17,10 @@ declare module "*.md?raw" {
|
|
|
43
17
|
const content: string;
|
|
44
18
|
export default content;
|
|
45
19
|
}
|
|
20
|
+
|
|
21
|
+
declare module "@umbra.ui/core" {
|
|
22
|
+
import type { DefineComponent } from "vue";
|
|
23
|
+
|
|
24
|
+
export const InlineDropdown: DefineComponent<{}, {}, any>;
|
|
25
|
+
export const InputCryptoAddress: DefineComponent<{}, {}, any>;
|
|
26
|
+
}
|