Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
feat: add link builtin component (#501)
Browse files Browse the repository at this point in the history
  • Loading branch information
marionebl authored and tilmx committed May 31, 2018
1 parent 7b67566 commit fb3fea7
Show file tree
Hide file tree
Showing 25 changed files with 291 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ function createArrayProperty(
contextId: args.symbol.name,
defaultValue: [],
description: '',
example: '',
hidden: false,
id: ctx.getPropertyId(args.symbol.name),
label: args.symbol.name,
Expand All @@ -144,6 +145,7 @@ function createArrayProperty(
contextId: args.symbol.name,
defaultValue: [],
description: '',
example: '',
hidden: false,
id: ctx.getPropertyId(args.symbol.name),
label: args.symbol.name,
Expand All @@ -164,6 +166,7 @@ function createBooleanProperty(
return {
contextId: args.symbol.name,
description: '',
example: '',
hidden: false,
id: ctx.getPropertyId(args.symbol.name),
label: args.symbol.name,
Expand Down Expand Up @@ -199,6 +202,7 @@ function createEnumProperty(
return {
contextId: args.symbol.name,
description: '',
example: '',
hidden: false,
id: enumId,
label: args.symbol.name,
Expand Down Expand Up @@ -232,6 +236,7 @@ function createNumberProperty(
return {
contextId: args.symbol.name,
description: '',
example: '',
hidden: false,
id: ctx.getPropertyId(args.symbol.name),
label: args.symbol.name,
Expand All @@ -250,6 +255,7 @@ function createStringProperty(
return {
contextId: args.symbol.name,
description: '',
example: '',
hidden: false,
id: ctx.getPropertyId(args.symbol.name),
label: args.symbol.name,
Expand All @@ -263,6 +269,7 @@ function createStringProperty(
return {
contextId: args.symbol.name,
description: '',
example: '',
hidden: false,
id: ctx.getPropertyId(args.symbol.name),
label: args.symbol.name,
Expand All @@ -283,13 +290,14 @@ function setPropertyMetaData(init: {

const { property, symbol } = init;

property.example = TypescriptUtils.getJsDocValueFromSymbol(symbol, 'example') || '';
property.required = (symbol.flags & Ts.SymbolFlags.Optional) !== Ts.SymbolFlags.Optional;
property.label = TypescriptUtils.getJsDocValueFromSymbol(symbol, 'name') || property.label;
property.description = TypescriptUtils.getJsDocValueFromSymbol(symbol, 'description') || '';
property.hidden = TypescriptUtils.symbolHasJsDocTag(symbol, 'ignore');

switch (property.type) {
case Types.PatternPropertyType.Enum:
case 'enum':
const defaultOption = property.options.find(
option => option.name === TypescriptUtils.getJsDocValueFromSymbol(symbol, 'default')
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/property-items/asset-item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface AssetItemProps {
onClearClick?: React.MouseEventHandler<HTMLButtonElement>;
onInputBlur?: React.ChangeEventHandler<HTMLInputElement>;
onInputChange?: React.ChangeEventHandler<HTMLInputElement>;
placeholder?: string;
}

export enum AssetPropertyInputType {
Expand Down Expand Up @@ -115,7 +116,7 @@ export const AssetItem: React.StatelessComponent<AssetItemProps> = props => (
onChange={props.onInputChange}
type="textarea"
value={props.inputValue}
placeholder="Enter external URL"
placeholder={props.placeholder}
/>
)}
{props.inputType === AssetPropertyInputType.File && (
Expand Down
3 changes: 2 additions & 1 deletion src/components/property-items/string-item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface StringItemProps {
label: string;
onBlur?: React.FocusEventHandler<HTMLInputElement>;
onChange?: React.ChangeEventHandler<HTMLInputElement>;
placeholder?: string;
value?: string;
}

Expand Down Expand Up @@ -71,7 +72,7 @@ export const StringItem: React.StatelessComponent<StringItemProps> = props => {
onBlur={onBlur}
type="text"
value={value || ''}
placeholder="…"
placeholder={props.placeholder}
/>
</StyledContainer>
{description && <PropertyDescription description={description || ''} />}
Expand Down
4 changes: 4 additions & 0 deletions src/container/property-list/property-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class PropertyViewContainer extends React.Component<PropertyViewContainerProps>
}

const base = { key: id, description, label };
const example = patternProperty.getExample();

// TODO: Split ElementProperty into type-specific classes for better type safety
// TODO: Implement inputs for
Expand Down Expand Up @@ -134,6 +135,7 @@ class PropertyViewContainer extends React.Component<PropertyViewContainerProps>
type: ServerMessageType.AssetReadRequest
});
}}
placeholder={example ? `e.g.: ${example}` : ''}
/>
);
}
Expand Down Expand Up @@ -173,6 +175,7 @@ class PropertyViewContainer extends React.Component<PropertyViewContainerProps>
value={value}
onBlur={e => this.handleInputBlur(e)}
onChange={e => this.handleInputChange(e)}
placeholder={example ? `e.g.: ${example}` : ''}
/>
);
}
Expand All @@ -184,6 +187,7 @@ class PropertyViewContainer extends React.Component<PropertyViewContainerProps>
value={property.getValue() as string}
onBlur={e => this.handleInputBlur(e)}
onChange={e => this.handleInputChange(e)}
placeholder={example ? `e.g.: ${example}` : ''}
/>
</div>
);
Expand Down
48 changes: 47 additions & 1 deletion src/electron/server.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { createCompiler } from '../compiler/create-compiler';
import * as Electron from 'electron';
import { EventEmitter } from 'events';
import * as express from 'express';
import * as Http from 'http';
import { isEqual } from 'lodash';
import { ServerMessage, ServerMessageType } from '../message';
import { previewDocument, PreviewDocumentMode } from '../preview/preview-document';
import * as Types from '../model/types';
import * as Url from 'url';
import * as uuid from 'uuid';
import { Compiler } from 'webpack';
import { OPEN, Server as WebsocketServer } from 'ws';
Expand Down Expand Up @@ -74,7 +76,51 @@ export async function createServer(opts: ServerOptions): Promise<EventEmitter> {
console.error(err);
});

ws.on('message', message => emitter.emit('client-message', message));
ws.on('message', envelope => {
emitter.emit('client-message', envelope);

try {
const message = JSON.parse(String(envelope));

switch (message.type) {
case 'click-element': {
const element = (state.payload.elements || []).find(
e => e.id === message.payload.id
);

if (!element) {
return;
}

const hrefPatternProp = (state.payload.patternProperties || []).find(
p => p.type === 'href'
);

if (!hrefPatternProp) {
return;
}

const hrefElementProp = element.properties.find(
p => p.patternPropertyId === hrefPatternProp.id
);

if (
hrefElementProp &&
typeof hrefElementProp.value === 'string' &&
hrefElementProp.value
) {
const parsed = Url.parse(hrefElementProp.value);

if (['http:', 'https:'].includes(parsed.protocol || '')) {
Electron.shell.openExternal(hrefElementProp.value);
}
}
}
}
} catch (err) {
console.error(err);
}
});
ws.send(JSON.stringify(state));
});

Expand Down
1 change: 1 addition & 0 deletions src/message/message.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as Types from '../model/types';

export enum PreviewMessageType {
ClickElement = 'click-element',
ContentRequest = 'content-request',
ContentResponse = 'content-response',
ElementChange = 'element-change',
Expand Down
1 change: 1 addition & 0 deletions src/model/pattern-library/builtins/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './box';
export * from './link';
export * from './page';
export * from './placeholder';
export * from './text';
51 changes: 51 additions & 0 deletions src/model/pattern-library/builtins/link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Pattern, PatternSlot } from '../../pattern';
import { BuiltInContext, BuiltInResult } from '../pattern-library';
import * as PatternProperty from '../../pattern-property';
import * as Types from '../../types';

const PATTERN_CONTEXT_ID = 'synthetic:link';
const SLOT_CONTEXT_ID = 'children';
const HREF_CONTEXT_ID = 'href';

export const Link = (context: BuiltInContext): BuiltInResult => {
const patternId = context.options.getGlobalPatternId(PATTERN_CONTEXT_ID);

const properties = [
new PatternProperty.PatternHrefProperty({
contextId: HREF_CONTEXT_ID,
example: 'https://meetalva.io',
id: context.options.getGlobalPropertyId(patternId, HREF_CONTEXT_ID),
label: 'Link target',
origin: Types.PatternPropertyOrigin.BuiltIn,
propertyName: 'href'
})
];

const slots = [
new PatternSlot({
contextId: SLOT_CONTEXT_ID,
displayName: 'Children',
propertyName: 'children',
id: context.options.getGlobalSlotId(patternId, SLOT_CONTEXT_ID),
type: Types.SlotType.Children
})
];

return {
pattern: new Pattern(
{
contextId: PATTERN_CONTEXT_ID,
description: 'for Interaction',
exportName: 'default',
id: patternId,
name: 'Link',
origin: Types.PatternOrigin.BuiltIn,
propertyIds: properties.map(p => p.getId()),
slots,
type: Types.PatternType.SyntheticLink
},
context
),
properties
};
};
2 changes: 1 addition & 1 deletion src/model/pattern-library/builtins/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const Page = (context: BuiltInContext): BuiltInResult => {
const properties = [
new PatternBooleanProperty({
contextId: VIEWPORT_CONTEXT_ID,
description: 'Lorem ipsum',
description: 'Adapt viewport to device',
id: context.options.getGlobalPropertyId(patternId, VIEWPORT_CONTEXT_ID),
label: 'Mobile Viewport',
origin: Types.PatternPropertyOrigin.BuiltIn,
Expand Down
15 changes: 10 additions & 5 deletions src/model/pattern-library/pattern-library.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Page, Placeholder, Text } from './builtins';
import { Box, Link, Page, Placeholder, Text } from './builtins';
import * as Fuse from 'fuse.js';
import { isEqual } from 'lodash';
import * as Mobx from 'mobx';
Expand Down Expand Up @@ -85,6 +85,7 @@ export class PatternLibrary {

root.addChild(syntheticFolder);

const link = Link({ patternLibrary, options });
const page = Page({ patternLibrary, options });
const placeholder = Placeholder({ patternLibrary, options });
const text = Text({ patternLibrary, options });
Expand All @@ -93,16 +94,20 @@ export class PatternLibrary {
syntheticFolder.addPattern(text.pattern);
syntheticFolder.addPattern(box.pattern);
syntheticFolder.addPattern(placeholder.pattern);
syntheticFolder.addPattern(link.pattern);

[page.pattern, text.pattern, box.pattern, placeholder.pattern].forEach(pattern => {
patternLibrary.addPattern(pattern);
});
[page.pattern, text.pattern, box.pattern, placeholder.pattern, link.pattern].forEach(
pattern => {
patternLibrary.addPattern(pattern);
}
);

[
...page.properties,
...placeholder.properties,
...text.properties,
...box.properties
...box.properties,
...link.properties
].forEach(property => {
patternLibrary.addProperty(property);
});
Expand Down
2 changes: 2 additions & 0 deletions src/model/pattern-property/asset-property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export class PatternAssetProperty extends PatternPropertyBase<string | undefined
contextId: serialized.contextId,
defaultValue: serialized.defaultValue,
description: serialized.description,
example: serialized.example,
hidden: serialized.hidden,
id: serialized.id,
label: serialized.label,
Expand All @@ -32,6 +33,7 @@ export class PatternAssetProperty extends PatternPropertyBase<string | undefined
contextId: this.contextId,
defaultValue: this.defaultValue,
description: this.description,
example: this.example,
hidden: this.hidden,
id: this.id,
label: this.label,
Expand Down
2 changes: 2 additions & 0 deletions src/model/pattern-property/boolean-property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export class PatternBooleanProperty extends PatternPropertyBase<boolean | undefi
contextId: serialized.contextId,
defaultValue: serialized.defaultValue,
description: serialized.description,
example: serialized.example,
hidden: serialized.hidden,
id: serialized.id,
label: serialized.label,
Expand All @@ -37,6 +38,7 @@ export class PatternBooleanProperty extends PatternPropertyBase<boolean | undefi
contextId: this.contextId,
defaultValue: this.defaultValue,
description: this.description,
example: this.example,
hidden: this.hidden,
id: this.id,
label: this.label,
Expand Down
2 changes: 2 additions & 0 deletions src/model/pattern-property/enum-property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class PatternEnumProperty extends PatternPropertyBase<EnumValue | undefin
return {
contextId: this.contextId,
defaultOptionId: this.defaultOptionId,
example: String(this.example),
description: this.description,
hidden: this.hidden,
id: this.id,
Expand All @@ -108,6 +109,7 @@ export class PatternEnumProperty extends PatternPropertyBase<EnumValue | undefin
public update(prop: PatternEnumProperty): void {
this.contextId = prop.getContextId();
this.defaultOptionId = prop.getDefaultOptionId();
this.example = prop.getExample();
this.hidden = prop.getHidden();
this.label = prop.getLabel();
this.propertyName = prop.getPropertyName();
Expand Down
Loading

0 comments on commit fb3fea7

Please sign in to comment.