@toife/vue 3.0.2 → 3.0.4
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/package.json +1 -1
- package/src/components/action/action.composable.ts +1 -0
- package/src/components/action/action.type.ts +10 -1
- package/src/components/action/action.vue +12 -10
- package/src/components/app/app.type.ts +9 -0
- package/src/components/app/app.vue +8 -7
- package/src/components/avatar/avatar.type.ts +1 -1
- package/src/components/avatar/avatar.vue +4 -13
- package/src/components/button/button.type.ts +1 -1
- package/src/components/button/button.vue +8 -8
- package/src/components/cable/cable.type.ts +1 -1
- package/src/components/cable/cable.vue +8 -8
- package/src/components/card/card/card.type.ts +1 -1
- package/src/components/card/card/card.vue +6 -6
- package/src/components/card/card-footer/card-footer.vue +4 -4
- package/src/components/card/card-header/card-header.vue +4 -4
- package/src/components/checkbox/checkbox.vue +8 -8
- package/src/components/collapse/collapse.type.ts +1 -1
- package/src/components/collapse/collapse.vue +15 -19
- package/src/components/container/container.vue +1 -0
- package/src/components/decision-modal/decision-modal.composable.ts +1 -0
- package/src/components/decision-modal/decision-modal.type.ts +1 -1
- package/src/components/decision-modal/decision-modal.vue +11 -11
- package/src/components/divider/divider.vue +4 -4
- package/src/components/field/field.type.ts +1 -1
- package/src/components/field/field.vue +7 -6
- package/src/components/field/outline/outline.vue +10 -10
- package/src/components/form-group/form-group.vue +5 -5
- package/src/components/gesture-indicator/gesture-indicator.type.ts +1 -1
- package/src/components/gesture-indicator/gesture-indicator.vue +5 -5
- package/src/components/image/image.type.ts +1 -1
- package/src/components/image/image.vue +10 -12
- package/src/components/modal/modal.vue +11 -9
- package/src/components/page/page.vue +2 -1
- package/src/components/present/present.composable.ts +1 -0
- package/src/components/present/present.vue +12 -12
- package/src/components/radio/radio/radio.type.ts +1 -1
- package/src/components/radio/radio/radio.vue +8 -8
- package/src/components/radio/radio-group/radio-group.vue +6 -6
- package/src/components/refresher/refresher.type.ts +1 -1
- package/src/components/refresher/refresher.vue +11 -11
- package/src/components/route/route-navigator/route-navigator.type.ts +24 -0
- package/src/components/route/route-navigator/route-navigator.vue +33 -16
- package/src/components/route/route-outlet/route-outlet.vue +20 -11
- package/src/components/route/route-provider/route-provider.vue +6 -6
- package/src/components/route/route-wrapper/route-wrapper.composable.ts +4 -3
- package/src/components/route/route-wrapper/route-wrapper.vue +7 -5
- package/src/components/route/route.util.ts +1 -0
- package/src/components/segmented-field/segmented-field.vue +8 -8
- package/src/components/skeleton/skeleton.type.ts +1 -1
- package/src/components/skeleton/skeleton.vue +4 -4
- package/src/components/switch/switch.type.ts +1 -1
- package/src/components/switch/switch.vue +8 -8
- package/src/components/tabs/tab/tab.type.ts +1 -1
- package/src/components/tabs/tab/tab.vue +6 -6
- package/src/components/tabs/tabs/tabs.type.ts +1 -1
- package/src/components/tabs/tabs/tabs.vue +13 -13
- package/src/components/toast/toast/toast.vue +6 -6
- package/src/components/toast/toast-content/toast-content.vue +7 -7
- package/src/components/toast/toast.composable.ts +1 -1
- package/src/components/toolbar/toolbar.type.ts +1 -1
- package/src/components/toolbar/toolbar.vue +4 -4
- package/src/factory.ts +2 -1
- package/src/utils/element.ts +6 -0
- package/src/utils/events.ts +8 -2
- package/src/utils/style/index.ts +17 -2
|
@@ -2,29 +2,38 @@
|
|
|
2
2
|
<script lang="ts" setup>
|
|
3
3
|
import { markRaw, onMounted, ref } from "vue";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
// Component setup (props, emits, injects)
|
|
6
|
+
// ----------------------------------------------------------------------------
|
|
7
7
|
const props = defineProps<{
|
|
8
8
|
component: unknown;
|
|
9
9
|
}>();
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
// Reactive state
|
|
12
|
+
// ----------------------------------------------------------------------------
|
|
13
13
|
const renderComponent = ref<unknown | null>(null);
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// Methods
|
|
16
|
+
// ----------------------------------------------------------------------------
|
|
17
17
|
const resolveComponent = async (raw: unknown): Promise<unknown> => {
|
|
18
18
|
if (typeof raw !== "function") return raw;
|
|
19
19
|
const mod = await (raw as () => Promise<{ default?: unknown }>)();
|
|
20
20
|
return mod?.default ?? mod;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
/** Accepts a component, async loader, or `{ default }` wrapper (common for vue-router). */
|
|
24
|
+
const resolveFromProp = async (raw: unknown): Promise<unknown | null> => {
|
|
25
|
+
if (raw == null) return null;
|
|
26
|
+
const inner =
|
|
27
|
+
typeof raw === "object" && raw !== null && "default" in raw
|
|
28
|
+
? (raw as { default: unknown }).default
|
|
29
|
+
: raw;
|
|
30
|
+
return resolveComponent(inner);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Lifecycle
|
|
34
|
+
// ----------------------------------------------------------------------------
|
|
25
35
|
onMounted(async () => {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
renderComponent.value = component ? markRaw(component) : null;
|
|
36
|
+
const resolved = await resolveFromProp(props.component);
|
|
37
|
+
renderComponent.value = resolved ? markRaw(resolved) : null;
|
|
29
38
|
});
|
|
30
39
|
</script>
|
|
@@ -4,16 +4,16 @@ import { ROUTE_PROVIDER_STATE_KEY } from "./route-provider.constant";
|
|
|
4
4
|
import { type RouteProviderProps, type RouteProviderState } from "./route-provider.type";
|
|
5
5
|
import { provide, computed } from "vue";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// Component setup (props, emits, injects)
|
|
8
|
+
// ----------------------------------------------------------------------------
|
|
9
9
|
const props = defineProps<RouteProviderProps>();
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
// Computed properties
|
|
12
|
+
// ----------------------------------------------------------------------------
|
|
13
13
|
const stack = computed(() => props.stack);
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// Provide / expose (public API)
|
|
16
|
+
// ----------------------------------------------------------------------------
|
|
17
17
|
provide<RouteProviderState>(ROUTE_PROVIDER_STATE_KEY, {
|
|
18
18
|
stack,
|
|
19
19
|
});
|
|
@@ -5,6 +5,7 @@ import { RouteWrapperOption } from "./route-wrapper.type";
|
|
|
5
5
|
|
|
6
6
|
const stack = shallowRef<RouteStack[]>([]);
|
|
7
7
|
|
|
8
|
+
/** Recursively builds a nested stack from vue-router `matched` for the navigator. */
|
|
8
9
|
const buildTree = (
|
|
9
10
|
matched: RouteLocationMatched[],
|
|
10
11
|
current: RouteStack[],
|
|
@@ -12,12 +13,12 @@ const buildTree = (
|
|
|
12
13
|
) => {
|
|
13
14
|
if (matched.length === 0) return current;
|
|
14
15
|
|
|
15
|
-
//
|
|
16
|
+
// User navigated back: drop the leaf so we merge into the parent segment
|
|
16
17
|
if (current.length > 1 && current[current.length - 2]?.name === matched[0].name) {
|
|
17
18
|
current.pop();
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
//
|
|
21
|
+
// Same route record: update nested stack only
|
|
21
22
|
if (
|
|
22
23
|
current.length > 0 &&
|
|
23
24
|
current[current.length - 1] &&
|
|
@@ -30,7 +31,7 @@ const buildTree = (
|
|
|
30
31
|
option
|
|
31
32
|
);
|
|
32
33
|
}
|
|
33
|
-
//
|
|
34
|
+
// Push a new segment (forward navigation)
|
|
34
35
|
else {
|
|
35
36
|
const name = String(matched[0].name);
|
|
36
37
|
const component = matched[0].components as RouteComponent;
|
|
@@ -6,15 +6,17 @@ import { useRouter, useRoute } from "vue-router";
|
|
|
6
6
|
import type { RouteWrapperProps } from "./route-wrapper.type";
|
|
7
7
|
import { RouteProvider } from "../route-provider";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const router = useRouter();
|
|
9
|
+
// Component setup (props, emits, injects)
|
|
10
|
+
// ----------------------------------------------------------------------------
|
|
12
11
|
const props = withDefaults(defineProps<RouteWrapperProps>(), {
|
|
13
12
|
homeRouteName: "home",
|
|
14
13
|
});
|
|
14
|
+
const { updateRoutes, stack } = useRouteWrapper();
|
|
15
|
+
const route = useRoute();
|
|
16
|
+
const router = useRouter();
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
// Lifecycle
|
|
19
|
+
// ----------------------------------------------------------------------------
|
|
18
20
|
watch(
|
|
19
21
|
() => route.matched,
|
|
20
22
|
() => {
|
|
@@ -7,8 +7,8 @@ import type { SegmentedFieldProps, SegmentedFieldEmit } from "./segmented-field.
|
|
|
7
7
|
import { withPrefix } from "../../utils";
|
|
8
8
|
import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
// Component setup (props, emits, injects)
|
|
11
|
+
// ----------------------------------------------------------------------------
|
|
12
12
|
const props = withDefaults(defineProps<SegmentedFieldProps>(), {
|
|
13
13
|
modelValue: undefined,
|
|
14
14
|
value: undefined,
|
|
@@ -26,13 +26,13 @@ const props = withDefaults(defineProps<SegmentedFieldProps>(), {
|
|
|
26
26
|
const emit = defineEmits<SegmentedFieldEmit>();
|
|
27
27
|
const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
// Reactive state
|
|
30
|
+
// ----------------------------------------------------------------------------
|
|
31
31
|
const keepValue = ref<string[]>([]);
|
|
32
32
|
const fields = ref<InstanceType<typeof Field>[]>([]);
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
// Computed properties
|
|
35
|
+
// ----------------------------------------------------------------------------
|
|
36
36
|
const segments = computed(() => {
|
|
37
37
|
let value: string[] | undefined = [];
|
|
38
38
|
if (props.value !== undefined && props.value.length > 0) value = props.value;
|
|
@@ -93,8 +93,8 @@ const nextIndex = computed(() => {
|
|
|
93
93
|
return nextIndex;
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
// Methods
|
|
97
|
+
// ----------------------------------------------------------------------------
|
|
98
98
|
const updateValue = (newValue: string[]) => {
|
|
99
99
|
keepValue.value = newValue;
|
|
100
100
|
emit("update:modelValue", newValue);
|
|
@@ -6,16 +6,16 @@ import { type SkeletonProps } from "./skeleton.type";
|
|
|
6
6
|
import { property, withPrefix } from "../../utils";
|
|
7
7
|
import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// Component setup (props, emits, injects)
|
|
10
|
+
// ----------------------------------------------------------------------------
|
|
11
11
|
const props = withDefaults(defineProps<SkeletonProps>(), {
|
|
12
12
|
width: "100%",
|
|
13
13
|
height: "1rem",
|
|
14
14
|
});
|
|
15
15
|
const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
// Computed properties
|
|
18
|
+
// ----------------------------------------------------------------------------
|
|
19
19
|
const skeletonAttrs = computed(() => {
|
|
20
20
|
const shape = props.shape || appState?.shape.value || "";
|
|
21
21
|
const role = props.role || appState?.role.value || "";
|
|
@@ -6,8 +6,8 @@ import type { SwitchProps, SwitchEmit } from "./switch.type";
|
|
|
6
6
|
import { withPrefix } from "../../utils";
|
|
7
7
|
import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// Component setup (props, emits, injects)
|
|
10
|
+
// ----------------------------------------------------------------------------
|
|
11
11
|
const props = withDefaults(defineProps<SwitchProps>(), {
|
|
12
12
|
modelValue: false,
|
|
13
13
|
readonly: false,
|
|
@@ -16,12 +16,12 @@ const props = withDefaults(defineProps<SwitchProps>(), {
|
|
|
16
16
|
const emit = defineEmits<SwitchEmit>();
|
|
17
17
|
const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
// Reactive state
|
|
20
|
+
// ----------------------------------------------------------------------------
|
|
21
21
|
const isFocused = ref(false);
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
// Computed properties
|
|
24
|
+
// ----------------------------------------------------------------------------
|
|
25
25
|
const switchWrapperAttrs = computed(() => {
|
|
26
26
|
const shadow = (props?.shadow !== undefined ? props.shadow : appState?.shadow.value) ?? false;
|
|
27
27
|
return {
|
|
@@ -56,8 +56,8 @@ const switchIconAttrs = {
|
|
|
56
56
|
class: [withPrefix("switch-icon")],
|
|
57
57
|
} as const;
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
// Methods
|
|
60
|
+
// ----------------------------------------------------------------------------
|
|
61
61
|
const onSwitch = () => {
|
|
62
62
|
if (props.disabled || props.readonly) return;
|
|
63
63
|
emit("update:modelValue", !props.modelValue);
|
|
@@ -6,15 +6,15 @@ import { type TabProps } from "./tab.type";
|
|
|
6
6
|
import { withPrefix } from "../../../utils";
|
|
7
7
|
import { type TabsProviderState, TABS_PROVIDER_STATE_KEY } from "../tabs";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// Component setup (props, emits, injects)
|
|
10
|
+
// ----------------------------------------------------------------------------
|
|
11
11
|
const props = withDefaults(defineProps<TabProps>(), {
|
|
12
12
|
disabled: false,
|
|
13
13
|
});
|
|
14
14
|
const tabsState = inject<TabsProviderState>(TABS_PROVIDER_STATE_KEY);
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
// Computed properties
|
|
17
|
+
// ----------------------------------------------------------------------------
|
|
18
18
|
const role = computed(() => tabsState?.role.value || "");
|
|
19
19
|
const shape = computed(() => tabsState?.shape.value || "");
|
|
20
20
|
const isActive = computed(() => tabsState?.activeValue.value === props.value);
|
|
@@ -29,8 +29,8 @@ const tabAttrs = computed(() => {
|
|
|
29
29
|
};
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
// Methods
|
|
33
|
+
// ----------------------------------------------------------------------------
|
|
34
34
|
const handleClick = () => {
|
|
35
35
|
if (props.disabled) return;
|
|
36
36
|
tabsState?.setValue(props.value || "");
|
|
@@ -7,8 +7,8 @@ import { property, withPrefix } from "../../../utils";
|
|
|
7
7
|
import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../../app";
|
|
8
8
|
import { TABS_PROVIDER_STATE_KEY } from "./tabs.constants";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
// Component setup (props, emits, injects)
|
|
11
|
+
// ----------------------------------------------------------------------------
|
|
12
12
|
const props = withDefaults(defineProps<TabsProps>(), {
|
|
13
13
|
placement: "top-start",
|
|
14
14
|
margin: () => [0, 0],
|
|
@@ -16,19 +16,19 @@ const props = withDefaults(defineProps<TabsProps>(), {
|
|
|
16
16
|
divider: undefined,
|
|
17
17
|
transition: true,
|
|
18
18
|
});
|
|
19
|
-
const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
|
|
20
19
|
const emit = defineEmits<TabsEmit>();
|
|
20
|
+
const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
// Reactive state
|
|
23
|
+
// ----------------------------------------------------------------------------
|
|
24
24
|
const width = ref(0);
|
|
25
25
|
const height = ref(0);
|
|
26
26
|
const top = ref(0);
|
|
27
27
|
const left = ref(0);
|
|
28
28
|
const container = ref();
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
// Computed properties
|
|
31
|
+
// ----------------------------------------------------------------------------
|
|
32
32
|
const role = computed(() => {
|
|
33
33
|
return props.role || appState?.role.value || "";
|
|
34
34
|
});
|
|
@@ -55,7 +55,7 @@ const tabsAttrs = computed(() => {
|
|
|
55
55
|
w = w + props.margin[1] * 2;
|
|
56
56
|
|
|
57
57
|
if (props.variant === "underline") {
|
|
58
|
-
|
|
58
|
+
// Underline variant: align the highlight strip for top vs bottom tab bars
|
|
59
59
|
if (props.placement.startsWith("top-")) {
|
|
60
60
|
t = h - props.border;
|
|
61
61
|
}
|
|
@@ -106,8 +106,8 @@ const tabsAttrs = computed(() => {
|
|
|
106
106
|
};
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
// Methods
|
|
110
|
+
// ----------------------------------------------------------------------------
|
|
111
111
|
const calcPosition = () => {
|
|
112
112
|
let active = container.value.querySelector(".active");
|
|
113
113
|
if (active) {
|
|
@@ -125,7 +125,7 @@ const calcPosition = () => {
|
|
|
125
125
|
};
|
|
126
126
|
|
|
127
127
|
// Lifecycle
|
|
128
|
-
|
|
128
|
+
// ----------------------------------------------------------------------------
|
|
129
129
|
watch(
|
|
130
130
|
() => props.modelValue,
|
|
131
131
|
async () => {
|
|
@@ -144,8 +144,8 @@ onUnmounted(() => {
|
|
|
144
144
|
window.removeEventListener("resize", calcPosition);
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
-
//
|
|
148
|
-
|
|
147
|
+
// Provide / expose (public API)
|
|
148
|
+
// ----------------------------------------------------------------------------
|
|
149
149
|
provide<TabsProviderState>(TABS_PROVIDER_STATE_KEY, {
|
|
150
150
|
activeValue,
|
|
151
151
|
role,
|
|
@@ -7,15 +7,15 @@ import { withPrefix } from "../../../utils";
|
|
|
7
7
|
import { useToast } from "../toast.composable";
|
|
8
8
|
import { ToastContent } from "../toast-content";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
// Component setup (props, emits, injects)
|
|
11
|
+
// ----------------------------------------------------------------------------
|
|
12
12
|
const props = withDefaults(defineProps<ToastProps>(), {
|
|
13
13
|
placement: "bottom-end",
|
|
14
14
|
});
|
|
15
15
|
const toast = useToast();
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
// Computed properties
|
|
18
|
+
// ----------------------------------------------------------------------------
|
|
19
19
|
const toastAttrs = computed(() => {
|
|
20
20
|
return {
|
|
21
21
|
class: [withPrefix("toast"), props.placement],
|
|
@@ -26,8 +26,8 @@ const toastMessages = computed(() => {
|
|
|
26
26
|
return toast.messages.value.filter((item) => item.placement == props.placement);
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
// Methods
|
|
30
|
+
// ----------------------------------------------------------------------------
|
|
31
31
|
const dismiss = (id: number) => {
|
|
32
32
|
toast.close(id);
|
|
33
33
|
};
|
|
@@ -6,8 +6,8 @@ import { type ToastContentProps, type ToastContentEmit } from "../toast.type";
|
|
|
6
6
|
import { withPrefix } from "../../../utils";
|
|
7
7
|
import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../../app";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// Component setup (props, emits, injects)
|
|
10
|
+
// ----------------------------------------------------------------------------
|
|
11
11
|
const props = withDefaults(defineProps<ToastContentProps>(), {
|
|
12
12
|
message: "",
|
|
13
13
|
duration: 2000,
|
|
@@ -16,12 +16,12 @@ const props = withDefaults(defineProps<ToastContentProps>(), {
|
|
|
16
16
|
const emit = defineEmits<ToastContentEmit>();
|
|
17
17
|
const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
// Reactive state
|
|
20
|
+
// ----------------------------------------------------------------------------
|
|
21
21
|
const isClosing = ref(false);
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
// Computed properties
|
|
24
|
+
// ----------------------------------------------------------------------------
|
|
25
25
|
const contentAttrs = computed(() => {
|
|
26
26
|
const role = props.role || appState?.role.value || "";
|
|
27
27
|
const shape = props.shape || appState?.shape.value || "";
|
|
@@ -40,7 +40,7 @@ const contentAttrs = computed(() => {
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
// Lifecycle
|
|
43
|
-
|
|
43
|
+
// ----------------------------------------------------------------------------
|
|
44
44
|
onMounted(() => {
|
|
45
45
|
setTimeout(() => {
|
|
46
46
|
isClosing.value = true;
|
|
@@ -8,8 +8,8 @@ import { type CableProviderState } from "../cable/cable.type";
|
|
|
8
8
|
import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
|
|
9
9
|
import { CABLE_PROVIDER_STATE_KEY } from "../cable";
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
// Component setup (props, emits, injects)
|
|
12
|
+
// ----------------------------------------------------------------------------
|
|
13
13
|
const props = withDefaults(defineProps<ToolbarProps>(), {
|
|
14
14
|
placement: null,
|
|
15
15
|
safeArea: true,
|
|
@@ -18,8 +18,8 @@ const props = withDefaults(defineProps<ToolbarProps>(), {
|
|
|
18
18
|
const cable = inject<CableProviderState>(CABLE_PROVIDER_STATE_KEY);
|
|
19
19
|
const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
// Computed properties
|
|
22
|
+
// ----------------------------------------------------------------------------
|
|
23
23
|
const toolbarAttrs = computed(() => {
|
|
24
24
|
const role = props.role || appState?.role.value || "";
|
|
25
25
|
const placement = props.placement || cable?.placement.value || "";
|
package/src/factory.ts
CHANGED
|
@@ -37,10 +37,11 @@ import {
|
|
|
37
37
|
Toolbar,
|
|
38
38
|
} from "./components";
|
|
39
39
|
import { type CreateToifeOptions } from "./type";
|
|
40
|
+
import type { App as VueApp } from "vue";
|
|
40
41
|
|
|
41
42
|
export const createToife = (options?: CreateToifeOptions) => {
|
|
42
43
|
return {
|
|
43
|
-
install: (app:
|
|
44
|
+
install: (app: VueApp) => {
|
|
44
45
|
const prefix = options?.prefix || "t-";
|
|
45
46
|
app.component(prefix + "app", App);
|
|
46
47
|
app.component(prefix + "action", Action);
|
package/src/utils/element.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if the target is a form element
|
|
3
|
+
*/
|
|
1
4
|
export const isFormElement = (target: any) => {
|
|
2
5
|
return (
|
|
3
6
|
target &&
|
|
@@ -5,6 +8,9 @@ export const isFormElement = (target: any) => {
|
|
|
5
8
|
);
|
|
6
9
|
};
|
|
7
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Blur the current active element
|
|
13
|
+
*/
|
|
8
14
|
export const blurCurrentActive = () => {
|
|
9
15
|
const active = document.activeElement as HTMLElement | null;
|
|
10
16
|
if (
|
package/src/utils/events.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { blurCurrentActive, isFormElement } from "./element";
|
|
2
2
|
|
|
3
|
+
/** Subset of the Virtual Keyboard API used for layout. */
|
|
4
|
+
type VirtualKeyboardOverlay = { overlaysContent: boolean };
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Prevent default behavior
|
|
8
|
+
*/
|
|
3
9
|
export const preventDefault = () => {
|
|
4
10
|
document.addEventListener("contextmenu", (e) => e.preventDefault());
|
|
5
11
|
document.addEventListener("pointerup", (e) => {
|
|
6
12
|
!isFormElement(e.target) && blurCurrentActive();
|
|
7
13
|
});
|
|
8
14
|
|
|
9
|
-
if ("virtualKeyboard" in navigator) {
|
|
10
|
-
(navigator.virtualKeyboard as
|
|
15
|
+
if ("virtualKeyboard" in navigator && navigator.virtualKeyboard) {
|
|
16
|
+
(navigator.virtualKeyboard as VirtualKeyboardOverlay).overlaysContent = true;
|
|
11
17
|
}
|
|
12
18
|
};
|
package/src/utils/style/index.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
let prefix: string | null = null;
|
|
2
2
|
let separator: string | null = null;
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Get the separator from the document element
|
|
6
|
+
*/
|
|
4
7
|
export const getSeparator = () => {
|
|
5
8
|
if (!separator)
|
|
6
9
|
separator = getComputedStyle(document.documentElement).getPropertyValue("--separator").trim();
|
|
@@ -8,6 +11,9 @@ export const getSeparator = () => {
|
|
|
8
11
|
return separator;
|
|
9
12
|
};
|
|
10
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Get the prefix from the document element
|
|
16
|
+
*/
|
|
11
17
|
export const getPrefix = () => {
|
|
12
18
|
if (!prefix)
|
|
13
19
|
prefix = getComputedStyle(document.documentElement).getPropertyValue("--prefix").trim();
|
|
@@ -15,6 +21,9 @@ export const getPrefix = () => {
|
|
|
15
21
|
return prefix;
|
|
16
22
|
};
|
|
17
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Generate the prefixed name
|
|
26
|
+
*/
|
|
18
27
|
export const withPrefix = (name: string | string[]) => {
|
|
19
28
|
const p = getPrefix();
|
|
20
29
|
const s = getSeparator();
|
|
@@ -33,10 +42,16 @@ export const withPrefix = (name: string | string[]) => {
|
|
|
33
42
|
return names.join(s);
|
|
34
43
|
};
|
|
35
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Generate the property name
|
|
47
|
+
*/
|
|
36
48
|
export const property = (name: string | string[]) => {
|
|
37
|
-
return
|
|
49
|
+
return `--${withPrefix(name)}`;
|
|
38
50
|
};
|
|
39
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Generate the name with var() syntax
|
|
54
|
+
*/
|
|
40
55
|
export const variable = (name: string | string[]) => {
|
|
41
|
-
return
|
|
56
|
+
return `var(${property(name)})`;
|
|
42
57
|
};
|