@origostudio/origo-design 0.0.46 → 0.0.48
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/CHANGELOG.md +5 -2
- package/bmad-resolved-config.json +226 -0
- package/bmad_prd_workflow.json +17 -0
- package/config_output.json +226 -0
- package/dist/packages/angular-renderer/CHANGELOG.md +15 -0
- package/dist/packages/angular-renderer/package.json +3 -3
- package/dist/packages/angular-renderer/src/components/primitives/button/button.component.d.ts +26 -0
- package/dist/packages/angular-renderer/src/components/primitives/button/button.component.js +29 -3
- package/dist/packages/angular-renderer/src/components/primitives/button/button.component.js.map +1 -1
- package/dist/packages/angular-renderer/src/components/primitives/button-group/button-group.component.d.ts +23 -0
- package/dist/packages/angular-renderer/src/components/primitives/button-group/button-group.component.js +73 -0
- package/dist/packages/angular-renderer/src/components/primitives/button-group/button-group.component.js.map +1 -0
- package/dist/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.d.ts +41 -0
- package/dist/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.js +87 -0
- package/dist/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.js.map +1 -0
- package/dist/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.d.ts +44 -0
- package/dist/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.js +93 -0
- package/dist/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.js.map +1 -0
- package/dist/packages/angular-renderer/src/index.d.ts +3 -0
- package/dist/packages/angular-renderer/src/index.js +3 -0
- package/dist/packages/angular-renderer/src/index.js.map +1 -1
- package/dist/packages/angular-renderer/src/lib/primitives.provider.js +6 -0
- package/dist/packages/angular-renderer/src/lib/primitives.provider.js.map +1 -1
- package/dist/packages/cli/CHANGELOG.md +8 -0
- package/dist/packages/cli/package.json +2 -2
- package/dist/packages/cli/package.json.bak +2 -2
- package/dist/packages/core/CHANGELOG.md +8 -0
- package/dist/packages/core/package.json +1 -1
- package/dist/packages/core/package.json.bak +1 -1
- package/dist/packages/design-tokens/CHANGELOG.md +8 -0
- package/dist/packages/design-tokens/package.json +1 -1
- package/dist/packages/playground/browser/{chunk-NvAbwArG.js → chunk-4MD_GCgA.js} +1 -1
- package/dist/packages/playground/browser/{chunk-D8xCSUn8.js → chunk-B8F7hD0p.js} +1 -1
- package/dist/packages/playground/browser/{chunk-KjK48aB_.js → chunk-BQfPUVzZ.js} +1 -1
- package/dist/packages/playground/browser/{chunk-Vi7LKue9.js → chunk-COjGAm8R.js} +1 -1
- package/dist/packages/playground/browser/{chunk-hQe37O_T.js → chunk-CQQHYSEg.js} +1 -1
- package/dist/packages/playground/browser/{chunk-M-QQ6mOa.js → chunk-CdNbNqNV.js} +1 -1
- package/dist/packages/playground/browser/{chunk-Ds2pJNq1.js → chunk-ChP61sze.js} +1 -1
- package/dist/packages/playground/browser/{chunk-D8NS9RS7.js → chunk-ClmlG9ZJ.js} +1 -1
- package/dist/packages/playground/browser/{chunk-DOh0X2ps.js → chunk-CtaS4wCa.js} +1 -1
- package/dist/packages/playground/browser/{chunk-CoC5zYQK.js → chunk-DRRJiw3L.js} +1 -1
- package/dist/packages/playground/browser/{chunk-Bnpjwr-7.js → chunk-DvVvDpcg.js} +1 -1
- package/dist/packages/playground/browser/{chunk-pi5vOCVu.js → chunk-DyfobgsU.js} +1 -1
- package/dist/packages/playground/browser/{chunk-DQXI3hQ7.js → chunk-PT1eAqp3.js} +1 -1
- package/dist/packages/playground/browser/{chunk-iW-WwSbU.js → chunk-cI3o8oNy.js} +1 -1
- package/dist/packages/playground/browser/{chunk-7aXhMYht.js → chunk-zkDXJCJr.js} +1 -1
- package/dist/packages/playground/browser/index.html +2 -2
- package/dist/packages/playground/browser/main-DTJJSNK4.js +733 -0
- package/package.json +1 -1
- package/packages/angular-renderer/CHANGELOG.md +15 -0
- package/packages/angular-renderer/package.json +3 -3
- package/packages/angular-renderer/src/components/primitives/button/button.component.html +16 -1
- package/packages/angular-renderer/src/components/primitives/button/button.component.ts +41 -3
- package/packages/angular-renderer/src/components/primitives/button-group/button-group.component.html +8 -0
- package/packages/angular-renderer/src/components/primitives/button-group/button-group.component.scss +18 -0
- package/packages/angular-renderer/src/components/primitives/button-group/button-group.component.ts +71 -0
- package/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.html +18 -0
- package/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.scss +47 -0
- package/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.ts +94 -0
- package/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.html +18 -0
- package/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.scss +34 -0
- package/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.ts +102 -0
- package/packages/angular-renderer/src/index.ts +3 -0
- package/packages/angular-renderer/src/lib/primitives.provider.ts +6 -0
- package/packages/cli/CHANGELOG.md +8 -0
- package/packages/cli/package.json +2 -2
- package/packages/core/CHANGELOG.md +8 -0
- package/packages/core/package.json +1 -1
- package/packages/design-tokens/CHANGELOG.md +8 -0
- package/packages/design-tokens/package.json +1 -1
- package/packages/devtools/CHANGELOG.md +8 -0
- package/packages/devtools/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/packages/devtools/package.json +3 -3
- package/packages/playground/CHANGELOG.md +8 -0
- package/packages/playground/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/packages/playground/package.json +3 -3
- package/dist/packages/playground/browser/main-HYTU6AQS.js +0 -731
package/package.json
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## 0.0.48 (2026-10-07)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- add core primitives, buttons, and review artifacts for Angular renderer ([f0cbc46](https://github.com/OrigoStudio/origo-design/commit/f0cbc46))
|
|
6
|
+
- add core button and action primitive components to angular-renderer ([2f7d926](https://github.com/OrigoStudio/origo-design/commit/2f7d926))
|
|
7
|
+
|
|
8
|
+
### ❤️ Thank You
|
|
9
|
+
|
|
10
|
+
- Hardik Patel @hardikpatelse
|
|
11
|
+
|
|
12
|
+
## 0.0.47 (2026-10-07)
|
|
13
|
+
|
|
14
|
+
This was a version bump only for angular-renderer to align it with other projects, there were no code changes.
|
|
15
|
+
|
|
1
16
|
## 0.0.46 (2026-10-02)
|
|
2
17
|
|
|
3
18
|
This was a version bump only for angular-renderer to align it with other projects, there were no code changes.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@origostudio/angular-renderer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.48",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@origostudio/core": "0.0.
|
|
10
|
-
"@origostudio/design-tokens": "0.0.
|
|
9
|
+
"@origostudio/core": "0.0.48",
|
|
10
|
+
"@origostudio/design-tokens": "0.0.48",
|
|
11
11
|
"tslib": "^2.3.0",
|
|
12
12
|
"@analogjs/vite-plugin-angular": "^2.7.1",
|
|
13
13
|
"zone.js": "^0.16.3",
|
|
@@ -3,7 +3,22 @@
|
|
|
3
3
|
[disabled]="computedDisabled()"
|
|
4
4
|
[attr.aria-label]="computedAriaLabel()"
|
|
5
5
|
[attr.aria-describedby]="computedAriaDescribedBy()"
|
|
6
|
+
[attr.aria-busy]="computedLoading() ? 'true' : null"
|
|
6
7
|
(click)="onClick()"
|
|
7
8
|
>
|
|
8
|
-
|
|
9
|
+
@if (computedLoading()) {
|
|
10
|
+
<span class="origo-spinner"></span>
|
|
11
|
+
}
|
|
12
|
+
@if (computedIcon() && computedIconPosition() !== 'right') {
|
|
13
|
+
<span [class]="'origo-icon origo-icon-' + computedIcon()"></span>
|
|
14
|
+
}
|
|
15
|
+
<span class="origo-button-label">{{ computedLabel() }}</span>
|
|
16
|
+
@if (computedBadge()) {
|
|
17
|
+
<span [class]="'origo-badge origo-badge-' + computedBadgeSeverity()">{{
|
|
18
|
+
computedBadge()
|
|
19
|
+
}}</span>
|
|
20
|
+
}
|
|
21
|
+
@if (computedIcon() && computedIconPosition() === 'right') {
|
|
22
|
+
<span [class]="'origo-icon origo-icon-' + computedIcon()"></span>
|
|
23
|
+
}
|
|
9
24
|
</button>
|
|
@@ -17,6 +17,16 @@ export interface ButtonProps {
|
|
|
17
17
|
type?: 'button' | 'submit' | 'reset';
|
|
18
18
|
'aria-label'?: string;
|
|
19
19
|
'aria-describedby'?: string;
|
|
20
|
+
loading?: boolean;
|
|
21
|
+
severity?: string;
|
|
22
|
+
variant?: string;
|
|
23
|
+
icon?: string;
|
|
24
|
+
iconPosition?: string;
|
|
25
|
+
badge?: string;
|
|
26
|
+
badgeSeverity?: string;
|
|
27
|
+
permissions?: any;
|
|
28
|
+
rules?: any;
|
|
29
|
+
metadata?: any;
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
@Component({
|
|
@@ -27,7 +37,7 @@ export interface ButtonProps {
|
|
|
27
37
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
28
38
|
encapsulation: ViewEncapsulation.ShadowDom,
|
|
29
39
|
host: {
|
|
30
|
-
'[class
|
|
40
|
+
'[class]': 'computedHostClasses()',
|
|
31
41
|
'[attr.data-testid]': 'contract().id ?? ""',
|
|
32
42
|
},
|
|
33
43
|
})
|
|
@@ -36,13 +46,41 @@ export class ButtonComponent implements OrigoAdapter<ButtonProps> {
|
|
|
36
46
|
label: 'string',
|
|
37
47
|
disabled: 'boolean',
|
|
38
48
|
type: 'string',
|
|
49
|
+
loading: 'boolean',
|
|
50
|
+
severity: 'string',
|
|
51
|
+
variant: 'string',
|
|
52
|
+
icon: 'string',
|
|
53
|
+
iconPosition: 'string',
|
|
54
|
+
badge: 'string',
|
|
55
|
+
badgeSeverity: 'string',
|
|
56
|
+
permissions: 'object',
|
|
57
|
+
rules: 'object',
|
|
58
|
+
metadata: 'object',
|
|
39
59
|
};
|
|
40
60
|
static readonly strictContract = false;
|
|
41
61
|
|
|
42
62
|
contract = input.required<InteractionContract<ButtonProps>>();
|
|
43
63
|
|
|
44
64
|
computedLabel = computed(() => this.contract().props?.label ?? 'Button');
|
|
45
|
-
|
|
65
|
+
computedLoading = computed(() => !!this.contract().props?.loading);
|
|
66
|
+
computedDisabled = computed(() => {
|
|
67
|
+
const props = this.contract().props;
|
|
68
|
+
const rulesDisable = props?.rules?.disable === true || props?.permissions?.allow === false;
|
|
69
|
+
return !!props?.disabled || this.computedLoading() || rulesDisable;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
computedIcon = computed(() => this.contract().props?.icon);
|
|
73
|
+
computedIconPosition = computed(() => this.contract().props?.iconPosition ?? 'left');
|
|
74
|
+
computedBadge = computed(() => this.contract().props?.badge);
|
|
75
|
+
computedBadgeSeverity = computed(() => this.contract().props?.badgeSeverity ?? 'info');
|
|
76
|
+
|
|
77
|
+
computedHostClasses = computed(() => {
|
|
78
|
+
const s = this.contract().props?.severity;
|
|
79
|
+
const v = this.contract().props?.variant;
|
|
80
|
+
return ['origo-button', s ? `origo-severity-${s}` : '', v ? `origo-variant-${v}` : '']
|
|
81
|
+
.filter(Boolean)
|
|
82
|
+
.join(' ');
|
|
83
|
+
});
|
|
46
84
|
computedType = computed(() => {
|
|
47
85
|
const type = this.contract().props?.type;
|
|
48
86
|
return type === 'button' || type === 'submit' || type === 'reset' ? type : 'button';
|
|
@@ -65,7 +103,7 @@ export class ButtonComponent implements OrigoAdapter<ButtonProps> {
|
|
|
65
103
|
private experienceAdapter = inject(WebExperienceAdapterService);
|
|
66
104
|
|
|
67
105
|
onClick() {
|
|
68
|
-
if (this.computedDisabled()) return;
|
|
106
|
+
if (this.computedDisabled() || this.computedLoading()) return;
|
|
69
107
|
|
|
70
108
|
const id = this.contract().id;
|
|
71
109
|
if (!id) return;
|
package/packages/angular-renderer/src/components/primitives/button-group/button-group.component.scss
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
}
|
|
4
|
+
.origo-button-group-content {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: row;
|
|
7
|
+
gap: var(--origo-spacing-container-padding);
|
|
8
|
+
}
|
|
9
|
+
:host(.origo-orientation-column) .origo-button-group-content {
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
}
|
|
12
|
+
:host(.origo-attached) .origo-button-group-content {
|
|
13
|
+
gap: 0;
|
|
14
|
+
}
|
|
15
|
+
/* Note: attached styling across shadow DOM requires passing CSS custom properties to children, which relies on children consuming them. */
|
|
16
|
+
:host(.origo-attached) {
|
|
17
|
+
--origo-button-radius: 0;
|
|
18
|
+
}
|
package/packages/angular-renderer/src/components/primitives/button-group/button-group.component.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
input,
|
|
4
|
+
ChangeDetectionStrategy,
|
|
5
|
+
computed,
|
|
6
|
+
ViewEncapsulation,
|
|
7
|
+
} from '@angular/core';
|
|
8
|
+
import { InteractionContract } from '@origostudio/core';
|
|
9
|
+
import { OrigoAdapter } from '../../../adapters/web/adapter';
|
|
10
|
+
|
|
11
|
+
export interface ButtonGroupProps {
|
|
12
|
+
orientation?: 'row' | 'column';
|
|
13
|
+
attached?: boolean;
|
|
14
|
+
size?: 'small' | 'medium' | 'large';
|
|
15
|
+
'aria-label'?: string;
|
|
16
|
+
'aria-describedby'?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@Component({
|
|
20
|
+
selector: 'origo-button-group',
|
|
21
|
+
standalone: true,
|
|
22
|
+
templateUrl: './button-group.component.html',
|
|
23
|
+
styleUrls: ['./button-group.component.scss'],
|
|
24
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
25
|
+
encapsulation: ViewEncapsulation.ShadowDom,
|
|
26
|
+
host: {
|
|
27
|
+
'[class]': 'computedHostClasses()',
|
|
28
|
+
'[attr.data-testid]': 'contract().id ?? ""',
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
export class ButtonGroupComponent implements OrigoAdapter<ButtonGroupProps> {
|
|
32
|
+
static readonly contractSchema = {
|
|
33
|
+
orientation: 'string',
|
|
34
|
+
attached: 'boolean',
|
|
35
|
+
size: 'string',
|
|
36
|
+
'aria-label': 'string',
|
|
37
|
+
'aria-describedby': 'string',
|
|
38
|
+
};
|
|
39
|
+
static readonly strictContract = false;
|
|
40
|
+
|
|
41
|
+
contract = input.required<InteractionContract<ButtonGroupProps>>();
|
|
42
|
+
|
|
43
|
+
computedHostClasses = computed(() => {
|
|
44
|
+
const rawO = this.contract().props?.orientation;
|
|
45
|
+
const o = rawO === 'column' ? 'column' : 'row';
|
|
46
|
+
const attached = this.contract().props?.attached;
|
|
47
|
+
const rawSize = this.contract().props?.size;
|
|
48
|
+
const size = ['small', 'medium', 'large'].includes(rawSize as string) ? rawSize : undefined;
|
|
49
|
+
return [
|
|
50
|
+
'origo-button-group',
|
|
51
|
+
`origo-orientation-${o}`,
|
|
52
|
+
attached ? 'origo-attached' : '',
|
|
53
|
+
size ? `origo-size-${size}` : '',
|
|
54
|
+
]
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
.join(' ');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
computedAriaLabel = computed(() => {
|
|
60
|
+
const label = this.contract().props?.['aria-label'];
|
|
61
|
+
return label !== undefined && label !== null && String(label).trim() !== ''
|
|
62
|
+
? String(label)
|
|
63
|
+
: undefined;
|
|
64
|
+
});
|
|
65
|
+
computedAriaDescribedBy = computed(() => {
|
|
66
|
+
const desc = this.contract().props?.['aria-describedby'];
|
|
67
|
+
return desc !== undefined && desc !== null && String(desc).trim() !== ''
|
|
68
|
+
? String(desc)
|
|
69
|
+
: undefined;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<button
|
|
2
|
+
type="button"
|
|
3
|
+
[disabled]="computedDisabled()"
|
|
4
|
+
[attr.aria-label]="computedAriaLabel()"
|
|
5
|
+
[attr.aria-describedby]="computedAriaDescribedBy()"
|
|
6
|
+
(click)="onClick()"
|
|
7
|
+
>
|
|
8
|
+
@if (computedLoading()) {
|
|
9
|
+
<span class="origo-spinner"></span>
|
|
10
|
+
} @else {
|
|
11
|
+
@if (computedIcon()) {
|
|
12
|
+
<span [class]="'origo-icon origo-icon-' + computedIcon()"></span>
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
@if (computedLabel()) {
|
|
16
|
+
<span class="origo-fab-label">{{ computedLabel() }}</span>
|
|
17
|
+
}
|
|
18
|
+
</button>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
position: fixed;
|
|
4
|
+
z-index: 1000;
|
|
5
|
+
}
|
|
6
|
+
:host(.origo-position-bottom-right) {
|
|
7
|
+
bottom: var(--origo-spacing-container-padding);
|
|
8
|
+
right: var(--origo-spacing-container-padding);
|
|
9
|
+
}
|
|
10
|
+
:host(.origo-position-bottom-left) {
|
|
11
|
+
bottom: var(--origo-spacing-container-padding);
|
|
12
|
+
left: var(--origo-spacing-container-padding);
|
|
13
|
+
}
|
|
14
|
+
button {
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
background-color: var(--origo-color-surface-primary);
|
|
17
|
+
color: var(--origo-color-text-inverse);
|
|
18
|
+
border: none;
|
|
19
|
+
border-radius: var(--origo-radius-xl);
|
|
20
|
+
box-shadow: var(--origo-shadow-md);
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
gap: var(--origo-spacing-sm, 8px);
|
|
25
|
+
min-width: 48px;
|
|
26
|
+
min-height: 48px;
|
|
27
|
+
padding: 0 var(--origo-spacing-container-padding);
|
|
28
|
+
transition: var(--origo-transition-all);
|
|
29
|
+
}
|
|
30
|
+
button:empty {
|
|
31
|
+
padding: 0;
|
|
32
|
+
}
|
|
33
|
+
button:hover:not(:disabled) {
|
|
34
|
+
background-color: var(--origo-color-surface-primary-hover);
|
|
35
|
+
box-shadow: var(--origo-shadow-lg);
|
|
36
|
+
}
|
|
37
|
+
button:active:not(:disabled) {
|
|
38
|
+
background-color: var(--origo-color-surface-primary-active);
|
|
39
|
+
}
|
|
40
|
+
button:focus-visible {
|
|
41
|
+
outline: var(--origo-outline-width, 2px) solid var(--origo-color-focus);
|
|
42
|
+
outline-offset: var(--origo-outline-width, 2px);
|
|
43
|
+
}
|
|
44
|
+
button:disabled {
|
|
45
|
+
cursor: not-allowed;
|
|
46
|
+
opacity: var(--origo-opacity-disabled);
|
|
47
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
input,
|
|
4
|
+
ChangeDetectionStrategy,
|
|
5
|
+
computed,
|
|
6
|
+
ViewEncapsulation,
|
|
7
|
+
inject,
|
|
8
|
+
} from '@angular/core';
|
|
9
|
+
import { InteractionContract } from '@origostudio/core';
|
|
10
|
+
import { OrigoAdapter } from '../../../adapters/web/adapter';
|
|
11
|
+
import { WebExperienceAdapterService } from '../../../adapters/web/experience-adapter.service';
|
|
12
|
+
|
|
13
|
+
export interface FabProps {
|
|
14
|
+
icon?: string;
|
|
15
|
+
label?: string;
|
|
16
|
+
severity?: string;
|
|
17
|
+
loading?: boolean;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
position?: 'bottom-right' | 'bottom-left';
|
|
20
|
+
'aria-label'?: string;
|
|
21
|
+
'aria-describedby'?: string;
|
|
22
|
+
permissions?: any;
|
|
23
|
+
rules?: any;
|
|
24
|
+
metadata?: any;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Component({
|
|
28
|
+
selector: 'origo-fab',
|
|
29
|
+
standalone: true,
|
|
30
|
+
templateUrl: './floating-action-button.component.html',
|
|
31
|
+
styleUrls: ['./floating-action-button.component.scss'],
|
|
32
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
33
|
+
encapsulation: ViewEncapsulation.ShadowDom,
|
|
34
|
+
host: {
|
|
35
|
+
'[class]': 'computedHostClasses()',
|
|
36
|
+
'[attr.data-testid]': 'contract().id ?? ""',
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
export class FloatingActionButtonComponent implements OrigoAdapter<FabProps> {
|
|
40
|
+
static readonly contractSchema = {
|
|
41
|
+
icon: 'string',
|
|
42
|
+
label: 'string',
|
|
43
|
+
severity: 'string',
|
|
44
|
+
loading: 'boolean',
|
|
45
|
+
disabled: 'boolean',
|
|
46
|
+
position: 'string',
|
|
47
|
+
'aria-label': 'string',
|
|
48
|
+
'aria-describedby': 'string',
|
|
49
|
+
permissions: 'object',
|
|
50
|
+
rules: 'object',
|
|
51
|
+
metadata: 'object',
|
|
52
|
+
};
|
|
53
|
+
static readonly strictContract = false;
|
|
54
|
+
|
|
55
|
+
contract = input.required<InteractionContract<FabProps>>();
|
|
56
|
+
|
|
57
|
+
computedIcon = computed(() => this.contract().props?.icon ?? '');
|
|
58
|
+
computedLabel = computed(() => this.contract().props?.label ?? '');
|
|
59
|
+
computedLoading = computed(() => !!this.contract().props?.loading);
|
|
60
|
+
computedDisabled = computed(() => {
|
|
61
|
+
const props = this.contract().props;
|
|
62
|
+
const rulesDisable = props?.rules?.disable === true || props?.permissions?.allow === false;
|
|
63
|
+
return !!props?.disabled || this.computedLoading() || rulesDisable;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
computedAriaLabel = computed(() => {
|
|
67
|
+
const p = this.contract().props;
|
|
68
|
+
const v = p?.['aria-label'] || p?.label;
|
|
69
|
+
return v ? String(v) : undefined;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
computedAriaDescribedBy = computed(() => {
|
|
73
|
+
const v = this.contract().props?.['aria-describedby'];
|
|
74
|
+
return v ? String(v) : undefined;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
computedHostClasses = computed(() => {
|
|
78
|
+
const s = this.contract().props?.severity;
|
|
79
|
+
const rawP = this.contract().props?.position;
|
|
80
|
+
const p = ['bottom-left', 'bottom-right'].includes(rawP as string) ? rawP : 'bottom-right';
|
|
81
|
+
return ['origo-fab', s ? `origo-severity-${s}` : '', `origo-position-${p}`]
|
|
82
|
+
.filter(Boolean)
|
|
83
|
+
.join(' ');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
private experienceAdapter = inject(WebExperienceAdapterService);
|
|
87
|
+
|
|
88
|
+
onClick() {
|
|
89
|
+
if (this.computedDisabled() || this.computedLoading()) return;
|
|
90
|
+
const id = this.contract().id;
|
|
91
|
+
if (!id) return;
|
|
92
|
+
this.experienceAdapter.dispatchCapability(id, 'click');
|
|
93
|
+
}
|
|
94
|
+
}
|
package/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.html
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<button
|
|
2
|
+
type="button"
|
|
3
|
+
[disabled]="computedDisabled()"
|
|
4
|
+
[attr.aria-label]="computedAriaLabel()"
|
|
5
|
+
[attr.aria-describedby]="computedAriaDescribedBy()"
|
|
6
|
+
[title]="contract().props?.tooltip || null"
|
|
7
|
+
(click)="onClick()"
|
|
8
|
+
>
|
|
9
|
+
@if (computedLoading()) {
|
|
10
|
+
<span class="origo-spinner"></span>
|
|
11
|
+
} @else {
|
|
12
|
+
@if (computedIcon()) {
|
|
13
|
+
<span [class]="'origo-icon origo-icon-' + computedIcon()"></span>
|
|
14
|
+
} @else {
|
|
15
|
+
<span class="origo-icon origo-icon-default"></span>
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
</button>
|
package/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.scss
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
}
|
|
4
|
+
button {
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
background-color: var(--origo-color-surface-primary);
|
|
7
|
+
color: var(--origo-color-text-inverse);
|
|
8
|
+
padding: var(--origo-spacing-container-padding);
|
|
9
|
+
border: none;
|
|
10
|
+
border-radius: var(--origo-radius-sm);
|
|
11
|
+
box-shadow: var(--origo-shadow-sm, none);
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
transition: var(--origo-transition-all);
|
|
16
|
+
}
|
|
17
|
+
button:hover:not(:disabled) {
|
|
18
|
+
background-color: var(--origo-color-surface-primary-hover);
|
|
19
|
+
}
|
|
20
|
+
button:active:not(:disabled) {
|
|
21
|
+
background-color: var(--origo-color-surface-primary-active);
|
|
22
|
+
}
|
|
23
|
+
button:focus-visible {
|
|
24
|
+
outline: var(--origo-outline-width, 2px) solid var(--origo-color-focus);
|
|
25
|
+
outline-offset: var(--origo-outline-width, 2px);
|
|
26
|
+
}
|
|
27
|
+
button:disabled {
|
|
28
|
+
cursor: not-allowed;
|
|
29
|
+
opacity: var(--origo-opacity-disabled);
|
|
30
|
+
}
|
|
31
|
+
:host(.origo-rounded) button {
|
|
32
|
+
border-radius: var(--origo-radius-round, 50%);
|
|
33
|
+
aspect-ratio: 1;
|
|
34
|
+
}
|
package/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
input,
|
|
4
|
+
ChangeDetectionStrategy,
|
|
5
|
+
computed,
|
|
6
|
+
ViewEncapsulation,
|
|
7
|
+
inject,
|
|
8
|
+
} from '@angular/core';
|
|
9
|
+
import { InteractionContract } from '@origostudio/core';
|
|
10
|
+
import { OrigoAdapter } from '../../../adapters/web/adapter';
|
|
11
|
+
import { WebExperienceAdapterService } from '../../../adapters/web/experience-adapter.service';
|
|
12
|
+
|
|
13
|
+
export interface IconButtonProps {
|
|
14
|
+
icon?: string;
|
|
15
|
+
label?: string;
|
|
16
|
+
tooltip?: string;
|
|
17
|
+
severity?: string;
|
|
18
|
+
variant?: string;
|
|
19
|
+
rounded?: boolean;
|
|
20
|
+
loading?: boolean;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
'aria-label'?: string;
|
|
23
|
+
'aria-describedby'?: string;
|
|
24
|
+
permissions?: any;
|
|
25
|
+
rules?: any;
|
|
26
|
+
metadata?: any;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Component({
|
|
30
|
+
selector: 'origo-icon-button',
|
|
31
|
+
standalone: true,
|
|
32
|
+
templateUrl: './icon-button.component.html',
|
|
33
|
+
styleUrls: ['./icon-button.component.scss'],
|
|
34
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
35
|
+
encapsulation: ViewEncapsulation.ShadowDom,
|
|
36
|
+
host: {
|
|
37
|
+
'[class]': 'computedHostClasses()',
|
|
38
|
+
'[attr.data-testid]': 'contract().id ?? ""',
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
export class IconButtonComponent implements OrigoAdapter<IconButtonProps> {
|
|
42
|
+
static readonly contractSchema = {
|
|
43
|
+
icon: 'string',
|
|
44
|
+
label: 'string',
|
|
45
|
+
tooltip: 'string',
|
|
46
|
+
severity: 'string',
|
|
47
|
+
variant: 'string',
|
|
48
|
+
rounded: 'boolean',
|
|
49
|
+
loading: 'boolean',
|
|
50
|
+
disabled: 'boolean',
|
|
51
|
+
'aria-label': 'string',
|
|
52
|
+
'aria-describedby': 'string',
|
|
53
|
+
permissions: 'object',
|
|
54
|
+
rules: 'object',
|
|
55
|
+
metadata: 'object',
|
|
56
|
+
};
|
|
57
|
+
static readonly strictContract = false;
|
|
58
|
+
|
|
59
|
+
contract = input.required<InteractionContract<IconButtonProps>>();
|
|
60
|
+
|
|
61
|
+
computedIcon = computed(() => this.contract().props?.icon ?? '');
|
|
62
|
+
computedLoading = computed(() => !!this.contract().props?.loading);
|
|
63
|
+
computedDisabled = computed(() => {
|
|
64
|
+
const props = this.contract().props;
|
|
65
|
+
const rulesDisable = props?.rules?.disable === true || props?.permissions?.allow === false;
|
|
66
|
+
return !!props?.disabled || this.computedLoading() || rulesDisable;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
computedAriaLabel = computed(() => {
|
|
70
|
+
const p = this.contract().props;
|
|
71
|
+
const v = p?.['aria-label'] || p?.label;
|
|
72
|
+
return v ? String(v) : undefined;
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
computedAriaDescribedBy = computed(() => {
|
|
76
|
+
const v = this.contract().props?.['aria-describedby'];
|
|
77
|
+
return v ? String(v) : undefined;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
computedHostClasses = computed(() => {
|
|
81
|
+
const s = this.contract().props?.severity;
|
|
82
|
+
const v = this.contract().props?.variant;
|
|
83
|
+
const rounded = this.contract().props?.rounded;
|
|
84
|
+
return [
|
|
85
|
+
'origo-icon-button',
|
|
86
|
+
s ? `origo-severity-${s}` : '',
|
|
87
|
+
v ? `origo-variant-${v}` : '',
|
|
88
|
+
rounded ? 'origo-rounded' : '',
|
|
89
|
+
]
|
|
90
|
+
.filter(Boolean)
|
|
91
|
+
.join(' ');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
private experienceAdapter = inject(WebExperienceAdapterService);
|
|
95
|
+
|
|
96
|
+
onClick() {
|
|
97
|
+
if (this.computedDisabled() || this.computedLoading()) return;
|
|
98
|
+
const id = this.contract().id;
|
|
99
|
+
if (!id) return;
|
|
100
|
+
this.experienceAdapter.dispatchCapability(id, 'click');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -5,6 +5,9 @@ export * from './adapters/web/adapter';
|
|
|
5
5
|
export * from './components/primitives/vbox/vbox.component';
|
|
6
6
|
export * from './components/primitives/text-input/text-input.component';
|
|
7
7
|
export * from './components/primitives/button/button.component';
|
|
8
|
+
export * from './components/primitives/icon-button/icon-button.component';
|
|
9
|
+
export * from './components/primitives/button-group/button-group.component';
|
|
10
|
+
export * from './components/primitives/floating-action-button/floating-action-button.component';
|
|
8
11
|
export * from './devtools';
|
|
9
12
|
export * from './components/primitives/select/select.component';
|
|
10
13
|
export * from './components/primitives/checkbox/checkbox.component';
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';
|
|
2
2
|
import { RENDERER_REGISTRY } from './renderer.tokens';
|
|
3
|
+
import { IconButtonComponent } from '../components/primitives/icon-button/icon-button.component';
|
|
4
|
+
import { ButtonGroupComponent } from '../components/primitives/button-group/button-group.component';
|
|
5
|
+
import { FloatingActionButtonComponent } from '../components/primitives/floating-action-button/floating-action-button.component';
|
|
3
6
|
import { SelectComponent } from '../components/primitives/select/select.component';
|
|
4
7
|
import { CheckboxComponent } from '../components/primitives/checkbox/checkbox.component';
|
|
5
8
|
import { RadioGroupComponent } from '../components/primitives/radio-group/radio-group.component';
|
|
@@ -21,6 +24,9 @@ import { VBoxComponent } from '../components/primitives/vbox/vbox.component';
|
|
|
21
24
|
|
|
22
25
|
export function provideOrigo9Primitives(): EnvironmentProviders {
|
|
23
26
|
const registryMap = new Map<string, unknown>([
|
|
27
|
+
['IconButton', IconButtonComponent],
|
|
28
|
+
['ButtonGroup', ButtonGroupComponent],
|
|
29
|
+
['FloatingActionButton', FloatingActionButtonComponent],
|
|
24
30
|
['Select', SelectComponent],
|
|
25
31
|
['Checkbox', CheckboxComponent],
|
|
26
32
|
['RadioGroup', RadioGroupComponent],
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 0.0.48 (2026-10-07)
|
|
2
|
+
|
|
3
|
+
This was a version bump only for cli to align it with other projects, there were no code changes.
|
|
4
|
+
|
|
5
|
+
## 0.0.47 (2026-10-07)
|
|
6
|
+
|
|
7
|
+
This was a version bump only for cli to align it with other projects, there were no code changes.
|
|
8
|
+
|
|
1
9
|
## 0.0.46 (2026-10-02)
|
|
2
10
|
|
|
3
11
|
This was a version bump only for cli to align it with other projects, there were no code changes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@origostudio/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.48",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"origo": "./src/main.js"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@origostudio/core": "0.0.
|
|
12
|
+
"@origostudio/core": "0.0.48",
|
|
13
13
|
"commander": "^15.0.0",
|
|
14
14
|
"tslib": "^2.3.0"
|
|
15
15
|
},
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 0.0.48 (2026-10-07)
|
|
2
|
+
|
|
3
|
+
This was a version bump only for core to align it with other projects, there were no code changes.
|
|
4
|
+
|
|
5
|
+
## 0.0.47 (2026-10-07)
|
|
6
|
+
|
|
7
|
+
This was a version bump only for core to align it with other projects, there were no code changes.
|
|
8
|
+
|
|
1
9
|
## 0.0.46 (2026-10-02)
|
|
2
10
|
|
|
3
11
|
This was a version bump only for core to align it with other projects, there were no code changes.
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 0.0.48 (2026-10-07)
|
|
2
|
+
|
|
3
|
+
This was a version bump only for design-tokens to align it with other projects, there were no code changes.
|
|
4
|
+
|
|
5
|
+
## 0.0.47 (2026-10-07)
|
|
6
|
+
|
|
7
|
+
This was a version bump only for design-tokens to align it with other projects, there were no code changes.
|
|
8
|
+
|
|
1
9
|
## 0.0.46 (2026-10-02)
|
|
2
10
|
|
|
3
11
|
This was a version bump only for design-tokens to align it with other projects, there were no code changes.
|