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> |
<i [class.hidden]="isLoading" class="icon-logo"></i> |
||||
Loading…
Reference in new issue