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

feat: add link builtin component #501

Merged
merged 1 commit into from
May 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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