routie dev init since i didn't adhere to any proper guidance up until now

This commit is contained in:
2026-04-29 22:27:29 -06:00
commit e1dabb71e2
15301 changed files with 3562618 additions and 0 deletions
@@ -0,0 +1,190 @@
import type { PropType, Ref, VNode } from 'vue';
import type { GenericProps } from '../../util/index.js';
export type VConfirmEditSlots<T> = {
default: {
model: Ref<T>;
save: () => void;
cancel: () => void;
isPristine: boolean;
get actions(): (props?: {}) => VNode;
};
};
export declare const makeVConfirmEditProps: <Defaults extends {
modelValue?: unknown;
color?: unknown;
cancelText?: unknown;
okText?: unknown;
disabled?: unknown;
hideActions?: unknown;
} = {}>(defaults?: Defaults | undefined) => {
modelValue: unknown extends Defaults["modelValue"] ? null : {
type: PropType<unknown extends Defaults["modelValue"] ? any : any>;
default: unknown extends Defaults["modelValue"] ? any : any;
};
color: unknown extends Defaults["color"] ? StringConstructor : {
type: PropType<unknown extends Defaults["color"] ? string : string | Defaults["color"]>;
default: unknown extends Defaults["color"] ? string : string | Defaults["color"];
};
cancelText: unknown extends Defaults["cancelText"] ? {
type: StringConstructor;
default: string;
} : Omit<{
type: StringConstructor;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["cancelText"] ? string : string | Defaults["cancelText"]>;
default: unknown extends Defaults["cancelText"] ? string : string | Defaults["cancelText"];
};
okText: unknown extends Defaults["okText"] ? {
type: StringConstructor;
default: string;
} : Omit<{
type: StringConstructor;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["okText"] ? string : string | Defaults["okText"]>;
default: unknown extends Defaults["okText"] ? string : string | Defaults["okText"];
};
disabled: unknown extends Defaults["disabled"] ? {
type: PropType<boolean | ('save' | 'cancel')[]>;
default: undefined;
} : Omit<{
type: PropType<boolean | ('save' | 'cancel')[]>;
default: undefined;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["disabled"] ? boolean | ("cancel" | "save")[] : boolean | ("cancel" | "save")[] | Defaults["disabled"]>;
default: unknown extends Defaults["disabled"] ? boolean | ("cancel" | "save")[] : Defaults["disabled"] | NonNullable<boolean | ("cancel" | "save")[]>;
};
hideActions: unknown extends Defaults["hideActions"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["hideActions"] ? boolean : boolean | Defaults["hideActions"]>;
default: unknown extends Defaults["hideActions"] ? boolean : boolean | Defaults["hideActions"];
};
};
export declare const VConfirmEdit: {
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<{
cancelText: string;
okText: string;
hideActions: boolean;
} & {
color?: string | undefined;
disabled?: boolean | ("cancel" | "save")[] | undefined;
} & {
onCancel?: (() => any) | undefined;
}, {
save: () => void;
cancel: () => void;
isPristine: import("vue").ComputedRef<boolean>;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Omit<{
cancel: () => true;
save: (value: any) => true;
'update:modelValue': (value: any) => true;
}, "$children" | "modelValue" | "save" | "update:modelValue" | "v-slot:default" | "v-slots">, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, {
cancelText: string;
okText: string;
disabled: boolean | ("cancel" | "save")[];
hideActions: boolean;
}, true, {}, import("vue").SlotsType<Partial<{
default: (arg: {
model: Ref<unknown, unknown>;
save: () => void;
cancel: () => void;
isPristine: boolean;
readonly actions: (props?: {}) => VNode;
}) => VNode[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, {
cancelText: string;
okText: string;
hideActions: boolean;
} & {
color?: string | undefined;
disabled?: boolean | ("cancel" | "save")[] | undefined;
} & {
onCancel?: (() => any) | undefined;
}, {
save: () => void;
cancel: () => void;
isPristine: import("vue").ComputedRef<boolean>;
}, {}, {}, {}, {
cancelText: string;
okText: string;
disabled: boolean | ("cancel" | "save")[];
hideActions: boolean;
}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & import("vue").ComponentOptionsBase<{
cancelText: string;
okText: string;
hideActions: boolean;
} & {
color?: string | undefined;
disabled?: boolean | ("cancel" | "save")[] | undefined;
} & {
onCancel?: (() => any) | undefined;
}, {
save: () => void;
cancel: () => void;
isPristine: import("vue").ComputedRef<boolean>;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Omit<{
cancel: () => true;
save: (value: any) => true;
'update:modelValue': (value: any) => true;
}, "$children" | "modelValue" | "save" | "update:modelValue" | "v-slot:default" | "v-slots">, string, {
cancelText: string;
okText: string;
disabled: boolean | ("cancel" | "save")[];
hideActions: boolean;
}, {}, string, import("vue").SlotsType<Partial<{
default: (arg: {
model: Ref<unknown, unknown>;
save: () => void;
cancel: () => void;
isPristine: boolean;
readonly actions: (props?: {}) => VNode;
}) => VNode[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new <T>(props: {
modelValue?: T;
'onUpdate:modelValue'?: (value: T) => void;
'onSave'?: (value: T) => void;
}, slots: VConfirmEditSlots<T>) => GenericProps<typeof props, typeof slots>) & import("../../util/index.js").FilterPropsOptions<{
modelValue: null;
color: StringConstructor;
cancelText: {
type: StringConstructor;
default: string;
};
okText: {
type: StringConstructor;
default: string;
};
disabled: {
type: PropType<boolean | ('save' | 'cancel')[]>;
default: undefined;
};
hideActions: BooleanConstructor;
}, import("vue").ExtractPropTypes<{
modelValue: null;
color: StringConstructor;
cancelText: {
type: StringConstructor;
default: string;
};
okText: {
type: StringConstructor;
default: string;
};
disabled: {
type: PropType<boolean | ('save' | 'cancel')[]>;
default: undefined;
};
hideActions: BooleanConstructor;
}>>;
export type VConfirmEdit = InstanceType<typeof VConfirmEdit>;
@@ -0,0 +1,102 @@
import { Fragment as _Fragment, mergeProps as _mergeProps, createVNode as _createVNode, createElementVNode as _createElementVNode } from "vue";
// Components
import { VBtn } from "../VBtn/index.js"; // Composables
import { useLocale } from "../../composables/locale.js";
import { useProxiedModel } from "../../composables/proxiedModel.js"; // Utilities
import { computed, ref, watchEffect } from 'vue';
import { deepEqual, deepToRaw, genericComponent, propsFactory, useRender } from "../../util/index.js"; // Types
export const makeVConfirmEditProps = propsFactory({
modelValue: null,
color: String,
cancelText: {
type: String,
default: '$vuetify.confirmEdit.cancel'
},
okText: {
type: String,
default: '$vuetify.confirmEdit.ok'
},
disabled: {
type: [Boolean, Array],
default: undefined
},
hideActions: Boolean
}, 'VConfirmEdit');
export const VConfirmEdit = genericComponent()({
name: 'VConfirmEdit',
props: makeVConfirmEditProps(),
emits: {
cancel: () => true,
save: value => true,
'update:modelValue': value => true
},
setup(props, {
emit,
slots
}) {
const model = useProxiedModel(props, 'modelValue');
const internalModel = ref();
watchEffect(() => {
internalModel.value = structuredClone(deepToRaw(model.value));
});
const {
t
} = useLocale();
const isPristine = computed(() => {
return deepEqual(model.value, internalModel.value);
});
function isActionDisabled(action) {
if (typeof props.disabled === 'boolean') {
return props.disabled;
}
if (Array.isArray(props.disabled)) {
return props.disabled.includes(action);
}
return isPristine.value;
}
const isSaveDisabled = computed(() => isActionDisabled('save'));
const isCancelDisabled = computed(() => isActionDisabled('cancel'));
function save() {
model.value = internalModel.value;
emit('save', internalModel.value);
}
function cancel() {
internalModel.value = structuredClone(deepToRaw(model.value));
emit('cancel');
}
function actions(actionsProps) {
return _createElementVNode(_Fragment, null, [_createVNode(VBtn, _mergeProps({
"disabled": isCancelDisabled.value,
"variant": "text",
"color": props.color,
"onClick": cancel,
"text": t(props.cancelText)
}, actionsProps), null), _createVNode(VBtn, _mergeProps({
"disabled": isSaveDisabled.value,
"variant": "text",
"color": props.color,
"onClick": save,
"text": t(props.okText)
}, actionsProps), null)]);
}
let actionsUsed = false;
useRender(() => {
return _createElementVNode(_Fragment, null, [slots.default?.({
model: internalModel,
save,
cancel,
isPristine: isPristine.value,
get actions() {
actionsUsed = true;
return actions;
}
}), !props.hideActions && !actionsUsed && actions()]);
});
return {
save,
cancel,
isPristine
};
}
});
//# sourceMappingURL=VConfirmEdit.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,76 @@
import { createElementVNode as _createElementVNode, createVNode as _createVNode, Fragment as _Fragment, createTextVNode as _createTextVNode } from "vue";
// Components
import { VConfirmEdit } from "../index.js"; // Utilities
import { render, screen, userEvent } from '@test';
import { nextTick, shallowRef } from 'vue';
describe('VConfirmEdit', () => {
it('mirrors external updates', async () => {
const externalModel = shallowRef('foo');
render(() => _createVNode(VConfirmEdit, {
"modelValue": externalModel.value
}, {
default: ({
model
}) => _createElementVNode("p", null, [model.value])
}));
expect(screen.getByText('foo')).toBeVisible();
externalModel.value = 'bar';
await nextTick();
expect(screen.getByText('bar')).toBeVisible();
});
it("doesn't mutate the original value", async () => {
const externalModel = shallowRef(['foo']);
render(() => _createVNode(VConfirmEdit, {
"modelValue": externalModel.value,
"onUpdate:modelValue": $event => externalModel.value = $event
}, {
default: ({
model
}) => _createElementVNode(_Fragment, null, [_createElementVNode("p", null, [model.value.join(',')]), _createElementVNode("button", {
"data-testid": "push",
"onClick": () => model.value.push('bar')
}, [_createTextVNode("Push")])])
}));
expect(screen.getByText('foo')).toBeVisible();
await userEvent.click(screen.getByTestId('push'));
expect(screen.getByText('foo,bar')).toBeVisible();
expect(externalModel.value).toEqual(['foo']);
await userEvent.click(screen.getByText('OK'));
expect(externalModel.value).toEqual(['foo', 'bar']);
});
describe('hides actions if used from the slot', () => {
it('nothing', () => {
render(() => _createVNode(VConfirmEdit, null, null));
expect(screen.getAllByCSS('button')).toHaveLength(2);
});
it('consume model', () => {
render(() => _createVNode(VConfirmEdit, null, {
default: ({
model
}) => {
void model;
}
}));
expect(screen.getAllByCSS('button')).toHaveLength(2);
});
it('consume actions', () => {
render(() => _createVNode(VConfirmEdit, null, {
default: ({
actions
}) => {
void actions;
}
}));
expect(screen.queryAllByCSS('button')).toHaveLength(0);
});
it('render actions', () => {
render(() => _createVNode(VConfirmEdit, null, {
default: ({
actions
}) => actions()
}));
expect(screen.getAllByCSS('button')).toHaveLength(2);
});
});
});
//# sourceMappingURL=VConfirmEdit.spec.browser.js.map
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
export { VConfirmEdit } from './VConfirmEdit.js';
+2
View File
@@ -0,0 +1,2 @@
export { VConfirmEdit } from "./VConfirmEdit.js";
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":["VConfirmEdit"],"sources":["../../../src/components/VConfirmEdit/index.ts"],"sourcesContent":["export { VConfirmEdit } from './VConfirmEdit'\n"],"mappings":"SAASA,YAAY","ignoreList":[]}