orio-ui 1.13.1 → 1.15.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/module.json +1 -1
- package/dist/runtime/components/Button.vue +3 -3
- package/dist/runtime/components/CheckBox.d.vue.ts +3 -2
- package/dist/runtime/components/CheckBox.vue +5 -6
- package/dist/runtime/components/CheckBox.vue.d.ts +3 -2
- package/dist/runtime/components/CheckboxGroup.d.vue.ts +35 -0
- package/dist/runtime/components/CheckboxGroup.vue +50 -0
- package/dist/runtime/components/CheckboxGroup.vue.d.ts +35 -0
- package/dist/runtime/components/ControlElement.d.vue.ts +19 -2
- package/dist/runtime/components/ControlElement.vue +67 -8
- package/dist/runtime/components/ControlElement.vue.d.ts +19 -2
- package/dist/runtime/components/Input.vue +8 -8
- package/dist/runtime/components/NavButton.vue +4 -4
- package/dist/runtime/components/NumberInput/index.vue +6 -6
- package/dist/runtime/components/RadioButton.d.vue.ts +32 -0
- package/dist/runtime/components/RadioButton.vue +100 -0
- package/dist/runtime/components/RadioButton.vue.d.ts +32 -0
- package/dist/runtime/components/Selector.vue +4 -4
- package/dist/runtime/components/SwitchButton.vue +3 -3
- package/dist/runtime/components/Textarea.vue +7 -7
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +6 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -56,13 +56,13 @@ button {
|
|
|
56
56
|
background-color: var(--color-accent);
|
|
57
57
|
color: var(--color-accent-ink);
|
|
58
58
|
border: 1px solid transparent;
|
|
59
|
-
border-radius: var(--
|
|
60
|
-
padding:
|
|
59
|
+
border-radius: var(--control-radius);
|
|
60
|
+
padding: var(--control-py) var(--control-px);
|
|
61
61
|
cursor: pointer;
|
|
62
62
|
display: inline-flex;
|
|
63
63
|
justify-content: center;
|
|
64
64
|
align-items: center;
|
|
65
|
-
gap:
|
|
65
|
+
gap: var(--control-gap);
|
|
66
66
|
user-select: none;
|
|
67
67
|
}
|
|
68
68
|
button.icon-only {
|
|
@@ -37,14 +37,14 @@ defineProps({
|
|
|
37
37
|
|
|
38
38
|
<style scoped>
|
|
39
39
|
.checkbox {
|
|
40
|
-
--box-size: 1rem;
|
|
40
|
+
--box-size: var(--control-icon-size, 1rem);
|
|
41
41
|
}
|
|
42
42
|
.checkbox-label {
|
|
43
43
|
position: relative;
|
|
44
44
|
user-select: none;
|
|
45
45
|
display: inline-flex;
|
|
46
46
|
align-items: center;
|
|
47
|
-
gap: 0.4rem;
|
|
47
|
+
gap: var(--control-gap, 0.4rem);
|
|
48
48
|
cursor: pointer;
|
|
49
49
|
color: var(--color-text);
|
|
50
50
|
}
|
|
@@ -73,10 +73,9 @@ defineProps({
|
|
|
73
73
|
}
|
|
74
74
|
.checkbox .checkbox-input:checked + .checkbox-box.defaultChecked::after {
|
|
75
75
|
content: "";
|
|
76
|
-
width: 0.
|
|
77
|
-
height: 0.
|
|
78
|
-
position:
|
|
79
|
-
bottom: 0.1rem;
|
|
76
|
+
width: calc(var(--box-size) * 0.3);
|
|
77
|
+
height: calc(var(--box-size) * 0.6);
|
|
78
|
+
position: absolute;
|
|
80
79
|
border: solid var(--color-accent-ink);
|
|
81
80
|
border-width: 0 2px 2px 0;
|
|
82
81
|
transform: rotate(45deg);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ControlProps } from "./ControlElement.vue.js";
|
|
2
|
+
export interface CheckboxOption {
|
|
3
|
+
label: string;
|
|
4
|
+
value: unknown;
|
|
5
|
+
}
|
|
6
|
+
export interface CheckboxGroupProps extends Omit<ControlProps, "appearance" | "group" | "id"> {
|
|
7
|
+
options?: CheckboxOption[];
|
|
8
|
+
}
|
|
9
|
+
type __VLS_Props = CheckboxGroupProps;
|
|
10
|
+
type __VLS_ModelProps = {
|
|
11
|
+
modelValue?: unknown[];
|
|
12
|
+
};
|
|
13
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
14
|
+
declare var __VLS_8: {};
|
|
15
|
+
type __VLS_Slots = {} & {
|
|
16
|
+
default?: (props: typeof __VLS_8) => any;
|
|
17
|
+
};
|
|
18
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
19
|
+
"update:modelValue": (value: unknown[]) => any;
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
21
|
+
"onUpdate:modelValue"?: ((value: unknown[]) => any) | undefined;
|
|
22
|
+
}>, {
|
|
23
|
+
error: string | null;
|
|
24
|
+
layout: import("./ControlElement.vue.js").ControlLayout;
|
|
25
|
+
size: import("./ControlElement.vue.js").ControlSize;
|
|
26
|
+
options: CheckboxOption[];
|
|
27
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
29
|
+
declare const _default: typeof __VLS_export;
|
|
30
|
+
export default _default;
|
|
31
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
32
|
+
new (): {
|
|
33
|
+
$slots: S;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import {} from "./ControlElement.vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
options: { type: Array, required: false, default: () => [] },
|
|
5
|
+
error: { type: [String, null], required: false, default: null },
|
|
6
|
+
label: { type: String, required: false },
|
|
7
|
+
layout: { type: String, required: false, default: "vertical" },
|
|
8
|
+
size: { type: String, required: false, default: "md" }
|
|
9
|
+
});
|
|
10
|
+
const modelValue = defineModel({ type: Array, ...{ default: () => [] } });
|
|
11
|
+
function isChecked(value) {
|
|
12
|
+
return modelValue.value.includes(value);
|
|
13
|
+
}
|
|
14
|
+
function toggle(value) {
|
|
15
|
+
if (isChecked(value)) {
|
|
16
|
+
modelValue.value = modelValue.value.filter((v) => v !== value);
|
|
17
|
+
} else {
|
|
18
|
+
modelValue.value = [...modelValue.value, value];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
<orio-control-element group :label :layout :size :error class="group-control">
|
|
25
|
+
<div class="checkboxes">
|
|
26
|
+
<slot>
|
|
27
|
+
<orio-check-box
|
|
28
|
+
v-for="option in options"
|
|
29
|
+
:key="String(option.value)"
|
|
30
|
+
appearance="minimal"
|
|
31
|
+
:model-value="isChecked(option.value)"
|
|
32
|
+
@update:model-value="toggle(option.value)"
|
|
33
|
+
>
|
|
34
|
+
{{ option.label }}
|
|
35
|
+
</orio-check-box>
|
|
36
|
+
</slot>
|
|
37
|
+
</div>
|
|
38
|
+
</orio-control-element>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<style scoped>
|
|
42
|
+
.checkboxes {
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.group-control.control.horizontal {
|
|
48
|
+
align-items: flex-start;
|
|
49
|
+
}
|
|
50
|
+
</style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ControlProps } from "./ControlElement.vue.js";
|
|
2
|
+
export interface CheckboxOption {
|
|
3
|
+
label: string;
|
|
4
|
+
value: unknown;
|
|
5
|
+
}
|
|
6
|
+
export interface CheckboxGroupProps extends Omit<ControlProps, "appearance" | "group" | "id"> {
|
|
7
|
+
options?: CheckboxOption[];
|
|
8
|
+
}
|
|
9
|
+
type __VLS_Props = CheckboxGroupProps;
|
|
10
|
+
type __VLS_ModelProps = {
|
|
11
|
+
modelValue?: unknown[];
|
|
12
|
+
};
|
|
13
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
14
|
+
declare var __VLS_8: {};
|
|
15
|
+
type __VLS_Slots = {} & {
|
|
16
|
+
default?: (props: typeof __VLS_8) => any;
|
|
17
|
+
};
|
|
18
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
19
|
+
"update:modelValue": (value: unknown[]) => any;
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
21
|
+
"onUpdate:modelValue"?: ((value: unknown[]) => any) | undefined;
|
|
22
|
+
}>, {
|
|
23
|
+
error: string | null;
|
|
24
|
+
layout: import("./ControlElement.vue.js").ControlLayout;
|
|
25
|
+
size: import("./ControlElement.vue.js").ControlSize;
|
|
26
|
+
options: CheckboxOption[];
|
|
27
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
29
|
+
declare const _default: typeof __VLS_export;
|
|
30
|
+
export default _default;
|
|
31
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
32
|
+
new (): {
|
|
33
|
+
$slots: S;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type ControlLayout = "vertical" | "horizontal";
|
|
2
|
+
export type ControlSize = "sm" | "md" | "lg" | "xl";
|
|
2
3
|
export interface ControlProps {
|
|
3
4
|
/**
|
|
4
5
|
* Minimal will reset margin and remove border and box shadow from every element inside the slot
|
|
@@ -8,26 +9,42 @@ export interface ControlProps {
|
|
|
8
9
|
* Error message to display below the control
|
|
9
10
|
*/
|
|
10
11
|
error?: string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Marks this control as a group (adds role="group" and aria-labelledby).
|
|
14
|
+
* The label renders as a <span> instead of <label>.
|
|
15
|
+
* Use for groups of related controls (e.g. CheckboxGroup).
|
|
16
|
+
*/
|
|
17
|
+
group?: boolean;
|
|
11
18
|
/**
|
|
12
19
|
* ID for the control's form element, auto-generated if not provided
|
|
13
20
|
*/
|
|
14
21
|
id?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Label text for the control (or legend text when group is true)
|
|
24
|
+
*/
|
|
25
|
+
label?: string;
|
|
15
26
|
/**
|
|
16
27
|
* Label position relative to the control
|
|
17
28
|
*/
|
|
18
29
|
layout?: ControlLayout;
|
|
30
|
+
/**
|
|
31
|
+
* Size of the control and its inner elements
|
|
32
|
+
*/
|
|
33
|
+
size?: ControlSize;
|
|
19
34
|
}
|
|
20
|
-
declare var
|
|
35
|
+
declare var __VLS_7: {
|
|
21
36
|
id: string;
|
|
22
37
|
};
|
|
23
38
|
type __VLS_Slots = {} & {
|
|
24
|
-
default?: (props: typeof
|
|
39
|
+
default?: (props: typeof __VLS_7) => any;
|
|
25
40
|
};
|
|
26
41
|
declare const __VLS_base: import("vue").DefineComponent<ControlProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ControlProps> & Readonly<{}>, {
|
|
27
42
|
appearance: "normal" | "minimal";
|
|
28
43
|
error: string | null;
|
|
44
|
+
group: boolean;
|
|
29
45
|
id: string;
|
|
30
46
|
layout: ControlLayout;
|
|
47
|
+
size: ControlSize;
|
|
31
48
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
32
49
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
33
50
|
declare const _default: typeof __VLS_export;
|
|
@@ -3,16 +3,28 @@ import { useId } from "vue";
|
|
|
3
3
|
const props = defineProps({
|
|
4
4
|
appearance: { type: String, required: false, default: "normal" },
|
|
5
5
|
error: { type: [String, null], required: false, default: null },
|
|
6
|
+
group: { type: Boolean, required: false, default: false },
|
|
6
7
|
id: { type: String, required: false, default: () => useId() },
|
|
7
|
-
|
|
8
|
+
label: { type: String, required: false },
|
|
9
|
+
layout: { type: String, required: false, default: "vertical" },
|
|
10
|
+
size: { type: String, required: false, default: "md" }
|
|
8
11
|
});
|
|
9
12
|
</script>
|
|
10
13
|
|
|
11
14
|
<template>
|
|
12
|
-
<div
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
<div
|
|
16
|
+
class="control"
|
|
17
|
+
:class="[appearance, layout, `size-${size}`, { 'has-error': error, group }]"
|
|
18
|
+
v-bind="group ? { role: 'group', 'aria-labelledby': id } : {}"
|
|
19
|
+
>
|
|
20
|
+
<component
|
|
21
|
+
:is="group ? 'span' : 'label'"
|
|
22
|
+
v-if="label"
|
|
23
|
+
class="control-label"
|
|
24
|
+
v-bind="group ? { id } : { for: id }"
|
|
25
|
+
>
|
|
26
|
+
{{ label }}
|
|
27
|
+
</component>
|
|
16
28
|
<div class="control-group">
|
|
17
29
|
<div class="slot-wrapper" v-bind="$attrs">
|
|
18
30
|
<slot :id />
|
|
@@ -23,6 +35,50 @@ const props = defineProps({
|
|
|
23
35
|
</template>
|
|
24
36
|
|
|
25
37
|
<style scoped>
|
|
38
|
+
.control {
|
|
39
|
+
--control-font-size: var(--font-md);
|
|
40
|
+
--control-py: 0.5rem;
|
|
41
|
+
--control-px: 0.75rem;
|
|
42
|
+
--control-gap: 0.5rem;
|
|
43
|
+
--control-radius: var(--border-radius-md);
|
|
44
|
+
--control-icon-size: 1rem;
|
|
45
|
+
--control-inner-block-start: 1.25rem;
|
|
46
|
+
--control-inner-block-end: 0.25rem;
|
|
47
|
+
--control-label-block-start: 0.25rem;
|
|
48
|
+
}
|
|
49
|
+
.control.size-sm {
|
|
50
|
+
--control-font-size: var(--font-sm);
|
|
51
|
+
--control-py: 0.25rem;
|
|
52
|
+
--control-px: 0.5rem;
|
|
53
|
+
--control-gap: 0.25rem;
|
|
54
|
+
--control-radius: var(--border-radius-sm);
|
|
55
|
+
--control-icon-size: 0.75rem;
|
|
56
|
+
--control-inner-block-start: 1rem;
|
|
57
|
+
--control-inner-block-end: 0.15rem;
|
|
58
|
+
--control-label-block-start: 0.2rem;
|
|
59
|
+
}
|
|
60
|
+
.control.size-lg {
|
|
61
|
+
--control-font-size: var(--font-lg);
|
|
62
|
+
--control-py: 0.625rem;
|
|
63
|
+
--control-px: 1rem;
|
|
64
|
+
--control-gap: 0.5rem;
|
|
65
|
+
--control-radius: var(--border-radius-md);
|
|
66
|
+
--control-icon-size: 1.25rem;
|
|
67
|
+
--control-inner-block-start: 1.75rem;
|
|
68
|
+
--control-inner-block-end: 0.25rem;
|
|
69
|
+
--control-label-block-start: 0.25rem;
|
|
70
|
+
}
|
|
71
|
+
.control.size-xl {
|
|
72
|
+
--control-font-size: var(--font-xl);
|
|
73
|
+
--control-py: 0.75rem;
|
|
74
|
+
--control-px: 1.25rem;
|
|
75
|
+
--control-gap: 0.75rem;
|
|
76
|
+
--control-radius: var(--border-radius-lg);
|
|
77
|
+
--control-icon-size: 1.5rem;
|
|
78
|
+
--control-inner-block-start: 2.25rem;
|
|
79
|
+
--control-inner-block-end: 0.375rem;
|
|
80
|
+
--control-label-block-start: 0.25rem;
|
|
81
|
+
}
|
|
26
82
|
.control {
|
|
27
83
|
margin: 0.5rem;
|
|
28
84
|
display: flex;
|
|
@@ -30,7 +86,7 @@ const props = defineProps({
|
|
|
30
86
|
gap: 0.1rem;
|
|
31
87
|
}
|
|
32
88
|
.control .control-label {
|
|
33
|
-
font-size: var(--font-
|
|
89
|
+
font-size: var(--control-font-size);
|
|
34
90
|
user-select: none;
|
|
35
91
|
}
|
|
36
92
|
.control .control-group {
|
|
@@ -38,11 +94,14 @@ const props = defineProps({
|
|
|
38
94
|
}
|
|
39
95
|
.control .control-error {
|
|
40
96
|
color: var(--color-danger);
|
|
41
|
-
font-size: var(--font-
|
|
97
|
+
font-size: var(--control-font-size);
|
|
98
|
+
}
|
|
99
|
+
.control .slot-wrapper :deep(*) {
|
|
100
|
+
font-size: var(--control-font-size);
|
|
42
101
|
}
|
|
43
102
|
.control.has-error .slot-wrapper :deep(*) {
|
|
44
103
|
border-color: var(--color-danger);
|
|
45
|
-
font-size: var(--font-
|
|
104
|
+
font-size: var(--control-font-size);
|
|
46
105
|
}
|
|
47
106
|
.control.minimal {
|
|
48
107
|
margin: 0;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type ControlLayout = "vertical" | "horizontal";
|
|
2
|
+
export type ControlSize = "sm" | "md" | "lg" | "xl";
|
|
2
3
|
export interface ControlProps {
|
|
3
4
|
/**
|
|
4
5
|
* Minimal will reset margin and remove border and box shadow from every element inside the slot
|
|
@@ -8,26 +9,42 @@ export interface ControlProps {
|
|
|
8
9
|
* Error message to display below the control
|
|
9
10
|
*/
|
|
10
11
|
error?: string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Marks this control as a group (adds role="group" and aria-labelledby).
|
|
14
|
+
* The label renders as a <span> instead of <label>.
|
|
15
|
+
* Use for groups of related controls (e.g. CheckboxGroup).
|
|
16
|
+
*/
|
|
17
|
+
group?: boolean;
|
|
11
18
|
/**
|
|
12
19
|
* ID for the control's form element, auto-generated if not provided
|
|
13
20
|
*/
|
|
14
21
|
id?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Label text for the control (or legend text when group is true)
|
|
24
|
+
*/
|
|
25
|
+
label?: string;
|
|
15
26
|
/**
|
|
16
27
|
* Label position relative to the control
|
|
17
28
|
*/
|
|
18
29
|
layout?: ControlLayout;
|
|
30
|
+
/**
|
|
31
|
+
* Size of the control and its inner elements
|
|
32
|
+
*/
|
|
33
|
+
size?: ControlSize;
|
|
19
34
|
}
|
|
20
|
-
declare var
|
|
35
|
+
declare var __VLS_7: {
|
|
21
36
|
id: string;
|
|
22
37
|
};
|
|
23
38
|
type __VLS_Slots = {} & {
|
|
24
|
-
default?: (props: typeof
|
|
39
|
+
default?: (props: typeof __VLS_7) => any;
|
|
25
40
|
};
|
|
26
41
|
declare const __VLS_base: import("vue").DefineComponent<ControlProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ControlProps> & Readonly<{}>, {
|
|
27
42
|
appearance: "normal" | "minimal";
|
|
28
43
|
error: string | null;
|
|
44
|
+
group: boolean;
|
|
29
45
|
id: string;
|
|
30
46
|
layout: ControlLayout;
|
|
47
|
+
size: ControlSize;
|
|
31
48
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
32
49
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
33
50
|
declare const _default: typeof __VLS_export;
|
|
@@ -21,7 +21,7 @@ const modelValue = defineModel({ type: String, ...{ default: "" } });
|
|
|
21
21
|
<style scoped>
|
|
22
22
|
:deep(.slot-wrapper) {
|
|
23
23
|
border: 1px solid var(--color-border);
|
|
24
|
-
border-radius: var(--
|
|
24
|
+
border-radius: var(--control-radius);
|
|
25
25
|
background-color: var(--color-bg);
|
|
26
26
|
transition: border-color 0.2s ease;
|
|
27
27
|
}
|
|
@@ -39,15 +39,15 @@ const modelValue = defineModel({ type: String, ...{ default: "" } });
|
|
|
39
39
|
:deep(.slot-wrapper) {
|
|
40
40
|
display: flex;
|
|
41
41
|
align-items: center;
|
|
42
|
-
gap:
|
|
43
|
-
padding: 0
|
|
42
|
+
gap: var(--control-gap);
|
|
43
|
+
padding: 0 var(--control-px);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
input {
|
|
47
47
|
border: 0;
|
|
48
48
|
background: transparent;
|
|
49
49
|
outline: none;
|
|
50
|
-
font-size: var(--font-
|
|
50
|
+
font-size: var(--control-font-size);
|
|
51
51
|
color: var(--color-text);
|
|
52
52
|
}
|
|
53
53
|
input::placeholder {
|
|
@@ -57,7 +57,7 @@ input::placeholder {
|
|
|
57
57
|
input {
|
|
58
58
|
flex: 1;
|
|
59
59
|
min-width: 0;
|
|
60
|
-
padding:
|
|
60
|
+
padding: var(--control-py) 0;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
.inner {
|
|
@@ -67,11 +67,11 @@ input {
|
|
|
67
67
|
position: absolute;
|
|
68
68
|
z-index: 1;
|
|
69
69
|
pointer-events: none;
|
|
70
|
-
left:
|
|
71
|
-
top:
|
|
70
|
+
left: var(--control-px);
|
|
71
|
+
top: var(--control-label-block-start);
|
|
72
72
|
color: var(--color-muted);
|
|
73
73
|
}
|
|
74
74
|
.inner input {
|
|
75
|
-
padding:
|
|
75
|
+
padding: var(--control-inner-block-start) 0 var(--control-inner-block-end);
|
|
76
76
|
}
|
|
77
77
|
</style>
|
|
@@ -42,17 +42,17 @@ button {
|
|
|
42
42
|
background-color: transparent;
|
|
43
43
|
color: var(--color-text);
|
|
44
44
|
border: none;
|
|
45
|
-
border-radius: var(--
|
|
46
|
-
padding:
|
|
45
|
+
border-radius: var(--control-radius);
|
|
46
|
+
padding: var(--control-py) var(--control-px);
|
|
47
47
|
cursor: pointer;
|
|
48
48
|
display: inline-flex;
|
|
49
49
|
align-items: center;
|
|
50
|
-
gap:
|
|
50
|
+
gap: var(--control-gap);
|
|
51
51
|
user-select: none;
|
|
52
52
|
transition: color 0.2s ease;
|
|
53
53
|
}
|
|
54
54
|
button.icon-only {
|
|
55
|
-
padding:
|
|
55
|
+
padding: var(--control-py);
|
|
56
56
|
border-radius: 50%;
|
|
57
57
|
aspect-ratio: 1;
|
|
58
58
|
justify-content: center;
|
|
@@ -85,10 +85,10 @@ input[type=number] {
|
|
|
85
85
|
|
|
86
86
|
.number-input {
|
|
87
87
|
width: 100%;
|
|
88
|
-
padding:
|
|
88
|
+
padding: var(--control-py) var(--control-px);
|
|
89
89
|
border: 1px solid var(--color-border);
|
|
90
|
-
border-radius: var(--
|
|
91
|
-
font-size: var(--font-
|
|
90
|
+
border-radius: var(--control-radius);
|
|
91
|
+
font-size: var(--control-font-size);
|
|
92
92
|
color: var(--color-text);
|
|
93
93
|
background-color: var(--color-bg);
|
|
94
94
|
box-sizing: border-box;
|
|
@@ -118,12 +118,12 @@ input[type=number] {
|
|
|
118
118
|
position: absolute;
|
|
119
119
|
z-index: 1;
|
|
120
120
|
pointer-events: none;
|
|
121
|
-
left:
|
|
122
|
-
top:
|
|
121
|
+
left: var(--control-px);
|
|
122
|
+
top: var(--control-label-block-start);
|
|
123
123
|
color: var(--color-muted);
|
|
124
124
|
}
|
|
125
125
|
.inner .number-input {
|
|
126
|
-
padding:
|
|
126
|
+
padding: var(--control-inner-block-start) var(--control-px) var(--control-inner-block-end);
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
.controls {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface RadioButtonProps {
|
|
2
|
+
/** The value this radio represents; compared to v-model to determine checked state */
|
|
3
|
+
value?: unknown;
|
|
4
|
+
/** HTML name attribute — groups radios together so only one is selected at a time */
|
|
5
|
+
name?: string;
|
|
6
|
+
/** Inline label text (alternative to default slot) */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** Visually hides the label while keeping it accessible to SR (screen readers) */
|
|
9
|
+
hideLabel?: boolean;
|
|
10
|
+
}
|
|
11
|
+
type __VLS_Props = RadioButtonProps;
|
|
12
|
+
type __VLS_ModelProps = {
|
|
13
|
+
modelValue?: unknown;
|
|
14
|
+
};
|
|
15
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
16
|
+
declare var __VLS_8: {};
|
|
17
|
+
type __VLS_Slots = {} & {
|
|
18
|
+
default?: (props: typeof __VLS_8) => any;
|
|
19
|
+
};
|
|
20
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
21
|
+
"update:modelValue": (value: unknown) => any;
|
|
22
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
23
|
+
"onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
|
|
24
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
26
|
+
declare const _default: typeof __VLS_export;
|
|
27
|
+
export default _default;
|
|
28
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
29
|
+
new (): {
|
|
30
|
+
$slots: S;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const modelValue = defineModel({ type: null });
|
|
3
|
+
defineProps({
|
|
4
|
+
value: { type: null, required: false },
|
|
5
|
+
name: { type: String, required: false },
|
|
6
|
+
label: { type: String, required: false },
|
|
7
|
+
hideLabel: { type: Boolean, required: false }
|
|
8
|
+
});
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<orio-control-element class="radio">
|
|
13
|
+
<label class="radio-label">
|
|
14
|
+
<input
|
|
15
|
+
v-model="modelValue"
|
|
16
|
+
type="radio"
|
|
17
|
+
:name="name"
|
|
18
|
+
:value="value"
|
|
19
|
+
class="radio-input"
|
|
20
|
+
tabindex="-1"
|
|
21
|
+
/>
|
|
22
|
+
<span class="radio-box" />
|
|
23
|
+
<span
|
|
24
|
+
v-if="label || $slots.default"
|
|
25
|
+
class="radio-text"
|
|
26
|
+
:class="{ 'sr-only': hideLabel }"
|
|
27
|
+
>
|
|
28
|
+
<slot>{{ label }}</slot>
|
|
29
|
+
</span>
|
|
30
|
+
</label>
|
|
31
|
+
</orio-control-element>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<style scoped>
|
|
35
|
+
.radio {
|
|
36
|
+
--box-size: var(--control-icon-size, 1rem);
|
|
37
|
+
}
|
|
38
|
+
.radio-label {
|
|
39
|
+
position: relative;
|
|
40
|
+
user-select: none;
|
|
41
|
+
display: inline-flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
gap: var(--control-gap, 0.4rem);
|
|
44
|
+
color: var(--color-text);
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
}
|
|
47
|
+
.radio-input {
|
|
48
|
+
position: absolute;
|
|
49
|
+
inset: 0;
|
|
50
|
+
width: var(--box-size);
|
|
51
|
+
height: 1rem;
|
|
52
|
+
margin: 0;
|
|
53
|
+
opacity: 0;
|
|
54
|
+
cursor: pointer;
|
|
55
|
+
}
|
|
56
|
+
.radio-box {
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
flex-shrink: 0;
|
|
59
|
+
width: var(--box-size);
|
|
60
|
+
height: var(--box-size);
|
|
61
|
+
border: 2px solid var(--color-border);
|
|
62
|
+
border-radius: var(--border-radius-pill);
|
|
63
|
+
background-color: var(--color-bg);
|
|
64
|
+
display: inline-flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: center;
|
|
67
|
+
transition: background-color 0.2s ease, border-color 0.2s ease;
|
|
68
|
+
}
|
|
69
|
+
.radio .radio-input:checked + .radio-box {
|
|
70
|
+
background-color: var(--color-accent);
|
|
71
|
+
border-color: var(--color-accent);
|
|
72
|
+
}
|
|
73
|
+
.radio .radio-input:checked + .radio-box::after {
|
|
74
|
+
position: absolute;
|
|
75
|
+
content: "";
|
|
76
|
+
width: calc(var(--box-size) * 0.4);
|
|
77
|
+
height: calc(var(--box-size) * 0.4);
|
|
78
|
+
border-radius: var(--border-radius-pill);
|
|
79
|
+
background-color: var(--color-accent-ink);
|
|
80
|
+
}
|
|
81
|
+
.radio-label:hover .radio-box {
|
|
82
|
+
border-color: var(--color-accent);
|
|
83
|
+
}
|
|
84
|
+
.radio .radio-input:focus-visible + .radio-box {
|
|
85
|
+
outline: 2px solid var(--color-accent);
|
|
86
|
+
outline-offset: 2px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.sr-only {
|
|
90
|
+
position: absolute;
|
|
91
|
+
width: 1px;
|
|
92
|
+
height: 1px;
|
|
93
|
+
padding: 0;
|
|
94
|
+
margin: -1px;
|
|
95
|
+
overflow: hidden;
|
|
96
|
+
clip: rect(0, 0, 0, 0);
|
|
97
|
+
white-space: nowrap;
|
|
98
|
+
border-width: 0;
|
|
99
|
+
}
|
|
100
|
+
</style>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface RadioButtonProps {
|
|
2
|
+
/** The value this radio represents; compared to v-model to determine checked state */
|
|
3
|
+
value?: unknown;
|
|
4
|
+
/** HTML name attribute — groups radios together so only one is selected at a time */
|
|
5
|
+
name?: string;
|
|
6
|
+
/** Inline label text (alternative to default slot) */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** Visually hides the label while keeping it accessible to SR (screen readers) */
|
|
9
|
+
hideLabel?: boolean;
|
|
10
|
+
}
|
|
11
|
+
type __VLS_Props = RadioButtonProps;
|
|
12
|
+
type __VLS_ModelProps = {
|
|
13
|
+
modelValue?: unknown;
|
|
14
|
+
};
|
|
15
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
16
|
+
declare var __VLS_8: {};
|
|
17
|
+
type __VLS_Slots = {} & {
|
|
18
|
+
default?: (props: typeof __VLS_8) => any;
|
|
19
|
+
};
|
|
20
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
21
|
+
"update:modelValue": (value: unknown) => any;
|
|
22
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
23
|
+
"onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
|
|
24
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
26
|
+
declare const _default: typeof __VLS_export;
|
|
27
|
+
export default _default;
|
|
28
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
29
|
+
new (): {
|
|
30
|
+
$slots: S;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -136,8 +136,8 @@ const selectorAttrs = computed(() => ({ getOptionKey, getOptionLabel }));
|
|
|
136
136
|
cursor: pointer;
|
|
137
137
|
background: var(--color-bg);
|
|
138
138
|
border: 1px solid var(--color-border);
|
|
139
|
-
border-radius: var(--
|
|
140
|
-
padding:
|
|
139
|
+
border-radius: var(--control-radius);
|
|
140
|
+
padding: var(--control-py) var(--control-px);
|
|
141
141
|
color: var(--color-text);
|
|
142
142
|
transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
|
|
143
143
|
}
|
|
@@ -163,7 +163,7 @@ const selectorAttrs = computed(() => ({ getOptionKey, getOptionLabel }));
|
|
|
163
163
|
overflow: auto;
|
|
164
164
|
background: var(--color-bg);
|
|
165
165
|
border: 1px solid var(--color-border);
|
|
166
|
-
border-radius: var(--
|
|
166
|
+
border-radius: var(--control-radius);
|
|
167
167
|
margin-top: 0.25rem;
|
|
168
168
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
|
169
169
|
}
|
|
@@ -173,7 +173,7 @@ const selectorAttrs = computed(() => ({ getOptionKey, getOptionLabel }));
|
|
|
173
173
|
margin: 0;
|
|
174
174
|
}
|
|
175
175
|
.selector-content ul li {
|
|
176
|
-
padding:
|
|
176
|
+
padding: var(--control-py) var(--control-px);
|
|
177
177
|
cursor: pointer;
|
|
178
178
|
transition: background-color 0.15s ease, color 0.15s ease;
|
|
179
179
|
color: var(--color-text);
|
|
@@ -30,12 +30,12 @@ function toggle() {
|
|
|
30
30
|
display: inline-flex;
|
|
31
31
|
align-items: center;
|
|
32
32
|
justify-content: center;
|
|
33
|
-
gap:
|
|
34
|
-
border-radius: var(--
|
|
33
|
+
gap: var(--control-gap);
|
|
34
|
+
border-radius: var(--control-radius);
|
|
35
35
|
background-color: var(--color-surface);
|
|
36
36
|
color: var(--color-muted);
|
|
37
37
|
border: 1px solid var(--color-border);
|
|
38
|
-
padding:
|
|
38
|
+
padding: var(--control-py) var(--control-px);
|
|
39
39
|
cursor: pointer;
|
|
40
40
|
user-select: none;
|
|
41
41
|
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
|
|
@@ -23,12 +23,12 @@ defineProps({
|
|
|
23
23
|
align-items: flex-start;
|
|
24
24
|
}
|
|
25
25
|
.control.horizontal :deep(.control-label) {
|
|
26
|
-
padding-top:
|
|
26
|
+
padding-top: var(--control-py);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
:deep(.slot-wrapper) {
|
|
30
30
|
border: 1px solid var(--color-border);
|
|
31
|
-
border-radius: var(--
|
|
31
|
+
border-radius: var(--control-radius);
|
|
32
32
|
background-color: var(--color-bg);
|
|
33
33
|
transition: border-color 0.2s ease;
|
|
34
34
|
}
|
|
@@ -48,7 +48,7 @@ textarea {
|
|
|
48
48
|
border: 0;
|
|
49
49
|
background: transparent;
|
|
50
50
|
outline: none;
|
|
51
|
-
font-size: var(--font-
|
|
51
|
+
font-size: var(--control-font-size);
|
|
52
52
|
color: var(--color-text);
|
|
53
53
|
}
|
|
54
54
|
textarea::placeholder {
|
|
@@ -57,7 +57,7 @@ textarea::placeholder {
|
|
|
57
57
|
}
|
|
58
58
|
textarea {
|
|
59
59
|
width: 100%;
|
|
60
|
-
padding:
|
|
60
|
+
padding: var(--control-py) var(--control-px);
|
|
61
61
|
resize: vertical;
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -68,11 +68,11 @@ textarea {
|
|
|
68
68
|
position: absolute;
|
|
69
69
|
z-index: 1;
|
|
70
70
|
pointer-events: none;
|
|
71
|
-
left:
|
|
72
|
-
top:
|
|
71
|
+
left: var(--control-px);
|
|
72
|
+
top: var(--control-label-block-start);
|
|
73
73
|
color: var(--color-muted);
|
|
74
74
|
}
|
|
75
75
|
.inner textarea {
|
|
76
|
-
padding:
|
|
76
|
+
padding: var(--control-inner-block-start) var(--control-px) var(--control-inner-block-end);
|
|
77
77
|
}
|
|
78
78
|
</style>
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export { default as NumberInputVertical } from "./components/NumberInput/Vertica
|
|
|
7
7
|
export { default as NumberInputHorizontal } from "./components/NumberInput/Horizontal.vue.js";
|
|
8
8
|
export { default as Textarea } from "./components/Textarea.vue.js";
|
|
9
9
|
export { default as CheckBox } from "./components/CheckBox.vue.js";
|
|
10
|
+
export { default as CheckboxGroup, type CheckboxOption, type CheckboxGroupProps, } from "./components/CheckboxGroup.vue.js";
|
|
11
|
+
export { default as RadioButton, type RadioButtonProps, } from "./components/RadioButton.vue.js";
|
|
10
12
|
export { default as SwitchButton } from "./components/SwitchButton.vue.js";
|
|
11
13
|
export { default as DatePicker } from "./components/DatePicker.vue.js";
|
|
12
14
|
export { default as DateRangePicker } from "./components/DateRangePicker.vue.js";
|
package/dist/runtime/index.js
CHANGED
|
@@ -7,6 +7,12 @@ export { default as NumberInputVertical } from "./components/NumberInput/Vertica
|
|
|
7
7
|
export { default as NumberInputHorizontal } from "./components/NumberInput/Horizontal.vue";
|
|
8
8
|
export { default as Textarea } from "./components/Textarea.vue";
|
|
9
9
|
export { default as CheckBox } from "./components/CheckBox.vue";
|
|
10
|
+
export {
|
|
11
|
+
default as CheckboxGroup
|
|
12
|
+
} from "./components/CheckboxGroup.vue";
|
|
13
|
+
export {
|
|
14
|
+
default as RadioButton
|
|
15
|
+
} from "./components/RadioButton.vue";
|
|
10
16
|
export { default as SwitchButton } from "./components/SwitchButton.vue";
|
|
11
17
|
export { default as DatePicker } from "./components/DatePicker.vue";
|
|
12
18
|
export { default as DateRangePicker } from "./components/DateRangePicker.vue";
|