diff --git a/src/app/app.component.html b/src/app/app.component.html index ddb520bb27c..7b36cae85b2 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -36,6 +36,14 @@ {{item.icon}} {{item.name}} + + + Compared to WC + + + {{item.icon}} + {{item.name}} + @@ -60,6 +68,19 @@ + + + + + + +
diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 2347fbdcaf7..271ac7a24fd 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -1,3 +1,7 @@ .test { color: red; } + +#paneldrawer { + --igx-nav-drawer-size: 27rem; +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 5f727bf4b8d..d3b85e2d551 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -6,6 +6,8 @@ import { PageHeaderComponent } from './pageHeading/pageHeading.component'; import { IgxIconComponent } from '../../projects/igniteui-angular/src/lib/icon/icon.component'; import { NgFor, NgIf } from '@angular/common'; import { IgxNavDrawerTemplateDirective, IgxNavDrawerItemDirective, IgxNavDrawerMiniTemplateDirective } from '../../projects/igniteui-angular/src/lib/navigation-drawer/navigation-drawer.directives'; +import { PropertiesPanelComponent, PropertyPanelConfig } from './properties-panel/properties-panel.component'; +import { PropertyChangeService } from './properties-panel/property-change.service'; @Component({ selector: 'app-root', @@ -25,6 +27,7 @@ import { IgxNavDrawerTemplateDirective, IgxNavDrawerItemDirective, IgxNavDrawerM PageHeaderComponent, RouterOutlet, IgxRippleDirective, + PropertiesPanelComponent ], }) export class AppComponent implements OnInit { @@ -34,6 +37,8 @@ export class AppComponent implements OnInit { @ViewChild('navdrawer', { read: IgxNavigationDrawerComponent, static: true }) public navdrawer; + public panelConfig: PropertyPanelConfig | null = null; + public urlString: string; public drawerState = { @@ -698,10 +703,152 @@ export class AppComponent implements OnInit { } ].sort((componentLink1, componentLink2) => componentLink1.name > componentLink2.name ? 1 : -1); - constructor(private router: Router, private iconService: IgxIconService) { + public WcCompareLinks = [ + { + link: '/avatar-showcase', + icon: 'radio_button_unchecked', + name: 'Avatar' + }, + { + link: '/badge-showcase', + icon: 'radio_button_unchecked', + name: 'Badge' + }, + { + link: '/banner-showcase', + icon: 'radio_button_unchecked', + name: 'Banner' + }, + { + link: '/button-showcase', + icon: 'radio_button_unchecked', + name: 'Buttons' + }, + { + link: '/buttonGroup-showcase', + icon: 'radio_button_unchecked', + name: 'Button Group' + }, + { + link: '/calendar-showcase', + icon: 'radio_button_unchecked', + name: 'Calendar' + }, + { + link: '/card-showcase', + icon: 'radio_button_unchecked', + name: 'Card' + }, + { + link: '/carousel-showcase', + icon: 'radio_button_unchecked', + name: 'Carousel' + }, + { + link: '/checkbox-showcase', + icon: 'radio_button_unchecked', + name: 'Checkbox' + }, + { + link: '/chip-showcase', + icon: 'radio_button_unchecked', + name: 'Chips' + }, + { + link: '/combo-showcase', + icon: 'radio_button_unchecked', + name: 'Combo' + }, + { + link: '/datePicker-showcase', + icon: 'radio_button_unchecked', + name: 'Date Picker' + }, + { + link: '/dialog-showcase', + icon: 'radio_button_unchecked', + name: 'Dialog' + }, + { + link: '/dropDown-showcase', + icon: 'radio_button_unchecked', + name: 'DropDown' + }, + { + link: '/expansionPanel-showcase', + icon: 'radio_button_unchecked', + name: 'Expansion Panel' + }, + { + link: '/icon-button-showcase', + icon: 'radio_button_unchecked', + name: 'Icon Button' + }, + { + link: '/input-group-showcase', + icon: 'radio_button_unchecked', + name: 'Input Group' + }, + { + link: '/list-showcase', + icon: 'radio_button_unchecked', + name: 'List' + }, + { + link: '/radio-showcase', + icon: 'radio_button_unchecked', + name: 'Radio' + }, + { + link: '/select-showcase', + icon: 'radio_button_unchecked', + name: 'Select' + }, + { + link: '/slider-showcase', + icon: 'radio_button_unchecked', + name: 'Slider' + }, + { + link: '/snackbar-showcase', + icon: 'radio_button_unchecked', + name: 'Snackbar' + }, + { + link: '/stepper-showcase', + icon: 'radio_button_unchecked', + name: 'Stepper' + }, + { + link: '/switch-showcase', + icon: 'radio_button_unchecked', + name: 'Switch' + }, + { + link: '/tabs-showcase', + icon: 'radio_button_unchecked', + name: 'Tabs' + }, + { + link: '/toast-showcase', + icon: 'radio_button_unchecked', + name: 'Toast' + }, + { + link: '/tree-showcase', + icon: 'radio_button_unchecked', + name: 'Tree' + } + ].sort((componentLink1, componentLink2) => componentLink1.name > componentLink2.name ? 1 : -1); + + constructor(private router: Router, private iconService: IgxIconService, private propertyChangeService: PropertyChangeService) { iconService.setFamily('fa-solid', { className: 'fa', type: 'font', prefix: 'fa-'}); iconService.setFamily('fa-brands', { className: 'fab', type: 'font' }); + this.propertyChangeService.panelConfig$.subscribe(config => { + this.panelConfig = config; + }); + router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => { for (const component of this.componentLinks) { if (component.link === router.url) { diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 98e5cbb6460..21a26069d67 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,22 +1,36 @@ import { TreeGridAddRowSampleComponent } from './tree-grid-add-row/tree-grid-add-row.sample'; import { Routes } from '@angular/router'; import { AvatarSampleComponent } from './avatar/avatar.sample'; +import { AvatarShowcaseSampleComponent } from './avatar-showcase/avatar-showcase.sample'; import { BadgeSampleComponent } from './badge/badge.sample'; +import { BadgeShowcaseSampleComponent } from './badge-showcase/badge-showcase.sample'; import { ButtonSampleComponent } from './button/button.sample'; +import { ButtonShowcaseSampleComponent } from './button-showcase/button-showcase.sample'; import { CalendarSampleComponent } from './calendar/calendar.sample'; +import { CalendarShowcaseSampleComponent } from './calendar-showcase/calendar-showcase.sample'; import { CardSampleComponent } from './card/card.sample'; +import { CardShowcaseSampleComponent } from './card-showcase/card-showcase.sample'; import { CarouselSampleComponent } from './carousel/carousel.sample'; +import { CarouselShowcaseSampleComponent } from './carousel-showcase/carousel-showcase.sample'; +import { CheckboxShowcaseSampleComponent } from './checkbox-showcase/checkbox-showcase.sample'; import { ChipsSampleComponent } from './chips/chips.sample'; +import { ChipsShowcaseSampleComponent } from './chips-showcase/chips-showcase.sample'; import { ExpansionPanelSampleComponent } from './expansion-panel/expansion-panel-sample'; +import { ExpansionPanelShowcaseSampleComponent } from './expansion-panel-showcase/expansion-panel-showcase-sample'; import { DatePickerSampleComponent } from './date-picker/date-picker.sample'; +import { DatePickerShowcaseSampleComponent } from './date-picker-showcase/date-picker-showcase.sample'; import { DialogSampleComponent } from './dialog/dialog.sample'; +import { DialogShowcaseSampleComponent } from './dialog-showcase/dialog-showcase.sample'; import { DragDropSampleComponent } from './drag-drop/drag-drop.sample'; import { MaskSampleComponent } from './mask/mask.sample'; import { IconSampleComponent } from './icon/icon.sample'; +import { IconButtonShowcaseSampleComponent } from './icon-button-showcase/icon-button-showcase.sample'; import { InputSampleComponent } from './input/input.sample'; import { InputGroupSampleComponent } from './input-group/input-group.sample'; +import { InputGroupShowcaseSampleComponent } from './input-group-showcase/input-group-showcase.sample'; import { LayoutSampleComponent } from './layout/layout.sample'; import { ListSampleComponent } from './list/list.sample'; +import { ListShowcaseSampleComponent } from './list-showcase/list-showcase.sample'; import { ListPanningSampleComponent } from './list-panning/list-panning.sample'; import { ListPerformanceSampleComponent } from './list-performance/list-performance.sample'; import { NavbarSampleComponent } from './navbar/navbar.sample'; @@ -24,8 +38,11 @@ import { NavdrawerSampleComponent } from './navdrawer/navdrawer.sample'; import { ProgressbarSampleComponent } from './progressbar/progressbar.sample'; import { RippleSampleComponent } from './ripple/ripple.sample'; import { SliderSampleComponent } from './slider/slider.sample'; +import { SliderShowcaseSampleComponent } from './slider-showcase/slider-showcase.sample'; import { SplitterSampleComponent } from './splitter/splitter.sample'; import { SnackbarSampleComponent } from './snackbar/snackbar.sample'; +import { SnackbarShowcaseSampleComponent } from './snackbar-showcase/snackbar-showcase.sample'; +import { SwitchShowcaseSampleComponent } from './switch-showcase/switch-showcase.sample'; import { ColorsSampleComponent } from './styleguide/colors/color.sample'; import { ShadowsSampleComponent } from './styleguide/shadows/shadows.sample'; import { TypographySampleComponent } from './styleguide/typography/typography.sample'; @@ -37,6 +54,7 @@ import { BottomNavRoutingView3Component } from './bottomnav-routing/bottomnav-routing-views.sample'; import { TabsSampleComponent } from './tabs/tabs.sample'; +import { TabsShowcaseSampleComponent } from './tabs-showcase/tabs-showcase.sample'; import { TabsRoutingSampleComponent } from './tabs-routing/tabs-routing.sample'; import { TabsRoutingView1Component, @@ -45,6 +63,7 @@ import { } from './tabs-routing/tabs-routing-views.sample'; import { TimePickerSampleComponent } from './time-picker/time-picker.sample'; import { ToastSampleComponent } from './toast/toast.sample'; +import { ToastShowcaseSampleComponent } from './toast-showcase/toast-showcase.sample'; import { VirtualForSampleComponent } from './virtual-for-directive/virtual-for.sample'; import { GridCellEditingComponent } from './grid-cellEditing/grid-cellEditing.component'; import { GridSampleComponent } from './grid/grid.sample'; @@ -62,15 +81,19 @@ import { GridToolbarSampleComponent } from './grid-toolbar/grid-toolbar.sample'; import { GridToolbarCustomSampleComponent } from './grid-toolbar/grid-toolbar-custom.sample'; import { GridVirtualizationSampleComponent } from './grid-remote-virtualization/grid-remote-virtualization.sample'; import { ButtonGroupSampleComponent } from './buttonGroup/buttonGroup.sample'; +import { ButtonGroupShowcaseSampleComponent } from './buttonGroup-showcase/buttonGroup-showcase.sample'; import { GridColumnGroupsSampleComponent } from './grid-column-groups/grid-column-groups.sample'; import { DropDownSampleComponent } from './drop-down/drop-down.sample'; +import { DropDownShowcaseSampleComponent } from './drop-down-showcase/drop-down-showcase.sample'; import { DropDownSizeSampleComponent } from './drop-down/drop-down-size/drop-down-size.sample'; import { DropDownVirtualComponent } from './drop-down/drop-down-virtual/drop-down-virtual.component'; import { ComboSampleComponent } from './combo/combo.sample'; +import { ComboShowcaseSampleComponent } from './combo-showcase/combo-showcase.sample'; import { OverlaySampleComponent } from './overlay/overlay.sample'; import { OverlayAnimationSampleComponent } from './overlay/overlay-animation.sample'; import { OverlayPresetsSampleComponent } from './overlay/overlay-presets.sample'; import { RadioSampleComponent } from './radio/radio.sample'; +import { RadioShowcaseSampleComponent } from './radio-showcase/radio-showcase.sample'; import { TooltipSampleComponent } from './tooltip/tooltip.sample'; import { GridCellStylingSampleComponent } from './gird-cell-styling/grid-cell-styling.sample'; import { GridRowEditSampleComponent } from './grid-row-edit/grid-row-edit-sample.component'; @@ -81,8 +104,10 @@ import { HierarchicalGridRemoteSampleComponent } from './hierarchical-grid-remot import { HierarchicalGridUpdatingSampleComponent } from './hierarchical-grid-updating/hierarchical-grid-updating.sample'; import { GridColumnPercentageWidthsSampleComponent } from './grid-percentage-columns/grid-percantge-widths.sample'; import { BannerSampleComponent } from './banner/banner.sample'; +import { BannerShowcaseSampleComponent } from './banner-showcase/banner-showcase.sample'; import { CalendarViewsSampleComponent } from './calendar-views/calendar-views.sample'; import { SelectSampleComponent } from './select/select.sample'; +import { SelectShowcaseSampleComponent } from './select-showcase/select-showcase.sample'; import { GridSearchComponent } from './grid-search/grid-search.sample'; import { AutocompleteSampleComponent } from './autocomplete/autocomplete.sample'; import { GridMRLSampleComponent } from './grid-multi-row-layout/grid-mrl.sample'; @@ -120,6 +145,7 @@ import { GridEventsComponent } from './grid-events/grid-events.component'; import { GridRowAPISampleComponent } from './grid-row-api/grid-row-api.sample'; import { GridUpdatesComponent } from './grid-updates-test/grid-updates.component'; import { TreeSampleComponent } from './tree/tree.sample'; +import { TreeShowcaseSampleComponent } from './tree-showcase/tree-showcase.sample'; import { GridColumnTypesSampleComponent } from './grid-column-types/grid-column-types.sample'; import { AccordionSampleComponent } from './accordion/accordion.sample'; import { GridLocalizationSampleComponent } from './grid-localization/grid-localization.sample'; @@ -130,6 +156,7 @@ import { PivotGridSampleComponent } from './pivot-grid/pivot-grid.sample'; import { PivotGridHierarchySampleComponent } from './pivot-grid-hierarchy/pivot-grid-hierarchy.sample'; import { PivotGridNoopSampleComponent } from './pivot-grid-noop/pivot-grid-noop.sample'; import { IgxStepperSampleComponent as StepperSampleComponent } from './stepper/stepper.sample'; +import { IgxStepperShowcaseSampleComponent } from './stepper-showcase/stepper-showcase.sample'; import { RatingSampleComponent } from './rating/rating.sample'; import { RangeSliderComponent } from './slider/range-slider/range-slider.component'; import { QueryBuilderComponent } from './query-builder/query-builder.sample'; @@ -164,26 +191,50 @@ export const appRoutes: Routes = [ path: 'avatar', component: AvatarSampleComponent }, + { + path: 'avatar-showcase', + component: AvatarShowcaseSampleComponent + }, { path: 'badge', component: BadgeSampleComponent }, + { + path: 'badge-showcase', + component: BadgeShowcaseSampleComponent + }, { path: 'banner', component: BannerSampleComponent }, + { + path: 'banner-showcase', + component: BannerShowcaseSampleComponent + }, { path: 'select', component: SelectSampleComponent }, + { + path: 'select-showcase', + component: SelectShowcaseSampleComponent + }, { path: 'buttons', component: ButtonSampleComponent }, + { + path: 'button-showcase', + component: ButtonShowcaseSampleComponent + }, { path: 'calendar', component: CalendarSampleComponent }, + { + path: 'calendar-showcase', + component: CalendarShowcaseSampleComponent + }, { path: 'calendar-views', component: CalendarViewsSampleComponent @@ -192,21 +243,45 @@ export const appRoutes: Routes = [ path: 'card', component: CardSampleComponent }, + { + path: 'card-showcase', + component: CardShowcaseSampleComponent + }, { path: 'carousel', component: CarouselSampleComponent }, + { + path: 'carousel-showcase', + component: CarouselShowcaseSampleComponent + }, + { + path: 'checkbox-showcase', + component: CheckboxShowcaseSampleComponent + }, { path: 'combo', component: ComboSampleComponent }, + { + path: 'combo-showcase', + component: ComboShowcaseSampleComponent + }, { path: 'expansionPanel', component: ExpansionPanelSampleComponent }, + { + path: 'expansionPanel-showcase', + component: ExpansionPanelShowcaseSampleComponent + }, { path: 'chip', component: ChipsSampleComponent + }, + { + path: 'chip-showcase', + component: ChipsShowcaseSampleComponent }, { path: 'divider', @@ -216,14 +291,26 @@ export const appRoutes: Routes = [ path: 'datePicker', component: DatePickerSampleComponent }, + { + path: 'datePicker-showcase', + component: DatePickerShowcaseSampleComponent + }, { path: 'dialog', component: DialogSampleComponent }, + { + path: 'dialog-showcase', + component: DialogShowcaseSampleComponent + }, { path: 'dropDown', component: DropDownSampleComponent }, + { + path: 'dropDown-showcase', + component: DropDownShowcaseSampleComponent + }, { path: 'dropDown-density', component: DropDownSizeSampleComponent @@ -244,6 +331,10 @@ export const appRoutes: Routes = [ path: 'icon', component: IconSampleComponent }, + { + path: 'icon-button-showcase', + component: IconButtonShowcaseSampleComponent + }, { path: 'lazyIconModule', loadChildren: () => import('./icon/LazyModule/lazyIcon.module').then(m => m.LazyIconModule) @@ -256,6 +347,10 @@ export const appRoutes: Routes = [ path: 'input-group', component: InputGroupSampleComponent }, + { + path: 'input-group-showcase', + component: InputGroupShowcaseSampleComponent + }, { path: 'layout', component: LayoutSampleComponent @@ -264,6 +359,10 @@ export const appRoutes: Routes = [ path: 'list', component: ListSampleComponent }, + { + path: 'list-showcase', + component: ListShowcaseSampleComponent + }, { path: 'listPanning', component: ListPanningSampleComponent @@ -312,6 +411,10 @@ export const appRoutes: Routes = [ path: 'radio', component: RadioSampleComponent }, + { + path: 'radio-showcase', + component: RadioShowcaseSampleComponent + }, { path: 'rating', component: RatingSampleComponent @@ -328,6 +431,10 @@ export const appRoutes: Routes = [ path: 'slider', component: SliderSampleComponent }, + { + path: 'slider-showcase', + component: SliderShowcaseSampleComponent + }, { path: 'range-slider', component: RangeSliderComponent @@ -340,6 +447,14 @@ export const appRoutes: Routes = [ path: 'snackbar', component: SnackbarSampleComponent }, + { + path: 'snackbar-showcase', + component: SnackbarShowcaseSampleComponent + }, + { + path: 'switch-showcase', + component: SwitchShowcaseSampleComponent + }, { path: 'colors', component: ColorsSampleComponent @@ -376,6 +491,10 @@ export const appRoutes: Routes = [ path: 'tabs', component: TabsSampleComponent }, + { + path: 'tabs-showcase', + component: TabsShowcaseSampleComponent + }, { path: 'tabs-routing', component: TabsRoutingSampleComponent, @@ -393,6 +512,10 @@ export const appRoutes: Routes = [ path: 'toast', component: ToastSampleComponent }, + { + path: 'toast-showcase', + component: ToastShowcaseSampleComponent + }, { path: 'virtualForDirective', component: VirtualForSampleComponent @@ -509,6 +632,10 @@ export const appRoutes: Routes = [ path: 'buttonGroup', component: ButtonGroupSampleComponent }, + { + path: 'buttonGroup-showcase', + component: ButtonGroupShowcaseSampleComponent + }, { path: 'gridColumnGroups', component: GridColumnGroupsSampleComponent @@ -560,10 +687,15 @@ export const appRoutes: Routes = [ { path: 'gridFinJS', component: MainComponent - }, { + }, + { path: 'tree', component: TreeSampleComponent }, + { + path: 'tree-showcase', + component: TreeShowcaseSampleComponent + }, { path: 'gridUpdates', component: GridUpdatesComponent @@ -676,6 +808,10 @@ export const appRoutes: Routes = [ path: 'stepper', component: StepperSampleComponent }, + { + path: 'stepper-showcase', + component: IgxStepperShowcaseSampleComponent + }, { path: 'labelDirective', component: LabelSampleComponent diff --git a/src/app/avatar-showcase/avatar-showcase.sample.html b/src/app/avatar-showcase/avatar-showcase.sample.html new file mode 100644 index 00000000000..0d4059f60fe --- /dev/null +++ b/src/app/avatar-showcase/avatar-showcase.sample.html @@ -0,0 +1,22 @@ +

