Skip to content

Commit

Permalink
feat(select): add sample and default style
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickjahr committed Apr 18, 2024
1 parent c326877 commit 680599a
Show file tree
Hide file tree
Showing 21 changed files with 324 additions and 169 deletions.
18 changes: 14 additions & 4 deletions apps/demo-app/src/app/app.routes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { Route } from '@angular/router';
import { SelectSampleComponent } from './pages/select-sample/select-sample.component';
import { SelectDefaultComponent } from './pages/select-sample/select-default/select-default.component';
import { SelectWithStyleComponent } from './pages/select-sample/select-with-style/select-with-style.component';

const UUID_REGEX = /^[a-z,0-9,-]{36,36}$/;

Expand All @@ -17,10 +20,17 @@ export const appRoutes: Route[] = [
},
{
path: 'select',
loadComponent: () =>
import('./pages/select-sample/select-sample.component').then(
(m) => m.SelectSampleComponent
),
component: SelectSampleComponent,
children: [
{
path: '',
component: SelectDefaultComponent,
},
{
path: 'with-style',
component: SelectWithStyleComponent,
},
],
},
{
path: 'list-sample',
Expand Down
5 changes: 1 addition & 4 deletions apps/demo-app/src/app/pages/overview/overview.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
<app-card label="WidgetComponent">
<span>Lorem ipsum dolor...</span>
</app-card>
<app-card
label="Select component"
[routes]="[{ route: '/select', label: 'Select component' }]"
>
<app-card label="Select component" [routes]="selectRoutes">
<span>Lorem ipsum dolor...</span>
</app-card>
11 changes: 11 additions & 0 deletions apps/demo-app/src/app/pages/overview/overview.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ export class OverviewComponent {
},
];

readonly selectRoutes = [
{
route: '/select/with-style',
label: 'Select Sample with styling',
},
{
route: '/select',
label: 'Select Sample Headless Default',
},
];

