Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into dropdown/combobox
Browse files Browse the repository at this point in the history
  • Loading branch information
mlmoravek committed Dec 17, 2024
2 parents f0a5e89 + f0eccaf commit 3c53fb8
Show file tree
Hide file tree
Showing 16 changed files with 86 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# These are supported funding model platforms

ko_fi: orugaui
ko_fi: mlmoravek
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<a href="https://www.npmjs.com/package/@oruga-ui/oruga-next"><img src="https://img.shields.io/npm/dt/@oruga-ui/oruga-next.svg" /></a>
<a href="https://github.com/oruga-ui/oruga/actions"><img src="https://github.com/oruga-ui/oruga/actions/workflows/build.yml/badge.svg" /><a>
<a href="https://discord.gg/RuKuBYN"><img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg?logo=discord" /></a>
<a href="https://ko-fi.com/mlmoravek"><img src="https://img.shields.io/badge/ko--fi-donate-%23FF5E5B?style=flat&logo=ko-fi&logoColor=white" /></a>
</p>

<p align="center">
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default defineConfig({
{ text: "Expo", link: "/expo/" },
{
text: "Support",
items: [{ text: "Ko-fi", link: "https://ko-fi.com/orugaui" }],
items: [{ text: "Ko-fi", link: "https://ko-fi.com/mlmoravek" }],
},
{
text: `v${version}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const datepicker = ref();
// get programmatic oruga access
const oruga = useOruga();
const triggerClass =
oruga.config.getOption("input.iconLeftClass", "o-input__icon-left") ??
"o-input__icon-left";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<script setup lang="ts">
import { getCurrentInstance, ref } from "vue";
import { ref } from "vue";
import { useOruga } from "@/utils/programmatic";
const datetimepicker = ref();
// get programmatic oruga access
const app = getCurrentInstance();
const oruga = app?.appContext.config.globalProperties.$oruga;
const triggerClass = oruga?.config
? oruga.config.getOption("dropdown.triggerClass", "o-drop__trigger")
: "o-drop__trigger";
const oruga = useOruga();
const triggerClass =
oruga.config.getOption("input.iconLeftClass", "o-input__icon-left") ??
"o-input__icon-left";
function openDatetimePicker() {
setTimeout(() => {
Expand Down
5 changes: 3 additions & 2 deletions packages/oruga/src/components/input/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import OIcon from "../icon/Icon.vue";
import { getDefault } from "@/utils/config";
import { isTrueish } from "@/utils/helpers";
import { defineClasses, useDebounce, useInputHandler } from "@/composables";
import { injectField } from "../field/fieldInjection";
Expand Down Expand Up @@ -129,7 +130,7 @@ const vmodel = defineModel<ModelValue, string, string, ModelValue>({
set: (value) =>
typeof value == "undefined"
? value
: props.number
: isTrueish(props.number)
? Number(value)
: String(value),
default: undefined,
Expand Down Expand Up @@ -231,7 +232,7 @@ function iconClick(event: Event): void {
function rightIconClick(event: Event): void {
if (props.passwordReveal) togglePasswordVisibility();
else if (props.clearable)
vmodel.value = (props.number ? 0 : "") as ModelValue;
vmodel.value = (isTrueish(props.number) ? 0 : "") as ModelValue;
if (props.iconRightClickable) {
emits("icon-right-click", event);
nextTick(() => setFocus());
Expand Down
8 changes: 4 additions & 4 deletions packages/oruga/src/components/steps/StepItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const providedData = computed<StepItemComponent<T>>(() => ({
value: itemValue,
$slots: slots,
navClasses: navItemClasses.value,
classes: stepClasses.value,
stepClasses: stepClasses.value,
labelClasses: stepLabelClasses.value,
iconClasses: stepIconClasses.value,
isTransitioning: isTransitioning.value,
Expand All @@ -62,9 +62,9 @@ const providedData = computed<StepItemComponent<T>>(() => ({
}));
/** inject functionalities and data from the parent component */
const { parent, item } = useProviderChild<StepsComponent>({
data: providedData,
});
const { parent, item } = useProviderChild<StepsComponent, StepItemComponent<T>>(
{ data: providedData },
);
const transitionName = ref();
Expand Down
23 changes: 11 additions & 12 deletions packages/oruga/src/components/steps/Steps.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const vmodel = defineModel<ModelValue>({ default: undefined });
// provided data is a computed ref to enjure reactivity
const provideData = computed<StepsComponent>(() => ({
activeIndex: activeItem.value?.index || 0,
activeIndex: activeItem.value?.index ?? 0,
labelPosition: props.labelPosition,
vertical: props.vertical,
animated: props.animated,
Expand Down Expand Up @@ -133,11 +133,10 @@ watch(
},
);
const activeItem = ref<StepItem<T>>(
items.value.find((item) => item.value === props.modelValue) ||
items.value[0],
);
/** the active item */
const activeItem = ref<StepItem<T>>();
// set the active item immediate and every time the vmodel changes
watchEffect(() => {
activeItem.value = isDefined(vmodel.value)
? items.value.find((item) => item.value === vmodel.value) ||
Expand All @@ -162,7 +161,7 @@ const prevItem = computed(() => {
let prevItem: StepItem<T> | undefined;
let idx =
items.value.findIndex(
(item) => item.identifier === activeItem.value.identifier,
(item) => item.identifier === activeItem.value?.identifier,
) - 1;
for (; idx >= 0; idx--) {
if (items.value[idx].visible) {
Expand All @@ -178,7 +177,7 @@ const nextItem = computed(() => {
let nextItem: StepItem<T> | undefined;
let idx = activeItem.value
? items.value.findIndex(
(item) => item.identifier === activeItem.value.identifier,
(item) => item.identifier === activeItem.value?.identifier,
) + 1
: 0;
for (; idx < items.value.length; idx++) {
Expand All @@ -193,7 +192,7 @@ const nextItem = computed(() => {
/** Return if the step should be clickable or not. */
function isItemClickable(item: StepItem<T>): boolean {
if (item.clickable === undefined)
return item.index < activeItem.value?.index;
return item.index < (activeItem.value?.index ?? 0);
return item.clickable;
}
Expand All @@ -214,7 +213,7 @@ function itemClick(item: StepItem<T>): void {
/** Activate next child and deactivate prev child */
function performAction(newValue: T): void {
const oldValue = activeItem.value.value;
const oldValue = activeItem.value?.value;
const oldItem = activeItem.value;
const newItem =
items.value.find((item) => item.value === newValue) || items.value[0];
Expand Down Expand Up @@ -313,17 +312,17 @@ const navigationClasses = defineClasses([
:class="childItem.navClasses"
:role="childItem.ariaRole"
:aria-current="
childItem.value === activeItem.value ? 'step' : undefined
childItem.value === activeItem?.value ? 'step' : undefined
"
:aria-controls="`tabpanel-${childItem.identifier}`"
:aria-selected="childItem.value === activeItem.value">
:aria-selected="childItem.value === activeItem?.value">
<span v-if="index > 0" :class="dividerClasses" />

<component
:is="childItem.tag"
role="button"
:tabindex="isItemClickable(childItem) ? 0 : null"
:class="childItem.classes"
:class="childItem.stepClasses"
@click="isItemClickable(childItem) && itemClick(childItem)"
@keydown.enter="
isItemClickable(childItem) && itemClick(childItem)
Expand Down
22 changes: 11 additions & 11 deletions packages/oruga/src/components/steps/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,6 @@ import type { ClassBind } from "@/types";

import type { StepItemProps } from "./props";

export type StepItemComponent<T> = StepItemProps<T, Component> & {
$slots: Slots;
navClasses: ClassBind[];
classes: ClassBind[];
iconClasses: ClassBind[];
labelClasses: ClassBind[];
isTransitioning: boolean;
activate: (index: number) => void;
deactivate: (index: number) => void;
};

export type StepsComponent = {
activeIndex: number;
labelPosition: string;
Expand All @@ -26,4 +15,15 @@ export type StepsComponent = {
variant: string;
};

export type StepItemComponent<T> = StepItemProps<T, Component> & {
$slots: Slots;
navClasses: ClassBind[];
stepClasses: ClassBind[];
iconClasses: ClassBind[];
labelClasses: ClassBind[];
isTransitioning: boolean;
activate: (index: number) => void;
deactivate: (index: number) => void;
};

export type StepItem<T> = Omit<ProviderItem, "data"> & StepItemComponent<T>;
2 changes: 1 addition & 1 deletion packages/oruga/src/components/table/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ function handleColumnDragLeave(
const rootClasses = defineClasses(
["rootClass", "o-table__root"],
["mobileClass", "o-table__root--mobile", null, isMobile],
["mobileClass", "o-table__root--mobile", null, isMobileActive],
);
const tableClasses = defineClasses(
Expand Down
7 changes: 4 additions & 3 deletions packages/oruga/src/components/table/TableColumn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ const providedData = computed<TableColumnComponent<T>>(() => ({
}));
/** inject functionalities and data from the parent component */
const { parent, item } = useProviderChild<TableComponent>({
data: providedData,
});
const { parent, item } = useProviderChild<
TableComponent,
TableColumnComponent<T>
>({ data: providedData });
// --- Computed Component Classes ---
Expand Down
2 changes: 1 addition & 1 deletion packages/oruga/src/components/tabs/TabItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const providedData = computed<TabItemComponent<T>>(() => ({
value: itemValue,
$slots: slots,
navClasses: navItemClasses.value,
classes: tabClasses.value,
tabClasses: tabClasses.value,
iconClasses: tabIconClasses.value,
labelClasses: tabLabelClasses.value,
isTransitioning: isTransitioning.value,
Expand Down
23 changes: 10 additions & 13 deletions packages/oruga/src/components/tabs/Tabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const vmodel = defineModel<ModelValue>({ default: undefined });
// provided data is a computed ref to enjure reactivity
const provideData = computed<TabsComponent>(() => ({
activeIndex: activeItem.value?.index || 0,
activeIndex: activeItem.value?.index ?? 0,
type: props.type,
vertical: props.vertical,
animated: props.animated,
Expand Down Expand Up @@ -125,20 +125,17 @@ watch(
},
);
const activeItem = ref<TabItem<T>>(
items.value.find((item) => item.value === props.modelValue) ||
items.value[0],
);
/** the active item */
const activeItem = ref<TabItem<T>>();
// set the active item immediate and every time the vmodel changes
watchEffect(() => {
activeItem.value = isDefined(vmodel.value)
? items.value.find((item) => item.value === vmodel.value) ||
items.value[0]
: items.value[0];
});
const activeIndex = computed(() => activeItem.value.index);
const isTransitioning = computed(() =>
items.value.some((item) => item.isTransitioning),
);
Expand Down Expand Up @@ -221,7 +218,7 @@ function getFirstViableItem(
let newIndex = startingIndex;
for (
;
newIndex !== activeIndex.value;
newIndex !== activeItem.value?.index;
newIndex = mod(newIndex + direction, items.value.length)
) {
// Break if the item at this index is viable (not disabled and is visible)
Expand Down Expand Up @@ -322,18 +319,18 @@ const contentClasses = defineClasses(
:class="childItem.navClasses"
role="tab"
:aria-controls="`tabpanel-${childItem.identifier}`"
:aria-selected="childItem.value === activeItem.value"
:aria-selected="childItem.value === activeItem?.value"
:tabindex="
childItem.value === activeItem.value ? undefined : '-1'
childItem.value === activeItem?.value ? undefined : '-1'
">
<o-slot-component
v-if="childItem.$slots.header"
:component="childItem"
:tag="childItem.tag"
name="header"
:class="childItem.classes"
:class="childItem.tabClasses"
:props="{
active: childItem.index === activeIndex,
active: childItem.index === activeItem?.index,
}"
@click="tabClick(childItem)"
@keydown.enter="tabClick(childItem)"
Expand All @@ -349,7 +346,7 @@ const contentClasses = defineClasses(
v-else
role="button"
:tabindex="0"
:class="childItem.classes"
:class="childItem.tabClasses"
@click="tabClick(childItem)"
@keydown.enter="tabClick(childItem)"
@keydown.left="prev($event, childItem.index)"
Expand Down
18 changes: 10 additions & 8 deletions packages/oruga/src/components/tabs/tests/tabs.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe("OTab with OTabItem tests", () => {

test("renders the tab buttons", async () => {
const wrapper = mount(componentWrapper);
await wrapper.vm.$nextTick();
await nextTick();

const tabButtons = wrapper.findAll(".o-tabs__nav-item");

Expand All @@ -81,7 +81,7 @@ describe("OTab with OTabItem tests", () => {

test("renders the tab panels", async () => {
const wrapper = mount(componentWrapper, { attachTo: document.body });
await wrapper.vm.$nextTick();
await nextTick();

const tabPanls = wrapper.findAll(`[data-oruga="tabs-item"]`);

Expand All @@ -96,22 +96,24 @@ describe("OTab with OTabItem tests", () => {

test("switches the content based on the tab clicked", async () => {
const wrapper = mount(componentWrapper, { attachTo: document.body });
await wrapper.vm.$nextTick();
await nextTick();

const tabs = wrapper.findAll(".o-tabs__tab");
const tabPanls = wrapper.findAll(`[data-oruga="tabs-item"]`);
const tabPanels = wrapper.findAll(`[data-oruga="tabs-item"]`);
expect(tabs).toHaveLength(3);
expect(tabPanels).toHaveLength(3);

// clicking the second tab reveals the second content
// and hides the first content
await tabs[1].trigger("click");
expect(tabPanls[1].isVisible()).toBeTruthy();
expect(tabPanls[0].isVisible()).toBeFalsy();
expect(tabPanels[1].isVisible()).toBeTruthy();
expect(tabPanels[0].isVisible()).toBeFalsy();

// clicking the third tab reveals the third content
// and hides the second content
await tabs[2].trigger("click");
expect(tabPanls[2].isVisible()).toBeTruthy();
expect(tabPanls[1].isVisible()).toBeFalsy();
expect(tabPanels[2].isVisible()).toBeTruthy();
expect(tabPanels[1].isVisible()).toBeFalsy();
});

test("render item with component prop correctly", () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/oruga/src/components/tabs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type TabsComponent = {
destroyOnHide: boolean;
};


export type TabItemComponent<T> = TabItemProps<T, Component> & {
$slots: Slots;
navClasses: ClassBind[];
Expand All @@ -25,4 +26,4 @@ export type TabItemComponent<T> = TabItemProps<T, Component> & {
deactivate: (index: number) => void;
};

export type TabItem<T> = Omit<ProviderItem, "data"> & TabItemComponent<T>;
export type TabItem<T> = Omit<ProviderItem<T>, "data"> & TabItemComponent<T>;
Loading

0 comments on commit 3c53fb8

Please sign in to comment.