diff --git a/docs/framework/public/components/colorinput.png b/docs/framework/public/components/colorinput.png new file mode 100644 index 000000000..a0d96a8c5 Binary files /dev/null and b/docs/framework/public/components/colorinput.png differ diff --git a/src/ui/src/core/index.ts b/src/ui/src/core/index.ts index 04c434292..0e1242806 100644 --- a/src/ui/src/core/index.ts +++ b/src/ui/src/core/index.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/ban-types */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { ref, Ref } from "vue"; +import { computed, ref, Ref } from "vue"; import { Component, ComponentMap, @@ -8,14 +8,14 @@ import { MailItem, UserFunction, } from "../writerTypes"; +import { auditAndFixComponents } from "./auditAndFix"; +import { loadExtensions } from "./loadExtensions"; +import { parseAccessor } from "./parsing"; import { - getSupportedComponentTypes, getComponentDefinition, + getSupportedComponentTypes, } from "./templateMap"; import * as typeHierarchy from "./typeHierarchy"; -import { auditAndFixComponents } from "./auditAndFix"; -import { parseAccessor } from "./parsing"; -import { loadExtensions } from "./loadExtensions"; const RECONNECT_DELAY_MS = 1000; const KEEP_ALIVE_DELAY_MS = 60000; @@ -127,7 +127,7 @@ export function generateCore() { Object.entries(mutations).forEach(([key, value]) => { /* Splits the key while respecting escaped dots. - For example, "files.myfile\.sh" will be split into ["files", "myfile.sh"] + For example, "files.myfile\.sh" will be split into ["files", "myfile.sh"] */ const mutationFlag = key.charAt(0); @@ -443,8 +443,8 @@ export function generateCore() { */ async function sendComponentUpdate(): Promise { /* - Ensure that the backend receives only components - created by the frontend (Builder-managed components, BMC), + Ensure that the backend receives only components + created by the frontend (Builder-managed components, BMC), and not the components it generated (Code-managed components, CMC). */ @@ -594,6 +594,7 @@ export function generateCore() { getSessionTimestamp, getUserState, isChildOf, + components: computed(() => Object.values(components.value)), }; return core; diff --git a/src/ui/src/core/templateMap.ts b/src/ui/src/core/templateMap.ts index b9a476552..6a0606339 100644 --- a/src/ui/src/core/templateMap.ts +++ b/src/ui/src/core/templateMap.ts @@ -16,6 +16,7 @@ import CoreTags from "../core_components/content/CoreTags.vue"; import CoreAvatar from "../core_components/content/CoreAvatar.vue"; // input import CoreCheckboxInput from "../core_components/input/CoreCheckboxInput.vue"; +import CoreColorInput from "../core_components/input/CoreColorInput.vue"; import CoreDateInput from "../core_components/input/CoreDateInput.vue"; import CoreDropdownInput from "../core_components/input/CoreDropdownInput.vue"; import CoreFileInput from "../core_components/input/CoreFileInput.vue"; @@ -93,6 +94,7 @@ const templateMap = { textareainput: CoreTextareaInput, numberinput: CoreNumberInput, sliderinput: CoreSliderInput, + colorinput: CoreColorInput, dateinput: CoreDateInput, timeinput: CoreTimeInput, radioinput: CoreRadioInput, diff --git a/src/ui/src/core_components/base/BaseInputColor.vue b/src/ui/src/core_components/base/BaseInputColor.vue new file mode 100644 index 000000000..e6b7b8719 --- /dev/null +++ b/src/ui/src/core_components/base/BaseInputColor.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/src/ui/src/core_components/base/hooks/useId.ts b/src/ui/src/core_components/base/hooks/useId.ts new file mode 100644 index 000000000..eb20ae423 --- /dev/null +++ b/src/ui/src/core_components/base/hooks/useId.ts @@ -0,0 +1,9 @@ +/** + * Simply generate a uniq ID to use as HTML `id` attribute + */ +export default function useId() { + // `crypto.randomUUID` is only available in HTTPS context + return typeof crypto.randomUUID === "function" + ? crypto.randomUUID() + : Date.now().toString(); +} diff --git a/src/ui/src/core_components/input/CoreColorInput.vue b/src/ui/src/core_components/input/CoreColorInput.vue new file mode 100644 index 000000000..0c37e598a --- /dev/null +++ b/src/ui/src/core_components/input/CoreColorInput.vue @@ -0,0 +1,100 @@ + + + + + + diff --git a/src/ui/src/renderer/useFormValueBroker.ts b/src/ui/src/renderer/useFormValueBroker.ts index 8d19dabd7..3d2623973 100644 --- a/src/ui/src/renderer/useFormValueBroker.ts +++ b/src/ui/src/renderer/useFormValueBroker.ts @@ -1,6 +1,6 @@ import { ComponentPublicInstance, computed, Ref, ref, watch } from "vue"; -import { Core, InstancePath } from "../writerTypes"; import { useEvaluator } from "../renderer/useEvaluator"; +import { Core, InstancePath } from "../writerTypes"; /** * @@ -10,14 +10,14 @@ import { useEvaluator } from "../renderer/useEvaluator"; * @param componentId * @returns */ -export function useFormValueBroker( +export function useFormValueBroker( wf: Core, instancePath: InstancePath, emitterEl: Ref, ) { - const formValue: Ref = ref(); + const formValue: Ref = ref(); const isBusy = ref(false); - const queuedEvent: Ref<{ eventValue: any; emitEventType: string }> = + const queuedEvent: Ref<{ eventValue: T; emitEventType: string }> = ref(null); const componentId = instancePath.at(-1).componentId;