aboutsummaryrefslogtreecommitdiffstats
path: root/stories
diff options
context:
space:
mode:
authorMichael Lando <ml636r@att.com>2018-05-21 20:19:48 +0000
committerGerrit Code Review <gerrit@onap.org>2018-05-21 20:19:48 +0000
commit05b37297177e8a342668c15e5d6f738b51f7aedd (patch)
treee236c96df52a13f935292db8aa73e84d0c41ad8a /stories
parent884dfb789593d2a3cc319047ab1f0215778aec9f (diff)
parent1994c98063c27a41797dec01f2ca9fcbe33ceab0 (diff)
Merge "init commit onap ui"HEAD2.0.0-ONAPmasterbeijing2.0.0-ONAP
Diffstat (limited to 'stories')
-rw-r--r--stories/README.md9
-rw-r--r--stories/ng2-component-lab/accordion.component.exp.ts146
-rw-r--r--stories/ng2-component-lab/autocomplete.component.exp.ts77
-rw-r--r--stories/ng2-component-lab/button.component.exp.ts164
-rw-r--r--stories/ng2-component-lab/checkbox.component.exp.ts33
-rw-r--r--stories/ng2-component-lab/checklist.component.exp.ts213
-rw-r--r--stories/ng2-component-lab/colors.component.exp.ts42
-rw-r--r--stories/ng2-component-lab/components.module.ts45
-rw-r--r--stories/ng2-component-lab/components/colors-table.component.ts26
-rw-r--r--stories/ng2-component-lab/components/modal-consumer.component.ts106
-rw-r--r--stories/ng2-component-lab/components/modal-inner-content-example.component.ts16
-rw-r--r--stories/ng2-component-lab/components/notifications-example.component.ts57
-rw-r--r--stories/ng2-component-lab/components/svg-icons-table.component.ts189
-rw-r--r--stories/ng2-component-lab/dropdown.component.exp.ts195
-rw-r--r--stories/ng2-component-lab/filter-bar.component.exp.ts56
-rw-r--r--stories/ng2-component-lab/infinite-scroll.component.exp.ts166
-rw-r--r--stories/ng2-component-lab/input.component.exp.ts79
-rw-r--r--stories/ng2-component-lab/modals.component.exp.ts126
-rw-r--r--stories/ng2-component-lab/notification.component.exp.ts11
-rw-r--r--stories/ng2-component-lab/pipes/search-filter-pipe.ts15
-rw-r--r--stories/ng2-component-lab/popup-menu.component.exp.ts104
-rw-r--r--stories/ng2-component-lab/radio.component.exp.ts179
-rw-r--r--stories/ng2-component-lab/search-bar.component.exp.ts19
-rw-r--r--stories/ng2-component-lab/svg-icon.component.exp.ts14
-rw-r--r--stories/ng2-component-lab/tabs.component.exp.ts28
-rw-r--r--stories/ng2-component-lab/tag-cloud.component.exp.ts61
-rw-r--r--stories/ng2-component-lab/tiles.component.exp.ts194
-rw-r--r--stories/ng2-component-lab/tooltip.directive.exp.ts231
-rw-r--r--stories/ng2-component-lab/utils/mock.json6
-rw-r--r--stories/ng2-component-lab/utils/pipes/keys.pipe.ts13
-rw-r--r--stories/ng2-component-lab/validation.component.exp.ts162
-rw-r--r--stories/react/Accordion.stories.js16
-rw-r--r--stories/react/Checkbox.stories.js33
-rw-r--r--stories/react/Checklist.stories.js65
-rw-r--r--stories/react/Colors.stories.js53
-rw-r--r--stories/react/Input.stories.js51
-rw-r--r--stories/react/Modal.stories.js133
-rw-r--r--stories/react/Panel.stories.js22
-rw-r--r--stories/react/PopupMenu.stories.js37
-rw-r--r--stories/react/Radio.stories.js33
-rw-r--r--stories/react/RadioGroup.stories.js34
-rw-r--r--stories/react/SVGIcon.stories.js103
-rw-r--r--stories/react/Tabs.stories.js48
-rw-r--r--stories/react/Tiles.stories.js89
-rw-r--r--stories/react/Typography.stories.js62
-rw-r--r--stories/react/buttons/LinkButtons.stories.js49
-rw-r--r--stories/react/buttons/PrimaryButtons.stories.js49
-rw-r--r--stories/react/buttons/SecondaryButtons.stories.js49
-rw-r--r--stories/react/index.js66
-rw-r--r--stories/react/utils/BeautifyHTML.js33
-rw-r--r--stories/react/utils/Examples.js23
-rw-r--r--stories/react/utils/InsertSVGIcons.js15
-rw-r--r--stories/react/utils/SourceToggle.js73
-rw-r--r--stories/react/utils/components/DropdownMenu.js14
-rw-r--r--stories/react/utils/jsxToString.js74
55 files changed, 4006 insertions, 0 deletions
diff --git a/stories/README.md b/stories/README.md
new file mode 100644
index 0000000..7ed8e9d
--- /dev/null
+++ b/stories/README.md
@@ -0,0 +1,9 @@
+# Storybook
+
+This is the part of the repo that is responsible for defining and building the stories for storybook. Take a look at the following guides for your assistance:
+
+## Adding a new component to storybook
+See [wiki page](https://github.com/onap-sdc/sdc-ui/wiki/Adding-a-new-component-to-storybook).
+
+## Deploying storybook to a fork's github pages
+See [wiki page](https://github.com/onap-sdc/sdc-ui/wiki/Deploying-storybook-to-a-fork's-github-pages).
diff --git a/stories/ng2-component-lab/accordion.component.exp.ts b/stories/ng2-component-lab/accordion.component.exp.ts
new file mode 100644
index 0000000..480a011
--- /dev/null
+++ b/stories/ng2-component-lab/accordion.component.exp.ts
@@ -0,0 +1,146 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+import {Placement} from "../../src/angular/common/enums";
+
+
+/**************************************************
+ * Adding custom styles for example
+ *************************************************/
+const style = document.createElement('style');
+style.innerHTML = `
+.sdc-accordion-custom-class .sdc-accordion-header,
+.sdc-accordion-custom-class .sdc-accordion-body.open {
+ padding: 10px;
+ border-radius: 3px;
+}
+.sdc-accordion-custom-class .sdc-accordion-header {
+ background-color: #d2d2d2;
+}
+.sdc-accordion-custom-class .sdc-accordion-body.open {
+ border: 1px solid #d2d2d2;
+ margin-top: 1px;
+ }
+`;
+const head = document.getElementsByTagName('head');
+head[0].appendChild(style);
+
+export default experimentOn('Accordion').group('Accordion',
+ [
+ {
+ id: 'simpleAccodion',
+ title: 'Simple accordion',
+ description: 'Example of accordion with default left arrow',
+ showSource: true,
+ template: `
+ <sdc-accordion title="Accordion header">
+ <p>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat dictum porttitor.
+ Nam facilisis, dui nec maximus facilisis, nisl eros mattis arcu, nec pharetra nisl nisi vitae metus.
+ Vestibulum urna nunc, fringilla nec imperdiet a, varius hendrerit neque. Aliquam pulvinar turpis enim, ac hendrerit dui blandit eu.
+ Curabitur ut mollis arcu, ac iaculis turpis. Pellentesque lobortis leo justo. Morbi commodo cursus dignissim.
+ Nam orci diam, mattis eget leo vel, tincidunt interdum dui.
+ Donec dapibus mauris non sapien ornare, non pharetra mi commodo.
+ </p>
+ </sdc-accordion>
+ `
+ },
+ {
+ id: 'accordionRightArrow',
+ title: 'Accordion with right arrow',
+ description: 'Example of accordion with right arrow',
+ showSource: true,
+ context: {
+ arrowDirection: Placement.right,
+ },
+ template: `
+
+
+
+ <sdc-accordion
+ title="Accordion header"
+ [arrow-direction]="arrowDirection">
+ <p>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat dictum porttitor.
+ Nam facilisis, dui nec maximus facilisis, nisl eros mattis arcu, nec pharetra nisl nisi vitae metus.
+ Vestibulum urna nunc, fringilla nec imperdiet a, varius hendrerit neque. Aliquam pulvinar turpis enim, ac hendrerit dui blandit eu.
+ Curabitur ut mollis arcu, ac iaculis turpis. Pellentesque lobortis leo justo. Morbi commodo cursus dignissim.
+ Nam orci diam, mattis eget leo vel, tincidunt interdum dui.
+ Donec dapibus mauris non sapien ornare, non pharetra mi commodo.
+ </p>
+ </sdc-accordion>
+ `
+ },
+ {
+ id: 'accordionRightArrowStyle',
+ title: 'Accordion with right arrow and custom style',
+ description: 'Example of accordion with right arrow and custom style',
+ showSource: true,
+ context: {
+ arrowDirection: Placement.right,
+ },
+ template: `
+ <sdc-accordion
+ title="Accordion header"
+ css-class="sdc-accordion-custom-class"
+ [arrow-direction]="arrowDirection">
+ <p>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat dictum porttitor.
+ Nam facilisis, dui nec maximus facilisis, nisl eros mattis arcu, nec pharetra nisl nisi vitae metus.
+ Vestibulum urna nunc, fringilla nec imperdiet a, varius hendrerit neque. Aliquam pulvinar turpis enim, ac hendrerit dui blandit eu.
+ Curabitur ut mollis arcu, ac iaculis turpis. Pellentesque lobortis leo justo. Morbi commodo cursus dignissim.
+ Nam orci diam, mattis eget leo vel, tincidunt interdum dui.
+ Donec dapibus mauris non sapien ornare, non pharetra mi commodo.
+ </p>
+ </sdc-accordion>
+ `
+ }
+ ,
+ {
+ id: 'accordionLeftArrowStyle',
+ title: 'Accordion with left arrow and custom style',
+ description: 'Example of accordion with left arrow and custom style',
+ showSource: true,
+ context: {
+ arrowDirection: Placement.left,
+ },
+ template: `
+ <sdc-accordion
+ title="Accordion header"
+ css-class="sdc-accordion-custom-class"
+ [arrow-direction]="arrowDirection">
+ <p>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat dictum porttitor.
+ Nam facilisis, dui nec maximus facilisis, nisl eros mattis arcu, nec pharetra nisl nisi vitae metus.
+ Vestibulum urna nunc, fringilla nec imperdiet a, varius hendrerit neque. Aliquam pulvinar turpis enim, ac hendrerit dui blandit eu.
+ Curabitur ut mollis arcu, ac iaculis turpis. Pellentesque lobortis leo justo. Morbi commodo cursus dignissim.
+ Nam orci diam, mattis eget leo vel, tincidunt interdum dui.
+ Donec dapibus mauris non sapien ornare, non pharetra mi commodo.
+ </p>
+ </sdc-accordion>
+ `
+ },
+ {
+ id: 'accordionLeftArrowStyleOpen',
+ title: 'Open accordion with left arrow and custom style',
+ description: 'Example of open accordion with left arrow and custom style',
+ showSource: true,
+ context: {
+ arrowDirection: Placement.left,
+ },
+ template: `
+ <sdc-accordion
+ title="Accordion header"
+ css-class="sdc-accordion-custom-class"
+ [open]="true"
+ [arrow-direction]="arrowDirection">
+ <p>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat dictum porttitor.
+ Nam facilisis, dui nec maximus facilisis, nisl eros mattis arcu, nec pharetra nisl nisi vitae metus.
+ Vestibulum urna nunc, fringilla nec imperdiet a, varius hendrerit neque. Aliquam pulvinar turpis enim, ac hendrerit dui blandit eu.
+ Curabitur ut mollis arcu, ac iaculis turpis. Pellentesque lobortis leo justo. Morbi commodo cursus dignissim.
+ Nam orci diam, mattis eget leo vel, tincidunt interdum dui.
+ Donec dapibus mauris non sapien ornare, non pharetra mi commodo.
+ </p>
+ </sdc-accordion>
+ `
+ }
+ ]);
diff --git a/stories/ng2-component-lab/autocomplete.component.exp.ts b/stories/ng2-component-lab/autocomplete.component.exp.ts
new file mode 100644
index 0000000..a1fa3dd
--- /dev/null
+++ b/stories/ng2-component-lab/autocomplete.component.exp.ts
@@ -0,0 +1,77 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+export default experimentOn('Autocomplete').group('Autocomplete',
+[
+ {
+ id: 'simpleAutocomplete',
+ title: 'Simple autocomplete data',
+ description: 'Example of auto complete with simple data',
+ showSource: true,
+ context: {
+ data: ['red', 'yellow', 'orange', 'green', 'white', 'black'],
+ selectedOption: '',
+ showSelectedItem: ((value: string) => {
+ alert(value);
+ })
+ },
+ template: `
+ <sdc-autocomplete
+ placeholder="search text"
+ label="search by color:"
+ [data]="data"
+ (itemSelected)="showSelectedItem($event)"
+ >
+ </sdc-autocomplete>
+ `
+ },
+ {
+ id: 'complexAutocomplete',
+ title: 'Complex autocomplete data',
+ description: 'Example of auto complete with complex data',
+ showSource: true,
+ context: {
+ data: [
+ {id: 'redId', color: 'red'},
+ {id: 'yellowId', color: 'yellow'},
+ {id: 'orangeId', color: 'orange'},
+ {id: 'greenId', color: 'green'},
+ {id: 'whiteId', color: 'white'},
+ {id: 'blackId', color: 'black'}
+ ],
+ showSelectedItem: ((value: string) => {
+ alert(value);
+ })
+ },
+ template: `
+ <sdc-autocomplete
+ placeholder="search text"
+ label="search by color:"
+ [data]="data"
+ [dataSchema]="{key: 'id', value: 'color'}"
+ (itemSelected)="showSelectedItem($event)"
+ >
+ </sdc-autocomplete>
+ `
+ },
+ {
+ id: 'complexAutocompleteWithBeData',
+ title: 'Complex autocomplete data from server',
+ description: 'Example of auto complete with complex data from server. (In this example the data is not really filtered, because it is from mock data)',
+ showSource: true,
+ context: {
+ showSelectedItem: ((value: string) => {
+ alert(value);
+ })
+ },
+ template: `
+ <sdc-autocomplete
+ placeholder="search text"
+ label="search by color:"
+ dataUrl="../../../stories/ng2-component-lab/utils/mock.json"
+ [dataSchema]="{key: 'id', value: 'color'}"
+ (itemSelected)="showSelectedItem($event)"
+ >
+ </sdc-autocomplete>
+ `
+ }
+]);
diff --git a/stories/ng2-component-lab/button.component.exp.ts b/stories/ng2-component-lab/button.component.exp.ts
new file mode 100644
index 0000000..6c5fb04
--- /dev/null
+++ b/stories/ng2-component-lab/button.component.exp.ts
@@ -0,0 +1,164 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+const buttonTypes = ['primary', 'secondary', 'link', 'alert'];
+const buttonSizes = ['large', 'medium', 'small', 'x-small', 'default'];
+const experiment = experimentOn('Button');
+
+experiment.group("Default button", [
+ {
+ id: "defaultButton",
+ showSource: true,
+ description: `Default button, does not need to supply type or size.
+ <br>The size of the button set to 'default' so it will shrink or expand according to the content.
+ `,
+ context: {
+ buttonClicked: ():void => {
+ window.alert("OK");
+ }
+ },
+ title: "Default button",
+ template: `
+ <sdc-button
+ text="Default button long text"
+ testId="longButton"
+ (click)="buttonClicked()">
+ </sdc-button>
+ <sdc-button
+ text="Sample button"
+ (click)="buttonClicked()"
+ [testId]="'defaultButtonTestId'"
+ >
+ </sdc-button>
+
+
+ `
+ }
+]);
+
+buttonTypes.forEach((buttonType) => {
+ [false, true].forEach((buttonDisabled) => {
+ experiment.group(`Button ${buttonType} ${buttonDisabled ? ' disabled' : ''}`, [ {
+ id: `Button ${buttonType}${buttonDisabled ? ' disabled' : ''}`,
+ showSource: true,
+ context: {
+ buttonClicked: ():void => {
+ window.alert("OK");
+ }
+ },
+ title: `Button ${buttonType}${buttonDisabled ? ' disabled' : ''}`,
+ template: buttonSizes.map((buttonSize) =>
+ `
+ <span style="display: inline-block;">
+ <div>${buttonSize}</div><br>
+ <sdc-button
+ text="Sample"
+ type="${buttonType}"
+ size="${buttonSize}"
+ (click)="buttonClicked()"
+ ${buttonDisabled ? ' [disabled]="true"' : ''}>
+ </sdc-button>
+ </span>
+ `).join('\n')
+ }
+ ]);
+ });
+});
+
+experiment.group("Buttons with icons", [
+ {
+ id: "buttonsWithIcons",
+ showSource: true,
+ description: `Buttons with icons forward`,
+ context: {
+ buttonClicked: (): void => {
+ window.alert("OK");
+ }
+ },
+ title: "Button with icons",
+ template: `
+ <sdc-button
+ text="Default button long text"
+ (click)="buttonClicked()"
+ icon_name="settings-o"
+ icon_position="left"
+ >
+ </sdc-button>
+
+ <sdc-button
+ text="Sample button"
+ (click)="buttonClicked()"
+ icon_name="plus-circle-o"
+ icon_position="left"
+ >
+ </sdc-button>
+
+ <sdc-button
+ text="Sample button"
+ type="secondary"
+ (click)="buttonClicked()"
+ icon_name="plus-circle"
+ icon_position="right"
+ >
+ </sdc-button>
+
+ <sdc-button
+ text="Sample button"
+ type="secondary"
+ (click)="buttonClicked()"
+ icon_name="caret2-right-circle-o"
+ icon_position="right"
+ >
+ </sdc-button>
+
+ `
+ }
+]);
+
+experiment.group("Buttons with spinners", [
+ {
+ id: "buttonsWithSpinnersRight",
+ showSource: true,
+ description: `Click the button to see the spinner shows for 2 seconds`,
+ context: {
+ buttonClicked: (button): void => {
+ button.show_spinner = true;
+ setTimeout(() => {button.show_spinner = false},2000);
+ },
+ },
+ title: "Button with spinner on the right",
+ template: `
+ <sdc-button
+ text="Click to show spinner"
+ (click)="buttonClicked(button)"
+ [show_spinner]="false"
+ spinner_position="right"
+ #button
+ >
+ </sdc-button>
+
+ `
+ },
+ {
+ id: "buttonsWithSpinnersLeft",
+ showSource: true,
+ description: `Click the button to see the spinner shows for 2 seconds`,
+ context: {
+ buttonClicked: (button): void => {
+ button.show_spinner = true;
+ setTimeout(() => {button.show_spinner = false},2000);
+ },
+ },
+ title: "Button with spinner on the left",
+ template: `
+ <sdc-button
+ text="Click to show spinner"
+ (click)="buttonClicked(button)"
+ spinner_position="left"
+ #button
+ >
+ </sdc-button>
+
+ `
+ }
+]);
+export default experiment;
diff --git a/stories/ng2-component-lab/checkbox.component.exp.ts b/stories/ng2-component-lab/checkbox.component.exp.ts
new file mode 100644
index 0000000..7ac53c9
--- /dev/null
+++ b/stories/ng2-component-lab/checkbox.component.exp.ts
@@ -0,0 +1,33 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+export default experimentOn('Checkbox')
+ .group("Checkbox",[
+ {
+ id: 'checkbox',
+ showSource: true,
+ title: 'Regular Checkbox',
+ description: 'Simple checkbox',
+ template: `<sdc-checkbox label="Simple"></sdc-checkbox>`,
+ },
+ {
+ id: 'checkboxChecked',
+ showSource: true,
+ title: 'Regular Checked Checkbox',
+ description: 'Simple checked checkbox',
+ template: `<sdc-checkbox label="Checked" [checked]="true"></sdc-checkbox>`,
+ },
+ {
+ id: 'disabledCheckbox',
+ showSource: true,
+ title: 'Disabled checkbox',
+ description: 'Simple disabled checkbox',
+ template: `<sdc-checkbox label="Disabled"[disabled]="true"></sdc-checkbox>`,
+ },
+ {
+ id: 'disabledCheckboxChecked',
+ showSource: true,
+ title: 'Disabled checked checkbox',
+ description: 'Simple disabled checked checkbox',
+ template: `<sdc-checkbox label="Disabled" [checked]="true" [disabled]="true"></sdc-checkbox>`,
+ }
+ ]);
diff --git a/stories/ng2-component-lab/checklist.component.exp.ts b/stories/ng2-component-lab/checklist.component.exp.ts
new file mode 100644
index 0000000..4700a74
--- /dev/null
+++ b/stories/ng2-component-lab/checklist.component.exp.ts
@@ -0,0 +1,213 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+import { ChecklistItemModel } from "../../src/angular/checklist/models/ChecklistItem";
+import { ChecklistModel } from "../../src/angular/checklist/models/Checklist";
+
+const styleCode = 'h5{color:red;} pre{background-color: #d1d1d1; padding: 10px;}';
+const checklistValuesExample1 = [];
+
+const checkListExample1: ChecklistModel = new ChecklistModel(checklistValuesExample1,
+ [new ChecklistItemModel('apple'),
+ new ChecklistItemModel('banana'),
+ new ChecklistItemModel('orange')]);
+
+const checklistValuesExample2 = [];
+const checkListExample2: ChecklistModel = new ChecklistModel(checklistValuesExample2,
+ [new ChecklistItemModel('apple', false, false, null, 0),
+ new ChecklistItemModel('banana', false, false, null, 1),
+ new ChecklistItemModel('orange', false, false, null, 2)]);
+
+const checklistValuesExample3 = [];
+const checkListExample3: ChecklistModel = new ChecklistModel(checklistValuesExample3,
+ [new ChecklistItemModel('apple', false, true),
+ new ChecklistItemModel('banana'),
+ new ChecklistItemModel('orange', false, true)]);
+
+const checklistValuesExample4 = [];
+const checkListExample4: ChecklistModel = new ChecklistModel(checklistValuesExample4,
+ [new ChecklistItemModel('apple', true, true),
+ new ChecklistItemModel('banana', true),
+ new ChecklistItemModel('orange')]);
+
+const checklistValuesExample5 = [];
+const innerChecklistValues = [];
+const checkListExample5: ChecklistModel = new ChecklistModel(checklistValuesExample5,
+ [new ChecklistItemModel('apple', false, false,
+ new ChecklistModel(innerChecklistValues,
+ [new ChecklistItemModel('red'), new ChecklistItemModel('green'), new ChecklistItemModel('yellow')])),
+ new ChecklistItemModel('banana'),
+ new ChecklistItemModel('orange')]);
+
+const checklistFirstLevelValuesExample6 = [];
+const checklistSecondLevelValuesExample6 = [];
+const checklistThirdLevelValuesExample6 = [];
+const checkListExample6: ChecklistModel = new ChecklistModel(checklistFirstLevelValuesExample6,
+ [new ChecklistItemModel('1', false, false,
+ new ChecklistModel(checklistSecondLevelValuesExample6, [new ChecklistItemModel('1.1'),
+ new ChecklistItemModel('1.2', false, false, new ChecklistModel(checklistThirdLevelValuesExample6, [new ChecklistItemModel('1.2.1'),
+ new ChecklistItemModel('1.2.2'),
+ new ChecklistItemModel('1.2.3')])),
+ new ChecklistItemModel('1.3')])),
+ new ChecklistItemModel('2'),
+ new ChecklistItemModel('3')]);
+
+export default experimentOn('Checklist')
+ .group("Checklist",[
+ {
+ id: 'checklist',
+ showSource: true,
+ context: {
+ checklistModel: checkListExample1,
+ checklistValues: checklistValuesExample1
+ },
+ styles: [styleCode],
+ title: 'Checklist',
+ description: `
+ <pre>
+ <h5>The checklistModel parameter:</h5>
+ const checklistValues = [];
+ const checklistModel: ChecklistModel =
+ new ChecklistModel(checklistValues,
+ [new ChecklistItemModel('apple'),
+ new ChecklistItemModel('banana'),
+ new ChecklistItemModel('orange')]);
+ </pre>
+ `,
+ template: `
+ <span>Selected values: {{checklistValues.toString()}}</span>
+ <sdc-checklist [checklistModel]="checklistModel"></sdc-checklist>
+ `,
+ },
+ {
+ id: 'checklistWithValues',
+ showSource: true,
+ context: {
+ checklistModel: checkListExample2,
+ checklistValues: checklistValuesExample2
+ },
+ styles: [styleCode],
+ title: 'Checklist with values',
+ description: `
+ <pre>
+ <h5>The checklistModel parameter:</h5>
+ const checklistValues = [];
+ const checklistModel: ChecklistModel = new ChecklistModel(checklistValues,
+ [new ChecklistItemModel('apple', false, false, null, 0),
+ new ChecklistItemModel('banana', false, false, null, 1),
+ new ChecklistItemModel('orange', false, false, null, 2)]);
+ </pre>
+ `,
+ template: `
+ <span>Selected values: {{checklistValues.toString()}}</span>
+ <sdc-checklist [checklistModel]="checklistModel"></sdc-checklist>
+ `
+ },
+ {
+ id: 'checklistWithSomeCheckedItems',
+ title: 'Checklist with some checked items',
+ showSource: true,
+ context: {
+ checklistModel: checkListExample3,
+ checklistValues: checklistValuesExample3
+ },
+ styles: [styleCode],
+ description: `
+ <pre><h5>The checklistModel parameter:</h5>
+ const checklistValues = [];
+ const checklistModel: ChecklistModel = new ChecklistModel(checklistValues,
+ [new ChecklistItemModel('apple', false, true),
+ new ChecklistItemModel('banana'),
+ new ChecklistItemModel('orange', false, true)]);
+ </pre>
+ `,
+ template: `
+ <span>Selected values: {{checklistValues.toString()}}</span>
+ <sdc-checklist [checklistModel]="checklistModel"></sdc-checklist>
+ `
+ },
+ {
+ id: 'checklistWithSomeDisabledItems',
+ title: 'Checklist with some disabled items',
+ showSource: true,
+ context: {
+ checklistModel: checkListExample4,
+ checklistValues: checklistValuesExample4
+ },
+ styles: [styleCode],
+ description: `
+ <pre><h5>The checklistModel parameter:</h5>
+ const checklistValues = [];
+ const checklistModel: ChecklistModel = new ChecklistModel(checklistValues,
+ [new ChecklistItemModel('apple', true, true),
+ new ChecklistItemModel('banana', true),
+ new ChecklistItemModel('orange')]);
+ </pre>
+ `,
+ template: `
+ <span>Selected values: {{checklistValues.toString()}}</span>
+ <sdc-checklist [checklistModel]="checklistModel"></sdc-checklist>
+ `
+ },
+ {
+ id: 'twoLevelsChecklist',
+ title: 'Multi-levels checklist',
+ showSource: true,
+ context: {
+ checklistModel: checkListExample5,
+ checklistValues: checklistValuesExample5,
+ innerChecklistValues: innerChecklistValues
+ },
+ styles: [styleCode],
+ description: `
+ <pre>
+ <h5>The checklistModel parameter:</h5>
+ const checklistValues = [];
+ const innerChecklistValues = [];
+ const checklistModel: ChecklistModel = new ChecklistModel(checklistValues,
+ [new ChecklistItemModel('apple', false, false,new ChecklistModel(innerChecklistValues,[new ChecklistItemModel('red'),
+ new ChecklistItemModel('green'),
+ new ChecklistItemModel('yellow')])),
+ new ChecklistItemModel('banana'),
+ new ChecklistItemModel('orange')]);</pre>
+ `,
+ template: `
+ <div>Selected values: {{checklistValues.toString()}}</div>
+ <div>Inner checklist selected values: {{innerChecklistValues.toString()}}</div>
+ <sdc-checklist [checklistModel]="checklistModel"></sdc-checklist>
+ `
+ },
+ {
+ id: 'multiLevelsChecklist',
+ title: 'Multi-levels checklist',
+ showSource: true,
+ context: {
+ checklistModel: checkListExample6,
+ checklistFirstLevelValues: checklistFirstLevelValuesExample6,
+ checklistSecondLevelValues: checklistSecondLevelValuesExample6,
+ checklistThirdLevelValues: checklistThirdLevelValuesExample6
+ },
+ styles: [styleCode],
+ description: `
+ <pre><h5>The checklistModel parameter:</h5>
+ const checklistFirstLevelValues = [];
+ const checklistSecondLevelValues = [];
+ const checklistThirdLevelValues = [];
+ const checklistModel: ChecklistModel = new ChecklistModel(checklistFirstLevelValues,
+ [new ChecklistItemModel('1', false, false,
+ new ChecklistModel(checklistSecondLevelValues, [new ChecklistItemModel('1.1'),
+ new ChecklistItemModel('1.2', false, false,
+ new ChecklistModel(checklistThirdLevelValues, [new ChecklistItemModel('1.2.1'),
+ new ChecklistItemModel('1.2.2'),
+ new ChecklistItemModel('1.2.3')])),
+ new ChecklistItemModel('1.3')])),
+ new ChecklistItemModel('2'),
+ new ChecklistItemModel('3')]);
+ </pre>
+ `,
+ template: `
+ <div>Selected values: {{checklistFirstLevelValues.toString()}}</div>
+ <div>Second level checklist selected values: {{checklistSecondLevelValues.toString()}}</div>
+ <div>Third level checklist selected values: {{checklistThirdLevelValues.toString()}}</div>
+ <sdc-checklist [checklistModel]="checklistModel"></sdc-checklist>
+ `
+ }
+ ]);
diff --git a/stories/ng2-component-lab/colors.component.exp.ts b/stories/ng2-component-lab/colors.component.exp.ts
new file mode 100644
index 0000000..f082d90
--- /dev/null
+++ b/stories/ng2-component-lab/colors.component.exp.ts
@@ -0,0 +1,42 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+const colorMap = {
+ 'white': '#ffffff',
+ 'dark-blue': '#0568ae',
+ 'blue': '#009fdb',
+ 'light-blue': '#1eb9f3',
+ 'blue-disabled': '#9dd9ef',
+ 'lighter-blue': '#e6f6fb',
+ 'black': '#000000',
+ 'text-black': '#191919',
+ 'rich-black': '#323943',
+ 'dark-gray': '#5a5a5a',
+ 'gray': '#959595',
+ 'light-gray': '#d2d2d2',
+ 'silver': '#eaeaea',
+ 'light-silver': '#f2f2f2',
+ 'lighter-silver':'#f8f8f8',
+ 'green': '#4ca90c',
+ 'red': '#cf2a2a',
+ 'light-red':'#ed4141',
+ 'disabled-red':'#f4adad',
+ 'yellow': '#ffb81c',
+ 'dark-purple': '#702f8a',
+ 'purple': '#9063cd',
+ 'light-purple': '#caa2dd'
+};
+
+export default experimentOn('Colors', 1)
+ .group("Color palette", [
+ {
+ id: 'colorPalette',
+ showSource: true,
+ context: {
+ colorMap
+ },
+ title: 'Color palette',
+ description: 'Supported design colors',
+ template: `<colors-table [tableTitle]="'Colors'" [tableMapColors]="colorMap"></colors-table>`,
+ }
+ ]
+ );
diff --git a/stories/ng2-component-lab/components.module.ts b/stories/ng2-component-lab/components.module.ts
new file mode 100644
index 0000000..266f047
--- /dev/null
+++ b/stories/ng2-component-lab/components.module.ts
@@ -0,0 +1,45 @@
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { FormsModule } from "@angular/forms";
+import { SdcUiComponentsModule } from "../../src/angular";
+import { KeysPipe } from "./utils/pipes/keys.pipe";
+import { SearchFilterPipe } from "./pipes/search-filter-pipe";
+import { ColorsTable } from "./components/colors-table.component";
+import { ModalInnerContent } from "./components/modal-inner-content-example.component";
+import { ModalConsumer } from "./components/modal-consumer.component";
+import { SvgIconsTableComponent } from "./components/svg-icons-table.component";
+import { NotificationsExample } from "./components/notifications-example.component";
+import { Mode, Placement, Size } from "./../../src/angular/common/enums";
+
+@NgModule({
+ declarations: [
+ ColorsTable,
+ KeysPipe,
+ ModalInnerContent,
+ ModalConsumer,
+ SearchFilterPipe,
+ SvgIconsTableComponent,
+ NotificationsExample
+ ],
+ imports: [
+ CommonModule,
+ FormsModule,
+ SdcUiComponentsModule
+ ],
+ exports: [
+ CommonModule,
+ SdcUiComponentsModule,
+ ModalInnerContent,
+ NotificationsExample,
+ ColorsTable,
+ SvgIconsTableComponent,
+ ModalConsumer,
+ SearchFilterPipe
+ ],
+ entryComponents: [
+ ModalInnerContent
+ ],
+ providers: [KeysPipe]
+})
+export class ComponentsModule {
+}
diff --git a/stories/ng2-component-lab/components/colors-table.component.ts b/stories/ng2-component-lab/components/colors-table.component.ts
new file mode 100644
index 0000000..fc7bd2f
--- /dev/null
+++ b/stories/ng2-component-lab/components/colors-table.component.ts
@@ -0,0 +1,26 @@
+import { Component, Input } from "@angular/core";
+
+@Component({
+ selector: "colors-table",
+ template: `
+
+ <h1>{{tableTitle}}</h1>
+ <div class="colors-table">
+ <div class="color-section" *ngFor="let color of tableMapColors | keys">
+ <div class='sdc-bc-{{color}} color-circle'></div>
+ <div>{{color}}</div>
+ <div>{{tableMapColors[color]}}</div>
+ </div>
+ </div>
+`
+})
+export class ColorsTable {
+
+ @Input() tableTitle:string;
+ @Input() tableMapColors: Object;
+
+ constructor() {
+
+ }
+
+}
diff --git a/stories/ng2-component-lab/components/modal-consumer.component.ts b/stories/ng2-component-lab/components/modal-consumer.component.ts
new file mode 100644
index 0000000..e4a3977
--- /dev/null
+++ b/stories/ng2-component-lab/components/modal-consumer.component.ts
@@ -0,0 +1,106 @@
+import { Component, Input, Output, EventEmitter } from "@angular/core";
+import { ModalService } from "../../../src/angular/modals/modal.service";
+import { IModalConfig, ModalType, ModalSize } from "../../../src/angular/modals/models/modal-config";
+import { ModalInnerContent } from "./modal-inner-content-example.component";
+import { ButtonComponent } from "../../../src/angular/buttons/button.component";
+import { ModalButtonComponent } from './../../../src/angular/modals/modal-button.component';
+import { Placement } from "../../../src/angular/common/enums";
+import { ModalComponent } from "../../../src/angular/components";
+
+const MODAL_CONTENT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed risus nisl, egestas vitae erat non,' +
+'pulvinar lacinia libero. Integer pulvinar pellentesque accumsan. Sed hendrerit lacus eu tempus pharetra';
+
+@Component({
+ selector: 'modal-consumer',
+ template: `<sdc-button [text]="'View Modal'" (click)="openModal()"></sdc-button>`
+})
+export class ModalConsumer {
+ @Input() action: string;
+
+ constructor(private modalService: ModalService) {
+ }
+
+ private openModal = (): void => {
+ if (this[this.action]) {
+ this[this.action]();
+ }
+ }
+
+ private openErrorModal = (): void => {
+ this.modalService.openErrorModal(MODAL_CONTENT, "sampleTestId");
+ }
+
+ private openAlertModal = (): void => {
+ this.modalService.openAlertModal("Alert Title", MODAL_CONTENT, 'Continue', this.onConfirmAction, 'sampleTestId');
+ }
+
+ private openActionModal = (): void => {
+ this.modalService.openActionModal('Standard Modal', MODAL_CONTENT, "OK", this.onConfirmAction, "sampleTestId");
+ }
+
+ private onConfirmAction = (): void => {
+ alert("Action has been confirmed");
+ }
+
+ private openCustomModal1 = (): void => {
+ const modalConfig = {
+ size: ModalSize.medium,
+ title: 'Title',
+ type: ModalType.custom,
+ testId: 'sampleTestIdModal1',
+ buttons: [
+ {id: "saveButton", text: "Save", callback: this.customModalOnSave1, closeModal: false},
+ {id: "cancelButton", text: "Cancel", size: 'x-small', type: 'secondary', closeModal: true}
+ ] as ModalButtonComponent[]
+ } as IModalConfig;
+ this.modalService.openCustomModal(modalConfig, ModalInnerContent, {name: "Sample Content"});
+ }
+
+ private customModalOnSave1 = (): void => {
+ const currentInstance: ModalComponent = this.modalService.getCurrentInstance();
+ const saveButton: ModalButtonComponent = currentInstance.getButtonById("saveButton");
+ saveButton.show_spinner = true;
+ saveButton.spinner_position = Placement.right;
+
+ // Show spinner for 2 seconds
+ console.log('Saving example, please wait ...');
+ window.setTimeout((button: ModalButtonComponent) => {
+ button.show_spinner = false;
+ console.log('Finish saving');
+ }, 2000, saveButton);
+ }
+
+ private openCustomModal2 = (): void => {
+ const modalConfig = {
+ size: ModalSize.medium,
+ title: 'Title',
+ type: ModalType.custom,
+ testId: 'sampleTestIdModal2',
+ buttons: [
+ {text: "Change title", callback: this.customModalChangeTitle2, closeModal: false},
+ {text: "Change buttons", callback: this.customModalUpdateButtons2, closeModal: false},
+ {text: "Disable close", callback: this.customModalUDisableClose2, closeModal: false}
+ ]
+ } as IModalConfig;
+ this.modalService.openCustomModal(modalConfig, ModalInnerContent, {name: "Sample Content"});
+ }
+
+ private customModalUDisableClose2 = (): void => {
+ const currentInstance: ModalComponent = this.modalService.getCurrentInstance();
+ currentInstance.getCloseButton().disabled = true;
+ }
+
+ private customModalChangeTitle2 = (): void => {
+ const currentInstance: ModalComponent = this.modalService.getCurrentInstance();
+ currentInstance.setTitle('New title');
+ }
+
+ private customModalUpdateButtons2 = (): void => {
+ const currentInstance: ModalComponent = this.modalService.getCurrentInstance();
+ const newButtons = [
+ {text: "Change title", callback: this.customModalChangeTitle2, closeModal: false},
+ {text: "Do nothing", closeModal: false}
+ ] as ModalButtonComponent[];
+ currentInstance.setButtons(newButtons);
+ }
+}
diff --git a/stories/ng2-component-lab/components/modal-inner-content-example.component.ts b/stories/ng2-component-lab/components/modal-inner-content-example.component.ts
new file mode 100644
index 0000000..1b6bed0
--- /dev/null
+++ b/stories/ng2-component-lab/components/modal-inner-content-example.component.ts
@@ -0,0 +1,16 @@
+import { Component, Input } from "@angular/core";
+
+@Component({
+ selector: "inner-content",
+ template: `
+ <div>
+ <sdc-input [label]="'Enter value'" [(value)]="name"> </sdc-input>
+ <sdc-input [label]="'Enter value'" [(value)]="name"> </sdc-input>
+ <sdc-input [label]="'Enter value'" [(value)]="name"> </sdc-input>
+ </div>
+`
+})
+export class ModalInnerContent {
+
+ @Input() name:string;
+}
diff --git a/stories/ng2-component-lab/components/notifications-example.component.ts b/stories/ng2-component-lab/components/notifications-example.component.ts
new file mode 100644
index 0000000..91dd95e
--- /dev/null
+++ b/stories/ng2-component-lab/components/notifications-example.component.ts
@@ -0,0 +1,57 @@
+import { Component, Input, ViewChild } from "@angular/core";
+import { NotificationsService } from "../../../src/angular/notifications/services/notifications.service";
+import { NotificationSettings } from "../../../src/angular/notifications/utilities/notification.config";
+import { InnerNotifContent } from "../../../src/angular/notifications/notification-inner-content-example.component";
+
+@Component({
+ selector: "notifications-example",
+ template: `
+ <div>
+ <span>Send Success Notification</span>
+ <sdc-button (click)="sendSuccessNotif()" text="Click Me!"></sdc-button>
+ </div>
+ <div>
+ <span>Send Warning Notification</span>
+ <sdc-button (click)="sendWarnNotif()" text="Click Me!"></sdc-button>
+ </div>
+ <div>
+ <span>Send Info Notification</span>
+ <sdc-button (click)="sendInfoNotif()" text="Click Me!"></sdc-button>
+ </div>
+ <div>
+ <span>Send Success MultipleLine Notification</span>
+ <sdc-button (click)="sendMultipleLinesSuceessNotif()" text="Click Me!"></sdc-button>
+ </div>
+ <div>
+ <span>Send Success Custom Notification</span>
+ <sdc-button (click)="sendSuccessCustomNotif()" text="Click Me!"></sdc-button>
+ </div>
+ <sdc-notification-container>
+ </sdc-notification-container>
+`
+})
+export class NotificationsExample {
+
+ constructor(private notifsService : NotificationsService) {
+ }
+
+ sendSuccessNotif() {
+ this.notifsService.push(new NotificationSettings("success", 'notif success message test', 'Notif Title Success'));
+ }
+
+ sendMultipleLinesSuceessNotif() {
+ this.notifsService.push(new NotificationSettings("success", 'notif success message test with a lot of test so we can test multiple line case lets just add blabla bcdesfg hijklmnop qrstuvw xyz abcdesfg hijklmnop qrstuvw xyz', 'Notif Title Success'));
+ }
+
+ sendWarnNotif() {
+ this.notifsService.push(new NotificationSettings("warn", 'notif warn message test', 'Notif Title Warn'));
+ }
+
+ sendInfoNotif() {
+ this.notifsService.push(new NotificationSettings("info", 'notif info message test', 'Notif Title Info'));
+ }
+
+ sendSuccessCustomNotif() {
+ this.notifsService.push(new NotificationSettings( "info", 'notif XYZ', 'Notif Custom XYZ', 10000, false, true, InnerNotifContent, { notifyText : "notif info custom inner message test", notifyTitle : "Notif Custom Inner Title Info"}));
+ }
+}
diff --git a/stories/ng2-component-lab/components/svg-icons-table.component.ts b/stories/ng2-component-lab/components/svg-icons-table.component.ts
new file mode 100644
index 0000000..732650d
--- /dev/null
+++ b/stories/ng2-component-lab/components/svg-icons-table.component.ts
@@ -0,0 +1,189 @@
+import { Component } from "@angular/core";
+import { Mode, Placement, Size } from "../../../src/angular/common/enums";
+import { SvgIconComponent } from "../../../src/angular/svg-icon/svg-icon.component";
+import { IDropDownOption, DropDownOptionType, DropDownTypes } from "../../../src/angular/form-elements/dropdown/dropdown-models";
+
+const options1: IDropDownOption[] = [
+ {
+ label: 'First Option',
+ value: 'First Option',
+ },
+ {
+ label: 'Second Option',
+ value: 'Second Option',
+ },
+ {
+ label: 'Third Option',
+ value: 'Third Option',
+ type: DropDownOptionType.Simple
+ }
+];
+
+@Component({
+ selector: "svg-icons-table",
+ template: `
+ <div class="icon-showcase">
+ <div>
+ <svg-icon [name]="selectedIcon" [mode]="defaultIconSettings.mode" [size]="defaultIconSettings.size"></svg-icon>
+ Selected icon: <b *ngIf="selectedIcon">{{selectedIcon}}</b><i *ngIf="!selectedIcon">None</i>
+ </div>
+
+ <div class="icon-options-wrapper">
+
+ <div class="icon-options">
+ <div class="icon-options-dropdowns">
+ <sdc-dropdown label="Mode" [selectedOption]="{'value': mode, 'label': mode}" [options]="modeOptions" (changed)="mode = $event.value"></sdc-dropdown>
+ <sdc-dropdown label="Label Placement" [selectedOption]="{'value': labelPlacement, 'label': labelPlacement}" [options]="labelPlacementOptions" [selectedOption]="labelPlacement" (changed)="labelPlacement = $event.value"></sdc-dropdown>
+ <sdc-dropdown label="Size" [selectedOption]="{'value': size, 'label': size}" [options]="sizeOptions" [selectedOption]="size" (changed)="size = $event.value"></sdc-dropdown>
+ </div>
+ <div class="icon-options-checkboxes-wrapper">
+ <div class="icon-options-checkboxes">
+ <sdc-checkbox label="Clickable" [checked]="clickable" (checkedChange)="clickable = $event"></sdc-checkbox>
+ <sdc-checkbox label="Disabled" [checked]="disabled" (checkedChange)="disabled = $event"></sdc-checkbox>
+ </div>
+ <div class="icon-options-label">
+ <sdc-input label="Label" [(value)]="label"></sdc-input>
+ </div>
+ <svg-icon-label [name]="selectedIcon" [mode]="mode" [size]="size" [clickable]="clickable" [disabled]="disabled" [label]="label" [labelPlacement]="labelPlacement"></svg-icon-label>
+ </div>
+ </div>
+
+ <div class="icon-code">
+ <pre>
+ &lt;svg-icon-label
+ [name]="{{selectedIcon}}"
+ [mode]="{{mode}}"
+ [size]="{{size}}"
+ [clickable]="{{clickable}}"
+ [disabled]="{{disabled}}"
+ [label]="{{label}}"
+ [labelPlacement]="{{labelPlacement}}"&gt;
+ &lt;/svg-icon-label&gt;
+ </pre>
+ </div>
+ </div>
+
+ </div>
+ <div class="svg-icons-table">
+ <div *ngFor="let iconName of iconsNames" class="svg-icon-cell" [ngClass]="{'selected': selectedIcon === iconName}" (click)="selectIcon(iconName)">
+ <svg-icon-label [name]="iconName" [label]="iconName" labelPlacement="right"></svg-icon-label>
+ </div>
+ </div>
+`,
+ styles: [`
+ .svg-icons-table {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: flex-start;
+ align-items: stretch;
+ overflow-y: auto;
+ }
+ .svg-icons-table .svg-icon-cell {
+ border: 1px solid #999;
+ padding: 5px;
+ margin: 5px;
+ width: 250px;
+ overflow: hidden;
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+ }
+ .svg-icons-table .svg-icon-cell.selected {
+ border-color: #1eb9f3;
+ background-color: #1eb9f3;
+ }
+ .icon-showcase {
+ margin: 20px 10px;
+ padding: 10px;
+ border: 1px solid #999;
+ background: #eee;
+ }
+ .icon-options-wrapper {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: flex-start;
+ margin-top: 10px;
+ }
+
+ .icon-options-checkboxes-wrapper {
+ display: flex;
+ flex-flow: row;
+ margin-top: 10px;
+ }
+
+ .icon-options-checkboxes {
+ margin-top: 27px;
+ margin-right: 30px;
+ }
+
+ .icon-options-label {
+ margin-right: 30px;
+ }
+
+ .icon-code pre {
+ user-select: text;
+ }
+
+ sdc-dropdown {
+ display: inline-block;
+ min-width: 160px;
+ }
+
+ sdc-dropdown .sdc-dropdown {
+ }
+`]
+})
+export class SvgIconsTableComponent {
+ public iconsNames: string[];
+ public selectedIcon: string;
+
+ public modeOptions;
+ public sizeOptions;
+ public labelPlacementOptions;
+
+ private mode: Mode;
+ private size: Size;
+ private labelPlacement: Placement;
+ private clickable: boolean;
+ private disabled: boolean;
+ private label: string;
+
+ private defaultIconSettings: {mode: Mode, size: Size};
+
+ constructor() {
+ this.iconsNames = Object.keys(SvgIconComponent.Icons);
+ this.mode = null;
+ this.size = Size.medium;
+ this.clickable = false;
+ this.disabled = false;
+ this.defaultIconSettings = { mode: Mode.info, size: Size.small };
+
+ this.modeOptions = [{value: null, label: 'NONE'}].concat(Object.keys(Mode).map((modeKey) => ({
+ value: modeKey,
+ label: Mode[modeKey]
+ })));
+
+ this.sizeOptions = Object.keys(Size).map((sizeKey) => ({
+ value: sizeKey,
+ label: Size[sizeKey]
+ }));
+
+ this.labelPlacementOptions = Object.keys(Placement).map((placementKey) => ({
+ value: placementKey,
+ label: Placement[placementKey]
+ }));
+
+ this.setDefaults();
+ }
+
+ private setDefaults = (): void => {
+ this.label = 'Some label';
+ this.selectedIcon = "attachment";
+ this.mode = Mode.primary;
+ this.labelPlacement = Placement.right;
+ }
+
+ public selectIcon(iconName) {
+ this.selectedIcon = iconName;
+ }
+}
diff --git a/stories/ng2-component-lab/dropdown.component.exp.ts b/stories/ng2-component-lab/dropdown.component.exp.ts
new file mode 100644
index 0000000..025409e
--- /dev/null
+++ b/stories/ng2-component-lab/dropdown.component.exp.ts
@@ -0,0 +1,195 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+import { IDropDownOption, DropDownOptionType, DropDownTypes } from "../../src/angular/form-elements/dropdown/dropdown-models";
+
+const options1: IDropDownOption[] = [
+ {
+ label: 'First Option Label',
+ value: 'firstOptionValue',
+ },
+ {
+ label: 'Second Option Label',
+ value: 'secondOptionValue',
+ },
+ {
+ label: 'Third Option Label',
+ value: 'thirdOptionValue',
+ type: DropDownOptionType.Simple
+ }
+];
+
+const options2: IDropDownOption[] = [
+ {
+ label: 'Header Label',
+ value: 'headerValue',
+ type: DropDownOptionType.Header
+ },
+ {
+ label: 'First Option Label',
+ value: 'firstOptionValue',
+ type: DropDownOptionType.Simple
+ },
+ {
+ label: 'Disabled Option Label',
+ value: 'headerValue',
+ type: DropDownOptionType.Disable
+ },
+ {
+ label: 'Second Option Label',
+ value: 'secondOptionValue',
+ type: DropDownOptionType.Simple
+ },
+ {
+ label: 'Ruler Label',
+ value: 'rulerValue',
+ type: DropDownOptionType.HorizontalLine
+ },
+ {
+ label: 'Third Option Label',
+ value: 'thirdOptionValue',
+ type: DropDownOptionType.Simple
+ },
+ {
+ label: 'Fourth Option Label',
+ value: 'FourthOptionValue',
+ type: DropDownOptionType.Simple
+ },
+ {
+ label: 'Fifth Option Label',
+ value: 'fifthOptionValue',
+ type: DropDownOptionType.Simple
+ },
+ {
+ label: 'Ruler Label',
+ value: 'rulerValue',
+ type: DropDownOptionType.HorizontalLine
+ },
+ {
+ label: 'Third Option Label',
+ value: 'thirdOptionValue',
+ type: DropDownOptionType.Simple
+ },
+ {
+ label: 'Fourth Option Label',
+ value: 'FourthOptionValue',
+ type: DropDownOptionType.Simple
+ },
+ {
+ label: 'Fifth Option Label',
+ value: 'fifthOptionValue',
+ type: DropDownOptionType.Simple
+ }
+];
+
+export default experimentOn('DropDown')
+ .group("DropDown", [
+ {
+ id: 'normalDropDown',
+ showSource: true,
+ context: {
+ options: options1,
+ onChange: function(option) {
+ this.valueSelected = option.value;
+ }
+ },
+ title: 'Normal DropDown',
+ description: 'Normal DropDown',
+ template: `
+ <sdc-dropdown label="Hi I am a label" placeHolder="Please choose option" [options]="options" (changed)="onChange($event)"></sdc-dropdown>
+ <div style="margin: 10px 0 30px 0px; font-size:18px">Selected value:<strong style="font-weight: 700">{{valueSelected}}</strong></div>
+ `
+ }, {
+ id: 'groupDropDown',
+ showSource: true,
+ context: {
+ options: options2,
+ onChange: function(option) {
+ this.valueSelected = option.value;
+ }
+ },
+ title: 'DropDown with groups',
+ description: 'DropDown with groups',
+ template: `
+ <sdc-dropdown label="Hi I am a label" placeHolder="Please choose option" [options]="options" (changed)="onChange($event)"></sdc-dropdown>
+ <div style="margin: 10px 0 30px 0px; font-size:18px">Selected value:<strong style="font-weight: 900">{{valueSelected}}</strong></div>
+ `
+ },
+ {
+ id: 'groupDropDownPreSelect',
+ showSource: true,
+ context: {
+ options: options2,
+ onChange: function(option) {
+ this.valueSelected = option.value;
+ }
+ },
+ title: 'DropDown with groups and pre-selected value',
+ description: 'DropDown with groups and pre-selected value',
+ template: `
+ <sdc-dropdown label="Hi I am a label"
+ placeHolder="Please choose option"
+ [options]="options"
+ [selectedOption]="{label: 'does not matter', value: 'firstOptionValue'}"
+ (changed)="onChange($event)"></sdc-dropdown>
+ <div style="margin: 10px 0 30px 0px; font-size:18px">Selected value:<strong style="font-weight: 900">{{valueSelected}}</strong></div>
+ `
+ },
+ {
+ id: 'headlesspDropDown',
+ showSource: true,
+ context: {
+ options: options2,
+ dropDownHedlessType: DropDownTypes.Headless,
+ onChange: function(option) {
+ this.valueSelected = option.value;
+ }
+ },
+ title: 'Headless and Labeless DropDown',
+ description: 'Headless and labeless DropDown',
+ template: `
+ <button style="margin-bottom: 10px;" SdcDropdownTrigger [dropDown]="dropDown1">Click to toggle!</button>
+ <sdc-dropdown #dropDown1 [options]="options" [type]="dropDownHedlessType" (changed)="onChange($event)"></sdc-dropdown>
+ <div style="margin: 10px 0 30px 0px; font-size:18px">Selected value:<strong style="font-weight: 900">{{valueSelected}}</strong></div>
+ `
+ },
+ {
+ id: 'disabledDropDown',
+ showSource: true,
+ context: {
+ options: options2,
+ onChange: function(option) {
+ this.valueSelected = option.value;
+ }
+ },
+ title: 'Disabled DropDown',
+ description: 'Disabled DropDown',
+ template: `
+ <sdc-dropdown label="Hi I am a label"
+ placeHolder="Please choose option"
+ disabled="true"
+ [options]="options"
+ (changed)="onChange($event)"></sdc-dropdown>
+ <div style="margin: 10px 0 30px 0px; font-size:18px">Selected value:<strong style="font-weight: 900">{{valueSelected}}</strong></div>
+ `
+ },
+ {
+ id: 'normalAutoDropDown',
+ showSource: true,
+ context: {
+ options: options1,
+ dropDownAutoType: DropDownTypes.Auto,
+ onChange: function(option) {
+ this.valueSelected = option.value;
+ }
+ },
+ title: 'Normal Auto DropDown',
+ description: 'Normal Auto DropDown',
+ template: `
+ <sdc-dropdown label="Hi I am a label"
+ placeHolder="Please choose option"
+ [type]="dropDownAutoType"
+ [options]="options"
+ (changed)="onChange($event)"></sdc-dropdown>
+ <div style="margin: 10px 0 30px 0px; font-size:18px">Selected value:<strong style="font-weight: 900">{{valueSelected}}</strong></div>
+ `
+ }
+ ]);
diff --git a/stories/ng2-component-lab/filter-bar.component.exp.ts b/stories/ng2-component-lab/filter-bar.component.exp.ts
new file mode 100644
index 0000000..12a287d
--- /dev/null
+++ b/stories/ng2-component-lab/filter-bar.component.exp.ts
@@ -0,0 +1,56 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+import { SearchFilterPipe } from './pipes/search-filter-pipe';
+
+const action = (e): void => {
+ console.log("The search query was changed to: ", e);
+};
+
+export default experimentOn('Filter Bar').group('FilterBar', [
+ {
+ id: 'filterBar',
+ title: 'Filter bar',
+ description: `
+ The filter bar component text is updated (after debounce time,
+ default 200 miliseconds) while user write something.
+ In this example the event on search query changed:
+ const action = (e): void => {
+ console.log("The search query was changed to: ", e);
+ };
+ `,
+ context: {
+ onChange: action
+ },
+ showSource: true,
+ template: `
+ <sdc-filter-bar placeholder="filter text"
+ label="filter example:"
+ [(searchQuery)]="searchText"
+ (searchQueryChange)="onChange($event)">
+ </sdc-filter-bar>
+ <br>
+ Text to search: {{searchText}}
+ `
+ },
+ {
+ id: 'filterBarWithData',
+ title: 'Filter bar with data',
+ description: `
+ Example of filter bar component with debounce 100 miliseconds,
+ and with example pipe for filterring.
+ `,
+ context: {
+ data: ['apple', 'banana', 'orange', 'peach']
+ },
+ showSource: true,
+ template: `
+ <sdc-filter-bar placeholder="filter text"
+ label="filter example:"
+ [debounceTime]="100"
+ [(searchQuery)]="searchText">
+ </sdc-filter-bar>
+ <ul style="height: 100px; background-color: #eeeeee;">
+ <li *ngFor="let item of data | PipeSearchFilter:searchText">{{item}}</li>
+ </ul>
+ `
+ }
+]);
diff --git a/stories/ng2-component-lab/infinite-scroll.component.exp.ts b/stories/ng2-component-lab/infinite-scroll.component.exp.ts
new file mode 100644
index 0000000..bd20be5
--- /dev/null
+++ b/stories/ng2-component-lab/infinite-scroll.component.exp.ts
@@ -0,0 +1,166 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+const basicContext = {
+ scrollContainerId: 'scrollContainer',
+ numLines: Array(20).fill(null),
+ hitBottomCount: 0,
+ pageCount: 0,
+ isPageLoading: false,
+ insertPageImmediately: function(pageNum) {
+ const scrollContainerElem: HTMLElement = document.getElementById(this.scrollContainerId);
+ scrollContainerElem.appendChild(document.createElement('hr'));
+ Array(10).fill(null).forEach((_, i) => {
+ const lineElem = document.createElement('div');
+ lineElem.innerHTML = `Page ${pageNum} - line ${i + 1}`;
+ scrollContainerElem.appendChild(lineElem);
+ });
+ },
+ loadPageAsync: function(pageNum, timeout) {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ this.insertPageImmediately(pageNum);
+ resolve();
+ }, timeout);
+ });
+ },
+ onScrollHitBottom: function() {
+ this.hitBottomCount++;
+ }
+};
+
+const basicStyle = `
+ .scroll-container {
+ margin: 12px;
+ border: none;
+ padding: 5px;
+ width: 200px;
+ height: 100px;
+ overflow: auto;
+ font-size: 20px !important;
+ box-shadow: #666 1px 1px 10px;
+ }
+
+ .example-source {
+ background: #eeeeee;
+ padding: 10px;
+ border: 1px solid #999999;
+ }
+ .example-source pre {
+ overflow: hidden;
+ background: #dddddd;
+ margin-top: 5px;
+ padding: 5px;
+ user-select: text;
+ }
+`;
+const makeBasicStyleDistance = (distance: number) => `
+ .scroll-container::after {
+ display: block;
+ content: '';
+ height: ${distance}px;
+ background: red;
+ }
+`;
+
+export default experimentOn('Infinite-Scroll')
+ .group("Infinite Scroll",[
+ {
+ id: 'infiniteScrollUsage',
+ showSource: true,
+ context: Object.assign({}, basicContext),
+ title: 'Infinite scroll usage',
+ description: 'Infinite scroll usage',
+ styles: [basicStyle],
+ template: `
+ <div (infiniteScroll)="onScrollHitBottom()" class="scroll-container">
+ <div *ngFor="let _i of numLines; let i=index">
+ Line {{i + 1}}
+ </div>
+ </div>
+ Hit bottom for <b>{{hitBottomCount}}</b> times!
+ <div class="example-source">
+ <b>onScrollHitBottom declaration:</b>
+ <pre>{{onScrollHitBottom}}</pre>
+ </div>
+ `
+ },
+ {
+ id: 'infiniteScrollUsageWithDistance',
+ showSource: true,
+ title: 'Infinite scroll usage with distance',
+ context: Object.assign({}, basicContext),
+ styles: [basicStyle, makeBasicStyleDistance(50)],
+ description: '',
+ template: `
+ <div (infiniteScroll)="onScrollHitBottom()" [infiniteScrollDistance]="50" class="scroll-container">
+ <div *ngFor="let _i of numLines; let i=index">
+ Line {{i + 1}}
+ </div>
+ </div>
+ Hit bottom for <b>{{hitBottomCount}}</b> times!
+ <div class="example-source">
+ <b>onScrollHitBottom declaration:</b>
+ <pre>{{onScrollHitBottom}}</pre>
+ </div>
+ `
+ },
+ {
+ id: 'infiniteScrollUsageWithExpandingContent',
+ title: 'Infinite scroll usage with expanding content',
+ showSource: true,
+ context: Object.assign({}, basicContext, {
+ scrollContainerId: 'scrollContainer1',
+ onScrollHitBottom: function() {
+ this.hitBottomCount++;
+ this.insertPageImmediately(this.pageCount + 1);
+ this.pageCount++;
+ }
+ }),
+ styles: [basicStyle, makeBasicStyleDistance(20)],
+ template: `
+ <div (infiniteScroll)="onScrollHitBottom()" [infiniteScrollDistance]="20" class="scroll-container" id="{{scrollContainerId}}">
+ <div *ngFor="let _i of numLines; let i=index">
+ Line {{i + 1}}
+ </div>
+ </div>
+ Hit bottom for <b>{{hitBottomCount}}</b> times!<br/>
+ Loaded {{pageCount}} pages!
+ <div class="example-source">
+ <b>onScrollHitBottom declaration:</b>
+ <pre>{{onScrollHitBottom}}</pre>
+ </div>
+ `
+ },
+ {
+ id: 'infiniteScrollUsageWithExpandingContentAsynchronous',
+ title: 'Infinite scroll usage with expanding content asynchronous',
+ showSource: true,
+ context: Object.assign({}, basicContext, {
+ scrollContainerId: 'scrollContainer2',
+ onScrollHitBottom: function() {
+ this.hitBottomCount++;
+ if (!this.isPageLoading) {
+ this.isPageLoading = true;
+ this.loadPageAsync(this.pageCount + 1, 5000).then(() => {
+ this.pageCount++;
+ this.isPageLoading = false;
+ });
+ }
+ }
+ }),
+ styles: [basicStyle, makeBasicStyleDistance(20)],
+ template: `
+ <div (infiniteScroll)="onScrollHitBottom()" [infiniteScrollDistance]="20" class="scroll-container" id="{{scrollContainerId}}">
+ <div *ngFor="let _i of numLines; let i=index">
+ Line {{i + 1}}
+ </div>
+ </div>
+ Hit bottom for <b>{{hitBottomCount}}</b> times!<br/>
+ Loaded {{pageCount}} pages! <span *ngIf="isPageLoading">LOADING page #{{this.pageCount + 1}} ...</span>
+ <div class="example-source">
+ <b>onScrollHitBottom declaration:</b>
+ <pre>{{onScrollHitBottom}}</pre>
+ </div>
+ `
+ }
+ ]);
diff --git a/stories/ng2-component-lab/input.component.exp.ts b/stories/ng2-component-lab/input.component.exp.ts
new file mode 100644
index 0000000..7e931d6
--- /dev/null
+++ b/stories/ng2-component-lab/input.component.exp.ts
@@ -0,0 +1,79 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+const valueChange = (value: any): void => {
+ console.log('The value was changed! >>>>', value);
+};
+
+export default experimentOn('Input')
+ .group("Input",[
+ {
+ id: 'normalInput',
+ showSource: true,
+ title: 'Normal input',
+ description: 'Normal input',
+ template: `
+ <sdc-input label="Please Enter value" name="myValue" testId="myTestId"></sdc-input>
+ `
+ },
+ {
+ id: 'disabledInput',
+ showSource: true,
+ title: 'Disabled input',
+ description: 'Disabled input',
+ template: `
+ <sdc-input [disabled]="true"></sdc-input>
+ `
+ },
+ {
+ id: 'InputTypeNumber',
+ showSource: true,
+ title: 'Input type number',
+ description: 'Input type number',
+ template: `
+ <sdc-input type='number'></sdc-input>
+ `
+ },
+ {
+ id: 'Input required',
+ title: 'Input required',
+ description: 'Input required (this add red * to the label, but does not perform validation, use sdc-validation for validation)',
+ showSource: true,
+ template: `
+ <sdc-input label="Please Enter Value" required="true" [maxLength]="5"></sdc-input>
+ `
+ },
+ {
+ id: 'inputWithMaxLength',
+ title: 'Input with max length',
+ description: 'Input with max length',
+ showSource: true,
+ template: `
+ <sdc-input [maxLength]="5"></sdc-input>
+ `
+ },
+ {
+ id: 'inputWithPlaceholder',
+ title: 'Input with placeholder, custom class, and tests ID',
+ description: 'Input with placeholder',
+ showSource: true,
+ template: `
+ <sdc-input placeHolder="Text..." [classNames]="'my-custom-class another-class'" [testId]="'customTestId'"></sdc-input>
+ `
+ },
+ {
+ id: 'inputWithDebounce',
+ title: 'Input with debounce time',
+ description: `<pre>On value change event code:
+ const valueChange = (value: any): void => {
+ console.log('The value was changed! >>>>', value);
+ };
+ This event will happen 5 sec after the change
+ </pre>`,
+ showSource: true,
+ context: {
+ changeEvent: valueChange
+ },
+ template: `
+ <sdc-input [debounceTime]="5000" (valueChange)="changeEvent($event)"></sdc-input>
+ `
+ }]);
diff --git a/stories/ng2-component-lab/modals.component.exp.ts b/stories/ng2-component-lab/modals.component.exp.ts
new file mode 100644
index 0000000..e7e38bc
--- /dev/null
+++ b/stories/ng2-component-lab/modals.component.exp.ts
@@ -0,0 +1,126 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+const sourceStyles:string =`
+ .example-source {
+ background: #eeeeee;
+ padding: 10px;
+ border: 1px solid #999999;
+ margin-top:30px;
+ }
+ .example-source pre {
+ overflow: hidden;
+ background: #dddddd;
+ margin-top: 5px;
+ padding: 5px;
+ user-select: text;
+ }
+ .example-source pre .comment{
+ color:#666;
+ opacity:0.4;
+ font-style:italic;
+ transition: opacity 400ms ease-in;
+ }
+ .example-source pre:hover .comment {
+ opacity:1;
+ }
+`;
+
+export default experimentOn('Modals')
+ .group("Modals", [
+ {
+ id: 'standardModal',
+ showSource: false,
+ title: 'Standard modal',
+ description: 'Opens a modal with a custom title, message, and confirm button with a callback.',
+ template: `
+ <modal-consumer [action]="'openActionModal'"></modal-consumer>
+ <div class="example-source">Source Code:
+ <pre>
+ const MODAL_CONTENT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed risus nisl, egestas vitae erat non,' +
+ 'pulvinar lacinia libero. Integer pulvinar pellentesque accumsan. Sed hendrerit lacus eu tempus pharetra';
+
+ this.modalService.openActionModal('Standard Modal', MODAL_CONTENT, "OK", this.onConfirmAction, "sampleTestId");
+
+ private onConfirmAction = ():void => {{ '{' }}
+ alert("Action has been confirmed");
+ {{ '}' }};
+ </pre></div>`,
+ styles: [sourceStyles]
+ },
+ {
+ id: 'alertModal',
+ showSource: false,
+ title: 'Alert modal',
+ description: 'Opens a standard alert modal with a custom title and message.',
+ template: `
+
+
+ <modal-consumer [action]="'openAlertModal'"></modal-consumer>
+ <div class="example-source">Source Code:
+ <pre>
+ const MODAL_CONTENT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed risus nisl, egestas vitae erat non,' +
+ 'pulvinar lacinia libero. Integer pulvinar pellentesque accumsan. Sed hendrerit lacus eu tempus pharetra';
+
+ this.modalService.openAlertModal("Alert Title", MODAL_CONTENT, "Continue", this.onConfirmAction, "sampleTestId");
+ </pre></div>`,
+ styles: [sourceStyles]
+ },
+ {
+ id: 'errorModal',
+ showSource: false,
+ title: 'Error modal',
+ description: `Opens a standard error modal with a custom message.`,
+ template: `<modal-consumer [action]="'openErrorModal'"></modal-consumer>
+ <div class="example-source">Source Code:
+ <pre>
+
+ this.modalService.openErrorModal("An error has occurred!", "sampleTestId");
+ </pre></div>`,
+ styles: [sourceStyles]
+ },
+ {
+ id: 'customModal1',
+ showSource: false,
+ title: 'Custom modal 1',
+ description: 'Opens a modal with dynamic inner content and customizable title, buttons, and callbacks.',
+ template: `
+ <modal-consumer [action]="'openCustomModal1'"></modal-consumer>
+ <div class="example-source">Source Code:
+ <pre>
+
+ <span class="comment">//create modal config object </span>
+ let modalConfig:IModalConfig = {{ '{' }}
+ size: ModalSize.small,
+ title: 'Title',
+ type: ModalType.standard,
+ buttons: [
+ {{ '{' }}text:"Save", size:"'x-small'", callback:this.customModalOnSave, closeModal:false{{ '}' }},
+ {{ '{' }}text:"Cancel", size:"'x-small'", closeModal:true{{ '}' }}]
+ {{ '}' }};
+
+ <span class="comment">//open modal with dynamically created 'modalInnerContent' example component. Send data object with input 'name'. </span>
+ this.modalService.openCustomModal(modalConfig, ModalInnerContent, {{ '{' }}name: "Sample Content"{{ '}' }});
+
+ private customModalOnDone = ():void => {{ '{' }}
+ let currentInstance:any = this.modalService.getCurrentInstance();
+ alert("Save with result: " + currentInstance.innerModalContent.instance.name);
+ {{ '}' }};
+
+ private customModalOnSave = ():void => {{ '{' }}
+ let currentInstance:any = this.modalService.getCurrentInstance();
+ alert("Save with result: " + currentInstance.innerModalContent.instance.name);
+ {{ '}' }};
+ </pre></div>`,
+ styles: [sourceStyles]
+ },
+ {
+ id: 'customModal2',
+ showSource: false,
+ title: 'Custom modal 2',
+ description: 'Opens a modal with, and change his buttons and title',
+ template: `
+ <modal-consumer [action]="'openCustomModal2'"></modal-consumer>
+ `,
+ styles: [sourceStyles]
+ }
+ ]);
diff --git a/stories/ng2-component-lab/notification.component.exp.ts b/stories/ng2-component-lab/notification.component.exp.ts
new file mode 100644
index 0000000..ba2ba24
--- /dev/null
+++ b/stories/ng2-component-lab/notification.component.exp.ts
@@ -0,0 +1,11 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+export default experimentOn('Notification')
+ .group("Default Notification",[
+ {
+ id: 'notificationContainer',
+ showSource: true,
+ title: 'Notification Container',
+ description: 'container example ...',
+ template: `<notifications-example></notifications-example>`,
+ }]);
diff --git a/stories/ng2-component-lab/pipes/search-filter-pipe.ts b/stories/ng2-component-lab/pipes/search-filter-pipe.ts
new file mode 100644
index 0000000..5469eb4
--- /dev/null
+++ b/stories/ng2-component-lab/pipes/search-filter-pipe.ts
@@ -0,0 +1,15 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe ({
+ name: 'PipeSearchFilter',
+})
+export class SearchFilterPipe implements PipeTransform {
+ public transform(value, text: string) {
+ if (!text || !text.length) {
+ return value;
+ }
+ return value.filter((item) => {
+ return item.toLowerCase().indexOf(text.toLowerCase()) > -1;
+ });
+ }
+}
diff --git a/stories/ng2-component-lab/popup-menu.component.exp.ts b/stories/ng2-component-lab/popup-menu.component.exp.ts
new file mode 100644
index 0000000..12da361
--- /dev/null
+++ b/stories/ng2-component-lab/popup-menu.component.exp.ts
@@ -0,0 +1,104 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+export default experimentOn('Menu')
+ .group("Popups",[
+ {
+ id: 'basicPopupMenuStatic',
+ showSource: true,
+ title: 'Basic popup menu (static)',
+ description: 'Basic popup menu (static)',
+ template: `
+ <popup-menu-list [open]="true">
+ <popup-menu-item>
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="18" viewBox="0 0 24 24">
+ <defs>
+ <path id="add-copy-a1" d="M11,0 C4.9,0 0,4.9 0,11 C0,17.1 4.9,22 11,22 C17.1,22 22,17.1 22,11 C22,4.9 17.1,0 11,0 M15,10 L12,10 L12,7 C12,6.4 11.6,6 11,6 C10.4,6 10,6.4 10,7 L10,10 L7,10 C6.4,10 6,10.4 6,11 C6,11.6 6.4,12 7,12 L10,12 L10,15 C10,15.6 10.4,16 11,16 C11.6,16 12,15.6 12,15 L12,12 L15,12 C15.6,12 16,11.6 16,11 C16,10.4 15.6,10 15,10"/>
+ </defs>
+ <g fill="none" fill-rule="evenodd" transform="translate(1 1)">
+ <use xlink:href="#add-copy-a1"/>
+ </g>
+ </svg>
+ First
+ </popup-menu-item>
+ <popup-menu-item type="selected">
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="18" viewBox="0 0 24 24">
+ <defs>
+ <path id="add-copy-a2" d="M11,0 C4.9,0 0,4.9 0,11 C0,17.1 4.9,22 11,22 C17.1,22 22,17.1 22,11 C22,4.9 17.1,0 11,0 M15,10 L12,10 L12,7 C12,6.4 11.6,6 11,6 C10.4,6 10,6.4 10,7 L10,10 L7,10 C6.4,10 6,10.4 6,11 C6,11.6 6.4,12 7,12 L10,12 L10,15 C10,15.6 10.4,16 11,16 C11.6,16 12,15.6 12,15 L12,12 L15,12 C15.6,12 16,11.6 16,11 C16,10.4 15.6,10 15,10"/>
+ </defs>
+ <g fill="none" fill-rule="evenodd" transform="translate(1 1)">
+ <use xlink:href="#add-copy-a2"/>
+ </g>
+ </svg>
+ Selected
+ </popup-menu-item>
+ <popup-menu-item type="disabled">
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="18" viewBox="0 0 24 24">
+ <defs>
+ <path id="add-copy-a3" d="M11,0 C4.9,0 0,4.9 0,11 C0,17.1 4.9,22 11,22 C17.1,22 22,17.1 22,11 C22,4.9 17.1,0 11,0 M15,10 L12,10 L12,7 C12,6.4 11.6,6 11,6 C10.4,6 10,6.4 10,7 L10,10 L7,10 C6.4,10 6,10.4 6,11 C6,11.6 6.4,12 7,12 L10,12 L10,15 C10,15.6 10.4,16 11,16 C11.6,16 12,15.6 12,15 L12,12 L15,12 C15.6,12 16,11.6 16,11 C16,10.4 15.6,10 15,10"/>
+ </defs>
+ <g fill="none" fill-rule="evenodd" transform="translate(1 1)">
+ <use xlink:href="#add-copy-a3"/>
+ </g>
+ </svg>
+ Disabled
+ </popup-menu-item>
+ <popup-menu-item type="separator"></popup-menu-item>
+ <popup-menu-item>
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="18" viewBox="0 0 24 24">
+ <defs>
+ <path id="add-copy-a4" d="M11,0 C4.9,0 0,4.9 0,11 C0,17.1 4.9,22 11,22 C17.1,22 22,17.1 22,11 C22,4.9 17.1,0 11,0 M15,10 L12,10 L12,7 C12,6.4 11.6,6 11,6 C10.4,6 10,6.4 10,7 L10,10 L7,10 C6.4,10 6,10.4 6,11 C6,11.6 6.4,12 7,12 L10,12 L10,15 C10,15.6 10.4,16 11,16 C11.6,16 12,15.6 12,15 L12,12 L15,12 C15.6,12 16,11.6 16,11 C16,10.4 15.6,10 15,10"/>
+ </defs>
+ <g fill="none" fill-rule="evenodd" transform="translate(1 1)">
+ <use xlink:href="#add-copy-a4"/>
+ </g>
+ </svg>
+ Second
+ </popup-menu-item>
+ </popup-menu-list>
+ `
+ },
+ {
+ id: 'basicMenuRelative',
+ title: 'Basic menu (relative)',
+ description: 'Basic menu (relative)',
+ showSource: true,
+ context: {
+ showSelectedItem: (msg, color) => {
+ const elm = document.getElementById('selectedItem');
+ elm.style.color = color;
+ elm.innerHTML = msg;
+ }
+ },
+ styles: [`
+ .message {
+ position: absolute;
+ top: 0; left: 0;
+ color: white;
+ }
+ .click-area {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ }
+ `],
+ template:
+ `
+ <div style="position: relative; width: 400px; height: 200px; background: blue;">
+ <span class="message">Click in the box...<br/>
+ (popup menu is {{menuStatus === undefined ? 'never opened' : (menuStatus ? 'open at '+menuPos.x+' , '+menuPos.y : 'closed')}})<br/>
+ selected: <span #selectedItem id="selectedItem"></span>
+ </span>
+ <div class="click-area"
+ (click)="menu.position = {x:$event.offsetX, y:$event.offsetY}; mopen=true;">
+ <popup-menu-list [(open)]="mopen" (openChange)="menuStatus=$event" (positionChange)="menuPos=$event" [relative]="true" #menu>
+ <popup-menu-item (action)="showSelectedItem('First', 'red')">First</popup-menu-item>
+ <popup-menu-item type="disabled">Disabled</popup-menu-item>
+ <popup-menu-item type="separator"></popup-menu-item>
+ <popup-menu-item (action)="showSelectedItem('Second', 'green')">Second</popup-menu-item>
+ <popup-menu-item>Third (none)</popup-menu-item>
+ </popup-menu-list>
+ </div>
+ </div>
+ `
+ }
+ ]);
diff --git a/stories/ng2-component-lab/radio.component.exp.ts b/stories/ng2-component-lab/radio.component.exp.ts
new file mode 100644
index 0000000..aa3959b
--- /dev/null
+++ b/stories/ng2-component-lab/radio.component.exp.ts
@@ -0,0 +1,179 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+export default experimentOn('Radios')
+ .group("Radios",[
+ {
+ id: 'radioButtonsGroupTwoWaysBinding',
+ showSource: true,
+ context: {
+ selectedValue: "val2"
+ },
+ title: 'Radio buttons group (two ways binding)',
+ description: 'Radio buttons group (two ways binding)',
+ template:
+ `
+ <sdc-radio-group
+ [legend]="'Radio Buttons Group legend'"
+ [(value)]="selectedValue"
+ [options] = "{
+ items: [
+ {
+ value: 'val1',
+ name: 'radio5',
+ label: 'Label of Radio 1'
+ },
+ {
+ value: 'val2',
+ name: 'radio5',
+ label: 'Label of Radio 2'
+ }
+ ]}"
+ ></sdc-radio-group>
+ <br><div>Selected Radio: {{selectedValue}}</div>
+ `
+ },
+ {
+ id: 'radioButtonsGroupDisabled',
+ title: 'Radio buttons group disabled',
+ description: 'Radio buttons group disabled',
+ showSource: true,
+ context: {
+ selectedValue: "val1"
+ },
+ template: `
+ <sdc-radio-group
+ [legend]="'Radio Buttons Group Disabled legend'"
+ [disabled]="true"
+ [value]="selectedValue"
+ [options] = "{
+ items: [{
+ value: 'val1',
+ name: 'radio6',
+ label: 'Label of Radio 1'
+ }, {
+ value: 'val2',
+ name: 'radio6',
+ label: 'Label of Radio 2'
+ }]
+ }"></sdc-radio-group>
+ <br><div>Selected Radio: {{selectedValue}}</div>
+ `
+ },
+ {
+ id: 'radioButtonsGroupPartiallyDisabled',
+ title: 'Radio buttons group partially disabled',
+ description: 'Radio buttons group partially disabled',
+ showSource: true,
+ context: {
+ selectedValue: "val2"
+ },
+ template: `
+ <sdc-radio-group
+ [legend]="'Radio Buttons Group partially disabled'"
+ [(value)]="selectedValue"
+ [options] = "{
+ items: [{
+ value: 'val1',
+ name: 'radio7',
+ label: 'Label of Radio 1'
+ }, {
+ value: 'val2',
+ disabled: 'true',
+ name: 'radio7',
+ label: 'Label of Radio 2'
+ }, {
+ value: 'val3',
+ name: 'radio7',
+ label: 'Label of Radio 3'
+ }]
+ }"></sdc-radio-group>
+ <br><div>Selected Radio: {{selectedValue}}</div>
+ `
+ },
+ {
+ id: 'radioButtonsGroupVertical',
+ title: 'Radio buttons group vertical',
+ description: 'Radio buttons group vertical',
+ showSource: true,
+ context: {
+ selectedValue: "val1"
+ },
+ template: `
+ <sdc-radio-group
+ [legend]="'Radio Buttons Group Vertical legend'"
+ [(value)]="selectedValue"
+ [direction]="'horizontal'"
+ [options]="{
+ items: [{
+ value:'val1',
+ name: 'radio8',
+ label: 'Label of Radio1'
+ }, {
+ value:'val2',
+ name: 'radio8',
+ label: 'Label of Radio2'
+ }]
+ }"></sdc-radio-group>
+ <br><div>Selected Radio: {{selectedValue}}</div>
+ `
+ },
+ {
+ id: 'radioButtonsGroupGetValue',
+ title: 'Radio buttons group get value',
+ description: 'Radio buttons group get value',
+ showSource: true,
+ context: {
+ selectedValue: "val1",
+ getSelectedValue: (val)=>{
+ alert(val);
+ }
+ },
+ template: `
+ <sdc-radio-group
+ #myRadioGroup
+ [legend]="'Radio Buttons Group Vertical legend'"
+ [(value)]="selectedValue"
+ [options]="{
+ items: [{
+ value:'val1',
+ name: 'radio8',
+ label: 'Label of Radio1'
+ }, {
+ value:'val2',
+ name: 'radio8',
+ label: 'Label of Radio2'
+ }]
+ }"></sdc-radio-group>
+ <br><div>Selected Radio: {{selectedValue}}</div>
+ <br><button (click)="getSelectedValue(myRadioGroup.value)">Get selected value</button>
+ `
+ },
+ {
+ id: 'radioButtonsGroupSelectValue',
+ title: 'Radio buttons group select value',
+ description: 'Radio buttons group select value',
+ showSource: true,
+ context: {
+ selectedValue: "val1"
+ },
+ template: `
+ <sdc-radio-group
+ #myRadioGroup
+ [legend]="'Radio Buttons Group Vertical legend'"
+ [(value)]="selectedValue"
+ [options]="{
+ items: [{
+ value:'val1',
+ name: 'radio8',
+ label: 'Label of Radio1'
+ }, {
+ value:'val2',
+ name: 'radio8',
+ label: 'Label of Radio2'
+ }]
+ }"></sdc-radio-group>
+ <br><div>Selected Radio: {{selectedValue}}</div>
+ <br><button (click)="myRadioGroup.value='val2'">Set value to val2</button>
+ `
+ }
+ ]);
diff --git a/stories/ng2-component-lab/search-bar.component.exp.ts b/stories/ng2-component-lab/search-bar.component.exp.ts
new file mode 100644
index 0000000..4a7e1fd
--- /dev/null
+++ b/stories/ng2-component-lab/search-bar.component.exp.ts
@@ -0,0 +1,19 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+export default experimentOn('Search Bar').group('SearchBar', [
+ {
+ id: 'search-bar',
+ title: 'Search Bar',
+ description: "The search text is updated on click on the magnify",
+ showSource: true,
+ template: `
+ The text to search: {{searchText}}
+ <sdc-search-bar placeholder="search text"
+ label="search example:"
+ [searchQuery]="searchText"
+ (searchQueryClick)="searchText = $event"
+ >
+ </sdc-search-bar>
+ `
+ }
+]);
diff --git a/stories/ng2-component-lab/svg-icon.component.exp.ts b/stories/ng2-component-lab/svg-icon.component.exp.ts
new file mode 100644
index 0000000..c87727d
--- /dev/null
+++ b/stories/ng2-component-lab/svg-icon.component.exp.ts
@@ -0,0 +1,14 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+import { Mode, Size } from "../../src/angular/common/enums";
+
+export default experimentOn('Icons')
+ .group('SvgIcons', [
+ {
+ id: 'SvgIcons',
+ showSource: false,
+ title: 'SVG Icons',
+ template: `
+ <svg-icons-table></svg-icons-table>
+ `
+ }
+ ]);
diff --git a/stories/ng2-component-lab/tabs.component.exp.ts b/stories/ng2-component-lab/tabs.component.exp.ts
new file mode 100644
index 0000000..ff4c0c5
--- /dev/null
+++ b/stories/ng2-component-lab/tabs.component.exp.ts
@@ -0,0 +1,28 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+export default experimentOn('Tabs').group('Tabs', [
+ {
+ id: 'simpleTabs',
+ title: 'Simple tabs with text title',
+ description: "Simple tabs with text title",
+ showSource: true,
+ template: `
+ <sdc-tabs>
+ <sdc-tab title="tab1">This is tab 1</sdc-tab>
+ <sdc-tab title="tab2">This is tab 2</sdc-tab>
+ </sdc-tabs>
+ `
+ },
+ {
+ id: 'simpleTabsWithIcons',
+ title: 'Simple tabs with icon title',
+ description: "Simple tabs with icon title",
+ showSource: true,
+ template: `
+ <sdc-tabs>
+ <sdc-tab titleIcon="inputs-o">This is tab 1</sdc-tab>
+ <sdc-tab titleIcon="edit-file-o">This is tab 2</sdc-tab>
+ </sdc-tabs>
+ `
+ }
+]);
diff --git a/stories/ng2-component-lab/tag-cloud.component.exp.ts b/stories/ng2-component-lab/tag-cloud.component.exp.ts
new file mode 100644
index 0000000..83ad03c
--- /dev/null
+++ b/stories/ng2-component-lab/tag-cloud.component.exp.ts
@@ -0,0 +1,61 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+export default experimentOn('Tag Cloud').group('Tag Cloud', [
+ {
+ id: 'list',
+ title: 'Simple tag-cloud',
+ description: 'Simple tag-cloud',
+ showSource: true,
+ template: `
+ <sdc-tag-cloud label="Please Enter value"
+ placeholder="Type a value and then click enter or '+'"
+ [list]="['aaa', 'bbb']">
+
+ </sdc-tag-cloud>
+ `
+ },
+ {
+ id: 'unique-tag-cloud',
+ title: 'List with unique validation',
+ description: 'List with unique validation',
+ showSource: true,
+ template: `
+ <sdc-tag-cloud label="Please Enter value"
+ placeholder="Type a value and then click enter or '+'"
+ [list]="['aaa', 'bbb']"
+ [isUniqueList]="true"
+ [uniqueErrorMessage]="'This value is already in the list'">
+
+ </sdc-tag-cloud>
+ `
+ },
+ {
+ id: 'disabled-tag-cloud',
+ title: 'Disabled tag-cloud',
+ description: 'When the parameter isViewOnly = true, the tag-cloud control is disabled',
+ showSource: true,
+ template: `
+ <sdc-tag-cloud label="Please Enter value"
+ placeholder="Type a value and then click enter or '+'"
+ [list]="['aaa', 'bbb']"
+ [isViewOnly]="true">
+
+ </sdc-tag-cloud>
+ `
+ },
+ {
+ id: 'tag-cloud-with-disabled-items',
+ title: 'List with some readonly items',
+ description: 'The parameter isViewOnly can get an array of indexes of tag-cloud items.',
+ showSource: true,
+ template: `
+ <sdc-tag-cloud label="Please Enter value"
+ placeholder="Type a value and then click enter or '+'"
+ [list]="['aaa', 'bbb', 'ccc', 'ddd']"
+ [isViewOnly]="[1,3]">
+
+ </sdc-tag-cloud>
+ `
+ }
+]);
+
diff --git a/stories/ng2-component-lab/tiles.component.exp.ts b/stories/ng2-component-lab/tiles.component.exp.ts
new file mode 100644
index 0000000..572b6ca
--- /dev/null
+++ b/stories/ng2-component-lab/tiles.component.exp.ts
@@ -0,0 +1,194 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+
+const alert1 = window.alert;
+const console1 = console.log;
+
+export default experimentOn('Tiles')
+ .group("Tiles",[
+ {
+ id: 'tileSampleBlue',
+ showSource: true,
+ context: {
+ alert: alert1,
+ console: console1
+ },
+ title: 'Tile sample blue',
+ description: 'Tile sample blue',
+ template: `
+ <sdc-tile>
+ <sdc-tile-header>
+ <div class="blue">P</div>
+ </sdc-tile-header>
+ <sdc-tile-content>
+ <div class="sdc-tile-content-icon blue">
+ <div class="svg-icon-wrapper" >
+ <svg class="svg-icon __vsp" viewBox="0 0 59.5 40" id="vsp_icon">
+ <title>
+ vsp_new_icon
+ </title>
+ <g id="Layer_2" data-name="Layer 2">
+ <g id="vlm_icon" data-name="vlm icon">
+ <path d="M58.28,30.74c-1.49-1.82-3-2.7-4.67-2.74a8.5,8.5,0,0,0-16.22-2.44,6.93,6.93,0,0,0-4.06.66A7.23,7.23,0,0,0,36.42,40H53.5a6,6,0,0,0,6-6A5.18,5.18,0,0,0,58.28,30.74ZM53.5,38H36.42a5.25,5.25,0,0,1-5.21-5.91,5.32,5.32,0,0,1,3-4.06,5,5,0,0,1,2.21-.53,5.25,5.25,0,0,1,1.35.18l.92.24L39,27A6.5,6.5,0,0,1,51.67,29v1.3l1.17-.2c1-.17,2.17-.17,3.91,2a3.18,3.18,0,0,1,.76,2A4,4,0,0,1,53.5,38Z">
+ </path>
+ <path d="M49,0,4,.17A3.79,3.79,0,0,0,0,3.69V7.94H0v2H0V36.31C0,38.35,2,40,4.25,40l20.84-.08a1,1,0,0,0,0-1.92L4,38.08a1.89,1.89,0,0,1-2-1.76V10H51v7a1,1,0,0,0,2,0V3.53A3.79,3.79,0,0,0,49,0ZM2,8V3.76A1.89,1.89,0,0,1,4,2l45-.16a1.89,1.89,0,0,1,2,1.76V8Z">
+ </path>
+ </g>
+ </g>
+ </svg>
+ </div>
+ </div>
+ <div class="sdc-tile-content-info">
+ <div class="sdc-tile-info-line title">Router</div>
+ <div class="sdc-tile-info-line subtitle">test</div>
+ </div>
+ </sdc-tile-content>
+ <sdc-tile-footer>
+ <span class="sdc-tile-footer-cell">Footer</span>
+ </sdc-tile-footer>
+ </sdc-tile>
+ `
+ },
+ {
+ id: 'tileSamplePurple',
+ title: 'Tile sample purple',
+ description: 'Tile sample purple',
+ showSource: true,
+ template: `
+ <sdc-tile>
+ <sdc-tile-header>
+ <div class="purple">P</div>
+ </sdc-tile-header>
+ <sdc-tile-content>
+ <div class="sdc-tile-content-icon purple">
+ <div class="svg-icon-wrapper" >
+ <svg class="svg-icon __vsp" viewBox="0 0 59.5 40" id="vsp_icon">
+ <title>
+ vsp_new_icon
+ </title>
+ <g id="Layer_2" data-name="Layer 2">
+ <g id="vlm_icon" data-name="vlm icon">
+ <path d="M58.28,30.74c-1.49-1.82-3-2.7-4.67-2.74a8.5,8.5,0,0,0-16.22-2.44,6.93,6.93,0,0,0-4.06.66A7.23,7.23,0,0,0,36.42,40H53.5a6,6,0,0,0,6-6A5.18,5.18,0,0,0,58.28,30.74ZM53.5,38H36.42a5.25,5.25,0,0,1-5.21-5.91,5.32,5.32,0,0,1,3-4.06,5,5,0,0,1,2.21-.53,5.25,5.25,0,0,1,1.35.18l.92.24L39,27A6.5,6.5,0,0,1,51.67,29v1.3l1.17-.2c1-.17,2.17-.17,3.91,2a3.18,3.18,0,0,1,.76,2A4,4,0,0,1,53.5,38Z">
+ </path>
+ <path d="M49,0,4,.17A3.79,3.79,0,0,0,0,3.69V7.94H0v2H0V36.31C0,38.35,2,40,4.25,40l20.84-.08a1,1,0,0,0,0-1.92L4,38.08a1.89,1.89,0,0,1-2-1.76V10H51v7a1,1,0,0,0,2,0V3.53A3.79,3.79,0,0,0,49,0ZM2,8V3.76A1.89,1.89,0,0,1,4,2l45-.16a1.89,1.89,0,0,1,2,1.76V8Z">
+ </path>
+ </g>
+ </g>
+ </svg>
+ </div>
+ </div>
+ <div class="sdc-tile-content-info">
+ <span class="sdc-tile-info-line title">Router</span>
+ <div class="sdc-tile-info-line subtitle">test</div>
+ </div>
+ </sdc-tile-content>
+ <sdc-tile-footer>
+ <span class="sdc-tile-footer-cell"> Footer </span>
+ </sdc-tile-footer>
+ </sdc-tile>
+ `
+ },
+ {
+ id: 'tileSampleWithoutFooter',
+ title: 'Tile sample without footer',
+ description: 'Tile sample without footer',
+ showSource: true,
+ template: `
+ <sdc-tile>
+ <sdc-tile-header>
+ <div class="purple">P</div>
+ </sdc-tile-header>
+ <sdc-tile-content>
+ <div class="sdc-tile-content-icon purple">
+ <div class="svg-icon-wrapper" >
+ <svg class="svg-icon __vsp" viewBox="0 0 59.5 40" id="vsp_icon">
+ <title>
+ vsp_new_icon
+ </title>
+ <g id="Layer_2" data-name="Layer 2">
+ <g id="vlm_icon" data-name="vlm icon">
+ <path d="M58.28,30.74c-1.49-1.82-3-2.7-4.67-2.74a8.5,8.5,0,0,0-16.22-2.44,6.93,6.93,0,0,0-4.06.66A7.23,7.23,0,0,0,36.42,40H53.5a6,6,0,0,0,6-6A5.18,5.18,0,0,0,58.28,30.74ZM53.5,38H36.42a5.25,5.25,0,0,1-5.21-5.91,5.32,5.32,0,0,1,3-4.06,5,5,0,0,1,2.21-.53,5.25,5.25,0,0,1,1.35.18l.92.24L39,27A6.5,6.5,0,0,1,51.67,29v1.3l1.17-.2c1-.17,2.17-.17,3.91,2a3.18,3.18,0,0,1,.76,2A4,4,0,0,1,53.5,38Z">
+ </path>
+ <path d="M49,0,4,.17A3.79,3.79,0,0,0,0,3.69V7.94H0v2H0V36.31C0,38.35,2,40,4.25,40l20.84-.08a1,1,0,0,0,0-1.92L4,38.08a1.89,1.89,0,0,1-2-1.76V10H51v7a1,1,0,0,0,2,0V3.53A3.79,3.79,0,0,0,49,0ZM2,8V3.76A1.89,1.89,0,0,1,4,2l45-.16a1.89,1.89,0,0,1,2,1.76V8Z">
+ </path>
+ </g>
+ </g>
+ </svg>
+ </div>
+ </div>
+ <div class="sdc-tile-content-info">
+ <span class="sdc-tile-info-line title">Router</span>
+ <div class="sdc-tile-info-line subtitle">test</div>
+ </div>
+ </sdc-tile-content>
+ </sdc-tile>
+ `
+ },
+ {
+ id: 'tileSampleWithoutHeader',
+ title: 'Tile sample without header',
+ description: 'Tile sample without header',
+ showSource: true,
+ template: `
+ <sdc-tile>
+ <sdc-tile-content>
+ <div class="sdc-tile-content-icon purple">
+ <div class="svg-icon-wrapper" >
+ <svg class="svg-icon __vsp" viewBox="0 0 59.5 40" id="vsp_icon">
+ <title>
+ vsp_new_icon
+ </title>
+ <g id="Layer_2" data-name="Layer 2">
+ <g id="vlm_icon" data-name="vlm icon">
+ <path d="M58.28,30.74c-1.49-1.82-3-2.7-4.67-2.74a8.5,8.5,0,0,0-16.22-2.44,6.93,6.93,0,0,0-4.06.66A7.23,7.23,0,0,0,36.42,40H53.5a6,6,0,0,0,6-6A5.18,5.18,0,0,0,58.28,30.74ZM53.5,38H36.42a5.25,5.25,0,0,1-5.21-5.91,5.32,5.32,0,0,1,3-4.06,5,5,0,0,1,2.21-.53,5.25,5.25,0,0,1,1.35.18l.92.24L39,27A6.5,6.5,0,0,1,51.67,29v1.3l1.17-.2c1-.17,2.17-.17,3.91,2a3.18,3.18,0,0,1,.76,2A4,4,0,0,1,53.5,38Z">
+ </path>
+ <path d="M49,0,4,.17A3.79,3.79,0,0,0,0,3.69V7.94H0v2H0V36.31C0,38.35,2,40,4.25,40l20.84-.08a1,1,0,0,0,0-1.92L4,38.08a1.89,1.89,0,0,1-2-1.76V10H51v7a1,1,0,0,0,2,0V3.53A3.79,3.79,0,0,0,49,0ZM2,8V3.76A1.89,1.89,0,0,1,4,2l45-.16a1.89,1.89,0,0,1,2,1.76V8Z">
+ </path>
+ </g>
+ </g>
+ </svg>
+ </div>
+ </div>
+ <div class="sdc-tile-content-info">
+ <span class="sdc-tile-info-line title">Router</span>
+ <div class="sdc-tile-info-line subtitle">test</div>
+ </div>
+ </sdc-tile-content>
+ <sdc-tile-footer>
+ <span class="sdc-tile-footer-cell"> Footer </span>
+ </sdc-tile-footer>
+ </sdc-tile>
+ `
+ },
+ {
+ id: 'tileJustWithInfo',
+ title: 'Tile just with info',
+ description: 'Tile just with info',
+ showSource: true,
+ template: `
+ <sdc-tile>
+ <sdc-tile-content>
+ <div class="sdc-tile-content-icon purple">
+ <div class="svg-icon-wrapper" >
+ <svg class="svg-icon __vsp" viewBox="0 0 59.5 40" id="vsp_icon">
+ <title>
+ vsp_new_icon
+ </title>
+ <g id="Layer_2" data-name="Layer 2">
+ <g id="vlm_icon" data-name="vlm icon">
+ <path d="M58.28,30.74c-1.49-1.82-3-2.7-4.67-2.74a8.5,8.5,0,0,0-16.22-2.44,6.93,6.93,0,0,0-4.06.66A7.23,7.23,0,0,0,36.42,40H53.5a6,6,0,0,0,6-6A5.18,5.18,0,0,0,58.28,30.74ZM53.5,38H36.42a5.25,5.25,0,0,1-5.21-5.91,5.32,5.32,0,0,1,3-4.06,5,5,0,0,1,2.21-.53,5.25,5.25,0,0,1,1.35.18l.92.24L39,27A6.5,6.5,0,0,1,51.67,29v1.3l1.17-.2c1-.17,2.17-.17,3.91,2a3.18,3.18,0,0,1,.76,2A4,4,0,0,1,53.5,38Z">
+ </path>
+ <path d="M49,0,4,.17A3.79,3.79,0,0,0,0,3.69V7.94H0v2H0V36.31C0,38.35,2,40,4.25,40l20.84-.08a1,1,0,0,0,0-1.92L4,38.08a1.89,1.89,0,0,1-2-1.76V10H51v7a1,1,0,0,0,2,0V3.53A3.79,3.79,0,0,0,49,0ZM2,8V3.76A1.89,1.89,0,0,1,4,2l45-.16a1.89,1.89,0,0,1,2,1.76V8Z">
+ </path>
+ </g>
+ </g>
+ </svg>
+ </div>
+ </div>
+ <div class="sdc-tile-content-info">
+ <span class="sdc-tile-info-line title">Router</span>
+ <div class="sdc-tile-info-line subtitle">test</div>
+ </div>
+ </sdc-tile-content>
+ </sdc-tile>`
+ }
+ ]);
diff --git a/stories/ng2-component-lab/tooltip.directive.exp.ts b/stories/ng2-component-lab/tooltip.directive.exp.ts
new file mode 100644
index 0000000..9e1dd0b
--- /dev/null
+++ b/stories/ng2-component-lab/tooltip.directive.exp.ts
@@ -0,0 +1,231 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+import { ArrowPlacement, TooltipPlacement } from '../../src/angular/tooltip/tooltip.directive';
+
+const customTemplate = `
+ .sdc-custom-tooltip-template-title {
+ font-size: 20px;
+ font-weight: bold;
+ background-color: $black;
+ color: $white;
+ text-align: center;
+ }
+
+ .sdc-custom-tooltip-template-content {
+ background-color: $black;
+ color: $white;
+ display: inline-block;
+ text-align: center;
+ }
+
+ .sdc-custom-tooltip-template-image {
+ width: 100%;
+ height:100%;
+ display: inline-block;
+ text-align: center;
+ background-color: #ffffff;
+ }
+`;
+
+export default experimentOn('Tooltip')
+ .group("Tooltip",[
+ {
+ id: 'leftAlignmentTextTooltip',
+ showSource: true,
+ title: 'Tooltip with short text (left placement)',
+ description: 'left placement',
+ context: {
+ placement: TooltipPlacement.Left,
+ arrowPlacement: ArrowPlacement.LeftTop
+ },
+ template: `
+ <div style="padding-bottom: 20px; width: 350px;">Lorem ipsum dolor sit amet,
+ <span style="color: #009fdb"
+ sdc-tooltip
+ tooltip-text = 'A short text name, short text'
+ [tooltip-placement]= 'placement'
+ [tooltip-arrow-placement] = 'arrowPlacement'>show tooltip
+ </span>
+ ,consectetur adipiscing elit. Sed risus nisl, egestas vitae erat non, pulvinar lacinia libero.
+ Integer pulvinar pellentesque accumsan.
+ <span style="color: #009fdb"
+ sdc-tooltip
+ tooltip-text = 'A short text name, short text'
+ [tooltip-placement]= 'placement'
+ [tooltip-arrow-placement] = 'arrowPlacement'>show tooltip
+ </span>
+ Sed hendrerit lacus eu tempus pharetra
+ </div>
+ `
+ },
+ {
+ id: 'leftAlignmentMultiLineTextTooltip',
+ showSource: true,
+ title: 'Tooltip with multi line text (left placement)',
+ description: 'left placement',
+ context: {
+ placement: TooltipPlacement.Left,
+ arrowPlacement: ArrowPlacement.LeftTop
+ },
+ template: `
+ <div style="padding-bottom: 20px;">
+ The is text example,
+ <span style="color: #009fdb"
+ sdc-tooltip
+ tooltip-text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed risus nisl, egestas vitae erat non, pulvinar lacinia libero. Integer pulvinar pellentesque accumsan. Sed hendrerit lacus eu tempus pharetra'
+ [tooltip-placement]= 'placement'
+ [tooltip-arrow-placement] = 'arrowPlacement'>show tooltip
+ </span>
+ , more text
+ </div>
+ `
+ },
+ {
+ id: 'customStyleTooltip',
+ showSource: true,
+ title: 'Tooltip with custom style',
+ description: 'Tooltip with custom style, define your class and style it via css.',
+ context: {
+ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed risus nisl, egestas vitae erat non, pulvinar lacinia libero. Integer pulvinar pellentesque accumsan. Sed hendrerit lacus eu tempus pharetra'
+ },
+ template: `
+ <![CDATA[
+ .sdc-custom-tooltip {
+ background-color: $dark-blue;
+ border-color: $dark-blue;
+ border-radius: 10px;
+ }
+ ]]>
+ <div style="padding-bottom: 20px;">
+ Some text example,
+ <span style="color: #009fdb" sdc-tooltip [tooltip-text]=text tooltip-css-class='sdc-custom-tooltip'>show tooltip</span>, more text
+ </div>
+ `
+ },
+ {
+ id: 'rightAlignmentHtmlTooltip',
+ showSource: true,
+ title: 'Tooltip with HTML template (right placement)',
+ description: 'right placement',
+ context: {
+ placement: TooltipPlacement.Right,
+ arrowPlacement: ArrowPlacement.LeftTop
+ },
+ styles: [customTemplate],
+ template: `
+ Template Input:
+ <pre><![CDATA[
+ <img src="../../../assets/images/logo_onap.png" class="sdc-custom-tooltip-template-image" />
+ <p class="sdc-tooltip-template-content">A long text name, very long, long text ...</p>
+ ]]></pre>
+
+ <div style="padding-bottom: 20px;">
+ The is text example,
+ <span style="color: #009fdb"
+ sdc-tooltip
+ tooltip-text = 'This is the tooltip test'
+ [tooltip-placement]= 'placement'
+ [tooltip-arrow-placement] = 'arrowPlacement'
+ [tooltip-template]='template'>show tooltip
+ </span>
+ , more text
+ </div>
+
+ <template #template>
+ <img src="../../../assets/images/logo_onap.png" class="sdc-custom-tooltip-template-image" />
+ <p class="sdc-tooltip-template-content">A long text name, very long, long text ...</p>
+ </template>
+ `
+ },
+ {
+ id: 'rightAlignmentHtmlCustomStyleTooltip',
+ showSource: true,
+ title: 'Tooltip with HTML template and custom style (right placement)',
+ description: 'right placement',
+ context: {
+ placement: TooltipPlacement.Right,
+ arrowPlacement: ArrowPlacement.LeftTop
+ },
+ styles: [customTemplate],
+ template: `
+ Template Input:
+ <pre><![CDATA[
+ <p class="sdc-custom-tooltip-template-title sdc-tooltip-template-big-title">Title... Title... Title... Title... Title...</p>
+ <img src="../../../assets/images/logo_onap.png" class="sdc-custom-tooltip-template-image" />
+ <p class="sdc-custom-tooltip-template-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed risus nisl, egestas vitae erat non, pulvinar lacinia libero. Integer pulvinar pellentesque accumsan. Sed hendrerit lacus eu tempus pharetra</p>
+ ]]></pre>
+
+ <div style="padding-bottom: 20px;">
+ The is text example,
+ <span style="color: #009fdb"
+ sdc-tooltip
+ tooltip-text = 'This is the tooltip test'
+ [tooltip-placement]= 'placement'
+ tooltip-css-class = 'sdc-custom-tooltip'
+ [tooltip-arrow-placement] = 'arrowPlacement'
+ [tooltip-template]='template'>show tooltip
+ </span>
+ , more text
+ </div>
+
+ <template #template>
+ <p class="sdc-custom-tooltip-template-title sdc-tooltip-template-big-title">Title... Title... Title... Title... Title...</p>
+ <img src="../../../assets/images/logo_onap.png" class="sdc-custom-tooltip-template-image" />
+ <p class="sdc-custom-tooltip-template-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed risus nisl, egestas vitae erat non, pulvinar lacinia libero. Integer pulvinar pellentesque accumsan. Sed hendrerit lacus eu tempus pharetra</p>
+ </template>
+ `
+ },
+ {
+ id: 'topAlignmentTextTooltip',
+ showSource: true,
+ title: 'Tooltip with text (top placement)',
+ description: 'top placement',
+ context: {
+ placement: TooltipPlacement.Top,
+ arrowPlacement: ArrowPlacement.LeftTop
+ },
+ template: `
+ <div style="padding-bottom: 20px;">
+ The is text example,
+ <span style="color: #009fdb"
+ sdc-tooltip
+ tooltip-text = 'A long text name, very long, long text'
+ [tooltip-placement]= 'placement'
+ [tooltip-arrow-placement] = 'arrowPlacement'>show tooltip
+ </span>
+ , more text
+ </div>
+ `
+ },
+ {
+ id: 'bottomAlignmentHtmlTooltip',
+ showSource: true,
+ title: 'Tooltip with HTML template (bottom placement)',
+ description: 'bottom placement',
+ context: {
+ placement: TooltipPlacement.Bottom,
+ arrowPlacement: ArrowPlacement.LeftTop
+ },
+ template: `
+ Template Input:
+ <pre><![CDATA[
+ <div class="sdc-tooltip-template-content">A long text name,</div>
+ <div class="sdc-tooltip-template-content">very long, long text</div>
+ ]]></pre>
+
+ <div style="width:30%; height: 30px; text-align: center;">
+ The is text example,
+ <a style="color: #009fdb; font-size: small; cursor: pointer;"
+ sdc-tooltip
+ tooltip-text = 'This is the tooltip test'
+ [tooltip-placement]= 'placement'
+ [tooltip-arrow-placement] = 'arrowPlacement'
+ [tooltip-template]='template' >link example</a>
+ , more text
+ </div>
+ <template #template>
+ <div class="sdc-tooltip-template-content">A long text name,</div>
+ <div class="sdc-tooltip-template-content">very long, long text</div>
+ </template>
+ `
+ },
+ ]);
diff --git a/stories/ng2-component-lab/utils/mock.json b/stories/ng2-component-lab/utils/mock.json
new file mode 100644
index 0000000..6cdaf3b
--- /dev/null
+++ b/stories/ng2-component-lab/utils/mock.json
@@ -0,0 +1,6 @@
+[{"id": "redId", "color": "red"},
+{"id": "yellowId", "color": "yellow"},
+{"id": "orangeId", "color": "orange"},
+{"id": "greenId", "color": "green"},
+{"id": "whiteId", "color": "white"},
+{"id": "blackId", "color": "black"}]
diff --git a/stories/ng2-component-lab/utils/pipes/keys.pipe.ts b/stories/ng2-component-lab/utils/pipes/keys.pipe.ts
new file mode 100644
index 0000000..2a58cd8
--- /dev/null
+++ b/stories/ng2-component-lab/utils/pipes/keys.pipe.ts
@@ -0,0 +1,13 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({name: 'keys'})
+export class KeysPipe implements PipeTransform {
+ transform(value, args:string[]) : any {
+ let keys = [];
+ for (let key in value) {
+ keys.push(key);
+ }
+ return keys;
+ }
+}
+
diff --git a/stories/ng2-component-lab/validation.component.exp.ts b/stories/ng2-component-lab/validation.component.exp.ts
new file mode 100644
index 0000000..7f18c93
--- /dev/null
+++ b/stories/ng2-component-lab/validation.component.exp.ts
@@ -0,0 +1,162 @@
+import { experimentOn } from '@islavi/ng2-component-lab';
+import { RegexPatterns } from '../../src/angular/common/enums';
+import { DropDownOptionType, IDropDownOption } from './../../src/angular/form-elements/dropdown/dropdown-models';
+
+const options1: IDropDownOption[] = [
+ {
+ label: 'First Option',
+ value: 'First Option',
+ },
+ {
+ label: 'Second Option',
+ value: 'Second Option',
+ },
+ {
+ label: 'Third Option',
+ value: 'Third Option',
+ type: DropDownOptionType.Simple
+ }
+];
+
+export default experimentOn('Validation')
+ .group("Validation", [
+ {
+ id: 'validation1',
+ showSource: true,
+ title: 'Simple validation',
+ description: 'Simple validation (validating that email is valid and that user inserted something in the field). \
+ By default the validation starts after first key press',
+ context: {
+ emailPattern: RegexPatterns.email
+ },
+ template: `
+ <sdc-input #email label="Please enter valid email address" [maxLength]="50" required="true"></sdc-input>
+ <sdc-validation [validateElement]="email">
+ <sdc-required-validator message="Field is required!"></sdc-required-validator>
+ <sdc-regex-validator message="This is not a valid email!" [pattern]="emailPattern"></sdc-regex-validator>
+ </sdc-validation>
+ `
+ },
+ {
+ id: 'validation2',
+ showSource: true,
+ title: 'Simple validation',
+ description: 'Simple validation',
+ context: {
+ numbersPattern: RegexPatterns.numbers,
+ isValueHundred: (value: any) => {
+ return (Number(value) === 100) ? true : false;
+ }
+ },
+ template: `
+ <sdc-input #numberValidator label="Please enter some number" [maxLength]="10" required="true"></sdc-input>
+ <sdc-validation [validateElement]="numberValidator">
+ <sdc-regex-validator message="This is not a number!" [pattern]="numbersPattern"></sdc-regex-validator>
+ <sdc-custom-validator message="The number should be 100" [callback]="isValueHundred"></sdc-custom-validator>
+ </sdc-validation>
+ `
+ },
+ {
+ id: 'validation3',
+ showSource: true,
+ title: 'Disabled validation',
+ description: 'Disabled validation',
+ context: {
+ emailPattern: RegexPatterns.email
+ },
+ template: `
+ <sdc-input #email label="Please enter valid email address" [maxLength]="50" required="true"></sdc-input>
+ <sdc-validation [validateElement]="email" disabled='true'>
+ <sdc-required-validator message="Field is required!"></sdc-required-validator>
+ <sdc-regex-validator message="This is not a valid email!" [pattern]="emailPattern"></sdc-regex-validator>
+ </sdc-validation>
+ `
+ },
+ {
+ id: 'validation4',
+ showSource: true,
+ title: 'Validation with value already entered',
+ description: 'Validation with value already entered',
+ context: {
+ emailPattern: RegexPatterns.email
+ },
+ template: `
+ <sdc-input #email label="Please enter valid email address" [maxLength]="50" required="true" value="notvalidemail@"></sdc-input>
+ <sdc-validation [validateElement]="email">
+ <sdc-required-validator message="Field is required!"></sdc-required-validator>
+ <sdc-regex-validator message="This is not a valid email!" [pattern]="emailPattern"></sdc-regex-validator>
+ </sdc-validation>
+ `
+ },
+ {
+ id: 'validation5',
+ showSource: true,
+ title: 'Validation with validity changed callback',
+ description: 'Simple validation with alert when validity changes',
+ context: {
+ numbersPattern: RegexPatterns.numbers,
+ validityChanged: (newState: boolean) => {
+ alert("Validity has changed to " + newState);
+ }
+ },
+ template: `
+ <sdc-input #validatorWithCallback label="Please enter a number" [maxLength]="10" required="true"></sdc-input>
+ <sdc-validation [validateElement]="validatorWithCallback" (validityChanged)="validityChanged($event)">
+ <sdc-regex-validator message="This is not a number!" [pattern]="numbersPattern"></sdc-regex-validator>
+ </sdc-validation>
+ `
+ },
+ {
+ id: 'dropdownWithValidation',
+ showSource: true,
+ context: {
+ options: options1,
+ isThirdOption: (value: any) => {
+ return value === 'Third Option';
+ }
+ },
+ title: 'DropDown with validation',
+ description: 'DropDown with validation',
+ template: `
+ <sdc-dropdown #mydropdown label="Hi I am a label" placeHolder="Please choose option" [options]="options"></sdc-dropdown>
+ <sdc-validation [validateElement]="mydropdown">
+ <sdc-required-validator message="Field is required!"></sdc-required-validator>
+ <sdc-custom-validator message="Please select the third option" [callback]="isThirdOption"></sdc-custom-validator>
+ </sdc-validation>
+ `
+ },
+ {
+ id: 'validationGroup',
+ showSource: true,
+ context: {
+ options: options1,
+ emailPattern: RegexPatterns.email,
+ isThirdOption: (value: any) => {
+ return value === 'Third Option';
+ },
+ validateGroup: (validationGroup) => {
+ validationGroup.validate();
+ }
+ },
+ title: 'Validation group',
+ description: 'Validation group (activating validation from code)',
+ template: `
+ <sdc-validation-group #validationGroup>
+
+ <sdc-input #email label="Please enter valid email address" [maxLength]="50" required="true"></sdc-input>
+ <sdc-validation [validateElement]="email">
+ <sdc-required-validator message="Field is required!"></sdc-required-validator>
+ <sdc-regex-validator message="This is not a valid email!" [pattern]="emailPattern"></sdc-regex-validator>
+ </sdc-validation>
+
+ <sdc-dropdown #mydropdown label="Hi I am a label" placeHolder="Please choose option" [options]="options"></sdc-dropdown>
+ <sdc-validation [validateElement]="mydropdown">
+ <sdc-required-validator message="Field is required!"></sdc-required-validator>
+ <sdc-custom-validator message="Please select the third option" [callback]="isThirdOption"></sdc-custom-validator>
+ </sdc-validation>
+
+ </sdc-validation-group>
+ <sdc-button text="validate group" (click)="validateGroup(validationGroup)"></sdc-button>
+ `
+ }
+ ]);
diff --git a/stories/react/Accordion.stories.js b/stories/react/Accordion.stories.js
new file mode 100644
index 0000000..85fdae3
--- /dev/null
+++ b/stories/react/Accordion.stories.js
@@ -0,0 +1,16 @@
+import React from 'react';
+import Examples from './utils/Examples.js';
+import Accordion from '../../src/react/Accordion.js';
+import HTMLBasic from '../../components/accordion/accordion-basic.html';
+let examples = {
+ Basic: {
+ jsx: <Accordion title='Accordion Title'><div>Accordion body</div></Accordion>,
+ html: HTMLBasic
+ }
+};
+
+const Checkboxes = () => (
+ <Examples examples={examples} />
+);
+
+export default Checkboxes;
diff --git a/stories/react/Checkbox.stories.js b/stories/react/Checkbox.stories.js
new file mode 100644
index 0000000..3fb3ad1
--- /dev/null
+++ b/stories/react/Checkbox.stories.js
@@ -0,0 +1,33 @@
+import React from 'react';
+import Examples from './utils/Examples.js';
+
+import Checkbox from '../../src/react/Checkbox';
+import HTMLCheckboxChecked from '../../components/checkbox/checkbox-checked.html';
+import HTMLCheckboxUnchecked from '../../components/checkbox/checkbox-unchecked.html';
+import HTMLCheckboxDisabled from '../../components/checkbox/checkbox-disabled.html';
+import HTMLCheckboxDisabledChecked from '../../components/checkbox/checkbox-disabled-checked.html';
+
+let examples = {
+ Checked: {
+ jsx: <Checkbox checked={true} label='This is the checkbox label' value='myVal' onChange={()=>{}} data-test-id='mycheckbox-1' inputRef={() => {} } />,
+ html: HTMLCheckboxChecked
+ },
+ Unchecked: {
+ jsx: <Checkbox label='This is the checkbox label' value='myVal' onChange={()=>{}} data-test-id='mycheckbox-2' inputRef={() => {} } />,
+ html: HTMLCheckboxUnchecked
+ },
+ Disabled: {
+ jsx: <Checkbox label='This is the checkbox label' disabled={true} value='myVal' onChange={()=>{}} data-test-id='mycheckbox-4' inputRef={() => {} } />,
+ html: HTMLCheckboxDisabled
+ },
+ 'Disabled and Checked': {
+ jsx: <Checkbox label='This is the checkbox label' disabled={true} checked={true} value='myVal' onChange={()=>{}} data-test-id='mycheckbox-4' inputRef={() => {} } />,
+ html: HTMLCheckboxDisabledChecked
+ }
+};
+
+const Checkboxes = () => (
+ <Examples examples={examples} />
+);
+
+export default Checkboxes;
diff --git a/stories/react/Checklist.stories.js b/stories/react/Checklist.stories.js
new file mode 100644
index 0000000..0fd089b
--- /dev/null
+++ b/stories/react/Checklist.stories.js
@@ -0,0 +1,65 @@
+import React from 'react';
+import Examples from './utils/Examples.js';
+import Checklist from '../../src/react/Checklist.js';
+import HTMLListChecked from '../../components/checklist/checklist-with-checked-items.html';
+import HTMLListDisabled from '../../components/checklist/checklist-with-disabled-items.html';
+const items = [
+ {
+ label: 'apple',
+ value: 'apple',
+ dataTestId: 'apple',
+ checked: true
+ },
+ {
+ label: 'banana',
+ value: 'banana',
+ dataTestId: 'banana',
+ checked: false
+ },
+ {
+ label: 'orange',
+ value: 'orange',
+ dataTestId: 'orange',
+ checked: true
+ }
+];
+
+const itemsDisabled = [
+ {
+ label: 'apple',
+ value: 'apple',
+ dataTestId: 'apple',
+ checked: true,
+ disabled: true
+ },
+ {
+ label: 'banana',
+ value: 'banana',
+ dataTestId: 'banana',
+ checked: false,
+ disabled: true
+ },
+ {
+ label: 'orange',
+ value: 'orange',
+ dataTestId: 'orange',
+ checked: false
+ }
+];
+
+let examples = {
+ Basic: {
+ jsx: <Checklist items={items} onChange={() => { }} />,
+ html: HTMLListChecked
+ },
+ Disabled: {
+ jsx: <Checklist items={itemsDisabled} onChange={() => { }} />,
+ html: HTMLListDisabled
+ }
+};
+
+const ChecklistStory = () => (
+ <Examples examples={examples} />
+);
+
+export default ChecklistStory; \ No newline at end of file
diff --git a/stories/react/Colors.stories.js b/stories/react/Colors.stories.js
new file mode 100644
index 0000000..d6758ce
--- /dev/null
+++ b/stories/react/Colors.stories.js
@@ -0,0 +1,53 @@
+import React, {Component} from 'react';
+
+const colorMap = {
+ '$white': '#ffffff',
+ '$blue': '#009fdb',
+ '$light-blue': '#1eb9f3',
+ '$lighter-blue': '#e6f6fb',
+ '$blue-disabled': '#9dd9ef',
+ '$dark-blue': '#0568ae',
+ '$black': '#000000',
+ '$rich-black': '#323943',
+ '$text-black': '#191919',
+ '$dark-gray': '#5a5a5a',
+ '$gray': '#959595',
+ '$light-gray': '#d2d2d2',
+ '$silver': '#eaeaea',
+ '$light-silver': '#f2f2f2',
+ '$green': '#4ca90c',
+ '$functional-red': '#cf2a2a',
+ '$yellow': '#ffb81c',
+ '$dark-purple': '#702f8a',
+ '$purple': '#9063cd',
+ '$light-purple': '#caa2dd'
+};
+
+function Color({colorName, colorValue}) {
+ return (
+ <div key={colorName} className='color-section'>
+ <div className='color-circle' style={{backgroundColor: colorValue}} />
+ <div>{colorName.replace('$', '')}</div>
+ <div>{colorValue}</div>
+ </div>
+ );
+}
+
+class Colors extends Component {
+
+ render() {
+ return (
+ <div>
+ <h1>Colors Palette</h1>
+ <div className='colors-table'>
+ {
+ Object.keys(colorMap).map(colorName => <Color key={colorName} colorValue={colorMap[colorName]} colorName={colorName}/>)
+ }
+ </div>
+ </div>
+ );
+ }
+
+}
+
+export default Colors;
diff --git a/stories/react/Input.stories.js b/stories/react/Input.stories.js
new file mode 100644
index 0000000..869bafa
--- /dev/null
+++ b/stories/react/Input.stories.js
@@ -0,0 +1,51 @@
+import React from 'react';
+import { action } from '@storybook/addon-actions';
+import Examples from './utils/Examples.js';
+
+import ReactInput from '../../src/react/Input.js';
+
+import InputDefaultHtml from '../../components/input/input.html';
+import InputRequiredHtml from '../../components/input/input-required.html';
+import InputNumberHtml from '../../components/input/input-number.html';
+import InputViewOnlyHtml from '../../components/input/input-view-only.html';
+import InputDisabledHtml from '../../components/input/input-disabled.html';
+import InputPlaceholderHtml from '../../components/input/input-placeholder.html';
+import InputErrorHtml from '../../components/input/input-error.html';
+
+let examples = {
+ 'Input Default': {
+ jsx: <ReactInput name='input1' value='Default' label='I am a label' onChange={ action('input-change')}/>,
+ html: InputDefaultHtml
+ },
+ 'Input Required': {
+ jsx: <ReactInput name='input2' value='Default' label='I am a label' onChange={ action('input-change')} isRequired/>,
+ html: InputRequiredHtml
+ },
+ 'Input Number': {
+ jsx: <ReactInput name='input3' value='3' label='I am a label' type="number" onChange={ action('input-change')}/>,
+ html: InputNumberHtml
+ },
+ 'Input View Only': {
+ jsx: <ReactInput value='Read Only Text' label='I am a label' onChange={ action('input-change')} readOnly/>,
+ html: InputViewOnlyHtml
+ },
+ 'Input Disabled': {
+ jsx: <ReactInput value='Default' label='I am a label' onChange={ action('input-change')} disabled/>,
+ html: InputDisabledHtml
+ },
+ 'Input Placeholder': {
+ jsx: <ReactInput name='input5' placeholder='Write Here...' label='I am a label' onChange={ action('input-change')}/>,
+ html: InputPlaceholderHtml
+ },
+ 'Input Error': {
+ jsx: <ReactInput value='Default' name='input6' label='I am a label' errorMessage='This is the error message' onChange={ action('input-change')}/>,
+ html: InputErrorHtml
+ }
+
+}
+
+const Inputs = () => (
+ <Examples examples={examples} />
+);
+
+export default Inputs;
diff --git a/stories/react/Modal.stories.js b/stories/react/Modal.stories.js
new file mode 100644
index 0000000..29ff7a5
--- /dev/null
+++ b/stories/react/Modal.stories.js
@@ -0,0 +1,133 @@
+import React from 'react';
+import Examples from './utils/Examples.js';
+import Button from '../../src/react/Button.js';
+import Modal from '../../src/react/Modal.js';
+import Input from '../../src/react/Input.js';
+import HTMLStandardModal from '../../components/modal/standard-modal.html';
+import HTMLAlertModal from '../../components/modal/alert-modal.html';
+import HTMLErrorModal from '../../components/modal/error-modal.html';
+import HTMLCustomModal from '../../components/modal/custom-modal.html';
+
+class Example extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ show: false
+ };
+ }
+ render() {
+ const { children } = this.props;
+ const { show } = this.state;
+ var childrenWithProps = React.Children.map(children, child => {
+ let childChildrenWithProps = [];
+ if (child.props.children) {
+ let childChildren = child.props.children;
+ childChildrenWithProps = React.Children.map(childChildren, child =>
+ React.cloneElement(child, { onClose: ()=>this.setState({show: !show}) }));
+
+ }
+ return React.cloneElement(child, { show: this.state.show, onClose: ()=>this.setState({show: !show}), children: childChildrenWithProps});
+ }
+ );
+
+ return (
+ <div>
+ <Button onClick={() => this.setState({show: !show})}>Modal</Button>
+ {childrenWithProps}
+ </div>
+ );
+ }
+}
+
+const ModalBody = () => {
+ return (
+ <div>
+ <Input
+ name='input1'
+ value='Default'
+ label='I am a label'
+ type='text' />
+ <Input
+ name='input1'
+ value='Default'
+ label='I am a label'
+ type='text' />
+ <Input
+ name='input1'
+ value='Default'
+ label='I am a label'
+ type='text' />
+
+ </div>);
+};
+
+const BODY_TEXT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed risus nisl, egestas vitae erat non,' +
+ 'pulvinar lacinia libero. Integer pulvinar pellentesque accumsan. Sed hendrerit lacus eu tempus pharetra';
+
+const isShown = false;
+
+let examples = {
+ Standard: {
+ jsx: <Example>
+ <Modal show={() => isShown()} size='small'>
+ <Modal.Header><Modal.Title>Standard Modal</Modal.Title></Modal.Header>
+ <Modal.Body>
+ {BODY_TEXT}
+ </Modal.Body>
+ <Modal.Footer actionButtonText='Yes' actionButtonClick={()=>{}}/>
+ </Modal>
+ </Example>,
+ html: HTMLStandardModal,
+ exclude: 'Example',
+ renderFromJsx: true
+ },
+ Alert: {
+ jsx: <Example>
+ <Modal show={() => isShown()} type='alert' size='small'>
+ <Modal.Header type='alert'><Modal.Title>Title</Modal.Title></Modal.Header>
+ <Modal.Body>
+ {BODY_TEXT}
+ </Modal.Body>
+ <Modal.Footer closeButtonText='Ok'/>
+ </Modal>
+ </Example>,
+ html: HTMLAlertModal,
+ exclude: 'Example',
+ renderFromJsx: true
+ },
+ Error: {
+ jsx: <Example>
+ <Modal show={() => isShown()} size='small' type='error'>
+ <Modal.Header onClose={()=>isShown(false)} type='error'><Modal.Title>Title</Modal.Title></Modal.Header>
+ <Modal.Body>
+ {BODY_TEXT}
+ </Modal.Body>
+ <Modal.Footer onClose={()=>isShown(false)} closeButtonText='Ok'/>
+ </Modal>
+ </Example>,
+ html: HTMLErrorModal,
+ exclude: 'Example',
+ renderFromJsx: true
+ },
+
+ Custom: {
+ jsx: <Example>
+ <Modal show={() => isShown()} type='custom'>
+ <Modal.Header type='custom'><Modal.Title>Title</Modal.Title></Modal.Header>
+ <Modal.Body>
+ <ModalBody/>
+ </Modal.Body>
+ <Modal.Footer actionButtonText='Ok' actionButtonClick={()=>{}}/>
+ </Modal>
+ </Example>,
+ html: HTMLCustomModal,
+ exclude: 'Example',
+ renderFromJsx: true
+ }
+};
+
+const Modals = () => (
+ <Examples examples={examples}/>
+);
+
+export default Modals; \ No newline at end of file
diff --git a/stories/react/Panel.stories.js b/stories/react/Panel.stories.js
new file mode 100644
index 0000000..f87eefb
--- /dev/null
+++ b/stories/react/Panel.stories.js
@@ -0,0 +1,22 @@
+import React from 'react';
+import Examples from './utils/Examples.js';
+import Panel from '../../src/react/Panel.js';
+import Checkbox from '../../src/react/Checkbox.js';
+import HTMLBasic from '../../components/panel/basic-panel.html';
+let examples = {
+ Basic: {
+ jsx:
+ <Panel>
+ <h3>Panel</h3>
+ <Checkbox label='filter-item' />
+ <Checkbox checked label='filter-item-checked' />
+ </Panel>,
+ html: HTMLBasic
+ }
+};
+
+const PanelStory = () => (
+ <Examples examples={examples} />
+);
+
+export default PanelStory;
diff --git a/stories/react/PopupMenu.stories.js b/stories/react/PopupMenu.stories.js
new file mode 100644
index 0000000..9d94522
--- /dev/null
+++ b/stories/react/PopupMenu.stories.js
@@ -0,0 +1,37 @@
+
+import React from 'react';
+import Examples from './utils/Examples.js';
+import PopupMenu from '../../src/react/PopupMenu.js';
+import PopupMenuItem from '../../src/react/PopupMenuItem.js';
+import HTMLPopupMenu from '../../components/menu/popup-menu.html';
+import HTMLPopupMenuRelative from '../../components/menu/relative-popup-menu.html';
+
+let examples = {
+ 'Basic popup menu (static)': {
+ jsx: <PopupMenu onMenuItemClick={() => {}}>
+ <PopupMenuItem itemId='1' value='item 1 (selected)' selected/>
+ <PopupMenuItem itemId='2' value='item 2' disabled/>
+ <PopupMenu.Separator />
+ <PopupMenuItem itemId='3' value='item 3'/>
+ <PopupMenuItem itemId='4' value='custom action' onClick={function customCallback() {}}/>
+ </PopupMenu>,
+ html: HTMLPopupMenu
+ },
+ 'Basic popup menu (relative)': {
+ jsx: <div className='sdc-popup-menu'>
+ <PopupMenu onMenuItemClick={()=> {}} position={{x: 10, y: 10}} relative>
+ <PopupMenuItem itemId='1' value='item 1 (selected)' selected/>
+ <PopupMenuItem itemId='2' value='item 2' disabled/>
+ <PopupMenu.Separator />
+ <PopupMenuItem itemId='3' value='item 3' onClick={function customCallback() {}}/>
+ </PopupMenu>
+ </div>,
+ html: HTMLPopupMenuRelative
+ }
+};
+
+const PopupMenuReactComponent = () => (
+ <Examples examples={examples} />
+);
+
+export default PopupMenuReactComponent; \ No newline at end of file
diff --git a/stories/react/Radio.stories.js b/stories/react/Radio.stories.js
new file mode 100644
index 0000000..151f947
--- /dev/null
+++ b/stories/react/Radio.stories.js
@@ -0,0 +1,33 @@
+import React from 'react';
+import Examples from './utils/Examples.js';
+
+import Radio from '../../src/react/Radio';
+import HTMLRadioChecked from '../../components/radio/radio-checked.html';
+import HTMLRadioUnchecked from '../../components/radio/radio-unchecked.html';
+import HTMLRadioDisabled from '../../components/radio/radio-disabled.html';
+import HTMLRadioDisabledChecked from '../../components/radio/radio-disabled-checked.html';
+
+let examples = {
+ Checked: {
+ jsx: <Radio name='grp1' checked={true} label='This is the radio label' value='myVal' onChange={()=>{}} data-test-id='myradio-1' inputRef={() => {} } />,
+ html: HTMLRadioChecked
+ },
+ Unchecked: {
+ jsx: <Radio name='grp2' label='This is the radio label' value='myVal' onChange={()=>{}} data-test-id='myradio-2' inputRef={() => {} } />,
+ html: HTMLRadioUnchecked
+ },
+ Disabled: {
+ jsx: <Radio name='grp3' label='This is the radio label' disabled={true} value='myVal' onChange={()=>{}} data-test-id='myradio-4' inputRef={() => {} } />,
+ html: HTMLRadioDisabled
+ },
+ 'Disabled and Checked': {
+ jsx: <Radio name='grp4' label='This is the radio label' disabled={true} checked={true} value='myVal' onChange={()=>{}} data-test-id='myradio-4' inputRef={() => {} } />,
+ html: HTMLRadioDisabledChecked
+ }
+};
+
+const Radios = () => (
+ <Examples examples={examples} />
+);
+
+export default Radios;
diff --git a/stories/react/RadioGroup.stories.js b/stories/react/RadioGroup.stories.js
new file mode 100644
index 0000000..912f9b9
--- /dev/null
+++ b/stories/react/RadioGroup.stories.js
@@ -0,0 +1,34 @@
+import React from 'react';
+import Examples from './utils/Examples.js';
+
+import RadioGroup from '../../src/react/RadioGroup';
+import HTMLRadioGroup from '../../components/radioGroup/radio-group.html';
+import HTMLRadioGroupValue from '../../components/radioGroup/radio-group-value.html';
+import HTMLRadioGroupDisabled from '../../components/radioGroup/radio-group-disabled.html';
+import HTMLRadioGroupNoTitle from '../../components/radioGroup/radio-group-no-title.html';
+
+let examples = {
+ 'Value': {
+ jsx: <RadioGroup name='grp2' value='1' title='Group B' onChange={()=>{}} data-test-id='grp2' options={[{value: '1', label: 'option 1'}, {value: '2', label: 'option 2'}]} />,
+ html: HTMLRadioGroupValue
+ },
+ 'No Value': {
+ jsx: <RadioGroup name='grp3' title='Group C' onChange={()=>{}} data-test-id='grp3' options={[{value: '1', label: 'option 1'}, {value: '2', label: 'option 2'}]} />,
+ html: HTMLRadioGroup
+ },
+ 'Disabled': {
+ jsx: <RadioGroup name='grp4' disabled={true} title='Group D' onChange={()=>{}} data-test-id='grp4' options={[{value: '1', label: 'option 1'}, {value: '2', label: 'option 2'}]} />,
+ html: HTMLRadioGroupDisabled
+ },
+ 'No title': {
+ jsx: <RadioGroup name='grp5' onChange={()=>{}} data-test-id='grp4' options={[{value: '1', label: 'option 1'}, {value: '2', label: 'option 2'}]} />,
+ html: HTMLRadioGroupNoTitle
+ }
+
+};
+
+const RadioGroups = () => (
+ <Examples examples={examples} />
+);
+
+export default RadioGroups;
diff --git a/stories/react/SVGIcon.stories.js b/stories/react/SVGIcon.stories.js
new file mode 100644
index 0000000..2c2ffc2
--- /dev/null
+++ b/stories/react/SVGIcon.stories.js
@@ -0,0 +1,103 @@
+import React from 'react';
+import Examples from './utils/Examples.js';
+import DropdownMenu from './utils/components/DropdownMenu.js';
+import SVGIcon from '../../src/react/SVGIcon.js';
+
+const iconLabelPositions = [
+ '', 'bottom', 'top', 'left', 'right'
+];
+
+const iconColors = [
+ '',
+ 'primary',
+ 'secondary',
+ 'positive',
+ 'negative',
+ 'warning'
+];
+
+const disabledStates = ['false', 'true'];
+
+function buildExamples({iconName, iconLabel, labelPosition, color, disabled}) {
+ return {
+ Example: {
+ jsx: <SVGIcon
+ label={iconLabel}
+ labelPosition={labelPosition}
+ color={color}
+ name={iconName}
+ disabled={disabled === 'true'} />
+ }
+ };
+}
+
+const IconTable = ({onClick}) => (
+ <div className='icons-table'>
+ {ICON_NAMES.map(icon => (
+ <div key={icon} className='icon-section'>
+ <SVGIcon
+ onClick={() => onClick(icon)}
+ label={icon}
+ iconClassName='storybook-small'
+ name={icon} />
+ </div>
+ ))}
+ </div>
+);
+
+class Icons extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ iconName: ICON_NAMES[0],
+ iconLabel: '',
+ labelPosition: iconLabelPositions[0],
+ color : iconColors[0]
+ };
+ }
+
+ render() {
+ let {iconName, iconLabel, labelPosition, color, disabled} = this.state;
+ return (
+ <div className='icons-screen'>
+ <h1>Icons</h1>
+ <div className='icons-option-selector'>
+ <DropdownMenu
+ title='Icon name'
+ value={iconName}
+ onChange={e => this.setState({iconName: e.target.value})}
+ options={ICON_NAMES} />
+ <div className='option-container'>
+ <label>Icon label</label>
+ <input value={iconLabel} onChange={e => this.setState({iconLabel: e.target.value})}/>
+ </div>
+ <DropdownMenu
+ title='Label position'
+ value={labelPosition}
+ onChange={e => this.setState({labelPosition: e.target.value})}
+ options={iconLabelPositions} />
+ <DropdownMenu
+ title='Color'
+ value={color}
+ onChange={e => this.setState({color: e.target.value})}
+ options={iconColors} />
+ <DropdownMenu
+ title='Disabled'
+ value={disabled}
+ onChange={e => this.setState({disabled: e.target.value})}
+ options={disabledStates} />
+ </div>
+ <Examples examples={buildExamples({iconName, iconLabel, labelPosition, color, disabled})} />
+ <IconTable onClick={icon => this.setState({iconName: icon})} />
+ <div className='missing-icon-section'>
+ <div >You will see the following if the icon name you used is not found:</div>
+ <SVGIcon
+ onClick={() => {}}
+ name='MissingIcon' />
+ </div>
+ </div>
+ );
+ };
+}
+
+export default Icons;
diff --git a/stories/react/Tabs.stories.js b/stories/react/Tabs.stories.js
new file mode 100644
index 0000000..74f163c
--- /dev/null
+++ b/stories/react/Tabs.stories.js
@@ -0,0 +1,48 @@
+import React from 'react';
+import Examples from './utils/Examples.js';
+import {default as TabsComp} from '../../src/react/Tabs.js';
+import Tab from '../../src/react/Tab.js';
+import HTMLTabsHeader from '../../components/tabs/tabs-header.html';
+import HTMLTabsDisabled from '../../components/tabs/tabs-disabled.html';
+import HTMLTabsMenu from '../../components/tabs/tabs-menu.html';
+
+let examples = {
+ 'Menu Tabs': {
+ jsx: <TabsComp type='menu' activeTab='1' onTabClick={(tabId) => {console.log(tabId);}}>
+ <Tab title='tab 1' tabId='1'>
+ <div>This is the active tab content</div>
+ </Tab>
+ <Tab title='tab 2' tabId='2' />
+ <Tab title='tab 3' tabId='3' />
+ </TabsComp>,
+ html: HTMLTabsMenu
+ },
+ 'Header Tabs': {
+ jsx: <TabsComp type='header' activeTab='1' onTabClick={(tabId) => {console.log(tabId);}}>
+ <Tab title='tab 1' tabId='1'>
+ <div>This is the active tab content</div>
+ </Tab>
+ <Tab title='tab 2' tabId='2' />
+ <Tab title='tab 3' tabId='3' />
+ </TabsComp>,
+ html: HTMLTabsHeader
+ },
+ 'Disabled Tabs': {
+ jsx: (
+ <TabsComp type='header' activeTab='1' onTabClick={(tabId) => {console.log(tabId);}}>
+ <Tab title='tab 1' tabId='1'>
+ <div>This is the active tab content</div>
+ </Tab>
+ <Tab title='tab 2' tabId='2' disabled/>
+ <Tab title='tab 3' tabId='3' disabled/>
+ </TabsComp>
+ ),
+ html: HTMLTabsDisabled
+ }
+};
+
+const Tabs = () => (
+ <Examples examples={examples} />
+);
+
+export default Tabs;
diff --git a/stories/react/Tiles.stories.js b/stories/react/Tiles.stories.js
new file mode 100644
index 0000000..04a6fb5
--- /dev/null
+++ b/stories/react/Tiles.stories.js
@@ -0,0 +1,89 @@
+import React from 'react';
+
+import Examples from './utils/Examples.js';
+import SVGIcon from '../../src/react/SVGIcon.js';
+import Button from '../../src/react/Button.js';
+
+import Tile from '../../src/react/Tile.js';
+import TileInfo from '../../src/react/TileInfo.js';
+import TileInfoLine from '../../src/react/TileInfoLine.js';
+import TileFooter from '../../src/react/TileFooter.js';
+import TileFooterCell from '../../src/react/TileFooterCell.js';
+
+import HTMLTileWithoutFooter from '../../components/tile/tile-without-footer.html';
+import HTMLVspTile from '../../components/tile/vsp-tile.html';
+import HTMLVlmTile from '../../components/tile/vlm-tile.html';
+import HTMLVendorTile from '../../components/tile/vendor-tile.html';
+import HTMLVfcTile from '../../components/tile/vfc-tile.html';
+
+let examples = {
+ 'Without footer': {
+ jsx: <Tile headerText='header' headerColor='blue' iconName='vsp' iconColor='blue'>
+ <TileInfo>
+ <TileInfoLine type='supertitle'>Supertitle</TileInfoLine>
+ <TileInfoLine type='title'>Title</TileInfoLine>
+ </TileInfo>
+ </Tile>,
+ html: HTMLTileWithoutFooter
+ },
+ VFC: {
+ jsx: <Tile headerText='vfc' headerColor='purple' iconName='network'>
+ <TileInfo>
+ <TileInfoLine type='title'>Title</TileInfoLine>
+ <TileInfoLine type='subtitle'>V 1.0</TileInfoLine>
+ </TileInfo>
+ <TileFooter>
+ <TileFooterCell>Certified</TileFooterCell>
+ </TileFooter>
+ </Tile>,
+ html: HTMLVfcTile
+ },
+ VSP: {
+ jsx: <Tile headerText='vsp' headerColor='blue' iconName='vsp' iconColor='blue'>
+ <TileInfo>
+ <TileInfoLine type='supertitle'>VLM</TileInfoLine>
+ <TileInfoLine type='title'>VSP name</TileInfoLine>
+ </TileInfo>
+ <TileFooter>
+ <TileFooterCell>Draft</TileFooterCell>
+ </TileFooter>
+ </Tile>,
+ html: HTMLVspTile
+ },
+ VLM: {
+ jsx: <Tile headerText='vlm' headerColor='purple' iconName='vlm' iconColor='purple'>
+ <TileInfo>
+ <TileInfoLine type='title'>VLM name</TileInfoLine>
+ </TileInfo>
+ <TileFooter>
+ <TileFooterCell>Certified</TileFooterCell>
+ <TileFooterCell>
+ <SVGIcon name='versionControllerPermissions' label='Owner' labelPosition='left' />
+ </TileFooterCell>
+ </TileFooter>
+ </Tile>,
+ html: HTMLVlmTile
+ },
+ Vendor: {
+ jsx: <Tile iconName='vendor' iconColor='dark-gray'>
+ <TileInfo align='center'>
+ <TileInfoLine type='title'>Vendor name</TileInfoLine>
+ <TileInfoLine>
+ <Button btnType='primary' onClick={() => {}}>100 VSPs</Button>
+ </TileInfoLine>
+ </TileInfo>
+ <TileFooter align='center'>
+ <TileFooterCell>
+ <Button btnType='link' color='primary' iconName='plusThin' onClick={() => {}}>Create new VSP</Button>
+ </TileFooterCell>
+ </TileFooter>
+ </Tile>,
+ html: HTMLVendorTile
+ },
+};
+
+const Tiles = () => (
+ <Examples examples={examples} />
+);
+
+export default Tiles;
diff --git a/stories/react/Typography.stories.js b/stories/react/Typography.stories.js
new file mode 100644
index 0000000..f1475c6
--- /dev/null
+++ b/stories/react/Typography.stories.js
@@ -0,0 +1,62 @@
+import React, {Component} from 'react';
+
+const typos = [
+ {className: 'heading-1', size: 28, text: 'Major Section Heading'},
+ {className: 'heading-2', size: 24, text: 'Sub-Section Heading'},
+ {className: 'heading-3', size: 20, text: 'Small Heading'},
+ {className: 'heading-4', size: 16, text: 'Small Heading'},
+ {className: 'heading-4-emphasis', size: 16, text: 'Small Heading'},
+ {className: 'heading-5', size: 14, text: 'Small Heading'},
+ {className: 'body-1', size: 14, text: 'Body (Standard) Text'},
+ {className: 'body-1-italic', size: 14, text: 'Body (Standard) Text'},
+ {className: 'body-2', size: 13, text: 'Text in Tables'},
+ {className: 'body-2-emphasis', size: 13, text: 'Text in Tables'},
+ {className: 'body-3', size: 12, text: 'Input Labels, Table Titles'},
+ {className: 'body-3-emphasis', size: 12, text: 'Even Smaller Text'},
+ {className: 'body-4', size: 10, text: 'Even Much Smaller Text'}
+];
+
+const fontWeights = ['OpenSans Regular 400', 'OpenSans Semibold 600'];
+
+function TextRow({className, size, text}) {
+ return (
+ <div className={`typo-section ${className}`}>
+ <div>{className}</div>
+ <div>{size}px</div>
+ <div className='sample-text'>{text}</div>
+ </div>
+ );
+}
+
+class Typography extends Component {
+
+ render() {
+ return (
+ <div className='typography-screen'>
+ <h1>Typography</h1>
+ <div className='typography-section'>
+ <h3>Font Family</h3>
+ <ul>
+ <li>OpenSans</li>
+ <li style={{'fontFamily': 'Arial'}}>Arial</li>
+ <li style={{'fontFamily':'sans-serif'}}>sans-serif</li>
+ </ul>
+ </div>
+ <div className='typography-section'>
+ <h3>Font Weights</h3>
+ <ul>{fontWeights.map(font => <li key={font} className={font}>{font}</li>)}</ul>
+ </div>
+ <div className='typography-section'>
+ <h3>Font Size</h3>
+ <div className='typo-table'>
+ <TextRow className='SCSS mixin name (@include ....)' size='Size (in Pixels)' text='Sample Text'/>
+ {typos.map(typo => <TextRow key={typo.className} {...typo}/>)}
+ </div>
+ </div>
+ </div>
+ );
+ }
+
+}
+
+export default Typography;
diff --git a/stories/react/buttons/LinkButtons.stories.js b/stories/react/buttons/LinkButtons.stories.js
new file mode 100644
index 0000000..ef32a22
--- /dev/null
+++ b/stories/react/buttons/LinkButtons.stories.js
@@ -0,0 +1,49 @@
+import React from 'react';
+import Examples from '../utils/Examples.js';
+
+import ReactButton from '../../../src/react/Button.js';
+
+import LinkButton from '../../../components/button/button-link.html';
+import LinkButtonDisabled from '../../../components/button/button-link-disabled.html';
+import ExtraSmall from '../../../components/button/button-link-extra-small.html';
+import Small from '../../../components/button/button-link-small.html';
+import Medium from '../../../components/button/button-link-medium.html';
+import Large from '../../../components/button/button-link-large.html';
+import Auto from '../../../components/button/button-link-auto.html';
+
+let examples = {
+ 'Link Default': {
+ jsx: <ReactButton btnType='link' onClick={() => {}}>Click Me</ReactButton>,
+ html: LinkButton
+ },
+ 'Link Disabled': {
+ jsx: <ReactButton btnType='link' onClick={() => {}} disabled>Click Me</ReactButton>,
+ html: LinkButtonDisabled,
+ },
+ 'Extra Small': {
+ jsx: <ReactButton btnType='link' size='x-small' onClick={() => {}}>Click Me</ReactButton>,
+ html: ExtraSmall
+ },
+ 'Small': {
+ jsx: <ReactButton btnType='link' size='small' onClick={() => {}}>Click Me</ReactButton>,
+ html: Small,
+ },
+ 'Medium': {
+ jsx: <ReactButton btnType='link' size='medium' onClick={() => {}}>Click Me</ReactButton>,
+ html: Medium
+ },
+ 'Large': {
+ jsx: <ReactButton btnType='link' size='large' onClick={() => {}}>Click Me</ReactButton>,
+ html: Large,
+ },
+ 'Auto Sizing': {
+ jsx: <ReactButton btnType='link' size='default' onClick={() => {}}>Click Me</ReactButton>,
+ html: Auto,
+ }
+};
+
+const DefaultButtons = () => (
+ <Examples examples={examples} />
+);
+
+export default DefaultButtons;
diff --git a/stories/react/buttons/PrimaryButtons.stories.js b/stories/react/buttons/PrimaryButtons.stories.js
new file mode 100644
index 0000000..db732b9
--- /dev/null
+++ b/stories/react/buttons/PrimaryButtons.stories.js
@@ -0,0 +1,49 @@
+import React from 'react';
+import Examples from '../utils/Examples.js';
+
+import ReactButton from '../../../src/react/Button.js';
+
+import PrimaryButton from '../../../components/button/button-primary.html';
+import PrimaryButtonDisabled from '../../../components/button/button-primary-disabled.html';
+import ExtraSmall from '../../../components/button/button-primary-extra-small.html';
+import Small from '../../../components/button/button-primary-small.html';
+import Medium from '../../../components/button/button-primary-medium.html';
+import Large from '../../../components/button/button-primary-large.html';
+import Auto from '../../../components/button/button-primary-auto.html';
+
+let examples = {
+ 'Primary Default': {
+ jsx: <ReactButton onClick={() => {}}>Click Me</ReactButton>,
+ html: PrimaryButton
+ },
+ 'Primary Disabled': {
+ jsx: <ReactButton onClick={() => {}} disabled>Click Me</ReactButton>,
+ html: PrimaryButtonDisabled,
+ },
+ 'Extra Small': {
+ jsx: <ReactButton size='x-small' onClick={() => {}}>Click Me</ReactButton>,
+ html: ExtraSmall
+ },
+ 'Small': {
+ jsx: <ReactButton size='small' onClick={() => {}}>Click Me</ReactButton>,
+ html: Small,
+ },
+ 'Medium': {
+ jsx: <ReactButton size='medium' onClick={() => {}}>Click Me</ReactButton>,
+ html: Medium
+ },
+ 'Large': {
+ jsx: <ReactButton size='large' onClick={() => {}}>Click Me</ReactButton>,
+ html: Large,
+ },
+ 'Auto Sizing': {
+ jsx: <ReactButton size='default' onClick={() => {}}>Click Me</ReactButton>,
+ html: Auto,
+ }
+};
+
+const DefaultButtons = () => (
+ <Examples examples={examples} />
+);
+
+export default DefaultButtons;
diff --git a/stories/react/buttons/SecondaryButtons.stories.js b/stories/react/buttons/SecondaryButtons.stories.js
new file mode 100644
index 0000000..75f9d54
--- /dev/null
+++ b/stories/react/buttons/SecondaryButtons.stories.js
@@ -0,0 +1,49 @@
+import React from 'react';
+import Examples from '../utils/Examples.js';
+
+import ReactButton from '../../../src/react/Button.js';
+
+import SecondaryButton from '../../../components/button/button-secondary.html';
+import SecondaryButtonDisabled from '../../../components/button/button-secondary-disabled.html';
+import ExtraSmall from '../../../components/button/button-secondary-extra-small.html';
+import Small from '../../../components/button/button-secondary-small.html';
+import Medium from '../../../components/button/button-secondary-medium.html';
+import Large from '../../../components/button/button-secondary-large.html';
+import Auto from '../../../components/button/button-secondary-auto.html';
+
+let examples = {
+ 'Secondary Default': {
+ jsx: <ReactButton btnType='secondary' onClick={() => {}}>Click Me</ReactButton>,
+ html: SecondaryButton
+ },
+ 'Secondary Disabled': {
+ jsx: <ReactButton btnType='secondary' onClick={() => {}} disabled>Click Me</ReactButton>,
+ html: SecondaryButtonDisabled,
+ },
+ 'Extra Small': {
+ jsx: <ReactButton btnType='secondary' size='x-small' onClick={() => {}}>Click Me</ReactButton>,
+ html: ExtraSmall
+ },
+ 'Small': {
+ jsx: <ReactButton btnType='secondary' size='small' onClick={() => {}}>Click Me</ReactButton>,
+ html: Small,
+ },
+ 'Medium': {
+ jsx: <ReactButton btnType='secondary' size='medium' onClick={() => {}}>Click Me</ReactButton>,
+ html: Medium
+ },
+ 'Large': {
+ jsx: <ReactButton btnType='secondary' size='large' onClick={() => {}}>Click Me</ReactButton>,
+ html: Large,
+ },
+ 'Auto Sizing': {
+ jsx: <ReactButton btnType='secondary' size='default' onClick={() => {}}>Click Me</ReactButton>,
+ html: Auto,
+ }
+};
+
+const DefaultButtons = () => (
+ <Examples examples={examples} />
+);
+
+export default DefaultButtons;
diff --git a/stories/react/index.js b/stories/react/index.js
new file mode 100644
index 0000000..6d425ba
--- /dev/null
+++ b/stories/react/index.js
@@ -0,0 +1,66 @@
+import React from 'react';
+import { storiesOf } from '@storybook/react';
+
+import PrimaryButtons from './buttons/PrimaryButtons.stories.js';
+import SecondaryButtons from './buttons/SecondaryButtons.stories.js';
+import LinkButtons from './buttons/LinkButtons.stories.js';
+
+import Colors from './Colors.stories.js';
+import Typography from './Typography.stories.js';
+import Checkboxes from './Checkbox.stories.js';
+import Checklist from './Checklist.stories.js';
+import Input from './Input.stories.js';
+import Icons from './SVGIcon.stories.js';
+import Tiles from './Tiles.stories.js';
+import Tabs from './Tabs.stories.js';
+import Radios from './Radio.stories.js';
+import RadioGroups from './RadioGroup.stories.js';
+import Modals from './Modal.stories.js';
+import PopupMenu from './PopupMenu.stories.js';
+import Accordion from './Accordion.stories.js';
+import Panel from './Panel.stories.js';
+
+storiesOf('Colors', module)
+ .add('Color Palette', () => <Colors />);
+
+storiesOf('Typography', module)
+ .add('Typography', () => <Typography />);
+
+storiesOf('Accordion', module)
+ .add('Accordion', () => <Accordion />);
+
+storiesOf('Buttons', module)
+ .add('Primary', () => <PrimaryButtons />)
+ .add('Secondary', () => <SecondaryButtons />)
+ .add('Link', () => <LinkButtons />);
+
+storiesOf('Checkboxes', module)
+ .add('Checkboxes', () => <Checkboxes />);
+
+storiesOf('Checklist', module)
+ .add('Checklist', () => <Checklist />);
+
+storiesOf('Input Fields', module)
+ .add('Input Text', () => <Input />);
+
+storiesOf('Icons', module)
+ .add('SVG Icons', () => <Icons />);
+
+storiesOf('Menu', module)
+ .add('Popup Menu', () => <PopupMenu />);
+
+storiesOf('Modals', module)
+ .add('Modal examples', () => <Modals />);
+
+storiesOf('Radios', module)
+ .add('Radio Buttons', () => <Radios />)
+ .add('Radio Button Groups', () => <RadioGroups />);
+
+storiesOf('Panel', module)
+ .add('Panel', () => <Panel />);
+
+storiesOf('Tabs', module)
+ .add('Tabs', () => <Tabs />);
+
+storiesOf('Tiles', module)
+ .add('Tiles', () => <Tiles />);
diff --git a/stories/react/utils/BeautifyHTML.js b/stories/react/utils/BeautifyHTML.js
new file mode 100644
index 0000000..1a29b00
--- /dev/null
+++ b/stories/react/utils/BeautifyHTML.js
@@ -0,0 +1,33 @@
+export default function beautifyHTML({html, indentChar = ' ', startingIndentCount = 0}) {
+ html = html.replace(/[ ]{2,}/g, ' ');
+
+ let result = '', indentCount = startingIndentCount, parsingText = false;
+ for (let i = 0; i < html.length; i++) {
+
+ let startOfTag, endOfTag, closingTag, upcomingTag, afterTag, numTabs;
+ if (html[i] === '<') { startOfTag = true; }
+ else if (html[i] === '>') { endOfTag = true; }
+ else if (html[i - 1] === '>') { afterTag = true; }
+ if (html[i + 1] === '/') { closingTag = true; }
+ else if (html[i + 1 ] === '<') { upcomingTag = true; }
+
+ if (startOfTag) {
+ if (closingTag) { numTabs = --indentCount; }
+ else { numTabs = indentCount++; }
+ }
+
+ if (parsingText && afterTag) {
+ numTabs = indentCount;
+ }
+
+ result += indentChar.repeat(numTabs) + html[i];
+
+ if (endOfTag || parsingText && upcomingTag) {
+ result += '\n';
+ parsingText = false;
+ if (!upcomingTag) { parsingText = true; }
+ }
+ }
+
+ return result.slice(0, -1);
+}
diff --git a/stories/react/utils/Examples.js b/stories/react/utils/Examples.js
new file mode 100644
index 0000000..5948b68
--- /dev/null
+++ b/stories/react/utils/Examples.js
@@ -0,0 +1,23 @@
+import React from 'react';
+import {renderToStaticMarkup} from 'react-dom/server';
+import SourceToggle from './SourceToggle.js';
+import beautifyHTML from './BeautifyHTML.js';
+import insertSVGIcons from './InsertSVGIcons.js';
+
+const Examples = ({examples}) => (
+ <div className={'examples'}>
+ {Object.keys(examples).map(key => {
+ let title = key;
+ let {jsx, html, displayTitle = true, exclude, renderFromJsx = false} = examples[key];
+ if (!html) {
+ html = renderToStaticMarkup(jsx);
+ html = beautifyHTML({html, indentChar: ' '});
+ } else {
+ html = insertSVGIcons({html, jsx});
+ }
+ return <SourceToggle title={displayTitle && title} jsx={jsx} html={html} key={key} exclude={exclude} renderFromJsx={renderFromJsx}/>;
+ })}
+ </div>
+);
+
+export default Examples;
diff --git a/stories/react/utils/InsertSVGIcons.js b/stories/react/utils/InsertSVGIcons.js
new file mode 100644
index 0000000..5a5e390
--- /dev/null
+++ b/stories/react/utils/InsertSVGIcons.js
@@ -0,0 +1,15 @@
+import {renderToStaticMarkup} from 'react-dom/server';
+import beautifyHTML from './BeautifyHTML.js';
+
+const insertSVGIcons = ({html, jsx, indentChar = ' '}) => {
+ let svgCode = renderToStaticMarkup(jsx).match(/(<svg\b[^<>]*>)[\s\S]*?(<\/svg>)/g);
+ let newHTML = html.replace(/\s*<!-- insert SVG -->/g, str => {
+ let html = '\n' + svgCode.shift();
+ let indentRegExp = new RegExp(`[${indentChar}]*`);
+ let startingIndentCount = str.slice(2).match(indentRegExp)[0].length / indentChar.length;
+ return beautifyHTML({html, startingIndentCount, indentChar});
+ });
+ return newHTML;
+};
+
+export default insertSVGIcons;
diff --git a/stories/react/utils/SourceToggle.js b/stories/react/utils/SourceToggle.js
new file mode 100644
index 0000000..a05c8d0
--- /dev/null
+++ b/stories/react/utils/SourceToggle.js
@@ -0,0 +1,73 @@
+/* eslint-disable react/no-danger */
+import React from 'react';
+import jsxToString from './jsxToString.js';
+
+import Prism from 'prismjs';
+
+import PrismJsx from 'prismjs/components/prism-jsx.js'; // eslint-disable-line no-unused-vars
+
+const sources = {
+ React: 'React',
+ HTML: 'HTML'
+};
+
+export default class SourceToggle extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ source: sources.React
+ };
+ }
+
+ renderFromSource() {
+ let {jsx, html, renderFromJsx} = this.props;
+ let {source} = this.state;
+ let classname = 'source-toggle-example';
+ switch (source) {
+ case sources.HTML:
+ return renderFromJsx ? <div className={classname}>{jsx}</div> : <div className={classname} dangerouslySetInnerHTML={{__html: html}} />;
+ case sources.React:
+ default:
+ return <div className={classname}>{jsx}</div>;
+ }
+ }
+
+ renderMarkdown() {
+ let {jsx, html, exclude} = this.props;
+ let {source} = this.state;
+ switch (source) {
+ case sources.HTML:
+ return {__html: Prism.highlight(html, Prism.languages.html)};
+ case sources.React:
+ default:
+ return {__html: Prism.highlight(jsxToString({jsx, exclude}), Prism.languages.jsx)};
+ }
+ }
+
+ render() {
+ let {title} = this.props;
+ return (
+ <div className='source-toggle-wrapper'>
+ {title && <div className='source-toggle-title'>{title}</div>}
+ <div className='source-toggle'>
+ {this.renderFromSource()}
+ <div className='source-toggle-code'>
+ <div className='source-toggle-code-tabs'>
+ {Object.keys(sources).map((source, i) => (
+ <div
+ key={i}
+ className={`source-toggle-tab${this.state.source === source ? ' selected' : ''}`}
+ onClick={() => this.setState({source})}>
+ {source}
+ </div>
+ ))}
+ </div>
+ <pre>
+ <code dangerouslySetInnerHTML={this.renderMarkdown()} />
+ </pre>
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/stories/react/utils/components/DropdownMenu.js b/stories/react/utils/components/DropdownMenu.js
new file mode 100644
index 0000000..4a69463
--- /dev/null
+++ b/stories/react/utils/components/DropdownMenu.js
@@ -0,0 +1,14 @@
+import React from 'react';
+
+const DropdownMenu = ({title, value, onChange, options}) => (
+ <div className='option-container'>
+ <label>{title}</label>
+ <select value={value} onChange={onChange}>
+ {options.map((option, i) =>
+ <option key={i} value={option}>{option}</option>
+ )}
+ </select>
+ </div>
+);
+
+export default DropdownMenu;
diff --git a/stories/react/utils/jsxToString.js b/stories/react/utils/jsxToString.js
new file mode 100644
index 0000000..8b799ad
--- /dev/null
+++ b/stories/react/utils/jsxToString.js
@@ -0,0 +1,74 @@
+import React, {Children} from 'react';
+
+const INDENT = ' ';
+
+function stringRepresentationForJsx(item) {
+ if (typeof item === 'string') {
+ return `'${item}'`;
+ } else if (typeof item === 'number') {
+ return item.toString();
+ } else if (Array.isArray(item)) {
+ return `[${item.map(val => stringRepresentationForJsx(val)).toString()}]`;
+ }
+ else if (typeof item === 'boolean') {
+ return item.toString();
+ }
+ else if (typeof item === 'function') {
+ return item.toString().replace(/\s{2,}/g, ' ');
+ } else if (typeof item === 'object') {
+ let repr = '{';
+ for (let key in item) {
+ if (item.hasOwnProperty(key)) {
+ repr += `${key}: ${stringRepresentationForJsx(item[key])}, `;
+ }
+ }
+ repr = repr.slice(0, -2);
+ repr += '}';
+ return repr;
+ }
+}
+
+function parseProps(jsx, indentCount) {
+ let result = '';
+ for (let prop in jsx.props) {
+ let value = jsx.props[prop];
+ if (prop !== 'children' && value) {
+ let repr = stringRepresentationForJsx(value);
+ let isString = repr.startsWith("'");
+ result += `\n${INDENT.repeat(indentCount)}${prop}`;
+ if (value !== true) {
+ result += `=${isString ? '' : '{ '}${stringRepresentationForJsx(value)}${isString ? '' : ' }'}`;
+ }
+ }
+ }
+ return result;
+}
+
+function jsxToString({jsx, indentCount=0, exclude}) {
+ if (typeof jsx === 'string'){
+ return jsx;
+ }
+
+ let name = typeof jsx.type === 'string' ? jsx.type : jsx.type.name;
+ let result = name === exclude ? ''
+ : `${INDENT.repeat(indentCount)}<${name}${parseProps(jsx, indentCount + 1)}`;
+
+ if (jsx.props.hasOwnProperty('children')) {
+ let {children} = jsx.props;
+ let childrenArr = Children.toArray(children);
+ if (name !== exclude) { result += '>\n';}
+ if (typeof children === 'string') {
+ result += `${INDENT.repeat(indentCount + 1)}${children}\n`;
+ } else {
+ let newIndentCount = name === exclude ? indentCount : indentCount + 1;
+ childrenArr.forEach(child => result += `${jsxToString({jsx: child, indentCount: newIndentCount})}\n`);
+ }
+ const closingTag = name === exclude ? ''
+ : `${INDENT.repeat(indentCount)}</${name}>`;
+ return result + closingTag;
+ }
+
+ return result + ' />';
+}
+
+export default jsxToString;