semmet-angular 0.42.0 → 0.43.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/README.en.md +2 -315
- package/README.md +169 -264
- package/package.json +2 -2
- package/src/accordion/files/__name@dasherize__/__name@dasherize__.css.template +4 -41
- package/src/accordion/schema.json +19 -4
- package/src/alert/files/__name@dasherize__/__name@dasherize__.css.template +1 -25
- package/src/alert/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
- package/src/alert/files/__name@dasherize__/__name@dasherize__.ts.template +4 -1
- package/src/alert/schema.json +19 -4
- package/src/alert-dialog/files/__name@dasherize__/__name@dasherize__.css.template +3 -56
- package/src/alert-dialog/files/__name@dasherize__/__name@dasherize__.html.template +6 -6
- package/src/alert-dialog/files/__name@dasherize__/__name@dasherize__.ts.template +7 -1
- package/src/alert-dialog/schema.json +19 -4
- package/src/avatar/files/__name@dasherize__/__name@dasherize__.css.template +17 -0
- package/src/avatar/files/__name@dasherize__/__name@dasherize__.html.template +28 -0
- package/src/avatar/files/__name@dasherize__/__name@dasherize__.spec.ts.template +27 -0
- package/src/avatar/files/__name@dasherize__/__name@dasherize__.ts.template +35 -0
- package/src/avatar/index.d.ts +1 -0
- package/src/avatar/index.js +6 -0
- package/src/avatar/index.js.map +1 -0
- package/src/avatar/index.ts +3 -0
- package/src/avatar/schema.d.ts +1 -0
- package/src/avatar/schema.js +3 -0
- package/src/avatar/schema.js.map +1 -0
- package/src/avatar/schema.json +44 -0
- package/src/avatar/schema.ts +1 -0
- package/src/badge/files/__name@dasherize__/__name@dasherize__.css.template +0 -77
- package/src/badge/files/__name@dasherize__/__name@dasherize__.ts.template +2 -5
- package/src/badge/schema.json +19 -4
- package/src/block/files/__name@dasherize__/__name@dasherize__.css.template +10 -81
- package/src/block/files/__name@dasherize__/__name@dasherize__.html.template +33 -25
- package/src/block/files/__name@dasherize__/__name@dasherize__.ts.template +41 -10
- package/src/block/schema.json +19 -4
- package/src/breadcrumb/files/__name@dasherize__/__name@dasherize__.css.template +2 -23
- package/src/breadcrumb/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
- package/src/breadcrumb/files/__name@dasherize__/__name@dasherize__.ts.template +9 -5
- package/src/breadcrumb/schema.json +19 -4
- package/src/button/files/__name@dasherize__/__name@dasherize__.css.template +2 -79
- package/src/button/files/__name@dasherize__/__name@dasherize__.ts.template +2 -5
- package/src/button/schema.json +19 -4
- package/src/button-group/files/__name@dasherize__/__name@dasherize__.css.template +2 -70
- package/src/button-group/files/__name@dasherize__/__name@dasherize__.ts.template +1 -2
- package/src/button-group/schema.json +19 -4
- package/src/card/files/__name@dasherize__/__name@dasherize__.css.template +0 -67
- package/src/card/files/__name@dasherize__/__name@dasherize__.html.template +10 -55
- package/src/card/files/__name@dasherize__/__name@dasherize__.ts.template +2 -45
- package/src/card/schema.json +19 -4
- package/src/carousel/files/__name@dasherize__/__name@dasherize__.css.template +2 -32
- package/src/carousel/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
- package/src/carousel/files/__name@dasherize__/__name@dasherize__.ts.template +4 -0
- package/src/carousel/schema.json +19 -4
- package/src/checkbox/files/__name@dasherize__/__name@dasherize__.css.template +5 -21
- package/src/checkbox/schema.json +19 -4
- package/src/close-button/files/__name@dasherize__/__name@dasherize__.css.template +9 -47
- package/src/close-button/files/__name@dasherize__/__name@dasherize__.ts.template +2 -5
- package/src/close-button/schema.json +19 -4
- package/src/collection.json +15 -0
- package/src/combobox/files/__name@dasherize__/__name@dasherize__.css.template +4 -49
- package/src/combobox/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
- package/src/combobox/files/__name@dasherize__/__name@dasherize__.ts.template +11 -8
- package/src/combobox/schema.json +19 -4
- package/src/dialog/files/__name@dasherize__/__name@dasherize__.css.template +3 -45
- package/src/dialog/files/__name@dasherize__/__name@dasherize__.html.template +5 -5
- package/src/dialog/files/__name@dasherize__/__name@dasherize__.ts.template +6 -1
- package/src/dialog/schema.json +19 -4
- package/src/disclosure/files/__name@dasherize__/__name@dasherize__.css.template +4 -36
- package/src/disclosure/schema.json +19 -4
- package/src/form/files/__name@dasherize__/__name@dasherize__.css.template +1 -77
- package/src/form/files/__name@dasherize__/__name@dasherize__.html.template +7 -7
- package/src/form/files/__name@dasherize__/__name@dasherize__.ts.template +20 -7
- package/src/form/schema.json +19 -4
- package/src/input/files/__name@dasherize__/__name@dasherize__.css.template +2 -58
- package/src/input/schema.json +19 -4
- package/src/input-group/files/__name@dasherize__/__name@dasherize__.css.template +2 -68
- package/src/input-group/files/__name@dasherize__/__name@dasherize__.html.template +13 -5
- package/src/input-group/files/__name@dasherize__/__name@dasherize__.ts.template +21 -6
- package/src/input-group/schema.json +19 -4
- package/src/landmarks/files/__name@dasherize__/__name@dasherize__.css.template +0 -24
- package/src/landmarks/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
- package/src/landmarks/files/__name@dasherize__/__name@dasherize__.ts.template +5 -2
- package/src/landmarks/schema.json +19 -4
- package/src/list-group/files/__name@dasherize__/__name@dasherize__.css.template +0 -123
- package/src/list-group/files/__name@dasherize__/__name@dasherize__.e2e-spec.ts.template +8 -9
- package/src/list-group/files/__name@dasherize__/__name@dasherize__.html.template +13 -47
- package/src/list-group/files/__name@dasherize__/__name@dasherize__.spec.ts.template +46 -24
- package/src/list-group/files/__name@dasherize__/__name@dasherize__.ts.template +97 -39
- package/src/list-group/schema.json +19 -4
- package/src/listbox/files/__name@dasherize__/__name@dasherize__.css.template +3 -37
- package/src/listbox/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
- package/src/listbox/files/__name@dasherize__/__name@dasherize__.ts.template +3 -1
- package/src/listbox/schema.json +19 -4
- package/src/menu-button/files/__name@dasherize__/__name@dasherize__.css.template +7 -47
- package/src/menu-button/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
- package/src/menu-button/files/__name@dasherize__/__name@dasherize__.ts.template +10 -7
- package/src/menu-button/schema.json +19 -4
- package/src/meter/files/__name@dasherize__/__name@dasherize__.css.template +0 -12
- package/src/meter/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
- package/src/meter/files/__name@dasherize__/__name@dasherize__.ts.template +3 -1
- package/src/meter/schema.json +19 -4
- package/src/navbar/files/__name@dasherize__/__name@dasherize__.css.template +6 -62
- package/src/navbar/schema.json +19 -4
- package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.css.template +6 -37
- package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.html.template +7 -6
- package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.ts.template +15 -1
- package/src/navigation-menu/schema.json +19 -4
- package/src/offcanvas/files/__name@dasherize__/__name@dasherize__.css.template +3 -70
- package/src/offcanvas/schema.json +19 -4
- package/src/pagination/files/__name@dasherize__/__name@dasherize__.css.template +2 -33
- package/src/pagination/files/__name@dasherize__/__name@dasherize__.html.template +6 -6
- package/src/pagination/files/__name@dasherize__/__name@dasherize__.ts.template +7 -1
- package/src/pagination/schema.json +19 -4
- package/src/popover/files/__name@dasherize__/__name@dasherize__.css.template +8 -69
- package/src/popover/schema.json +19 -4
- package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.css.template +1 -31
- package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
- package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.ts.template +5 -1
- package/src/progress-bar/schema.json +19 -4
- package/src/radio-group/files/__name@dasherize__/__name@dasherize__.css.template +4 -31
- package/src/radio-group/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
- package/src/radio-group/files/__name@dasherize__/__name@dasherize__.ts.template +2 -1
- package/src/radio-group/schema.json +19 -4
- package/src/rating/files/__name@dasherize__/__name@dasherize__.css.template +17 -0
- package/src/rating/files/__name@dasherize__/__name@dasherize__.html.template +34 -0
- package/src/rating/files/__name@dasherize__/__name@dasherize__.spec.ts.template +38 -0
- package/src/rating/files/__name@dasherize__/__name@dasherize__.ts.template +75 -0
- package/src/rating/index.d.ts +1 -0
- package/src/rating/index.js +6 -0
- package/src/rating/index.js.map +1 -0
- package/src/rating/index.ts +3 -0
- package/src/rating/schema.d.ts +1 -0
- package/src/rating/schema.js +3 -0
- package/src/rating/schema.js.map +1 -0
- package/src/rating/schema.json +44 -0
- package/src/rating/schema.ts +1 -0
- package/src/select/files/__name@dasherize__/__name@dasherize__.css.template +4 -55
- package/src/select/schema.json +19 -4
- package/src/skeleton/files/__name@dasherize__/__name@dasherize__.css.template +2 -29
- package/src/skeleton/files/__name@dasherize__/__name@dasherize__.ts.template +1 -3
- package/src/skeleton/schema.json +19 -4
- package/src/skip-link/files/__name@dasherize__/__name@dasherize__.css.template +2 -14
- package/src/skip-link/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
- package/src/skip-link/files/__name@dasherize__/__name@dasherize__.ts.template +5 -2
- package/src/skip-link/schema.json +19 -4
- package/src/slider/files/__name@dasherize__/__name@dasherize__.css.template +6 -20
- package/src/slider/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
- package/src/slider/files/__name@dasherize__/__name@dasherize__.ts.template +3 -1
- package/src/slider/schema.json +19 -4
- package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.css.template +6 -35
- package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
- package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.ts.template +5 -1
- package/src/spinbutton/schema.json +19 -4
- package/src/spinner/files/__name@dasherize__/__name@dasherize__.css.template +0 -43
- package/src/spinner/files/__name@dasherize__/__name@dasherize__.ts.template +2 -5
- package/src/spinner/schema.json +19 -4
- package/src/steps/files/__name@dasherize__/__name@dasherize__.css.template +36 -0
- package/src/steps/files/__name@dasherize__/__name@dasherize__.html.template +44 -0
- package/src/steps/files/__name@dasherize__/__name@dasherize__.spec.ts.template +35 -0
- package/src/steps/files/__name@dasherize__/__name@dasherize__.ts.template +107 -0
- package/src/steps/index.d.ts +1 -0
- package/src/steps/index.js +6 -0
- package/src/steps/index.js.map +1 -0
- package/src/steps/index.ts +3 -0
- package/src/steps/schema.d.ts +1 -0
- package/src/steps/schema.js +3 -0
- package/src/steps/schema.js.map +1 -0
- package/src/steps/schema.json +44 -0
- package/src/steps/schema.ts +1 -0
- package/src/switch/files/__name@dasherize__/__name@dasherize__.css.template +7 -22
- package/src/switch/schema.json +19 -4
- package/src/table/files/__name@dasherize__/__name@dasherize__.css.template +0 -25
- package/src/table/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
- package/src/table/files/__name@dasherize__/__name@dasherize__.ts.template +3 -0
- package/src/table/schema.json +19 -4
- package/src/tabs/files/__name@dasherize__/__name@dasherize__.css.template +5 -44
- package/src/tabs/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
- package/src/tabs/files/__name@dasherize__/__name@dasherize__.ts.template +2 -0
- package/src/tabs/schema.json +19 -4
- package/src/textarea/files/__name@dasherize__/__name@dasherize__.css.template +2 -59
- package/src/textarea/schema.json +19 -4
- package/src/toast/files/__name@dasherize__/__name@dasherize__.css.template +1 -35
- package/src/toast/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
- package/src/toast/files/__name@dasherize__/__name@dasherize__.ts.template +5 -1
- package/src/toast/schema.json +19 -4
- package/src/toolbar/files/__name@dasherize__/__name@dasherize__.css.template +2 -36
- package/src/toolbar/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
- package/src/toolbar/files/__name@dasherize__/__name@dasherize__.ts.template +11 -8
- package/src/toolbar/schema.json +19 -4
- package/src/tooltip/files/__name@dasherize__/__name@dasherize__.css.template +1 -32
- package/src/tooltip/schema.json +19 -4
- package/src/tree-view/files/__name@dasherize__/__name@dasherize__.css.template +5 -27
- package/src/tree-view/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
- package/src/tree-view/files/__name@dasherize__/__name@dasherize__.ts.template +16 -13
- package/src/tree-view/schema.json +19 -4
- package/src/utils/generate-component.js +3 -1
- package/src/utils/generate-component.js.map +1 -1
- package/src/utils/generate-component.ts +3 -1
- package/src/utils/generate-composition.js +0 -1
- package/src/utils/generate-composition.js.map +1 -1
- package/src/utils/generate-composition.ts +0 -1
- package/src/utils/schema-types.d.ts +1 -0
- package/src/utils/schema-types.ts +1 -0
- package/README.pt-BR.md +0 -330
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, ElementRef, computed, signal, viewChildren } from '@angular/core';
|
|
1
|
+
import { Component, ElementRef, computed, input, signal, viewChildren } from '@angular/core';
|
|
2
2
|
|
|
3
3
|
interface <%= classify(name) %>Node {
|
|
4
4
|
id: number;
|
|
@@ -11,6 +11,17 @@ interface VisibleNode {
|
|
|
11
11
|
parentId: number | null;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
const DEFAULT_TREE: readonly <%= classify(name) %>Node[] = [
|
|
15
|
+
{
|
|
16
|
+
id: 1,
|
|
17
|
+
label: 'Documents',
|
|
18
|
+
children: [
|
|
19
|
+
{ id: 2, label: 'Resume.pdf' },
|
|
20
|
+
{ id: 3, label: 'Cover Letter.docx' },
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
|
|
14
25
|
@Component({
|
|
15
26
|
selector: '<%= selector %>',
|
|
16
27
|
imports: [],
|
|
@@ -20,23 +31,15 @@ interface VisibleNode {
|
|
|
20
31
|
export class <%= classify(name) %> {
|
|
21
32
|
private readonly treeItems = viewChildren<ElementRef<HTMLElement>>('treeItem');
|
|
22
33
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
id: 1,
|
|
26
|
-
label: 'Documents',
|
|
27
|
-
children: [
|
|
28
|
-
{ id: 2, label: 'Resume.pdf' },
|
|
29
|
-
{ id: 3, label: 'Cover Letter.docx' },
|
|
30
|
-
],
|
|
31
|
-
},
|
|
32
|
-
];
|
|
34
|
+
readonly label = input('Files');
|
|
35
|
+
readonly tree = input<readonly <%= classify(name) %>Node[]>(DEFAULT_TREE);
|
|
33
36
|
|
|
34
37
|
private readonly expandedIds = signal<ReadonlySet<number>>(new Set([1]));
|
|
35
38
|
protected readonly activeId = signal(1);
|
|
36
39
|
|
|
37
40
|
protected readonly visibleNodes = computed<VisibleNode[]>(() => {
|
|
38
41
|
const result: VisibleNode[] = [];
|
|
39
|
-
const walk = (nodes: <%= classify(name) %>Node[], parentId: number | null): void => {
|
|
42
|
+
const walk = (nodes: readonly <%= classify(name) %>Node[], parentId: number | null): void => {
|
|
40
43
|
for (const node of nodes) {
|
|
41
44
|
result.push({ node, parentId });
|
|
42
45
|
if (node.children && this.expandedIds().has(node.id)) {
|
|
@@ -44,7 +47,7 @@ export class <%= classify(name) %> {
|
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
};
|
|
47
|
-
walk(this.tree, null);
|
|
50
|
+
walk(this.tree(), null);
|
|
48
51
|
return result;
|
|
49
52
|
});
|
|
50
53
|
|
|
@@ -9,21 +9,36 @@
|
|
|
9
9
|
"name": {
|
|
10
10
|
"type": "string",
|
|
11
11
|
"description": "The name for the new component. Used to derive the class name, selector, and file names.",
|
|
12
|
-
"$default": {
|
|
12
|
+
"$default": {
|
|
13
|
+
"$source": "argv",
|
|
14
|
+
"index": 0
|
|
15
|
+
},
|
|
13
16
|
"x-prompt": "What name would you like to use for the tree view component?"
|
|
14
17
|
},
|
|
18
|
+
"e2e": {
|
|
19
|
+
"type": "boolean",
|
|
20
|
+
"default": false,
|
|
21
|
+
"description": "Generate a Playwright e2e spec for this component. Requires Playwright to be installed/configured in the consuming app."
|
|
22
|
+
},
|
|
15
23
|
"path": {
|
|
16
24
|
"type": "string",
|
|
17
25
|
"format": "path",
|
|
18
|
-
"$default": {
|
|
26
|
+
"$default": {
|
|
27
|
+
"$source": "workingDirectory"
|
|
28
|
+
},
|
|
19
29
|
"description": "The path where the component files should be created, relative to the workspace root. Defaults to the project's source root.",
|
|
20
30
|
"visible": false
|
|
21
31
|
},
|
|
22
32
|
"project": {
|
|
23
33
|
"type": "string",
|
|
24
34
|
"description": "The name of the project to add the component to.",
|
|
25
|
-
"$default": {
|
|
35
|
+
"$default": {
|
|
36
|
+
"$source": "projectName"
|
|
37
|
+
}
|
|
26
38
|
}
|
|
27
39
|
},
|
|
28
|
-
"required": [
|
|
40
|
+
"required": [
|
|
41
|
+
"name",
|
|
42
|
+
"project"
|
|
43
|
+
]
|
|
29
44
|
}
|
|
@@ -15,7 +15,8 @@ const validation_1 = require("@schematics/angular/utility/validation");
|
|
|
15
15
|
function createAriaComponentSchematic(config = {}) {
|
|
16
16
|
return (0, project_1.createProjectSchematic)((options, { project }) => {
|
|
17
17
|
const includeSharedUnitTest = config.includeSharedUnitTest ?? true;
|
|
18
|
-
const
|
|
18
|
+
const includeE2eTest = options.e2e ?? false;
|
|
19
|
+
const includeSharedE2eTest = (config.includeSharedE2eTest ?? true) && includeE2eTest;
|
|
19
20
|
options.path ??= (0, workspace_1.buildDefaultPath)(project);
|
|
20
21
|
const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
|
|
21
22
|
const name = parsedPath.name;
|
|
@@ -23,6 +24,7 @@ function createAriaComponentSchematic(config = {}) {
|
|
|
23
24
|
(0, validation_1.validateHtmlSelector)(selector);
|
|
24
25
|
(0, validation_1.validateClassName)(core_1.strings.classify(name));
|
|
25
26
|
const componentTemplateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [
|
|
27
|
+
(0, schematics_1.filter)((path) => !path.endsWith('.e2e-spec.ts.template') || includeE2eTest),
|
|
26
28
|
(0, schematics_1.applyTemplates)({ ...core_1.strings, name, selector }),
|
|
27
29
|
(0, schematics_1.move)(parsedPath.path),
|
|
28
30
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-component.js","sourceRoot":"","sources":["generate-component.ts"],"names":[],"mappings":";;AAkBA,
|
|
1
|
+
{"version":3,"file":"generate-component.js","sourceRoot":"","sources":["generate-component.ts"],"names":[],"mappings":";;AAkBA,oEAwCC;AA1DD,2DAA8G;AAC9G,+CAA+C;AAC/C,iEAA6E;AAC7E,qEAAyE;AACzE,uEAAmE;AACnE,uEAAiG;AAQjG;;;;GAIG;AACH,SAAgB,4BAA4B,CAAC,SAAuC,EAAE;IACpF,OAAO,IAAA,gCAAsB,EAA4B,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QAChF,MAAM,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,IAAI,IAAI,CAAC;QACnE,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,IAAI,KAAK,CAAC;QAC5C,MAAM,oBAAoB,GAAG,CAAC,MAAM,CAAC,oBAAoB,IAAI,IAAI,CAAC,IAAI,cAAc,CAAC;QACrF,OAAO,CAAC,IAAI,KAAK,IAAA,4BAAgB,EAAC,OAAO,CAAC,CAAC;QAE3C,MAAM,UAAU,GAAG,IAAA,sBAAS,EAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;QAE7B,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,cAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3F,IAAA,iCAAoB,EAAC,QAAQ,CAAC,CAAC;QAC/B,IAAA,8BAAiB,EAAC,cAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1C,MAAM,uBAAuB,GAAG,IAAA,kBAAK,EAAC,IAAA,gBAAG,EAAC,SAAS,CAAC,EAAE;YACpD,IAAA,mBAAM,EAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,IAAI,cAAc,CAAC;YAC3E,IAAA,2BAAc,EAAC,EAAE,GAAG,cAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC9C,IAAA,iBAAI,EAAC,UAAU,CAAC,IAAI,CAAC;SACtB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,CAAC,IAAA,sBAAS,EAAC,uBAAuB,CAAC,CAAC,CAAC;QAEnD,IAAI,qBAAqB,IAAI,oBAAoB,EAAE,CAAC;YAClD,MAAM,kBAAkB,GAAG,IAAA,kBAAK,EAAC,IAAA,gBAAG,EAAC,+BAA+B,CAAC,EAAE;gBACrE,IAAA,mBAAM,EAAC,CAAC,IAAI,EAAE,EAAE;oBACd,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;wBACvC,OAAO,qBAAqB,CAAC;oBAC/B,CAAC;oBACD,IAAI,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;wBAC3C,OAAO,oBAAoB,CAAC;oBAC9B,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC,CAAC;gBACF,IAAA,2BAAc,EAAC,EAAE,GAAG,cAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;gBAC9C,IAAA,iBAAI,EAAC,UAAU,CAAC,IAAI,CAAC;aACtB,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,IAAA,sBAAS,EAAC,kBAAkB,CAAC,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,IAAA,kBAAK,EAAC,KAAK,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -19,7 +19,8 @@ interface AriaComponentSchematicConfig {
|
|
|
19
19
|
export function createAriaComponentSchematic(config: AriaComponentSchematicConfig = {}): (options: ComponentSchematicOptions) => Rule {
|
|
20
20
|
return createProjectSchematic<ComponentSchematicOptions>((options, { project }) => {
|
|
21
21
|
const includeSharedUnitTest = config.includeSharedUnitTest ?? true;
|
|
22
|
-
const
|
|
22
|
+
const includeE2eTest = options.e2e ?? false;
|
|
23
|
+
const includeSharedE2eTest = (config.includeSharedE2eTest ?? true) && includeE2eTest;
|
|
23
24
|
options.path ??= buildDefaultPath(project);
|
|
24
25
|
|
|
25
26
|
const parsedPath = parseName(options.path, options.name);
|
|
@@ -30,6 +31,7 @@ export function createAriaComponentSchematic(config: AriaComponentSchematicConfi
|
|
|
30
31
|
validateClassName(strings.classify(name));
|
|
31
32
|
|
|
32
33
|
const componentTemplateSource = apply(url('./files'), [
|
|
34
|
+
filter((path) => !path.endsWith('.e2e-spec.ts.template') || includeE2eTest),
|
|
33
35
|
applyTemplates({ ...strings, name, selector }),
|
|
34
36
|
move(parsedPath.path),
|
|
35
37
|
]);
|
|
@@ -40,7 +40,6 @@ function getSupportingComponent(kind) {
|
|
|
40
40
|
case 'section-table':
|
|
41
41
|
return { templatePath: '../table/files', variable: 'table' };
|
|
42
42
|
case 'header-navbar':
|
|
43
|
-
case 'footer-navigation':
|
|
44
43
|
return { templatePath: '../navbar/files', variable: 'navbar' };
|
|
45
44
|
case 'section-form':
|
|
46
45
|
return { templatePath: '../form/files', variable: 'form' };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-composition.js","sourceRoot":"","sources":["generate-composition.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"generate-composition.js","sourceRoot":"","sources":["generate-composition.ts"],"names":[],"mappings":"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"}
|
|
@@ -53,7 +53,6 @@ function getSupportingComponent(kind: string): SupportingComponent | null {
|
|
|
53
53
|
case 'section-table':
|
|
54
54
|
return { templatePath: '../table/files', variable: 'table' };
|
|
55
55
|
case 'header-navbar':
|
|
56
|
-
case 'footer-navigation':
|
|
57
56
|
return { templatePath: '../navbar/files', variable: 'navbar' };
|
|
58
57
|
case 'section-form':
|
|
59
58
|
return { templatePath: '../form/files', variable: 'form' };
|
package/README.pt-BR.md
DELETED
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
# semmet-angular
|
|
2
|
-
|
|
3
|
-
**Dev kit de entrega de UI acessível em Angular.**
|
|
4
|
-
|
|
5
|
-
Gere componentes Angular acessíveis, blocos de interface e scaffolds de entrega pelo CLI.
|
|
6
|
-
|
|
7
|
-
Semmet Angular ajuda times a gerar, compor, testar, verificar e empacotar UI acessível usando o ecossistema do Angular CLI.
|
|
8
|
-
|
|
9
|
-
**Gerar. Compor. Testar. Verificar. Empacotar.**
|
|
10
|
-
|
|
11
|
-
Leia a direção geral do produto em [PRODUCT_VISION.md](./PRODUCT_VISION.md).
|
|
12
|
-
|
|
13
|
-
`ng generate semmet-angular:accordion minha-faq` cria um componente Angular standalone baseado em signals — `.ts`/`.html`/`.css` — junto com testes `.spec.ts` e `.e2e-spec.ts`. O componente gerado implementa de verdade um padrão do W3C ARIA Authoring Practices Guide: roles corretos, ligação de atributos `aria-*`, comportamento de teclado/foco exigido pelo padrão (navegação por setas, focus trap, restauração de foco...) e uma identidade visual consistente logo de saída.
|
|
14
|
-
|
|
15
|
-
## Uso
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
ng add semmet-angular
|
|
19
|
-
ng generate semmet-angular:accordion minha-faq
|
|
20
|
-
ng generate semmet-angular:block section-card
|
|
21
|
-
ng generate semmet-angular:ci
|
|
22
|
-
ng generate semmet-angular:docker
|
|
23
|
-
ng generate semmet-angular:deploy
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
`ng add semmet-angular` instala o pacote e configura uma vez o fluxo de entrega da aplicação alvo, incluindo suporte a e2e com Playwright, scripts npm e `npm run verify`. Cada componente gerado entra no seu projeto do mesmo jeito que entraria com `ng generate component` (respeitando `angular.json`, `sourceRoot` e prefixo de seletor), e tem **zero dependência em tempo de execução** deste pacote — `semmet-angular` só é necessário na geração.
|
|
27
|
-
|
|
28
|
-
## Arquitetura em Camadas
|
|
29
|
-
|
|
30
|
-
Use componentes isolados quando precisar de controle fino, ou compositions quando quiser acelerar telas acessíveis com estrutura já validada.
|
|
31
|
-
|
|
32
|
-
- **Components**: componentes isolados como `button`, `card`, `accordion`, `table` e `navbar`.
|
|
33
|
-
- **Compositions / Blocks**: seções prontas como `section-card`, `section-faq`, `section-pricing`, `section-stats`, `section-table`, `section-form`, `section-tabs`, `section-list-group`, `section-alert`, `section-progress`, `section-carousel`, `header-navbar`, `footer-navigation` e `command-list`.
|
|
34
|
-
- **Delivery**: `ng add`, `ci`, `docker`, `deploy` e `verify`.
|
|
35
|
-
|
|
36
|
-
## Comandos de Composição
|
|
37
|
-
|
|
38
|
-
Compositions/blocks geram seções Angular standalone usando os componentes correspondentes da própria Semmet. O CSS gerado fica local no block e usa tokens locais de espaçamento para manter ritmo de landing page sem injetar estilo global na aplicação.
|
|
39
|
-
|
|
40
|
-
| Comando | Gera | Usa como base |
|
|
41
|
-
|---|---|---|
|
|
42
|
-
| `ng generate semmet-angular:block hero` | Seção hero semântica | Estrutura de seção |
|
|
43
|
-
| `ng generate semmet-angular:block section-card` | Seção de cards | `card` |
|
|
44
|
-
| `ng generate semmet-angular:block section-faq` | Seção de FAQ | `accordion` |
|
|
45
|
-
| `ng generate semmet-angular:block section-pricing` | Seção de preços | `card` |
|
|
46
|
-
| `ng generate semmet-angular:block section-stats` | Seção de métricas | Estrutura de seção |
|
|
47
|
-
| `ng generate semmet-angular:block section-table` | Seção com tabela | `table` |
|
|
48
|
-
| `ng generate semmet-angular:block section-form` | Seção com formulário | `form` |
|
|
49
|
-
| `ng generate semmet-angular:block section-tabs` | Seção com abas | `tabs` |
|
|
50
|
-
| `ng generate semmet-angular:block section-list-group` | Seção com lista de ações | `list-group` |
|
|
51
|
-
| `ng generate semmet-angular:block section-alert` | Seção com alerta | `alert` |
|
|
52
|
-
| `ng generate semmet-angular:block section-progress` | Seção com progresso | `progress-bar` |
|
|
53
|
-
| `ng generate semmet-angular:block section-carousel` | Seção com carousel | `carousel` |
|
|
54
|
-
| `ng generate semmet-angular:block header-navbar` | Header com navegação | `navbar` |
|
|
55
|
-
| `ng generate semmet-angular:block footer-navigation` | Footer com navegação | `navbar` |
|
|
56
|
-
| `ng generate semmet-angular:block command-list` | Seção de comandos | Estrutura de seção |
|
|
57
|
-
|
|
58
|
-
## Fluxo de Entrega
|
|
59
|
-
|
|
60
|
-
Depois de rodar `ng add semmet-angular`, use:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
npm test
|
|
64
|
-
npm run e2e
|
|
65
|
-
npm run e2e:ui
|
|
66
|
-
npm run verify
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
`npm run e2e` executa o Playwright contra o servidor de desenvolvimento Angular configurado por `playwright.config.ts`; `npm run e2e:ui` abre a interface interativa do Playwright.
|
|
70
|
-
|
|
71
|
-
O script `npm run verify` é criado sem sobrescrever um script `verify` existente. Quando os scripts estão disponíveis no `package.json` da aplicação, ele compõe um fluxo simples com:
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
npm test -- --watch=false
|
|
75
|
-
npm run e2e
|
|
76
|
-
npm run build
|
|
77
|
-
npm run lint
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
`lint` só entra quando a aplicação já tem um script `lint`; `build` e `test` seguem a mesma lógica. O `e2e` entra depois da configuração do Playwright feita pelo `ng add`.
|
|
81
|
-
|
|
82
|
-
## CI com GitHub Actions
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
ng generate semmet-angular:ci
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Esse comando gera `.github/workflows/ci.yml` usando os scripts já existentes no `package.json`. O workflow usa Node 24, detecta o gerenciador de pacotes por lockfile (`package-lock.json`, `pnpm-lock.yaml` ou `yarn.lock`), instala dependências e executa `verify` quando disponível. Se `verify` ainda não existir, ele roda `build`, `test` e `e2e` conforme esses scripts existirem.
|
|
89
|
-
|
|
90
|
-
Quando o projeto usa Playwright, o CI também instala o Chromium com `playwright install --with-deps chromium` e cacheia `~/.cache/ms-playwright` com `actions/cache`, reduzindo o tempo das execuções seguintes.
|
|
91
|
-
|
|
92
|
-
Por padrão, o comando não sobrescreve um workflow existente. Use `--force` quando quiser substituir `.github/workflows/ci.yml`.
|
|
93
|
-
|
|
94
|
-
## Empacotamento com Docker
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
ng generate semmet-angular:docker
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Esse comando gera `Dockerfile`, `.dockerignore` e `nginx.conf` para empacotar a aplicação Angular como uma imagem servida por Nginx. O Dockerfile usa Node 24 no estágio de build, detecta o gerenciador de pacotes por lockfile, executa o build e copia o output configurado no `angular.json` para `/usr/share/nginx/html`.
|
|
101
|
-
|
|
102
|
-
O `nginx.conf` inclui fallback de SPA com `try_files ... /index.html`. Por padrão, o comando não sobrescreve arquivos existentes; use `--force` para substituir a configuração Docker atual.
|
|
103
|
-
|
|
104
|
-
## Deploy Guiado
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
ng generate semmet-angular:deploy
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
O comando pergunta qual plataforma você quer usar e gera a configuração mínima para o destino escolhido. Também dá para passar a plataforma direto:
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
ng generate semmet-angular:deploy --platform=vercel
|
|
114
|
-
ng generate semmet-angular:deploy --platform=netlify
|
|
115
|
-
ng generate semmet-angular:deploy --platform=firebase
|
|
116
|
-
ng generate semmet-angular:deploy --platform=github-pages
|
|
117
|
-
ng generate semmet-angular:deploy --platform=docker
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Destinos suportados: Vercel (`vercel.json`), Netlify (`netlify.toml`), Firebase Hosting (`firebase.json` e `.firebaserc`), GitHub Pages (`.github/workflows/deploy.yml`) e deploy baseado em Docker (`compose.yml` e `deploy/docker.README.md`). O comando detecta o output do build no `angular.json` quando possível e não sobrescreve arquivos existentes sem `--force`.
|
|
121
|
-
|
|
122
|
-
## Testes Gerados
|
|
123
|
-
|
|
124
|
-
Todo comando de componente gera arquivos de teste ao lado do componente:
|
|
125
|
-
|
|
126
|
-
```text
|
|
127
|
-
minha-faq.ts
|
|
128
|
-
minha-faq.html
|
|
129
|
-
minha-faq.css
|
|
130
|
-
minha-faq.spec.ts
|
|
131
|
-
minha-faq.e2e-spec.ts
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
O teste unitário usa o `TestBed` do Angular para verificar o componente pelo seletor público. Componentes interativos também geram testes focados em comportamento: estado ARIA, fluxo de teclado, mudanças de valor, gerenciamento de foco e abertura/fechamento. O teste e2e usa Playwright e passa a valer assim que o componente estiver montado em uma rota ou componente host. Se o componente ainda não estiver em nenhuma página renderizada, o smoke test e2e gerado é pulado com uma mensagem clara, sem quebrar a suíte inteira.
|
|
135
|
-
|
|
136
|
-
## Containers com Conteúdo Projetado
|
|
137
|
-
|
|
138
|
-
Alguns componentes gerados são containers: eles cuidam da ligação ARIA, comportamento de teclado, gerenciamento de foco e casca visual, enquanto a sua aplicação controla o conteúdo renderizado dentro deles.
|
|
139
|
-
|
|
140
|
-
`accordion`, `tabs`, `carousel`, `disclosure`, `card`, `button`, `badge`, `navbar`, `table` e `button-group` usam o padrão moderno de projeção do Angular com `ng-template`, signal queries e `NgTemplateOutlet`. Isso permite colocar componentes reais da aplicação dentro dos componentes gerados sem factories de componente dinâmico.
|
|
141
|
-
|
|
142
|
-
Exemplo depois de gerar `faq`:
|
|
143
|
-
|
|
144
|
-
```ts
|
|
145
|
-
import { Component, signal } from '@angular/core';
|
|
146
|
-
import { Faq, FaqItem } from './faq/faq';
|
|
147
|
-
import { ProfilePanel } from './profile-panel/profile-panel';
|
|
148
|
-
import { SettingsPanel } from './settings-panel/settings-panel';
|
|
149
|
-
|
|
150
|
-
@Component({
|
|
151
|
-
selector: 'app-root',
|
|
152
|
-
imports: [Faq, FaqItem, ProfilePanel, SettingsPanel],
|
|
153
|
-
templateUrl: './app.html',
|
|
154
|
-
})
|
|
155
|
-
export class App {
|
|
156
|
-
readonly userId = signal(123);
|
|
157
|
-
|
|
158
|
-
reload(): void {}
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
```html
|
|
163
|
-
<app-faq>
|
|
164
|
-
<ng-template faqItem id="profile" title="Perfil" [expanded]="true">
|
|
165
|
-
<app-profile-panel />
|
|
166
|
-
</ng-template>
|
|
167
|
-
|
|
168
|
-
<ng-template faqItem id="settings" title="Configurações">
|
|
169
|
-
<app-settings-panel [userId]="userId()" (saved)="reload()" />
|
|
170
|
-
</ng-template>
|
|
171
|
-
</app-faq>
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
O mesmo padrão vale para `tabs`, `carousel` e `disclosure`:
|
|
175
|
-
|
|
176
|
-
```html
|
|
177
|
-
<app-settings-tabs>
|
|
178
|
-
<ng-template settingsTabsItem id="profile" label="Perfil" [selected]="true">
|
|
179
|
-
<app-profile-panel />
|
|
180
|
-
</ng-template>
|
|
181
|
-
</app-settings-tabs>
|
|
182
|
-
|
|
183
|
-
<app-featured-carousel>
|
|
184
|
-
<ng-template featuredCarouselSlide id="intro" label="Introdução">
|
|
185
|
-
<app-intro-slide />
|
|
186
|
-
</ng-template>
|
|
187
|
-
</app-featured-carousel>
|
|
188
|
-
|
|
189
|
-
<app-details label="Mostrar detalhes do perfil" [(expanded)]="profileDetailsOpen">
|
|
190
|
-
<ng-template detailsContent>
|
|
191
|
-
<app-profile-details [userId]="userId()" />
|
|
192
|
-
</ng-template>
|
|
193
|
-
</app-details>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
Por padrão, o conteúdo projetado de painel/slide é preservado depois da primeira renderização. Use `[preserveContent]="false"` no container gerado para destruir conteúdo inativo quando ele fechar ou ficar inativo.
|
|
197
|
-
|
|
198
|
-
Os componentes estruturais menores mantêm APIs simples por input e adicionam slots seguros onde o componente gerado continua dono da estrutura acessível:
|
|
199
|
-
|
|
200
|
-
```html
|
|
201
|
-
<app-product-card title="Componentes acessíveis">
|
|
202
|
-
<ng-template productCardMedia>
|
|
203
|
-
<img src="/assets/card.png" alt="Prévia de componente Angular gerado" />
|
|
204
|
-
</ng-template>
|
|
205
|
-
|
|
206
|
-
<ng-template productCardDescription>
|
|
207
|
-
Gere componentes Angular com ARIA, comportamento de teclado e signals.
|
|
208
|
-
</ng-template>
|
|
209
|
-
|
|
210
|
-
<ng-template productCardActions>
|
|
211
|
-
<a href="/docs">Ler docs</a>
|
|
212
|
-
</ng-template>
|
|
213
|
-
</app-product-card>
|
|
214
|
-
|
|
215
|
-
<app-save-button label="Salvar">
|
|
216
|
-
<ng-template saveButtonLeading>
|
|
217
|
-
<app-save-icon aria-hidden="true" />
|
|
218
|
-
</ng-template>
|
|
219
|
-
</app-save-button>
|
|
220
|
-
|
|
221
|
-
<app-status-badge accessibleLabel="Build passou">
|
|
222
|
-
<ng-template statusBadgeLabel>Passou</ng-template>
|
|
223
|
-
</app-status-badge>
|
|
224
|
-
|
|
225
|
-
<app-main-navbar brand="Acme">
|
|
226
|
-
<ng-template mainNavbarActions>
|
|
227
|
-
<a href="/conta">Conta</a>
|
|
228
|
-
</ng-template>
|
|
229
|
-
</app-main-navbar>
|
|
230
|
-
|
|
231
|
-
<app-results-table caption="Receita trimestral" [rows]="results">
|
|
232
|
-
<ng-template resultsTableEmpty>Nenhum resultado de receita ainda.</ng-template>
|
|
233
|
-
</app-results-table>
|
|
234
|
-
|
|
235
|
-
<app-view-switcher [items]="views">
|
|
236
|
-
<ng-template viewSwitcherItem let-item>
|
|
237
|
-
{{ item.label }}
|
|
238
|
-
</ng-template>
|
|
239
|
-
</app-view-switcher>
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
## Componentes, Blocks e Entrega (43)
|
|
243
|
-
|
|
244
|
-
**Overlays e disclosure**
|
|
245
|
-
|
|
246
|
-
| Comando | Gera | Comportamento de teclado/foco implementado |
|
|
247
|
-
|---|---|---|
|
|
248
|
-
| `ng generate semmet-angular:accordion <nome>` | [Accordion](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/) | Clique/Enter/Espaço alterna; Cima/Baixo/Home/End move foco entre cabeçalhos |
|
|
249
|
-
| `ng generate semmet-angular:disclosure <nome>` | [Disclosure](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/) | Clique/Enter/Espaço alterna |
|
|
250
|
-
| `ng generate semmet-angular:dialog <nome>` | [Dialog (Modal)](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/) | Foco entra ao abrir; Tab/Shift+Tab prende o foco; Escape fecha; foco volta para o acionador |
|
|
251
|
-
| `ng generate semmet-angular:alert-dialog <nome>` | [Alert Dialog](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/) | Mesmo focus trap do Dialog; foco inicial na ação menos destrutiva (Cancelar) |
|
|
252
|
-
| `ng generate semmet-angular:offcanvas <nome>` | Offcanvas / Drawer | Semântica de dialog modal; foco entra; Tab/Shift+Tab prende o foco; Escape/backdrop fecha; foco volta para o acionador |
|
|
253
|
-
| `ng generate semmet-angular:popover <nome>` | Popover | Acionador disclosure com `aria-haspopup="dialog"`; Escape fecha; clique externo dispensa |
|
|
254
|
-
| `ng generate semmet-angular:tooltip <nome>` | [Tooltip](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/) | Aparece no hover **e** no foco; esconde no blur/mouseleave/Escape |
|
|
255
|
-
| `ng generate semmet-angular:menu-button <nome>` | [Menu Button](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/) | Cima/Baixo/Home/End/Escape dentro do menu; fecha em clique externo; foco volta para o acionador |
|
|
256
|
-
| `ng generate semmet-angular:button <nome>` | Button | `<button>` nativo com variante, tamanho, desabilitado, ocupado, estado pressionado opcional e slots seguros de rótulo/ícone |
|
|
257
|
-
| `ng generate semmet-angular:button-group <nome>` | Button Group | Botões nativos agrupados com `role="group"`, estado toggle opcional com `aria-pressed` e projeção segura de rótulo por item |
|
|
258
|
-
| `ng generate semmet-angular:close-button <nome>` | Close Button | Botão de ícone nativo com rótulo acessível obrigatório |
|
|
259
|
-
|
|
260
|
-
**Navegação e estrutura**
|
|
261
|
-
|
|
262
|
-
| Comando | Gera | Comportamento de teclado/foco implementado |
|
|
263
|
-
|---|---|---|
|
|
264
|
-
| `ng generate semmet-angular:tabs <nome>` | [Tabs](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/) | Ativação automática; Esquerda/Direita/Home/End com `tabindex` roving |
|
|
265
|
-
| `ng generate semmet-angular:breadcrumb <nome>` | [Breadcrumb](https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/) | Estático — links simples + `aria-current="page"` |
|
|
266
|
-
| `ng generate semmet-angular:navigation-menu <nome>` | [Navigation Menu (Disclosure)](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/) | Clique/Enter/Espaço alterna submenu; evita `role="menu"` de propósito, reservado para menus de aplicação |
|
|
267
|
-
| `ng generate semmet-angular:navbar <nome>` | Navbar | Estrutura semântica `nav`/lista/link com toggle responsivo, `aria-current` e slots seguros de marca/ações |
|
|
268
|
-
| `ng generate semmet-angular:pagination <nome>` | Pagination | Estado de página funcional; Anterior/Próximo desabilitam nos limites |
|
|
269
|
-
| `ng generate semmet-angular:skip-link <nome>` | [Skip Link](https://www.w3.org/WAI/WCAG21/Techniques/general/G1) | Escondido até receber foco, conforme o padrão de skip link |
|
|
270
|
-
| `ng generate semmet-angular:landmarks <nome>` | [Landmarks (Page Skeleton)](https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/) | Wrapper de layout com projeção de conteúdo (`header`/`nav`/`main`/`aside`/`footer`) |
|
|
271
|
-
| `ng generate semmet-angular:tree-view <nome>` | [Tree View](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/) | Cima/Baixo/Esquerda/Direita/Home/End/Enter com `tabindex` roving nos nós visíveis |
|
|
272
|
-
| `ng generate semmet-angular:toolbar <nome>` | [Toolbar](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/) | Esquerda/Direita/Home/End com `tabindex` roving |
|
|
273
|
-
| `ng generate semmet-angular:card <nome>` | Card | `<article>` semântico com heading/descrição/ações/mídia e slots seguros |
|
|
274
|
-
| `ng generate semmet-angular:list-group <nome>` | List Group | Estrutura semântica de lista com itens de ação, estado ativo, badges opcionais e estados desabilitados |
|
|
275
|
-
| `ng generate semmet-angular:table <nome>` | [Table](https://www.w3.org/WAI/ARIA/apg/patterns/table/) | Caption + cabeçalhos escopados, linhas por input e slots seguros de caption/estado vazio |
|
|
276
|
-
|
|
277
|
-
**Formulários e inputs**
|
|
278
|
-
|
|
279
|
-
| Comando | Gera | Comportamento de teclado/foco implementado |
|
|
280
|
-
|---|---|---|
|
|
281
|
-
| `ng generate semmet-angular:form <nome>` | Form | `<form>` nativo com controles rotulados, validação inline e mensagens de status |
|
|
282
|
-
| `ng generate semmet-angular:input <nome>` | Input | `<input>` nativo com label, dica, mensagem de validação e valor com signal |
|
|
283
|
-
| `ng generate semmet-angular:select <nome>` | Select | `<select>` nativo com label, dica, mensagem de validação e valor com signal |
|
|
284
|
-
| `ng generate semmet-angular:input-group <nome>` | Input Group | `<input>` nativo com prefixo/sufixo anunciados por `aria-describedby` e botão de ação opcional |
|
|
285
|
-
| `ng generate semmet-angular:textarea <nome>` | Textarea | `<textarea>` nativo com label, dica, contador, mensagem de validação e valor com signal |
|
|
286
|
-
| `ng generate semmet-angular:checkbox <nome>` | [Checkbox](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/) | Clique/Enter/Espaço alterna |
|
|
287
|
-
| `ng generate semmet-angular:radio-group <nome>` | [Radio Group](https://www.w3.org/WAI/ARIA/apg/patterns/radio/) | Cima/Baixo/Esquerda/Direita/Home/End movem foco e seleção juntos |
|
|
288
|
-
| `ng generate semmet-angular:switch <nome>` | [Switch](https://www.w3.org/WAI/ARIA/apg/patterns/switch/) | `<button>` nativo — Clique/Enter/Espaço alterna |
|
|
289
|
-
| `ng generate semmet-angular:combobox <nome>` | [Combobox](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) | Filtro em tempo real; Cima/Baixo/Home/End/Enter/Escape via `aria-activedescendant` |
|
|
290
|
-
| `ng generate semmet-angular:listbox <nome>` | [Listbox](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/) | Cima/Baixo/Home/End via `aria-activedescendant` |
|
|
291
|
-
| `ng generate semmet-angular:slider <nome>` | [Slider](https://www.w3.org/WAI/ARIA/apg/patterns/slider/) | Setas/PageUp/PageDown/Home/End, além de arraste por ponteiro |
|
|
292
|
-
| `ng generate semmet-angular:spinbutton <nome>` | [Spinbutton](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/) | Cima/Baixo/Home/End, além de botões incrementar/decrementar |
|
|
293
|
-
| `ng generate semmet-angular:meter <nome>` | [Meter](https://www.w3.org/TR/wai-aria-1.2/#meter) | Estático — `<meter>` nativo ligado a um signal |
|
|
294
|
-
| `ng generate semmet-angular:progress-bar <nome>` | [Progress Bar](https://www.w3.org/TR/wai-aria-1.2/#progressbar) | `<progress>` nativo ligado a um signal |
|
|
295
|
-
|
|
296
|
-
**Feedback e mídia**
|
|
297
|
-
|
|
298
|
-
| Comando | Gera | Comportamento de teclado/foco implementado |
|
|
299
|
-
|---|---|---|
|
|
300
|
-
| `ng generate semmet-angular:alert <nome>` | [Alert](https://www.w3.org/WAI/ARIA/apg/patterns/alert/) | Região live assertiva e dispensável |
|
|
301
|
-
| `ng generate semmet-angular:toast <nome>` | Toast / Notification | Auto-dismiss após 5s (limpo via `DestroyRef`); pode ser dispensado antes |
|
|
302
|
-
| `ng generate semmet-angular:skeleton <nome>` | Skeleton Loading | Placeholder de carregamento composível para texto, mídia, círculos, cards e blocos customizados |
|
|
303
|
-
| `ng generate semmet-angular:badge <nome>` | Badge | Rótulo/contador compacto com modo decorativo, rótulo acessível opcional e projeção segura de label |
|
|
304
|
-
| `ng generate semmet-angular:spinner <nome>` | Spinner | Status de carregamento com `role="status"`, rótulo visualmente escondido por padrão e suporte a reduced motion |
|
|
305
|
-
| `ng generate semmet-angular:carousel <nome>` | [Carousel](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/) | Controles Anterior/Próximo; região de slide com `aria-live="polite"` |
|
|
306
|
-
|
|
307
|
-
## Como Cada Componente Gerado É
|
|
308
|
-
|
|
309
|
-
- Standalone (implícito — sem `standalone: true`, alinhado ao padrão atual do Angular).
|
|
310
|
-
- Estado via `signal()`/`computed()`, não campos simples de classe.
|
|
311
|
-
- Templates usam o control flow embutido (`@for`, `@if`), não `*ngFor`/`*ngIf`.
|
|
312
|
-
- Sem sufixo `.component` nos nomes de arquivos ou classes (`accordion.ts`, `export class Accordion`), seguindo a convenção atual de `ng generate component`.
|
|
313
|
-
- Id único por instância (`<nome>-0`, `<nome>-1`, ...) para múltiplas instâncias do mesmo componente nunca colidirem em `id`/`aria-controls`/`aria-labelledby`.
|
|
314
|
-
- Teste unitário (`.spec.ts`) e smoke test e2e Playwright (`.e2e-spec.ts`) gerados para o componente já nascer com uma superfície de teste.
|
|
315
|
-
|
|
316
|
-
## Identidade Visual
|
|
317
|
-
|
|
318
|
-
Todo componente gerado compartilha um visual inspirado em Material Design — superfícies limpas, elevação sutil e escala consistente de raio/movimento — usando sua própria paleta de cores (não as cores do Material, para evitar qualquer risco de cópia visual). Os tokens são CSS custom properties declaradas no `:host` de cada componente (por exemplo, `--semmet-color-primary`, `--semmet-radius-md`, `--semmet-elevation-1`), então você pode usar os defaults como estão ou sobrescrever a família inteira em uma stylesheet global sem tocar nos arquivos gerados.
|
|
319
|
-
|
|
320
|
-
## Opções
|
|
321
|
-
|
|
322
|
-
Todo comando de componente aceita as mesmas três opções de `ng generate component`:
|
|
323
|
-
|
|
324
|
-
- `name` (obrigatório, posicional) — nome do componente.
|
|
325
|
-
- `project` — projeto alvo; por padrão, usa o projeto atual/default.
|
|
326
|
-
- `path` — diretório alvo; por padrão, usa `src/app` do projeto.
|
|
327
|
-
|
|
328
|
-
## Licença
|
|
329
|
-
|
|
330
|
-
MIT
|