mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
35 changed files with 758 additions and 117 deletions
@ -0,0 +1,106 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; |
|||
import { moduleMetadata } from '@storybook/angular'; |
|||
import { Meta, Story } from '@storybook/angular/types-6-0'; |
|||
import { map, Observable, timer } from 'rxjs'; |
|||
import { AutocompleteComponent, LocalizerService, SqxFrameworkModule } from '@app/framework'; |
|||
import { AutocompleteSource } from './autocomplete.component'; |
|||
|
|||
const TRANSLATIONS = { |
|||
'common.search': 'Search', |
|||
'common.empty': 'Nothing available.', |
|||
}; |
|||
|
|||
export default { |
|||
title: 'Framework/Autocomplete', |
|||
component: AutocompleteComponent, |
|||
argTypes: { |
|||
disabled: { |
|||
control: 'boolean', |
|||
}, |
|||
dropdownFullWidth: { |
|||
control: 'boolean', |
|||
}, |
|||
}, |
|||
decorators: [ |
|||
moduleMetadata({ |
|||
imports: [ |
|||
BrowserAnimationsModule, |
|||
SqxFrameworkModule, |
|||
SqxFrameworkModule.forRoot(), |
|||
], |
|||
providers: [ |
|||
{ provide: LocalizerService, useFactory: () => new LocalizerService(TRANSLATIONS) }, |
|||
], |
|||
}), |
|||
], |
|||
} as Meta; |
|||
|
|||
const Template: Story<AutocompleteComponent & { model: any }> = (args: AutocompleteComponent) => ({ |
|||
props: args, |
|||
template: ` |
|||
<sqx-root-view> |
|||
<sqx-autocomplete |
|||
[disabled]="disabled" |
|||
[icon]="icon" |
|||
[inputStyle]="inputStyle" |
|||
[source]="source"> |
|||
</sqx-autocomplete> |
|||
</sqx-root-view> |
|||
`,
|
|||
}); |
|||
|
|||
class Source implements AutocompleteSource { |
|||
constructor( |
|||
private readonly values: string[], |
|||
private readonly delay = 0, |
|||
) { |
|||
} |
|||
|
|||
public find(query: string): Observable<readonly any[]> { |
|||
return timer(this.delay).pipe(map(() => this.values.filter(x => x.indexOf(query) >= 0))); |
|||
} |
|||
} |
|||
|
|||
export const Default = Template.bind({}); |
|||
|
|||
Default.args = { |
|||
source: new Source(['Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing']), |
|||
}; |
|||
|
|||
export const Disabled = Template.bind({}); |
|||
|
|||
Disabled.args = { |
|||
disabled: true, |
|||
}; |
|||
|
|||
export const Icon = Template.bind({}); |
|||
|
|||
Icon.args = { |
|||
icon: 'user', |
|||
}; |
|||
|
|||
export const IconLoading = Template.bind({}); |
|||
|
|||
IconLoading.args = { |
|||
source: new Source(['Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing'], 4000), |
|||
icon: 'user', |
|||
}; |
|||
|
|||
export const StyleEmpty = Template.bind({}); |
|||
|
|||
StyleEmpty.args = { |
|||
inputStyle: 'empty', |
|||
}; |
|||
|
|||
export const StyleUnderlined = Template.bind({}); |
|||
|
|||
StyleUnderlined.args = { |
|||
inputStyle: 'underlined', |
|||
}; |
|||
@ -0,0 +1,175 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
import { Component } from '@angular/core'; |
|||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; |
|||
import { moduleMetadata } from '@storybook/angular'; |
|||
import { Meta, Story } from '@storybook/angular/types-6-0'; |
|||
import { DropdownComponent, LocalizerService, SqxFrameworkModule } from '@app/framework'; |
|||
|
|||
const TRANSLATIONS = { |
|||
'common.search': 'Search', |
|||
'common.empty': 'Nothing available.', |
|||
}; |
|||
|
|||
@Component({ |
|||
selector: 'sqx-dropdown-test', |
|||
template: ` |
|||
<sqx-root-view> |
|||
<sqx-dropdown |
|||
[allowOpen]="true" |
|||
[items]="items" |
|||
[itemsLoading]="itemsLoading" |
|||
(open)="load()"> |
|||
</sqx-dropdown> |
|||
</sqx-root-view> |
|||
`,
|
|||
}) |
|||
class TestComponent { |
|||
public items: string[] = []; |
|||
public itemsLoading = false; |
|||
|
|||
public load() { |
|||
this.items = []; |
|||
this.itemsLoading = true; |
|||
|
|||
setTimeout(() => { |
|||
this.items = ['A', 'B']; |
|||
this.itemsLoading = false; |
|||
}, 1000); |
|||
} |
|||
} |
|||
|
|||
export default { |
|||
title: 'Framework/Dropdown', |
|||
component: DropdownComponent, |
|||
argTypes: { |
|||
disabled: { |
|||
control: 'boolean', |
|||
}, |
|||
dropdownFullWidth: { |
|||
control: 'boolean', |
|||
}, |
|||
}, |
|||
decorators: [ |
|||
moduleMetadata({ |
|||
declarations: [ |
|||
TestComponent, |
|||
], |
|||
imports: [ |
|||
BrowserAnimationsModule, |
|||
SqxFrameworkModule, |
|||
SqxFrameworkModule.forRoot(), |
|||
], |
|||
providers: [ |
|||
{ provide: LocalizerService, useFactory: () => new LocalizerService(TRANSLATIONS) }, |
|||
], |
|||
}), |
|||
], |
|||
} as Meta; |
|||
|
|||
const Template: Story<DropdownComponent & { model: any }> = (args: DropdownComponent) => ({ |
|||
props: args, |
|||
template: ` |
|||
<sqx-root-view> |
|||
<sqx-dropdown |
|||
[disabled]="disabled" |
|||
[dropdownPosition]="'bottom-left'" |
|||
[dropdownFullWidth]="dropdownFullWidth" |
|||
[items]="items" |
|||
[itemsLoading]="itemsLoading" |
|||
[ngModel]="model"> |
|||
</sqx-dropdown> |
|||
</sqx-root-view> |
|||
`,
|
|||
}); |
|||
|
|||
const Template2: Story<DropdownComponent & { model: any }> = (args: DropdownComponent) => ({ |
|||
props: args, |
|||
template: ` |
|||
<sqx-root-view> |
|||
<sqx-dropdown |
|||
[disabled]="disabled" |
|||
[dropdownPosition]="'bottom-left'" |
|||
[dropdownFullWidth]="dropdownFullWidth" |
|||
[items]="items" |
|||
[itemsLoading]="itemsLoading" |
|||
[searchProperty]="searchProperty" |
|||
[ngModel]="model" |
|||
[valueProperty]="valueProperty"> |
|||
<ng-template let-target="$implicit"> |
|||
{{target.label}} |
|||
</ng-template> |
|||
</sqx-dropdown> |
|||
</sqx-root-view> |
|||
`,
|
|||
}); |
|||
|
|||
const Template3: Story<DropdownComponent & { model: any }> = (args: DropdownComponent) => ({ |
|||
props: args, |
|||
template: ` |
|||
<sqx-dropdown-test></sqx-dropdown-test> |
|||
`,
|
|||
}); |
|||
|
|||
export const Default = Template.bind({}); |
|||
|
|||
Default.args = { |
|||
items: ['A', 'B', 'C'], |
|||
model: 'B', |
|||
}; |
|||
|
|||
export const Empty = Template.bind({}); |
|||
|
|||
Empty.args = { |
|||
items: [], |
|||
model: 'B', |
|||
}; |
|||
|
|||
export const EmptyLoading = Template.bind({}); |
|||
|
|||
EmptyLoading.args = { |
|||
items: [], |
|||
itemsLoading: true, |
|||
}; |
|||
|
|||
export const NoSearch = Template.bind({}); |
|||
|
|||
NoSearch.args = { |
|||
items: ['A', 'B', 'C'], |
|||
canSearch: false, |
|||
}; |
|||
|
|||
export const FullWidth = Template.bind({}); |
|||
|
|||
FullWidth.args = { |
|||
items: ['A', 'B', 'C'], |
|||
dropdownFullWidth: true, |
|||
}; |
|||
|
|||
export const ComplexValues = Template2.bind({}); |
|||
|
|||
ComplexValues.args = { |
|||
searchProperty: 'label', |
|||
items: [{ |
|||
id: 1, |
|||
label: 'Lorem', |
|||
}, { |
|||
id: 2, |
|||
label: 'ipsum', |
|||
}, { |
|||
id: 3, |
|||
label: 'dolor', |
|||
}, { |
|||
id: 4, |
|||
label: 'sit', |
|||
}], |
|||
model: 2, |
|||
valueProperty: 'id', |
|||
}; |
|||
|
|||
export const Lazy = Template3.bind({}); |
|||
@ -0,0 +1,170 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
import { Component } from '@angular/core'; |
|||
import { moduleMetadata } from '@storybook/angular'; |
|||
import { Meta, Story } from '@storybook/angular/types-6-0'; |
|||
import { LocalizerService, SqxFrameworkModule, TagEditorComponent } from '@app/framework'; |
|||
|
|||
const TRANSLATIONS = { |
|||
'common.tagAdd': ', to add tag', |
|||
'common.empty': 'Nothing available.', |
|||
}; |
|||
|
|||
@Component({ |
|||
selector: 'sqx-tag-editor-test', |
|||
template: ` |
|||
<sqx-root-view> |
|||
<sqx-tag-editor |
|||
[allowOpen]="true" |
|||
[suggestions]="suggestions" |
|||
[suggestionsLoading]="suggestionsLoading" |
|||
(open)="load()"> |
|||
</sqx-tag-editor> |
|||
</sqx-root-view> |
|||
`,
|
|||
}) |
|||
class TestComponent { |
|||
public suggestions: string[] = []; |
|||
public suggestionsLoading = false; |
|||
|
|||
public load() { |
|||
this.suggestions = []; |
|||
this.suggestionsLoading = true; |
|||
|
|||
setTimeout(() => { |
|||
this.suggestions = ['A', 'B']; |
|||
this.suggestionsLoading = false; |
|||
}, 1000); |
|||
} |
|||
} |
|||
|
|||
export default { |
|||
title: 'Framework/TagEditor', |
|||
component: TagEditorComponent, |
|||
argTypes: { |
|||
dashed: { |
|||
control: 'boolean', |
|||
}, |
|||
disabled: { |
|||
control: 'boolean', |
|||
}, |
|||
}, |
|||
decorators: [ |
|||
moduleMetadata({ |
|||
declarations: [ |
|||
TestComponent, |
|||
], |
|||
imports: [ |
|||
SqxFrameworkModule, |
|||
SqxFrameworkModule.forRoot(), |
|||
], |
|||
providers: [ |
|||
{ provide: LocalizerService, useFactory: () => new LocalizerService(TRANSLATIONS) }, |
|||
], |
|||
}), |
|||
], |
|||
} as Meta; |
|||
|
|||
const Template: Story<TagEditorComponent & { ngModel: any }> = (args: TagEditorComponent) => ({ |
|||
props: args, |
|||
template: ` |
|||
<sqx-root-view> |
|||
<sqx-tag-editor |
|||
[allowOpen]="allowOpen" |
|||
[disabled]="disabled" |
|||
[ngModel]="ngModel" |
|||
[singleLine]="singleLine" |
|||
[styleBlank]="styleBlank" |
|||
[styleDashed]="styleDashed" |
|||
[suggestions]="suggestions" |
|||
[suggestionsLoading]="suggestionsLoading"> |
|||
</sqx-tag-editor> |
|||
</sqx-root-view> |
|||
`,
|
|||
}); |
|||
|
|||
const Template2: Story<TagEditorComponent & { ngModel: any }> = (args: TagEditorComponent) => ({ |
|||
props: args, |
|||
template: ` |
|||
<sqx-tag-editor-test></sqx-tag-editor-test> |
|||
`,
|
|||
}); |
|||
|
|||
export const Default = Template.bind({}); |
|||
|
|||
export const Suggestions = Template.bind({}); |
|||
|
|||
Suggestions.args = { |
|||
suggestions: ['A', 'B', 'C'], |
|||
allowOpen: true, |
|||
}; |
|||
|
|||
export const SuggestionsEmpty = Template.bind({}); |
|||
|
|||
SuggestionsEmpty.args = { |
|||
suggestions: [], |
|||
allowOpen: true, |
|||
}; |
|||
|
|||
export const SuggestionsLoading = Template.bind({}); |
|||
|
|||
SuggestionsLoading.args = { |
|||
suggestionsLoading: true, |
|||
allowOpen: true, |
|||
}; |
|||
|
|||
export const Values = Template.bind({}); |
|||
|
|||
Values.args = { |
|||
suggestions: [], |
|||
ngModel: ['A', 'A', 'B'], |
|||
}; |
|||
|
|||
export const StyleDashed = Template.bind({}); |
|||
|
|||
StyleDashed.args = { |
|||
styleDashed: true, |
|||
ngModel: [], |
|||
}; |
|||
|
|||
export const StyleDashedValues = Template.bind({}); |
|||
|
|||
StyleDashedValues.args = { |
|||
styleDashed: true, |
|||
ngModel: ['A', 'B', 'C'], |
|||
}; |
|||
|
|||
export const StyleBlank = Template.bind({}); |
|||
|
|||
StyleBlank.args = { |
|||
styleBlank: true, |
|||
ngModel: [], |
|||
}; |
|||
|
|||
export const StyleBlankValues = Template.bind({}); |
|||
|
|||
StyleBlankValues.args = { |
|||
styleBlank: true, |
|||
ngModel: ['A', 'B', 'C'], |
|||
}; |
|||
|
|||
export const Multiline = Template.bind({}); |
|||
|
|||
Multiline.args = { |
|||
singleLine: false, |
|||
ngModel: ['Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit', 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore', 'magna', 'aliqua'], |
|||
}; |
|||
|
|||
export const SingleLine = Template.bind({}); |
|||
|
|||
SingleLine.args = { |
|||
singleLine: true, |
|||
ngModel: ['Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit', 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore', 'magna', 'aliqua'], |
|||
}; |
|||
|
|||
export const Lazy = Template2.bind({}); |
|||
|
After Width: | Height: | Size: 596 B |
@ -0,0 +1,22 @@ |
|||
@import 'mixins'; |
|||
@import 'vars'; |
|||
|
|||
:host { |
|||
display: inline-block; |
|||
} |
|||
|
|||
.theme { |
|||
stroke: $color-theme-brand; |
|||
} |
|||
|
|||
.white { |
|||
stroke: $color-white; |
|||
} |
|||
|
|||
.input { |
|||
stroke: $color-input; |
|||
} |
|||
|
|||
.text { |
|||
stroke: $color-text; |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
/* eslint-disable import/no-cycle */ |
|||
|
|||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; |
|||
|
|||
@Component({ |
|||
selector: 'sqx-loader', |
|||
styleUrls: ['./loader.component.scss'], |
|||
templateUrl: './loader.component.html', |
|||
changeDetection: ChangeDetectionStrategy.OnPush, |
|||
}) |
|||
export class LoaderComponent { |
|||
@Input() |
|||
public size = 18; |
|||
|
|||
@Input() |
|||
public color: 'input' | 'theme' | 'white' | 'text' = 'text'; |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
import { moduleMetadata } from '@storybook/angular'; |
|||
import { Meta, Story } from '@storybook/angular/types-6-0'; |
|||
import { LoaderComponent, SqxFrameworkModule } from '@app/framework'; |
|||
|
|||
export default { |
|||
title: 'Framework/Loader', |
|||
component: LoaderComponent, |
|||
argTypes: { |
|||
size: { |
|||
control: 'number', |
|||
}, |
|||
color: { |
|||
control: 'enum', |
|||
options: [ |
|||
'white', |
|||
'theme', |
|||
'text', |
|||
], |
|||
}, |
|||
}, |
|||
decorators: [ |
|||
moduleMetadata({ |
|||
imports: [ |
|||
SqxFrameworkModule, |
|||
SqxFrameworkModule.forRoot(), |
|||
], |
|||
}), |
|||
], |
|||
} as Meta; |
|||
|
|||
const Template: Story<LoaderComponent> = (args: LoaderComponent) => ({ |
|||
props: args, |
|||
}); |
|||
|
|||
export const ColorWhite = Template.bind({}); |
|||
|
|||
ColorWhite.args = { |
|||
color: 'white', |
|||
}; |
|||
|
|||
export const ColorTheme = Template.bind({}); |
|||
|
|||
ColorTheme.args = { |
|||
color: 'theme', |
|||
}; |
|||
|
|||
export const ColorText = Template.bind({}); |
|||
|
|||
ColorText.args = { |
|||
color: 'text', |
|||
}; |
|||
|
|||
export const ColorInput = Template.bind({}); |
|||
|
|||
ColorInput.args = { |
|||
color: 'input', |
|||
}; |
|||
|
|||
export const SizeSmall = Template.bind({}); |
|||
|
|||
SizeSmall.args = { |
|||
size: 16, |
|||
}; |
|||
|
|||
export const SizeMedium = Template.bind({}); |
|||
|
|||
SizeMedium.args = { |
|||
size: 32, |
|||
}; |
|||
|
|||
export const SizeLarge = Template.bind({}); |
|||
|
|||
SizeLarge.args = { |
|||
size: 64, |
|||
}; |
|||
@ -1,3 +1,6 @@ |
|||
<img [class.hidden]="!isLoading" class="loader" src="./images/loader-white.svg" /> |
|||
<div [class.hidden]="!isLoading" class="loader" > |
|||
<sqx-loader color="white" [size]="28"></sqx-loader> |
|||
</div> |
|||
|
|||
|
|||
<i [class.hidden]="isLoading" class="icon-logo"></i> |
|||
Loading…
Reference in new issue