@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.
Files changed (77) hide show
  1. package/README.md +12 -1
  2. package/dist/agent/catalog.json +1 -1
  3. package/dist/module.json +1 -1
  4. package/dist/runtime/components/Autocomplete.vue +6 -0
  5. package/dist/runtime/components/Checkbox.d.vue.ts +6 -4
  6. package/dist/runtime/components/Checkbox.vue +30 -22
  7. package/dist/runtime/components/Checkbox.vue.d.ts +6 -4
  8. package/dist/runtime/components/DatePicker.d.vue.ts +27 -27
  9. package/dist/runtime/components/DatePicker.vue +58 -99
  10. package/dist/runtime/components/DatePicker.vue.d.ts +27 -27
  11. package/dist/runtime/components/Editable.d.vue.ts +91 -0
  12. package/dist/runtime/components/Editable.vue +257 -0
  13. package/dist/runtime/components/Editable.vue.d.ts +91 -0
  14. package/dist/runtime/components/Input.d.vue.ts +7 -4
  15. package/dist/runtime/components/Input.vue +41 -25
  16. package/dist/runtime/components/Input.vue.d.ts +7 -4
  17. package/dist/runtime/components/Select.vue +6 -0
  18. package/dist/runtime/components/Textarea.d.vue.ts +7 -4
  19. package/dist/runtime/components/Textarea.vue +42 -28
  20. package/dist/runtime/components/Textarea.vue.d.ts +7 -4
  21. package/dist/runtime/components/Toolbar.d.vue.ts +25 -0
  22. package/dist/runtime/components/Toolbar.vue +35 -0
  23. package/dist/runtime/components/Toolbar.vue.d.ts +25 -0
  24. package/dist/runtime/components/ToolbarButton.d.vue.ts +20 -0
  25. package/dist/runtime/components/ToolbarButton.vue +46 -0
  26. package/dist/runtime/components/ToolbarButton.vue.d.ts +20 -0
  27. package/dist/runtime/components/ToolbarSeparator.d.vue.ts +10 -0
  28. package/dist/runtime/components/ToolbarSeparator.vue +22 -0
  29. package/dist/runtime/components/ToolbarSeparator.vue.d.ts +10 -0
  30. package/dist/runtime/components/ToolbarToggleGroup.d.vue.ts +37 -0
  31. package/dist/runtime/components/ToolbarToggleGroup.vue +44 -0
  32. package/dist/runtime/components/ToolbarToggleGroup.vue.d.ts +37 -0
  33. package/dist/runtime/internal/ComboboxSelectBase.d.vue.ts +7 -63
  34. package/dist/runtime/internal/ComboboxSelectBase.vue +58 -54
  35. package/dist/runtime/internal/ComboboxSelectBase.vue.d.ts +7 -63
  36. package/dist/runtime/internal/FieldClearButton.d.vue.ts +21 -0
  37. package/dist/runtime/internal/FieldClearButton.vue +30 -0
  38. package/dist/runtime/internal/FieldClearButton.vue.d.ts +21 -0
  39. package/dist/runtime/internal/ListboxOption.d.vue.ts +2 -1
  40. package/dist/runtime/internal/ListboxOption.vue +3 -2
  41. package/dist/runtime/internal/ListboxOption.vue.d.ts +2 -1
  42. package/dist/runtime/theme/date-picker.d.ts +27 -0
  43. package/dist/runtime/theme/date-picker.js +6 -3
  44. package/dist/runtime/theme/editable.d.ts +155 -0
  45. package/dist/runtime/theme/editable.js +25 -0
  46. package/dist/runtime/theme/field-clear-button.d.ts +56 -0
  47. package/dist/runtime/theme/field-clear-button.js +15 -0
  48. package/dist/runtime/theme/input.d.ts +6 -9
  49. package/dist/runtime/theme/input.js +7 -12
  50. package/dist/runtime/theme/listbox.js +1 -1
  51. package/dist/runtime/theme/select.d.ts +15 -0
  52. package/dist/runtime/theme/select.js +13 -10
  53. package/dist/runtime/theme/textarea.d.ts +6 -9
  54. package/dist/runtime/theme/textarea.js +6 -4
  55. package/dist/runtime/theme/toolbar-button.d.ts +65 -0
  56. package/dist/runtime/theme/toolbar-button.js +21 -0
  57. package/dist/runtime/theme/toolbar-separator.d.ts +35 -0
  58. package/dist/runtime/theme/toolbar-separator.js +8 -0
  59. package/dist/runtime/theme/toolbar-toggle-group.d.ts +74 -0
  60. package/dist/runtime/theme/toolbar-toggle-group.js +13 -0
  61. package/dist/runtime/theme/toolbar.d.ts +35 -0
  62. package/dist/runtime/theme/toolbar.js +11 -0
  63. package/dist/runtime/theme-config.d.ts +36 -0
  64. package/dist/runtime/types/index.d.ts +6 -0
  65. package/dist/runtime/utils/field-adornments.d.ts +14 -0
  66. package/dist/runtime/utils/field-adornments.js +36 -0
  67. package/dist/runtime/utils/field-clear.d.ts +9 -0
  68. package/dist/runtime/utils/field-clear.js +7 -0
  69. package/dist/runtime/utils/icons.d.ts +1 -0
  70. package/dist/runtime/utils/icons.js +1 -0
  71. package/dist/runtime/utils/messages.d.ts +4 -0
  72. package/dist/runtime/utils/messages.js +4 -0
  73. package/dist/runtime/utils/select-contracts.d.ts +3 -0
  74. package/dist/runtime/utils/toolbar.d.ts +9 -0
  75. package/dist/runtime/utils/toolbar.js +1 -0
  76. package/package.json +13 -5
  77. package/skills/selaras/SKILL.md +11 -7
