@design-system-rte/angular 0.1.1-rc3 → 0.1.1-rc4

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.
Files changed (36) hide show
  1. package/ng-package.json +7 -0
  2. package/package.json +3 -16
  3. package/src/lib/components/button/button.component.html +7 -0
  4. package/src/lib/components/button/button.component.scss +156 -0
  5. package/src/lib/components/button/button.component.spec.ts +23 -0
  6. package/src/lib/components/button/button.component.stories.ts +102 -0
  7. package/src/lib/components/button/button.component.ts +25 -0
  8. package/src/lib/components/grid/col/col.directive.ts +37 -0
  9. package/src/lib/components/grid/grid.directive.stories.ts +149 -0
  10. package/src/lib/components/grid/grid.directive.ts +24 -0
  11. package/src/lib/components/link/link.component.html +5 -0
  12. package/src/lib/components/link/link.component.scss +108 -0
  13. package/src/lib/components/link/link.component.stories.ts +61 -0
  14. package/src/lib/components/link/link.component.ts +19 -0
  15. package/src/lib/components/radio-button/radio-button.component.html +24 -0
  16. package/src/lib/components/radio-button/radio-button.component.scss +140 -0
  17. package/src/lib/components/radio-button/radio-button.component.stories.ts +75 -0
  18. package/src/lib/components/radio-button/radio-button.component.ts +23 -0
  19. package/src/lib/components/radio-button-group/radio-button-group.component.html +45 -0
  20. package/src/lib/components/radio-button-group/radio-button-group.component.scss +82 -0
  21. package/src/lib/components/radio-button-group/radio-button-group.component.stories.ts +124 -0
  22. package/src/lib/components/radio-button-group/radio-button-group.component.ts +30 -0
  23. package/src/public-api.ts +5 -0
  24. package/tsconfig.lib.json +14 -0
  25. package/tsconfig.lib.prod.json +10 -0
  26. package/tsconfig.spec.json +14 -0
  27. package/esm2022/design-system-rte-angular.mjs +0 -5
  28. package/esm2022/lib/lib.component.mjs +0 -19
  29. package/esm2022/lib/lib.service.mjs +0 -14
  30. package/esm2022/public-api.mjs +0 -6
  31. package/fesm2022/design-system-rte-angular.mjs +0 -42
  32. package/fesm2022/design-system-rte-angular.mjs.map +0 -1
  33. package/index.d.ts +0 -5
  34. package/lib/lib.component.d.ts +0 -5
  35. package/lib/lib.service.d.ts +0 -6
  36. package/public-api.d.ts +0 -2