Angular vs WebComponents Avatar

+
+
+
+ Angular Avatars +

Avatar with an image

+ + +

Avatar with initials

+ +
+ +
+ WebComponents Avatars +

Avatar with an image

+ + +

Avatar with initials

+ +
+
+
diff --git a/src/app/avatar-showcase/avatar-showcase.sample.scss b/src/app/avatar-showcase/avatar-showcase.sample.scss new file mode 100644 index 00000000000..7609447c847 --- /dev/null +++ b/src/app/avatar-showcase/avatar-showcase.sample.scss @@ -0,0 +1,11 @@ +.avatars-wrapper { + display: grid; + grid-template-columns: repeat(2, 1fr); +} + +.avatars { + display: grid; + grid-auto-flow: row; + justify-items: center; + gap: 12px; +} diff --git a/src/app/avatar-showcase/avatar-showcase.sample.ts b/src/app/avatar-showcase/avatar-showcase.sample.ts new file mode 100644 index 00000000000..78837ff6670 --- /dev/null +++ b/src/app/avatar-showcase/avatar-showcase.sample.ts @@ -0,0 +1,71 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { IgxAvatarComponent } from 'igniteui-angular'; +import { CommonModule } from '@angular/common'; +import { defineComponents, IgcAvatarComponent } from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcAvatarComponent); + +@Component({ + selector: 'app-avatar-showcase-sample', + styleUrls: ['avatar-showcase.sample.scss'], + templateUrl: `avatar-showcase.sample.html`, + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [CommonModule, IgxAvatarComponent] +}) + +export class AvatarShowcaseSampleComponent implements OnInit { + public panelConfig: PropertyPanelConfig = { + size: { + control: { + type: 'button-group', + options: ['small', 'medium', 'large'], + defaultValue: 'medium' + } + }, + shape: { + control: { + type: 'radio-inline', + options: ['circle', 'rounded', 'square'], + defaultValue: 'square' + } + }, + src: { + label: 'The image source to use', + control: { + type: 'text', + defaultValue: 'https://images.unsplash.com/photo-1514041790697-53f1f86214d2?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=b7ac79503fbe78855a346c8d814f95ba&auto=format&fit=crop&w=1650&q=80' + } + }, + initials: { + control: { + type: 'text', + defaultValue: 'RK' + } + } + } + + constructor(protected propertyChangeService: PropertyChangeService) {} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + protected get src() { + return this.propertyChangeService.getProperty('src'); + } + + protected get shape() { + return this.propertyChangeService.getProperty('shape'); + } + + protected get initials() { + return this.propertyChangeService.getProperty('initials'); + } + + protected get size() { + return this.propertyChangeService.getProperty('size'); + } +} diff --git a/src/app/badge-showcase/badge-showcase.sample.html b/src/app/badge-showcase/badge-showcase.sample.html new file mode 100644 index 00000000000..4aa27dadd56 --- /dev/null +++ b/src/app/badge-showcase/badge-showcase.sample.html @@ -0,0 +1,12 @@ +

Angular vs WebComponents Badge

+
+
+ Angular Badge + +
+ +
+ WC Badge + 8 +
+
diff --git a/src/app/badge-showcase/badge-showcase.sample.scss b/src/app/badge-showcase/badge-showcase.sample.scss new file mode 100644 index 00000000000..1b6386692ee --- /dev/null +++ b/src/app/badge-showcase/badge-showcase.sample.scss @@ -0,0 +1,14 @@ +.wrapper { + display: grid; + grid-template-columns: repeat(2, 1fr); +} + +.badges { + display: flex; + flex-direction: column; + align-items: center; + + > * { + margin-bottom: 8px; + } +} diff --git a/src/app/badge-showcase/badge-showcase.sample.ts b/src/app/badge-showcase/badge-showcase.sample.ts new file mode 100644 index 00000000000..ac3582e13f7 --- /dev/null +++ b/src/app/badge-showcase/badge-showcase.sample.ts @@ -0,0 +1,70 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { IgxBadgeComponent } from 'igniteui-angular'; +import { defineComponents, IgcBadgeComponent } from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcBadgeComponent); + +@Component({ + selector: 'app-badge-showcase-sample', + styleUrls: ['badge-showcase.sample.scss'], + templateUrl: 'badge-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxBadgeComponent] +}) + +export class BadgeShowcaseSampleComponent implements OnInit { + public panelConfig: PropertyPanelConfig = { + shape: { + control: { + type: 'button-group', + options: ['rounded', 'square'], + defaultValue: 'rounded' + } + }, + variant: { + control: { + type: 'select', + options: ['default', 'info', 'success', 'warning', 'error'] + } + }, + outlined: { + control: { + type: 'boolean', + } + } + }; + + constructor(protected propertyChangeService: PropertyChangeService) {} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + private variantMap = { + default: 'primary', + info: 'info', + success: 'success', + warning: 'warning', + error: 'danger', + }; + + public get angularVariant() { + return this.propertyChangeService.getProperty('variant'); + } + + public get wcVariant() { + const variant = this.propertyChangeService.getProperty('variant'); + return this.variantMap[variant] || 'primary'; + } + + public get shape() { + return this.propertyChangeService.getProperty('shape'); + } + + public get outlined() { + return this.propertyChangeService.getProperty('outlined'); + } +} + diff --git a/src/app/banner-showcase/banner-showcase.sample.html b/src/app/banner-showcase/banner-showcase.sample.html new file mode 100644 index 00000000000..65741da5801 --- /dev/null +++ b/src/app/banner-showcase/banner-showcase.sample.html @@ -0,0 +1,33 @@ +

Angular vs WebComponents Banner

+
+ + + + + Your connections is not private! + lock + +
+ +
+ + + + + Your connections is not private! + +
+ Dismiss +
+
+
+ +
+ + +
+ diff --git a/src/app/banner-showcase/banner-showcase.sample.scss b/src/app/banner-showcase/banner-showcase.sample.scss new file mode 100644 index 00000000000..ffe4e8efbee --- /dev/null +++ b/src/app/banner-showcase/banner-showcase.sample.scss @@ -0,0 +1,9 @@ +:host, +.sample-actions { + display: flex; + gap: 20px; +} + +:host { + flex-direction: column; +} diff --git a/src/app/banner-showcase/banner-showcase.sample.ts b/src/app/banner-showcase/banner-showcase.sample.ts new file mode 100644 index 00000000000..ab8b17b9d7f --- /dev/null +++ b/src/app/banner-showcase/banner-showcase.sample.ts @@ -0,0 +1,48 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild } from '@angular/core'; +import { useAnimation } from '@angular/animations'; +import { IgxBannerActionsDirective, IgxBannerComponent, IgxFlexDirective, IgxIconComponent, IgxLayoutDirective, IgxRippleDirective, IgxNavbarModule, IgxButtonModule } from 'igniteui-angular'; +import { growVerIn, growVerOut } from 'igniteui-angular/animations'; +import { defineComponents, IgcBannerComponent, IgcIconComponent, registerIconFromText } from "igniteui-webcomponents"; + +defineComponents(IgcBannerComponent, IgcIconComponent); + +const lock = '' +registerIconFromText("lock", lock); + +@Component({ + selector: 'app-banner-showcase-sample', + templateUrl: `banner-showcase.sample.html`, + styleUrls: [`banner-showcase.sample.scss`], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxBannerComponent, IgxIconComponent, IgxBannerActionsDirective, IgxRippleDirective, IgxLayoutDirective, IgxFlexDirective, IgxNavbarModule, IgxButtonModule] +}) +export class BannerShowcaseSampleComponent { + @ViewChild('bannerNoSafeConnection', { static: true }) + private bannerNoSafeConnection: IgxBannerComponent; + + public animationSettings = { openAnimation: useAnimation(growVerIn, { + params: { + duration: '2000ms' + } + }), closeAnimation: useAnimation(growVerOut)}; + public toggle() { + if (this.bannerNoSafeConnection.collapsed) { + this.bannerNoSafeConnection.open(); + } else { + this.bannerNoSafeConnection.close(); + } + } + + public onOpen(ev) { + console.log('Open', ev); + } + + public onClose(ev) { + console.log('Close', ev); + } + + public onButtonClick(ev) { + console.log('Button click', ev); + } +} diff --git a/src/app/button-showcase/button-showcase.sample.html b/src/app/button-showcase/button-showcase.sample.html new file mode 100644 index 00000000000..818e5421aaa --- /dev/null +++ b/src/app/button-showcase/button-showcase.sample.html @@ -0,0 +1,15 @@ +
+
+

Angular Button

+

WC Button

