This repository has been archived by the owner on Oct 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 224
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ab6d5dd
commit 243a4d2
Showing
17 changed files
with
351 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import AssetItem from './index'; | ||
import * as React from 'react'; | ||
import styled from 'styled-components'; | ||
|
||
const NOOP = () => {}; // tslint:disable-line no-empty | ||
|
||
const StyledDemo = styled.div` | ||
width: 200px; | ||
margin-bottom: 20px; | ||
`; | ||
|
||
const AssetItemDemo: React.StatelessComponent<void> = (): JSX.Element => ( | ||
<div> | ||
<StyledDemo> | ||
<AssetItem label="Empty" /> | ||
</StyledDemo> | ||
<StyledDemo> | ||
<AssetItem | ||
handleChooseClick={NOOP} | ||
handleClearClick={NOOP} | ||
handleInputChange={NOOP} | ||
label="Internal" | ||
imageSrc="http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/light-bulb-icon.png" | ||
/> | ||
</StyledDemo> | ||
<StyledDemo> | ||
<AssetItem | ||
handleChooseClick={NOOP} | ||
handleClearClick={NOOP} | ||
handleInputChange={NOOP} | ||
label="External" | ||
inputValue="http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/light-bulb-icon.png" | ||
/> | ||
</StyledDemo> | ||
</div> | ||
); | ||
|
||
export default AssetItemDemo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { colors } from '../../colors'; | ||
import { fonts } from '../../fonts'; | ||
import * as React from 'react'; | ||
import { getSpace, Size } from '../../space'; | ||
import styled from 'styled-components'; | ||
|
||
export interface AssetItemProps { | ||
className?: string; | ||
handleChooseClick?: React.MouseEventHandler<HTMLButtonElement>; | ||
handleClearClick?: React.MouseEventHandler<HTMLButtonElement>; | ||
handleInputChange?: React.ChangeEventHandler<HTMLInputElement>; | ||
imageSrc?: string; | ||
inputValue?: string; | ||
label: string; | ||
} | ||
|
||
const StyledAssetItem = styled.div` | ||
width: 100%; | ||
`; | ||
|
||
const StyledPreview = styled.div` | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
margin-bottom: ${getSpace(Size.XS)}px; | ||
`; | ||
|
||
const StyledLabel = styled.span` | ||
display: block; | ||
margin-bottom: ${getSpace(Size.XS)}px; | ||
font-size: 12px; | ||
font-family: ${fonts().NORMAL_FONT}; | ||
color: ${colors.grey36.toString()}; | ||
`; | ||
|
||
const StyledInput = styled.input` | ||
display: inline-block; | ||
box-sizing: border-box; | ||
max-width: 75%; | ||
text-overflow: ellipsis; | ||
border: none; | ||
border-bottom: 1px solid transparent; | ||
background: transparent; | ||
font-family: ${fonts().NORMAL_FONT}; | ||
font-size: 15px; | ||
color: ${colors.grey36.toString()}; | ||
transition: all 0.2s; | ||
::-webkit-input-placeholder { | ||
color: ${colors.grey60.toString()}; | ||
} | ||
&:hover { | ||
color: ${colors.black.toString()}; | ||
border-color: ${colors.grey60.toString()}; | ||
} | ||
&:focus { | ||
outline: none; | ||
border-color: ${colors.blue40.toString()}; | ||
color: ${colors.black.toString()}; | ||
} | ||
`; | ||
|
||
const StyledImageBox = styled.div` | ||
box-sizing: border-box; | ||
border-radius: 3px; | ||
width: 42px; | ||
height: 42px; | ||
background-color: ${colors.white.toString()}; | ||
border: 0.5px solid ${colors.grey90.toString()}; | ||
padding: 3px; | ||
margin-right: 6px; | ||
flex-shrink: 0; | ||
`; | ||
|
||
const StyledImage = styled.img` | ||
width: 100%; | ||
`; | ||
|
||
const StyledButton = styled.button` | ||
max-width: 50%; | ||
margin-right: 3px; | ||
border: 0.5px solid ${colors.grey90.toString()}; | ||
border-radius: 3px; | ||
background-color: ${colors.white.toString()}; | ||
padding: ${getSpace(Size.XS)}px ${getSpace(Size.S)}px; | ||
`; | ||
|
||
export const AssetItem: React.StatelessComponent<AssetItemProps> = props => ( | ||
<StyledAssetItem className={props.className}> | ||
<label> | ||
<StyledLabel>{props.label}</StyledLabel> | ||
<StyledPreview> | ||
<StyledImageBox> | ||
<StyledImage src={props.imageSrc} /> | ||
</StyledImageBox> | ||
<StyledInput | ||
onChange={props.handleInputChange} | ||
type="textarea" | ||
value={props.inputValue} | ||
placeholder="Enter external URL" | ||
/> | ||
</StyledPreview> | ||
</label> | ||
<StyledButton onClick={props.handleChooseClick}>Open</StyledButton> | ||
<StyledButton onClick={props.handleClearClick}>Clear</StyledButton> | ||
</StyledAssetItem> | ||
); | ||
|
||
export default AssetItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"name": "asset-item", | ||
"displayName": "Asset Item", | ||
"version": "1.0.0", | ||
"tags": [ | ||
"property" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import * as FileUtils from 'fs'; | ||
import * as fetch from 'isomorphic-fetch'; | ||
import * as MimeTypes from 'mime-types'; | ||
import * as PathUtils from 'path'; | ||
import { Property } from './property'; | ||
|
||
/** | ||
* An asset property is a property that takes an uploaded file (e.g. an image) | ||
* as a data-URL string to output it as src of an img tag or alike. | ||
* As designer content value (raw value), the asset property accepts data-URL strings and | ||
* undefined (as empty src) only. All other values are invalid and converted into undefined. | ||
* To convert a given file, Buffer, or HTTP URL into a data-URL string, | ||
* use getValueFromFile, getValueFromBuffer, or getValueFromUrl. | ||
* @see Property | ||
* @see AssetProperty.getValueFromFile | ||
* @see AssetProperty.getValueFromBuffer | ||
* @see AssetProperty.getValueFromUrl | ||
*/ | ||
export class AssetProperty extends Property { | ||
/** | ||
* Creates a new asset property. | ||
* @param id The technical ID of this property (e.g. the property name | ||
* in the TypeScript props interface). | ||
*/ | ||
public constructor(id: string) { | ||
super(id); | ||
} | ||
|
||
/** | ||
* Converts a given buffer and mime type into a data-URL string, a valid value for this property. | ||
* @param buffer The buffer to read. | ||
* @param mimeType The mime type of the buffer content. | ||
* @return The data-URL string. | ||
*/ | ||
public static getValueFromBuffer(buffer: Buffer, mimeType: string): string { | ||
return `data:${mimeType};base64,${buffer.toString('base64')}`; | ||
} | ||
|
||
/** | ||
* Reads a given file and converts it into a data-URL string, a valid value for this property. | ||
* @param path The OS-specific path to the file to read. | ||
* @return The data-URL string. | ||
*/ | ||
public static getValueFromFile(path: string): string { | ||
const fileName: string | undefined = path.split(PathUtils.sep).pop(); | ||
if (fileName === undefined) { | ||
throw new Error(`Invalid asset path ${path}`); | ||
} | ||
|
||
const mimeType = MimeTypes.lookup(fileName) || 'application/octet-stream'; | ||
const buffer: Buffer = FileUtils.readFileSync(path); | ||
return this.getValueFromBuffer(buffer, mimeType); | ||
} | ||
|
||
/** | ||
* Downloads a given file from HTTP and converts it into a data-URL string, | ||
* a valid value for this property. | ||
* @param url The URL of the file to download. | ||
* @param callback A callback that gets the downloaded file as data-URL. | ||
*/ | ||
public static async getValueFromUrl(url: string): Promise<string> { | ||
const response = await fetch(url); | ||
if (response.status >= 400) { | ||
throw new Error(`Failed to load file from server: HTTP ${response.status}`); | ||
} | ||
if (!response.body) { | ||
throw new Error('Server returned no content'); | ||
} | ||
|
||
const mimeType = response.headers.get('Content-Type') || 'application/octet-stream'; | ||
|
||
// tslint:disable-next-line:no-any | ||
const buffer: Buffer = await (response as any).buffer(); | ||
return AssetProperty.getValueFromBuffer(buffer, mimeType); | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
// tslint:disable-next-line:no-any | ||
public async coerceValue(value: any): Promise<any> { | ||
if (typeof value === 'string') { | ||
return value; | ||
} | ||
|
||
return undefined; | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public getType(): string { | ||
return 'asset'; | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public toString(): string { | ||
return `AssetProperty(${super.toString()})`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.