Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/showcase/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ const childRoutes: Routes = [
m => m.SliderComponent
)
},
{
path: COMPONENTS_ROUTES.SWITCH.substring(1),
loadComponent: () =>
import("./components/switch/switch.component").then(
m => m.SwitchComponent
)
},
{
path: COMPONENTS_ROUTES.TAB.substring(1),
loadComponent: () =>
Expand Down
3 changes: 3 additions & 0 deletions packages/showcase/src/app/bundles-and-url-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const COMPONENTS_ROUTES = {
SEARCH: "/components/search",
SEGMENTED_CONTROL: "/components/segmented-control",
SLIDER: "/components/slider",
SWITCH: "/components/switch",
TAB: "/components/tab",
TABULAR_GRID: "/components/tabular-grid",
TOOLTIP: "/components/tooltip",
Expand Down Expand Up @@ -53,6 +54,7 @@ export const bundleMapping = {
[COMPONENTS_ROUTES.SEARCH]: "components/edit",
[COMPONENTS_ROUTES.SEGMENTED_CONTROL]: "components/segmented-control",
[COMPONENTS_ROUTES.SLIDER]: "components/slider",
[COMPONENTS_ROUTES.SWITCH]: "components/switch",
[COMPONENTS_ROUTES.TAB]: "components/tab",
[COMPONENTS_ROUTES.TABULAR_GRID]: "components/tabular-grid",
[COMPONENTS_ROUTES.TOOLTIP]: "components/tooltip",
Expand Down Expand Up @@ -83,6 +85,7 @@ export const URL_MAPPING = {
[COMPONENTS_ROUTES.SEARCH]: "Search",
[COMPONENTS_ROUTES.SEGMENTED_CONTROL]: "Segmented Control",
[COMPONENTS_ROUTES.SLIDER]: "Slider",
[COMPONENTS_ROUTES.SWITCH]: "Switch",
[COMPONENTS_ROUTES.TAB]: "Tab",
[COMPONENTS_ROUTES.TABULAR_GRID]: "Tabular Grid",
[COMPONENTS_ROUTES.TOOLTIP]: "Tooltip",
Expand Down
105 changes: 105 additions & 0 deletions packages/showcase/src/app/components/switch/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import type { ComponentMetadata } from "../../../common/types";

const CHECKED_CAPTION = "On";
const UNCHECKED_CAPTION = "Off";
const CHECKED_VALUE = "On";
const UNCHECKED_VALUE = "Off";

export const switchMetadata = {
title: "Switch",
description:
"A switch component is a user interface control designed to toggle between two states, typically on and off. It provides a clear, accessible way for users to make binary choices, often used for settings, preferences, or enabling features, and enhances interaction by offering immediate visual feedback.",
codeSnippets: {
smallChecked: {
linkId: "small-checkewd",
title: "1.1. Small: Checked",
template: {
tag: "ch-switch",
class: "switch-small",
properties: [
{ name: "checkedCaption", value: CHECKED_CAPTION },
{ name: "unCheckedCaption", value: UNCHECKED_CAPTION },
{ name: "checkedValue", value: CHECKED_VALUE },
{ name: "unCheckedValue", value: UNCHECKED_VALUE }
]
}
},

smallUnchecked: {
linkId: "small-uncheckewd",
title: "1.2. Small: Unchecked",
template: {
tag: "ch-switch",
class: "switch-small",
properties: [
{ name: "checkedCaption", value: CHECKED_CAPTION },
{ name: "unCheckedCaption", value: UNCHECKED_CAPTION },
{ name: "checkedValue", value: CHECKED_VALUE },
{ name: "unCheckedValue", value: UNCHECKED_VALUE }
]
}
},

smallDisabled: {
linkId: "small-disabled",
title: "1.3. Small: Disabled",
template: {
tag: "ch-switch",
class: "switch-small",
properties: [
{ name: "checkedCaption", value: CHECKED_CAPTION },
{ name: "unCheckedCaption", value: UNCHECKED_CAPTION },
{ name: "checkedValue", value: CHECKED_VALUE },
{ name: "unCheckedValue", value: UNCHECKED_VALUE },
{ name: "disabled", value: true, variable: true }
]
}
},

largeChecked: {
linkId: "large-checkewd",
title: "2.1. Large: Checked",
template: {
tag: "ch-switch",
class: "switch-large",
properties: [
{ name: "checkedCaption", value: CHECKED_CAPTION },
{ name: "unCheckedCaption", value: UNCHECKED_CAPTION },
{ name: "checkedValue", value: CHECKED_VALUE },
{ name: "unCheckedValue", value: UNCHECKED_VALUE }
]
}
},

largeUnchecked: {
linkId: "large-uncheckewd",
title: "2.2. Large: Unchecked",
template: {
tag: "ch-switch",
class: "switch-large",
properties: [
{ name: "checkedCaption", value: CHECKED_CAPTION },
{ name: "unCheckedCaption", value: UNCHECKED_CAPTION },
{ name: "checkedValue", value: CHECKED_VALUE },
{ name: "unCheckedValue", value: UNCHECKED_VALUE }
]
}
},

largeDisabled: {
linkId: "large-disabled",
title: "2.3. Large: Disabled",
template: {
tag: "ch-switch",
class: "switch-large",
properties: [
{ name: "checkedCaption", value: CHECKED_CAPTION },
{ name: "unCheckedCaption", value: UNCHECKED_CAPTION },
{ name: "checkedValue", value: CHECKED_VALUE },
{ name: "unCheckedValue", value: UNCHECKED_VALUE },
{ name: "disabled", value: true, variable: true }
]
}
}
}
} as const satisfies ComponentMetadata;
144 changes: 144 additions & 0 deletions packages/showcase/src/app/components/switch/switch.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<runtime-bundles [bundles]="['components/switch', 'components/checkbox']" />

<header>
<h1 class="heading-1">{{ metadata.title }}</h1>
</header>

<p class="body-regular-l">{{ metadata.description }}</p>

<ol class="filters elevation-1">
@for (switchEntry of this.switches().entries(); track switchEntry[0]) {
@let switchName = switchEntry[0];

<li class="filters-checkbox">
<ch-checkbox
class="checkbox"
[caption]="switchName"
[checkedValue]="'true'"
[unCheckedValue]="'false'"
[value]="switchEntry[1].toString()"
(input)="updateRenderedSwitch(switchName)($event)"
></ch-checkbox>
</li>
}
</ol>

<!-- switch small -->

<section aria-labelledby="switch-small">
<h2 id="switch-small" class="heading-2">
<a routerLink="." fragment="button-primary">1. Switch Small</a>
</h2>

@if (showSmallChecked()) {
<code-snippet
[codeSnippet]="codeSnippets.smallChecked"
[language]="'ts'"
[headingLevel]="3"
>
<ch-switch
class="switch-small"
[checkedCaption]="'On'"
[unCheckedCaption]="'Off'"
[checkedValue]="'checked'"
[unCheckedValue]="'unchecked'"
[value]="'checked'"
></ch-switch>
</code-snippet>
}

@if (showSmallUnchecked()) {
<code-snippet
[codeSnippet]="codeSnippets.smallUnchecked"
[language]="'ts'"
[headingLevel]="3"
>
<ch-switch
class="switch-small"
[checkedCaption]="'On'"
[unCheckedCaption]="'Off'"
[checkedValue]="'checked'"
[unCheckedValue]="'unchecked'"
[value]="'unchecked'"
></ch-switch>
</code-snippet>
}

@if (showSmallDisabled()) {
<code-snippet
[codeSnippet]="codeSnippets.smallDisabled"
[language]="'ts'"
[headingLevel]="3"
>
<ch-switch
class="switch-small"
[checkedCaption]="'On'"
[unCheckedCaption]="'Off'"
[checkedValue]="'checked'"
[unCheckedValue]="'unchecked'"
[value]="'checked'"
disabled
></ch-switch>
</code-snippet>
}
</section>

<!-- switch large -->

<section aria-labelledby="switch-large">
<h2 id="switch-large" class="heading-2">
<a routerLink="." fragment="button-primary">2. Switch Large</a>
</h2>

@if (showLargeChecked()) {
<code-snippet
[codeSnippet]="codeSnippets.largeChecked"
[language]="'ts'"
[headingLevel]="3"
>
<ch-switch
class="switch-large"
[checkedCaption]="'On'"
[unCheckedCaption]="'Off'"
[checkedValue]="'checked'"
[unCheckedValue]="'unchecked'"
[value]="'checked'"
></ch-switch>
</code-snippet>
}

@if (showLargeUnchecked()) {
<code-snippet
[codeSnippet]="codeSnippets.largeUnchecked"
[language]="'ts'"
[headingLevel]="3"
>
<ch-switch
class="switch-large"
[checkedCaption]="'On'"
[unCheckedCaption]="'Off'"
[checkedValue]="'checked'"
[unCheckedValue]="'unchecked'"
[value]="'unchecked'"
></ch-switch>
</code-snippet>
}

@if (showLargeDisabled()) {
<code-snippet
[codeSnippet]="codeSnippets.largeDisabled"
[language]="'ts'"
[headingLevel]="3"
>
<ch-switch
class="switch-large"
[checkedCaption]="'On'"
[unCheckedCaption]="'Off'"
[checkedValue]="'checked'"
[unCheckedValue]="'unchecked'"
[value]="'checked'"
disabled
></ch-switch>
</code-snippet>
}
</section>
91 changes: 91 additions & 0 deletions packages/showcase/src/app/components/switch/switch.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import {
ChangeDetectionStrategy,
Component,
computed,
input,
CUSTOM_ELEMENTS_SCHEMA,
inject
} from "@angular/core";
import { CommonModule } from "@angular/common";
import type { ChCheckboxCustomEvent } from "@genexus/chameleon-controls-library";

import { switchMetadata } from "./metadata";
import { CodeSnippetComponent } from "../../../user-controls/code-snippet/code-snippet.component";
import { RuntimeBundlesComponent } from "../../../user-controls/runtime-bundles/runtime-bundles.component";
import { Router } from "@angular/router";

@Component({
selector: "components-switch",
templateUrl: "./switch.component.html",
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, CodeSnippetComponent, RuntimeBundlesComponent],
host: { class: "main-content" },
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class SwitchComponent {
metadata = switchMetadata;
codeSnippets = switchMetadata.codeSnippets;
router = inject(Router);

hiddenSwitches = input<string>("");
/**
* This map is useful for rendering checkboxes to determine whether a
* migration section must be rendered.
*/
switches = computed(() => {
const newMigrations = new Map<string, boolean>([
["Small: Checked", true],
["Small: Unchecked", true],
["Small: Disabled", true],

["Large: Checked", true],
["Large: Unchecked", true],
["Large: Disabled", true]
]);

// Update the rendered migrations by watching changes for the
// hiddenSwitches query parameter
const hiddenSwitchesArray = this.hiddenSwitches()
? this.hiddenSwitches().split(",")
: [];

// Display all typographies
newMigrations.forEach((_, migrationName) =>
newMigrations.set(migrationName, true)
);

// Remove those typographies that must be hidden
hiddenSwitchesArray.forEach(hiddenMigrationName =>
newMigrations.set(hiddenMigrationName, false)
);

return newMigrations;
});

showSmallChecked = computed(() => this.switches().get("Small: Checked"));
showSmallUnchecked = computed(() => this.switches().get("Small: Unchecked"));
showSmallDisabled = computed(() => this.switches().get("Small: Disabled"));

showLargeChecked = computed(() => this.switches().get("Large: Checked"));
showLargeUnchecked = computed(() => this.switches().get("Large: Unchecked"));
showLargeDisabled = computed(() => this.switches().get("Large: Disabled"));

updateRenderedSwitch =
(switchName: string) => (event: ChCheckboxCustomEvent<string>) => {
this.switches().set(switchName, event.detail === "true");

let hiddenSwitchesQueryParm = "";

this.switches().forEach((renderDialog, switchName) => {
if (!renderDialog) {
hiddenSwitchesQueryParm +=
hiddenSwitchesQueryParm === "" ? switchName : "," + switchName;
}
});

this.router.navigate([], {
queryParams: { hiddenSwitches: hiddenSwitchesQueryParm },
queryParamsHandling: "merge" // Conserve other query parameters
});
};
}
Loading