ng-comps 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ng-comps.mjs +4254 -0
- package/package.json +54 -58
- package/src/styles.css +54 -0
- package/types/ng-comps.d.ts +1348 -0
- package/.editorconfig +0 -17
- package/.github/copilot-instructions.md +0 -55
- package/.github/workflows/ci.yml +0 -29
- package/.prettierrc +0 -12
- package/.storybook/main.ts +0 -21
- package/.storybook/preview.ts +0 -27
- package/.storybook/tsconfig.doc.json +0 -10
- package/.storybook/tsconfig.json +0 -15
- package/.storybook/typings.d.ts +0 -4
- package/.vscode/extensions.json +0 -4
- package/.vscode/launch.json +0 -20
- package/.vscode/mcp.json +0 -9
- package/.vscode/tasks.json +0 -42
- package/ACCESSIBILITY.md +0 -127
- package/angular.json +0 -106
- package/documentation.json +0 -13394
- package/ng-package.json +0 -27
- package/public/favicon.ico +0 -0
- package/scripts/prepare-package.mjs +0 -80
- package/src/app/a11y/accessibility.utils.ts +0 -35
- package/src/app/a11y/index.ts +0 -6
- package/src/app/accessibility/ng-comps.a11y.spec.ts +0 -108
- package/src/app/app.config.ts +0 -11
- package/src/app/app.css +0 -107
- package/src/app/app.html +0 -48
- package/src/app/app.routes.ts +0 -3
- package/src/app/app.spec.ts +0 -23
- package/src/app/app.ts +0 -10
- package/src/app/components/accordion/index.ts +0 -2
- package/src/app/components/accordion/mf-accordion.component.css +0 -38
- package/src/app/components/accordion/mf-accordion.component.spec.ts +0 -48
- package/src/app/components/accordion/mf-accordion.component.ts +0 -53
- package/src/app/components/alert/index.ts +0 -2
- package/src/app/components/alert/mf-alert.component.css +0 -100
- package/src/app/components/alert/mf-alert.component.spec.ts +0 -59
- package/src/app/components/alert/mf-alert.component.ts +0 -68
- package/src/app/components/autocomplete/index.ts +0 -5
- package/src/app/components/autocomplete/mf-autocomplete.component.css +0 -105
- package/src/app/components/autocomplete/mf-autocomplete.component.spec.ts +0 -116
- package/src/app/components/autocomplete/mf-autocomplete.component.ts +0 -307
- package/src/app/components/avatar/index.ts +0 -2
- package/src/app/components/avatar/mf-avatar.component.css +0 -27
- package/src/app/components/avatar/mf-avatar.component.spec.ts +0 -49
- package/src/app/components/avatar/mf-avatar.component.ts +0 -99
- package/src/app/components/badge/index.ts +0 -2
- package/src/app/components/badge/mf-badge.component.css +0 -32
- package/src/app/components/badge/mf-badge.component.spec.ts +0 -40
- package/src/app/components/badge/mf-badge.component.ts +0 -105
- package/src/app/components/breadcrumb/index.ts +0 -2
- package/src/app/components/breadcrumb/mf-breadcrumb.component.css +0 -61
- package/src/app/components/breadcrumb/mf-breadcrumb.component.spec.ts +0 -61
- package/src/app/components/breadcrumb/mf-breadcrumb.component.ts +0 -75
- package/src/app/components/button/index.ts +0 -2
- package/src/app/components/button/mf-button.component.css +0 -136
- package/src/app/components/button/mf-button.component.ts +0 -174
- package/src/app/components/card/index.ts +0 -2
- package/src/app/components/card/mf-card.component.css +0 -82
- package/src/app/components/card/mf-card.component.ts +0 -59
- package/src/app/components/checkbox/index.ts +0 -1
- package/src/app/components/checkbox/mf-checkbox.component.css +0 -75
- package/src/app/components/checkbox/mf-checkbox.component.ts +0 -187
- package/src/app/components/chip/index.ts +0 -2
- package/src/app/components/chip/mf-chip.component.css +0 -69
- package/src/app/components/chip/mf-chip.component.spec.ts +0 -47
- package/src/app/components/chip/mf-chip.component.ts +0 -77
- package/src/app/components/datepicker/index.ts +0 -2
- package/src/app/components/datepicker/mf-datepicker.component.css +0 -102
- package/src/app/components/datepicker/mf-datepicker.component.spec.ts +0 -69
- package/src/app/components/datepicker/mf-datepicker.component.ts +0 -233
- package/src/app/components/dialog/index.ts +0 -3
- package/src/app/components/dialog/mf-dialog.component.css +0 -73
- package/src/app/components/dialog/mf-dialog.component.ts +0 -160
- package/src/app/components/dialog/mf-dialog.service.spec.ts +0 -61
- package/src/app/components/dialog/mf-dialog.service.ts +0 -52
- package/src/app/components/divider/index.ts +0 -2
- package/src/app/components/divider/mf-divider.component.css +0 -38
- package/src/app/components/divider/mf-divider.component.spec.ts +0 -40
- package/src/app/components/divider/mf-divider.component.ts +0 -44
- package/src/app/components/form-field/index.ts +0 -1
- package/src/app/components/form-field/mf-form-field.component.css +0 -51
- package/src/app/components/form-field/mf-form-field.component.ts +0 -74
- package/src/app/components/grid-list/index.ts +0 -2
- package/src/app/components/grid-list/mf-grid-list.component.css +0 -47
- package/src/app/components/grid-list/mf-grid-list.component.spec.ts +0 -57
- package/src/app/components/grid-list/mf-grid-list.component.ts +0 -68
- package/src/app/components/icon/index.ts +0 -2
- package/src/app/components/icon/mf-icon.component.css +0 -56
- package/src/app/components/icon/mf-icon.component.ts +0 -41
- package/src/app/components/input/index.ts +0 -2
- package/src/app/components/input/mf-input.component.css +0 -105
- package/src/app/components/input/mf-input.component.ts +0 -217
- package/src/app/components/menu/index.ts +0 -2
- package/src/app/components/menu/mf-menu.component.css +0 -31
- package/src/app/components/menu/mf-menu.component.spec.ts +0 -49
- package/src/app/components/menu/mf-menu.component.ts +0 -66
- package/src/app/components/paginator/index.ts +0 -1
- package/src/app/components/paginator/mf-paginator.component.css +0 -32
- package/src/app/components/paginator/mf-paginator.component.spec.ts +0 -44
- package/src/app/components/paginator/mf-paginator.component.ts +0 -52
- package/src/app/components/progress-bar/index.ts +0 -2
- package/src/app/components/progress-bar/mf-progress-bar.component.css +0 -53
- package/src/app/components/progress-bar/mf-progress-bar.component.spec.ts +0 -65
- package/src/app/components/progress-bar/mf-progress-bar.component.ts +0 -79
- package/src/app/components/progress-spinner/index.ts +0 -2
- package/src/app/components/progress-spinner/mf-progress-spinner.component.css +0 -38
- package/src/app/components/progress-spinner/mf-progress-spinner.component.spec.ts +0 -59
- package/src/app/components/progress-spinner/mf-progress-spinner.component.ts +0 -81
- package/src/app/components/radio-button/index.ts +0 -2
- package/src/app/components/radio-button/mf-radio-button.component.css +0 -86
- package/src/app/components/radio-button/mf-radio-button.component.spec.ts +0 -55
- package/src/app/components/radio-button/mf-radio-button.component.ts +0 -219
- package/src/app/components/select/index.ts +0 -2
- package/src/app/components/select/mf-select.component.css +0 -121
- package/src/app/components/select/mf-select.component.spec.ts +0 -108
- package/src/app/components/select/mf-select.component.ts +0 -252
- package/src/app/components/sidenav/index.ts +0 -2
- package/src/app/components/sidenav/mf-sidenav.component.css +0 -168
- package/src/app/components/sidenav/mf-sidenav.component.spec.ts +0 -57
- package/src/app/components/sidenav/mf-sidenav.component.ts +0 -126
- package/src/app/components/slide-toggle/index.ts +0 -1
- package/src/app/components/slide-toggle/mf-slide-toggle.component.css +0 -42
- package/src/app/components/slide-toggle/mf-slide-toggle.component.spec.ts +0 -43
- package/src/app/components/slide-toggle/mf-slide-toggle.component.ts +0 -188
- package/src/app/components/snackbar/index.ts +0 -2
- package/src/app/components/snackbar/mf-snackbar.service.css +0 -31
- package/src/app/components/snackbar/mf-snackbar.service.spec.ts +0 -81
- package/src/app/components/snackbar/mf-snackbar.service.ts +0 -77
- package/src/app/components/table/index.ts +0 -2
- package/src/app/components/table/mf-table.component.css +0 -68
- package/src/app/components/table/mf-table.component.spec.ts +0 -76
- package/src/app/components/table/mf-table.component.ts +0 -117
- package/src/app/components/tabs/index.ts +0 -2
- package/src/app/components/tabs/mf-tabs.component.css +0 -31
- package/src/app/components/tabs/mf-tabs.component.spec.ts +0 -50
- package/src/app/components/tabs/mf-tabs.component.ts +0 -62
- package/src/app/components/textarea/index.ts +0 -2
- package/src/app/components/textarea/mf-textarea.component.css +0 -48
- package/src/app/components/textarea/mf-textarea.component.spec.ts +0 -55
- package/src/app/components/textarea/mf-textarea.component.ts +0 -227
- package/src/app/components/toolbar/index.ts +0 -2
- package/src/app/components/toolbar/mf-toolbar.component.css +0 -77
- package/src/app/components/toolbar/mf-toolbar.component.ts +0 -56
- package/src/app/components/tooltip/index.ts +0 -3
- package/src/app/components/tooltip/mf-tooltip.component.css +0 -7
- package/src/app/components/tooltip/mf-tooltip.component.spec.ts +0 -37
- package/src/app/components/tooltip/mf-tooltip.component.ts +0 -47
- package/src/app/components/tooltip/mf-tooltip.directive.ts +0 -22
- package/src/index.html +0 -18
- package/src/main.ts +0 -6
- package/src/public-api.ts +0 -31
- package/src/stories/About.mdx +0 -72
- package/src/stories/Accessibility.mdx +0 -59
- package/src/stories/Welcome.mdx +0 -26
- package/src/stories/assets/accessibility.png +0 -0
- package/src/stories/assets/accessibility.svg +0 -1
- package/src/stories/assets/addon-library.png +0 -0
- package/src/stories/assets/assets.png +0 -0
- package/src/stories/assets/avif-test-image.avif +0 -0
- package/src/stories/assets/context.png +0 -0
- package/src/stories/assets/discord.svg +0 -1
- package/src/stories/assets/docs.png +0 -0
- package/src/stories/assets/figma-plugin.png +0 -0
- package/src/stories/assets/github.svg +0 -1
- package/src/stories/assets/share.png +0 -0
- package/src/stories/assets/styling.png +0 -0
- package/src/stories/assets/testing.png +0 -0
- package/src/stories/assets/theming.png +0 -0
- package/src/stories/assets/tutorials.svg +0 -1
- package/src/stories/assets/youtube.svg +0 -1
- package/src/stories/mf-a11y-contracts.stories.ts +0 -472
- package/src/stories/mf-autocomplete.stories.ts +0 -194
- package/src/stories/mf-button.stories.ts +0 -152
- package/src/stories/mf-card.stories.ts +0 -147
- package/src/stories/mf-checkbox.stories.ts +0 -88
- package/src/stories/mf-datepicker.stories.ts +0 -118
- package/src/stories/mf-dialog.stories.ts +0 -159
- package/src/stories/mf-form-field.stories.ts +0 -108
- package/src/stories/mf-grid-list.stories.ts +0 -104
- package/src/stories/mf-icon.stories.ts +0 -133
- package/src/stories/mf-input.stories.ts +0 -158
- package/src/stories/mf-menu.stories.ts +0 -71
- package/src/stories/mf-progress-bar.stories.ts +0 -119
- package/src/stories/mf-progress-spinner.stories.ts +0 -124
- package/src/stories/mf-radio-button.stories.ts +0 -111
- package/src/stories/mf-select.stories.ts +0 -184
- package/src/stories/mf-sidenav.stories.ts +0 -331
- package/src/stories/mf-table.stories.ts +0 -80
- package/src/stories/mf-toolbar.stories.ts +0 -112
- package/src/stories/user.ts +0 -3
- package/tsconfig.app.json +0 -15
- package/tsconfig.json +0 -33
- package/tsconfig.spec.json +0 -15
- package/vercel.json +0 -6
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/angular';
|
|
2
|
-
import { Component, signal } from '@angular/core';
|
|
3
|
-
import { MfSidenavComponent, MfSidenavNavItem } from '../app/components/sidenav';
|
|
4
|
-
|
|
5
|
-
const NAV_ITEMS: MfSidenavNavItem[] = [
|
|
6
|
-
{ id: 'home', icon: 'home', label: 'Home', active: true },
|
|
7
|
-
{ id: 'dashboard', icon: 'dashboard', label: 'Dashboard' },
|
|
8
|
-
{ id: 'analytics', icon: 'bar_chart', label: 'Analytics', badge: 3 },
|
|
9
|
-
{ id: 'users', icon: 'group', label: 'Users' },
|
|
10
|
-
{ id: 'messages', icon: 'mail', label: 'Messages', badge: 12 },
|
|
11
|
-
{ id: 'settings', icon: 'settings', label: 'Settings' },
|
|
12
|
-
{ id: 'archived', icon: 'archive', label: 'Archived', disabled: true },
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
const meta: Meta<MfSidenavComponent> = {
|
|
16
|
-
title: 'Organisms/MfSidenav',
|
|
17
|
-
component: MfSidenavComponent,
|
|
18
|
-
tags: ['autodocs'],
|
|
19
|
-
parameters: {
|
|
20
|
-
layout: 'fullscreen',
|
|
21
|
-
docs: {
|
|
22
|
-
description: {
|
|
23
|
-
component: `
|
|
24
|
-
**MfSidenav** is the side navigation component from the ng-comps library.
|
|
25
|
-
It wraps Angular Material \`mat-sidenav-container\` with custom styling, Material icons, active and disabled states, notification badges, and a customizable header.
|
|
26
|
-
|
|
27
|
-
**Two usage patterns:**
|
|
28
|
-
|
|
29
|
-
1. **Declarative nav items** - Provide \`navItems\`, \`headerTitle\`, and \`headerIcon\`.
|
|
30
|
-
2. **Content projection** - Project \`[mfSidenavContent]\` for full control over the panel content.
|
|
31
|
-
|
|
32
|
-
Main content is always projected through the default slot.
|
|
33
|
-
|
|
34
|
-
| Property | Description |
|
|
35
|
-
|----------------|--------------------------------------------------------------|
|
|
36
|
-
| \`navItems\` | Array of items \`{ id, icon, label, active?, disabled?, badge? }\` |
|
|
37
|
-
| \`headerTitle\` | Sidenav header title |
|
|
38
|
-
| \`headerIcon\` | Header Material icon |
|
|
39
|
-
| \`opened\` | Whether the sidenav is open |
|
|
40
|
-
| \`mode\` | \`side\` · \`over\` · \`push\` |
|
|
41
|
-
| \`position\` | \`start\` (left) · \`end\` (right) |
|
|
42
|
-
| \`sidenavWidth\` | Panel width (CSS value) |
|
|
43
|
-
`,
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
argTypes: {
|
|
48
|
-
opened: { control: 'boolean', description: 'Open or closed' },
|
|
49
|
-
mode: {
|
|
50
|
-
control: 'select',
|
|
51
|
-
options: ['side', 'over', 'push'],
|
|
52
|
-
description: 'Opening mode',
|
|
53
|
-
},
|
|
54
|
-
position: {
|
|
55
|
-
control: 'select',
|
|
56
|
-
options: ['start', 'end'],
|
|
57
|
-
description: 'Panel position',
|
|
58
|
-
},
|
|
59
|
-
sidenavWidth: { control: 'text', description: 'Side panel width' },
|
|
60
|
-
headerTitle: { control: 'text', description: 'Header title' },
|
|
61
|
-
headerIcon: { control: 'text', description: 'Header Material icon' },
|
|
62
|
-
mfOpenedChange: { action: 'mfOpenedChange' },
|
|
63
|
-
mfNavItemClick: { action: 'mfNavItemClick' },
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export default meta;
|
|
68
|
-
type Story = StoryObj<MfSidenavComponent>;
|
|
69
|
-
|
|
70
|
-
const mainContent = `
|
|
71
|
-
<div style="padding: 24px;">
|
|
72
|
-
<h2 style="margin: 0 0 8px; font-size: 1.25rem; color: var(--mf-color-on-surface);">Main content</h2>
|
|
73
|
-
<p style="color: var(--mf-color-neutral-600); font-size: 0.875rem; margin: 0;">
|
|
74
|
-
The side panel is rendered on the left. You can interact with the menu items.
|
|
75
|
-
</p>
|
|
76
|
-
</div>
|
|
77
|
-
`;
|
|
78
|
-
|
|
79
|
-
export const Default: Story = {
|
|
80
|
-
name: 'With navItems (side mode)',
|
|
81
|
-
args: {
|
|
82
|
-
opened: true,
|
|
83
|
-
mode: 'side',
|
|
84
|
-
headerTitle: 'MF App',
|
|
85
|
-
headerIcon: 'apps',
|
|
86
|
-
navItems: NAV_ITEMS,
|
|
87
|
-
},
|
|
88
|
-
render: (args) => ({
|
|
89
|
-
props: args,
|
|
90
|
-
template: `
|
|
91
|
-
<div style="height: 480px;">
|
|
92
|
-
<mf-sidenav
|
|
93
|
-
[opened]="opened"
|
|
94
|
-
[mode]="mode"
|
|
95
|
-
[position]="position"
|
|
96
|
-
[navItems]="navItems"
|
|
97
|
-
[headerTitle]="headerTitle"
|
|
98
|
-
[headerIcon]="headerIcon"
|
|
99
|
-
[sidenavWidth]="sidenavWidth || '260px'"
|
|
100
|
-
(mfNavItemClick)="mfNavItemClick($event)"
|
|
101
|
-
(mfOpenedChange)="mfOpenedChange($event)"
|
|
102
|
-
>
|
|
103
|
-
${mainContent}
|
|
104
|
-
</mf-sidenav>
|
|
105
|
-
</div>
|
|
106
|
-
`,
|
|
107
|
-
moduleMetadata: { imports: [MfSidenavComponent] },
|
|
108
|
-
}),
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export const Over: Story = {
|
|
112
|
-
name: 'Over mode',
|
|
113
|
-
args: {
|
|
114
|
-
opened: true,
|
|
115
|
-
mode: 'over',
|
|
116
|
-
headerTitle: 'MF App',
|
|
117
|
-
headerIcon: 'apps',
|
|
118
|
-
navItems: NAV_ITEMS,
|
|
119
|
-
},
|
|
120
|
-
render: (args) => ({
|
|
121
|
-
props: args,
|
|
122
|
-
template: `
|
|
123
|
-
<div style="height: 480px;">
|
|
124
|
-
<mf-sidenav
|
|
125
|
-
[opened]="opened"
|
|
126
|
-
[mode]="mode"
|
|
127
|
-
[navItems]="navItems"
|
|
128
|
-
[headerTitle]="headerTitle"
|
|
129
|
-
[headerIcon]="headerIcon"
|
|
130
|
-
(mfNavItemClick)="mfNavItemClick($event)"
|
|
131
|
-
>
|
|
132
|
-
${mainContent}
|
|
133
|
-
</mf-sidenav>
|
|
134
|
-
</div>
|
|
135
|
-
`,
|
|
136
|
-
moduleMetadata: { imports: [MfSidenavComponent] },
|
|
137
|
-
}),
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
export const EndPosition: Story = {
|
|
141
|
-
name: 'Right position',
|
|
142
|
-
args: {
|
|
143
|
-
opened: true,
|
|
144
|
-
mode: 'side',
|
|
145
|
-
position: 'end',
|
|
146
|
-
headerTitle: 'Details',
|
|
147
|
-
headerIcon: 'info',
|
|
148
|
-
navItems: [
|
|
149
|
-
{ id: 'notifications', icon: 'notifications', label: 'Notifications', badge: 5, active: true },
|
|
150
|
-
{ id: 'messages', icon: 'mail', label: 'Messages', badge: 2 },
|
|
151
|
-
{ id: 'activity', icon: 'history', label: 'Recent activity' },
|
|
152
|
-
{ id: 'bookmarks', icon: 'bookmark', label: 'Saved' },
|
|
153
|
-
],
|
|
154
|
-
},
|
|
155
|
-
render: (args) => ({
|
|
156
|
-
props: args,
|
|
157
|
-
template: `
|
|
158
|
-
<div style="height: 480px;">
|
|
159
|
-
<mf-sidenav
|
|
160
|
-
[opened]="opened"
|
|
161
|
-
[mode]="mode"
|
|
162
|
-
[position]="position"
|
|
163
|
-
[navItems]="navItems"
|
|
164
|
-
[headerTitle]="headerTitle"
|
|
165
|
-
[headerIcon]="headerIcon"
|
|
166
|
-
(mfNavItemClick)="mfNavItemClick($event)"
|
|
167
|
-
>
|
|
168
|
-
${mainContent}
|
|
169
|
-
</mf-sidenav>
|
|
170
|
-
</div>
|
|
171
|
-
`,
|
|
172
|
-
moduleMetadata: { imports: [MfSidenavComponent] },
|
|
173
|
-
}),
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
export const Closed: Story = {
|
|
177
|
-
name: 'Closed',
|
|
178
|
-
args: {
|
|
179
|
-
opened: false,
|
|
180
|
-
mode: 'over',
|
|
181
|
-
headerTitle: 'MF App',
|
|
182
|
-
headerIcon: 'apps',
|
|
183
|
-
navItems: NAV_ITEMS,
|
|
184
|
-
},
|
|
185
|
-
render: (args) => ({
|
|
186
|
-
props: args,
|
|
187
|
-
template: `
|
|
188
|
-
<div style="height: 480px;">
|
|
189
|
-
<mf-sidenav
|
|
190
|
-
[opened]="opened"
|
|
191
|
-
[mode]="mode"
|
|
192
|
-
[navItems]="navItems"
|
|
193
|
-
[headerTitle]="headerTitle"
|
|
194
|
-
[headerIcon]="headerIcon"
|
|
195
|
-
>
|
|
196
|
-
<div style="padding: 24px;">
|
|
197
|
-
<p style="color: var(--mf-color-neutral-600); font-size: 0.875rem;">
|
|
198
|
-
The sidenav is closed. In <code>over</code> mode it overlays the content when opened.
|
|
199
|
-
</p>
|
|
200
|
-
</div>
|
|
201
|
-
</mf-sidenav>
|
|
202
|
-
</div>
|
|
203
|
-
`,
|
|
204
|
-
moduleMetadata: { imports: [MfSidenavComponent] },
|
|
205
|
-
}),
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
@Component({
|
|
209
|
-
selector: 'mf-sidenav-interactive-demo',
|
|
210
|
-
imports: [MfSidenavComponent],
|
|
211
|
-
template: `
|
|
212
|
-
<div style="height: 520px; display: flex; flex-direction: column;">
|
|
213
|
-
<div style="display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--mf-color-border); background: var(--mf-color-surface); flex-shrink: 0;">
|
|
214
|
-
<button
|
|
215
|
-
type="button"
|
|
216
|
-
(click)="toggle()"
|
|
217
|
-
style="display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border: 1px solid var(--mf-color-border); border-radius: 9999px; background: var(--mf-color-surface); font-family: var(--mf-font-base); font-size: 0.875rem; font-weight: 500; cursor: pointer; color: var(--mf-color-on-surface);"
|
|
218
|
-
>
|
|
219
|
-
<span style="font-family: 'Material Icons'; font-size: 18px; line-height: 1;">menu</span>
|
|
220
|
-
{{ opened() ? 'Close panel' : 'Open panel' }}
|
|
221
|
-
</button>
|
|
222
|
-
<span style="font-size: 0.875rem; color: var(--mf-color-neutral-400);">Panel: {{ opened() ? 'open' : 'closed' }}</span>
|
|
223
|
-
</div>
|
|
224
|
-
<div style="flex: 1; min-height: 0;">
|
|
225
|
-
<mf-sidenav
|
|
226
|
-
[opened]="opened()"
|
|
227
|
-
mode="over"
|
|
228
|
-
headerTitle="MF App"
|
|
229
|
-
headerIcon="apps"
|
|
230
|
-
[navItems]="items()"
|
|
231
|
-
(mfOpenedChange)="opened.set($event)"
|
|
232
|
-
(mfNavItemClick)="onNavItemClick($event)"
|
|
233
|
-
>
|
|
234
|
-
<div style="padding: 24px;">
|
|
235
|
-
<h2 style="margin: 0 0 8px; font-size: 1.25rem; color: var(--mf-color-on-surface);">{{ activeLabel() }}</h2>
|
|
236
|
-
<p style="color: var(--mf-color-neutral-600); font-size: 0.875rem; margin: 0;">
|
|
237
|
-
Click the menu items to change the active section.
|
|
238
|
-
</p>
|
|
239
|
-
</div>
|
|
240
|
-
</mf-sidenav>
|
|
241
|
-
</div>
|
|
242
|
-
</div>
|
|
243
|
-
`,
|
|
244
|
-
})
|
|
245
|
-
class MfSidenavInteractiveDemoComponent {
|
|
246
|
-
readonly opened = signal(false);
|
|
247
|
-
readonly activeId = signal('home');
|
|
248
|
-
|
|
249
|
-
readonly items = signal<MfSidenavNavItem[]>([
|
|
250
|
-
{ id: 'home', icon: 'home', label: 'Home', active: true },
|
|
251
|
-
{ id: 'dashboard', icon: 'dashboard', label: 'Dashboard' },
|
|
252
|
-
{ id: 'analytics', icon: 'bar_chart', label: 'Analytics', badge: 3 },
|
|
253
|
-
{ id: 'users', icon: 'group', label: 'Users' },
|
|
254
|
-
{ id: 'messages', icon: 'mail', label: 'Messages', badge: 12 },
|
|
255
|
-
{ id: 'settings', icon: 'settings', label: 'Settings' },
|
|
256
|
-
]);
|
|
257
|
-
|
|
258
|
-
readonly activeLabel = () =>
|
|
259
|
-
this.items().find((i) => i.id === this.activeId())?.label ?? 'Home';
|
|
260
|
-
|
|
261
|
-
toggle(): void {
|
|
262
|
-
this.opened.set(!this.opened());
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
onNavItemClick(item: MfSidenavNavItem): void {
|
|
266
|
-
this.activeId.set(item.id);
|
|
267
|
-
this.items.set(
|
|
268
|
-
this.items().map((i) => ({ ...i, active: i.id === item.id })),
|
|
269
|
-
);
|
|
270
|
-
this.opened.set(false);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
export const Interactive: Story = {
|
|
275
|
-
name: 'Interactive (toggle + selection)',
|
|
276
|
-
render: () => ({
|
|
277
|
-
template: `<mf-sidenav-interactive-demo />`,
|
|
278
|
-
moduleMetadata: { imports: [MfSidenavInteractiveDemoComponent] },
|
|
279
|
-
}),
|
|
280
|
-
parameters: {
|
|
281
|
-
docs: {
|
|
282
|
-
description: {
|
|
283
|
-
story:
|
|
284
|
-
'Panel in `over` mode with a toggle button and active item updates on click.',
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
|
-
},
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
export const ContentProjection: Story = {
|
|
291
|
-
name: 'Content projection (custom)',
|
|
292
|
-
render: () => ({
|
|
293
|
-
template: `
|
|
294
|
-
<div style="height: 480px;">
|
|
295
|
-
<mf-sidenav opened="true" mode="side" sidenavWidth="240px">
|
|
296
|
-
<div mfSidenavContent style="display: flex; flex-direction: column; height: 100%;">
|
|
297
|
-
<div style="padding: 20px 16px 16px; border-bottom: 1px solid var(--mf-color-border);">
|
|
298
|
-
<span style="font-family: var(--mf-font-display); font-weight: 700; color: var(--mf-color-brand);">Workspace</span>
|
|
299
|
-
</div>
|
|
300
|
-
<nav style="flex: 1; padding: 12px; display: flex; flex-direction: column; gap: 4px;">
|
|
301
|
-
<a href="#" style="display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 10px; text-decoration: none; color: var(--mf-color-on-surface); font-size: 0.875rem; background: var(--mf-color-brand-light); color: var(--mf-color-brand); font-weight: 600;">
|
|
302
|
-
<span class="material-icons" style="font-size: 20px;">star</span> Highlights
|
|
303
|
-
</a>
|
|
304
|
-
<a href="#" style="display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 10px; text-decoration: none; color: var(--mf-color-neutral-600); font-size: 0.875rem;">
|
|
305
|
-
<span class="material-icons" style="font-size: 20px;">folder</span> Projects
|
|
306
|
-
</a>
|
|
307
|
-
<a href="#" style="display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 10px; text-decoration: none; color: var(--mf-color-neutral-600); font-size: 0.875rem;">
|
|
308
|
-
<span class="material-icons" style="font-size: 20px;">people</span> Team
|
|
309
|
-
</a>
|
|
310
|
-
</nav>
|
|
311
|
-
</div>
|
|
312
|
-
<div style="padding: 24px;">
|
|
313
|
-
<h2 style="margin: 0 0 8px; font-size: 1.25rem; color: var(--mf-color-on-surface);">Custom panel</h2>
|
|
314
|
-
<p style="color: var(--mf-color-neutral-600); font-size: 0.875rem; margin: 0;">
|
|
315
|
-
Using <code>[mfSidenavContent]</code> to project fully custom content.
|
|
316
|
-
</p>
|
|
317
|
-
</div>
|
|
318
|
-
</mf-sidenav>
|
|
319
|
-
</div>
|
|
320
|
-
`,
|
|
321
|
-
moduleMetadata: { imports: [MfSidenavComponent] },
|
|
322
|
-
}),
|
|
323
|
-
parameters: {
|
|
324
|
-
docs: {
|
|
325
|
-
description: {
|
|
326
|
-
story:
|
|
327
|
-
'When `navItems` is not provided, the `[mfSidenavContent]` slot is used to project custom HTML.',
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
|
-
},
|
|
331
|
-
};
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/angular';
|
|
2
|
-
|
|
3
|
-
import { MfTableComponent } from '../app/components/table';
|
|
4
|
-
|
|
5
|
-
const COLUMNS = [
|
|
6
|
-
{ key: 'name', header: 'Name', sortable: true },
|
|
7
|
-
{ key: 'role', header: 'Role' },
|
|
8
|
-
{ key: 'status', header: 'Status' },
|
|
9
|
-
];
|
|
10
|
-
|
|
11
|
-
const DATA = [
|
|
12
|
-
{ name: 'Ana Torres', role: 'Frontend', status: 'Active' },
|
|
13
|
-
{ name: 'Luis Vega', role: 'Design Ops', status: 'Pending' },
|
|
14
|
-
{ name: 'Marta Solis', role: 'QA', status: 'Active' },
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
const meta: Meta<MfTableComponent> = {
|
|
18
|
-
title: 'Organisms/MfTable',
|
|
19
|
-
component: MfTableComponent,
|
|
20
|
-
tags: ['autodocs'],
|
|
21
|
-
parameters: {
|
|
22
|
-
docs: {
|
|
23
|
-
description: {
|
|
24
|
-
component: `
|
|
25
|
-
**MfTable** renders data with native table semantics and explicit row actions.
|
|
26
|
-
|
|
27
|
-
The v1 contract avoids clickable rows as the default interaction pattern. If a row needs actions, render focusable controls inside cells and give them contextual accessible names.
|
|
28
|
-
`,
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
argTypes: {
|
|
33
|
-
variant: {
|
|
34
|
-
control: 'select',
|
|
35
|
-
options: ['default', 'striped', 'bordered'],
|
|
36
|
-
},
|
|
37
|
-
rowActionLabel: { control: 'text', description: 'Visible label for the row action button' },
|
|
38
|
-
rowActionHeader: { control: 'text', description: 'Header text for the action column' },
|
|
39
|
-
mfSortChange: { action: 'mfSortChange' },
|
|
40
|
-
mfRowAction: { action: 'mfRowAction' },
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export default meta;
|
|
45
|
-
type Story = StoryObj<MfTableComponent>;
|
|
46
|
-
|
|
47
|
-
export const Default: Story = {
|
|
48
|
-
args: {
|
|
49
|
-
columns: COLUMNS,
|
|
50
|
-
data: DATA,
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const WithExplicitActions: Story = {
|
|
55
|
-
name: 'With Explicit Actions',
|
|
56
|
-
args: {
|
|
57
|
-
columns: COLUMNS,
|
|
58
|
-
data: DATA,
|
|
59
|
-
rowActionLabel: 'View details',
|
|
60
|
-
rowActionHeader: 'Actions',
|
|
61
|
-
rowActionAriaLabel: (row) => `View details for ${String(row['name'])}`,
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const IncorrectUsage: Story = {
|
|
66
|
-
name: 'Incorrect Usage',
|
|
67
|
-
render: () => ({
|
|
68
|
-
template: `
|
|
69
|
-
<section style="max-width: 720px; border: 1px solid var(--mf-color-border); border-radius: 16px; padding: 20px; background: var(--mf-color-surface);">
|
|
70
|
-
<h2 style="margin: 0 0 12px; font-size: 1rem;">Anti-patterns</h2>
|
|
71
|
-
<ul style="margin: 0 0 16px; padding-left: 18px;">
|
|
72
|
-
<li>Making the entire row clickable with \`(click)\` on \`tr\`.</li>
|
|
73
|
-
<li>Using color as the only status indicator.</li>
|
|
74
|
-
<li>Repeating the same accessible name for every row action.</li>
|
|
75
|
-
</ul>
|
|
76
|
-
<pre style="margin: 0; padding: 16px; border-radius: 12px; background: #111827; color: #f9fafb; overflow: auto;"><code><tr (click)="openDetail(row)">...</tr></code></pre>
|
|
77
|
-
</section>
|
|
78
|
-
`,
|
|
79
|
-
}),
|
|
80
|
-
};
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/angular';
|
|
2
|
-
|
|
3
|
-
import { MfToolbarComponent } from '../app/components/toolbar';
|
|
4
|
-
import { MfButtonComponent } from '../app/components/button';
|
|
5
|
-
import { MfIconComponent } from '../app/components/icon';
|
|
6
|
-
|
|
7
|
-
const meta: Meta<MfToolbarComponent> = {
|
|
8
|
-
title: 'Organisms/MfToolbar',
|
|
9
|
-
component: MfToolbarComponent,
|
|
10
|
-
tags: ['autodocs'],
|
|
11
|
-
parameters: {
|
|
12
|
-
docs: {
|
|
13
|
-
description: {
|
|
14
|
-
component: `
|
|
15
|
-
**MfToolbar** is the toolbar component from the ng-comps library.
|
|
16
|
-
It uses Angular Material \`mat-toolbar\` under the hood with a clean, minimal presentation.
|
|
17
|
-
|
|
18
|
-
| Variant | When to use it |
|
|
19
|
-
|----------------|------------------------------------|
|
|
20
|
-
| \`surface\` | Default toolbar on a light surface |
|
|
21
|
-
| \`brand\` | Toolbar using brand color |
|
|
22
|
-
| \`transparent\` | Over images or gradient backgrounds |
|
|
23
|
-
`,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
argTypes: {
|
|
28
|
-
title: { control: 'text', description: 'Toolbar title' },
|
|
29
|
-
variant: {
|
|
30
|
-
control: 'select',
|
|
31
|
-
options: ['surface', 'brand', 'transparent'],
|
|
32
|
-
description: 'Visual variant',
|
|
33
|
-
},
|
|
34
|
-
bordered: { control: 'boolean', description: 'Bottom border' },
|
|
35
|
-
sticky: { control: 'boolean', description: 'Sticky position' },
|
|
36
|
-
elevated: { control: 'boolean', description: 'Subtle shadow' },
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export default meta;
|
|
41
|
-
type Story = StoryObj<MfToolbarComponent>;
|
|
42
|
-
|
|
43
|
-
export const Surface: Story = {
|
|
44
|
-
render: (args) => ({
|
|
45
|
-
props: args,
|
|
46
|
-
template: `
|
|
47
|
-
<mf-toolbar [title]="title" [variant]="variant" [bordered]="bordered">
|
|
48
|
-
<mf-button mfToolbarEnd label="Sign in" variant="outlined" size="sm" />
|
|
49
|
-
<mf-button mfToolbarEnd label="Register" variant="filled" size="sm" />
|
|
50
|
-
</mf-toolbar>
|
|
51
|
-
`,
|
|
52
|
-
moduleMetadata: { imports: [MfToolbarComponent, MfButtonComponent] },
|
|
53
|
-
}),
|
|
54
|
-
args: {
|
|
55
|
-
title: 'MF Components',
|
|
56
|
-
variant: 'surface',
|
|
57
|
-
bordered: true,
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export const Brand: Story = {
|
|
62
|
-
render: (args) => ({
|
|
63
|
-
props: args,
|
|
64
|
-
template: `
|
|
65
|
-
<mf-toolbar [title]="title" variant="brand" [bordered]="bordered">
|
|
66
|
-
<mf-button mfToolbarEnd label="Dashboard" variant="text" size="sm" />
|
|
67
|
-
<mf-button mfToolbarEnd label="Settings" variant="text" size="sm" />
|
|
68
|
-
</mf-toolbar>
|
|
69
|
-
`,
|
|
70
|
-
moduleMetadata: { imports: [MfToolbarComponent, MfButtonComponent] },
|
|
71
|
-
}),
|
|
72
|
-
args: {
|
|
73
|
-
title: 'Dashboard',
|
|
74
|
-
bordered: true,
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export const WithIcons: Story = {
|
|
79
|
-
name: 'With icons',
|
|
80
|
-
render: () => ({
|
|
81
|
-
template: `
|
|
82
|
-
<mf-toolbar title="My App" variant="surface" [bordered]="true" [elevated]="true">
|
|
83
|
-
<mf-icon mfToolbarEnd name="notifications" color="muted" />
|
|
84
|
-
<mf-icon mfToolbarEnd name="settings" color="muted" />
|
|
85
|
-
<mf-icon mfToolbarEnd name="account_circle" size="lg" color="brand" />
|
|
86
|
-
</mf-toolbar>
|
|
87
|
-
`,
|
|
88
|
-
moduleMetadata: { imports: [MfToolbarComponent, MfIconComponent] },
|
|
89
|
-
}),
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export const Elevated: Story = {
|
|
93
|
-
render: () => ({
|
|
94
|
-
template: `
|
|
95
|
-
<mf-toolbar title="Elevated" [elevated]="true" [bordered]="false">
|
|
96
|
-
<mf-button mfToolbarEnd label="Action" variant="filled" size="sm" />
|
|
97
|
-
</mf-toolbar>
|
|
98
|
-
`,
|
|
99
|
-
moduleMetadata: { imports: [MfToolbarComponent, MfButtonComponent] },
|
|
100
|
-
}),
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export const Transparent: Story = {
|
|
104
|
-
render: () => ({
|
|
105
|
-
template: `
|
|
106
|
-
<div style="background: linear-gradient(135deg, var(--mf-color-primary-700), var(--mf-color-primary-900)); padding: 0; border-radius: var(--mf-radius-lg);">
|
|
107
|
-
<mf-toolbar title="On gradient" variant="transparent" [bordered]="false" />
|
|
108
|
-
</div>
|
|
109
|
-
`,
|
|
110
|
-
moduleMetadata: { imports: [MfToolbarComponent] },
|
|
111
|
-
}),
|
|
112
|
-
};
|
package/src/stories/user.ts
DELETED
package/tsconfig.app.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
-
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
-
{
|
|
4
|
-
"extends": "./tsconfig.json",
|
|
5
|
-
"compilerOptions": {
|
|
6
|
-
"outDir": "./out-tsc/app",
|
|
7
|
-
"types": []
|
|
8
|
-
},
|
|
9
|
-
"include": [
|
|
10
|
-
"src/**/*.ts"
|
|
11
|
-
],
|
|
12
|
-
"exclude": [
|
|
13
|
-
"src/**/*.spec.ts"
|
|
14
|
-
]
|
|
15
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
-
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
-
{
|
|
4
|
-
"compileOnSave": false,
|
|
5
|
-
"compilerOptions": {
|
|
6
|
-
"strict": true,
|
|
7
|
-
"noImplicitOverride": true,
|
|
8
|
-
"noPropertyAccessFromIndexSignature": true,
|
|
9
|
-
"noImplicitReturns": true,
|
|
10
|
-
"noFallthroughCasesInSwitch": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"isolatedModules": true,
|
|
13
|
-
"experimentalDecorators": true,
|
|
14
|
-
"importHelpers": true,
|
|
15
|
-
"target": "ES2022",
|
|
16
|
-
"module": "preserve"
|
|
17
|
-
},
|
|
18
|
-
"angularCompilerOptions": {
|
|
19
|
-
"enableI18nLegacyMessageIdFormat": false,
|
|
20
|
-
"strictInjectionParameters": true,
|
|
21
|
-
"strictInputAccessModifiers": true,
|
|
22
|
-
"strictTemplates": true
|
|
23
|
-
},
|
|
24
|
-
"files": [],
|
|
25
|
-
"references": [
|
|
26
|
-
{
|
|
27
|
-
"path": "./tsconfig.app.json"
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"path": "./tsconfig.spec.json"
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
}
|
package/tsconfig.spec.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
-
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
-
{
|
|
4
|
-
"extends": "./tsconfig.json",
|
|
5
|
-
"compilerOptions": {
|
|
6
|
-
"outDir": "./out-tsc/spec",
|
|
7
|
-
"types": [
|
|
8
|
-
"vitest/globals"
|
|
9
|
-
]
|
|
10
|
-
},
|
|
11
|
-
"include": [
|
|
12
|
-
"src/**/*.d.ts",
|
|
13
|
-
"src/**/*.spec.ts"
|
|
14
|
-
]
|
|
15
|
-
}
|