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

Commit

Permalink
feat: restore slot handling based on element contents (#548)
Browse files Browse the repository at this point in the history
* feat: restore slot handling based on element contents
* style: remove disabled code
* feat: support jsdoc meta data for slots
* feat: make elements with slots collapsible
* fix: provide root drop zone on 100% of element list height
* fix: add slot description
* fix: remove duplicate stylings
  • Loading branch information
marionebl authored and tilmx committed Jun 13, 2018
1 parent 7bb8a57 commit 56a60cd
Show file tree
Hide file tree
Showing 25 changed files with 1,007 additions and 495 deletions.
228 changes: 114 additions & 114 deletions package-lock.json

Large diffs are not rendered by default.

23 changes: 18 additions & 5 deletions src/analyzer/typescript-react-analyzer/slot-analzyer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,25 @@ export function analyzeSlots(
return;
}

const propertyName = memberSymbol.getName();
const label = TypescriptUtils.getJsDocValueFromSymbol(memberSymbol, 'name');
const example = TypescriptUtils.getJsDocValueFromSymbol(memberSymbol, 'example') || '';
const required =
(memberSymbol.flags & Ts.SymbolFlags.Optional) !== Ts.SymbolFlags.Optional;
const description =
TypescriptUtils.getJsDocValueFromSymbol(memberSymbol, 'description') || '';
const hidden = TypescriptUtils.hasJsDocTagFromSymbol(memberSymbol, 'ignore');

return {
contextId: memberSymbol.getName(),
displayName: memberSymbol.getName(),
id: ctx.getSlotId(memberSymbol.getName()),
propertyName: memberSymbol.getName(),
type: memberSymbol.getName() === 'children' ? 'children' : 'property'
contextId: propertyName,
label: label || propertyName,
description,
example,
hidden,
id: ctx.getSlotId(propertyName),
propertyName,
required,
type: propertyName === 'children' && !isExplicitSlot ? 'children' : 'property'
};
})
.filter((slot): slot is Types.SerializedPatternSlot => typeof slot !== 'undefined');
Expand Down
50 changes: 50 additions & 0 deletions src/components/element-slot/demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import DemoContainer from '../demo-container';
import * as React from 'react';
import { ElementSlot, ElementSlotState } from '.';

const FloatingButtonDemo: React.StatelessComponent<void> = (): JSX.Element => (
<DemoContainer title="Element Slot">
<>
Default
<ElementSlot
description="Slot"
id=""
open={false}
state={ElementSlotState.Default}
title="Slot"
/>
</>
<>
Open
<ElementSlot
description="Slot"
id=""
open={true}
state={ElementSlotState.Default}
title="Open Slot"
/>
</>
<>
Disabled
<ElementSlot
description="Slot"
id=""
open={true}
state={ElementSlotState.Disabled}
title="Disabled Slot"
/>
</>
<>
Highlighted
<ElementSlot
description="Slot"
id=""
open={true}
state={ElementSlotState.Highlighted}
title="Disabled Slot"
/>
</>
</DemoContainer>
);

export default FloatingButtonDemo;
130 changes: 130 additions & 0 deletions src/components/element-slot/element-slot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { Color } from '../colors';
import { ElementAnchors } from '../element';
import { Icon, IconName, IconSize } from '../icons';
import * as React from 'react';
import { getSpace, SpaceSize } from '../space';
import styled from 'styled-components';
import { tag } from '../tag';

export enum ElementSlotState {
Default = 'default',
Disabled = 'disabled',
Highlighted = 'highlighted'
}

export interface ElementSlotProps {
children?: React.ReactNode;
description: string;
id: string;
open: boolean;
state: ElementSlotState;
title: string;
}

interface StyledElementSlotLabelProps {
state: ElementSlotState;
}

interface StyledIconProps {
open: boolean;
}

const StyledElementSlot = styled.div`
position: relative;
z-index: 1;
`;

const div = tag('div').omit(['active', 'highlight']);

const LABEL_COLOR = (props: StyledElementSlotLabelProps): string => {
switch (props.state) {
case ElementSlotState.Disabled:
return Color.Grey60;
case ElementSlotState.Highlighted:
case ElementSlotState.Default:
default:
return 'inherit';
}
};

const LABEL_BACKGROUND = (props: StyledElementSlotLabelProps): string => {
switch (props.state) {
case ElementSlotState.Highlighted:
return Color.Grey90;
default:
return 'transparent';
}
};

const StyledElementSlotLabel = styled(div)`
position: relative;
display: flex;
align-items: center;
font-size: 15px;
line-height: 21px;
z-index: 1;
color: ${LABEL_COLOR};
background: ${LABEL_BACKGROUND};
`;

const elementDiv = tag('div').omit(['open']);

const StyledElementChildren = styled(elementDiv)`
flex-basis: 100%;
padding-left: ${getSpace(SpaceSize.L)}px;
`;

const StyledIcon = styled(Icon)`
position: absolute;
left: ${getSpace(SpaceSize.XS) + getSpace(SpaceSize.XXS)}px;
fill: ${Color.Grey60};
width: ${getSpace(SpaceSize.S)}px;
height: ${getSpace(SpaceSize.S)}px;
padding: ${getSpace(SpaceSize.XS)}px;
transition: transform 0.2s;
${(props: StyledIconProps) => (props.open ? 'transform: rotate(90deg)' : '')};
`;

