@sewadah/selaras 0.8.0 → 0.10.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/README.md +12 -1
- package/dist/agent/catalog.json +1 -1
- package/dist/module.json +1 -1
- package/dist/runtime/components/Autocomplete.vue +6 -0
- package/dist/runtime/components/Checkbox.d.vue.ts +6 -4
- package/dist/runtime/components/Checkbox.vue +30 -22
- package/dist/runtime/components/Checkbox.vue.d.ts +6 -4
- package/dist/runtime/components/DatePicker.d.vue.ts +27 -27
- package/dist/runtime/components/DatePicker.vue +58 -99
- package/dist/runtime/components/DatePicker.vue.d.ts +27 -27
- package/dist/runtime/components/Editable.d.vue.ts +91 -0
- package/dist/runtime/components/Editable.vue +257 -0
- package/dist/runtime/components/Editable.vue.d.ts +91 -0
- package/dist/runtime/components/Input.d.vue.ts +7 -4
- package/dist/runtime/components/Input.vue +41 -25
- package/dist/runtime/components/Input.vue.d.ts +7 -4
- package/dist/runtime/components/Select.vue +6 -0
- package/dist/runtime/components/Textarea.d.vue.ts +7 -4
- package/dist/runtime/components/Textarea.vue +42 -28
- package/dist/runtime/components/Textarea.vue.d.ts +7 -4
- package/dist/runtime/components/Toolbar.d.vue.ts +25 -0
- package/dist/runtime/components/Toolbar.vue +35 -0
- package/dist/runtime/components/Toolbar.vue.d.ts +25 -0
- package/dist/runtime/components/ToolbarButton.d.vue.ts +20 -0
- package/dist/runtime/components/ToolbarButton.vue +46 -0
- package/dist/runtime/components/ToolbarButton.vue.d.ts +20 -0
- package/dist/runtime/components/ToolbarSeparator.d.vue.ts +10 -0
- package/dist/runtime/components/ToolbarSeparator.vue +22 -0
- package/dist/runtime/components/ToolbarSeparator.vue.d.ts +10 -0
- package/dist/runtime/components/ToolbarToggleGroup.d.vue.ts +37 -0
- package/dist/runtime/components/ToolbarToggleGroup.vue +44 -0
- package/dist/runtime/components/ToolbarToggleGroup.vue.d.ts +37 -0
- package/dist/runtime/internal/ComboboxSelectBase.d.vue.ts +7 -63
- package/dist/runtime/internal/ComboboxSelectBase.vue +58 -54
- package/dist/runtime/internal/ComboboxSelectBase.vue.d.ts +7 -63
- package/dist/runtime/internal/FieldClearButton.d.vue.ts +21 -0
- package/dist/runtime/internal/FieldClearButton.vue +30 -0
- package/dist/runtime/internal/FieldClearButton.vue.d.ts +21 -0
- package/dist/runtime/internal/ListboxOption.d.vue.ts +2 -1
- package/dist/runtime/internal/ListboxOption.vue +3 -2
- package/dist/runtime/internal/ListboxOption.vue.d.ts +2 -1
- package/dist/runtime/theme/date-picker.d.ts +27 -0
- package/dist/runtime/theme/date-picker.js +6 -3
- package/dist/runtime/theme/editable.d.ts +155 -0
- package/dist/runtime/theme/editable.js +25 -0
- package/dist/runtime/theme/field-clear-button.d.ts +56 -0
- package/dist/runtime/theme/field-clear-button.js +15 -0
- package/dist/runtime/theme/input.d.ts +6 -9
- package/dist/runtime/theme/input.js +7 -12
- package/dist/runtime/theme/listbox.js +1 -1
- package/dist/runtime/theme/select.d.ts +15 -0
- package/dist/runtime/theme/select.js +13 -10
- package/dist/runtime/theme/textarea.d.ts +6 -9
- package/dist/runtime/theme/textarea.js +6 -4
- package/dist/runtime/theme/toolbar-button.d.ts +65 -0
- package/dist/runtime/theme/toolbar-button.js +21 -0
- package/dist/runtime/theme/toolbar-separator.d.ts +35 -0
- package/dist/runtime/theme/toolbar-separator.js +8 -0
- package/dist/runtime/theme/toolbar-toggle-group.d.ts +74 -0
- package/dist/runtime/theme/toolbar-toggle-group.js +13 -0
- package/dist/runtime/theme/toolbar.d.ts +35 -0
- package/dist/runtime/theme/toolbar.js +11 -0
- package/dist/runtime/theme-config.d.ts +36 -0
- package/dist/runtime/types/index.d.ts +6 -0
- package/dist/runtime/utils/field-adornments.d.ts +14 -0
- package/dist/runtime/utils/field-adornments.js +36 -0
- package/dist/runtime/utils/field-clear.d.ts +9 -0
- package/dist/runtime/utils/field-clear.js +7 -0
- package/dist/runtime/utils/icons.d.ts +1 -0
- package/dist/runtime/utils/icons.js +1 -0
- package/dist/runtime/utils/messages.d.ts +4 -0
- package/dist/runtime/utils/messages.js +4 -0
- package/dist/runtime/utils/select-contracts.d.ts +3 -0
- package/dist/runtime/utils/toolbar.d.ts +9 -0
- package/dist/runtime/utils/toolbar.js +1 -0
- package/package.json +13 -5
- package/skills/selaras/SKILL.md +11 -7
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ToolbarToggleGroup, ToolbarToggleItem } from "reka-ui";
|
|
3
|
+
import { computed, inject } from "vue";
|
|
4
|
+
import { toolbarToggleGroupTheme } from "../theme/toolbar-toggle-group";
|
|
5
|
+
import { TOOLBAR_CONTEXT } from "../utils/toolbar";
|
|
6
|
+
import { resolveSlot, useComponentTheme, useRootProps } from "../utils/ui";
|
|
7
|
+
import Button from "./Button.vue";
|
|
8
|
+
import Icon from "./Icon.vue";
|
|
9
|
+
defineOptions({ inheritAttrs: false });
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
items: { type: Array, required: true },
|
|
12
|
+
type: { type: String, required: false, default: "single" },
|
|
13
|
+
modelValue: { type: [String, Array], required: false },
|
|
14
|
+
defaultValue: { type: [String, Array], required: false },
|
|
15
|
+
disabled: { type: Boolean, required: false },
|
|
16
|
+
iconOnly: { type: Boolean, required: false },
|
|
17
|
+
size: { type: String, required: false },
|
|
18
|
+
color: { type: null, required: false },
|
|
19
|
+
ui: { type: Object, required: false }
|
|
20
|
+
});
|
|
21
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
22
|
+
defineSlots();
|
|
23
|
+
const toolbar = inject(TOOLBAR_CONTEXT, void 0);
|
|
24
|
+
const disabled = computed(() => props.disabled || toolbar?.value.disabled);
|
|
25
|
+
const size = computed(() => props.size ?? toolbar?.value.size ?? "sm");
|
|
26
|
+
const color = computed(() => props.color ?? toolbar?.value.color ?? "primary");
|
|
27
|
+
const items = computed(() => props.items.map((item) => typeof item === "string" ? { value: item, label: item } : item));
|
|
28
|
+
const theme = useComponentTheme("toolbarToggleGroup", toolbarToggleGroupTheme);
|
|
29
|
+
const ui = computed(() => theme.value({ size: size.value, orientation: toolbar?.value.orientation }));
|
|
30
|
+
const rootProps = useRootProps(() => ui.value.root, () => props.ui?.root);
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<ToolbarToggleGroup :type="type" :model-value="modelValue" :default-value="defaultValue" :disabled="disabled" v-bind="rootProps" @update:model-value="emit('update:modelValue', $event)">
|
|
35
|
+
<ToolbarToggleItem v-for="item in items" :key="item.value" as-child :value="item.value" :disabled="disabled || item.disabled">
|
|
36
|
+
<Button :size="size" :color="color" variant="ghost" :disabled="disabled || item.disabled" :square="iconOnly" :aria-label="iconOnly ? item.label : void 0" :title="iconOnly ? item.label : void 0" :ui="{ base: resolveSlot(ui.item, props.ui?.item) }">
|
|
37
|
+
<slot name="item" :item="item">
|
|
38
|
+
<Icon v-if="item.icon" :name="item.icon" v-bind="resolveSlot(ui.icon, props.ui?.icon)" />
|
|
39
|
+
<span v-if="!iconOnly">{{ item.label }}</span>
|
|
40
|
+
</slot>
|
|
41
|
+
</Button>
|
|
42
|
+
</ToolbarToggleItem>
|
|
43
|
+
</ToolbarToggleGroup>
|
|
44
|
+
</template>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ToolbarToggleGroupThemeSlots } from '../theme/toolbar-toggle-group.js';
|
|
2
|
+
import type { ColorRole } from '../utils/color-registry.js';
|
|
3
|
+
import type { UiProp } from '../utils/ui.js';
|
|
4
|
+
import type { ToggleGroupItemDef } from './ToggleGroup.vue.js';
|
|
5
|
+
type __VLS_Slots = ToolbarToggleGroupSlots;
|
|
6
|
+
export interface ToolbarToggleGroupProps {
|
|
7
|
+
items: (string | ToggleGroupItemDef)[];
|
|
8
|
+
type?: 'single' | 'multiple';
|
|
9
|
+
modelValue?: string | string[];
|
|
10
|
+
defaultValue?: string | string[];
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
iconOnly?: boolean;
|
|
13
|
+
size?: 'sm' | 'md' | 'lg';
|
|
14
|
+
color?: ColorRole;
|
|
15
|
+
ui?: UiProp<ToolbarToggleGroupThemeSlots>;
|
|
16
|
+
}
|
|
17
|
+
export interface ToolbarToggleGroupEmits {
|
|
18
|
+
'update:modelValue': [value: string | string[]];
|
|
19
|
+
}
|
|
20
|
+
export interface ToolbarToggleGroupSlots {
|
|
21
|
+
item?: (props: {
|
|
22
|
+
item: ToggleGroupItemDef;
|
|
23
|
+
}) => any;
|
|
24
|
+
}
|
|
25
|
+
declare const __VLS_base: import("vue").DefineComponent<ToolbarToggleGroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
26
|
+
"update:modelValue": (value: string | string[]) => any;
|
|
27
|
+
}, string, import("vue").PublicProps, Readonly<ToolbarToggleGroupProps> & Readonly<{
|
|
28
|
+
"onUpdate:modelValue"?: ((value: string | string[]) => any) | undefined;
|
|
29
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
31
|
+
declare const _default: typeof __VLS_export;
|
|
32
|
+
export default _default;
|
|
33
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
34
|
+
new (): {
|
|
35
|
+
$slots: S;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
@@ -2,12 +2,18 @@ import type { VariantProps } from 'tailwind-variants';
|
|
|
2
2
|
import type { SelectThemeSlots } from '../theme/select.js';
|
|
3
3
|
import type { RoundedArrowConfig } from '../utils/arrow.js';
|
|
4
4
|
import type { ColorRole } from '../utils/color-registry.js';
|
|
5
|
+
import type { FieldAdornmentSlotProps } from '../utils/field-adornments.js';
|
|
5
6
|
import type { OverlayPortal, OverlayPositioning } from '../utils/overlay.js';
|
|
6
7
|
import type { SelectModelValue } from '../utils/select-contracts.js';
|
|
7
8
|
import type { UiProp } from '../utils/ui.js';
|
|
8
|
-
import type { SelectItems
|
|
9
|
+
import type { SelectItems } from './combobox-select.js';
|
|
9
10
|
import { selectTheme } from '../theme/select.js';
|
|
10
11
|
type SelectVariants = VariantProps<typeof selectTheme>;
|
|
12
|
+
type __VLS_Slots = {
|
|
13
|
+
leading?: (props: FieldAdornmentSlotProps) => any;
|
|
14
|
+
trailing?: (props: FieldAdornmentSlotProps) => any;
|
|
15
|
+
[name: string]: ((props: any) => any) | undefined;
|
|
16
|
+
};
|
|
11
17
|
export interface ComboboxSelectBaseProps {
|
|
12
18
|
id?: string;
|
|
13
19
|
name?: string;
|
|
@@ -58,68 +64,6 @@ export interface ComboboxSelectBaseEmits {
|
|
|
58
64
|
'update:modelValue': [value: SelectModelValue | SelectModelValue[] | undefined];
|
|
59
65
|
'update:searchTerm': [value: string];
|
|
60
66
|
}
|
|
61
|
-
declare var __VLS_43: {
|
|
62
|
-
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
63
|
-
}, __VLS_98: {}, __VLS_105: {}, __VLS_120: {}, __VLS_136: {}, __VLS_143: {}, __VLS_150: {}, __VLS_174: {
|
|
64
|
-
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
65
|
-
}, __VLS_194: {
|
|
66
|
-
selected: import("./combobox-select.js").ResolvedOption | undefined;
|
|
67
|
-
}, __VLS_205: {}, __VLS_212: {}, __VLS_219: {}, __VLS_249: {}, __VLS_252: {}, __VLS_255: {}, __VLS_258: {}, __VLS_261: {
|
|
68
|
-
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
69
|
-
}, __VLS_264: {
|
|
70
|
-
group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
|
|
71
|
-
}, __VLS_267: {}, __VLS_305: string, __VLS_306: {}, __VLS_309: {}, __VLS_319: {
|
|
72
|
-
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
73
|
-
}, __VLS_322: {
|
|
74
|
-
group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
|
|
75
|
-
};
|
|
76
|
-
type __VLS_Slots = {} & {
|
|
77
|
-
[K in NonNullable<typeof __VLS_305>]?: (props: typeof __VLS_306) => any;
|
|
78
|
-
} & {
|
|
79
|
-
item?: (props: typeof __VLS_43) => any;
|
|
80
|
-
} & {
|
|
81
|
-
'clear-icon'?: (props: typeof __VLS_98) => any;
|
|
82
|
-
} & {
|
|
83
|
-
'loading-icon'?: (props: typeof __VLS_105) => any;
|
|
84
|
-
} & {
|
|
85
|
-
'dropdown-icon'?: (props: typeof __VLS_120) => any;
|
|
86
|
-
} & {
|
|
87
|
-
'clear-icon'?: (props: typeof __VLS_136) => any;
|
|
88
|
-
} & {
|
|
89
|
-
'loading-icon'?: (props: typeof __VLS_143) => any;
|
|
90
|
-
} & {
|
|
91
|
-
'dropdown-icon'?: (props: typeof __VLS_150) => any;
|
|
92
|
-
} & {
|
|
93
|
-
item?: (props: typeof __VLS_174) => any;
|
|
94
|
-
} & {
|
|
95
|
-
value?: (props: typeof __VLS_194) => any;
|
|
96
|
-
} & {
|
|
97
|
-
'clear-icon'?: (props: typeof __VLS_205) => any;
|
|
98
|
-
} & {
|
|
99
|
-
'loading-icon'?: (props: typeof __VLS_212) => any;
|
|
100
|
-
} & {
|
|
101
|
-
'dropdown-icon'?: (props: typeof __VLS_219) => any;
|
|
102
|
-
} & {
|
|
103
|
-
header?: (props: typeof __VLS_249) => any;
|
|
104
|
-
} & {
|
|
105
|
-
'filter-icon'?: (props: typeof __VLS_252) => any;
|
|
106
|
-
} & {
|
|
107
|
-
empty?: (props: typeof __VLS_255) => any;
|
|
108
|
-
} & {
|
|
109
|
-
'empty-filter'?: (props: typeof __VLS_258) => any;
|
|
110
|
-
} & {
|
|
111
|
-
item?: (props: typeof __VLS_261) => any;
|
|
112
|
-
} & {
|
|
113
|
-
group?: (props: typeof __VLS_264) => any;
|
|
114
|
-
} & {
|
|
115
|
-
footer?: (props: typeof __VLS_267) => any;
|
|
116
|
-
} & {
|
|
117
|
-
header?: (props: typeof __VLS_309) => any;
|
|
118
|
-
} & {
|
|
119
|
-
item?: (props: typeof __VLS_319) => any;
|
|
120
|
-
} & {
|
|
121
|
-
group?: (props: typeof __VLS_322) => any;
|
|
122
|
-
};
|
|
123
67
|
declare const __VLS_base: import("vue").DefineComponent<ComboboxSelectBaseProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
124
68
|
"update:modelValue": (value: SelectModelValue | SelectModelValue[] | undefined) => any;
|
|
125
69
|
"update:open": (value: boolean) => any;
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
TagsInputRoot,
|
|
17
17
|
useDirection
|
|
18
18
|
} from "reka-ui";
|
|
19
|
-
import { computed, getCurrentInstance, mergeProps, nextTick, onMounted, onUnmounted, ref, useId, watch } from "vue";
|
|
19
|
+
import { computed, getCurrentInstance, mergeProps, nextTick, onMounted, onUnmounted, ref, useAttrs, useId, watch } from "vue";
|
|
20
20
|
import Button from "../components/Button.vue";
|
|
21
21
|
import Chip from "../components/Chip.vue";
|
|
22
22
|
import Icon from "../components/Icon.vue";
|
|
@@ -28,12 +28,15 @@ import { useIsMobile } from "../composables/use-media-query";
|
|
|
28
28
|
import { useMessages } from "../composables/use-messages";
|
|
29
29
|
import { selectTheme } from "../theme/select";
|
|
30
30
|
import { arrowContentProps, arrowElementProps } from "../utils/arrow";
|
|
31
|
+
import { useFieldAdornments } from "../utils/field-adornments";
|
|
32
|
+
import { canClearField, isFieldReadonly } from "../utils/field-clear";
|
|
31
33
|
import { isNativeInputA11yAttr, isNativeInputAttr, isNativeInputEvent } from "../utils/native-input";
|
|
32
34
|
import { overlayPortalProps } from "../utils/overlay";
|
|
33
35
|
import { resolveRegisteredColorRole } from "../utils/registered-colors";
|
|
34
|
-
import { resolveSlot, useComponentTheme, useFallthroughAttrs, useRootProps, useThemeBindings } from "../utils/ui";
|
|
36
|
+
import { applyClassPrefix, resolveSlot, useComponentTheme, useFallthroughAttrs, useRootProps, useThemeBindings } from "../utils/ui";
|
|
35
37
|
import { useComboboxSelect } from "./combobox-select";
|
|
36
38
|
import ComboboxSelectBody from "./ComboboxSelectBody.vue";
|
|
39
|
+
import FieldClearButton from "./FieldClearButton.vue";
|
|
37
40
|
defineOptions({ inheritAttrs: false });
|
|
38
41
|
const props = defineProps({
|
|
39
42
|
id: { type: String, required: false },
|
|
@@ -72,7 +75,10 @@ const props = defineProps({
|
|
|
72
75
|
ui: { type: Object, required: false }
|
|
73
76
|
});
|
|
74
77
|
const emit = defineEmits(["update:open", "update:modelValue", "update:searchTerm"]);
|
|
78
|
+
const slots = defineSlots();
|
|
79
|
+
const { leading, trailing, padding } = useFieldAdornments();
|
|
75
80
|
const instance = getCurrentInstance();
|
|
81
|
+
const attrs = useAttrs();
|
|
76
82
|
const initialValue = Array.isArray(props.defaultValue) ? [...props.defaultValue] : props.defaultValue;
|
|
77
83
|
const isControlled = () => Object.hasOwn(instance.vnode.props ?? {}, "modelValue") || Object.hasOwn(instance.vnode.props ?? {}, "model-value");
|
|
78
84
|
function selectionForMode(value, multiple) {
|
|
@@ -161,9 +167,6 @@ const {
|
|
|
161
167
|
} = useComboboxSelect(new Proxy(props, {
|
|
162
168
|
get: (target, key) => key === "modelValue" ? selection.value : Reflect.get(target, key)
|
|
163
169
|
}), updateSelection, { creatable: props.creatable });
|
|
164
|
-
function clear() {
|
|
165
|
-
setValue(props.multiple ? [] : void 0);
|
|
166
|
-
}
|
|
167
170
|
const selectedChipValue = ref();
|
|
168
171
|
const dir = useDirection();
|
|
169
172
|
function onTriggerKeydown(event) {
|
|
@@ -234,6 +237,12 @@ const searchText = computed({
|
|
|
234
237
|
emit("update:searchTerm", value);
|
|
235
238
|
}
|
|
236
239
|
});
|
|
240
|
+
const showClear = computed(() => canClearField(
|
|
241
|
+
props.clearable,
|
|
242
|
+
selectedValues.value.length > 0 || !!props.creatable && searchText.value.length > 0,
|
|
243
|
+
props.disabled,
|
|
244
|
+
isFieldReadonly(attrs.readonly)
|
|
245
|
+
));
|
|
237
246
|
const isSearchComposing = ref(false);
|
|
238
247
|
function onSearchCompositionStart() {
|
|
239
248
|
isSearchComposing.value = true;
|
|
@@ -412,7 +421,8 @@ const searchDescribedBy = computed(() => [
|
|
|
412
421
|
props.creatable && props.multiple && props.displayMode === "comma" && selectedOptions.value.length ? selectedSummaryId : void 0
|
|
413
422
|
].filter(Boolean).join(" ") || void 0);
|
|
414
423
|
const effectiveSize = computed(() => props.size ?? field?.size ?? "md");
|
|
415
|
-
const
|
|
424
|
+
const adornmentButtonSize = computed(() => ({ sm: "sm", md: "sm", lg: "md" })[effectiveSize.value]);
|
|
425
|
+
const adornmentScope = computed(() => ({ disabled: !!props.disabled, size: effectiveSize.value, buttonSize: adornmentButtonSize.value }));
|
|
416
426
|
const icons = useIcons();
|
|
417
427
|
const messages = useMessages();
|
|
418
428
|
const theme = useComponentTheme("select", selectTheme);
|
|
@@ -427,6 +437,9 @@ const triggerProps = computed(() => mergeProps(
|
|
|
427
437
|
resolveSlot(ui.value.trigger, props.ui?.trigger),
|
|
428
438
|
!props.creatable ? nativeTriggerAttrs.value : {}
|
|
429
439
|
));
|
|
440
|
+
function adornedTriggerProps() {
|
|
441
|
+
return mergeProps({ style: padding(!!slots.leading, !!slots.trailing) }, triggerProps.value);
|
|
442
|
+
}
|
|
430
443
|
const valueProps = computed(() => resolveSlot(ui.value.value, props.ui?.value));
|
|
431
444
|
const commaValueProps = computed(() => {
|
|
432
445
|
const override = props.ui?.value;
|
|
@@ -579,6 +592,17 @@ const bodyProps = computed(() => ({
|
|
|
579
592
|
itemProps: itemProps.value,
|
|
580
593
|
itemIndicatorProps: itemIndicatorProps.value
|
|
581
594
|
}));
|
|
595
|
+
async function clear() {
|
|
596
|
+
if (!showClear.value)
|
|
597
|
+
return;
|
|
598
|
+
searchText.value = "";
|
|
599
|
+
setValue(props.multiple ? [] : void 0);
|
|
600
|
+
await nextTick();
|
|
601
|
+
if (props.creatable)
|
|
602
|
+
activeEditableInput.value?.focus();
|
|
603
|
+
else
|
|
604
|
+
selectTrigger.value?.$el?.focus();
|
|
605
|
+
}
|
|
582
606
|
</script>
|
|
583
607
|
|
|
584
608
|
<template>
|
|
@@ -596,7 +620,10 @@ const bodyProps = computed(() => ({
|
|
|
596
620
|
@update:open="updateOpen($event)"
|
|
597
621
|
@update:model-value="(value2) => onComboboxValueUpdate(value2)"
|
|
598
622
|
>
|
|
599
|
-
<ComboboxAnchor>
|
|
623
|
+
<ComboboxAnchor :class="applyClassPrefix('relative')">
|
|
624
|
+
<fieldset v-if="slots.leading" ref="leading" :disabled="disabled" :inert="disabled || void 0" v-bind="resolveSlot(ui.leading, props.ui?.leading)">
|
|
625
|
+
<slot name="leading" v-bind="adornmentScope" />
|
|
626
|
+
</fieldset>
|
|
600
627
|
<!--
|
|
601
628
|
Select (creatable=false): a button trigger, opened by clicking anywhere
|
|
602
629
|
on it - the search input (if any) lives inside the popover instead.
|
|
@@ -608,7 +635,7 @@ const bodyProps = computed(() => ({
|
|
|
608
635
|
data-ui-group-item
|
|
609
636
|
:data-selaras-field-filled="selectedValues.length ? '' : void 0"
|
|
610
637
|
:data-selaras-field-active="open ? '' : void 0"
|
|
611
|
-
v-bind="
|
|
638
|
+
v-bind="adornedTriggerProps()"
|
|
612
639
|
@keydown.capture="onSearchKeydown"
|
|
613
640
|
>
|
|
614
641
|
<!--
|
|
@@ -713,29 +740,18 @@ const bodyProps = computed(() => ({
|
|
|
713
740
|
display-value re-syncs the visible text once modelValue changes.
|
|
714
741
|
tabindex="-1" replicates the one bit of its behavior this used.
|
|
715
742
|
-->
|
|
716
|
-
<
|
|
717
|
-
v-if="
|
|
718
|
-
|
|
719
|
-
variant="text"
|
|
720
|
-
color="neutral"
|
|
721
|
-
tabindex="-1"
|
|
722
|
-
:aria-label="messages.clear"
|
|
723
|
-
v-bind="clearProps"
|
|
724
|
-
@click.stop="clear"
|
|
725
|
-
>
|
|
726
|
-
<template #icon="{ class: iconClass }">
|
|
727
|
-
<slot name="clear-icon">
|
|
728
|
-
<Icon :name="icons.close" :class="iconClass" />
|
|
729
|
-
</slot>
|
|
743
|
+
<FieldClearButton v-if="showClear" :size="effectiveSize" tabindex="-1" v-bind="clearProps" @click.stop="clear">
|
|
744
|
+
<template v-if="slots['clear-icon']" #default>
|
|
745
|
+
<slot name="clear-icon" />
|
|
730
746
|
</template>
|
|
731
|
-
</
|
|
747
|
+
</FieldClearButton>
|
|
732
748
|
<slot v-if="loading" name="loading-icon">
|
|
733
|
-
<Icon :name="icons.loading" class="
|
|
749
|
+
<Icon :name="icons.loading" class="animate-spin" v-bind="iconProps" />
|
|
734
750
|
</slot>
|
|
735
751
|
<span v-if="loading" class="sr-only">{{ messages.loading }}</span>
|
|
736
752
|
<ComboboxTrigger v-if="dropdown" v-bind="dropdownProps" @click="onDropdownClick">
|
|
737
753
|
<slot name="dropdown-icon">
|
|
738
|
-
<Icon :name="icons.chevronDown"
|
|
754
|
+
<Icon :name="icons.chevronDown" v-bind="iconProps" />
|
|
739
755
|
</slot>
|
|
740
756
|
</ComboboxTrigger>
|
|
741
757
|
</div>
|
|
@@ -745,7 +761,7 @@ const bodyProps = computed(() => ({
|
|
|
745
761
|
data-ui-group-item
|
|
746
762
|
:data-selaras-field-filled="selectedValues.length ? '' : void 0"
|
|
747
763
|
:data-selaras-field-active="open ? '' : void 0"
|
|
748
|
-
v-bind="
|
|
764
|
+
v-bind="adornedTriggerProps()"
|
|
749
765
|
@click="openMobileAutocomplete()"
|
|
750
766
|
>
|
|
751
767
|
<span v-if="multiple && selectedOptions.length" v-bind="commaValueProps">{{ commaText }}</span>
|
|
@@ -765,21 +781,19 @@ const bodyProps = computed(() => ({
|
|
|
765
781
|
:aria-controls="modalId"
|
|
766
782
|
@keydown="openMobileAutocomplete"
|
|
767
783
|
>
|
|
768
|
-
<
|
|
769
|
-
<template #
|
|
770
|
-
<slot name="clear-icon"
|
|
771
|
-
<Icon :name="icons.close" class="size-4" />
|
|
772
|
-
</slot>
|
|
784
|
+
<FieldClearButton v-if="showClear" :size="effectiveSize" tabindex="-1" v-bind="clearProps" @click.stop="clear">
|
|
785
|
+
<template v-if="slots['clear-icon']" #default>
|
|
786
|
+
<slot name="clear-icon" />
|
|
773
787
|
</template>
|
|
774
|
-
</
|
|
788
|
+
</FieldClearButton>
|
|
775
789
|
<slot v-if="loading" name="loading-icon">
|
|
776
|
-
<Icon :name="icons.loading" class="
|
|
790
|
+
<Icon :name="icons.loading" class="animate-spin" v-bind="iconProps" />
|
|
777
791
|
</slot>
|
|
778
792
|
<span v-if="loading" class="sr-only">{{ messages.loading }}</span>
|
|
779
793
|
<button v-if="dropdown" type="button" tabindex="-1" :disabled="disabled" :aria-label="messages.search" v-bind="dropdownProps" @click.stop="onDropdownClick();
|
|
780
794
|
openMobileAutocomplete()">
|
|
781
795
|
<slot name="dropdown-icon">
|
|
782
|
-
<Icon :name="icons.chevronDown"
|
|
796
|
+
<Icon :name="icons.chevronDown" v-bind="iconProps" />
|
|
783
797
|
</slot>
|
|
784
798
|
</button>
|
|
785
799
|
</div>
|
|
@@ -794,7 +808,7 @@ const bodyProps = computed(() => ({
|
|
|
794
808
|
:aria-invalid="selectInvalid || void 0"
|
|
795
809
|
:aria-describedby="describedBy"
|
|
796
810
|
:aria-busy="loading || void 0"
|
|
797
|
-
v-bind="mergeProps(
|
|
811
|
+
v-bind="mergeProps(adornedTriggerProps(), modalTriggerAttrs)"
|
|
798
812
|
tabindex="0"
|
|
799
813
|
@keydown="onTriggerKeydown"
|
|
800
814
|
@blur="selectedChipValue = void 0"
|
|
@@ -864,36 +878,26 @@ const bodyProps = computed(() => ({
|
|
|
864
878
|
already set here regardless, so nothing about keyboard
|
|
865
879
|
reachability changes.
|
|
866
880
|
-->
|
|
867
|
-
<
|
|
868
|
-
v-if="
|
|
869
|
-
|
|
870
|
-
role="button"
|
|
871
|
-
:size="clearSize"
|
|
872
|
-
variant="text"
|
|
873
|
-
color="neutral"
|
|
874
|
-
tabindex="-1"
|
|
875
|
-
:aria-label="messages.clear"
|
|
876
|
-
v-bind="clearProps"
|
|
877
|
-
@click.stop="clear"
|
|
878
|
-
>
|
|
879
|
-
<template #icon="{ class: iconClass }">
|
|
880
|
-
<slot name="clear-icon">
|
|
881
|
-
<Icon :name="icons.close" :class="iconClass" />
|
|
882
|
-
</slot>
|
|
881
|
+
<FieldClearButton v-if="showClear" as="span" role="button" :size="effectiveSize" tabindex="-1" v-bind="clearProps" @click.stop="clear">
|
|
882
|
+
<template v-if="slots['clear-icon']" #default>
|
|
883
|
+
<slot name="clear-icon" />
|
|
883
884
|
</template>
|
|
884
|
-
</
|
|
885
|
+
</FieldClearButton>
|
|
885
886
|
<template v-if="loading">
|
|
886
887
|
<slot name="loading-icon">
|
|
887
|
-
<Icon :name="icons.loading" class="
|
|
888
|
+
<Icon :name="icons.loading" class="animate-spin" v-bind="iconProps" />
|
|
888
889
|
</slot>
|
|
889
890
|
</template>
|
|
890
891
|
<template v-else>
|
|
891
892
|
<slot name="dropdown-icon">
|
|
892
|
-
<Icon :name="icons.chevronDown"
|
|
893
|
+
<Icon :name="icons.chevronDown" v-bind="iconProps" />
|
|
893
894
|
</slot>
|
|
894
895
|
</template>
|
|
895
896
|
<span v-if="loading" class="sr-only">{{ messages.loading }}</span>
|
|
896
897
|
</ComboboxTrigger>
|
|
898
|
+
<fieldset v-if="slots.trailing" ref="trailing" :disabled="disabled" :inert="disabled || void 0" v-bind="resolveSlot(ui.trailing, props.ui?.trailing)">
|
|
899
|
+
<slot name="trailing" v-bind="adornmentScope" />
|
|
900
|
+
</fieldset>
|
|
897
901
|
</ComboboxAnchor>
|
|
898
902
|
|
|
899
903
|
<ComboboxPortal v-if="!showMobileModal" v-bind="portalProps">
|
|
@@ -2,12 +2,18 @@ import type { VariantProps } from 'tailwind-variants';
|
|
|
2
2
|
import type { SelectThemeSlots } from '../theme/select.js';
|
|
3
3
|
import type { RoundedArrowConfig } from '../utils/arrow.js';
|
|
4
4
|
import type { ColorRole } from '../utils/color-registry.js';
|
|
5
|
+
import type { FieldAdornmentSlotProps } from '../utils/field-adornments.js';
|
|
5
6
|
import type { OverlayPortal, OverlayPositioning } from '../utils/overlay.js';
|
|
6
7
|
import type { SelectModelValue } from '../utils/select-contracts.js';
|
|
7
8
|
import type { UiProp } from '../utils/ui.js';
|
|
8
|
-
import type { SelectItems
|
|
9
|
+
import type { SelectItems } from './combobox-select.js';
|
|
9
10
|
import { selectTheme } from '../theme/select.js';
|
|
10
11
|
type SelectVariants = VariantProps<typeof selectTheme>;
|
|
12
|
+
type __VLS_Slots = {
|
|
13
|
+
leading?: (props: FieldAdornmentSlotProps) => any;
|
|
14
|
+
trailing?: (props: FieldAdornmentSlotProps) => any;
|
|
15
|
+
[name: string]: ((props: any) => any) | undefined;
|
|
16
|
+
};
|
|
11
17
|
export interface ComboboxSelectBaseProps {
|
|
12
18
|
id?: string;
|
|
13
19
|
name?: string;
|
|
@@ -58,68 +64,6 @@ export interface ComboboxSelectBaseEmits {
|
|
|
58
64
|
'update:modelValue': [value: SelectModelValue | SelectModelValue[] | undefined];
|
|
59
65
|
'update:searchTerm': [value: string];
|
|
60
66
|
}
|
|
61
|
-
declare var __VLS_43: {
|
|
62
|
-
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
63
|
-
}, __VLS_98: {}, __VLS_105: {}, __VLS_120: {}, __VLS_136: {}, __VLS_143: {}, __VLS_150: {}, __VLS_174: {
|
|
64
|
-
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
65
|
-
}, __VLS_194: {
|
|
66
|
-
selected: import("./combobox-select.js").ResolvedOption | undefined;
|
|
67
|
-
}, __VLS_205: {}, __VLS_212: {}, __VLS_219: {}, __VLS_249: {}, __VLS_252: {}, __VLS_255: {}, __VLS_258: {}, __VLS_261: {
|
|
68
|
-
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
69
|
-
}, __VLS_264: {
|
|
70
|
-
group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
|
|
71
|
-
}, __VLS_267: {}, __VLS_305: string, __VLS_306: {}, __VLS_309: {}, __VLS_319: {
|
|
72
|
-
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
73
|
-
}, __VLS_322: {
|
|
74
|
-
group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
|
|
75
|
-
};
|
|
76
|
-
type __VLS_Slots = {} & {
|
|
77
|
-
[K in NonNullable<typeof __VLS_305>]?: (props: typeof __VLS_306) => any;
|
|
78
|
-
} & {
|
|
79
|
-
item?: (props: typeof __VLS_43) => any;
|
|
80
|
-
} & {
|
|
81
|
-
'clear-icon'?: (props: typeof __VLS_98) => any;
|
|
82
|
-
} & {
|
|
83
|
-
'loading-icon'?: (props: typeof __VLS_105) => any;
|
|
84
|
-
} & {
|
|
85
|
-
'dropdown-icon'?: (props: typeof __VLS_120) => any;
|
|
86
|
-
} & {
|
|
87
|
-
'clear-icon'?: (props: typeof __VLS_136) => any;
|
|
88
|
-
} & {
|
|
89
|
-
'loading-icon'?: (props: typeof __VLS_143) => any;
|
|
90
|
-
} & {
|
|
91
|
-
'dropdown-icon'?: (props: typeof __VLS_150) => any;
|
|
92
|
-
} & {
|
|
93
|
-
item?: (props: typeof __VLS_174) => any;
|
|
94
|
-
} & {
|
|
95
|
-
value?: (props: typeof __VLS_194) => any;
|
|
96
|
-
} & {
|
|
97
|
-
'clear-icon'?: (props: typeof __VLS_205) => any;
|
|
98
|
-
} & {
|
|
99
|
-
'loading-icon'?: (props: typeof __VLS_212) => any;
|
|
100
|
-
} & {
|
|
101
|
-
'dropdown-icon'?: (props: typeof __VLS_219) => any;
|
|
102
|
-
} & {
|
|
103
|
-
header?: (props: typeof __VLS_249) => any;
|
|
104
|
-
} & {
|
|
105
|
-
'filter-icon'?: (props: typeof __VLS_252) => any;
|
|
106
|
-
} & {
|
|
107
|
-
empty?: (props: typeof __VLS_255) => any;
|
|
108
|
-
} & {
|
|
109
|
-
'empty-filter'?: (props: typeof __VLS_258) => any;
|
|
110
|
-
} & {
|
|
111
|
-
item?: (props: typeof __VLS_261) => any;
|
|
112
|
-
} & {
|
|
113
|
-
group?: (props: typeof __VLS_264) => any;
|
|
114
|
-
} & {
|
|
115
|
-
footer?: (props: typeof __VLS_267) => any;
|
|
116
|
-
} & {
|
|
117
|
-
header?: (props: typeof __VLS_309) => any;
|
|
118
|
-
} & {
|
|
119
|
-
item?: (props: typeof __VLS_319) => any;
|
|
120
|
-
} & {
|
|
121
|
-
group?: (props: typeof __VLS_322) => any;
|
|
122
|
-
};
|
|
123
67
|
declare const __VLS_base: import("vue").DefineComponent<ComboboxSelectBaseProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
124
68
|
"update:modelValue": (value: SelectModelValue | SelectModelValue[] | undefined) => any;
|
|
125
69
|
"update:open": (value: boolean) => any;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ButtonThemeSlots } from '../theme/button.js';
|
|
2
|
+
import type { UiProp } from '../utils/ui.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
size?: 'sm' | 'md' | 'lg';
|
|
5
|
+
ui?: UiProp<ButtonThemeSlots>;
|
|
6
|
+
};
|
|
7
|
+
declare var __VLS_11: {
|
|
8
|
+
class: unknown;
|
|
9
|
+
};
|
|
10
|
+
type __VLS_Slots = {} & {
|
|
11
|
+
default?: (props: typeof __VLS_11) => any;
|
|
12
|
+
};
|
|
13
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
17
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
18
|
+
new (): {
|
|
19
|
+
$slots: S;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import Button from "../components/Button.vue";
|
|
4
|
+
import Icon from "../components/Icon.vue";
|
|
5
|
+
import { useIcons } from "../composables/use-icons";
|
|
6
|
+
import { useMessages } from "../composables/use-messages";
|
|
7
|
+
import { fieldClearButtonTheme } from "../theme/field-clear-button";
|
|
8
|
+
import { resolveSlot, useComponentTheme, useRootProps } from "../utils/ui";
|
|
9
|
+
defineOptions({ inheritAttrs: false });
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
size: { type: String, required: false },
|
|
12
|
+
ui: { type: Object, required: false }
|
|
13
|
+
});
|
|
14
|
+
const theme = useComponentTheme("fieldClearButton", fieldClearButtonTheme);
|
|
15
|
+
const ui = computed(() => theme.value({ size: props.size }));
|
|
16
|
+
const rootProps = useRootProps(() => ui.value.base, () => props.ui?.base);
|
|
17
|
+
const iconProps = computed(() => resolveSlot(ui.value.icon, props.ui?.leadingIcon));
|
|
18
|
+
const icons = useIcons();
|
|
19
|
+
const messages = useMessages();
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<Button :size="size" variant="ghost" color="neutral" square :aria-label="messages.clear" v-bind="rootProps" :ui="{ leadingIcon: iconProps }" @mousedown.prevent>
|
|
24
|
+
<template #icon="{ class: iconClass }">
|
|
25
|
+
<slot :class="iconClass">
|
|
26
|
+
<Icon :name="icons.close" :class="iconClass" />
|
|
27
|
+
</slot>
|
|
28
|
+
</template>
|
|
29
|
+
</Button>
|
|
30
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ButtonThemeSlots } from '../theme/button.js';
|
|
2
|
+
import type { UiProp } from '../utils/ui.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
size?: 'sm' | 'md' | 'lg';
|
|
5
|
+
ui?: UiProp<ButtonThemeSlots>;
|
|
6
|
+
};
|
|
7
|
+
declare var __VLS_11: {
|
|
8
|
+
class: unknown;
|
|
9
|
+
};
|
|
10
|
+
type __VLS_Slots = {} & {
|
|
11
|
+
default?: (props: typeof __VLS_11) => any;
|
|
12
|
+
};
|
|
13
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
17
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
18
|
+
new (): {
|
|
19
|
+
$slots: S;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ListboxThemeSlots } from '../theme/listbox.js';
|
|
2
|
+
import type { ColorRole } from '../utils/color-registry.js';
|
|
2
3
|
import type { ResolvedItemOption } from './combobox-select.js';
|
|
3
4
|
type __VLS_Props = {
|
|
4
5
|
option: ResolvedItemOption;
|
|
@@ -7,7 +8,7 @@ type __VLS_Props = {
|
|
|
7
8
|
disabled?: boolean;
|
|
8
9
|
checkbox?: boolean;
|
|
9
10
|
descriptionKey: string;
|
|
10
|
-
color:
|
|
11
|
+
color: ColorRole;
|
|
11
12
|
size?: 'sm' | 'md' | 'lg';
|
|
12
13
|
parts: Record<ListboxThemeSlots, Record<string, unknown>>;
|
|
13
14
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ListboxItem, ListboxItemIndicator } from "reka-ui";
|
|
3
3
|
import { computed } from "vue";
|
|
4
|
+
import Checkbox from "../components/Checkbox.vue";
|
|
4
5
|
import Icon from "../components/Icon.vue";
|
|
5
6
|
import { useIcons } from "../composables/use-icons";
|
|
6
7
|
const props = defineProps({
|
|
@@ -10,7 +11,7 @@ const props = defineProps({
|
|
|
10
11
|
disabled: { type: Boolean, required: false },
|
|
11
12
|
checkbox: { type: Boolean, required: false },
|
|
12
13
|
descriptionKey: { type: String, required: true },
|
|
13
|
-
color: { type:
|
|
14
|
+
color: { type: null, required: true },
|
|
14
15
|
size: { type: String, required: false },
|
|
15
16
|
parts: { type: Object, required: true }
|
|
16
17
|
});
|
|
@@ -22,7 +23,7 @@ const icon = computed(() => typeof record.value?.icon === "string" ? record.valu
|
|
|
22
23
|
|
|
23
24
|
<template>
|
|
24
25
|
<ListboxItem :value="option.value" :text-value="option.label" :disabled="disabled || option.disabled" v-bind="parts.item">
|
|
25
|
-
<
|
|
26
|
+
<Checkbox v-if="checkbox" :model-value="selected" :color="color" :size="size" :data-state="selected ? 'checked' : 'unchecked'" decorative variant="default" v-bind="parts.checkbox" />
|
|
26
27
|
<slot :item="option.raw" :index="index" :selected="selected" :disabled="!!(disabled || option.disabled)">
|
|
27
28
|
<Icon v-if="icon" :name="icon" v-bind="parts.icon" />
|
|
28
29
|
<span v-bind="parts.itemContent">
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ListboxThemeSlots } from '../theme/listbox.js';
|
|
2
|
+
import type { ColorRole } from '../utils/color-registry.js';
|
|
2
3
|
import type { ResolvedItemOption } from './combobox-select.js';
|
|
3
4
|
type __VLS_Props = {
|
|
4
5
|
option: ResolvedItemOption;
|
|
@@ -7,7 +8,7 @@ type __VLS_Props = {
|
|
|
7
8
|
disabled?: boolean;
|
|
8
9
|
checkbox?: boolean;
|
|
9
10
|
descriptionKey: string;
|
|
10
|
-
color:
|
|
11
|
+
color: ColorRole;
|
|
11
12
|
size?: 'sm' | 'md' | 'lg';
|
|
12
13
|
parts: Record<ListboxThemeSlots, Record<string, unknown>>;
|
|
13
14
|
};
|