readonly widgetLinks = [
{
route: '/widget-sample',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<sk-select [(ngModel)]="selectedValue">
<span skSelectPlaceholder>Select option</span>
<span skSelectLabel>{{ selectedValue?.label }}</span>
@for (option of options; track option.value) {
<sk-select-option [value]="option">
{{ option.label }}
</sk-select-option>
}
</sk-select>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SelectDemoOption } from '../select-sample.component';
import {
faBell,
faCog,
faEnvelope,
faGlobe,
faHeart,
faHome,
faKey,
faLock,
faStar,
faUser,
} from '@fortawesome/free-solid-svg-icons';
import { SelectComponent, SelectOptionComponent } from '@qupaya/sketch';
import { FormsModule } from '@angular/forms';

@Component({
selector: 'app-select-default',
standalone: true,
imports: [CommonModule, SelectComponent, SelectOptionComponent, FormsModule],
templateUrl: './select-default.component.html',
})
export class SelectDefaultComponent {
readonly options: SelectDemoOption[] = [
{ label: 'Option 1', icon: faHome, value: 1 },
{ label: 'Option 2', icon: faUser, value: 2 },
{ label: 'Option 3', icon: faCog, value: 3 },
{ label: 'Option 4', icon: faHeart, value: 4 },
{ label: 'Option 5', icon: faStar, value: 5 },
{ label: 'Option 6', icon: faBell, value: 6 },
{ label: 'Option 7', icon: faEnvelope, value: 7 },
{ label: 'Option 8', icon: faGlobe, value: 8 },
{ label: 'Option 9', icon: faLock, value: 9 },
{ label: 'Option 10', icon: faKey, value: 10 },
];
selectedValue?: SelectDemoOption;
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,25 +1 @@
Multiple: <input type="checkbox" (change)="switchMultiple($event)" />

<sk-select
[ngModel]="value"
(ngModelChange)="valueChanged($event)"
[multiple]="multiple()"
[animationDelay]="250"
[closeOnSelect]="true"
(open)="showAnimation.set($event)"
>
<div class="sk-label" skSelectPlaceholder>Please select an option</div>
<div class="sk-label" skSelectLabel>
<div class="sk-label-item">
@for (item of selectedValues(); track item.value) { @if
(selectedValues().length <= 1) {
<fa-icon [icon]="item.icon"></fa-icon>
}
{{ item.label }}
}
</div>
</div>

<app-select-options-sample [options]="options" [show]="showAnimation()">
</app-select-options-sample>
</sk-select>
<router-outlet></router-outlet>
Original file line number Diff line number Diff line change
@@ -1,27 +1,7 @@
import { Component, effect, signal } from '@angular/core';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SelectComponent, SelectOptionComponent } from '@qupaya/sketch';
import { FormsModule } from '@angular/forms';
import { SelectOptionsSampleComponent } from './select-options-sample/select-options-sample.component';
import { query, transition, trigger } from '@angular/animations';
import {
slideDeleteAnimation,
slideFadeAnimationFactory,
} from '../../animations/slide.animation';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import {
faBell,
faCog,
faEnvelope,
faGlobe,
faHeart,
faHome,
faKey,
faLock,
faStar,
faUser,
} from '@fortawesome/free-solid-svg-icons';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { RouterOutlet } from '@angular/router';

export interface SelectDemoOption {
label: string;
Expand All @@ -32,78 +12,7 @@ export interface SelectDemoOption {
@Component({
selector: 'app-select-sample',
standalone: true,
imports: [
CommonModule,
SelectComponent,
SelectOptionComponent,
FormsModule,
SelectOptionsSampleComponent,
FaIconComponent,
],
imports: [CommonModule, RouterOutlet],
templateUrl: './select-sample.component.html',
styleUrl: './select-sample.component.css',
animations: [
trigger('animation', [
transition(
'hidden => visible',
query('.sk-option', slideFadeAnimationFactory(), {
optional: true,
})
),
transition(
'visible => hidden',
query('.sk-option', slideDeleteAnimation(), {
optional: true,
})
),
]),
],
})
export class SelectSampleComponent {
readonly showAnimation = signal(false);
readonly animateOptions = signal<'hidden' | 'visible'>('hidden');
readonly multiple = signal(false);
readonly selectedValues = signal<SelectDemoOption[]>([]);
readonly options: SelectDemoOption[] = [
{ label: 'Option 1', icon: faHome, value: 1 },
{ label: 'Option 2', icon: faUser, value: 2 },
{ label: 'Option 3', icon: faCog, value: 3 },
{ label: 'Option 4', icon: faHeart, value: 4 },
{ label: 'Option 5', icon: faStar, value: 5 },
{ label: 'Option 6', icon: faBell, value: 6 },
{ label: 'Option 7', icon: faEnvelope, value: 7 },
{ label: 'Option 8', icon: faGlobe, value: 8 },
{ label: 'Option 9', icon: faLock, value: 9 },
{ label: 'Option 10', icon: faKey, value: 10 },
];

value: number | number[] | undefined;

switchMultiple(event: Event): void {
if (event?.target && 'checked' in event.target) {
this.multiple.set(event.target.checked as boolean);
}
}

valueChanged(value: number | number[] | undefined): void {
if (!value) {
this.selectedValues.set([]);
}
if (Array.isArray(value)) {
this.selectedValues.set(
this.options.filter((option) => value.includes(option.value))
);
} else {
const item = this.options.find((option) => option.value === value);
this.selectedValues.set(item ? [item] : []);
}
this.value = value;
}

protected readonly runAnimation = effect(
() => this.animateOptions.set(this.showAnimation() ? 'visible' : 'hidden'),
{ allowSignalWrites: true }
);

protected readonly Array = Array;
}
export class SelectSampleComponent {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Component, effect, HostBinding, input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { query, transition, trigger } from '@angular/animations';
import { SelectOptionComponent } from '@qupaya/sketch';
import { slideFadeAnimationFactory } from '../../../animations/slide.animation';
import { fadeFactory } from '../../../animations/fade.animations';
import { slideFadeAnimationFactory } from '../../../../animations/slide.animation';
import { fadeFactory } from '../../../../animations/fade.animations';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { SelectDemoOption } from '../select-sample.component';
import { SelectDemoOption } from '../../select-sample.component';

@Component({
selector: 'app-select-options-sample',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
sk-select {
--sk-select-label-background: rgb(255 255 255 / 10%);
--sk-select-label-color: #fefefe;
--sk-select-label-padding: 0;
--sk-select-label-border-radius: 8px;
--sk-select-label-border-color: transparent;
--sk-select-label-border-focus-color: deeppink;

display: block;
margin-top: 1rem;
}

.sk-label {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.25rem;
border-radius: 8px;
padding: 0.5rem 1rem;
box-shadow: rgb(255 255 255 / 5%) 0 6px 24px 0,
rgb(255 255 255 / 8%) 0 0 0 1px;
}

.sk-label .sk-arrow {
transform: rotate(0);
transition: transform 0.3s ease-in-out;
}

.sk-label.open .sk-arrow {
transform: rotate(180deg);
}

.sk-label .sk-label-item {
display: flex;
align-items: center;
gap: 0.25rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 90%;
}

fa-icon {
width: 1.5rem;
height: 1.5rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Multiple: <input type="checkbox" (change)="switchMultiple($event)" />

<sk-select
[ngModel]="value"
(ngModelChange)="valueChanged($event)"
[multiple]="multiple()"
[animationDelay]="250"
[closeOnSelect]="!multiple()"
(open)="showAnimation.set($event)"
>
<div class="sk-label" [class.open]="showAnimation()" skSelectPlaceholder>
<span>Please select an option</span>
<fa-icon class="sk-arrow" [icon]="faArrowAltCircleDown"></fa-icon>
</div>
<div class="sk-label" [class.open]="showAnimation()" skSelectLabel>
<div class="sk-label-item">
@for (item of selectedValues(); track item.value) { @if
(selectedValues().length <= 1) {
<fa-icon [icon]="item.icon"></fa-icon>
}
{{ item.label }}
}
</div>
<fa-icon class="sk-arrow" [icon]="faArrowAltCircleDown"></fa-icon>
</div>

<app-select-options-sample [options]="options" [show]="showAnimation()">
</app-select-options-sample>
</sk-select>
Loading

0 comments on commit 680599a

Please sign in to comment.