Skip to content

Commit

Permalink
Merge pull request #266 from raaymax/link-component
Browse files Browse the repository at this point in the history
feat: added link component
  • Loading branch information
ramedina86 authored Mar 3, 2024
2 parents 2c35845 + 952dd95 commit 26eb89a
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 4 deletions.
Binary file added docs/docs/public/components/link.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ui/src/builder/BuilderApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ function handleRendererClick(ev: PointerEvent): void {
const targetId = targetEl.dataset.streamsyncId;
const targetInstancePath = targetEl.dataset.streamsyncInstancePath;
if (targetId !== ssbm.getSelectedId()) {
ev.preventDefault();
ev.stopPropagation();
ssbm.setSelection(targetId, targetInstancePath);
}
Expand Down
12 changes: 11 additions & 1 deletion ui/src/builder/BuilderFieldsText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
:id="`list-${componentId}-${fieldKey}`"
>
<option
v-for="(option, optionKey) in templateField.options"
v-for="(option, optionKey) in options"
:key="optionKey"
:value="optionKey"
>
Expand Down Expand Up @@ -76,6 +76,16 @@ const templateField = computed(() => {
return definition.fields[fieldKey.value];
});
const options = computed(() => {
const field = templateField.value;
if (field.options) {
return typeof field.options === "function"
? field.options(ss, componentId.value)
: field.options;
}
return [];
});
const handleInput = (ev: Event) => {
setContentValue(
component.value.id,
Expand Down
2 changes: 2 additions & 0 deletions ui/src/core/templateMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import CorePlotlyGraph from "../core_components/content/CorePlotlyGraph.vue";
import CoreText from "../core_components/content/CoreText.vue";
import CoreVegaLiteChart from "../core_components/content/CoreVegaLiteChart.vue";
import CoreVideoPlayer from "../core_components/content/CoreVideoPlayer.vue";
import CoreLink from "../core_components/content/CoreLink.vue";
import CoreChat from "../core_components/content/CoreChat.vue";
// input
import CoreCheckboxInput from "../core_components/input/CoreCheckboxInput.vue";
Expand Down Expand Up @@ -73,6 +74,7 @@ const templateMap = {
columns: CoreColumns,
tab: CoreTab,
tabs: CoreTabs,
link: CoreLink,
horizontalstack: CoreHorizontalStack,
separator: CoreSeparator,
image: CoreImage,
Expand Down
81 changes: 81 additions & 0 deletions ui/src/core_components/content/CoreLink.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<template>
<div class="CoreLink">
<a
:href="fields.url.value"
:target="fields.target.value"
:rel="fields.rel.value"
>
{{ displayText }}
</a>
</div>
</template>

<script lang="ts">
import { FieldType, Core } from "../../streamsyncTypes";
import { cssClasses, primaryTextColor } from "../../renderer/sharedStyleFields";
import injectionKeys from "../../injectionKeys";
export default {
streamsync: {
name: "Link",
description: "A component to create a hyperlink.",
category: "Content",
fields: {
url: {
name: "URL",
type: FieldType.Text,
default: "https://streamsync.cloud",
desc: "Specify a URL or choose a page. Keep in mind that you can only link to pages for which a key has been specified.",
options: (ss: Core) => {
return Object.fromEntries(
ss
.getComponents("root", true)
.map((page) => page.content.key)
.filter((key) => Boolean(key))
.map((key) => [`#${key}`, `Page with key: ${key}`]),
);
},
},
target: {
name: "Target",
type: FieldType.Text,
options: {
_self: "Self",
_blank: "Blank",
_parent: "Parent",
_top: "Top",
},
desc: "Specifies where to open the linked document.",
default: "_self",
},
rel: {
name: "Rel",
type: FieldType.Text,
desc: "Specifies the relationship between the current document and the linked document.",
},
text: {
name: "Text",
default: "",
type: FieldType.Text,
desc: "The text to display in the link.",
},
primaryTextColor,
cssClasses,
},
},
};
</script>

<script setup lang="ts">
import { inject, computed } from "vue";
const fields = inject(injectionKeys.evaluatedFields);
const displayText = computed(() => {
return fields.text.value || fields.url.value;
});
</script>

<style scoped>
.CoreLink a {
color: var(--primaryTextColor);
}
</style>
14 changes: 11 additions & 3 deletions ui/src/streamsyncTypes.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { generateCore } from "./core";
import { generateBuilderManager } from "./builder/builderManager";

export type Core = ReturnType<typeof generateCore>;

type ComponentId = string;

/**
* Basic building block of applications.
* Multiple instances of a single component can exists. For example, via Repeater.
*/

export type Component = {
id: string;
id: ComponentId;
parentId: string;
type: string;
position: number;
Expand Down Expand Up @@ -55,7 +59,12 @@ export type StreamsyncComponentDefinition = {
desc?: string; // Description
default?: string; // Value used if the field is empty, e.g. "(No text)"
control?: FieldControl; // Which control (text, textarea, etc) to use if not the default for the type
options?: Record<string, string>; // List of values to be provided as autocomplete options
options?:
| Record<string, string>
| ((
ss?: Core,
componentId?: ComponentId,
) => Record<string, string>); // List of values to be provided as autocomplete options
type: FieldType; // Data type for the field
category?: FieldCategory; // Category (Layout, Content, etc)
applyStyleVariable?: boolean; // Use the value of this field as a CSS variable
Expand All @@ -73,7 +82,6 @@ export type StreamsyncComponentDefinition = {
positionless?: boolean; // Whether this type of component is positionless (like Sidebar)
};

export type Core = ReturnType<typeof generateCore>;
export type BuilderManager = ReturnType<typeof generateBuilderManager>;

export const enum ClipboardOperation {
Expand Down

0 comments on commit 26eb89a

Please sign in to comment.