@@ -0,0 +1,7 @@
1
+ {
2
+ "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3
+ "dest": "../../dist/lib",
4
+ "lib": {
5
+ "entryFile": "src/public-api.ts"
6
+ }
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design-system-rte/angular",
3
- "version": "0.1.1-rc3",
3
+ "version": "0.1.1-rc4",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^17.3.0",
6
6
  "@angular/core": "^17.3.0"
@@ -8,18 +8,5 @@
8
8
  "dependencies": {
9
9
  "tslib": "^2.3.0"
10
10
  },
11
- "sideEffects": false,
12
- "module": "fesm2022/design-system-rte-angular.mjs",
13
- "typings": "index.d.ts",
14
- "exports": {
15
- "./package.json": {
16
- "default": "./package.json"
17
- },
18
- ".": {
19
- "types": "./index.d.ts",
20
- "esm2022": "./esm2022/design-system-rte-angular.mjs",
21
- "esm": "./esm2022/design-system-rte-angular.mjs",
22
- "default": "./fesm2022/design-system-rte-angular.mjs"
23
- }
24
- }
25
- }
11
+ "sideEffects": false
12
+ }
@@ -0,0 +1,7 @@
1
+ <button
2
+ class="rte-button {{ variant() }} size-{{ size() }}"
3
+ [disabled]="disabled()"
4
+ (click)="onClick($event)"
5
+ >
6
+ <span class="rte-button-label">{{ label() }}</span>
7
+ </button>
@@ -0,0 +1,156 @@
1
+ @use '@design-system-rte/core/tokens/main.scss' as *;
2
+
3
+ .rte-button {
4
+ align-items: center;
5
+ cursor: pointer;
6
+ display: inline-flex;
7
+ flex-shrink: 0;
8
+ justify-content: center;
9
+
10
+ &:focus-visible {
11
+ outline: 1px solid var(--border-brand-focused);
12
+ outline-offset: 4px;
13
+ }
14
+
15
+ &.size-s {
16
+ @include typography-button-s;
17
+ height: 24px;
18
+ border-radius: $radius-s;
19
+ padding: $positive-spacing_050 $positive-spacing_100;
20
+
21
+ .rte-button-label {
22
+ margin: 0 $positive-spacing_050;
23
+ }
24
+ }
25
+
26
+ &.size-m {
27
+ @include typography-button-m;
28
+ height: 32px;
29
+ border-radius: $radius-s;
30
+ padding: $positive-spacing_050 $positive-spacing_150;
31
+
32
+ .rte-button-label {
33
+ margin: 0 $positive-spacing_075;
34
+ }
35
+ }
36
+
37
+ &.size-l {
38
+ @include typography-button-l;
39
+ height: 40px;
40
+ border-radius: $radius-m;
41
+ padding: $positive-spacing_050 $positive-spacing_200;
42
+
43
+ .rte-button-label {
44
+ margin: 0 $positive-spacing_100;
45
+ }
46
+ }
47
+
48
+ &.filled {
49
+ border: var(--border-brand-default);
50
+ color: var(--content-primary-inverse);
51
+ background: var(--background-brand-default);
52
+
53
+ &:hover {
54
+ background: var(--background-brand-hover);
55
+ border: var(--background-brand-hover);
56
+ }
57
+
58
+ &:active {
59
+ background: var(--background-brand-pressed);
60
+ }
61
+
62
+ &:disabled {
63
+ background: var(--background-disabled);
64
+ border: solid 1px var(--border-disabled);
65
+ color: var(--content-disabled);
66
+ box-shadow: none;
67
+ cursor: default;
68
+ }
69
+ };
70
+
71
+ &.outlined {
72
+ background: var(--background-default);
73
+ border: solid 1px var(--border-brand-default);
74
+ color: var(--content-brand-default);
75
+
76
+ &:hover {
77
+ background: var(--background-brand-inverse-hover);
78
+ border: solid 1px var(--border-brand-default);
79
+ }
80
+
81
+ &:active {
82
+ border: var(--background-brand-inverse);
83
+ background: var(--background-brand-inverse-pressed);
84
+ }
85
+
86
+ &:disabled {
87
+ background: var(--background-disabled);
88
+ border: solid 1px var(--border-disabled);
89
+ color: var(--content-disabled);
90
+ cursor: default;
91
+ }
92
+ };
93
+
94
+ &.text {
95
+ background: transparent;
96
+ border: none;
97
+ color: var(--content-brand-default);
98
+
99
+ &:hover {
100
+ background: var(--background-brand-inverse-hover);
101
+ }
102
+
103
+ &:active {
104
+ background: var(--background-brand-inverse-pressed);
105
+ }
106
+
107
+ &:disabled {
108
+ background: var(--background-disabled);
109
+ color: var(--content-disabled);
110
+ cursor: default;
111
+ }
112
+ };
113
+
114
+ &.transparent {
115
+ background: transparent;
116
+ border: none;
117
+ color: var(--content-brand-default);
118
+
119
+ &:hover {
120
+ color: var(--content-brand-hover);
121
+ }
122
+
123
+ &:active {
124
+ color: var(--content-brand-pressed);
125
+ }
126
+
127
+ &:disabled {
128
+ color: var(--content-disabled);
129
+ box-shadow: none;
130
+ cursor: default;
131
+ }
132
+ };
133
+
134
+ &.danger {
135
+ background: var(--background-danger-default);
136
+ border: none;
137
+ color: var(--content-primary-inverse);
138
+ border-radius: $radius-m;
139
+
140
+ &:hover {
141
+ background: var(--background-danger-hover);
142
+ }
143
+
144
+ &:active {
145
+ background: var(--background-danger-pressed);
146
+ }
147
+
148
+ &:disabled {
149
+ background: var(--background-disabled);
150
+ border: var(--border-disabled);
151
+ color: var(--content-disabled);
152
+ box-shadow: none;
153
+ cursor: default;
154
+ }
155
+ }
156
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ButtonComponent } from './button.component';
4
+
5
+ describe('ButtonComponent', () => {
6
+ let component: ButtonComponent;
7
+ let fixture: ComponentFixture<ButtonComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [ButtonComponent]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(ButtonComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,102 @@
1
+ import type { Meta, StoryObj } from '@storybook/angular';
2
+ import { fn, userEvent, within, expect } from '@storybook/test';
3
+ import { ENTER_KEY, SPACE_KEY, TAB_KEY } from '@design-system-rte/core/constants/keyboard.constants';
4
+
5
+ import { ButtonComponent } from './button.component';
6
+
7
+
8
+ const meta: Meta<ButtonComponent>= {
9
+ title: 'Button',
10
+ component: ButtonComponent,
11
+ tags: ['autodocs'],
12
+ argTypes: {
13
+ variant: {
14
+ control: 'select',
15
+ options: ['filled', 'outlined', 'text', 'transparent', 'danger'],
16
+ },
17
+ size: {
18
+ control: 'select',
19
+ options: ['s', 'm', 'l'],
20
+ },
21
+ disabled: {
22
+ control: 'boolean',
23
+ },
24
+ },
25
+ args: { click: fn() },
26
+ };
27
+
28
+ export default meta;
29
+ type Story = StoryObj<ButtonComponent>;
30
+
31
+ const mockFn = fn();
32
+
33
+ export const Default: Story = {
34
+
35
+ args: {
36
+ variant: 'filled',
37
+ label: 'Button',
38
+ click: mockFn,
39
+ },
40
+ play: async ({ canvasElement }) => {
41
+ const canvas = within(canvasElement);
42
+ const button = canvas.getByRole('button');
43
+ await userEvent.click(button);
44
+ expect(mockFn).toHaveBeenCalled();
45
+ button.blur();
46
+ },
47
+ };
48
+
49
+ export const Sizing: Story = {
50
+
51
+ render: (args) => ({
52
+ props: args,
53
+ template: `
54
+ <div style="display: flex; gap: 8px;">
55
+ <rte-button
56
+ size="s"
57
+ label="Small"
58
+ variant="filled"
59
+ data-testid="small-button"
60
+ />
61
+ <rte-button
62
+ size="m"
63
+ label="Medium"
64
+ variant="filled"
65
+ data-testid="medium-button"
66
+ />
67
+ <rte-button
68
+ size="l"
69
+ label="Large"
70
+ variant="filled"
71
+ data-testid="large-button"
72
+ />
73
+ </div>
74
+ `,
75
+ }),
76
+ play: async ({ canvasElement }) => {
77
+ const canvas = within(canvasElement);
78
+ const smallButton = canvas.getByTestId('small-button').getElementsByTagName('button')[0];
79
+ const mediumButton = canvas.getByTestId('medium-button').getElementsByTagName('button')[0];
80
+ const largeButton = canvas.getByTestId('large-button').getElementsByTagName('button')[0];
81
+
82
+ expect(smallButton.clientHeight).toBe(24);
83
+ expect(mediumButton.clientHeight).toBe(32);
84
+ expect(largeButton.clientHeight).toBe(40);
85
+ },
86
+ };
87
+
88
+ export const KeyboardInteraction: Story = {
89
+ args: {
90
+ ...Default.args,
91
+ },
92
+ play: async ({ canvasElement }) => {
93
+ const canvas = within(canvasElement);
94
+ const button = canvas.getByRole('button');
95
+ await userEvent.keyboard(`{Tab}`);
96
+ expect(button).toHaveFocus();
97
+ await userEvent.keyboard(`{Enter}}`);
98
+ await userEvent.keyboard(`{ }`);
99
+ expect(mockFn).toHaveBeenCalledTimes(2);
100
+ button.blur();
101
+ },
102
+ };
@@ -0,0 +1,25 @@
1
+ import { Component, input, output } from '@angular/core';
2
+ import { ButtonSize, ButtonVariant } from '@design-system-rte/core/components/button/button.interface';
3
+
4
+ @Component({
5
+ selector: 'rte-button',
6
+ standalone: true,
7
+ imports: [],
8
+ templateUrl: './button.component.html',
9
+ styleUrl: './button.component.scss'
10
+ })
11
+ export class ButtonComponent {
12
+
13
+ label = input('');
14
+ variant = input<ButtonVariant>('filled');
15
+ size = input<ButtonSize>('m');
16
+ disabled = input(false);
17
+
18
+ click = output<void>();
19
+
20
+ onClick(event: MouseEvent | KeyboardEvent): void {
21
+ event.stopPropagation();
22
+ this.click.emit();
23
+ }
24
+
25
+ }
@@ -0,0 +1,37 @@
1
+ import { Directive, HostBinding, input } from '@angular/core';
2
+
3
+ @Directive({
4
+ selector: '[dsCol]',
5
+ standalone: true
6
+ })
7
+ export class ColDirective {
8
+
9
+ xxs = input<number>()
10
+ xs = input<number>()
11
+ s = input<number>()
12
+ m = input<number>()
13
+ l = input<number>()
14
+ xl = input<number>()
15
+
16
+ @HostBinding ("class")
17
+ get colClasses(): string {
18
+ return [
19
+ 'col',
20
+ this.generateColumnClass('col-xxs', this.xxs()),
21
+ this.generateColumnClass('col-xs', this.xs()),
22
+ this.generateColumnClass('col-s', this.s()),
23
+ this.generateColumnClass('col-m', this.m()),
24
+ this.generateColumnClass('col-l', this.l()),
25
+ this.generateColumnClass('col-xl', this.xl()),
26
+ ]
27
+ .filter(Boolean)
28
+ .join(' ');
29
+ }
30
+
31
+ constructor() { }
32
+
33
+ private generateColumnClass(prefix: string, size?: number): string {
34
+ return size ? `${prefix}-${size}` : '';
35
+ }
36
+
37
+ }
@@ -0,0 +1,149 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { GridType } from '@design-system-rte/core/components/grid/grid.interface';
3
+ import { componentWrapperDecorator, moduleMetadata, type Meta, type StoryObj } from '@storybook/angular';
4
+ import { GridDirective } from './grid.directive';
5
+ import { ColDirective } from './col/col.directive';
6
+
7
+ type GridStoriesArgs = GridDirective;
8
+
9
+ const COLUMN_NUMBER = 12;
10
+
11
+ const meta: Meta<GridStoriesArgs>= {
12
+ title: 'Grid',
13
+ component: GridDirective,
14
+ tags: ['autodocs'],
15
+ argTypes: {
16
+ gridType: {
17
+ control: 'select',
18
+ defaultValue: (args: GridStoriesArgs) => args.gridType,
19
+ options: ['fluid', 'fixed-narrow', 'fixed-wide'],
20
+ description: 'The type of grid to use',
21
+ },
22
+ },
23
+ decorators: [
24
+ moduleMetadata({
25
+ imports: [CommonModule, ColDirective],
26
+ }),
27
+ componentWrapperDecorator((story) => `<div class="sb-css-grid-container">${story}</div>`)
28
+ ],
29
+ };
30
+
31
+ export default meta;
32
+ type Story = StoryObj<GridStoriesArgs>;
33
+
34
+ const defaultTemplate = (gridType: GridType) => {
35
+ return `
36
+ <div rte-grid
37
+ [gridType]="'${gridType}'"
38
+ data-testid="grid"
39
+ >
40
+ <ng-container *ngFor="let item of items">
41
+ <div
42
+ dsCol
43
+ ></div>
44
+ </ng-container>
45
+ </div>
46
+ `;
47
+ };
48
+
49
+ export const Fluid: Story = {
50
+ args: {
51
+ gridType: 'fluid',
52
+ },
53
+ render: (args) => ({
54
+ props: {
55
+ ...args,
56
+ items: Array.from(Array(COLUMN_NUMBER)).map((_,i)=>i+1)
57
+ },
58
+ template: defaultTemplate(args.gridType),
59
+ }),
60
+ };
61
+
62
+ export const FixedWide: Story = {
63
+ args: {
64
+ gridType: 'fixed-wide',
65
+ },
66
+ render: (args) => ({
67
+ props: {
68
+ ...args,
69
+ items: Array.from(Array(COLUMN_NUMBER)).map((_,i)=>i+1)
70
+ },
71
+ template: defaultTemplate(args.gridType),
72
+ }),
73
+ };
74
+
75
+ export const FixedNarrow: Story = {
76
+ args: {
77
+ gridType: 'fixed-narrow',
78
+ },
79
+ render: (args) => ({
80
+ props: {
81
+ ...args,
82
+ items: Array.from(Array(COLUMN_NUMBER)).map((_,i)=>i+1)
83
+ },
84
+ template: defaultTemplate(args.gridType),
85
+ }),
86
+ };
87
+
88
+ export const ResponsiveColumns: Story = {
89
+ args: {
90
+ gridType: 'fluid',
91
+ },
92
+ render: (args) => ({
93
+ template:`
94
+ <div rte-grid
95
+ [gridType]="'${args.gridType}'"
96
+ data-testid="grid"
97
+ >
98
+ <div dsCol [xxs]=1 [xs]=1 [s]=3 [m]=4 [l]=4 [xl]=12>
99
+ <div>
100
+ <p>xxs : Span 1 de 2</p>
101
+ <p>xs : Span 1 de 6</p>
102
+ <p>s : Span 3 de 6</p>
103
+ </div>
104
+ <div>
105
+ <p>m : Span 4 de 12</p>
106
+ <p>l : Span 4 de 12</p>
107
+ <p>xl : Span 12 de 12</p>
108
+ </div>
109
+ </div>
110
+ <div dsCol [xxs]=1 [xs]=3 [s]=3 [m]=4 [l]=8 [xl]=12>
111
+ <div>
112
+ <p>xxs : Span 1 de 2</p>
113
+ <p>xs : Span 3 de 6</p>
114
+ <p>s : Span 3 de 6</p>
115
+ </div>
116
+ <div>
117
+ <p>m : Span 4 de 12</p>
118
+ <p>l : Span 8 de 12</p>
119
+ <p>xl : Span 12 de 12</p>
120
+ </div>
121
+ </div>
122
+ <div dsCol [xxs]=2 [xs]=2 [s]=3 [m]=4 [l]=10 [xl]=12>
123
+ <div>
124
+ <p>xxs : Span 2 de 2</p>
125
+ <p>xs : Span 2 de 6</p>
126
+ <p>s : Span 3 de 6</p>
127
+ </div>
128
+ <div>
129
+ <p>m : Span 4 de 12</p>
130
+ <p>l : Span 10 de 12</p>
131
+ <p>xl : Span 12 de 12</p>
132
+ </div>
133
+ </div>
134
+ <div dsCol [xxs]=2 [xs]=6 [s]=6 [m]=4 [l]=12 [xl]=12>
135
+ <div>
136
+ <p>xxs : Span 2 de 2</p>
137
+ <p>xs : Span 6 de 6</p>
138
+ <p>s : Span 6 de 6</p>
139
+ </div>
140
+ <div>
141
+ <p>m : Span 4 de 12</p>
142
+ <p>l : Span 12 de 12</p>
143
+ <p>xl : Span 12 de 12</p>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ `
148
+ }),
149
+ };
@@ -0,0 +1,24 @@
1
+ import { Directive, HostBinding, input } from '@angular/core';
2
+ import { GridType } from '@design-system-rte/core/components/grid/grid.interface';
3
+
4
+ @Directive({
5
+ selector: '[rte-grid]',
6
+ standalone: true
7
+ })
8
+ export class GridDirective {
9
+
10
+ gridType = input<GridType>('fluid');
11
+
12
+ @HostBinding("class")
13
+ get hostClasses(): string {
14
+ return 'grid'
15
+ }
16
+
17
+ @HostBinding("attr.data-gridtype")
18
+ get hostDataClasses(): string {
19
+ const variation = this.gridType();
20
+ return `${variation}`;
21
+ }
22
+ constructor() { }
23
+
24
+ }
@@ -0,0 +1,5 @@
1
+ <a class="rte-link" [ngClass]="{'subtle': subtle()}" href="{{ href() }}" role="link">
2
+ <span class="rte-link-label">
3
+ {{ label() }}
4
+ </span>
5
+ </a>
@@ -0,0 +1,108 @@
1
+ @use '@design-system-rte/core/tokens/main.scss' as *;
2
+
3
+ .rte-link {
4
+
5
+ @include typography-link-m;
6
+ align-items: center;
7
+ cursor: pointer;
8
+ display: inline-flex;
9
+ justify-content: center;
10
+
11
+ &:visited {
12
+
13
+ color: var(--content-link-visited);
14
+ text-decoration: underline;
15
+
16
+ &:hover {
17
+ color: var(--content-link-visited-hover);
18
+ text-decoration: none;
19
+ }
20
+
21
+ &:active {
22
+ color: var(--content-link-visited-press);
23
+ text-decoration: underline;
24
+ }
25
+
26
+ &:focus-visible {
27
+ color: var(--content-link-visited);
28
+ text-decoration: underline;
29
+ outline: 1px solid var(--border-brand-focused);
30
+ outline-offset: $radius-s;
31
+ border-radius: $radius-s;
32
+ }
33
+ }
34
+
35
+ &:not(:visited) {
36
+
37
+ color: var(--content-link-default);
38
+
39
+ &:hover {
40
+ color: var(--content-link-hover);
41
+ text-decoration: none;
42
+ }
43
+
44
+ &:active {
45
+ color: var(--content-link-press);
46
+ text-decoration: underline;
47
+ }
48
+
49
+ &:focus-visible {
50
+ color: var(--content-link-default);
51
+ text-decoration: underline;
52
+ outline: 1px solid var(--border-brand-focused);
53
+ outline-offset: $radius-s;
54
+ border-radius: $radius-s;
55
+ }
56
+ }
57
+
58
+ &.subtle{
59
+
60
+ &:visited {
61
+
62
+ color: var(--content-primary);
63
+ text-decoration: none;
64
+
65
+ &:hover {
66
+ color: var(--content-link-secondary);
67
+ text-decoration: underline;
68
+ }
69
+
70
+ &:active {
71
+ color: var(--content-link-primary);
72
+ text-decoration: none;
73
+ }
74
+
75
+ &:focus-visible {
76
+ color: var(--content-link-primary);
77
+ text-decoration: none;
78
+ outline: 1px solid var(--border-brand-focused);
79
+ outline-offset: $radius-s;
80
+ border-radius: $radius-s;
81
+ }
82
+ }
83
+
84
+ &:not(:visited) {
85
+
86
+ color: var(--content-primary);
87
+ text-decoration: none;
88
+
89
+ &:hover {
90
+ color: var(--content-secondary);
91
+ text-decoration: underline;
92
+ }
93
+
94
+ &:active {
95
+ color: var(--content-primary);
96
+ text-decoration: none;
97
+ }
98
+
99
+ &:focus-visible {
100
+ color: var(--content-primary);
101
+ text-decoration: none;
102
+ outline: 1px solid var(--border-brand-focused);
103
+ outline-offset: $radius-s;
104
+ border-radius: $radius-s;
105
+ }
106
+ }
107
+ }
108
+ }