const StyledElementSlotLabelContent = styled.div`
box-sizing: border-box;
margin-left: ${getSpace(SpaceSize.XXL) - 3}px;
overflow: hidden;
padding: ${getSpace(SpaceSize.XS)}px ${getSpace(SpaceSize.XXS)}px;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
`;

const StyledElementSlotLabelDescription = styled.div`
box-sizing: border-box;
padding: 0 ${getSpace(SpaceSize.M)}px 0 ${getSpace(SpaceSize.XS)}px;
font-size: 12px;
justify-self: flex-end;
`;

export class ElementSlot extends React.Component<ElementSlotProps> {
public render(): JSX.Element | null {
const { props } = this;

return (
<StyledElementSlot {...{ [ElementAnchors.content]: props.id }}>
<StyledElementSlotLabel state={props.state}>
<StyledIcon
dataIcon={props.id}
name={IconName.ArrowFillRight}
size={IconSize.XXS}
color={Color.Grey60}
open={props.open}
/>
<StyledElementSlotLabelContent {...{ [ElementAnchors.label]: true }}>
{props.title}
</StyledElementSlotLabelContent>
<StyledElementSlotLabelDescription>
{props.description}
</StyledElementSlotLabelDescription>
</StyledElementSlotLabel>
<StyledElementChildren>{props.open && props.children}</StyledElementChildren>
</StyledElementSlot>
);
}
}
1 change: 1 addition & 0 deletions src/components/element-slot/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './element-slot';
9 changes: 9 additions & 0 deletions src/components/element-slot/pattern.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "element-slot",
"main": "./element-slot",
"description": "Slot in element tree",
"displayName": "Element Slot",
"flag": "alpha",
"version": "1.0.0",
"tags": []
}
18 changes: 18 additions & 0 deletions src/components/element/demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ const NOOP = () => {};
const CHILD = (
<Element
id="1"
contentId="1"
state={ElementState.Default}
capabilities={[ElementCapability.Editable]}
open={false}
placeholder={true}
onChange={NOOP}
title="Child Element"
dragging={false}
Expand All @@ -23,10 +25,12 @@ const ElementDemo: React.StatelessComponent<void> = (): JSX.Element => (
Default
<Element
id="1"
contentId="1"
state={ElementState.Default}
capabilities={[ElementCapability.Editable]}
open={false}
onChange={NOOP}
placeholder={true}
title="Element"
dragging={false}
/>
Expand All @@ -35,9 +39,11 @@ const ElementDemo: React.StatelessComponent<void> = (): JSX.Element => (
Active
<Element
id="2"
contentId="2"
capabilities={[ElementCapability.Editable]}
open={false}
onChange={NOOP}
placeholder={true}
state={ElementState.Active}
title="Element"
dragging={false}
Expand All @@ -47,9 +53,11 @@ const ElementDemo: React.StatelessComponent<void> = (): JSX.Element => (
Highlighted
<Element
id="2"
contentId="2"
capabilities={[ElementCapability.Editable]}
open={false}
onChange={NOOP}
placeholder={true}
state={ElementState.Highlighted}
title="Element"
dragging={false}
Expand All @@ -59,9 +67,11 @@ const ElementDemo: React.StatelessComponent<void> = (): JSX.Element => (
Placeholder Highlighted
<Element
id="2"
contentId="2"
capabilities={[ElementCapability.Editable]}
open={false}
onChange={NOOP}
placeholder={true}
placeholderHighlighted={true}
state={ElementState.Default}
title="Element"
Expand All @@ -72,9 +82,11 @@ const ElementDemo: React.StatelessComponent<void> = (): JSX.Element => (
Editable
<Element
id="2"
contentId="2"
capabilities={[ElementCapability.Editable]}
open={false}
onChange={NOOP}
placeholder={true}
state={ElementState.Editable}
title="Element"
dragging={false}
Expand All @@ -84,9 +96,11 @@ const ElementDemo: React.StatelessComponent<void> = (): JSX.Element => (
May open, closed
<Element
id="3"
contentId="3"
capabilities={[ElementCapability.Editable, ElementCapability.Openable]}
onChange={NOOP}
open={false}
placeholder={true}
title="Element"
state={ElementState.Default}
dragging={false}
Expand All @@ -98,9 +112,11 @@ const ElementDemo: React.StatelessComponent<void> = (): JSX.Element => (
May open, opened
<Element
id="3"
contentId="3"
capabilities={[ElementCapability.Editable, ElementCapability.Openable]}
onChange={NOOP}
open
placeholder={true}
title="Element"
state={ElementState.Default}
dragging={false}
Expand All @@ -112,9 +128,11 @@ const ElementDemo: React.StatelessComponent<void> = (): JSX.Element => (
With child, active and open
<Element
id="4"
contentId="4"
capabilities={[ElementCapability.Editable, ElementCapability.Openable]}
onChange={NOOP}
open
placeholder={true}
title="Element"
state={ElementState.Active}
dragging={false}
Expand Down
Loading

0 comments on commit 56a60cd

Please sign in to comment.