Skip to content

Commit ae6b566

Browse files
authored
chore: Improved stories (#2159)
1 parent b4f3602 commit ae6b566

8 files changed

Lines changed: 1098 additions & 320 deletions

stories/chat.stories.ts

Lines changed: 387 additions & 200 deletions
Large diffs are not rendered by default.

stories/highlight.stories.ts

Lines changed: 228 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,41 @@ import { ifDefined } from 'lit/directives/if-defined.js';
44
import { createRef, ref } from 'lit/directives/ref.js';
55

66
import {
7+
IgcAvatarComponent,
8+
IgcButtonComponent,
9+
IgcCardActionsComponent,
10+
IgcCardComponent,
11+
IgcCardContentComponent,
12+
IgcCardHeaderComponent,
13+
IgcChipComponent,
714
IgcDividerComponent,
815
IgcExpansionPanelComponent,
916
IgcHighlightComponent,
1017
IgcIconButtonComponent,
1118
IgcInputComponent,
19+
IgcListComponent,
20+
IgcListHeaderComponent,
21+
IgcListItemComponent,
1222
defineComponents,
1323
} from 'igniteui-webcomponents';
1424
import { disableStoryControls } from './story.js';
1525

1626
defineComponents(
17-
IgcIconButtonComponent,
27+
IgcAvatarComponent,
28+
IgcButtonComponent,
29+
IgcCardActionsComponent,
30+
IgcCardComponent,
31+
IgcCardContentComponent,
32+
IgcCardHeaderComponent,
33+
IgcChipComponent,
34+
IgcDividerComponent,
1835
IgcExpansionPanelComponent,
19-
IgcInputComponent,
2036
IgcHighlightComponent,
21-
IgcDividerComponent
37+
IgcIconButtonComponent,
38+
IgcInputComponent,
39+
IgcListComponent,
40+
IgcListHeaderComponent,
41+
IgcListItemComponent
2242
);
2343

2444
// region default
@@ -29,22 +49,22 @@ const metadata: Meta<IgcHighlightComponent> = {
2949
docs: {
3050
description: {
3151
component:
32-
'The highlight component provides a way for efficient searching and highlighting of\ntext projected into it.',
52+
'The highlight component provides efficient searching and highlighting of text\nprojected into it via its default slot. It uses the native CSS Custom Highlight API\nto apply highlight styles to matched text nodes without modifying the DOM.\n\nThe component supports case-sensitive matching, programmatic navigation between\nmatches, and automatic scroll-into-view of the active match.',
3353
},
3454
},
3555
},
3656
argTypes: {
3757
caseSensitive: {
3858
type: 'boolean',
3959
description:
40-
'Whether to match the searched text with case sensitivity in mind.',
60+
'Whether to match the searched text with case sensitivity in mind.\nWhen `true`, only exact-case occurrences of `searchText` are highlighted.',
4161
control: 'boolean',
4262
table: { defaultValue: { summary: 'false' } },
4363
},
4464
searchText: {
4565
type: 'string',
4666
description:
47-
'The string to search and highlight in the DOM content of the component.',
67+
'The string to search and highlight in the DOM content of the component.\nSetting this property triggers a new search automatically.\nAn empty string clears all highlights.',
4868
control: 'text',
4969
},
5070
},
@@ -54,9 +74,16 @@ const metadata: Meta<IgcHighlightComponent> = {
5474
export default metadata;
5575

5676
interface IgcHighlightArgs {
57-
/** Whether to match the searched text with case sensitivity in mind. */
77+
/**
78+
* Whether to match the searched text with case sensitivity in mind.
79+
* When `true`, only exact-case occurrences of `searchText` are highlighted.
80+
*/
5881
caseSensitive: boolean;
59-
/** The string to search and highlight in the DOM content of the component. */
82+
/**
83+
* The string to search and highlight in the DOM content of the component.
84+
* Setting this property triggers a new search automatically.
85+
* An empty string clears all highlights.
86+
*/
6087
searchText: string;
6188
}
6289
type Story = StoryObj<IgcHighlightArgs>;
@@ -224,7 +251,12 @@ export const SearchUI: Story = {
224251
position: sticky;
225252
top: 0;
226253
z-index: 1;
227-
background-color: var(--ig-surface-color, #fff);
254+
background-color: #fff;
255+
}
256+
@container style(--ig-theme-variant: dark) {
257+
.search-bar {
258+
background-color: #000;
259+
}
228260
}
229261
</style>
230262
@@ -359,7 +391,12 @@ export const Performance: Story = {
359391
position: sticky;
360392
top: 0;
361393
z-index: 1;
362-
background-color: var(--ig-surface-color, #fff);
394+
background-color: #fff;
395+
}
396+
@container style(--ig-theme-variant: dark) {
397+
.search-bar {
398+
background-color: #000;
399+
}
363400
}
364401
</style>
365402
@@ -371,3 +408,184 @@ export const Performance: Story = {
371408
`;
372409
},
373410
};
411+
412+
const articles = [
413+
{
414+
initials: 'AJ',
415+
title: 'Getting Started with Web Components',
416+
author: 'Alice Johnson',
417+
date: 'Mar 15, 2026',
418+
category: 'Tutorial',
419+
tags: ['web-components', 'custom-elements', 'beginner'],
420+
excerpt:
421+
'Web Components are a suite of web platform APIs that allow you to create reusable custom elements with encapsulated functionality. Built on Custom Elements, Shadow DOM, and HTML Templates, they work in any JavaScript framework or without one at all. This tutorial walks you through defining your first custom element, attaching a shadow root, and using HTML templates to stamp out reusable markup.',
422+
},
423+
{
424+
initials: 'ML',
425+
title: 'Reactive Rendering with the Lit Framework',
426+
author: 'Marcus Lee',
427+
date: 'Mar 10, 2026',
428+
category: 'Framework',
429+
tags: ['lit', 'reactive', 'performance'],
430+
excerpt:
431+
"Lit is a lightweight library built on top of the Web Components standard that adds reactive properties and a declarative template system. Its efficient update cycle batches property changes and only re-renders the portions of the DOM that actually changed. By leveraging tagged template literals and the browser's native custom element lifecycle, Lit components stay small, fast, and framework-agnostic.",
432+
},
433+
{
434+
initials: 'ST',
435+
title: 'Accessibility in Component Design',
436+
author: 'Sarah Torres',
437+
date: 'Mar 5, 2026',
438+
category: 'Accessibility',
439+
tags: ['accessibility', 'aria', 'wcag'],
440+
excerpt:
441+
'Building accessible components means more than adding an aria-label. Every interactive element must be keyboard-navigable, focusable in a logical order, and communicate its state through ARIA roles and properties. Shadow DOM complicates accessibility trees, so authors must ensure focus management and screen-reader announcements work correctly across shadow boundaries. Following WCAG 2.2 guidelines from the start is far less costly than retrofitting them later.',
442+
},
443+
{
444+
initials: 'DK',
445+
title: 'Deep Dive into Shadow DOM',
446+
author: 'David Kim',
447+
date: 'Feb 28, 2026',
448+
category: 'Web Standards',
449+
tags: ['shadow-dom', 'encapsulation', 'css'],
450+
excerpt:
451+
'Shadow DOM creates an isolated DOM subtree attached to a host element, preventing styles and scripts from leaking in or out. Selectors like :host and ::slotted let component authors style the host and slotted light-DOM content respectively, while CSS custom properties pierce the shadow boundary, enabling external theming. Understanding the difference between open and closed shadow roots is essential for building well-encapsulated, themeable custom elements.',
452+
},
453+
{
454+
initials: 'EC',
455+
title: 'TypeScript Patterns for Lit Components',
456+
author: 'Emily Chen',
457+
date: 'Feb 22, 2026',
458+
category: 'TypeScript',
459+
tags: ['typescript', 'decorators', 'types'],
460+
excerpt:
461+
"Strong TypeScript typing transforms large component libraries into self-documenting, refactor-safe codebases. Property decorators like @property and @state provide both the Lit reactive system and TypeScript's type checker with metadata at once. Defining strict interfaces for component events and using generic types for slot-aware helpers makes cross-component composition predictable and IDE-friendly across the entire library.",
462+
},
463+
{
464+
initials: 'JR',
465+
title: 'Theming with CSS Custom Properties',
466+
author: 'James Rivera',
467+
date: 'Feb 18, 2026',
468+
category: 'Styling',
469+
tags: ['css', 'custom-properties', 'design-tokens'],
470+
excerpt:
471+
'CSS custom properties — often called CSS variables — pierce the shadow boundary, making them the natural choice for theming custom elements. By mapping design tokens to custom properties at the :root or :host level, a single theme change cascades through an entire component library. Pairing this approach with a dedicated theming package lets consumers switch between light, dark, and brand-specific palettes without touching component internals.',
472+
},
473+
];
474+
475+
export const KnowledgeBase: Story = {
476+
argTypes: disableStoryControls(metadata),
477+
render: () => {
478+
const controller = createSearchController();
479+
480+
return html`
481+
<style>
482+
.kb-layout {
483+
display: flex;
484+
flex-direction: column;
485+
gap: 2rem;
486+
padding: 1rem 0;
487+
}
488+
.kb-section-title {
489+
font-size: 1rem;
490+
font-weight: 600;
491+
margin: 0 0 0.75rem;
492+
color: var(--ig-gray-700, #374151);
493+
}
494+
.kb-card-grid {
495+
display: grid;
496+
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
497+
gap: 1rem;
498+
}
499+
.kb-card-excerpt {
500+
font-size: 0.875rem;
501+
line-height: 1.6;
502+
color: var(--ig-gray-600, #4b5563);
503+
margin: 0;
504+
}
505+
.kb-tags {
506+
display: flex;
507+
flex-wrap: wrap;
508+
gap: 4px;
509+
margin-top: 0.75rem;
510+
}
511+
.search-bar {
512+
position: sticky;
513+
top: 0;
514+
z-index: 1;
515+
background-color: #fff;
516+
}
517+
@container style(--ig-theme-variant: dark) {
518+
.search-bar {
519+
background-color: #000;
520+
}
521+
}
522+
</style>
523+
524+
${SearchBar(controller)}
525+
526+
<igc-highlight ${ref(controller.highlightRef)}>
527+
<div class="kb-layout">
528+
<section>
529+
<p class="kb-section-title">Article Index</p>
530+
<igc-list>
531+
<igc-list-header><h4>Recent Publications</h4></igc-list-header>
532+
${articles.map(
533+
(a) => html`
534+
<igc-list-item>
535+
<igc-avatar
536+
slot="start"
537+
initials=${a.initials}
538+
shape="circle"
539+
></igc-avatar>
540+
<span slot="title">${a.title}</span>
541+
<span slot="subtitle"
542+
>${a.author} &middot; ${a.date} &middot;
543+
${a.category}</span
544+
>
545+
</igc-list-item>
546+
`
547+
)}
548+
</igc-list>
549+
</section>
550+
551+
<igc-divider></igc-divider>
552+
553+
<section>
554+
<p class="kb-section-title">Featured Articles</p>
555+
<div class="kb-card-grid">
556+
${articles.map(
557+
(a) => html`
558+
<igc-card>
559+
<igc-card-header>
560+
<igc-avatar
561+
slot="thumbnail"
562+
initials=${a.initials}
563+
shape="circle"
564+
></igc-avatar>
565+
<h3 slot="title">${a.title}</h3>
566+
<h5 slot="subtitle">${a.author} &middot; ${a.date}</h5>
567+
</igc-card-header>
568+
<igc-card-content>
569+
<p class="kb-card-excerpt">${a.excerpt}</p>
570+
<div class="kb-tags">
571+
${a.tags.map(
572+
(t) => html`<igc-chip tabindex="-1">${t}</igc-chip>`
573+
)}
574+
</div>
575+
</igc-card-content>
576+
<igc-card-actions>
577+
<igc-button slot="start" variant="flat"
578+
>Read More</igc-button
579+
>
580+
<span slot="end">${a.category}</span>
581+
</igc-card-actions>
582+
</igc-card>
583+
`
584+
)}
585+
</div>
586+
</section>
587+
</div>
588+
</igc-highlight>
589+
`;
590+
},
591+
};

stories/radio.stories.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,7 @@ const metadata: Meta<IgcRadioComponent> = {
1515
title: 'Radio',
1616
component: 'igc-radio',
1717
parameters: {
18-
docs: {
19-
description: {
20-
component:
21-
'The radio component lets users select a single option from a group. Radios are designed to be used inside an `igc-radio-group`, which manages mutual exclusivity, keyboard navigation, and form submission.',
22-
},
23-
},
18+
docs: { description: { component: '' } },
2419
actions: { handles: ['igcChange'] },
2520
},
2621
argTypes: {

stories/ripple.stories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const metadata: Meta<IgcRippleComponent> = {
1717
docs: {
1818
description: {
1919
component:
20-
'The ripple component adds a touch-feedback wave animation to any interactive surface. Place `<igc-ripple>` inside a `position: relative; overflow: hidden` container — the ripple fills the parent and plays the animation on each `pointerdown` event. Use the `--color` CSS custom property to tint the effect.',
20+
'A ripple can be applied to an element to represent\ninteractive surface.',
2121
},
2222
},
2323
},

stories/snackbar.stories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const metadata: Meta<IgcSnackbarComponent> = {
2222
docs: {
2323
description: {
2424
component:
25-
'A snackbar provides brief feedback about an operation by displaying a short message near the bottom of the screen. It disappears automatically after a configurable `displayTime`, or can stay open with `keepOpen`. An optional action button lets users respond (e.g. Undo).',
25+
'A snackbar component is used to provide feedback about an operation\nby showing a brief message at the bottom of the screen.',
2626
},
2727
},
2828
actions: { handles: ['igcAction'] },

stories/switch.stories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const metadata: Meta<IgcSwitchComponent> = {
1818
docs: {
1919
description: {
2020
component:
21-
'A switch toggles a single setting on or off, providing immediate feedback. It is semantically equivalent to a checkbox but communicates a binary state change that takes effect right away — without requiring a form submission.',
21+
'Similar to a checkbox, a switch controls the state of a single setting on or off.',
2222
},
2323
},
2424
actions: { handles: ['igcChange'] },

0 commit comments

Comments
 (0)