+
+ +
+
+ +
+
+ Button +
+
+
diff --git a/src/app/button-showcase/button-showcase.sample.scss b/src/app/button-showcase/button-showcase.sample.scss new file mode 100644 index 00000000000..e0ec01a5c76 --- /dev/null +++ b/src/app/button-showcase/button-showcase.sample.scss @@ -0,0 +1,21 @@ +.columns-container{ + margin: 24px 16px; +} + +.title { + display: grid; + grid-template-columns: repeat(2, 1fr); + justify-items: center; +} + +.buttons-sample { + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-auto-rows: minmax(80px, auto); + align-items: center; +} + +.button-sample { + justify-self: center; +} + diff --git a/src/app/button-showcase/button-showcase.sample.ts b/src/app/button-showcase/button-showcase.sample.ts new file mode 100644 index 00000000000..687bb77ee6f --- /dev/null +++ b/src/app/button-showcase/button-showcase.sample.ts @@ -0,0 +1,61 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewEncapsulation, OnInit } from '@angular/core'; +import { IgxButtonDirective, IgxButtonGroupComponent, IgxIconButtonDirective, IgxIconComponent, IgxRippleDirective } from 'igniteui-angular'; +import { defineComponents, IgcButtonComponent, IgcIconButtonComponent, registerIconFromText} from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcButtonComponent, IgcIconButtonComponent); + +const favorite = '' +registerIconFromText("favorite", favorite ); + +@Component({ + selector: 'app-button-showcase-sample', + styleUrls: ['button-showcase.sample.scss'], + templateUrl: 'button-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + encapsulation: ViewEncapsulation.None, + standalone: true, + imports: [IgxButtonDirective, IgxIconComponent, IgxButtonGroupComponent, IgxIconButtonDirective, IgxRippleDirective] +}) +export class ButtonShowcaseSampleComponent implements OnInit { + public panelConfig: PropertyPanelConfig = { + size: { + control: { + type: "button-group", + options: ['small', 'medium', 'large'], + } + }, + variant: { + control: { + type: "button-group", + options: ['flat', 'contained', 'outlined', 'fab'], + defaultValue: 'flat' + } + }, + disabled: { + control: { + type: "boolean", + defaultValue: false + } + } + } + + constructor(protected propertyChangeService: PropertyChangeService) {} + + public ngOnInit(): void { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + protected get size() { + return this.propertyChangeService.getProperty('size'); + } + + protected get variant() { + return this.propertyChangeService.getProperty('variant'); + } + + protected get disabled() { + return this.propertyChangeService.getProperty('disabled'); + } +} diff --git a/src/app/buttonGroup-showcase/buttonGroup-showcase.sample.html b/src/app/buttonGroup-showcase/buttonGroup-showcase.sample.html new file mode 100644 index 00000000000..843c596dc9f --- /dev/null +++ b/src/app/buttonGroup-showcase/buttonGroup-showcase.sample.html @@ -0,0 +1,32 @@ +
+
+

Angular ButtonGroup

+ + + +
+ +
+

WC ButtonGroup

+ + + {{ city.label }} + + +
+
diff --git a/src/app/buttonGroup-showcase/buttonGroup-showcase.sample.ts b/src/app/buttonGroup-showcase/buttonGroup-showcase.sample.ts new file mode 100644 index 00000000000..71a6b5ea770 --- /dev/null +++ b/src/app/buttonGroup-showcase/buttonGroup-showcase.sample.ts @@ -0,0 +1,96 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { NgFor } from '@angular/common'; +import { IgxButtonDirective, IgxButtonGroupComponent, IgxIconComponent, IgxLayoutDirective } from 'igniteui-angular'; +import { defineComponents, IgcButtonGroupComponent, IgcToggleButtonComponent } from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcButtonGroupComponent, IgcToggleButtonComponent); + +@Component({ + selector: 'app-buttongroup-showcase-sample', + templateUrl: 'buttonGroup-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxButtonGroupComponent, IgxButtonDirective, IgxIconComponent, NgFor, IgxLayoutDirective] +}) + +export class ButtonGroupShowcaseSampleComponent implements OnInit { + public cities = []; + + public ngOnInit(): void { + this.cities = [ + { + disabled: false, + label: 'Sofia', + selected: true, + togglable: false + }, + { + disabled: false, + label: 'London', + selected: false + }, + { + disabled: false, + label: 'New York', + selected: false + }, + { + disabled: true, + label: 'Tokyo', + selected: false + } + ]; + + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + public panelConfig: PropertyPanelConfig = { + alignment: { + control: { + type: 'button-group', + options: ['horizontal', 'vertical'], + defaultValue: 'horizontal' + } + }, + selection: { + control: { + type: 'select', + options: ['single', 'singleRequired', 'multiple'], + defaultValue: 'single' + } + }, + disabled: { + control: { + type: 'boolean', + defaultValue: false + } + } + } + + constructor(protected propertyChangeService: PropertyChangeService) {} + + private selectionMap = { + single: 'single', + multiple: 'multi', + singleRequired: 'single-required' + }; + + protected get angularSelection() { + return this.propertyChangeService.getProperty('selection'); + } + + public get wcSelection() { + const selection = this.propertyChangeService.getProperty('selection'); + return this.selectionMap[selection]; + } + + protected get disabled() { + return this.propertyChangeService.getProperty('disabled') + } + + protected get alignment() { + return this.propertyChangeService.getProperty('alignment') + } +} diff --git a/src/app/calendar-showcase/calendar-showcase.sample.html b/src/app/calendar-showcase/calendar-showcase.sample.html new file mode 100644 index 00000000000..980e02a1c61 --- /dev/null +++ b/src/app/calendar-showcase/calendar-showcase.sample.html @@ -0,0 +1,81 @@ +
+
+
+ Angular Calendar + + > + +
+ +
+ WC Calendar + + +
+
+ + +
+ + + + + + + + + + + + +
+
+
diff --git a/src/app/calendar-showcase/calendar-showcase.sample.scss b/src/app/calendar-showcase/calendar-showcase.sample.scss new file mode 100644 index 00000000000..f41d4368b6a --- /dev/null +++ b/src/app/calendar-showcase/calendar-showcase.sample.scss @@ -0,0 +1,34 @@ +.calendar-wrapper { + flex-basis: 100px; + display: flex; + flex-direction: column; + flex-grow: 1; + + strong { + display: block; + text-align: center; + padding: 10px; + } +} + +.preview { + display: flex; + overflow: hidden; + height: 100%; + + &__sample { + display: flex; + flex-wrap: wrap; + padding: 2rem; + gap: 2rem; + overflow: auto; + flex-grow: 1; + } +} + +.custom-controls { + > *:not(label) { + display: block; + margin-bottom: 16px; + } +} diff --git a/src/app/calendar-showcase/calendar-showcase.sample.ts b/src/app/calendar-showcase/calendar-showcase.sample.ts new file mode 100644 index 00000000000..fc48a4d05b3 --- /dev/null +++ b/src/app/calendar-showcase/calendar-showcase.sample.ts @@ -0,0 +1,301 @@ +import { + Component, + CUSTOM_ELEMENTS_SCHEMA, + OnInit, + TemplateRef, + ViewChild, +} from "@angular/core"; +import { NgFor, DatePipe, DATE_PIPE_DEFAULT_OPTIONS } from "@angular/common"; +import { FormsModule } from "@angular/forms"; +import { + IgxButtonDirective, + IgxButtonGroupComponent, + IgxDateRangePickerModule, + IgxCalendarComponent, + IgxCardComponent, + IgxHintDirective, + IgxIconComponent, + IgxInputDirective, + IgxInputGroupComponent, + IgxLabelDirective, + IgxRippleDirective, + IgxSwitchComponent, + IViewDateChangeEventArgs, + IgxCalendarView, + IFormattingOptions, + DateRange, + DateRangeDescriptor, + DateRangeType, +} from "igniteui-angular"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +import { defineComponents, IgcCalendarComponent } from "igniteui-webcomponents"; + +defineComponents(IgcCalendarComponent); + +@Component({ + selector: "app-calendar-showcase-sample", + templateUrl: "calendar-showcase.sample.html", + styleUrls: ["calendar-showcase.sample.scss"], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + providers: [ + { + provide: DATE_PIPE_DEFAULT_OPTIONS, + useValue: { dateFormat: 'longDate', } + } + ], + imports: [ + IgxButtonDirective, + IgxRippleDirective, + IgxDateRangePickerModule, + IgxCardComponent, + IgxCalendarComponent, + IgxButtonGroupComponent, + IgxInputGroupComponent, + IgxLabelDirective, + IgxInputDirective, + IgxHintDirective, + FormsModule, + IgxSwitchComponent, + IgxIconComponent, + NgFor, + DatePipe, + ], +}) +export class CalendarShowcaseSampleComponent implements OnInit { + @ViewChild('customControls', { static: true }) public customControlsTemplate!: TemplateRef; + private _today = new Date(); + + private _formatOptions: IFormattingOptions = { + day: "numeric", + month: "long", + weekday: "narrow", + year: "numeric", + }; + + public panelConfig: PropertyPanelConfig = { + locale: { + label: 'Change Locale', + control: { + type: 'button-group', + options: ['EN', 'BG', 'DE', 'FR', 'JP'], + defaultValue: 'EN' + } + }, + weekStart: { + label: 'Week Start', + control: { + type: 'button-group', + options: ['monday', 'sunday'], + defaultValue: 'monday' + } + }, + selection: { + control: { + type: 'button-group', + options: ['single', 'multiple', 'range'], + defaultValue: 'single' + } + }, + headerOrientation: { + label: 'Header Orientation', + control: { + type: 'button-group', + options: ['horizontal', 'vertical'], + defaultValue: 'horizontal' + } + }, + viewOrientation: { + label: 'View Orientation', + control: { + type: 'button-group', + options: ['horizontal', 'vertical'], + defaultValue: 'horizontal' + } + }, + hideHeader: { + label: 'Hide Header', + control: { + type: 'boolean', + defaultValue: false + } + }, + hideOutsideDays: { + label: 'Hide Outside Days', + control: { + type: 'boolean', + defaultValue: false + } + }, + showWeekNumbers: { + label: 'Show Week Numbers', + control: { + type: 'boolean', + defaultValue: false + } + }, + monthsViewNumber: { + label: 'Number of Months', + control: { + type: 'number', + min: 1, + max: 4, + defaultValue: 1 + } + } + } + + constructor(protected propertyChangeService: PropertyChangeService) { } + + private weekStartMap = { + monday: 1, + sunday: 7 + }; + + private selectionMap = { + single: 'single', + multiple: 'multi', + range: 'range' + }; + + protected get locale() { + return this.propertyChangeService.getProperty('locale'); + } + + protected get weekStartWC() { + return this.propertyChangeService.getProperty('weekStart') || 'monday'; + } + + protected get weekStartAngular() { + const weekStart = this.propertyChangeService.getProperty('weekStart') || 'monday'; + return this.weekStartMap[weekStart]; + } + + protected get selectionWC() { + return this.propertyChangeService.getProperty('selection'); + } + + protected get selectionAngular() { + const selection = this.propertyChangeService.getProperty('selection'); + return this.selectionMap[selection]; + } + + protected get headerOrientation() { + return this.propertyChangeService.getProperty('headerOrientation'); + } + + protected get viewOrientation() { + return this.propertyChangeService.getProperty('viewOrientation'); + } + + protected get hideHeader() { + return this.propertyChangeService.getProperty('hideHeader'); + } + + protected get hideOutsideDays() { + return this.propertyChangeService.getProperty('hideOutsideDays'); + } + + protected get showWeekNumbers() { + return this.propertyChangeService.getProperty('showWeekNumbers'); + } + + protected get monthsViewNumber() { + return this.propertyChangeService.getProperty('monthsViewNumber'); + } + + public ngOnInit(): void { + this.propertyChangeService.setPanelConfig(this.panelConfig); + this.propertyChangeService.setCustomControls(this.customControlsTemplate); + } + + protected onSelection(event: Date | Date[]) { + console.log(`Selected Date(s): ${event}`); + } + + protected viewDateChanged(event: IViewDateChangeEventArgs) { + console.table(event); + } + + protected activeViewChanged(view: IgxCalendarView) { + console.log(`Selected View: ${view}`); + } + + protected set formatOptions(value: IFormattingOptions) { + this._formatOptions = value; + } + + protected get formatOptions(): IFormattingOptions { + return this._formatOptions; + } + + protected setWeekDayFormat(format: IFormattingOptions["weekday"] | string) { + this.formatOptions = { + ...this.formatOptions, + weekday: format as IFormattingOptions["weekday"], + }; + } + + protected setMonthFormat(format: IFormattingOptions["month"] | string) { + this.formatOptions = { + ...this.formatOptions, + month: format as IFormattingOptions["month"], + }; + } + + protected disabledDates = [ + { + type: DateRangeType.Specific, + dateRange: [ + new Date(this._today.getFullYear(), this._today.getMonth(), 0), + new Date(this._today.getFullYear(), this._today.getMonth(), 20), + new Date(this._today.getFullYear(), this._today.getMonth(), 21), + ], + }, + ]; + + protected mySpecialDates = [ + { + type: DateRangeType.Specific, + dateRange: [ + new Date(this._today.getFullYear(), this._today.getMonth(), 1), + new Date(this._today.getFullYear(), this._today.getMonth(), 3), + new Date(this._today.getFullYear(), this._today.getMonth(), 7), + ], + }, + ]; + + private _specialRange: DateRange = { + start: new Date(this._today.getFullYear(), this._today.getMonth(), 8), + end: new Date(this._today.getFullYear(), this._today.getMonth(), 10), + }; + + protected set specialRange(value: DateRange) { + this.specialDates = value; + this._specialRange = value; + }; + + protected get specialRange(): DateRange { + return this._specialRange; + } + + private _specialDates: DateRangeDescriptor[] = [{ + type: DateRangeType.Between, + dateRange: [this.specialRange.start as Date, this.specialRange.end as Date] + }] + + protected get specialDates(): DateRangeDescriptor[] { + return this._specialDates; + } + + protected set specialDates(dates: DateRange) { + this._specialDates = [ + { + type: DateRangeType.Between, + dateRange: [dates.start as Date, dates.end as Date] + } + ] + } +} diff --git a/src/app/card-showcase/card-showcase.sample.html b/src/app/card-showcase/card-showcase.sample.html new file mode 100644 index 00000000000..67c24d48447 --- /dev/null +++ b/src/app/card-showcase/card-showcase.sample.html @@ -0,0 +1,63 @@ +
+ +
+

Angular Card

+ + + + + + + +

{{ cards[0].title }}

+

{{ cards[0].subtitle }}

+
+ + +

{{ cards[0].content }}

+
+ + + + + {{icon}} + + + +
+
+ + + +
+

WC Card

+ + + + + + + + New York City + City in New York + + + + New York City comspanrises 5 boroughs sitting where the Hudson River + meets the Atlantic Ocean. At its core is Manhattan, a densely + populated borough that’s among the world’s major commercial, + financial and cultural centers. + + + + Read More + + + + + +
+ +
diff --git a/src/app/card-showcase/card-showcase.sample.scss b/src/app/card-showcase/card-showcase.sample.scss new file mode 100644 index 00000000000..2377e721531 --- /dev/null +++ b/src/app/card-showcase/card-showcase.sample.scss @@ -0,0 +1,17 @@ +.grid-container { + display: grid; + grid-template-columns: repeat(2, minmax(320px, 1fr)); + column-gap: 10px; + justify-items: center; + padding: 30px; +} + +.card { + min-width: 320px; + max-width: 320px; + margin: 10px; + + h4 { + margin-bottom: 1rem; + } +} diff --git a/src/app/card-showcase/card-showcase.sample.ts b/src/app/card-showcase/card-showcase.sample.ts new file mode 100644 index 00000000000..526cf56d28b --- /dev/null +++ b/src/app/card-showcase/card-showcase.sample.ts @@ -0,0 +1,79 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewEncapsulation } from '@angular/core'; +import { NgFor } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IgxAvatarComponent, IgxButtonDirective, IgxCardActionsComponent, IgxCardComponent, IgxCardContentDirective, IgxCardHeaderComponent, IgxCardHeaderSubtitleDirective, IgxCardHeaderTitleDirective, IgxCardMediaDirective, IgxIconButtonDirective, IgxIconComponent, IgxRippleDirective } from 'igniteui-angular'; +import { defineComponents, IgcCardComponent, IgcAvatarComponent, IgcButtonComponent, IgcIconButtonComponent, registerIconFromText} from "igniteui-webcomponents"; + +defineComponents(IgcCardComponent, IgcAvatarComponent, IgcButtonComponent, IgcIconButtonComponent); + +const favorite = '' +const share = '' +const bookmark = '' + +registerIconFromText("favorite", favorite); +registerIconFromText("share", share); +registerIconFromText("bookmark", bookmark); + +export interface ICard { + title: string; + subtitle: string; + content: string; + imageUrl: string; + avatarUrl: string; + unit: string; + buttons: string[]; + chip: string[]; + icons: string[]; +} + +const cardFactory = (params: any): ICard => ({ + title: params.title || 'Card Title', + subtitle: params.subtitle || 'Card Subtitle', + unit: params.unit || '°C', + content: params.content || 'Some card content should be place here.', + imageUrl: params.imageUrl || 'images/card/media/placeholder.jpg', + avatarUrl: params.avatarUrl || 'images/card/avatars/rupert_stadler.jpg', + buttons: params.buttons || ['ACTION1', 'ACTION2'], + chip: params.chip || ['ACTION1', 'ACTION2', 'ACTION3'], + icons: params.icons || ['favorite', 'bookmark', 'share'] +}); + +@Component({ + encapsulation: ViewEncapsulation.None, + selector: 'app-card-showcase-sample', + styleUrls: ['card-showcase.sample.scss'], + templateUrl: 'card-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [ + NgFor, + FormsModule, + IgxCardComponent, + IgxCardMediaDirective, + IgxCardHeaderComponent, + IgxCardContentDirective, + IgxCardActionsComponent, + IgxButtonDirective, + IgxRippleDirective, + IgxIconComponent, + IgxAvatarComponent, + IgxCardHeaderTitleDirective, + IgxCardHeaderSubtitleDirective, + IgxIconButtonDirective + ] +}) +export class CardShowcaseSampleComponent { + public cards = [ + cardFactory({ + content: `New York City comprises 5 boroughs sitting where the + Hudson River meets the Atlantic Ocean. At its core is Manhattan, + a densely populated borough that’s among the world’s major commercial, + financial and cultural centers.`, + avatarUrl: 'assets/images/card/avatars/statue_of_liberty.jpg', + icons: ['favorite', 'bookmark', 'share'], + imageUrl: 'assets/images/card/media/ny.jpg', + subtitle: 'City in New York', + title: 'New York City' + }), + ]; +} diff --git a/src/app/carousel-showcase/carousel-showcase.sample.html b/src/app/carousel-showcase/carousel-showcase.sample.html new file mode 100644 index 00000000000..240a2f3839c --- /dev/null +++ b/src/app/carousel-showcase/carousel-showcase.sample.html @@ -0,0 +1,35 @@ +
+
+

Angular Carousel

+ + + + + + +

WC Carousel

+ + + + + +
+
diff --git a/src/app/carousel-showcase/carousel-showcase.sample.scss b/src/app/carousel-showcase/carousel-showcase.sample.scss new file mode 100644 index 00000000000..da73c14b961 --- /dev/null +++ b/src/app/carousel-showcase/carousel-showcase.sample.scss @@ -0,0 +1,5 @@ +.sample-wrapper { + igx-carousel { + margin-bottom: 64px; + } +} diff --git a/src/app/carousel-showcase/carousel-showcase.sample.ts b/src/app/carousel-showcase/carousel-showcase.sample.ts new file mode 100644 index 00000000000..fe015bee576 --- /dev/null +++ b/src/app/carousel-showcase/carousel-showcase.sample.ts @@ -0,0 +1,182 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { NgFor, NgIf } from '@angular/common'; +import { IgxButtonDirective, IgxCarouselComponent, IgxCarouselIndicatorDirective, IgxDropDownComponent, IgxDropDownItemComponent, IgxDropDownItemNavigationDirective, IgxSlideComponent, IgxSwitchComponent, IgxToggleActionDirective } from 'igniteui-angular'; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; +import { + IgcButtonComponent, + IgcCarouselComponent, + IgcIconComponent, + IgcInputComponent, + IgcTextareaComponent, + defineComponents, + registerIconFromText, + } from 'igniteui-webcomponents'; + + defineComponents( + IgcCarouselComponent, + IgcIconComponent, + IgcInputComponent, + IgcButtonComponent, + IgcTextareaComponent + ); + + const icons = [ + { + name: 'previous', + text: '', + }, + { + name: 'next', + text: ` + + `, + }, + ]; + + icons.forEach((icon) => { + registerIconFromText(icon.name, icon.text, 'material'); + }); + +@Component({ + selector: 'app-carousel-showcase-sample', + styleUrls: ['carousel-showcase.sample.scss'], + templateUrl: 'carousel-showcase.sample.html', + standalone: true, + schemas: [CUSTOM_ELEMENTS_SCHEMA], + imports: [IgxSwitchComponent, IgxButtonDirective, IgxToggleActionDirective, IgxDropDownItemNavigationDirective, IgxDropDownComponent, NgFor, IgxDropDownItemComponent, IgxCarouselComponent, IgxSlideComponent, IgxCarouselIndicatorDirective, NgIf] +}) +export class CarouselShowcaseSampleComponent implements OnInit { + public panelConfig: PropertyPanelConfig = { + disableLoop: { + label: 'Disable Loop', + control: { + type: 'boolean' + } + }, + disablePauseOnInteraction: { + label: 'Disable Pause on Interaction', + control: { + type: 'boolean' + } + }, + hideNavigation: { + label: 'Hide Navigation', + control: { + type: 'boolean' + } + }, + hideIndicators: { + label: 'Hide Indicator', + control: { + type: 'boolean' + } + }, + vertical: { + control: { + type: 'boolean', + defaultValue: false + } + }, + interval: { + control: { + type: 'number', + min: 500 + } + }, + animationType: { + label: 'Animation Type', + control: { + type: 'button-group', + options: ['slide', 'fade', 'none'], + defaultValue: 'slide' + } + }, + indicatorsOrientation: { + label: 'Indicators Orientation', + control: { + type: 'button-group', + options: ['start', 'end'], + defaultValue: 'end' + } + }, + maximumIndicatorsCount: { + label: 'Maximum Indicators Count', + control: { + type: 'number', + defaultValue: 10 + } + } + } + + protected get disableLoop(){ + return this.propertyChangeService.getProperty('disableLoop'); + } + + protected get disablePauseOnInteraction(){ + return this.propertyChangeService.getProperty('disablePauseOnInteraction'); + } + + protected get hideIndicators(){ + return this.propertyChangeService.getProperty('hideIndicators'); + } + + protected get hideNavigation(){ + return this.propertyChangeService.getProperty('hideNavigation'); + } + + protected get vertical(){ + return this.propertyChangeService.getProperty('vertical'); + } + + protected get interval(){ + return this.propertyChangeService.getProperty('interval'); + } + + protected get animationType(){ + return this.propertyChangeService.getProperty('animationType'); + } + + private indicatorsOrientationMap = { + start: 'top', + end: 'bottom', + }; + + protected get angularIndicatorsOrientation() { + const orientation = this.propertyChangeService.getProperty('indicatorsOrientation'); + return this.indicatorsOrientationMap[orientation] || 'bottom'; + } + + protected get wcIndicatorsOrientation() { + return this.propertyChangeService.getProperty('indicatorsOrientation'); + } + + protected get maximumIndicatorsCount() { + return this.propertyChangeService.getProperty('maximumIndicatorsCount'); + } + + public slides = []; + + constructor(protected propertyChangeService: PropertyChangeService) { + this.addNewSlide(); + } + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + public addNewSlide() { + this.slides.push( + {image: 'assets/images/carousel/slide1@x2.jpg', active: true}, + {image: 'assets/images/carousel/slide2@x2.jpg', active: false}, + {image: 'assets/images/carousel/slide3@x2.jpg', active: false} + ); + } +} diff --git a/src/app/checkbox-showcase/checkbox-showcase.sample.html b/src/app/checkbox-showcase/checkbox-showcase.sample.html new file mode 100644 index 00000000000..1f0cd5031f3 --- /dev/null +++ b/src/app/checkbox-showcase/checkbox-showcase.sample.html @@ -0,0 +1,33 @@ +
+
+

Angular Checkbox

+ + + Label + +
+ +
+

WC Checkbox

+ + + Label + +
+
diff --git a/src/app/checkbox-showcase/checkbox-showcase.sample.scss b/src/app/checkbox-showcase/checkbox-showcase.sample.scss new file mode 100644 index 00000000000..9df693180a4 --- /dev/null +++ b/src/app/checkbox-showcase/checkbox-showcase.sample.scss @@ -0,0 +1,4 @@ +.wrapper { + display: inline-grid; + grid-template-columns: 1fr 1fr; +} diff --git a/src/app/checkbox-showcase/checkbox-showcase.sample.ts b/src/app/checkbox-showcase/checkbox-showcase.sample.ts new file mode 100644 index 00000000000..6cbce85e2ee --- /dev/null +++ b/src/app/checkbox-showcase/checkbox-showcase.sample.ts @@ -0,0 +1,106 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { IgxCheckboxComponent } from 'igniteui-angular'; +import { defineComponents, IgcCheckboxComponent} from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcCheckboxComponent); + +@Component({ + selector: 'app-checkbox-showcase-sample', + styleUrls: ['checkbox-showcase.sample.scss'], + templateUrl: 'checkbox-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxCheckboxComponent] +}) +export class CheckboxShowcaseSampleComponent implements OnInit { + public panelConfig : PropertyPanelConfig = { + indeterminate: { + control: { + type: 'boolean', + defaultValue: false + } + }, + required: { + control: { + type: 'boolean', + defaultValue: false + } + }, + disabled: { + control: { + type: 'boolean', + defaultValue: false + } + }, + invalid: { + control: { + type: 'boolean', + defaultValue: false + } + }, + checked: { + control: { + type: 'boolean', + defaultValue: false + } + }, + labelPosition: { + control: { + type: 'button-group', + options: ['before', 'after'], + defaultValue: 'after' + } + }, + name: { + control: { + type: 'text' + } + }, + value: { + control: { + type: 'text' + } + }, + } + + constructor(private propertyChangeService : PropertyChangeService) {} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + protected get indeterminate() { + return this.propertyChangeService.getProperty('indeterminate'); + } + + protected get required() { + return this.propertyChangeService.getProperty('required'); + } + + protected get disabled() { + return this.propertyChangeService.getProperty('disabled'); + } + + protected get invalid() { + return this.propertyChangeService.getProperty('invalid'); + } + + protected get checked() { + return this.propertyChangeService.getProperty('checked'); + } + + protected get labelPosition() { + return this.propertyChangeService.getProperty('labelPosition'); + } + + protected get name() { + return this.propertyChangeService.getProperty('name'); + } + + protected get value() { + return this.propertyChangeService.getProperty('value'); + } + +} diff --git a/src/app/chips-showcase/chips-showcase.sample.html b/src/app/chips-showcase/chips-showcase.sample.html new file mode 100644 index 00000000000..87b8678e573 --- /dev/null +++ b/src/app/chips-showcase/chips-showcase.sample.html @@ -0,0 +1,72 @@ + diff --git a/src/app/chips-showcase/chips-showcase.sample.scss b/src/app/chips-showcase/chips-showcase.sample.scss new file mode 100644 index 00000000000..49fa8c1b01f --- /dev/null +++ b/src/app/chips-showcase/chips-showcase.sample.scss @@ -0,0 +1,25 @@ +h6 { + margin-top: 24px; +} + +.preview__sample { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 1rem; + gap: 1rem; + flex: 1; +} + +.custom-controls { + igx-switch { + display: flex; + align-items: center; + margin-bottom: 16px; + + label { + margin: 0; + } + } +} diff --git a/src/app/chips-showcase/chips-showcase.sample.ts b/src/app/chips-showcase/chips-showcase.sample.ts new file mode 100644 index 00000000000..1afa15169cf --- /dev/null +++ b/src/app/chips-showcase/chips-showcase.sample.ts @@ -0,0 +1,138 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { NgFor, NgIf } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { + IChipsAreaSelectEventArgs, + IgxAvatarComponent, + IgxButtonGroupComponent, + IgxChipComponent, + IgxChipsAreaComponent, + IgxDropDirective, + IgxIconComponent, + IgxPrefixDirective, + IgxSelectComponent, + IgxSelectItemComponent, + IgxSuffixDirective, + IgxSwitchComponent, + IgxCircularProgressBarComponent, +} from 'igniteui-angular'; +import { SizeSelectorComponent } from '../size-selector/size-selector.component'; +import { defineComponents, IgcChipComponent, IgcAvatarComponent, IgcButtonComponent, IgcIconButtonComponent, IgcCircularProgressComponent} from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcChipComponent, IgcAvatarComponent, IgcButtonComponent, IgcIconButtonComponent, IgcCircularProgressComponent); + +@Component({ + selector: 'app-chips-showcase-sample', + styleUrls: ['chips-showcase.sample.scss', '../app.component.scss'], + templateUrl: 'chips-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [ + IgxButtonGroupComponent, + IgxChipComponent, + IgxCircularProgressBarComponent, + IgxIconComponent, + IgxPrefixDirective, + IgxSelectComponent, + IgxSelectItemComponent, + IgxSuffixDirective, + IgxSwitchComponent, + IgxChipsAreaComponent, + NgFor, + NgIf, + FormsModule, + IgxAvatarComponent, + IgxDropDirective, + SizeSelectorComponent + ] +}) +export class ChipsShowcaseSampleComponent implements OnInit { + @ViewChild('customControls', { static: true }) public customControlsTemplate!: TemplateRef; + + public panelConfig : PropertyPanelConfig = { + variant: { + control: { + type: 'select', + options: ['default', 'primary', 'info', 'success', 'warning', 'danger'] + } + }, + size: { + control: { + type: 'button-group', + options: ['small', 'medium', 'large'], + defaultValue: 'large' + } + }, + disabled: { + control: { + type: 'boolean', + defaultValue: false + } + }, + selectable: { + control: { + type: 'boolean', + defaultValue: false + } + }, + selected: { + control: { + type: 'boolean', + defaultValue: false + } + }, + removable: { + control: { + type: 'boolean', + defaultValue: false + } + }, + } + + constructor(protected propertyChangeService: PropertyChangeService){} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + this.propertyChangeService.setCustomControls(this.customControlsTemplate) + } + + protected get variant() { + return this.propertyChangeService.getProperty('variant'); + } + + protected get size() { + return this.propertyChangeService.getProperty('size'); + } + + protected get disabled() { + return this.propertyChangeService.getProperty('disabled'); + } + + protected get removable() { + return this.propertyChangeService.getProperty('removable'); + } + + protected get selectable() { + return this.propertyChangeService.getProperty('selectable'); + } + + protected get selected() { + return this.propertyChangeService.getProperty('selected'); + } + + public hasSuffix = false; + public hasPrefix = false; + public hasAvatar = false; + public hasProgressbar = false; + public customIcons = false; + + public removeChip(chip: IgxChipComponent) { + chip.nativeElement.remove(); + } + + public onChipsSelected(event: IChipsAreaSelectEventArgs) { + console.log(event); + } +} diff --git a/src/app/combo-showcase/combo-showcase.sample.html b/src/app/combo-showcase/combo-showcase.sample.html new file mode 100644 index 00000000000..498136e1708 --- /dev/null +++ b/src/app/combo-showcase/combo-showcase.sample.html @@ -0,0 +1,32 @@ +
+
+

Angular and WC combo next to each other

+ + {{isDisabled? 'Enable' : 'Disable'}} +
+
+ + + + Select a unique falsy value + + + Select a unique falsy value + +
+
+
+
diff --git a/src/app/combo-showcase/combo-showcase.sample.scss b/src/app/combo-showcase/combo-showcase.sample.scss new file mode 100644 index 00000000000..5a2f711549d --- /dev/null +++ b/src/app/combo-showcase/combo-showcase.sample.scss @@ -0,0 +1,56 @@ +.combo-sample { + display: flex; + flex-direction: column; + gap: 28px; + max-width: 800px; + margin: 0 auto; + padding: 32px 16px; + + &__section, + &__row { + display: flex; + gap: 16px + } + + &__row { + &--stretch { + > * { + flex: 1; + } + } + } + + &__section { + flex-direction: column; + padding: 16px; + border: 1px dashed hsla(var(--ig-gray-300)); + } + + &__form { + display: flex; + flex-direction: column; + gap: 16px; + } + + &__title { + font-weight: 600; + font-size: 20px; + letter-spacing: .4px; + margin: 0; + line-height: normal; + } + + igx-simple-combo, + igx-combo { + max-width: 100%; + min-width: 30%; + } +} + +.custom-combo-footer, +.custom-combo-header { + text-align: center; + padding: 8px 16px; + background: hsla(var(--ig-gray-100)); +} + diff --git a/src/app/combo-showcase/combo-showcase.sample.ts b/src/app/combo-showcase/combo-showcase.sample.ts new file mode 100644 index 00000000000..09a0d474035 --- /dev/null +++ b/src/app/combo-showcase/combo-showcase.sample.ts @@ -0,0 +1,63 @@ +import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { + IgxButtonGroupComponent, + IgxComboAddItemDirective, + IgxComboComponent, + IgxComboFooterDirective, + IgxComboHeaderDirective, + IgxHintDirective, + IgxIconComponent, + IgxInputDirective, + IgxInputGroupComponent, + IgxLabelDirective, + IgxPrefixDirective, + IgxSimpleComboComponent, + IgxSwitchComponent, +} from 'igniteui-angular'; +import { SizeSelectorComponent } from '../size-selector/size-selector.component'; +import { defineComponents, IgcComboComponent} from "igniteui-webcomponents"; + +defineComponents(IgcComboComponent); + +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'combo-showcase-sample', + templateUrl: './combo-showcase.sample.html', + styleUrls: ['combo-showcase.sample.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [ + IgxInputGroupComponent, + IgxInputDirective, + FormsModule, + IgxSimpleComboComponent, + IgxLabelDirective, + IgxHintDirective, + IgxComboComponent, + IgxComboHeaderDirective, + IgxComboFooterDirective, + IgxComboAddItemDirective, + IgxPrefixDirective, + IgxIconComponent, + IgxSwitchComponent, + IgxButtonGroupComponent, + SizeSelectorComponent, + ] +}) +export class ComboShowcaseSampleComponent { + public isDisabled = false; + public uniqueFalsyData: any[]; + + constructor( + public cdr: ChangeDetectorRef) { + this.uniqueFalsyData = [ + { field: 'null', value: null }, + { field: 'true', value: true }, + { field: 'false', value: false }, + { field: 'empty', value: '' }, + { field: 'undefined', value: undefined }, + { field: 'NaN', value: NaN } + ]; + } +} diff --git a/src/app/date-picker-showcase/date-picker-showcase.sample.html b/src/app/date-picker-showcase/date-picker-showcase.sample.html new file mode 100644 index 00000000000..7386843eb25 --- /dev/null +++ b/src/app/date-picker-showcase/date-picker-showcase.sample.html @@ -0,0 +1,24 @@ +
+
Angular Date Picker
+ + + + alarm + + + + + + + + +
WC Date Picker
+ + +
+ Today + Next Year + Select Today +
+
+
diff --git a/src/app/date-picker-showcase/date-picker-showcase.sample.scss b/src/app/date-picker-showcase/date-picker-showcase.sample.scss new file mode 100644 index 00000000000..b587440b294 --- /dev/null +++ b/src/app/date-picker-showcase/date-picker-showcase.sample.scss @@ -0,0 +1,8 @@ +igx-date-picker { + margin-bottom: 10px; +} + +h6 { + margin-top: 32px; + margin-bottom: 12px; +} diff --git a/src/app/date-picker-showcase/date-picker-showcase.sample.ts b/src/app/date-picker-showcase/date-picker-showcase.sample.ts new file mode 100644 index 00000000000..3fd08555d05 --- /dev/null +++ b/src/app/date-picker-showcase/date-picker-showcase.sample.ts @@ -0,0 +1,32 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { DateRangeDescriptor, DateRangeType, IgxButtonDirective, IgxDatePickerComponent, IgxIconComponent, IgxLabelDirective, IgxPickerActionsDirective, IgxRippleDirective, IgxSuffixDirective } from 'igniteui-angular'; +import { defineComponents, IgcDatePickerComponent, IgcButtonComponent, IgcIconComponent, registerIconFromText} from "igniteui-webcomponents"; + +defineComponents(IgcDatePickerComponent, IgcButtonComponent,IgcIconComponent); + +const alarm = '' +registerIconFromText('alarm', alarm); + +@Component({ + selector: 'app-date-picker-showcase-sample', + styleUrls: ['date-picker-showcase.sample.scss'], + templateUrl: 'date-picker-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxDatePickerComponent, IgxLabelDirective, IgxSuffixDirective, IgxIconComponent, IgxPickerActionsDirective, IgxButtonDirective, IgxRippleDirective] +}) + +export class DatePickerShowcaseSampleComponent { + public date1 = new Date(); + public date2 = new Date(new Date(this.date1.getFullYear(), this.date1.getMonth(), this.date1.getDate() + 1)); + public date3 = new Date(new Date(this.date2.getFullYear(), this.date2.getMonth(), this.date2.getDate() + 1)); + public date4 = new Date(new Date(this.date3.getFullYear(), this.date3.getMonth(), this.date3.getDate() + 1)); + public date5 = new Date(new Date(this.date4.getFullYear(), this.date4.getMonth(), this.date4.getDate() + 1)); + public date6 = new Date(new Date(this.date5.getFullYear(), this.date5.getMonth(), this.date5.getDate() + 1)); + public date7 = new Date(new Date(this.date6.getFullYear(), this.date6.getMonth(), this.date6.getDate() + 1)); + public today = new Date(this.date1); + public nextYear = new Date(this.date1.getFullYear() + 1, this.date1.getMonth(), this.date1.getDate()); + + public disabledDates: DateRangeDescriptor[] = [{ type: DateRangeType.Specific, dateRange: [this.date1, this.date2, this.date3] }]; + public specialDates: DateRangeDescriptor[] = [{ type: DateRangeType.Specific, dateRange: [this.date5, this.date6, this.date7] }]; +} diff --git a/src/app/dialog-showcase/dialog-showcase.sample.html b/src/app/dialog-showcase/dialog-showcase.sample.html new file mode 100644 index 00000000000..56abc789937 --- /dev/null +++ b/src/app/dialog-showcase/dialog-showcase.sample.html @@ -0,0 +1,33 @@ +
+
+

Angular Dialog

+

Detailed description to be added

+
+ + + +
+ +
+

WC Dialog

+

Detailed description to be added

+
+ + + Are you sure you want to delete the Microsoft_Annual_Report_2015.pdf and Microsoft_Annual_Report_2015.pdf files? + Cancel + OK + +
+
diff --git a/src/app/dialog-showcase/dialog-showcase.sample.scss b/src/app/dialog-showcase/dialog-showcase.sample.scss new file mode 100644 index 00000000000..dc22a6646ac --- /dev/null +++ b/src/app/dialog-showcase/dialog-showcase.sample.scss @@ -0,0 +1,23 @@ +::ng-deep .igx-dialog { + max-width: 60vw; +} + +igc-dialog::part(base) { + max-width: 30vw; +} + +[igxButton] { + max-width: 200px; +} + +.sample-column { + padding: 32px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + max-width: 350px; + margin-right: 16px; + border: 1px solid #999; + text-align: center; +} diff --git a/src/app/dialog-showcase/dialog-showcase.sample.ts b/src/app/dialog-showcase/dialog-showcase.sample.ts new file mode 100644 index 00000000000..57fa3734670 --- /dev/null +++ b/src/app/dialog-showcase/dialog-showcase.sample.ts @@ -0,0 +1,64 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { IgxButtonDirective, IgxDialogActionsDirective, IgxDialogComponent, IgxDialogTitleDirective, IgxIconComponent, IgxInputDirective, IgxInputGroupComponent, IgxLabelDirective, IgxPrefixDirective, IgxRippleDirective, IgxSwitchComponent } from 'igniteui-angular'; +import { defineComponents, IgcDialogComponent, IgcButtonComponent} from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcDialogComponent, IgcButtonComponent); + +@Component({ + selector: 'app-dialog-showcase-sample', + styleUrls: ['dialog-showcase.sample.scss'], + templateUrl: 'dialog-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxButtonDirective, IgxRippleDirective, IgxSwitchComponent, IgxDialogComponent, IgxInputGroupComponent, IgxPrefixDirective, IgxIconComponent, IgxInputDirective, IgxLabelDirective, IgxDialogTitleDirective, IgxDialogActionsDirective] +}) +export class DialogShowcaseSampleComponent implements OnInit { + public panelConfig : PropertyPanelConfig = { + keepOpenOnEscape: { + label: 'Keep Open on Escape', + control: { + type: 'boolean' + } + }, + closeOnOutsideClick: { + label: 'Close on Outside Click', + control: { + type: 'boolean' + } + }, + title: { + control: { + type: 'text', + defaultValue: 'Confirmation' + } + } + } + + constructor(private propertyChangeService: PropertyChangeService){} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + protected get keepOpenOnEscape() { + return this.propertyChangeService.getProperty('keepOpenOnEscape'); + } + + protected get closeOnOutsideClick() { + return this.propertyChangeService.getProperty('closeOnOutsideClick'); + } + + protected get title() { + return this.propertyChangeService.getProperty('title'); + } + + protected onDialogOKSelected(args) { + args.dialog.close(); + } + + protected closeDialog(evt) { + console.log(evt); + } +} diff --git a/src/app/drop-down-showcase/drop-down-showcase.sample.html b/src/app/drop-down-showcase/drop-down-showcase.sample.html new file mode 100644 index 00000000000..13e07b00d6b --- /dev/null +++ b/src/app/drop-down-showcase/drop-down-showcase.sample.html @@ -0,0 +1,33 @@ +
+
+ Angular DropDown + + + + {{ item.field }} + + +
+ +
+ WC DropDown + + Toggle + + + {{ item.field }} + + + {{ item.field }} + + + +
+
+ +
diff --git a/src/app/drop-down-showcase/drop-down-showcase.sample.scss b/src/app/drop-down-showcase/drop-down-showcase.sample.scss new file mode 100644 index 00000000000..37ad14609fd --- /dev/null +++ b/src/app/drop-down-showcase/drop-down-showcase.sample.scss @@ -0,0 +1,15 @@ + +.sample-wrapper { + display: flex; + flex-direction: column; + + >* { + margin-bottom: 16px; + } +} + +igc-dropdown::part(base) { + height: 400px; + width: 180px; + overflow: auto; +} diff --git a/src/app/drop-down-showcase/drop-down-showcase.sample.ts b/src/app/drop-down-showcase/drop-down-showcase.sample.ts new file mode 100644 index 00000000000..b9922d027b7 --- /dev/null +++ b/src/app/drop-down-showcase/drop-down-showcase.sample.ts @@ -0,0 +1,220 @@ +import { Component, OnInit, ViewChild, ElementRef, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { NgFor, NgIf } from '@angular/common'; +import { + ConnectedPositioningStrategy, + IgxButtonDirective, + IgxButtonGroupComponent, + IgxDropDownComponent, + IgxDropDownGroupComponent, + IgxDropDownItemComponent, + IgxDropDownItemNavigationDirective, + IgxIconComponent, + IgxInputDirective, + IgxInputGroupComponent, + IgxOverlayOutletDirective, + IgxRippleDirective, + IgxToggleActionDirective, + IgxToggleDirective, + NoOpScrollStrategy, + OverlaySettings, +} from 'igniteui-angular'; +import { defineComponents, IgcDropdownComponent, IgcButtonComponent} from "igniteui-webcomponents"; + +defineComponents(IgcDropdownComponent, IgcButtonComponent); + +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'drop-down-showcase-sample', + templateUrl: './drop-down-showcase.sample.html', + styleUrls: ['drop-down-showcase.sample.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [ + NgFor, + IgxButtonGroupComponent, + IgxButtonDirective, + IgxDropDownItemNavigationDirective, + IgxToggleActionDirective, + IgxDropDownComponent, + IgxDropDownItemComponent, + IgxToggleDirective, + IgxDropDownGroupComponent, + IgxInputGroupComponent, + IgxInputDirective, + IgxRippleDirective, + IgxOverlayOutletDirective, + IgxIconComponent, + NgIf, + ], +}) +export class DropDownShowcaseSampleComponent implements OnInit { + @ViewChild(IgxDropDownComponent, { static: true }) + private igxDropDown: IgxDropDownComponent; + private igxDropDownSelection: IgxDropDownComponent; + @ViewChild('button', { static: true }) + private button: ElementRef; + @ViewChild(IgxOverlayOutletDirective, { static: true }) + private igxOverlayOutlet: IgxOverlayOutletDirective; + + public items: any[] = []; + + public ngOnInit() { + this.igxDropDown.height = '400px'; + this.igxDropDown.width = '180px'; + + const states = [ + 'New England', + 'Connecticut', + 'Maine', + 'Massachusetts', + 'New Hampshire', + 'Rhode Island', + 'Vermont', + 'Mid-Atlantic', + 'New Jersey', + 'New York', + 'Pennsylvania', + 'East North Central', + 'Illinois', + 'Indiana', + 'Michigan', + 'Ohio', + 'Wisconsin', + 'West North Central', + 'Iowa', + 'Kansas', + 'Minnesota', + 'Missouri', + 'Nebraska', + 'North Dakota', + 'South Dakota', + 'South Atlantic', + 'Delaware', + 'Florida', + 'Georgia', + 'Maryland', + 'North Carolina', + 'South Carolina', + 'Virginia', + 'District of Columbia', + 'West Virginia', + 'East South Central', + 'Alabama', + 'Kentucky', + 'Mississippi', + 'Tennessee', + 'West South Central', + 'Arkansas', + 'Louisiana', + 'Oklahoma', + 'Texas', + 'Mountain', + 'Arizona', + 'Colorado', + 'Idaho', + 'Montana', + 'Nevada', + 'New Mexico', + 'Utah', + 'Wyoming', + 'Pacific', + 'Alaska', + 'California', + 'Hawaii', + 'Oregon', + 'Washington']; + + const areas = [ + 'New England', + 'Mid-Atlantic', + 'East North Central', + 'West North Central', + 'South Atlantic', + 'East South Central', + 'West South Central', + 'Mountain', + 'Pacific' + ]; + + for (let i = 0; i < states.length; i += 1) { + const item = { field: states[i] }; + if (areas.indexOf(states[i]) !== -1) { + item['header'] = true; + } else if (i % 7 === 4 || i > 49) { + item['disabled'] = true; + } + this.items.push(item); + } + + this.items[3]['selected'] = true; + } + + public toggleDropDown() { + const overlaySettings: OverlaySettings = { + positionStrategy: new ConnectedPositioningStrategy(), + scrollStrategy: new NoOpScrollStrategy(), + closeOnOutsideClick: false, + modal: false, + outlet: this.igxOverlayOutlet + }; + + overlaySettings.target = this.button.nativeElement; + this.igxDropDown.toggle(overlaySettings); + } + + public toggleDropDownWC() { + const overlaySettings: OverlaySettings = { + positionStrategy: new ConnectedPositioningStrategy(), + scrollStrategy: new NoOpScrollStrategy(), + closeOnOutsideClick: false, + modal: false, + outlet: this.igxOverlayOutlet + }; + + overlaySettings.target = this.button.nativeElement; + this.igxDropDown.toggle(overlaySettings); + } + + public open() { + const overlaySettings: OverlaySettings = { + positionStrategy: new ConnectedPositioningStrategy(), + scrollStrategy: new NoOpScrollStrategy(), + closeOnOutsideClick: false, + modal: false, + outlet: this.igxOverlayOutlet + }; + + overlaySettings.target = this.button.nativeElement; + this.igxDropDown.open(overlaySettings); + } + + public close() { + this.igxDropDown.close(); + } + + public clearSelection() { + this.igxDropDownSelection.clearSelection(); + } + + public onSelection(event) { + console.log(event); + const old = event.oldSelection; + event.oldSelection = event.newSelection; + event.newSelection = old; + } + + public onSelectionLogger(event) { + // event.cancel = true; + console.log(event); + } + + public onSelectionMenu(eventArgs) { + eventArgs.cancel = true; + + console.log(`new selection ${eventArgs.newSelection.element.nativeElement.textContent}`); + console.log(`old selection ${eventArgs.oldSelection ? eventArgs.oldSelection.element.nativeElement.textContent : ''}`); + } + + public onOpening() { + } +} diff --git a/src/app/drop-down-showcase/foods.ts b/src/app/drop-down-showcase/foods.ts new file mode 100644 index 00000000000..378f609468b --- /dev/null +++ b/src/app/drop-down-showcase/foods.ts @@ -0,0 +1,43 @@ +export const foods: { + name: string; + entries: { + name: string; + refNo: string; + }[]; +}[] = [{ + name: 'Vegetables', + entries: [{ + name: 'Cucumber', + refNo: `00000` + }, { + name: 'Lettuce', + refNo: `00001` + }, { + name: 'Cabbage', + refNo: `00002` + }] +}, { + name: 'Fruits', + entries: [{ + name: 'Banana', + refNo: `10000` + }, { + name: 'Tomato', + refNo: `10001` + }, { + name: 'Kiwi', + refNo: `10002` + }] +}, { + name: 'Meats', + entries: [{ + name: 'Chicken', + refNo: `20000` + }, { + name: 'Beef', + refNo: `20001` + }, { + name: 'Veal', + refNo: `20002` + }] +}]; diff --git a/src/app/expansion-panel-showcase/expansion-panel-showcase-sample.html b/src/app/expansion-panel-showcase/expansion-panel-showcase-sample.html new file mode 100644 index 00000000000..1d992d93150 --- /dev/null +++ b/src/app/expansion-panel-showcase/expansion-panel-showcase-sample.html @@ -0,0 +1,33 @@ +
+
+ Angular Expansion Panel + + + + The Expendables + + + Action, Adventure, Thriller + + + + Barney Ross leads the "Expendables", a band of highly skilled + mercenaries including knife enthusiast Lee Christmas, martial arts + expert Yin Yang, heavy weapons specialist Hale Caesar, demolitionist + Toll Road and loose-cannon sniper Gunner Jensen. + + +
+ +
+ WC Expansion Panel + + The Expendables + Action, Adventure, Thriller +
Barney Ross leads the "Expendables", a band of highly skilled + mercenaries including knife enthusiast Lee Christmas, martial arts + expert Yin Yang, heavy weapons specialist Hale Caesar, demolitionist + Toll Road and loose-cannon sniper Gunner Jensen.
+
+
+
diff --git a/src/app/expansion-panel-showcase/expansion-panel-showcase-sample.scss b/src/app/expansion-panel-showcase/expansion-panel-showcase-sample.scss new file mode 100644 index 00000000000..7ef1e8c1bc6 --- /dev/null +++ b/src/app/expansion-panel-showcase/expansion-panel-showcase-sample.scss @@ -0,0 +1,15 @@ +.flex-container { + display: flex; + justify-content: space-around; +} + +.flex-item { + width: 100%; + + strong { + color: hsla(var(--ig-secondary-500)); + display: block; + text-align: center; + margin-bottom: 12px; + } +} \ No newline at end of file diff --git a/src/app/expansion-panel-showcase/expansion-panel-showcase-sample.ts b/src/app/expansion-panel-showcase/expansion-panel-showcase-sample.ts new file mode 100644 index 00000000000..0c293a5d51a --- /dev/null +++ b/src/app/expansion-panel-showcase/expansion-panel-showcase-sample.ts @@ -0,0 +1,69 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { NgIf } from '@angular/common'; +import { IgxExpansionPanelBodyComponent, IgxExpansionPanelComponent, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelHeaderComponent, IgxExpansionPanelIconDirective, IgxExpansionPanelTitleDirective } from 'igniteui-angular'; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; +import { defineComponents, IgcExpansionPanelComponent} from "igniteui-webcomponents"; + +defineComponents(IgcExpansionPanelComponent); + +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'expansion-panel-showcase-sample', + templateUrl: './expansion-panel-showcase-sample.html', + styleUrls: ['expansion-panel-showcase-sample.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective, IgxExpansionPanelDescriptionDirective, NgIf, IgxExpansionPanelIconDirective, IgxExpansionPanelBodyComponent] +}) +export class ExpansionPanelShowcaseSampleComponent implements OnInit { + public panelConfig: PropertyPanelConfig = { + indicatorPosition: { + label: 'Indicator Position', + control: { + type: 'radio-inline', + options: ['start', 'end'], + defaultValue: 'start' + } + }, + open: { + control: { + type: 'boolean' + } + }, + disabled: { + control: { + type: 'boolean', + defaultValue: false + } + } + } + + constructor(public propertyChangeService: PropertyChangeService) {} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + protected get open(){ + return this.propertyChangeService.getProperty('open'); + } + + protected get disabled(){ + return this.propertyChangeService.getProperty('disabled'); + } + + private indicatorPositionMap = { + start: 'left', + end: 'right' + }; + + protected get indicatorPositionWC(){ + return this.propertyChangeService.getProperty('indicatorPosition'); + } + + protected get indicatorPositionAngular(){ + const position = this.propertyChangeService.getProperty('indicatorPosition'); + return this.indicatorPositionMap[position]; + } +} diff --git a/src/app/icon-button-showcase/icon-button-showcase.sample.html b/src/app/icon-button-showcase/icon-button-showcase.sample.html new file mode 100644 index 00000000000..4080f63c86c --- /dev/null +++ b/src/app/icon-button-showcase/icon-button-showcase.sample.html @@ -0,0 +1,18 @@ +
+
+

Angular Icon Button

+

WC Icon Button

+
+ +
+
+ +
+
+ + +
+
+
diff --git a/src/app/icon-button-showcase/icon-button-showcase.sample.scss b/src/app/icon-button-showcase/icon-button-showcase.sample.scss new file mode 100644 index 00000000000..e0ec01a5c76 --- /dev/null +++ b/src/app/icon-button-showcase/icon-button-showcase.sample.scss @@ -0,0 +1,21 @@ +.columns-container{ + margin: 24px 16px; +} + +.title { + display: grid; + grid-template-columns: repeat(2, 1fr); + justify-items: center; +} + +.buttons-sample { + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-auto-rows: minmax(80px, auto); + align-items: center; +} + +.button-sample { + justify-self: center; +} + diff --git a/src/app/icon-button-showcase/icon-button-showcase.sample.ts b/src/app/icon-button-showcase/icon-button-showcase.sample.ts new file mode 100644 index 00000000000..7f0f858afe0 --- /dev/null +++ b/src/app/icon-button-showcase/icon-button-showcase.sample.ts @@ -0,0 +1,61 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewEncapsulation, OnInit } from '@angular/core'; +import { IgxIconButtonDirective, IgxIconComponent, IgxRippleDirective } from 'igniteui-angular'; +import { defineComponents, IgcIconButtonComponent, registerIconFromText} from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents( IgcIconButtonComponent); + +const favorite = '' +registerIconFromText("favorite", favorite ); + +@Component({ + selector: 'app-icon-button-showcase-sample', + styleUrls: ['icon-button-showcase.sample.scss'], + templateUrl: 'icon-button-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + encapsulation: ViewEncapsulation.None, + standalone: true, + imports: [IgxIconComponent, IgxIconButtonDirective, IgxRippleDirective] +}) +export class IconButtonShowcaseSampleComponent implements OnInit { + public panelConfig: PropertyPanelConfig = { + size: { + control: { + type: "button-group", + options: ['small', 'medium', 'large'], + } + }, + variant: { + control: { + type: "button-group", + options: ['flat', 'contained', 'outlined'], + defaultValue: 'flat' + } + }, + disabled: { + control: { + type: "boolean", + defaultValue: false + } + } + } + + constructor(protected propertyChangeService: PropertyChangeService) {} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + protected get size() { + return this.propertyChangeService.getProperty('size'); + } + + protected get variant() { + return this.propertyChangeService.getProperty('variant'); + } + + protected get disabled() { + return this.propertyChangeService.getProperty('disabled'); + } +} diff --git a/src/app/input-group-showcase/input-group-showcase.sample.html b/src/app/input-group-showcase/input-group-showcase.sample.html new file mode 100644 index 00000000000..79c10302d1b --- /dev/null +++ b/src/app/input-group-showcase/input-group-showcase.sample.html @@ -0,0 +1,39 @@ + +
+ Angular Input + + + face + + + Type your web address + + face + + + + WC Input + + + + + Web component + + don't have {{inputType}} type! + + + +
\ No newline at end of file diff --git a/src/app/input-group-showcase/input-group-showcase.sample.scss b/src/app/input-group-showcase/input-group-showcase.sample.scss new file mode 100644 index 00000000000..15f5cd4d5b0 --- /dev/null +++ b/src/app/input-group-showcase/input-group-showcase.sample.scss @@ -0,0 +1,7 @@ +strong { + color: hsla(var(--ig-secondary-500)); + display: block; + text-align: center; + margin-top: 24px; + margin-bottom: 12px; +} \ No newline at end of file diff --git a/src/app/input-group-showcase/input-group-showcase.sample.ts b/src/app/input-group-showcase/input-group-showcase.sample.ts new file mode 100644 index 00000000000..e446dc53e9a --- /dev/null +++ b/src/app/input-group-showcase/input-group-showcase.sample.ts @@ -0,0 +1,146 @@ +import { Component, Inject, OnInit, AfterViewInit, ViewChild, ElementRef, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { UntypedFormBuilder, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { NgIf, NgFor } from '@angular/common'; + +import { defineComponents, IgcInputComponent, IgcIconComponent, registerIconFromText } from 'igniteui-webcomponents'; +import { ButtonGroupAlignment, IButtonGroupEventArgs, IGX_BUTTON_GROUP_DIRECTIVES, IGX_DATE_PICKER_DIRECTIVES, IGX_INPUT_GROUP_DIRECTIVES, IGX_INPUT_GROUP_TYPE, IGX_SELECT_DIRECTIVES, IgxIconComponent, IgxInputGroupType, IgxMaskDirective, IgxSwitchComponent } from 'igniteui-angular'; +import { SizeSelectorComponent } from '../size-selector/size-selector.component'; + +defineComponents(IgcInputComponent, IgcIconComponent); + +const face = '' +registerIconFromText('face', face); + +interface Selection { + selected: boolean; + type?: IgxInputGroupType; + label: string; + togglable: boolean; +} + +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'app-input-group-showcase-sample', + styleUrls: ['input-group-showcase.sample.scss'], + templateUrl: 'input-group-showcase.sample.html', + providers: [{ provide: IGX_INPUT_GROUP_TYPE, useValue: 'box' }], + standalone: true, + imports: [ + FormsModule, + NgIf, + ReactiveFormsModule, + NgFor, + IGX_INPUT_GROUP_DIRECTIVES, + IGX_BUTTON_GROUP_DIRECTIVES, + IGX_DATE_PICKER_DIRECTIVES, + IGX_SELECT_DIRECTIVES, + IgxMaskDirective, + IgxIconComponent, + IgxSwitchComponent, + SizeSelectorComponent + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class InputGroupShowcaseSampleComponent implements OnInit, AfterViewInit { + + @ViewChild('igcInput') + private igcInput: ElementRef; + public inputValue: any; + public isRequired = false; + public isDisabled = false; + public alignment: ButtonGroupAlignment = ButtonGroupAlignment.vertical; + + public displayDensities: Selection[]; + public inputType: IgxInputGroupType = null; + public inputTypes: Selection[]; + public items: string[] = ['Orange', 'Apple', 'Banana', 'Mango']; + + public myForm = this.fb.group({ + myTextField: [], + myTextField2: ['', Validators.required], + mySelectField: [] + }); + public date = new Date(); + + public isOutlined() { + return this.inputType === 'border' + } + + constructor( + private fb: UntypedFormBuilder, + @Inject(IGX_INPUT_GROUP_TYPE) public TOKEN: IgxInputGroupType + ) { + this.myForm.disable(); + } + + public ngOnInit(): void { + this.inputTypes = [ + { + selected: this.inputType === 'line', + type: 'line', + label: 'Line', + togglable: true + }, + { + selected: true, + type: 'box', + label: 'Box', + togglable: true, + }, + { + selected: this.inputType === 'border', + type: 'border', + label: 'Border', + togglable: true, + }, + { + selected: this.inputType === 'search', + type: 'search', + label: 'Search', + togglable: true, + }, + ]; + } + + public ngAfterViewInit() { + console.log(`The InputGroupToken set for all material themed components + (that have no explicit type set on component OR sample lv) is: `, + this.TOKEN); + } + + public selectInputType(event: IButtonGroupEventArgs) { + const currentType = this.inputTypes[event.index].type; + this.inputType = currentType; + this.igcInput.nativeElement.removeAttribute('outlined'); + if (currentType === 'border') { + this.igcInput.nativeElement.setAttribute('outlined', 'true'); + } + console.log('New type set is = ', currentType); + } + + public enableText() { + this.myForm.get('myTextField').enable(); + this.myForm.get('myTextField2').enable(); + } + + public disableText() { + this.myForm.get('myTextField').disable(); + this.myForm.get('myTextField2').disable(); + } + + public enableSelect() { + this.myForm.get('mySelectField').enable(); + } + + public disableSelect() { + this.myForm.get('mySelectField').disable(); + } + + public enableForm() { + this.myForm.enable(); + } + + public disableForm() { + this.myForm.disable(); + } +} diff --git a/src/app/list-showcase/list-showcase.sample.html b/src/app/list-showcase/list-showcase.sample.html new file mode 100644 index 00000000000..e60a53f0577 --- /dev/null +++ b/src/app/list-showcase/list-showcase.sample.html @@ -0,0 +1,40 @@ +
+ + +
+ +
+ Angular List +
+ + Job positions + + + +

{{employee.name}}

+

{{employee.position}}

+ more_horiz +
+
+
+
+
+ +
+ WC List +
+ + + Job Positions + + + + + {{employee.name}} + {{employee.position}} + + + + +
+
\ No newline at end of file diff --git a/src/app/list-showcase/list-showcase.sample.scss b/src/app/list-showcase/list-showcase.sample.scss new file mode 100644 index 00000000000..818746edf9c --- /dev/null +++ b/src/app/list-showcase/list-showcase.sample.scss @@ -0,0 +1,10 @@ +span { + display: block; +} + +strong { + color: hsla(var(--ig-secondary-500)); + display: block; + text-align: center; + margin-bottom: 12px; +} \ No newline at end of file diff --git a/src/app/list-showcase/list-showcase.sample.ts b/src/app/list-showcase/list-showcase.sample.ts new file mode 100644 index 00000000000..15dbbecced1 --- /dev/null +++ b/src/app/list-showcase/list-showcase.sample.ts @@ -0,0 +1,84 @@ +import {Component, CUSTOM_ELEMENTS_SCHEMA, ViewEncapsulation} from '@angular/core'; +import { NgFor } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { + IGX_INPUT_GROUP_DIRECTIVES, + IGX_LIST_DIRECTIVES, + IgxAvatarComponent, + IgxBadgeComponent, + IgxButtonDirective, + IgxButtonGroupComponent, + IgxCardComponent, + IgxCheckboxComponent, + IgxDialogComponent, + IgxFilterDirective, + IgxFilterPipe, + IgxIconComponent, + IgxRippleDirective, + IgxSwitchComponent +} from 'igniteui-angular'; +import { SizeSelectorComponent } from '../size-selector/size-selector.component'; +import { defineComponents, IgcListComponent, IgcAvatarComponent, IgcListHeaderComponent, IgcListItemComponent, IgcIconComponent, registerIconFromText } from 'igniteui-webcomponents'; + +defineComponents(IgcListComponent, IgcListHeaderComponent, IgcListItemComponent, IgcAvatarComponent, IgcIconComponent); + +const more_horiz = '' +registerIconFromText('more_horiz', more_horiz) + +interface Employee { + imageURL: string; + name: string; + position: string; + description: string; +} + +@Component({ + selector: 'app-list-showcase-sample', + styleUrls: ['list-showcase.sample.scss'], + templateUrl: 'list-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + encapsulation: ViewEncapsulation.None, + standalone: true, + imports: [ + NgFor, + FormsModule, + IgxButtonGroupComponent, + IgxBadgeComponent, + IgxCardComponent, + IgxRippleDirective, + IgxIconComponent, + IgxCheckboxComponent, + IgxAvatarComponent, + IgxSwitchComponent, + IgxFilterDirective, + IgxButtonDirective, + IgxDialogComponent, + IgxFilterPipe, + SizeSelectorComponent, + IGX_LIST_DIRECTIVES, + IGX_INPUT_GROUP_DIRECTIVES + ] +}) +export class ListShowcaseSampleComponent { + public employeeItems: Employee[] = [{ + imageURL: 'assets/images/avatar/18.jpg', + name: 'Marin Popov', + position: 'Web designer', + description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam, vel?, consectetur adipisicing elit. Aperiam, vel?' + }, { + imageURL: 'assets/images/avatar/2.jpg', + name: 'Simeon Simeonov', + position: 'Front-end Developer', + description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam, vel?, consectetur adipisicing elit. Aperiam, vel?' + }, { + imageURL: 'assets/images/avatar/7.jpg', + name: 'Stefan ivanov', + position: 'UX Architect', + description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam, vel?, consectetur adipisicing elit. Aperiam, vel?' + }, { + imageURL: 'assets/images/avatar/6.jpg', + name: 'Svilen Dimchevski', + position: 'Graphic designer', + description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam, vel, consectetur adipisicing elit. Aperiam, vel??' + }]; +} diff --git a/src/app/pageHeading/pageHeading.component.ts b/src/app/pageHeading/pageHeading.component.ts index 316b48e0056..c5270b3f280 100644 --- a/src/app/pageHeading/pageHeading.component.ts +++ b/src/app/pageHeading/pageHeading.component.ts @@ -1,15 +1,23 @@ import { Component, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; import { IgxButtonDirective, IgxIconButtonDirective, IgxIconComponent, IgxRippleDirective, IgxToggleActionDirective } from 'igniteui-angular'; - +import { PropertyChangeService } from '../properties-panel/property-change.service'; @Component({ selector: 'app-page-header', styleUrls: ['./pageHeading.styles.scss'], templateUrl: './pageHeading.template.html', standalone: true, - imports: [IgxButtonDirective, IgxRippleDirective, IgxToggleActionDirective, IgxIconComponent, IgxIconButtonDirective] + imports: [IgxButtonDirective, IgxRippleDirective, IgxToggleActionDirective, IgxIconComponent, IgxIconButtonDirective, CommonModule] }) export class PageHeaderComponent { @Input() public title: string; + public panelConfig: any; + + constructor(protected propertyChangeService: PropertyChangeService) { + this.propertyChangeService.panelConfig$.subscribe(config => { + this.panelConfig = config; + }); + } } diff --git a/src/app/pageHeading/pageHeading.styles.scss b/src/app/pageHeading/pageHeading.styles.scss index feb5040db6a..3c7795aa2d1 100644 --- a/src/app/pageHeading/pageHeading.styles.scss +++ b/src/app/pageHeading/pageHeading.styles.scss @@ -27,11 +27,17 @@ .sample-header { display: flex; align-items: center; + justify-content: space-between; height: rem(90px); padding: 0 rem(16px); background: var(--ph-background); overflow: hidden; + .wrapper { + display: flex; + align-items: center; + } + .title { color: var(--ph-foreground); margin: 0; @@ -40,4 +46,8 @@ overflow: hidden; text-overflow: ellipsis; } + + .toggle-properties-panel { + color: var(--ph-foreground); + } } diff --git a/src/app/pageHeading/pageHeading.template.html b/src/app/pageHeading/pageHeading.template.html index 67cecc3f958..f7b0e004c9e 100644 --- a/src/app/pageHeading/pageHeading.template.html +++ b/src/app/pageHeading/pageHeading.template.html @@ -1,12 +1,22 @@
- +
+ {{ title }} +
+
+ -
- {{ title }} -
diff --git a/src/app/properties-panel/properties-panel.component.html b/src/app/properties-panel/properties-panel.component.html new file mode 100644 index 00000000000..364769215ee --- /dev/null +++ b/src/app/properties-panel/properties-panel.component.html @@ -0,0 +1,95 @@ +
+
Properties Panel
+
+ @if (getControlType(key) !== 'boolean') { + + } + + + @if (getControlType(key) === 'text') { + + + + } + + + @if (getControlType(key) === 'number') { + + + + } + + + @if (getControlType(key) === 'range') { + + + } + + + @if (getControlType(key) === 'boolean') { +
+ + +
+ } + + + @if (getControlType(key) === 'date') { + + } + + + @if (getControlType(key) === 'time') { + + } + + + @if (getControlType(key) === 'date-time') { +
+ + +
+ } + + + @if ( + getControlType(key) === 'radio' || getControlType(key) === 'radio-inline' + ) { + + + {{ getControlLabels(key)[i] }} + + + } + + + @if (getControlType(key) === 'button-group') { + + + + } + + + @if (getControlType(key) === 'select') { + + + {{ option }} + + } +
+ + + + +
diff --git a/src/app/properties-panel/properties-panel.component.scss b/src/app/properties-panel/properties-panel.component.scss new file mode 100644 index 00000000000..a684efefc90 --- /dev/null +++ b/src/app/properties-panel/properties-panel.component.scss @@ -0,0 +1,32 @@ +#date-time { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} + +#properties-panel { + padding: .5rem; + + igx-input-group { + --ig-size: var(--ig-size-small); + } + + .switch-container { + display: flex; + align-items: center; + gap: 8px; + + label { + margin: 0; + } + } + + .panel-title { + margin-bottom: 2rem; + } + + + > *:not(:last-child) { + margin-bottom: 16px; + } +} diff --git a/src/app/properties-panel/properties-panel.component.ts b/src/app/properties-panel/properties-panel.component.ts new file mode 100644 index 00000000000..bafcb1f27d1 --- /dev/null +++ b/src/app/properties-panel/properties-panel.component.ts @@ -0,0 +1,128 @@ +import { Component, Input, OnInit, TemplateRef } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms'; +import { PropertyChangeService } from './property-change.service'; +import { + IgxButtonGroupComponent, + IgxButtonDirective, + IgxInputDirective, + IgxInputGroupComponent, + IgxInputGroupModule, + IgxSliderComponent, + IgxTickLabelTemplateDirective, + IgxSwitchComponent, + IgxRadioModule, + RadioGroupAlignment, + IgxSelectComponent, + IgxSelectItemComponent, + IgxDatePickerComponent, + IgxTimePickerComponent, + IgxDateTimeEditorModule +} from 'igniteui-angular'; + +export type ControlType = + 'boolean' | + 'number' | + 'range' | + 'radio' | + 'radio-inline' | + 'button-group' | + 'select' | + 'text' | + 'date' | + 'time' | + 'date-time'; + +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export type PropertyPanelConfig = { + [key: string]: { + label?: string; + control: { + type: ControlType, + options?: string[]; + labels?: string[]; + min?: number; + max?: number; + step?: number; + defaultValue?: any; + }; + }; +} + +@Component({ + selector: 'app-properties-panel', + standalone: true, + templateUrl: './properties-panel.component.html', + styleUrl: './properties-panel.component.scss', + imports: [ + ReactiveFormsModule, + CommonModule, + IgxButtonDirective, + IgxButtonGroupComponent, + IgxInputDirective, + IgxInputGroupComponent, + IgxInputGroupModule, + IgxSliderComponent, + IgxTickLabelTemplateDirective, + IgxSwitchComponent, + IgxRadioModule, + IgxSelectComponent, + IgxSelectItemComponent, + IgxDatePickerComponent, + IgxTimePickerComponent, + IgxDateTimeEditorModule + ] +}) + +export class PropertiesPanelComponent implements OnInit { + @Input() public config!: PropertyPanelConfig; + + protected form!: FormGroup; + protected radioAlignment = RadioGroupAlignment.vertical; + protected customControlsTemplate: TemplateRef | null = null; + + constructor(private propertyChangeService: PropertyChangeService) { } + + public ngOnInit(): void { + this.form = this.createFormGroup(this.config); + this.propertyChangeService.emitInitialValues(this.config); + this.form.valueChanges.subscribe(this.onFormValueChange.bind(this)); + + this.propertyChangeService.customControls$.subscribe(template => { + this.customControlsTemplate = template; + }); + } + + protected onFormValueChange(value: any): void { + Object.keys(value).forEach((key) => { + this.propertyChangeService.updateProperty(key, value[key]); + }); + } + + protected createFormGroup(config: PropertyPanelConfig): FormGroup { + const group: Record = {}; + Object.keys(config).forEach((key) => { + const defaultValue = config[key]?.control?.defaultValue ?? ''; + group[key] = new FormControl(defaultValue); + }); + return new FormGroup(group); + } + + protected getConfigKeys(): string[] { + return Object.keys(this.config); + } + + protected getControlType(key: string): string { + return this.config[key].control.type; + } + + protected getControlOptions(key: string): any { + return this.config[key].control.options; + } + + protected getControlLabels(key: string): string[] { + const labels = this.config[key].control.labels || []; + const options = this.getControlOptions(key); + return labels.length > 0 ? labels : options.map(option => option.toString()); + } +} diff --git a/src/app/properties-panel/property-change.service.ts b/src/app/properties-panel/property-change.service.ts new file mode 100644 index 00000000000..872c23998f1 --- /dev/null +++ b/src/app/properties-panel/property-change.service.ts @@ -0,0 +1,65 @@ +import { Injectable, TemplateRef } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { PropertyPanelConfig } from './properties-panel.component'; +import { NavigationEnd, Router } from '@angular/router'; + +@Injectable({ + providedIn: 'root', +}) +export class PropertyChangeService { + private propertyChanges = new BehaviorSubject({}); + public propertyChanges$ = this.propertyChanges.asObservable(); + + public panelConfig = new BehaviorSubject({}); + public panelConfig$ = this.panelConfig.asObservable(); + + private customControlsSource = new BehaviorSubject | null>(null); + public customControls$ = this.customControlsSource.asObservable(); + + public emitInitialValues(config: PropertyPanelConfig): void { + this.panelConfig.next(config); + Object.keys(config).forEach((key) => { + const defaultValue = config[key]?.control?.defaultValue; + if (defaultValue !== undefined && defaultValue !== null) { + this.updateProperty(key, defaultValue); + } + }); + } + + public updateProperty(key: string, value: any): void { + const currentChanges = this.propertyChanges.getValue(); + currentChanges[key] = value; + this.propertyChanges.next(currentChanges); + } + + public getProperty(key: string): any { + const changes = this.propertyChanges.getValue(); + return changes[key]; + } + + public setPanelConfig(config: PropertyPanelConfig): void { + this.panelConfig.next(config); + } + + public clearPanelConfig(): void { + this.panelConfig.next(null); + } + + public setCustomControls(controls: TemplateRef): void { + this.customControlsSource.next(controls); + } + + public clearCustomControls(): void { + this.customControlsSource.next(null); + } + + constructor(private router: Router) { + this.router.events.subscribe(event => { + if (event instanceof NavigationEnd) { + this.clearPanelConfig(); + this.clearCustomControls(); + } + }); + } +} + diff --git a/src/app/propertiesPanel/Properties-Panel-Spec.md b/src/app/propertiesPanel/Properties-Panel-Spec.md new file mode 100644 index 00000000000..cbf4318f3f9 --- /dev/null +++ b/src/app/propertiesPanel/Properties-Panel-Spec.md @@ -0,0 +1,131 @@ +# Properties Panel Specification + +### Contents + +1. [Overview & Objectives](#overview) +2. [User Stories](#user-stories) +3. [Functionality](#functionality) + +### Owned by + +**Team Name**: Design and Web Development (DnD) + +**Developer**: Dilyana Yarabanova + +### Requires approval from + +- [x] Simeon Simeonov | Date: + +### Signed off by + +- [x] Simeon Simeonov | Date: + +## Revision History + +| Version | Users | Date | Notes | +| ------: | --------------- | ---------------- | ------------- | +| 1 | Simeon Simeonov | Date: 1 Oct 2024 | Initial draft | +| 2 | Dilyana Yarabanova | Date: 3 Oct 2024 | Update Specification | + +## 1. Overview & Objectives + +The properties panel aims to provide a unified User Interface for configuring components in various app samples. It is configured via a standardized data model. + +### Acceptance criteria + +1. Should be able to configure the panel using a data object specifying the configuration properties and their default values. +2. Should generate UI elements for the provided data object. +3. Should emit event with the updated properties when the user changes them. + +```html + +``` + +```ts +@Component({ + selector: "app-sample", + ... +}) +export class AppSampleComponent { + public config = { + disabled: { + label?: 'Disabled', + control: { + type: 'boolean', + labels?: '' + } + }, + locale: { + label: 'Change Locale', + control: { + type: 'button-group', + options: ['en', 'fr', 'ru', 'es'], + labels: ['EN', 'FR', 'RU', 'ES'], + defaultValue: 'en' + }, + }, + monthsNum: { + label: 'Number of months', + control: { + type: 'number', + defaultValue: 1, + min?: 1, + max?: 4, + step?: 1 + } + } + } +} +``` + +**End-user stories:** + +## 3. Functionality + +1. Here's a table of the available control types and how to use them: + +| Control Type | Description | +| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| boolean | Provides a toggle for switching between possible states. config = { disabled: { control: { type: 'boolean'}}} | +| number | Provides a numeric input to include the range of all possible values. config = { monthsNum: { control: { type: 'number', min:1, max:30, step: 2 }}} | +| range | Provides a slider component to include all possible values. config = { odd: { control: { type: 'range', min: 1, max: 30, step: 3 }}} | +| radio | Provides a set of radio buttons based on the available options. config = { contact: { control: { type: 'radio', options: ['email', 'phone', 'mail'] }}} | +| radio-inline | Provides a set of inlined radio buttons based on the available options. config = { contact: { control: { type: 'radio', options: ['email', 'phone', 'mail'] }}} | +| button-group | Provides a button group with the available options config = { locale: { control: { type: 'button-group', options: ['en', 'fr', 'ru', 'es']}}} | +| select | Provides a drop-down list component to handle single value selection. config = { age: { control: { type: 'select', options: [20, 30, 40, 50] }}} | +| text | Provides a freeform text input. config = { label: { control: { type: 'text' }}} | +| date | Provides a datepicker component to handle date selection. config = { startDate: { control: { type: 'date' }}} | +| time | Provides a timepicker component to handle time selection. config = { startDate: { control: { type: 'date' }}} | +| date-time | Provides an input component with date-time editor directive to handle date and time selection/change. config = { startDate: { control: { type: 'date' }}} | + +2. You can also add label to show the user the name or a short description of the property. + +```ts +public config = { + monthsNum: { + label: 'Number of months', + control: { + type: 'number', + } + } +} +``` + +That way above the control, there will be a label - "Number of months" so the user has better understanding of what this property does. + +3. Labels for the controls are also available, if you want to show the property values in a more visually pleasing way: + +```ts +public config = { + locale: { + control: { + type: 'button-group', + options: ['en', 'fr', 'ru', 'es'], + labels: ['EN', 'FR', 'RU', 'ES'], + defaultValue: 'en' + }, + }, +} +``` + +Using labels for the options, in this example, the text of the buttons will use the capitalized values from `labels`, but will pass to the property the values from `options`. You can also see how we use `defaultValue` in this example and it's available for all control types. diff --git a/src/app/radio-showcase/radio-showcase.sample.html b/src/app/radio-showcase/radio-showcase.sample.html new file mode 100644 index 00000000000..5b4e0d07e4b --- /dev/null +++ b/src/app/radio-showcase/radio-showcase.sample.html @@ -0,0 +1,35 @@ +
+
+

Angular Radio

+ + + Foo + + Bar + +
+ +
+

WC Radio

+ + + Foo + + Bar + +
+
diff --git a/src/app/radio-showcase/radio-showcase.sample.scss b/src/app/radio-showcase/radio-showcase.sample.scss new file mode 100644 index 00000000000..9df693180a4 --- /dev/null +++ b/src/app/radio-showcase/radio-showcase.sample.scss @@ -0,0 +1,4 @@ +.wrapper { + display: inline-grid; + grid-template-columns: 1fr 1fr; +} diff --git a/src/app/radio-showcase/radio-showcase.sample.ts b/src/app/radio-showcase/radio-showcase.sample.ts new file mode 100644 index 00000000000..53fe2831022 --- /dev/null +++ b/src/app/radio-showcase/radio-showcase.sample.ts @@ -0,0 +1,95 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { IgxRadioComponent, IgxRadioGroupDirective, RadioGroupAlignment } from 'igniteui-angular'; +import { defineComponents, IgcRadioComponent, IgcRadioGroupComponent} from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcRadioComponent, IgcRadioGroupComponent); + +@Component({ + selector: 'app-radio-showcase-sample', + styleUrls: ['radio-showcase.sample.scss'], + templateUrl: 'radio-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxRadioComponent, IgxRadioGroupDirective, CommonModule] +}) +export class RadioShowcaseSampleComponent implements OnInit { + public panelConfig : PropertyPanelConfig = { + alignment: { + control: { + type: 'button-group', + options: ['vertical', 'horizontal'] + } + }, + labelPosition: { + label: 'Label Position', + control: { + type: 'button-group', + options: ['before', 'after'], + defaultValue: 'after' + } + }, + checked: { + control: { + type: 'boolean', + defaultValue: false + } + }, + required: { + control: { + type: 'boolean', + defaultValue: false + } + }, + disabled: { + control: { + type: 'boolean', + defaultValue: false + } + }, + invalid: { + control: { + type: 'boolean', + defaultValue: false + } + }, + } + + constructor(private propertyChangeService : PropertyChangeService) {} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + private alignmentMap = { + vertical: RadioGroupAlignment.vertical, + horizontal: RadioGroupAlignment.horizontal, + }; + + public get alignment(): RadioGroupAlignment { + const alignment = this.propertyChangeService.getProperty('alignment'); + return this.alignmentMap[alignment] || RadioGroupAlignment.vertical; + } + + protected get required() { + return this.propertyChangeService.getProperty('required'); + } + + protected get disabled() { + return this.propertyChangeService.getProperty('disabled'); + } + + protected get invalid() { + return this.propertyChangeService.getProperty('invalid'); + } + + protected get checked() { + return this.propertyChangeService.getProperty('checked'); + } + + protected get labelPosition() { + return this.propertyChangeService.getProperty('labelPosition'); + } +} diff --git a/src/app/select-showcase/select-showcase.sample.html b/src/app/select-showcase/select-showcase.sample.html new file mode 100644 index 00000000000..3773b3e92bf --- /dev/null +++ b/src/app/select-showcase/select-showcase.sample.html @@ -0,0 +1,32 @@ + + +
+ Angular Select + + + favorite + I am a Hint + Apple + Orange + Grapes + Banana + + + WC Select + + + I am a Hint + Apple + Orange + Grapes + Banana + +
diff --git a/src/app/select-showcase/select-showcase.sample.scss b/src/app/select-showcase/select-showcase.sample.scss new file mode 100644 index 00000000000..48d159bd9f9 --- /dev/null +++ b/src/app/select-showcase/select-showcase.sample.scss @@ -0,0 +1,10 @@ +strong { + color: hsla(var(--ig-secondary-500)); + display: block; + text-align: center; + margin-bottom: 12px; +} + +.select-sample { + margin-top: 24px; +} diff --git a/src/app/select-showcase/select-showcase.sample.ts b/src/app/select-showcase/select-showcase.sample.ts new file mode 100644 index 00000000000..46cae0bd8aa --- /dev/null +++ b/src/app/select-showcase/select-showcase.sample.ts @@ -0,0 +1,59 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { NgFor } from '@angular/common'; +import { IgxButtonDirective, IgxSelectComponent, IgxLabelDirective, IgxPrefixDirective, IgxIconComponent, IgxSelectItemComponent, IgxSelectHeaderDirective, IgxSelectFooterDirective, IgxButtonGroupComponent, IgxSuffixDirective, IgxHintDirective, IgxSelectGroupComponent, IgxSwitchComponent } from 'igniteui-angular'; +import { SizeSelectorComponent } from '../size-selector/size-selector.component'; +import { defineComponents, IgcSelectGroupComponent, IgcSelectComponent, IgcSelectItemComponent, IgcSelectHeaderComponent, IgcIconComponent, registerIconFromText } from 'igniteui-webcomponents'; + +defineComponents(IgcSelectGroupComponent, IgcSelectComponent, IgcSelectItemComponent, IgcSelectHeaderComponent, IgcIconComponent); + +const favorite = ''; +registerIconFromText('favorite', favorite); + +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'app-select-showcase-sample', + styleUrls: ['./select-showcase.sample.scss'], + templateUrl: './select-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [ + IgxButtonDirective, + IgxSelectComponent, + FormsModule, + IgxLabelDirective, + IgxPrefixDirective, + IgxIconComponent, + IgxSelectItemComponent, + NgFor, + IgxSelectHeaderDirective, + IgxSelectFooterDirective, + IgxButtonGroupComponent, + IgxSuffixDirective, + IgxHintDirective, + IgxSelectGroupComponent, + ReactiveFormsModule, + IgxSwitchComponent, + SizeSelectorComponent + ] +}) +export class SelectShowcaseSampleComponent { + @ViewChild('selectReactive', { read: IgxSelectComponent, static: true }) + public select: IgxSelectComponent; + @ViewChild('model', { read: IgxSelectComponent, static: true }) + public selectFruits: IgxSelectComponent; + @ViewChild('sizeSelect', { read: IgxSelectComponent, static: true }) + public sizeSelect: IgxSelectComponent; + + public fruits: string[] = ['Orange', 'Apple', 'Banana', 'Mango', 'Pear', 'Lemon', 'Peach', 'Apricot', 'Grapes', 'Cactus']; + public selected: string; + + public selectBanana() { + this.selectFruits.setSelectedItem(3); + } + + public setToNull() { + this.selectFruits.value = null; + this.selected = null; + } +} diff --git a/src/app/slider-showcase/slider-showcase.sample.html b/src/app/slider-showcase/slider-showcase.sample.html new file mode 100644 index 00000000000..e37e0372a2c --- /dev/null +++ b/src/app/slider-showcase/slider-showcase.sample.html @@ -0,0 +1,44 @@ +
+
+ Angular Slider + + +
+ +
+ WC Slider + + + +
+
diff --git a/src/app/slider-showcase/slider-showcase.sample.scss b/src/app/slider-showcase/slider-showcase.sample.scss new file mode 100644 index 00000000000..ae129e23ede --- /dev/null +++ b/src/app/slider-showcase/slider-showcase.sample.scss @@ -0,0 +1,12 @@ +.sample-container { + margin: 24px; +} + +.sample-item { + margin-bottom: 60px; +} + +strong { + display: block; + text-align: center; +} \ No newline at end of file diff --git a/src/app/slider-showcase/slider-showcase.sample.ts b/src/app/slider-showcase/slider-showcase.sample.ts new file mode 100644 index 00000000000..5d50645e926 --- /dev/null +++ b/src/app/slider-showcase/slider-showcase.sample.ts @@ -0,0 +1,180 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { TicksOrientation, IgxSliderComponent, TickLabelsOrientation } from 'igniteui-angular'; +import { defineComponents, IgcSliderComponent, IgcSliderLabelComponent } from 'igniteui-webcomponents'; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcSliderComponent, IgcSliderLabelComponent); + +@Component({ + selector: 'app-slider-showcase-sample', + styleUrls: ['slider-showcase.sample.scss'], + templateUrl: 'slider-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxSliderComponent] +}) +export class SliderShowcaseSampleComponent implements OnInit { + public panelConfig : PropertyPanelConfig = { + value: { + control: { + type: 'number' + } + }, + minValue: { + label: 'Min Value', + control: { + type: 'number' + } + }, + maxValue: { + label: 'Max Value', + control: { + type: 'number' + } + }, + step: { + control: { + type: 'number' + } + }, + lowerBound: { + label: 'Lower Bound', + control: { + type: 'number' + } + }, + upperBound: { + label: 'Upper Bound', + control: { + type: 'number' + } + }, + primaryTicks: { + label: 'Primary Ticks', + control: { + type: 'number' + } + }, + secondaryTicks: { + label: 'Secondary Ticks', + control: { + type: 'number' + } + }, + ticksOrientation: { + label: 'Ticks Orientation', + control: { + type: 'button-group', + options: ['mirror', 'start', 'end'], + defaultValue: 'end' + } + }, + tickLabelOrientation: { + label: 'Tick Label Orientation', + control: { + type: 'button-group', + options: ['0', '90', '-90'], + labels: ['horizontal', 'top to bottom', 'bottom to top'], + defaultValue: '0' + } + }, + disabled: { + control: { + type: 'boolean' + } + }, + primaryTickLabels: { + label: 'Hide Primary Tick Labels', + control: { + type: 'boolean' + } + }, + secondaryTickLabels: { + label: 'Hide Secondary Tick Labels', + control: { + type: 'boolean' + } + } + } + + constructor(protected propertyChangeService: PropertyChangeService) {} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + private ticksOrientationMap = { + start: TicksOrientation.Top, + end: TicksOrientation.Bottom, + mirror: TicksOrientation.Mirror + }; + + private tickLabelOrientationMap: { [key: string]: TickLabelsOrientation } = { + '0': TickLabelsOrientation.Horizontal, + '90': TickLabelsOrientation.TopToBottom, + '-90': TickLabelsOrientation.BottomToTop, + }; + + protected get angularTickLabelOrientation(): TickLabelsOrientation { + const orientation = this.propertyChangeService.getProperty('tickLabelOrientation'); + return this.tickLabelOrientationMap[orientation] ?? TickLabelsOrientation.Horizontal; + } + + protected get wcTickLabelOrientation(): number { + return this.propertyChangeService.getProperty('tickLabelOrientation'); + } + + protected get value(): number { + return this.propertyChangeService.getProperty('value') || 0; + } + + protected get disabled(): boolean { + return !!this.propertyChangeService.getProperty('disabled'); + } + + protected get minValue(): number { + return this.propertyChangeService.getProperty('minValue') || 0; + } + + protected get maxValue(): number { + return this.propertyChangeService.getProperty('maxValue') || 100; + } + + protected get step(): number { + return this.propertyChangeService.getProperty('step') || 1; + } + + protected get lowerBound(): number { + return this.propertyChangeService.getProperty('lowerBound') || 0; + } + + protected get upperBound(): number { + return this.propertyChangeService.getProperty('upperBound') || 100; + } + + protected get primaryTicks(): number { + return this.propertyChangeService.getProperty('primaryTicks') || 0; + } + + protected get secondaryTicks(): number { + return this.propertyChangeService.getProperty('secondaryTicks') || 0; + } + + protected get ticksOrientationAngular(): TicksOrientation { + const orientation = this.propertyChangeService.getProperty('ticksOrientation'); + return this.ticksOrientationMap[orientation] || TicksOrientation.Bottom; + } + + protected get ticksOrientationWC(): string { + return this.propertyChangeService.getProperty('ticksOrientation'); + } + + protected get primaryTickLabels(): boolean { + return !!this.propertyChangeService.getProperty('primaryTickLabels'); + } + + protected get secondaryTickLabels(): boolean { + return !!this.propertyChangeService.getProperty('secondaryTickLabels'); + } +} diff --git a/src/app/snackbar-showcase/snackbar-showcase.sample.css b/src/app/snackbar-showcase/snackbar-showcase.sample.css new file mode 100644 index 00000000000..5fff386efdd --- /dev/null +++ b/src/app/snackbar-showcase/snackbar-showcase.sample.css @@ -0,0 +1,4 @@ +.snackbar-sample { + position: relative; + height: 300px; +} diff --git a/src/app/snackbar-showcase/snackbar-showcase.sample.html b/src/app/snackbar-showcase/snackbar-showcase.sample.html new file mode 100644 index 00000000000..25db52d3af5 --- /dev/null +++ b/src/app/snackbar-showcase/snackbar-showcase.sample.html @@ -0,0 +1,33 @@ +
+
+
+

Snackbar

+
+
+ Snackbar Message + +
+
+
+ +
+
+ +
+
+ +
+ + Snackbar Message + + +
+
+
+ diff --git a/src/app/snackbar-showcase/snackbar-showcase.sample.ts b/src/app/snackbar-showcase/snackbar-showcase.sample.ts new file mode 100644 index 00000000000..46020cb1e52 --- /dev/null +++ b/src/app/snackbar-showcase/snackbar-showcase.sample.ts @@ -0,0 +1,26 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild } from '@angular/core'; +// eslint-disable-next-line max-len +import { IgxButtonDirective, IgxOverlayOutletDirective, IgxSnackbarComponent } from 'igniteui-angular'; +import { defineComponents, IgcSnackbarComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcSnackbarComponent); + +@Component({ + selector: 'app-snackbar-showcase-sample', + styleUrls: ['snackbar-showcase.sample.css'], + templateUrl: 'snackbar-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxSnackbarComponent, IgxOverlayOutletDirective, IgxButtonDirective] +}) +export class SnackbarShowcaseSampleComponent { + @ViewChild('snackbar') + private snackbar: IgxSnackbarComponent; + + public color: string; + public actionName: string; + + public toggleSnackbar() { + this.snackbar.toggle(); + } +} diff --git a/src/app/stepper-showcase/stepper-showcase.sample.html b/src/app/stepper-showcase/stepper-showcase.sample.html new file mode 100644 index 00000000000..065d17d10b3 --- /dev/null +++ b/src/app/stepper-showcase/stepper-showcase.sample.html @@ -0,0 +1,139 @@ +
+ Angular Stepper + + + Step 1 + (completed) +
+
+ + + + + + +
+
+
+ + Step 2 + (default) +
+
+ + + + + + +
+
+
+ + Step 3 + (optional) +
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur + soluta nulla asperiores, officia ullam recusandae voluptatem omnis + perferendis vitae non magni magnam praesentium placeat nemo quas + repudiandae. Nisi, quo ex! + + +
+
+ + + Step 4 + (disabled) +
+ Tabbable content +
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur + soluta nulla asperiores, officia ullam recusandae voluptatem omnis + perferendis vitae non magni magnam praesentium placeat nemo quas + repudiandae. Nisi, quo ex! +
+
+
+
+ +
+ WC Stepper + + + Step1 + (completed) + + + + + + Step 2 + (default) + + + + + + Step 3 + (Optional) + Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur + soluta nulla asperiores, officia ullam recusandae voluptatem omnis + perferendis vitae non magni magnam praesentium placeat nemo quas + repudiandae. Nisi, quo ex! + + + + + Step 4 + (disabled) +
+ Tabbable content +
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur + soluta nulla asperiores, officia ullam recusandae voluptatem omnis + perferendis vitae non magni magnam praesentium placeat nemo quas + repudiandae. Nisi, quo ex! +
+
+
+
diff --git a/src/app/stepper-showcase/stepper-showcase.sample.scss b/src/app/stepper-showcase/stepper-showcase.sample.scss new file mode 100644 index 00000000000..885b25fa260 --- /dev/null +++ b/src/app/stepper-showcase/stepper-showcase.sample.scss @@ -0,0 +1,19 @@ +.nav-buttons { + margin: 40px 0; + + > * { + margin-right: 16px; + } +} + +.sample-stepper-wrapper { + margin: 16px 0; + padding: 16px; + border: 1px solid rgba(54, 54, 54, .43); +} + +strong { + display: block; + text-align: center; + margin-bottom: 24px; +} diff --git a/src/app/stepper-showcase/stepper-showcase.sample.ts b/src/app/stepper-showcase/stepper-showcase.sample.ts new file mode 100644 index 00000000000..ba2de9d4fbf --- /dev/null +++ b/src/app/stepper-showcase/stepper-showcase.sample.ts @@ -0,0 +1,16 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { NgIf } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { IgxButtonDirective, IgxButtonGroupComponent, IgxInputGroupComponent, IgxLabelDirective, IgxInputDirective, IgxSuffixDirective, IgxSwitchComponent, IgxStepActiveIndicatorDirective, IgxIconComponent, IgxStepComponent, IgxStepIndicatorDirective, IgxStepTitleDirective, IgxStepSubtitleDirective, IgxStepContentDirective, IgxAvatarComponent, IgxBadgeComponent, IgxTimePickerComponent, IgxSelectComponent, IgxSelectItemComponent, IgxPrefixDirective, IgxHintDirective, IgxStepperComponent } from 'igniteui-angular'; +import { defineComponents, IgcStepperComponent, IgcButtonComponent, IgcInputComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcStepperComponent, IgcButtonComponent, IgcInputComponent); + +@Component({ + templateUrl: 'stepper-showcase.sample.html', + styleUrls: ['stepper-showcase.sample.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxButtonDirective, IgxButtonGroupComponent, IgxInputGroupComponent, IgxLabelDirective, FormsModule, IgxInputDirective, IgxSuffixDirective, IgxSwitchComponent, IgxStepperComponent, IgxStepActiveIndicatorDirective, IgxIconComponent, IgxStepComponent, IgxStepIndicatorDirective, IgxStepTitleDirective, IgxStepSubtitleDirective, IgxStepContentDirective, NgIf, IgxAvatarComponent, IgxBadgeComponent, IgxTimePickerComponent, ReactiveFormsModule, IgxSelectComponent, IgxSelectItemComponent, IgxPrefixDirective, IgxHintDirective] +}) +export class IgxStepperShowcaseSampleComponent {} diff --git a/src/app/switch-showcase/switch-showcase.sample.html b/src/app/switch-showcase/switch-showcase.sample.html new file mode 100644 index 00000000000..bc741064b2a --- /dev/null +++ b/src/app/switch-showcase/switch-showcase.sample.html @@ -0,0 +1,31 @@ +
+
+

Angular Switch

+ + + Label + +
+ +
+

WC Switch

+ + + Label + +
+
diff --git a/src/app/switch-showcase/switch-showcase.sample.scss b/src/app/switch-showcase/switch-showcase.sample.scss new file mode 100644 index 00000000000..9df693180a4 --- /dev/null +++ b/src/app/switch-showcase/switch-showcase.sample.scss @@ -0,0 +1,4 @@ +.wrapper { + display: inline-grid; + grid-template-columns: 1fr 1fr; +} diff --git a/src/app/switch-showcase/switch-showcase.sample.ts b/src/app/switch-showcase/switch-showcase.sample.ts new file mode 100644 index 00000000000..6f9be730ced --- /dev/null +++ b/src/app/switch-showcase/switch-showcase.sample.ts @@ -0,0 +1,96 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from '@angular/core'; +import { IgxSwitchComponent } from 'igniteui-angular'; +import { defineComponents, IgcSwitchComponent} from "igniteui-webcomponents"; +import { PropertyPanelConfig } from '../properties-panel/properties-panel.component'; +import { PropertyChangeService } from '../properties-panel/property-change.service'; + +defineComponents(IgcSwitchComponent); + +@Component({ + selector: 'app-switch-showcase-sample', + styleUrls: ['switch-showcase.sample.scss'], + templateUrl: 'switch-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxSwitchComponent] +}) +export class SwitchShowcaseSampleComponent implements OnInit { + public panelConfig : PropertyPanelConfig = { + required: { + control: { + type: 'boolean', + defaultValue: false + } + }, + disabled: { + control: { + type: 'boolean', + defaultValue: false + } + }, + invalid: { + control: { + type: 'boolean', + defaultValue: false + } + }, + checked: { + control: { + type: 'boolean', + defaultValue: false + } + }, + labelPosition: { + control: { + type: 'button-group', + options: ['before', 'after'], + defaultValue: 'after' + } + }, + name: { + control: { + type: 'text' + } + }, + value: { + control: { + type: 'text' + } + }, + } + + constructor(private propertyChangeService : PropertyChangeService) {} + + public ngOnInit() { + this.propertyChangeService.setPanelConfig(this.panelConfig); + } + + protected get required() { + return this.propertyChangeService.getProperty('required'); + } + + protected get disabled() { + return this.propertyChangeService.getProperty('disabled'); + } + + protected get invalid() { + return this.propertyChangeService.getProperty('invalid'); + } + + protected get checked() { + return this.propertyChangeService.getProperty('checked'); + } + + protected get labelPosition() { + return this.propertyChangeService.getProperty('labelPosition'); + } + + protected get name() { + return this.propertyChangeService.getProperty('name'); + } + + protected get value() { + return this.propertyChangeService.getProperty('value'); + } + +} diff --git a/src/app/tabs-showcase/tabs-showcase.sample.html b/src/app/tabs-showcase/tabs-showcase.sample.html new file mode 100644 index 00000000000..d6998a756ce --- /dev/null +++ b/src/app/tabs-showcase/tabs-showcase.sample.html @@ -0,0 +1,99 @@ +
+
+ Angular Tabs + + + + folder + Tab 1 + + + Content 1 + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius sapien ligula. + + + + + + folder + Tab 2 + + +
+ + + +

{{contact.text}}

+ {{contact.phone}} + phone +
+
+
+
+
+ + + + folder + Tab 3 Lorem ipsum dolor + + + Content 3 + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius sapien ligula. + + + + + + folder + Tab 4 Disabled + + + Content 4 + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius sapien ligula. + + +
+
+ +
+ WC Tabs + + + folder + Tab 1 + + + folder + Tab 2 + + + folder + Tab 3 Lorem ipsum dolor + + + folder + Tab 4 disabled + + Content 1 Lorem ipsum dolor sit, amet consectetur adipisicing elit. Repellat, eos? + +
+ + + +

{{contact.text}}

+ {{contact.phone}} + phone +
+
+
+
+ Content 3 Lorem ipsum dolor sit amet consectetur adipisicing elit. At, doloremque? +
+
+
diff --git a/src/app/tabs-showcase/tabs-showcase.sample.scss b/src/app/tabs-showcase/tabs-showcase.sample.scss new file mode 100644 index 00000000000..cf735fa6ed1 --- /dev/null +++ b/src/app/tabs-showcase/tabs-showcase.sample.scss @@ -0,0 +1,10 @@ +.items-wrapper { + height: 400px; +} + +strong { + color: hsla(var(--ig-secondary-500)); + display: block; + text-align: center; + margin-bottom: 24px; +} diff --git a/src/app/tabs-showcase/tabs-showcase.sample.ts b/src/app/tabs-showcase/tabs-showcase.sample.ts new file mode 100644 index 00000000000..add86fddf41 --- /dev/null +++ b/src/app/tabs-showcase/tabs-showcase.sample.ts @@ -0,0 +1,48 @@ +import {Component, CUSTOM_ELEMENTS_SCHEMA, ViewEncapsulation} from '@angular/core'; +import { NgFor } from '@angular/common'; +import { IgxAvatarComponent, IgxButtonDirective, IgxIconButtonDirective, IgxIconComponent, IgxListActionDirective, IgxListComponent, IgxListItemComponent, IgxListLineSubTitleDirective, IgxListLineTitleDirective, IgxListThumbnailDirective, IgxPrefixDirective, IgxRippleDirective, IgxSuffixDirective, IgxTabContentComponent, IgxTabHeaderComponent, IgxTabHeaderIconDirective, IgxTabHeaderLabelDirective, IgxTabItemComponent, IgxTabsComponent } from 'igniteui-angular'; +import { defineComponents, IgcTabsComponent, IgcTabComponent, IgcTabPanelComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcTabsComponent, IgcTabComponent, IgcTabPanelComponent); + +@Component({ + selector: 'app-tabs-showcase-sample', + styleUrls: ['tabs-showcase.sample.scss'], + templateUrl: 'tabs-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + encapsulation: ViewEncapsulation.None, + standalone: true, + imports: [IgxButtonDirective, IgxTabsComponent, IgxTabItemComponent, IgxTabHeaderComponent, IgxRippleDirective, IgxIconComponent, IgxTabHeaderIconDirective, IgxIconButtonDirective, IgxTabHeaderLabelDirective, IgxTabContentComponent, IgxListComponent, NgFor, IgxListItemComponent, IgxAvatarComponent, IgxListThumbnailDirective, IgxListLineTitleDirective, IgxListLineSubTitleDirective, IgxListActionDirective, IgxPrefixDirective, IgxSuffixDirective] +}) +export class TabsShowcaseSampleComponent { + public contacts: any[] = [{ + avatar: 'assets/images/avatar/1.jpg', + favorite: true, + key: '1', + link: '#', + phone: '770-504-2217', + text: 'Terrance Orta' + }, { + avatar: 'assets/images/avatar/2.jpg', + favorite: false, + key: '2', + link: '#', + phone: '423-676-2869', + text: 'Richard Mahoney' + }, { + avatar: 'assets/images/avatar/3.jpg', + favorite: false, + key: '3', + link: '#', + phone: '859-496-2817', + text: 'Donna Price' + }, { + avatar: 'assets/images/avatar/4.jpg', + favorite: false, + key: '4', + link: '#', + phone: '901-747-3428', + text: 'Lisa Landers' + }]; +} + diff --git a/src/app/toast-showcase/toast-showcase.sample.html b/src/app/toast-showcase/toast-showcase.sample.html new file mode 100644 index 00000000000..f03d5152ac1 --- /dev/null +++ b/src/app/toast-showcase/toast-showcase.sample.html @@ -0,0 +1,25 @@ +
+ +
+

Angular Toast vs WebComponents Toast

+
+ +
+
+
+ +
+ + + Angular Toast will self-destruct in 4 seconds. + + + + WC Toast will self-destruct in 4 seconds. + diff --git a/src/app/toast-showcase/toast-showcase.sample.scss b/src/app/toast-showcase/toast-showcase.sample.scss new file mode 100644 index 00000000000..d14115563f6 --- /dev/null +++ b/src/app/toast-showcase/toast-showcase.sample.scss @@ -0,0 +1,19 @@ +.columns-container { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + column-gap: 16px; + margin: 16px; +} + +.column { + margin: 16px 0; +} + +.btn-group { + display: flex; + margin-top: 16px; +} + +button { + margin-right: 16px; +} diff --git a/src/app/toast-showcase/toast-showcase.sample.ts b/src/app/toast-showcase/toast-showcase.sample.ts new file mode 100644 index 00000000000..4584d535acc --- /dev/null +++ b/src/app/toast-showcase/toast-showcase.sample.ts @@ -0,0 +1,15 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { IgxButtonDirective, IgxOverlayOutletDirective, IgxRippleDirective, IgxToastComponent } from 'igniteui-angular'; +import { defineComponents, IgcToastComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcToastComponent); + +@Component({ + selector: 'app-toast-showcase-sample', + styleUrls: ['toast-showcase.sample.scss'], + templateUrl: 'toast-showcase.sample.html', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [IgxButtonDirective, IgxRippleDirective, IgxOverlayOutletDirective, IgxToastComponent] +}) +export class ToastShowcaseSampleComponent {} diff --git a/src/app/tree-showcase/tree-showcase.sample.html b/src/app/tree-showcase/tree-showcase.sample.html new file mode 100644 index 00000000000..f1c3a768d4a --- /dev/null +++ b/src/app/tree-showcase/tree-showcase.sample.html @@ -0,0 +1,39 @@ + + +
+
+ Angular Tree + + + {{ node.CompanyName }} + + {{ child.CompanyName }} + + {{ leafchild.CompanyName }} + + + + +
+ +
+ WC Tree + + + + + + + + + + + + + + + + + +
+
diff --git a/src/app/tree-showcase/tree-showcase.sample.scss b/src/app/tree-showcase/tree-showcase.sample.scss new file mode 100644 index 00000000000..385d1c2f89d --- /dev/null +++ b/src/app/tree-showcase/tree-showcase.sample.scss @@ -0,0 +1,16 @@ +.wrapper { + display: grid; + grid-template-columns: 1fr 1fr; +} + +.tree-container { + margin: 16px; + max-width: 350px; +} + +strong { + color: hsla(var(--ig-secondary-500)); + display: block; + margin-top: 16px; + margin-bottom: 24px; +} \ No newline at end of file diff --git a/src/app/tree-showcase/tree-showcase.sample.ts b/src/app/tree-showcase/tree-showcase.sample.ts new file mode 100644 index 00000000000..953bacbc1c6 --- /dev/null +++ b/src/app/tree-showcase/tree-showcase.sample.ts @@ -0,0 +1,347 @@ +import { useAnimation } from '@angular/animations'; +import { NgFor, NgTemplateOutlet, NgIf, AsyncPipe } from '@angular/common'; +import { AfterViewInit, ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { + IgxTreeNodeComponent, + IgxTreeSearchResolver, + IgxTreeComponent, + ITreeNodeTogglingEventArgs, + ITreeNodeToggledEventArgs, + ITreeNodeSelectionEvent, + IgxTreeNode, + IgxButtonDirective, + IgxButtonGroupComponent, + IgxIconComponent, + IgxInputDirective, + IgxInputGroupComponent, + IgxLabelDirective, + IgxLayoutDirective, + IgxSwitchComponent, + IgxTreeNodeLinkDirective, + IgxTreeExpandIndicatorDirective +} from 'igniteui-angular'; +import { Subject } from 'rxjs'; +import { cloneDeep } from 'lodash-es'; +import { HIERARCHICAL_SAMPLE_DATA } from '../shared/sample-data'; +import { growVerIn, growVerOut } from 'igniteui-angular/animations'; +import { SizeSelectorComponent } from '../size-selector/size-selector.component'; +import { defineComponents, IgcTreeComponent, IgcTreeItemComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcTreeComponent, IgcTreeItemComponent); + +interface CompanyData { + ID: string; + CompanyName?: string; + ContactName?: string; + ContactTitle?: string; + Address?: string; + City?: string; + Region?: string; + PostalCode?: string; + Country?: string; + Phone?: string; + Fax?: string; + ChildCompanies?: CompanyData[]; + selected?: boolean; + expanded?: boolean; + disabled?: boolean; + active?: boolean; +} + +@Component({ + selector: 'app-tree-showcase-sample', + templateUrl: 'tree-showcase.sample.html', + styleUrls: ['tree-showcase.sample.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + imports: [ + IgxLayoutDirective, + IgxInputGroupComponent, + IgxInputDirective, + IgxButtonDirective, + IgxLabelDirective, + FormsModule, + IgxSwitchComponent, + IgxButtonGroupComponent, + IgxTreeComponent, + IgxTreeNodeComponent, + NgFor, + IgxTreeNodeLinkDirective, + IgxTreeExpandIndicatorDirective, + NgTemplateOutlet, + IgxIconComponent, + NgIf, + AsyncPipe, + SizeSelectorComponent + ] +}) +export class TreeShowcaseSampleComponent implements AfterViewInit { + @ViewChild('tree1', { static: true }) + public tree: IgxTreeComponent; + + @ViewChild('test', { static: true }) + public testNode: IgxTreeNodeComponent; + + public selectionModes = []; + + public selectionMode = 'Cascading'; + + public animationDuration = 400; + + public data: CompanyData[]; + + public singleBranchExpand = false; + + public asyncItems = new Subject(); + public loadDuration = 6000; + private iteration = 0; + private addedIndex = 0; + + private initData: CompanyData[]; + + constructor(private cdr: ChangeDetectorRef) { + this.selectionModes = [ + { label: 'None', selectMode: 'None', selected: this.selectionMode === 'None', togglable: true }, + { label: 'Multiple', selectMode: 'Multiple', selected: this.selectionMode === 'Multiple', togglable: true }, + { label: 'Cascade', selectMode: 'Cascading', selected: this.selectionMode === 'Cascading', togglable: true } + ]; + this.data = cloneDeep(HIERARCHICAL_SAMPLE_DATA); + this.initData = cloneDeep(HIERARCHICAL_SAMPLE_DATA); + this.mapData(this.data); + } + + public setDummy() { + this.data = generateHierarchicalData('ChildCompanies', 3, 6, 0); + } + + public handleNodeExpanding(_event: ITreeNodeTogglingEventArgs) { + // do something w/ data + } + + public handleNodeExpanded(_event: ITreeNodeToggledEventArgs) { + // do something w/ data + } + + public handleNodeCollapsing(_event: ITreeNodeTogglingEventArgs) { + // do something w/ data + } + + public handleNodeCollapsed(_event: ITreeNodeToggledEventArgs) { + // do something w/ data + } + + + public addDataChild(key: string) { + const targetNode = this.getNodeByName(key); + if (!targetNode.data.ChildCompanies) { + targetNode.data.ChildCompanies = []; + } + const data = targetNode.data.ChildCompanies; + data.push(Object.assign({}, data[data.length - 1], + { CompanyName: `Added ${this.addedIndex++}`, selected: this.addedIndex % 2 === 0, ChildCompanies: [] })); + this.cdr.detectChanges(); + } + + public deleteLastChild(key: string) { + const targetNode = this.getNodeByName(key); + if (!targetNode.data.ChildCompanies) { + targetNode.data.ChildCompanies = []; + } + const data = targetNode.data.ChildCompanies; + data.splice(data.length - 1, 1); + } + + public deleteNodesFromParent(key: string, deleteNodes: string) { + const parent = this.getNodeByName(key); + const nodeIds = deleteNodes.split(';'); + nodeIds.forEach((nodeId) => { + const index = parent.data.ChildCompanies.findIndex(e => e.ID === nodeId); + parent.data.ChildCompanies.splice(index, 1); + }); + } + + public addSeveralNodes(key: string) { + const targetNode = this.getNodeByName(key); + if (!targetNode.data.ChildCompanies) { + targetNode.data.ChildCompanies = []; + } + const arr = [{ + ID: 'Some1', + CompanyName: 'Test 1', + selected: false, + ChildCompanies: [{ + ID: 'Some4', + CompanyName: 'Test 5', + selected: true, + }] + }, + { + ID: 'Some2', + CompanyName: 'Test 2', + selected: false + }, + { + ID: 'Some3', + CompanyName: 'Test 3', + selected: false + }]; + this.getNodeByName(key).data.ChildCompanies = arr; + this.cdr.detectChanges(); + } + + public handleRemote(node: IgxTreeNodeComponent, event: boolean) { + console.log(event); + node.loading = true; + setTimeout(() => { + const newData: CompanyData[] = []; + for (let i = 0; i < 10; i++) { + newData.push({ + ID: `Remote ${i}`, + CompanyName: `Remote ${i}` + }); + } + node.loading = false; + this.asyncItems.next(newData); + }, this.loadDuration); + } + + public ngAfterViewInit() { + this.tree.nodes.toArray().forEach(node => { + node.selectedChange.subscribe(() => {}); + }); + } + + public toggleSelectionMode() { } + + public addItem() { + const newArray = [...this.data]; + const children = Math.floor(Math.random() * 4); + const createChildren = (count: number): CompanyData[] => { + const array = []; + for (let i = 0; i < count; i++) { + this.iteration++; + array.push({ + ID: `TEST${this.iteration}`, + CompanyName: `TEST${this.iteration}` + }); + } + return array; + }; + + this.iteration++; + newArray.push({ + ID: `TEST${this.iteration}`, + CompanyName: `TEST${this.iteration}`, + ChildCompanies: createChildren(children) + }); + this.data = newArray; + } + + public resetData() { + this.data = [...this.initData]; + } + + public get animationSettings() { + return { + openAnimation: useAnimation(growVerIn, { + params: { + duration: `${this.animationDuration}ms` + } + }), + closeAnimation: useAnimation(growVerOut, { + params: { + duration: `${this.animationDuration}ms` + } + }) + }; + } + + public selectSpecific() { + this.tree.nodes.toArray()[0].selected = true; + this.tree.nodes.toArray()[14].selected = true; + this.tree.nodes.toArray()[1].selected = true; + this.tree.nodes.toArray()[4].selected = true; + } + + public selectAll() { + this.tree.nodes.toArray().forEach(node => node.selected = true); + } + + public deselectSpecific() { + const arr = [ + this.tree.nodes.toArray()[0], + this.tree.nodes.toArray()[14], + this.tree.nodes.toArray()[1], + this.tree.nodes.toArray()[4] + ]; + this.tree.deselectAll(arr); + } + + public deselectAll() { + this.tree.deselectAll(); + } + + public changeNodeSelectionState() { + this.tree.nodes.toArray()[8].selected = !this.tree.nodes.toArray()[8].selected; + } + + public changeNodeData() { + this.tree.nodes.toArray()[8].data.selected = !this.tree.nodes.toArray()[8].data.selected; + this.cdr.detectChanges(); + } + + public nodeSelection(event: ITreeNodeSelectionEvent) { + // console.log(event); + if (event.newSelection.find(x => x.data.ID === 'igxTreeNode_1')) { + //event.newSelection = [...event.newSelection, this.tree.nodes.toArray()[0]]; + } + } + + public customSearch(term: string) { + const searchResult = this.tree.findNodes(term, this.containsComparer); + // console.log(searchResult); + return searchResult; + } + + public activeNodeChanged(_event: IgxTreeNode) { + // active node changed + } + + public keydown(_event: KeyboardEvent) { + // console.log(evt); + } + + private mapData(data: any[]) { + data.forEach(x => { + x.selected = false; + if (x.hasOwnProperty('ChildCompanies') && x.ChildCompanies.length) { + this.mapData(x.ChildCompanies); + } + }); + } + + private containsComparer: IgxTreeSearchResolver = + (term: any, node: IgxTreeNodeComponent) => node.data?.ID?.toLowerCase()?.indexOf(term.toLowerCase()) > -1; + + private getNodeByName(key: string) { + return this.tree.findNodes(key, (_term: string, n: IgxTreeNodeComponent) => n.data?.ID === _term)[0]; + } +} + + +const generateHierarchicalData = (childKey: string, level = 7, children = 6, iter = 0): any[] => { + const returnArray = []; + if (level === 0) { + return returnArray; + } + for (let i = 0; i < children; i++) { + // create Root member + iter++; + returnArray.push({ + ID: `Dummy${iter}`, CompanyName: `Dummy-${iter}`, + [childKey]: generateHierarchicalData(childKey, children, level - 1) + }); + } + return returnArray; +}; diff --git a/src/styles/_app-layout.scss b/src/styles/_app-layout.scss index 528e7e56f55..b8f1cb11ada 100644 --- a/src/styles/_app-layout.scss +++ b/src/styles/_app-layout.scss @@ -47,7 +47,7 @@ .content { position: relative; - overflow-y: scroll; + overflow-y: auto; perspective: 5000px; padding-top: 90px; flex: 1;