Skip to content

Commit

Permalink
Merge pull request #211 from streamsync-cloud/dev
Browse files Browse the repository at this point in the history
Merge branch 'master' into dev
  • Loading branch information
ramedina86 authored Jan 28, 2024
2 parents 58a9fe9 + 0705a56 commit c7f58bd
Show file tree
Hide file tree
Showing 11 changed files with 319 additions and 68 deletions.
245 changes: 245 additions & 0 deletions ui/src/builder/BuilderFieldsWidth.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
<template>
<div class="BuilderFieldsWidth" tabindex="-1" ref="rootEl">
<div class="chipStackContainer">
<div class="chipStack">
<button
class="chip"
tabindex="0"
:class="{ active: mode == 'default' }"
v-on:click="
() => {
setMode('default');
setContentValue(component.id, fieldKey, undefined);
}
"
>
Default
</button>
<button
class="chip"
tabindex="0"
:class="{ active: mode == 'css' }"
v-on:click="setMode('css')"
>
CSS
</button>
<button
class="chip"
:class="{ active: mode == 'pick' }"
tabindex="0"
v-on:click="setMode('pick')"
>
Pick
</button>
</div>
</div>

<div class="main" v-if="mode == 'pick' || mode == 'css'">
<div class="pickerContainer" v-if="mode == 'pick'">
<BuilderSelect :defaultValue=subMode :options=selectOptions @select="handleInputSelect"/>
<div v-if="subMode == SubMode.fixed" class="fixedContainer">
<input type="text" :value="valuePickFixed" v-on:input="handleInputFixed" ref="fixedEl" />
<div>px</div>
</div>

</div>

<input
type="text"
ref="freehandInputEl"
:value="component.content[fieldKey]"
v-on:input="handleInputCss"
v-if="mode == 'css'"
/>
</div>
</div>
</template>

<script setup lang="ts">
import {
computed,
inject,
nextTick,
onBeforeUnmount,
onMounted,
Ref,
ref,
toRefs,
} from "vue";
import { Component } from "../streamsyncTypes";
import { useComponentActions } from "./useComponentActions";
import injectionKeys from "../injectionKeys";
import BuilderSelect from "./BuilderSelect.vue";
const ss = inject(injectionKeys.core);
const ssbm = inject(injectionKeys.builderManager);
const { setContentValue } = useComponentActions(ss, ssbm);
const rootEl: Ref<HTMLElement> = ref(null);
const pickerEl: Ref<HTMLInputElement> = ref(null);
const fixedEl: Ref<HTMLInputElement> = ref(null);
const freehandInputEl: Ref<HTMLInputElement> = ref(null);
type Mode = "pick" | "css" | "default";
enum SubMode {
fixed = "fixed",
fit_content = "fit-content",
full = "full",
}
const subModes: Array<{key: SubMode, label: string, match: (v: string) => boolean, default: string, icon?: string}> = [
{'key': SubMode.fixed, label: 'Fixed', match: (v) => v.endsWith('px'), default: '160px'},
{'key': SubMode.fit_content, label: 'Fit Content', match: (v) => v == 'fit-content', default: 'fit-content'},
{'key': SubMode.full, label: 'Full', match: (v) => v == '100%', default: '100%'},
]
const focusEls: Record<Mode, Ref<HTMLInputElement>> = {
pick: pickerEl,
css: freehandInputEl,
default: null,
};
const props = defineProps<{
componentId: Component["id"];
fieldKey: string;
}>();
const { componentId, fieldKey } = toRefs(props);
const component = computed(() => ss.getComponentById(componentId.value));
const selectOptions = computed(() => {
return subModes.map((m) => {
return { value: m.key, label: m.label, icon: "ri-split-cells-horizontal" };
});
});
const subMode = computed(() => {
const value = component.value.content[fieldKey.value]
for (const k in subModes) {
if (value && subModes[k].match(value)) {
return subModes[k].key
}
}
return null
})
const valueCss = computed(() => {
const value = component.value.content[fieldKey.value]
if (!value) {
return ''
} else {
return value
}
})
const valuePickFixed = computed(() => {
const value = component.value.content[fieldKey.value]
if (!value) {
return null
} else if (value.endsWith('px')) {
return value.substring(0, value.length - 2)
}
return null
})
const getInitialMode = (): Mode => {
if (!valueCss.value) {
return "default";
}
for (const k in subModes) {
if (subModes[k].match(valueCss.value)) {
return "pick"
}
}
return "css";
};
const mode: Ref<Mode> = ref(getInitialMode());
const autofocus = () => {
const focusEl = focusEls[mode.value]?.value;
if (!focusEl) return;
focusEl.focus();
if (typeof focusEl.selectionStart !== "number") return;
focusEl.selectionStart = focusEl.selectionEnd = focusEl.value.length;
};
const setMode = async (newMode: Mode) => {
if (mode.value == newMode) return;
mode.value = newMode;
await nextTick();
autofocus();
};
const handleInputSelect = (select: string) => {
for (const k in subModes) {
if (subModes[k].key == select) {
const value = subModes[k].default;
component.value.content[fieldKey.value] = value;
setContentValue(
component.value.id,
fieldKey.value,
value
);
}
}
if (select == SubMode.fixed) {
nextTick(() => {
fixedEl.value.focus();
});
}
}
const handleInputCss = (ev: Event) => {
setContentValue(
component.value.id,
fieldKey.value,
(ev.target as HTMLInputElement).value
)
}
const handleInputFixed = (ev: Event) => {
setContentValue(
component.value.id,
fieldKey.value,
(ev.target as HTMLInputElement).value + 'px'
)
}
onMounted(() => {
rootEl.value.addEventListener("focus", autofocus);
});
onBeforeUnmount(() => {
rootEl.value.removeEventListener("focus", autofocus);
});
</script>