@@ -1,13 +1,13 @@
1
1
  <script setup>
2
- import { computed, mergeProps } from "vue";
2
+ import { computed, mergeProps, nextTick, ref, useAttrs } from "vue";
3
3
  import { useFormField } from "../composables/use-form-field";
4
- import { useIcons } from "../composables/use-icons";
5
- import { useMessages } from "../composables/use-messages";
4
+ import FieldClearButton from "../internal/FieldClearButton.vue";
6
5
  import { inputTheme } from "../theme/input";
6
+ import { useFieldAdornments } from "../utils/field-adornments";
7
+ import { canClearField, fieldClearWidths, isFieldReadonly } from "../utils/field-clear";
7
8
  import { isNativeInputA11yAttr, isNativeInputAttr } from "../utils/native-input";
8
9
  import { resolveRegisteredColorRole } from "../utils/registered-colors";
9
10
  import { resolveSlot, useComponentTheme, useFallthroughAttrs, useRootProps, useThemeProps } from "../utils/ui";
10
- import Button from "./Button.vue";
11
11
  import Icon from "./Icon.vue";
12
12
  defineOptions({ inheritAttrs: false });
13
13
  const props = defineProps({
@@ -26,21 +26,29 @@ const props = defineProps({
26
26
  ui: { type: Object, required: false }
27
27
  });
28
28
  const emit = defineEmits(["update:modelValue"]);
29
+ const slots = defineSlots();
30
+ const { leading, trailing, padding, clearOffset } = useFieldAdornments();
29
31
  const field = useFormField();
32
+ const attrs = useAttrs();
33
+ const inputRef = ref();
30
34
  const effectivePlaceholder = computed(() => props.placeholder || (field?.floatingLabel.value ? " " : void 0));
31
35
  const inputId = computed(() => props.id ?? field?.id);
32
36
  const inputInvalid = computed(() => props.invalid || (field?.invalid.value ?? false));
33
37
  const describedBy = computed(() => field?.describedBy.value);
34
- const hasValue = computed(() => props.modelValue !== void 0 && props.modelValue !== "");
35
- const showClear = computed(() => !!props.clearable && !props.disabled && hasValue.value);
36
- function clear() {
38
+ const hasValue = computed(() => props.modelValue != null && props.modelValue !== "");
39
+ const showClear = computed(() => canClearField(props.clearable, hasValue.value, props.disabled, isFieldReadonly(attrs.readonly)));
40
+ async function clear() {
41
+ if (!showClear.value)
42
+ return;
37
43
  emit("update:modelValue", "");
44
+ await nextTick();
45
+ inputRef.value?.focus();
38
46
  }
39
47
  const themeProps = useThemeProps("input");
40
48
  const effectiveSize = computed(() => props.size ?? field?.size ?? themeProps.value.size ?? "md");
41
- const clearSize = computed(() => ({ sm: "sm", md: "sm", lg: "md" })[effectiveSize.value]);
42
- const icons = useIcons();
43
- const messages = useMessages();
49
+ const adornmentButtonSize = computed(() => ({ sm: "sm", md: "sm", lg: "md" })[effectiveSize.value]);
50
+ const adornmentScope = computed(() => ({ disabled: !!props.disabled, size: effectiveSize.value, buttonSize: adornmentButtonSize.value }));
51
+ const clearWidth = computed(() => fieldClearWidths[effectiveSize.value]);
44
52
  const theme = useComponentTheme("input", inputTheme);
45
53
  const effectiveColor = computed(() => resolveRegisteredColorRole(props.color ?? themeProps.value.color ?? "primary", "primary"));
46
54
  const ui = computed(() => theme.value({
@@ -55,13 +63,23 @@ const rootProps = useRootProps(() => ui.value.root, () => props.ui?.root, { excl
55
63
  const nativeInputAttrs = useFallthroughAttrs(isInputAttr);
56
64
  const baseProps = computed(() => resolveSlot(ui.value.base, props.ui?.base));
57
65
  const inputProps = computed(() => mergeProps(baseProps.value, nativeInputAttrs.value));
66
+ function adornedInputProps() {
67
+ return mergeProps({ style: padding(!!slots.leading, !!slots.trailing, showClear.value ? clearWidth.value : "0rem") }, inputProps.value);
68
+ }
69
+ function clearProps() {
70
+ return mergeProps({ style: slots.trailing ? clearOffset() : void 0 }, resolveSlot(ui.value.clear, props.ui?.clear));
71
+ }
58
72
  </script>
59
73
 
60
74
  <template>
61
- <div :data-selaras-color="inputInvalid ? 'danger' : effectiveColor" :data-selaras-field-leading="icon ? '' : void 0" v-bind="rootProps">
62
- <Icon v-if="icon" :name="icon" v-bind="resolveSlot(ui.leadingIcon, props.ui?.leadingIcon)" />
75
+ <div :data-selaras-color="inputInvalid ? 'danger' : effectiveColor" :data-selaras-field-leading="icon || slots.leading ? '' : void 0" v-bind="rootProps">
76
+ <fieldset v-if="slots.leading" ref="leading" :disabled="disabled" :inert="disabled || void 0" v-bind="resolveSlot(ui.leading, props.ui?.leading)">
77
+ <slot name="leading" v-bind="adornmentScope" />
78
+ </fieldset>
79
+ <Icon v-else-if="icon" :name="icon" v-bind="resolveSlot(ui.leadingIcon, props.ui?.leadingIcon)" />
63
80
  <input
64
81
  :id="inputId"
82
+ ref="inputRef"
65
83
  data-ui-group-item
66
84
  :value="modelValue"
67
85
  :type="type"
@@ -70,24 +88,22 @@ const inputProps = computed(() => mergeProps(baseProps.value, nativeInputAttrs.v
70
88
  :disabled="disabled"
71
89
  :aria-invalid="inputInvalid || void 0"
72
90
  :aria-describedby="describedBy"
73
- v-bind="inputProps"
91
+ v-bind="adornedInputProps()"
74
92
  @input="$emit('update:modelValue', $event.target.value)"
75
93
  >
76
- <Button
94
+ <FieldClearButton
77
95
  v-if="showClear"
78
- :size="clearSize"
79
- variant="text"
80
- color="neutral"
81
- :aria-label="messages.clear"
82
- v-bind="resolveSlot(ui.clear, props.ui?.clear)"
96
+ :size="effectiveSize"
97
+ v-bind="clearProps()"
83
98
  @click="clear"
84
99
  >
85
- <template #icon="{ class: iconClass }">
86
- <slot name="clear-icon">
87
- <Icon :name="icons.close" :class="iconClass" />
88
- </slot>
100
+ <template v-if="slots['clear-icon']" #default>
101
+ <slot name="clear-icon" />
89
102
  </template>
90
- </Button>
91
- <Icon v-else-if="trailingIcon" :name="trailingIcon" v-bind="resolveSlot(ui.trailingIcon, props.ui?.trailingIcon)" />
103
+ </FieldClearButton>
104
+ <Icon v-else-if="trailingIcon && !slots.trailing" :name="trailingIcon" v-bind="resolveSlot(ui.trailingIcon, props.ui?.trailingIcon)" />
105
+ <fieldset v-if="slots.trailing" ref="trailing" :disabled="disabled" :inert="disabled || void 0" v-bind="resolveSlot(ui.trailing, props.ui?.trailing)">
106
+ <slot name="trailing" v-bind="adornmentScope" />
107
+ </fieldset>
92
108
  </div>
93
109
  </template>
@@ -1,9 +1,11 @@
1
1
  import type { VariantProps } from 'tailwind-variants';
2
2
  import type { InputThemeSlots } from '../theme/input.js';
3
3
  import type { ColorRole } from '../utils/color-registry.js';
4
+ import type { FieldAdornmentSlotProps } from '../utils/field-adornments.js';
4
5
  import type { UiProp } from '../utils/ui.js';
5
6
  import { inputTheme } from '../theme/input.js';
6
7
  type InputVariants = VariantProps<typeof inputTheme>;
8
+ type __VLS_Slots = InputSlots;
7
9
  export interface InputProps {
8
10
  id?: string;
9
11
  name?: string;
@@ -23,10 +25,11 @@ export interface InputProps {
23
25
  export interface InputEmits {
24
26
  'update:modelValue': [value: string];
25
27
  }
26
- declare var __VLS_15: {};
27
- type __VLS_Slots = {} & {
28
- 'clear-icon'?: (props: typeof __VLS_15) => any;
29
- };
28
+ export interface InputSlots {
29
+ 'leading'?: (props: FieldAdornmentSlotProps) => any;
30
+ 'trailing'?: (props: FieldAdornmentSlotProps) => any;
31
+ 'clear-icon'?: () => any;
32
+ }
30
33
  declare const __VLS_base: import("vue").DefineComponent<InputProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
31
34
  "update:modelValue": (value: string) => any;
32
35
  }, string, import("vue").PublicProps, Readonly<InputProps> & Readonly<{
@@ -75,6 +75,12 @@ const unscopedSlots = ["header", "footer", "empty", "empty-filter", "filter-icon
75
75
  @update:model-value="updateValue"
76
76
  @update:search-term="emit('update:searchTerm', $event)"
77
77
  >
78
+ <template v-if="slots.leading" #leading="scope">
79
+ <slot name="leading" v-bind="scope" />
80
+ </template>
81
+ <template v-if="slots.trailing" #trailing="scope">
82
+ <slot name="trailing" v-bind="scope" />
83
+ </template>
78
84
  <template v-if="slots.item" #item="{ item }">
79
85
  <slot name="item" :item="itemData(item)" />
80
86
  </template>
@@ -1,9 +1,11 @@
1
1
  import type { VariantProps } from 'tailwind-variants';
2
2
  import type { TextareaThemeSlots } from '../theme/textarea.js';
3
3
  import type { ColorRole } from '../utils/color-registry.js';
4
+ import type { FieldAdornmentSlotProps } from '../utils/field-adornments.js';
4
5
  import type { UiProp } from '../utils/ui.js';
5
6
  import { textareaTheme } from '../theme/textarea.js';
6
7
  type TextareaVariants = VariantProps<typeof textareaTheme>;
8
+ type __VLS_Slots = TextareaSlots;
7
9
  export interface TextareaProps {
8
10
  id?: string;
9
11
  name?: string;
@@ -27,10 +29,11 @@ export interface TextareaProps {
27
29
  export interface TextareaEmits {
28
30
  'update:modelValue': [value: string];
29
31
  }
30
- declare var __VLS_15: {};
31
- type __VLS_Slots = {} & {
32
- 'clear-icon'?: (props: typeof __VLS_15) => any;
33
- };
32
+ export interface TextareaSlots {
33
+ 'leading'?: (props: FieldAdornmentSlotProps) => any;
34
+ 'trailing'?: (props: FieldAdornmentSlotProps) => any;
35
+ 'clear-icon'?: () => any;
36
+ }
34
37
  declare const __VLS_base: import("vue").DefineComponent<TextareaProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
35
38
  "update:modelValue": (value: string) => any;
36
39
  }, string, import("vue").PublicProps, Readonly<TextareaProps> & Readonly<{
@@ -1,13 +1,13 @@
1
1
  <script setup>
2
- import { computed, mergeProps, nextTick, onMounted, ref, watch } from "vue";
2
+ import { computed, mergeProps, nextTick, onMounted, ref, useAttrs, watch } from "vue";
3
3
  import { useFormField } from "../composables/use-form-field";
4
- import { useIcons } from "../composables/use-icons";
5
- import { useMessages } from "../composables/use-messages";
4
+ import FieldClearButton from "../internal/FieldClearButton.vue";
6
5
  import { textareaTheme } from "../theme/textarea";
6
+ import { useFieldAdornments } from "../utils/field-adornments";
7
+ import { canClearField, fieldClearWidths, isFieldReadonly } from "../utils/field-clear";
7
8
  import { isNativeInputA11yAttr, isNativeInputAttr } from "../utils/native-input";
8
9
  import { resolveRegisteredColorRole } from "../utils/registered-colors";
9
10
  import { resolveSlot, useComponentTheme, useFallthroughAttrs, useRootProps } from "../utils/ui";
10
- import Button from "./Button.vue";
11
11
  import Icon from "./Icon.vue";
12
12
  defineOptions({ inheritAttrs: false });
13
13
  const props = defineProps({
@@ -28,20 +28,28 @@ const props = defineProps({
28
28
  ui: { type: Object, required: false }
29
29
  });
30
30
  const emit = defineEmits(["update:modelValue"]);
31
+ const slots = defineSlots();
32
+ const { leading, trailing, padding, clearOffset } = useFieldAdornments();
31
33
  const field = useFormField();
34
+ const attrs = useAttrs();
35
+ const textareaRef = ref();
32
36
  const effectivePlaceholder = computed(() => props.placeholder || (field?.floatingLabel.value ? " " : void 0));
33
37
  const textareaId = computed(() => props.id ?? field?.id);
34
38
  const textareaInvalid = computed(() => props.invalid || (field?.invalid.value ?? false));
35
39
  const describedBy = computed(() => field?.describedBy.value);
36
- const hasValue = computed(() => props.modelValue !== void 0 && props.modelValue !== "");
37
- const showClear = computed(() => !!props.clearable && !props.disabled && hasValue.value);
38
- function clear() {
40
+ const hasValue = computed(() => props.modelValue != null && props.modelValue !== "");
41
+ const showClear = computed(() => canClearField(props.clearable, hasValue.value, props.disabled, isFieldReadonly(attrs.readonly)));
42
+ async function clear() {
43
+ if (!showClear.value)
44
+ return;
39
45
  emit("update:modelValue", "");
46
+ await nextTick();
47
+ textareaRef.value?.focus();
40
48
  }
41
49
  const effectiveSize = computed(() => props.size ?? field?.size ?? "md");
42
- const clearSize = computed(() => ({ sm: "sm", md: "sm", lg: "md" })[effectiveSize.value]);
43
- const icons = useIcons();
44
- const messages = useMessages();
50
+ const adornmentButtonSize = computed(() => ({ sm: "sm", md: "sm", lg: "md" })[effectiveSize.value]);
51
+ const adornmentScope = computed(() => ({ disabled: !!props.disabled, size: effectiveSize.value, buttonSize: adornmentButtonSize.value }));
52
+ const clearWidth = computed(() => fieldClearWidths[effectiveSize.value]);
45
53
  const theme = useComponentTheme("textarea", textareaTheme);
46
54
  const effectiveColor = computed(() => resolveRegisteredColorRole(props.color ?? "primary", "primary"));
47
55
  const ui = computed(() => theme.value({
@@ -56,7 +64,6 @@ const isTextareaAttr = (key) => isNativeInputAttr(key) || isNativeInputA11yAttr(
56
64
  const rootProps = useRootProps(() => ui.value.root, () => props.ui?.root, { exclude: isTextareaAttr });
57
65
  const nativeTextareaAttrs = useFallthroughAttrs(isTextareaAttr);
58
66
  const baseProps = computed(() => mergeProps(resolveSlot(ui.value.base, props.ui?.base), nativeTextareaAttrs.value));
59
- const textareaRef = ref();
60
67
  async function resize() {
61
68
  if (!props.autoresize || !textareaRef.value)
62
69
  return;
@@ -66,8 +73,8 @@ async function resize() {
66
73
  if (props.maxrows) {
67
74
  const cs = getComputedStyle(el);
68
75
  const lineHeight = Number.parseFloat(cs.lineHeight);
69
- const padding = Number.parseFloat(cs.paddingTop) + Number.parseFloat(cs.paddingBottom);
70
- const maxHeight = lineHeight * props.maxrows + padding;
76
+ const padding2 = Number.parseFloat(cs.paddingTop) + Number.parseFloat(cs.paddingBottom);
77
+ const maxHeight = lineHeight * props.maxrows + padding2;
71
78
  el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`;
72
79
  el.style.overflowY = el.scrollHeight > maxHeight ? "auto" : "hidden";
73
80
  return;
@@ -76,11 +83,20 @@ async function resize() {
76
83
  }
77
84
  onMounted(resize);
78
85
  watch(() => props.modelValue, resize);
86
+ function adornedInputProps() {
87
+ return mergeProps({ style: padding(!!slots.leading, !!slots.trailing, showClear.value ? clearWidth.value : "0rem") }, baseProps.value);
88
+ }
89
+ function clearProps() {
90
+ return mergeProps({ style: slots.trailing ? clearOffset() : void 0 }, resolveSlot(ui.value.clear, props.ui?.clear));
91
+ }
79
92
  </script>
80
93
 
81
94
  <template>
82
- <div :data-selaras-color="textareaInvalid ? 'danger' : effectiveColor" :data-selaras-field-leading="icon ? '' : void 0" v-bind="rootProps">
83
- <Icon v-if="icon" :name="icon" v-bind="resolveSlot(ui.leadingIcon, props.ui?.leadingIcon)" />
95
+ <div :data-selaras-color="textareaInvalid ? 'danger' : effectiveColor" :data-selaras-field-leading="icon || slots.leading ? '' : void 0" v-bind="rootProps">
96
+ <fieldset v-if="slots.leading" ref="leading" :disabled="disabled" :inert="disabled || void 0" v-bind="resolveSlot(ui.leading, props.ui?.leading)">
97
+ <slot name="leading" v-bind="adornmentScope" />
98
+ </fieldset>
99
+ <Icon v-else-if="icon" :name="icon" v-bind="resolveSlot(ui.leadingIcon, props.ui?.leadingIcon)" />
84
100
  <textarea
85
101
  :id="textareaId"
86
102
  ref="textareaRef"
@@ -92,25 +108,23 @@ watch(() => props.modelValue, resize);
92
108
  :disabled="disabled"
93
109
  :aria-invalid="textareaInvalid || void 0"
94
110
  :aria-describedby="describedBy"
95
- v-bind="baseProps"
111
+ v-bind="adornedInputProps()"
96
112
  @input="$emit('update:modelValue', $event.target.value);
97
113
  resize()"
98
114
  />
99
- <Button
115
+ <FieldClearButton
100
116
  v-if="showClear"
101
- :size="clearSize"
102
- variant="text"
103
- color="neutral"
104
- :aria-label="messages.clear"
105
- v-bind="resolveSlot(ui.clear, props.ui?.clear)"
117
+ :size="effectiveSize"
118
+ v-bind="clearProps()"
106
119
  @click="clear"
107
120
  >
108
- <template #icon="{ class: iconClass }">
109
- <slot name="clear-icon">
110
- <Icon :name="icons.close" :class="iconClass" />
111
- </slot>
121
+ <template v-if="slots['clear-icon']" #default>
122
+ <slot name="clear-icon" />
112
123
  </template>
113
- </Button>
114
- <Icon v-else-if="trailingIcon" :name="trailingIcon" v-bind="resolveSlot(ui.trailingIcon, props.ui?.trailingIcon)" />
124
+ </FieldClearButton>
125
+ <Icon v-else-if="trailingIcon && !slots.trailing" :name="trailingIcon" v-bind="resolveSlot(ui.trailingIcon, props.ui?.trailingIcon)" />
126
+ <fieldset v-if="slots.trailing" ref="trailing" :disabled="disabled" :inert="disabled || void 0" v-bind="resolveSlot(ui.trailing, props.ui?.trailing)">
127
+ <slot name="trailing" v-bind="adornmentScope" />
128
+ </fieldset>
115
129
  </div>
116
130
  </template>
@@ -1,9 +1,11 @@
1
1
  import type { VariantProps } from 'tailwind-variants';
2
2
  import type { TextareaThemeSlots } from '../theme/textarea.js';
3
3
  import type { ColorRole } from '../utils/color-registry.js';
4
+ import type { FieldAdornmentSlotProps } from '../utils/field-adornments.js';
4
5
  import type { UiProp } from '../utils/ui.js';
5
6
  import { textareaTheme } from '../theme/textarea.js';
6
7
  type TextareaVariants = VariantProps<typeof textareaTheme>;
8
+ type __VLS_Slots = TextareaSlots;
7
9
  export interface TextareaProps {
8
10
  id?: string;
9
11
  name?: string;
@@ -27,10 +29,11 @@ export interface TextareaProps {
27
29
  export interface TextareaEmits {
28
30
  'update:modelValue': [value: string];
29
31
  }
30
- declare var __VLS_15: {};
31
- type __VLS_Slots = {} & {
32
- 'clear-icon'?: (props: typeof __VLS_15) => any;
33
- };
32
+ export interface TextareaSlots {
33
+ 'leading'?: (props: FieldAdornmentSlotProps) => any;
34
+ 'trailing'?: (props: FieldAdornmentSlotProps) => any;
35
+ 'clear-icon'?: () => any;
36
+ }
34
37
  declare const __VLS_base: import("vue").DefineComponent<TextareaProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
35
38
  "update:modelValue": (value: string) => any;
36
39
  }, string, import("vue").PublicProps, Readonly<TextareaProps> & Readonly<{
@@ -0,0 +1,25 @@
1
+ import type { ToolbarThemeSlots } from '../theme/toolbar.js';
2
+ import type { ColorRole } from '../utils/color-registry.js';
3
+ import type { UiProp } from '../utils/ui.js';
4
+ type __VLS_Slots = ToolbarSlots;
5
+ export interface ToolbarProps {
6
+ orientation?: 'horizontal' | 'vertical';
7
+ size?: 'sm' | 'md' | 'lg';
8
+ color?: ColorRole;
9
+ disabled?: boolean;
10
+ loop?: boolean;
11
+ dir?: 'ltr' | 'rtl';
12
+ ui?: UiProp<ToolbarThemeSlots>;
13
+ }
14
+ export interface ToolbarSlots {
15
+ default?: () => any;
16
+ }
17
+ declare const __VLS_base: import("vue").DefineComponent<ToolbarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ToolbarProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
21
+ type __VLS_WithSlots<T, S> = T & {
22
+ new (): {
23
+ $slots: S;
24
+ };
25
+ };
@@ -0,0 +1,35 @@
1
+ <script setup>
2
+ import { ToolbarRoot } from "reka-ui";
3
+ import { computed, provide } from "vue";
4
+ import { toolbarTheme } from "../theme/toolbar";
5
+ import { TOOLBAR_CONTEXT } from "../utils/toolbar";
6
+ import { useComponentTheme, useRootProps, useThemeProps } from "../utils/ui";
7
+ defineOptions({ inheritAttrs: false });
8
+ const props = defineProps({
9
+ orientation: { type: String, required: false, default: "horizontal" },
10
+ size: { type: String, required: false },
11
+ color: { type: null, required: false },
12
+ disabled: { type: Boolean, required: false },
13
+ loop: { type: Boolean, required: false, default: true },
14
+ dir: { type: String, required: false },
15
+ ui: { type: Object, required: false }
16
+ });
17
+ defineSlots();
18
+ const defaults = useThemeProps("toolbar");
19
+ const context = computed(() => ({
20
+ size: props.size ?? defaults.value.size ?? "sm",
21
+ color: props.color ?? defaults.value.color ?? "primary",
22
+ disabled: !!props.disabled,
23
+ orientation: props.orientation
24
+ }));
25
+ provide(TOOLBAR_CONTEXT, context);
26
+ const theme = useComponentTheme("toolbar", toolbarTheme);
27
+ const ui = computed(() => theme.value({ orientation: props.orientation }));
28
+ const rootProps = useRootProps(() => ui.value.root, () => props.ui?.root);
29
+ </script>
30
+
31
+ <template>
32
+ <ToolbarRoot :orientation="orientation" :dir="dir" :loop="loop" :aria-disabled="disabled || void 0" v-bind="rootProps">
33
+ <slot />
34
+ </ToolbarRoot>
35
+ </template>
@@ -0,0 +1,25 @@
1
+ import type { ToolbarThemeSlots } from '../theme/toolbar.js';
2
+ import type { ColorRole } from '../utils/color-registry.js';
3
+ import type { UiProp } from '../utils/ui.js';
4
+ type __VLS_Slots = ToolbarSlots;
5
+ export interface ToolbarProps {
6
+ orientation?: 'horizontal' | 'vertical';
7
+ size?: 'sm' | 'md' | 'lg';
8
+ color?: ColorRole;
9
+ disabled?: boolean;
10
+ loop?: boolean;
11
+ dir?: 'ltr' | 'rtl';
12
+ ui?: UiProp<ToolbarThemeSlots>;
13
+ }
14
+ export interface ToolbarSlots {
15
+ default?: () => any;
16
+ }
17
+ declare const __VLS_base: import("vue").DefineComponent<ToolbarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ToolbarProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
21
+ type __VLS_WithSlots<T, S> = T & {
22
+ new (): {
23
+ $slots: S;
24
+ };
25
+ };
@@ -0,0 +1,20 @@
1
+ import type { ButtonProps } from './Button.vue.js';
2
+ type __VLS_Slots = ToolbarButtonSlots;
3
+ export interface ToolbarButtonProps extends ButtonProps {
4
+ /** Formatting state owned by the editor; omitted for ordinary actions. */
5
+ pressed?: boolean;
6
+ /** Composes a custom trigger into the toolbar's keyboard navigation. */
7
+ asChild?: boolean;
8
+ }
9
+ export interface ToolbarButtonSlots {
10
+ default?: () => any;
11
+ }
12
+ declare const __VLS_base: import("vue").DefineComponent<ToolbarButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ToolbarButtonProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ type __VLS_WithSlots<T, S> = T & {
17
+ new (): {
18
+ $slots: S;
19
+ };
20
+ };
@@ -0,0 +1,46 @@
1
+ <script setup>
2
+ import { ToolbarButton } from "reka-ui";
3
+ import { computed, inject } from "vue";
4
+ import { toolbarButtonTheme } from "../theme/toolbar-button";
5
+ import { TOOLBAR_CONTEXT } from "../utils/toolbar";
6
+ import { resolveSlot, useComponentTheme, useRootProps } from "../utils/ui";
7
+ import Button from "./Button.vue";
8
+ defineOptions({ inheritAttrs: false });
9
+ const props = defineProps({
10
+ pressed: { type: Boolean, required: false, default: void 0 },
11
+ asChild: { type: Boolean, required: false },
12
+ as: { type: null, required: false },
13
+ to: { type: String, required: false },
14
+ type: { type: String, required: false },
15
+ color: { type: null, required: false },
16
+ variant: { type: null, required: false },
17
+ size: { type: null, required: false },
18
+ block: { type: Boolean, required: false },
19
+ disabled: { type: Boolean, required: false },
20
+ loading: { type: Boolean, required: false },
21
+ raised: { type: Boolean, required: false },
22
+ icon: { type: String, required: false },
23
+ trailingIcon: { type: String, required: false },
24
+ square: { type: Boolean, required: false, default: void 0 },
25
+ ui: { type: Object, required: false }
26
+ });
27
+ defineSlots();
28
+ const toolbar = inject(TOOLBAR_CONTEXT, void 0);
29
+ const disabled = computed(() => props.disabled || toolbar?.value.disabled);
30
+ const size = computed(() => props.size ?? toolbar?.value.size ?? "sm");
31
+ const color = computed(() => props.color ?? toolbar?.value.color ?? "primary");
32
+ const theme = useComponentTheme("toolbarButton", toolbarButtonTheme);
33
+ const ui = computed(() => theme.value({ size: size.value, variant: props.variant ?? "ghost" }));
34
+ const rootProps = useRootProps(() => ui.value.base, () => props.ui?.base);
35
+ </script>
36
+
37
+ <template>
38
+ <ToolbarButton as-child :disabled="disabled" :aria-pressed="pressed" :data-state="pressed === void 0 ? void 0 : pressed ? 'on' : 'off'" v-bind="rootProps">
39
+ <slot v-if="asChild" />
40
+ <Button v-else v-bind="as ? { as } : {}" :to="to" :type="type" :disabled="disabled" :size="size" :color="color" :variant="variant ?? 'ghost'" :icon="icon" :trailing-icon="trailingIcon" :square="square" :loading="loading" :raised="raised" :block="block" :ui="{ leadingIcon: resolveSlot(ui.leadingIcon, props.ui?.leadingIcon), trailingIcon: resolveSlot(ui.trailingIcon, props.ui?.trailingIcon) }">
41
+ <template v-if="$slots.default" #default>
42
+ <slot />
43
+ </template>
44
+ </Button>
45
+ </ToolbarButton>
46
+ </template>
@@ -0,0 +1,20 @@
1
+ import type { ButtonProps } from './Button.vue.js';
2
+ type __VLS_Slots = ToolbarButtonSlots;
3
+ export interface ToolbarButtonProps extends ButtonProps {
4
+ /** Formatting state owned by the editor; omitted for ordinary actions. */
5
+ pressed?: boolean;
6
+ /** Composes a custom trigger into the toolbar's keyboard navigation. */
7
+ asChild?: boolean;
8
+ }
9
+ export interface ToolbarButtonSlots {
10
+ default?: () => any;
11
+ }
12
+ declare const __VLS_base: import("vue").DefineComponent<ToolbarButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ToolbarButtonProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ type __VLS_WithSlots<T, S> = T & {
17
+ new (): {
18
+ $slots: S;
19
+ };
20
+ };
@@ -0,0 +1,10 @@
1
+ import type { ToolbarSeparatorThemeSlots } from '../theme/toolbar-separator.js';
2
+ import type { UiProp } from '../utils/ui.js';
3
+ export interface ToolbarSeparatorProps {
4
+ orientation?: 'horizontal' | 'vertical';
5
+ decorative?: boolean;
6
+ ui?: UiProp<ToolbarSeparatorThemeSlots>;
7
+ }
8
+ declare const __VLS_export: import("vue").DefineComponent<ToolbarSeparatorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ToolbarSeparatorProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,22 @@
1
+ <script setup>
2
+ import { Separator } from "reka-ui";
3
+ import { computed, inject } from "vue";
4
+ import { toolbarSeparatorTheme } from "../theme/toolbar-separator";
5
+ import { TOOLBAR_CONTEXT } from "../utils/toolbar";
6
+ import { useComponentTheme, useRootProps } from "../utils/ui";
7
+ defineOptions({ inheritAttrs: false });
8
+ const props = defineProps({
9
+ orientation: { type: String, required: false },
10
+ decorative: { type: Boolean, required: false, default: true },
11
+ ui: { type: Object, required: false }
12
+ });
13
+ const toolbar = inject(TOOLBAR_CONTEXT, void 0);
14
+ const orientation = computed(() => props.orientation ?? (toolbar?.value.orientation === "vertical" ? "horizontal" : "vertical"));
15
+ const theme = useComponentTheme("toolbarSeparator", toolbarSeparatorTheme);
16
+ const ui = computed(() => theme.value({ orientation: orientation.value }));
17
+ const rootProps = useRootProps(() => ui.value.root, () => props.ui?.root);
18
+ </script>
19
+
20
+ <template>
21
+ <Separator :orientation="orientation" :decorative="decorative" v-bind="rootProps" />
22
+ </template>
@@ -0,0 +1,10 @@
1
+ import type { ToolbarSeparatorThemeSlots } from '../theme/toolbar-separator.js';
2
+ import type { UiProp } from '../utils/ui.js';
3
+ export interface ToolbarSeparatorProps {
4
+ orientation?: 'horizontal' | 'vertical';
5
+ decorative?: boolean;
6
+ ui?: UiProp<ToolbarSeparatorThemeSlots>;
7
+ }
8
+ declare const __VLS_export: import("vue").DefineComponent<ToolbarSeparatorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ToolbarSeparatorProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -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
+ };