orio-ui 1.12.1 → 1.13.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/assets/css/main.css +1 -1
- package/dist/runtime/assets/css/variables.css +1 -1
- package/dist/runtime/components/Badge.vue +1 -1
- package/dist/runtime/components/Button.vue +0 -2
- package/dist/runtime/components/CheckBox.vue +0 -1
- package/dist/runtime/components/ControlElement.d.vue.ts +14 -1
- package/dist/runtime/components/ControlElement.vue +28 -9
- package/dist/runtime/components/ControlElement.vue.d.ts +14 -1
- package/dist/runtime/components/DatePicker.vue +4 -6
- package/dist/runtime/components/DateRangePicker.vue +9 -17
- package/dist/runtime/components/Input.d.vue.ts +24 -3
- package/dist/runtime/components/Input.vue +55 -22
- package/dist/runtime/components/Input.vue.d.ts +24 -3
- package/dist/runtime/components/NavButton.vue +0 -2
- package/dist/runtime/components/NumberInput/Horizontal.d.vue.ts +3 -8
- package/dist/runtime/components/NumberInput/Horizontal.vue +6 -0
- package/dist/runtime/components/NumberInput/Horizontal.vue.d.ts +3 -8
- package/dist/runtime/components/NumberInput/Vertical.d.vue.ts +3 -8
- package/dist/runtime/components/NumberInput/Vertical.vue +1 -0
- package/dist/runtime/components/NumberInput/Vertical.vue.d.ts +3 -8
- package/dist/runtime/components/NumberInput/index.d.vue.ts +7 -2
- package/dist/runtime/components/NumberInput/index.vue +28 -5
- package/dist/runtime/components/NumberInput/index.vue.d.ts +7 -2
- package/dist/runtime/components/Selector.vue +0 -2
- package/dist/runtime/components/SwitchButton.vue +2 -3
- package/dist/runtime/components/Tag.vue +1 -1
- package/dist/runtime/components/Textarea.d.vue.ts +11 -6
- package/dist/runtime/components/Textarea.vue +54 -20
- package/dist/runtime/components/Textarea.vue.d.ts +11 -6
- package/dist/runtime/components/Tooltip.vue +1 -1
- package/dist/runtime/components/gallery/Carousel.d.vue.ts +4 -0
- package/dist/runtime/components/gallery/Carousel.vue +107 -37
- package/dist/runtime/components/gallery/Carousel.vue.d.ts +4 -0
- package/dist/runtime/components/view/Text.vue +4 -4
- package/package.json +1 -2
package/dist/module.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import "./colors.css";@import "./variables.css";@import "./animation.css";@import "./scroll.css";@import "./cool-gradient-hover.css";*,:after,:before{box-sizing:border-box}
|
|
1
|
+
@import "./colors.css";@import "./variables.css";@import "./animation.css";@import "./scroll.css";@import "./cool-gradient-hover.css";*,:after,:before{box-sizing:border-box;line-height:1.5}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--border-radius-sm:4px;--border-radius-md:8px;--border-radius-lg:12px;--border-radius-pill:9999px}
|
|
1
|
+
:root{--border-radius-sm:4px;--border-radius-md:8px;--border-radius-lg:12px;--border-radius-pill:9999px;--font-sm:0.75rem;--font-md:0.875rem;--font-lg:1.25rem;--font-xl:1.75rem}
|
|
@@ -23,5 +23,5 @@ const isDot = computed(() => !hasDefaultContent.value);
|
|
|
23
23
|
</template>
|
|
24
24
|
|
|
25
25
|
<style scoped>
|
|
26
|
-
.badge-wrapper{display:inline-flex;position:relative}.badge{align-items:center;border:1px solid transparent;border-radius:var(--border-radius-sm);display:inline-flex;font-size
|
|
26
|
+
.badge-wrapper{display:inline-flex;position:relative}.badge{align-items:center;border:1px solid transparent;border-radius:var(--border-radius-sm);display:inline-flex;font-size:var(--font-sm);font-weight:600;justify-content:center;padding:.125rem .5rem;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.badge.positioned{position:absolute;right:.5rem;top:.5rem;transform:translate(50%,-50%)}.badge.pill{border-radius:var(--border-radius-pill)}.badge.dot{border-radius:50%;height:.5rem;min-height:.5rem;min-width:.5rem;padding:0;width:.5rem}.badge.primary{background-color:var(--color-accent);border-color:var(--color-accent);color:var(--color-accent-ink)}.badge.danger{background-color:var(--color-danger);border-color:var(--color-danger);color:var(--color-danger-ink)}.badge.alert{background-color:var(--color-alert);border-color:var(--color-alert);color:var(--color-alert-ink)}.badge.grey{background-color:var(--color-surface);border-color:var(--color-border);color:var(--color-muted)}
|
|
27
27
|
</style>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type ControlLayout = "vertical" | "horizontal";
|
|
1
2
|
export interface ControlProps {
|
|
2
3
|
/**
|
|
3
4
|
* Minimal will reset margin and remove border and box shadow from every element inside the slot
|
|
@@ -7,14 +8,26 @@ export interface ControlProps {
|
|
|
7
8
|
* Error message to display below the control
|
|
8
9
|
*/
|
|
9
10
|
error?: string | null;
|
|
11
|
+
/**
|
|
12
|
+
* ID for the control's form element, auto-generated if not provided
|
|
13
|
+
*/
|
|
14
|
+
id?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Label position relative to the control
|
|
17
|
+
*/
|
|
18
|
+
layout?: ControlLayout;
|
|
10
19
|
}
|
|
11
|
-
declare var __VLS_1: {
|
|
20
|
+
declare var __VLS_1: {
|
|
21
|
+
id: string;
|
|
22
|
+
};
|
|
12
23
|
type __VLS_Slots = {} & {
|
|
13
24
|
default?: (props: typeof __VLS_1) => any;
|
|
14
25
|
};
|
|
15
26
|
declare const __VLS_base: import("vue").DefineComponent<ControlProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ControlProps> & Readonly<{}>, {
|
|
16
27
|
appearance: "normal" | "minimal";
|
|
17
28
|
error: string | null;
|
|
29
|
+
id: string;
|
|
30
|
+
layout: ControlLayout;
|
|
18
31
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
32
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
20
33
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
|
|
2
|
+
import { useId } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
3
4
|
appearance: { type: String, required: false, default: "normal" },
|
|
4
|
-
error: { type: [String, null], required: false, default: null }
|
|
5
|
+
error: { type: [String, null], required: false, default: null },
|
|
6
|
+
id: { type: String, required: false, default: () => useId() },
|
|
7
|
+
layout: { type: String, required: false, default: "vertical" }
|
|
5
8
|
});
|
|
6
9
|
</script>
|
|
7
10
|
|
|
8
11
|
<template>
|
|
9
|
-
<div class="control" :class="[appearance, { 'has-error': error }]">
|
|
10
|
-
<label v-if="$attrs.label" class="control-label"
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
<div class="control" :class="[appearance, layout, { 'has-error': error }]">
|
|
13
|
+
<label v-if="$attrs.label" class="control-label" :for="id">
|
|
14
|
+
{{ $attrs.label }}
|
|
15
|
+
</label>
|
|
16
|
+
<div class="control-group">
|
|
17
|
+
<div class="slot-wrapper" v-bind="$attrs">
|
|
18
|
+
<slot :id />
|
|
19
|
+
</div>
|
|
20
|
+
<span v-if="error" class="control-error">{{ error }}</span>
|
|
13
21
|
</div>
|
|
14
|
-
<span v-if="error" class="control-error">{{ error }}</span>
|
|
15
22
|
</div>
|
|
16
23
|
</template>
|
|
17
24
|
|
|
@@ -23,23 +30,35 @@ defineProps({
|
|
|
23
30
|
gap: 0.1rem;
|
|
24
31
|
}
|
|
25
32
|
.control .control-label {
|
|
33
|
+
font-size: var(--font-md);
|
|
26
34
|
user-select: none;
|
|
27
35
|
}
|
|
36
|
+
.control .control-group {
|
|
37
|
+
width: 100%;
|
|
38
|
+
}
|
|
28
39
|
.control .control-error {
|
|
29
40
|
color: var(--color-danger);
|
|
30
|
-
font-size:
|
|
41
|
+
font-size: var(--font-md);
|
|
31
42
|
}
|
|
32
43
|
.control.has-error .slot-wrapper :deep(*) {
|
|
33
44
|
border-color: var(--color-danger);
|
|
45
|
+
font-size: var(--font-md);
|
|
34
46
|
}
|
|
35
47
|
.control.minimal {
|
|
36
48
|
margin: 0;
|
|
37
49
|
}
|
|
38
50
|
.control.minimal .slot-wrapper :first-child {
|
|
39
|
-
line-height: 1.5;
|
|
40
51
|
border: 0;
|
|
41
52
|
}
|
|
42
53
|
.control.minimal .slot-wrapper :first-child:focus {
|
|
43
54
|
box-shadow: none;
|
|
44
55
|
}
|
|
56
|
+
.control.horizontal {
|
|
57
|
+
flex-direction: row;
|
|
58
|
+
align-items: center;
|
|
59
|
+
gap: 0.75rem;
|
|
60
|
+
}
|
|
61
|
+
.control.horizontal .control-label {
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
}
|
|
45
64
|
</style>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type ControlLayout = "vertical" | "horizontal";
|
|
1
2
|
export interface ControlProps {
|
|
2
3
|
/**
|
|
3
4
|
* Minimal will reset margin and remove border and box shadow from every element inside the slot
|
|
@@ -7,14 +8,26 @@ export interface ControlProps {
|
|
|
7
8
|
* Error message to display below the control
|
|
8
9
|
*/
|
|
9
10
|
error?: string | null;
|
|
11
|
+
/**
|
|
12
|
+
* ID for the control's form element, auto-generated if not provided
|
|
13
|
+
*/
|
|
14
|
+
id?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Label position relative to the control
|
|
17
|
+
*/
|
|
18
|
+
layout?: ControlLayout;
|
|
10
19
|
}
|
|
11
|
-
declare var __VLS_1: {
|
|
20
|
+
declare var __VLS_1: {
|
|
21
|
+
id: string;
|
|
22
|
+
};
|
|
12
23
|
type __VLS_Slots = {} & {
|
|
13
24
|
default?: (props: typeof __VLS_1) => any;
|
|
14
25
|
};
|
|
15
26
|
declare const __VLS_base: import("vue").DefineComponent<ControlProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ControlProps> & Readonly<{}>, {
|
|
16
27
|
appearance: "normal" | "minimal";
|
|
17
28
|
error: string | null;
|
|
29
|
+
id: string;
|
|
30
|
+
layout: ControlLayout;
|
|
18
31
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
32
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
20
33
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed } from "vue";
|
|
3
|
-
import { nanoid } from "nanoid";
|
|
4
2
|
defineProps({
|
|
5
3
|
month: { type: Boolean, required: false }
|
|
6
4
|
});
|
|
7
5
|
const date = defineModel("date", { type: null, ...{
|
|
8
6
|
required: true
|
|
9
7
|
} });
|
|
10
|
-
const randomName = computed(() => `date-${nanoid(8)}`);
|
|
11
8
|
</script>
|
|
12
9
|
|
|
13
10
|
<template>
|
|
14
|
-
<orio-control-element class="date-picker" v-bind="$attrs">
|
|
11
|
+
<orio-control-element v-slot="{ id }" class="date-picker" v-bind="$attrs">
|
|
15
12
|
<input
|
|
13
|
+
:id
|
|
16
14
|
v-model="date"
|
|
17
15
|
:type="month ? 'month' : 'date'"
|
|
18
16
|
class="date-input"
|
|
19
|
-
:name="
|
|
17
|
+
:name="id"
|
|
20
18
|
/>
|
|
21
19
|
</orio-control-element>
|
|
22
20
|
</template>
|
|
23
21
|
|
|
24
22
|
<style scoped>
|
|
25
|
-
.date-picker *{cursor:pointer;width:100%}.date-
|
|
23
|
+
.date-picker *{cursor:pointer;width:100%}.date-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--border-radius-md);box-sizing:border-box;color:var(--color-text);padding:.4rem .6rem;transition:border-color .2s ease}.date-input:focus,.date-input:hover{border-color:var(--color-accent)}.date-input:focus{outline:none}.date-input:disabled{background-color:var(--color-surface);color:var(--color-muted);cursor:not-allowed}.date-input::-webkit-calendar-picker-indicator{cursor:pointer;filter:invert(36%) sepia(65%) saturate(325%) hue-rotate(180deg);opacity:.7;-webkit-transition:opacity .2s ease;transition:opacity .2s ease}.date-input::-webkit-calendar-picker-indicator:hover{opacity:1}
|
|
26
24
|
</style>
|
|
@@ -22,18 +22,16 @@ defineExpose({ dateIsCorrect });
|
|
|
22
22
|
</script>
|
|
23
23
|
|
|
24
24
|
<template>
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<div v-if="!dateIsCorrect" class="error-message">
|
|
34
|
-
<p>Start date must be before end date.</p>
|
|
25
|
+
<orio-control-element
|
|
26
|
+
v-bind="$attrs"
|
|
27
|
+
:error="!dateIsCorrect && 'Start date must be before end date.'"
|
|
28
|
+
>
|
|
29
|
+
<div class="date-range-picker">
|
|
30
|
+
<orio-date-picker v-model:date="dates.startDate" :month />
|
|
31
|
+
<orio-date-picker v-model:date="dates.endDate" :month />
|
|
32
|
+
<orio-check-box v-model="present"> Present </orio-check-box>
|
|
35
33
|
</div>
|
|
36
|
-
</
|
|
34
|
+
</orio-control-element>
|
|
37
35
|
</template>
|
|
38
36
|
|
|
39
37
|
<style scoped>
|
|
@@ -54,10 +52,4 @@ defineExpose({ dateIsCorrect });
|
|
|
54
52
|
.date-range-picker .checkbox {
|
|
55
53
|
margin-inline-start: 0.25rem;
|
|
56
54
|
}
|
|
57
|
-
|
|
58
|
-
.error-message {
|
|
59
|
-
color: red;
|
|
60
|
-
font-size: 0.875rem;
|
|
61
|
-
margin-top: 0.5rem;
|
|
62
|
-
}
|
|
63
55
|
</style>
|
|
@@ -1,10 +1,31 @@
|
|
|
1
|
+
import type { ControlLayout } from "./ControlElement.vue.js";
|
|
2
|
+
export type InputLayout = ControlLayout | "inner";
|
|
3
|
+
interface Props {
|
|
4
|
+
layout?: InputLayout;
|
|
5
|
+
}
|
|
6
|
+
type __VLS_Props = Props;
|
|
1
7
|
type __VLS_ModelProps = {
|
|
2
8
|
modelValue?: string;
|
|
3
9
|
};
|
|
4
|
-
|
|
10
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
11
|
+
declare var __VLS_8: {}, __VLS_10: {};
|
|
12
|
+
type __VLS_Slots = {} & {
|
|
13
|
+
before?: (props: typeof __VLS_8) => any;
|
|
14
|
+
} & {
|
|
15
|
+
after?: (props: typeof __VLS_10) => any;
|
|
16
|
+
};
|
|
17
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
18
|
"update:modelValue": (value: string) => any;
|
|
6
|
-
}, string, import("vue").PublicProps, Readonly<
|
|
19
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
7
20
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
8
|
-
}>, {
|
|
21
|
+
}>, {
|
|
22
|
+
layout: InputLayout;
|
|
23
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
9
25
|
declare const _default: typeof __VLS_export;
|
|
10
26
|
export default _default;
|
|
27
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
28
|
+
new (): {
|
|
29
|
+
$slots: S;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -1,44 +1,77 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
+
defineProps({
|
|
3
|
+
layout: { type: String, required: false, default: "vertical" }
|
|
4
|
+
});
|
|
2
5
|
const modelValue = defineModel({ type: String, ...{ default: "" } });
|
|
3
6
|
</script>
|
|
4
7
|
|
|
5
8
|
<template>
|
|
6
|
-
<orio-control-element
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/>
|
|
9
|
+
<orio-control-element
|
|
10
|
+
v-slot="{ id }"
|
|
11
|
+
v-bind="$attrs"
|
|
12
|
+
:layout="layout === 'inner' ? 'vertical' : layout"
|
|
13
|
+
:class="{ inner: layout === 'inner' }"
|
|
14
|
+
>
|
|
15
|
+
<slot name="before" />
|
|
16
|
+
<input v-bind="$attrs" :id v-model="modelValue" type="text" />
|
|
17
|
+
<slot name="after" />
|
|
13
18
|
</orio-control-element>
|
|
14
19
|
</template>
|
|
15
20
|
|
|
16
21
|
<style scoped>
|
|
17
|
-
.
|
|
18
|
-
width: 100%;
|
|
19
|
-
padding: 0.5rem 0.75rem;
|
|
22
|
+
:deep(.slot-wrapper) {
|
|
20
23
|
border: 1px solid var(--color-border);
|
|
21
24
|
border-radius: var(--border-radius-md);
|
|
22
|
-
font-size: 1rem;
|
|
23
|
-
line-height: 1.5;
|
|
24
|
-
color: var(--color-text);
|
|
25
25
|
background-color: var(--color-bg);
|
|
26
|
-
|
|
27
|
-
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
|
28
|
-
}
|
|
29
|
-
.text-input::placeholder {
|
|
30
|
-
color: var(--color-muted);
|
|
26
|
+
transition: border-color 0.2s ease;
|
|
31
27
|
}
|
|
32
|
-
.
|
|
28
|
+
:deep(.slot-wrapper):hover {
|
|
33
29
|
border-color: var(--color-accent);
|
|
34
30
|
}
|
|
35
|
-
.
|
|
31
|
+
:deep(.slot-wrapper):focus-within {
|
|
36
32
|
border-color: var(--color-accent);
|
|
37
|
-
outline: none;
|
|
38
33
|
}
|
|
39
|
-
.
|
|
34
|
+
:deep(.slot-wrapper):has(:disabled) {
|
|
40
35
|
background-color: var(--color-surface);
|
|
41
36
|
color: var(--color-muted);
|
|
42
37
|
cursor: not-allowed;
|
|
43
38
|
}
|
|
39
|
+
:deep(.slot-wrapper) {
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
gap: 0.5rem;
|
|
43
|
+
padding: 0 0.75rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
input {
|
|
47
|
+
border: 0;
|
|
48
|
+
background: transparent;
|
|
49
|
+
outline: none;
|
|
50
|
+
font-size: var(--font-md);
|
|
51
|
+
color: var(--color-text);
|
|
52
|
+
}
|
|
53
|
+
input::placeholder {
|
|
54
|
+
color: var(--color-muted);
|
|
55
|
+
user-select: none;
|
|
56
|
+
}
|
|
57
|
+
input {
|
|
58
|
+
flex: 1;
|
|
59
|
+
min-width: 0;
|
|
60
|
+
padding: 0.5rem 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.inner {
|
|
64
|
+
position: relative;
|
|
65
|
+
}
|
|
66
|
+
.inner :deep(.control-label) {
|
|
67
|
+
position: absolute;
|
|
68
|
+
z-index: 1;
|
|
69
|
+
pointer-events: none;
|
|
70
|
+
left: 0.75rem;
|
|
71
|
+
top: 0.25rem;
|
|
72
|
+
color: var(--color-muted);
|
|
73
|
+
}
|
|
74
|
+
.inner input {
|
|
75
|
+
padding: 1.25rem 0 0.25rem;
|
|
76
|
+
}
|
|
44
77
|
</style>
|
|
@@ -1,10 +1,31 @@
|
|
|
1
|
+
import type { ControlLayout } from "./ControlElement.vue.js";
|
|
2
|
+
export type InputLayout = ControlLayout | "inner";
|
|
3
|
+
interface Props {
|
|
4
|
+
layout?: InputLayout;
|
|
5
|
+
}
|
|
6
|
+
type __VLS_Props = Props;
|
|
1
7
|
type __VLS_ModelProps = {
|
|
2
8
|
modelValue?: string;
|
|
3
9
|
};
|
|
4
|
-
|
|
10
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
11
|
+
declare var __VLS_8: {}, __VLS_10: {};
|
|
12
|
+
type __VLS_Slots = {} & {
|
|
13
|
+
before?: (props: typeof __VLS_8) => any;
|
|
14
|
+
} & {
|
|
15
|
+
after?: (props: typeof __VLS_10) => any;
|
|
16
|
+
};
|
|
17
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
18
|
"update:modelValue": (value: string) => any;
|
|
6
|
-
}, string, import("vue").PublicProps, Readonly<
|
|
19
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
7
20
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
8
|
-
}>, {
|
|
21
|
+
}>, {
|
|
22
|
+
layout: InputLayout;
|
|
23
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
9
25
|
declare const _default: typeof __VLS_export;
|
|
10
26
|
export default _default;
|
|
27
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
28
|
+
new (): {
|
|
29
|
+
$slots: S;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
max?: number;
|
|
4
|
-
step?: number;
|
|
5
|
-
decimalPlaces?: number;
|
|
6
|
-
disabled?: boolean;
|
|
7
|
-
}
|
|
8
|
-
type __VLS_Props = Props;
|
|
1
|
+
import type { NumberInputProps } from "./index.vue.js";
|
|
2
|
+
type __VLS_Props = NumberInputProps;
|
|
9
3
|
type __VLS_ModelProps = {
|
|
10
4
|
modelValue?: number;
|
|
11
5
|
};
|
|
@@ -16,6 +10,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
16
10
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
17
11
|
}>, {
|
|
18
12
|
disabled: boolean;
|
|
13
|
+
layout: import("../Input.vue.js").InputLayout;
|
|
19
14
|
step: number;
|
|
20
15
|
min: number;
|
|
21
16
|
max: number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { usePressAndHold } from "../../composables/usePressAndHold";
|
|
3
3
|
defineProps({
|
|
4
|
+
layout: { type: String, required: false, default: "vertical" },
|
|
4
5
|
min: { type: Number, required: false, default: void 0 },
|
|
5
6
|
max: { type: Number, required: false, default: void 0 },
|
|
6
7
|
step: { type: Number, required: false, default: 1 },
|
|
@@ -47,4 +48,9 @@ const { pressAndHold, stop } = usePressAndHold();
|
|
|
47
48
|
.horizontal :deep(.slot-wrapper) {
|
|
48
49
|
line-height: 0;
|
|
49
50
|
}
|
|
51
|
+
.horizontal.inner :deep(.control-label) {
|
|
52
|
+
left: 0;
|
|
53
|
+
right: 0;
|
|
54
|
+
text-align: center;
|
|
55
|
+
}
|
|
50
56
|
</style>
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
max?: number;
|
|
4
|
-
step?: number;
|
|
5
|
-
decimalPlaces?: number;
|
|
6
|
-
disabled?: boolean;
|
|
7
|
-
}
|
|
8
|
-
type __VLS_Props = Props;
|
|
1
|
+
import type { NumberInputProps } from "./index.vue.js";
|
|
2
|
+
type __VLS_Props = NumberInputProps;
|
|
9
3
|
type __VLS_ModelProps = {
|
|
10
4
|
modelValue?: number;
|
|
11
5
|
};
|
|
@@ -16,6 +10,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
16
10
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
17
11
|
}>, {
|
|
18
12
|
disabled: boolean;
|
|
13
|
+
layout: import("../Input.vue.js").InputLayout;
|
|
19
14
|
step: number;
|
|
20
15
|
min: number;
|
|
21
16
|
max: number;
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
max?: number;
|
|
4
|
-
step?: number;
|
|
5
|
-
decimalPlaces?: number;
|
|
6
|
-
disabled?: boolean;
|
|
7
|
-
}
|
|
8
|
-
type __VLS_Props = Props;
|
|
1
|
+
import type { NumberInputProps } from "./index.vue.js";
|
|
2
|
+
type __VLS_Props = NumberInputProps;
|
|
9
3
|
type __VLS_ModelProps = {
|
|
10
4
|
modelValue?: number;
|
|
11
5
|
};
|
|
@@ -16,6 +10,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
16
10
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
17
11
|
}>, {
|
|
18
12
|
disabled: boolean;
|
|
13
|
+
layout: import("../Input.vue.js").InputLayout;
|
|
19
14
|
step: number;
|
|
20
15
|
min: number;
|
|
21
16
|
max: number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { usePressAndHold } from "../../composables/usePressAndHold";
|
|
3
3
|
defineProps({
|
|
4
|
+
layout: { type: String, required: false, default: "vertical" },
|
|
4
5
|
min: { type: Number, required: false, default: void 0 },
|
|
5
6
|
max: { type: Number, required: false, default: void 0 },
|
|
6
7
|
step: { type: Number, required: false, default: 1 },
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
max?: number;
|
|
4
|
-
step?: number;
|
|
5
|
-
decimalPlaces?: number;
|
|
6
|
-
disabled?: boolean;
|
|
7
|
-
}
|
|
8
|
-
type __VLS_Props = Props;
|
|
1
|
+
import type { NumberInputProps } from "./index.vue.js";
|
|
2
|
+
type __VLS_Props = NumberInputProps;
|
|
9
3
|
type __VLS_ModelProps = {
|
|
10
4
|
modelValue?: number;
|
|
11
5
|
};
|
|
@@ -16,6 +10,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
16
10
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
17
11
|
}>, {
|
|
18
12
|
disabled: boolean;
|
|
13
|
+
layout: import("../Input.vue.js").InputLayout;
|
|
19
14
|
step: number;
|
|
20
15
|
min: number;
|
|
21
16
|
max: number;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import type { InputLayout } from "../Input.vue.js";
|
|
2
|
+
export interface NumberInputProps {
|
|
3
|
+
layout?: InputLayout;
|
|
2
4
|
min?: number;
|
|
3
5
|
max?: number;
|
|
4
6
|
step?: number;
|
|
5
7
|
decimalPlaces?: number;
|
|
8
|
+
disabled?: boolean;
|
|
6
9
|
}
|
|
7
|
-
type __VLS_Props =
|
|
10
|
+
type __VLS_Props = NumberInputProps;
|
|
8
11
|
declare function increase(): void;
|
|
9
12
|
declare function decrease(): void;
|
|
10
13
|
type __VLS_ModelProps = {
|
|
@@ -25,6 +28,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
25
28
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
26
29
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
27
30
|
}>, {
|
|
31
|
+
disabled: boolean;
|
|
32
|
+
layout: InputLayout;
|
|
28
33
|
step: number;
|
|
29
34
|
min: number;
|
|
30
35
|
max: number;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, toRefs } from "vue";
|
|
3
3
|
const props = defineProps({
|
|
4
|
+
layout: { type: String, required: false, default: "vertical" },
|
|
4
5
|
min: { type: Number, required: false, default: void 0 },
|
|
5
6
|
max: { type: Number, required: false, default: void 0 },
|
|
6
7
|
step: { type: Number, required: false, default: 1 },
|
|
7
|
-
decimalPlaces: { type: Number, required: false, default: 0 }
|
|
8
|
+
decimalPlaces: { type: Number, required: false, default: 0 },
|
|
9
|
+
disabled: { type: Boolean, required: false, default: false }
|
|
8
10
|
});
|
|
9
11
|
const { min, max, step, decimalPlaces } = toRefs(props);
|
|
10
12
|
const modelValue = defineModel({ type: Number, ...{ default: 0 } });
|
|
@@ -43,10 +45,16 @@ const slotExpose = computed(() => ({
|
|
|
43
45
|
</script>
|
|
44
46
|
|
|
45
47
|
<template>
|
|
46
|
-
<orio-control-element
|
|
48
|
+
<orio-control-element
|
|
49
|
+
v-slot="{ id }"
|
|
50
|
+
v-bind="$attrs"
|
|
51
|
+
:layout="layout === 'inner' ? 'vertical' : layout"
|
|
52
|
+
:class="{ inner: layout === 'inner' }"
|
|
53
|
+
>
|
|
47
54
|
<div class="wrapper">
|
|
48
55
|
<input
|
|
49
56
|
v-bind="$attrs"
|
|
57
|
+
:id
|
|
50
58
|
v-model="modelValue"
|
|
51
59
|
type="number"
|
|
52
60
|
class="number-input"
|
|
@@ -80,15 +88,15 @@ input[type=number] {
|
|
|
80
88
|
padding: 0.5rem 0.75rem;
|
|
81
89
|
border: 1px solid var(--color-border);
|
|
82
90
|
border-radius: var(--border-radius-md);
|
|
83
|
-
font-size:
|
|
84
|
-
line-height: 1.5;
|
|
91
|
+
font-size: var(--font-md);
|
|
85
92
|
color: var(--color-text);
|
|
86
93
|
background-color: var(--color-bg);
|
|
87
94
|
box-sizing: border-box;
|
|
88
|
-
transition: border-color 0.2s ease
|
|
95
|
+
transition: border-color 0.2s ease;
|
|
89
96
|
}
|
|
90
97
|
.number-input::placeholder {
|
|
91
98
|
color: var(--color-muted);
|
|
99
|
+
user-select: none;
|
|
92
100
|
}
|
|
93
101
|
.number-input:hover {
|
|
94
102
|
border-color: var(--color-accent);
|
|
@@ -103,6 +111,21 @@ input[type=number] {
|
|
|
103
111
|
cursor: not-allowed;
|
|
104
112
|
}
|
|
105
113
|
|
|
114
|
+
.inner {
|
|
115
|
+
position: relative;
|
|
116
|
+
}
|
|
117
|
+
.inner :deep(.control-label) {
|
|
118
|
+
position: absolute;
|
|
119
|
+
z-index: 1;
|
|
120
|
+
pointer-events: none;
|
|
121
|
+
left: 0.75rem;
|
|
122
|
+
top: 0.25rem;
|
|
123
|
+
color: var(--color-muted);
|
|
124
|
+
}
|
|
125
|
+
.inner .number-input {
|
|
126
|
+
padding: 1.25rem 0.75rem 0.25rem;
|
|
127
|
+
}
|
|
128
|
+
|
|
106
129
|
.controls {
|
|
107
130
|
position: absolute;
|
|
108
131
|
inset: 0;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import type { InputLayout } from "../Input.vue.js";
|
|
2
|
+
export interface NumberInputProps {
|
|
3
|
+
layout?: InputLayout;
|
|
2
4
|
min?: number;
|
|
3
5
|
max?: number;
|
|
4
6
|
step?: number;
|
|
5
7
|
decimalPlaces?: number;
|
|
8
|
+
disabled?: boolean;
|
|
6
9
|
}
|
|
7
|
-
type __VLS_Props =
|
|
10
|
+
type __VLS_Props = NumberInputProps;
|
|
8
11
|
declare function increase(): void;
|
|
9
12
|
declare function decrease(): void;
|
|
10
13
|
type __VLS_ModelProps = {
|
|
@@ -25,6 +28,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
25
28
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
26
29
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
27
30
|
}>, {
|
|
31
|
+
disabled: boolean;
|
|
32
|
+
layout: InputLayout;
|
|
28
33
|
step: number;
|
|
29
34
|
min: number;
|
|
30
35
|
max: number;
|
|
@@ -138,8 +138,6 @@ const selectorAttrs = computed(() => ({ getOptionKey, getOptionLabel }));
|
|
|
138
138
|
border: 1px solid var(--color-border);
|
|
139
139
|
border-radius: var(--border-radius-md);
|
|
140
140
|
padding: 0.5rem 0.75rem;
|
|
141
|
-
font-size: 0.95rem;
|
|
142
|
-
line-height: 1.5;
|
|
143
141
|
color: var(--color-text);
|
|
144
142
|
transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
|
|
145
143
|
}
|
|
@@ -10,8 +10,9 @@ function toggle() {
|
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
13
|
-
<orio-control-element>
|
|
13
|
+
<orio-control-element v-slot="{ id }">
|
|
14
14
|
<button
|
|
15
|
+
:id
|
|
15
16
|
class="switch-button"
|
|
16
17
|
:class="{ active: modelValue, disabled }"
|
|
17
18
|
:disabled="disabled"
|
|
@@ -35,8 +36,6 @@ function toggle() {
|
|
|
35
36
|
color: var(--color-muted);
|
|
36
37
|
border: 1px solid var(--color-border);
|
|
37
38
|
padding: 8px 16px;
|
|
38
|
-
font-size: 1rem;
|
|
39
|
-
line-height: 1.5;
|
|
40
39
|
cursor: pointer;
|
|
41
40
|
user-select: none;
|
|
42
41
|
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
|
|
@@ -12,5 +12,5 @@ defineProps({
|
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
14
|
<style scoped>
|
|
15
|
-
.tag{border:1px solid transparent;border-radius:var(--border-radius-lg);display:inline-block;font-size
|
|
15
|
+
.tag{border:1px solid transparent;border-radius:var(--border-radius-lg);display:inline-block;font-size:var(--font-sm);font-weight:500;padding:.25rem .6rem;-webkit-user-select:none;-moz-user-select:none;user-select:none}.tag--neutral{background-color:var(--color-surface);border-color:color-mix(in srgb,var(--color-border) 80%,var(--color-accent) 20%);color:var(--color-muted)}.tag--accent{background-color:var(--color-accent-soft);border-color:var(--color-accent-border);color:var(--color-accent)}
|
|
16
16
|
</style>
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
+
import type { InputLayout } from "./Input.vue.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
layout?: InputLayout;
|
|
4
|
+
}
|
|
5
|
+
type __VLS_Props = Props;
|
|
1
6
|
type __VLS_ModelProps = {
|
|
2
7
|
modelValue?: string;
|
|
3
8
|
};
|
|
4
|
-
|
|
9
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
11
|
"update:modelValue": (value: string) => any;
|
|
6
|
-
} & {
|
|
7
|
-
input: (value: string) => any;
|
|
8
|
-
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
9
|
-
onInput?: ((value: string) => any) | undefined;
|
|
12
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
10
13
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
11
|
-
}>, {
|
|
14
|
+
}>, {
|
|
15
|
+
layout: InputLayout;
|
|
16
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
17
|
declare const _default: typeof __VLS_export;
|
|
13
18
|
export default _default;
|
|
@@ -1,44 +1,78 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useAttrs } from "vue";
|
|
3
3
|
const attrs = useAttrs();
|
|
4
|
-
defineEmits(["input"]);
|
|
5
4
|
const modelValue = defineModel({ type: String, ...{ default: "" } });
|
|
5
|
+
defineProps({
|
|
6
|
+
layout: { type: String, required: false, default: "vertical" }
|
|
7
|
+
});
|
|
6
8
|
</script>
|
|
7
9
|
|
|
8
10
|
<template>
|
|
9
|
-
<orio-control-element
|
|
10
|
-
|
|
11
|
+
<orio-control-element
|
|
12
|
+
v-slot="{ id }"
|
|
13
|
+
v-bind="attrs"
|
|
14
|
+
:layout="layout === 'inner' ? 'vertical' : layout"
|
|
15
|
+
:class="{ inner: layout === 'inner' }"
|
|
16
|
+
>
|
|
17
|
+
<textarea v-bind="attrs" :id v-model="modelValue" rows="4" />
|
|
11
18
|
</orio-control-element>
|
|
12
19
|
</template>
|
|
13
20
|
|
|
14
21
|
<style scoped>
|
|
15
|
-
.
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
.control.horizontal {
|
|
23
|
+
align-items: flex-start;
|
|
24
|
+
}
|
|
25
|
+
.control.horizontal :deep(.control-label) {
|
|
26
|
+
padding-top: 0.5rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
:deep(.slot-wrapper) {
|
|
18
30
|
border: 1px solid var(--color-border);
|
|
19
31
|
border-radius: var(--border-radius-md);
|
|
20
|
-
font-size: 1rem;
|
|
21
|
-
line-height: 1.5;
|
|
22
|
-
color: var(--color-text);
|
|
23
32
|
background-color: var(--color-bg);
|
|
24
|
-
|
|
25
|
-
resize: vertical; /* Let user resize vertically only */
|
|
26
|
-
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
|
33
|
+
transition: border-color 0.2s ease;
|
|
27
34
|
}
|
|
28
|
-
.
|
|
29
|
-
color: var(--color-muted);
|
|
30
|
-
}
|
|
31
|
-
.textarea:hover {
|
|
35
|
+
:deep(.slot-wrapper):hover {
|
|
32
36
|
border-color: var(--color-accent);
|
|
33
37
|
}
|
|
34
|
-
.
|
|
38
|
+
:deep(.slot-wrapper):focus-within {
|
|
35
39
|
border-color: var(--color-accent);
|
|
36
|
-
box-shadow: 0 0 0 2px var(--color-accent-soft);
|
|
37
|
-
outline: none;
|
|
38
40
|
}
|
|
39
|
-
.
|
|
41
|
+
:deep(.slot-wrapper):has(:disabled) {
|
|
40
42
|
background-color: var(--color-surface);
|
|
41
43
|
color: var(--color-muted);
|
|
42
44
|
cursor: not-allowed;
|
|
43
45
|
}
|
|
46
|
+
|
|
47
|
+
textarea {
|
|
48
|
+
border: 0;
|
|
49
|
+
background: transparent;
|
|
50
|
+
outline: none;
|
|
51
|
+
font-size: var(--font-md);
|
|
52
|
+
color: var(--color-text);
|
|
53
|
+
}
|
|
54
|
+
textarea::placeholder {
|
|
55
|
+
color: var(--color-muted);
|
|
56
|
+
user-select: none;
|
|
57
|
+
}
|
|
58
|
+
textarea {
|
|
59
|
+
width: 100%;
|
|
60
|
+
padding: 0.5rem 0.75rem;
|
|
61
|
+
resize: vertical;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.inner {
|
|
65
|
+
position: relative;
|
|
66
|
+
}
|
|
67
|
+
.inner :deep(.control-label) {
|
|
68
|
+
position: absolute;
|
|
69
|
+
z-index: 1;
|
|
70
|
+
pointer-events: none;
|
|
71
|
+
left: 0.75rem;
|
|
72
|
+
top: 0.25rem;
|
|
73
|
+
color: var(--color-muted);
|
|
74
|
+
}
|
|
75
|
+
.inner textarea {
|
|
76
|
+
padding: 1.25rem 0.75rem 0.25rem;
|
|
77
|
+
}
|
|
44
78
|
</style>
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
+
import type { InputLayout } from "./Input.vue.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
layout?: InputLayout;
|
|
4
|
+
}
|
|
5
|
+
type __VLS_Props = Props;
|
|
1
6
|
type __VLS_ModelProps = {
|
|
2
7
|
modelValue?: string;
|
|
3
8
|
};
|
|
4
|
-
|
|
9
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
11
|
"update:modelValue": (value: string) => any;
|
|
6
|
-
} & {
|
|
7
|
-
input: (value: string) => any;
|
|
8
|
-
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
9
|
-
onInput?: ((value: string) => any) | undefined;
|
|
12
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
10
13
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
11
|
-
}>, {
|
|
14
|
+
}>, {
|
|
15
|
+
layout: InputLayout;
|
|
16
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
17
|
declare const _default: typeof __VLS_export;
|
|
13
18
|
export default _default;
|
|
@@ -108,5 +108,5 @@ const arrowClass = computed(() => `arrow-${props.placement}`);
|
|
|
108
108
|
</template>
|
|
109
109
|
|
|
110
110
|
<style scoped>
|
|
111
|
-
.trigger{align-items:center;display:inline-flex;justify-content:center}.tooltip{pointer-events:none;position:absolute;z-index:9999}.content{background-color:rgba(0,0,0,.9);border-radius:var(--border-radius-sm,4px);box-shadow:0 2px 8px rgba(0,0,0,.15);color:#fff;font-size
|
|
111
|
+
.trigger{align-items:center;display:inline-flex;justify-content:center}.tooltip{pointer-events:none;position:absolute;z-index:9999}.content{background-color:rgba(0,0,0,.9);border-radius:var(--border-radius-sm,4px);box-shadow:0 2px 8px rgba(0,0,0,.15);color:#fff;font-size:var(--font-md);padding:.5rem .75rem;white-space:nowrap}.arrow{border-style:solid;height:0;position:absolute;width:0}.arrow-top{border-color:rgba(0,0,0,.9) transparent transparent;border-width:4px 4px 0;bottom:-4px}.arrow-bottom,.arrow-top{left:50%;transform:translateX(-50%)}.arrow-bottom{border-color:transparent transparent rgba(0,0,0,.9);border-width:0 4px 4px;top:-4px}.arrow-left{border-color:transparent transparent transparent rgba(0,0,0,.9);border-width:4px 0 4px 4px;right:-4px}.arrow-left,.arrow-right{top:50%;transform:translateY(-50%)}.arrow-right{border-color:transparent rgba(0,0,0,.9) transparent transparent;border-width:4px 4px 4px 0;left:-4px}
|
|
112
112
|
</style>
|
|
@@ -9,10 +9,14 @@ type __VLS_ModelProps = {
|
|
|
9
9
|
};
|
|
10
10
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
11
11
|
declare var __VLS_1: {
|
|
12
|
+
image: string | undefined;
|
|
13
|
+
}, __VLS_3: {
|
|
12
14
|
image: string;
|
|
13
15
|
};
|
|
14
16
|
type __VLS_Slots = {} & {
|
|
15
17
|
image?: (props: typeof __VLS_1) => any;
|
|
18
|
+
} & {
|
|
19
|
+
image?: (props: typeof __VLS_3) => any;
|
|
16
20
|
};
|
|
17
21
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
18
22
|
"update:activeImage": (value: string | undefined) => any;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
computed,
|
|
4
|
+
nextTick,
|
|
5
|
+
onMounted,
|
|
6
|
+
ref,
|
|
7
|
+
toRefs,
|
|
8
|
+
useTemplateRef,
|
|
9
|
+
watch
|
|
10
|
+
} from "vue";
|
|
3
11
|
import { useElementSize } from "@vueuse/core";
|
|
4
12
|
const props = defineProps({
|
|
5
13
|
images: { type: Array, required: false, default: () => [] },
|
|
@@ -7,22 +15,62 @@ const props = defineProps({
|
|
|
7
15
|
fit: { type: String, required: false, default: "contain" }
|
|
8
16
|
});
|
|
9
17
|
const { images, size, fit } = toRefs(props);
|
|
10
|
-
const rawSizes = computed(
|
|
11
|
-
|
|
18
|
+
const rawSizes = computed(() => {
|
|
19
|
+
const parts = size.value.split(":");
|
|
20
|
+
return {
|
|
21
|
+
width: parts[0] ? parseFloat(parts[0]) : null,
|
|
22
|
+
height: parts[1] ? parseFloat(parts[1]) : null
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
const isDynamicHeight = computed(
|
|
26
|
+
() => rawSizes.value.width !== null && rawSizes.value.height === null
|
|
27
|
+
);
|
|
28
|
+
const isDynamicWidth = computed(
|
|
29
|
+
() => rawSizes.value.width === null && rawSizes.value.height !== null
|
|
12
30
|
);
|
|
13
31
|
const carousel = useTemplateRef("carousel");
|
|
32
|
+
const measureContainer = useTemplateRef("measureContainer");
|
|
14
33
|
const { width: carouselWidth } = useElementSize(carousel);
|
|
34
|
+
const contentWidth = ref(0);
|
|
35
|
+
const contentHeight = ref(0);
|
|
36
|
+
const contentAspectRatio = computed(() => {
|
|
37
|
+
if (!contentWidth.value || !contentHeight.value) return 1;
|
|
38
|
+
return contentWidth.value / contentHeight.value;
|
|
39
|
+
});
|
|
15
40
|
const calculatedSize = computed(() => {
|
|
41
|
+
const { width, height } = rawSizes.value;
|
|
42
|
+
if (isDynamicHeight.value) {
|
|
43
|
+
const dynamicHeight = contentAspectRatio.value ? width / contentAspectRatio.value : width;
|
|
44
|
+
return {
|
|
45
|
+
width: `${width}px`,
|
|
46
|
+
height: `${dynamicHeight}px`
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (isDynamicWidth.value) {
|
|
50
|
+
const dynamicWidth = contentAspectRatio.value ? height * contentAspectRatio.value : height;
|
|
51
|
+
return {
|
|
52
|
+
width: `${dynamicWidth}px`,
|
|
53
|
+
height: `${height}px`
|
|
54
|
+
};
|
|
55
|
+
}
|
|
16
56
|
return {
|
|
17
|
-
width: `${
|
|
18
|
-
height: `${
|
|
57
|
+
width: `${width}px`,
|
|
58
|
+
height: `${height}px`
|
|
19
59
|
};
|
|
20
60
|
});
|
|
21
61
|
const maxHeight = computed(() => {
|
|
22
|
-
const
|
|
62
|
+
const { width, height } = rawSizes.value;
|
|
63
|
+
if (!width || !height) return "none";
|
|
64
|
+
const dimensions = width / height;
|
|
23
65
|
if (!carouselWidth.value) return "100%";
|
|
24
66
|
return `${carouselWidth.value / dimensions}px`;
|
|
25
67
|
});
|
|
68
|
+
function measureContent() {
|
|
69
|
+
if (!measureContainer.value) return;
|
|
70
|
+
const el = measureContainer.value;
|
|
71
|
+
contentWidth.value = el.scrollWidth;
|
|
72
|
+
contentHeight.value = el.scrollHeight;
|
|
73
|
+
}
|
|
26
74
|
const activeImage = defineModel("activeImage", { type: String });
|
|
27
75
|
const activeImageIndex = computed(
|
|
28
76
|
() => images.value.findIndex((image) => image === activeImage.value)
|
|
@@ -63,51 +111,73 @@ function getItemClasses(image) {
|
|
|
63
111
|
if (images.value.findIndex((img) => image === img) === activeImageIndex.value - 1)
|
|
64
112
|
return ["previous-image"];
|
|
65
113
|
}
|
|
114
|
+
watch(activeImage, () => {
|
|
115
|
+
if (isDynamicHeight.value || isDynamicWidth.value) {
|
|
116
|
+
nextTick(measureContent);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
66
119
|
onMounted(() => {
|
|
67
120
|
if (!activeImage.value) activeImage.value = images.value[0];
|
|
121
|
+
if (isDynamicHeight.value || isDynamicWidth.value) {
|
|
122
|
+
nextTick(measureContent);
|
|
123
|
+
}
|
|
68
124
|
});
|
|
69
125
|
</script>
|
|
70
126
|
|
|
71
127
|
<template>
|
|
72
|
-
<div
|
|
128
|
+
<div class="carousel-wrapper">
|
|
129
|
+
<!-- Hidden container to measure natural content size -->
|
|
73
130
|
<div
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
131
|
+
v-if="isDynamicHeight || isDynamicWidth"
|
|
132
|
+
ref="measureContainer"
|
|
133
|
+
class="carousel-measure"
|
|
77
134
|
>
|
|
135
|
+
<slot name="image" :image="activeImage">
|
|
136
|
+
<img :src="activeImage" :alt="activeImage" @load="measureContent" />
|
|
137
|
+
</slot>
|
|
138
|
+
</div>
|
|
139
|
+
<div ref="carousel" class="carousel">
|
|
78
140
|
<div
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
:class="getItemClasses(image)"
|
|
83
|
-
>
|
|
84
|
-
<slot name="image" :image>
|
|
85
|
-
<img :src="image" :alt="image" draggable="false" />
|
|
86
|
-
</slot>
|
|
87
|
-
</div>
|
|
88
|
-
<orio-button
|
|
89
|
-
variant="subdued"
|
|
90
|
-
icon="chevron-left"
|
|
91
|
-
class="switch-button previous-button"
|
|
92
|
-
@click="previousImage"
|
|
93
|
-
>
|
|
94
|
-
<template #icon>
|
|
95
|
-
<orio-icon name="chevron-left" size="40px" />
|
|
96
|
-
</template>
|
|
97
|
-
</orio-button>
|
|
98
|
-
<orio-button
|
|
99
|
-
variant="subdued"
|
|
100
|
-
class="switch-button next-button"
|
|
101
|
-
@click="nextImage"
|
|
141
|
+
class="carousel-track"
|
|
142
|
+
@pointerdown="onPointerDown"
|
|
143
|
+
@pointerup="onPointerUp"
|
|
102
144
|
>
|
|
103
|
-
<
|
|
104
|
-
|
|
145
|
+
<div
|
|
146
|
+
v-for="image of images"
|
|
147
|
+
:key="image"
|
|
148
|
+
class="carousel-item"
|
|
149
|
+
:class="getItemClasses(image)"
|
|
150
|
+
>
|
|
151
|
+
<slot name="image" :image>
|
|
152
|
+
<img :src="image" :alt="image" draggable="false" />
|
|
153
|
+
</slot>
|
|
154
|
+
</div>
|
|
155
|
+
<template v-if="images.length > 1">
|
|
156
|
+
<orio-button
|
|
157
|
+
variant="subdued"
|
|
158
|
+
icon="chevron-left"
|
|
159
|
+
class="switch-button previous-button"
|
|
160
|
+
@click="previousImage"
|
|
161
|
+
>
|
|
162
|
+
<template #icon>
|
|
163
|
+
<orio-icon name="chevron-left" size="40px" />
|
|
164
|
+
</template>
|
|
165
|
+
</orio-button>
|
|
166
|
+
<orio-button
|
|
167
|
+
variant="subdued"
|
|
168
|
+
class="switch-button next-button"
|
|
169
|
+
@click="nextImage"
|
|
170
|
+
>
|
|
171
|
+
<template #icon>
|
|
172
|
+
<orio-icon name="chevron-right" size="40px" />
|
|
173
|
+
</template>
|
|
174
|
+
</orio-button>
|
|
105
175
|
</template>
|
|
106
|
-
</
|
|
176
|
+
</div>
|
|
107
177
|
</div>
|
|
108
178
|
</div>
|
|
109
179
|
</template>
|
|
110
180
|
|
|
111
181
|
<style scoped>
|
|
112
|
-
.carousel{border:1px solid var(--color-border);border-radius:var(--border-radius-lg);height:v-bind("calculatedSize.height");max-height:v-bind(maxHeight);max-width:100%;overflow:hidden;width:v-bind("calculatedSize.width")}.
|
|
182
|
+
.carousel-wrapper{display:block;position:relative}.carousel-measure{height:-moz-max-content;height:max-content;pointer-events:none;position:absolute;visibility:hidden;width:-moz-max-content;width:max-content}.carousel-measure img{display:block}.carousel{border:1px solid var(--color-border);border-radius:var(--border-radius-lg);height:v-bind("calculatedSize.height");max-height:v-bind(maxHeight);max-width:100%;overflow:hidden;transition:width .3s ease,height .3s ease;width:v-bind("calculatedSize.width")}.carousel-track{align-items:center;cursor:grab;display:flex;gap:.75rem;height:100%;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.carousel-track:active{cursor:grabbing}.carousel-item{background:var(--color-surface);border-radius:var(--border-radius-sm);color:var(--color-text);height:100%;inset:0;opacity:0;padding:.5rem .75rem;pointer-events:none;position:absolute;transition:opacity .5s ease-in-out,transform .5s ease-in-out;white-space:nowrap;width:100%}.carousel-item.previous-image{transform:translateX(-100%)}.carousel-item.next-image{transform:translateX(100%)}.carousel-item.active-image{opacity:1;pointer-events:auto;transform:translateX(0)}.carousel-item img{height:100%;-o-object-fit:v-bind(fit);object-fit:v-bind(fit);width:100%}.carousel-empty{color:var(--color-muted)}.switch-button{position:absolute}.switch-button :deep(button){background:transparent!important;border:none!important;color:transparent!important}.switch-button :deep(button:hover){color:transparent!important}.switch-button :deep(.orio-icon){color:#fff!important;fill:#fff!important;filter:drop-shadow(0 0 2px rgba(0,0,0,.8)) drop-shadow(0 0 4px rgba(0,0,0,.6))}@supports (mix-blend-mode:difference) and (not (-webkit-hyphens:none)){.switch-button :deep(.orio-icon){color:#000!important;fill:#000!important;filter:grayscale(1) contrast(9) invert(1) drop-shadow(0 0 1px black) drop-shadow(0 0 2px black);mix-blend-mode:difference}}.switch-button.previous-button{left:0}.switch-button.next-button{right:0}
|
|
113
183
|
</style>
|
|
@@ -9,10 +9,14 @@ type __VLS_ModelProps = {
|
|
|
9
9
|
};
|
|
10
10
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
11
11
|
declare var __VLS_1: {
|
|
12
|
+
image: string | undefined;
|
|
13
|
+
}, __VLS_3: {
|
|
12
14
|
image: string;
|
|
13
15
|
};
|
|
14
16
|
type __VLS_Slots = {} & {
|
|
15
17
|
image?: (props: typeof __VLS_1) => any;
|
|
18
|
+
} & {
|
|
19
|
+
image?: (props: typeof __VLS_3) => any;
|
|
16
20
|
};
|
|
17
21
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
18
22
|
"update:activeImage": (value: string | undefined) => any;
|
|
@@ -54,15 +54,15 @@ div.italics {
|
|
|
54
54
|
color: var(--color-muted);
|
|
55
55
|
}
|
|
56
56
|
div.small {
|
|
57
|
-
font-size:
|
|
57
|
+
font-size: var(--font-sm);
|
|
58
58
|
}
|
|
59
59
|
div.medium {
|
|
60
|
-
font-size:
|
|
60
|
+
font-size: var(--font-md);
|
|
61
61
|
}
|
|
62
62
|
div.large {
|
|
63
|
-
font-size:
|
|
63
|
+
font-size: var(--font-lg);
|
|
64
64
|
}
|
|
65
65
|
div.extra-large {
|
|
66
|
-
font-size:
|
|
66
|
+
font-size: var(--font-xl);
|
|
67
67
|
}
|
|
68
68
|
</style>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orio-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Modern Nuxt component library with theme support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/module.mjs",
|
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
"@vueuse/integrations": "^11.0.0",
|
|
40
40
|
"change-case": "^5.4.4",
|
|
41
41
|
"fuse.js": "^7.0.0",
|
|
42
|
-
"nanoid": "^5.0.0",
|
|
43
42
|
"ofetch": "^1.5.1",
|
|
44
43
|
"universal-cookie": "^7.0.0"
|
|
45
44
|
},
|