<style scoped>
@import "./sharedStyles.css";
.chipStackContainer {
padding: 12px;
margin-top: 4px;
padding-bottom: 12px;
}
.main {
border-top: 1px solid var(--builderSeparatorColor);
padding: 12px;
}
.fixedContainer {
display: flex;
flex-direction: row;
gap: 8px;
padding: 8px;
}
</style>
4 changes: 2 additions & 2 deletions ui/src/core_components/CoreButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
</template>

<script lang="ts">
import { FieldCategory, FieldType } from "../streamsyncTypes";
import {
buttonColor,
buttonTextColor,
buttonShadow,
separatorColor,
cssClasses
cssClasses,
} from "../renderer/sharedStyleFields";
import { watch } from "vue";
import { getClick } from "../renderer/syntheticEvents";
Expand Down Expand Up @@ -79,7 +80,6 @@ export default {
</script>
<script setup lang="ts">
import { Ref, inject, ref } from "vue";
import { FieldCategory, FieldType } from "../streamsyncTypes";
import injectionKeys from "../injectionKeys";
const rootEl:Ref<HTMLElement> = ref(null);
Expand Down
3 changes: 2 additions & 1 deletion ui/src/core_components/CoreColumns.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
</template>

<script lang="ts">
import { cssClasses } from "../renderer/sharedStyleFields";
export default {
streamsync: {
name: "Column Container",
Expand All @@ -21,7 +23,6 @@ export default {
<script setup lang="ts">
import { inject } from "vue";
import injectionKeys from "../injectionKeys";
import { cssClasses } from "../renderer/sharedStyleFields";
const instanceData = inject(injectionKeys.instanceData);
instanceData.at(-1).value = { minimumNonCollapsiblePosition: undefined };
Expand Down
5 changes: 3 additions & 2 deletions ui/src/core_components/CoreHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
</template>

<script lang="ts">
import { FieldType } from "../streamsyncTypes";
import { accentColor, cssClasses, emptinessColor } from "../renderer/sharedStyleFields";
const description =
"A container component that typically contains the main navigation elements.";
Expand All @@ -36,9 +39,7 @@ export default {
</script>
<script setup lang="ts">
import { inject } from "vue";
import { FieldType } from "../streamsyncTypes";
import injectionKeys from "../injectionKeys";
import { accentColor, cssClasses, emptinessColor } from "../renderer/sharedStyleFields";
const fields = inject(injectionKeys.evaluatedFields);
</script>
Expand Down
5 changes: 3 additions & 2 deletions ui/src/core_components/CoreHeading.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
</template>

<script lang="ts">
import { FieldCategory, FieldType } from "../streamsyncTypes";
import { cssClasses, primaryTextColor } from "../renderer/sharedStyleFields";
const description =
"A text component used to display headings or titles in different sizes and styles.";
Expand Down Expand Up @@ -55,9 +58,7 @@ export default {
</script>
<script setup lang="ts">
import { inject } from "vue";
import { FieldCategory, FieldType } from "../streamsyncTypes";
import injectionKeys from "../injectionKeys";
import { cssClasses, primaryTextColor } from "../renderer/sharedStyleFields";
const fields = inject(injectionKeys.evaluatedFields);
</script>
<style scoped>
Expand Down
Loading

0 comments on commit c7f58bd

Please sign in to comment.