@origostudio/origo-design 0.0.48 → 0.0.49

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 (151) hide show
  1. package/CHANGELOG.md +4 -5
  2. package/apply-fixes.js +18 -0
  3. package/dist/packages/angular-renderer/CHANGELOG.md +11 -0
  4. package/dist/packages/angular-renderer/package.json +3 -3
  5. package/dist/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.d.ts +6 -0
  6. package/dist/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.js +3 -0
  7. package/dist/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.js.map +1 -1
  8. package/dist/packages/angular-renderer/src/components/primitives/button/button.component.d.ts +6 -6
  9. package/dist/packages/angular-renderer/src/components/primitives/button/button.component.js +4 -4
  10. package/dist/packages/angular-renderer/src/components/primitives/button/button.component.js.map +1 -1
  11. package/dist/packages/angular-renderer/src/components/primitives/button-group/button-group.component.d.ts +6 -0
  12. package/dist/packages/angular-renderer/src/components/primitives/button-group/button-group.component.js +3 -0
  13. package/dist/packages/angular-renderer/src/components/primitives/button-group/button-group.component.js.map +1 -1
  14. package/dist/packages/angular-renderer/src/components/primitives/card/card.component.d.ts +6 -0
  15. package/dist/packages/angular-renderer/src/components/primitives/card/card.component.js +3 -0
  16. package/dist/packages/angular-renderer/src/components/primitives/card/card.component.js.map +1 -1
  17. package/dist/packages/angular-renderer/src/components/primitives/checkbox/checkbox.component.d.ts +15 -0
  18. package/dist/packages/angular-renderer/src/components/primitives/checkbox/checkbox.component.js +9 -0
  19. package/dist/packages/angular-renderer/src/components/primitives/checkbox/checkbox.component.js.map +1 -1
  20. package/dist/packages/angular-renderer/src/components/primitives/chip/chip.component.d.ts +3 -0
  21. package/dist/packages/angular-renderer/src/components/primitives/chip/chip.component.js.map +1 -1
  22. package/dist/packages/angular-renderer/src/components/primitives/data-grid/data-grid.component.d.ts +6 -0
  23. package/dist/packages/angular-renderer/src/components/primitives/data-grid/data-grid.component.js +3 -0
  24. package/dist/packages/angular-renderer/src/components/primitives/data-grid/data-grid.component.js.map +1 -1
  25. package/dist/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.d.ts +6 -6
  26. package/dist/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.js +4 -4
  27. package/dist/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.js.map +1 -1
  28. package/dist/packages/angular-renderer/src/components/primitives/form-field/form-field.component.d.ts +6 -0
  29. package/dist/packages/angular-renderer/src/components/primitives/form-field/form-field.component.js +3 -0
  30. package/dist/packages/angular-renderer/src/components/primitives/form-field/form-field.component.js.map +1 -1
  31. package/dist/packages/angular-renderer/src/components/primitives/hbox/hbox.component.d.ts +6 -0
  32. package/dist/packages/angular-renderer/src/components/primitives/hbox/hbox.component.js +3 -0
  33. package/dist/packages/angular-renderer/src/components/primitives/hbox/hbox.component.js.map +1 -1
  34. package/dist/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.d.ts +6 -6
  35. package/dist/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.js +4 -4
  36. package/dist/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.js.map +1 -1
  37. package/dist/packages/angular-renderer/src/components/primitives/input-number/input-number.component.d.ts +46 -0
  38. package/dist/packages/angular-renderer/src/components/primitives/input-number/input-number.component.js +120 -0
  39. package/dist/packages/angular-renderer/src/components/primitives/input-number/input-number.component.js.map +1 -0
  40. package/dist/packages/angular-renderer/src/components/primitives/label/label.component.d.ts +6 -0
  41. package/dist/packages/angular-renderer/src/components/primitives/label/label.component.js +3 -0
  42. package/dist/packages/angular-renderer/src/components/primitives/label/label.component.js.map +1 -1
  43. package/dist/packages/angular-renderer/src/components/primitives/list/list.component.d.ts +6 -0
  44. package/dist/packages/angular-renderer/src/components/primitives/list/list.component.js +3 -0
  45. package/dist/packages/angular-renderer/src/components/primitives/list/list.component.js.map +1 -1
  46. package/dist/packages/angular-renderer/src/components/primitives/radio-group/radio-group.component.d.ts +15 -0
  47. package/dist/packages/angular-renderer/src/components/primitives/radio-group/radio-group.component.js +9 -0
  48. package/dist/packages/angular-renderer/src/components/primitives/radio-group/radio-group.component.js.map +1 -1
  49. package/dist/packages/angular-renderer/src/components/primitives/select/select.component.d.ts +6 -0
  50. package/dist/packages/angular-renderer/src/components/primitives/select/select.component.js +3 -0
  51. package/dist/packages/angular-renderer/src/components/primitives/select/select.component.js.map +1 -1
  52. package/dist/packages/angular-renderer/src/components/primitives/sidebar/sidebar.component.d.ts +6 -0
  53. package/dist/packages/angular-renderer/src/components/primitives/sidebar/sidebar.component.js +3 -0
  54. package/dist/packages/angular-renderer/src/components/primitives/sidebar/sidebar.component.js.map +1 -1
  55. package/dist/packages/angular-renderer/src/components/primitives/switch/switch.component.d.ts +9 -0
  56. package/dist/packages/angular-renderer/src/components/primitives/switch/switch.component.js +6 -0
  57. package/dist/packages/angular-renderer/src/components/primitives/switch/switch.component.js.map +1 -1
  58. package/dist/packages/angular-renderer/src/components/primitives/tabs/tabs.component.d.ts +6 -0
  59. package/dist/packages/angular-renderer/src/components/primitives/tabs/tabs.component.js +3 -0
  60. package/dist/packages/angular-renderer/src/components/primitives/tabs/tabs.component.js.map +1 -1
  61. package/dist/packages/angular-renderer/src/components/primitives/text-input/text-input.component.d.ts +28 -0
  62. package/dist/packages/angular-renderer/src/components/primitives/text-input/text-input.component.js +38 -2
  63. package/dist/packages/angular-renderer/src/components/primitives/text-input/text-input.component.js.map +1 -1
  64. package/dist/packages/angular-renderer/src/components/primitives/textarea/textarea.component.d.ts +26 -0
  65. package/dist/packages/angular-renderer/src/components/primitives/textarea/textarea.component.js +44 -0
  66. package/dist/packages/angular-renderer/src/components/primitives/textarea/textarea.component.js.map +1 -1
  67. package/dist/packages/angular-renderer/src/components/primitives/vbox/vbox.component.d.ts +6 -0
  68. package/dist/packages/angular-renderer/src/components/primitives/vbox/vbox.component.js +3 -0
  69. package/dist/packages/angular-renderer/src/components/primitives/vbox/vbox.component.js.map +1 -1
  70. package/dist/packages/angular-renderer/src/index.d.ts +1 -0
  71. package/dist/packages/angular-renderer/src/index.js +1 -0
  72. package/dist/packages/angular-renderer/src/index.js.map +1 -1
  73. package/dist/packages/angular-renderer/src/lib/primitives.provider.js +2 -0
  74. package/dist/packages/angular-renderer/src/lib/primitives.provider.js.map +1 -1
  75. package/dist/packages/cli/CHANGELOG.md +4 -0
  76. package/dist/packages/cli/package.json +2 -2
  77. package/dist/packages/cli/package.json.bak +2 -2
  78. package/dist/packages/core/CHANGELOG.md +4 -0
  79. package/dist/packages/core/package.json +1 -1
  80. package/dist/packages/core/package.json.bak +1 -1
  81. package/dist/packages/design-tokens/CHANGELOG.md +4 -0
  82. package/dist/packages/design-tokens/package.json +1 -1
  83. package/dist/packages/playground/browser/{chunk-CtaS4wCa.js → chunk-B8mwHWgW.js} +1 -1
  84. package/dist/packages/playground/browser/{chunk-CdNbNqNV.js → chunk-B_swdRuc.js} +1 -1
  85. package/dist/packages/playground/browser/{chunk-BQfPUVzZ.js → chunk-BbeNQQ9Z.js} +1 -1
  86. package/dist/packages/playground/browser/{chunk-ClmlG9ZJ.js → chunk-BlCRDoSd.js} +1 -1
  87. package/dist/packages/playground/browser/{chunk-DRRJiw3L.js → chunk-C8l8Pst_.js} +1 -1
  88. package/dist/packages/playground/browser/{chunk-CQQHYSEg.js → chunk-CCE_vAje.js} +1 -1
  89. package/dist/packages/playground/browser/{chunk-zkDXJCJr.js → chunk-Cb2ALrKC.js} +1 -1
  90. package/dist/packages/playground/browser/{chunk-4MD_GCgA.js → chunk-CpaI4VGh.js} +1 -1
  91. package/dist/packages/playground/browser/{chunk-ChP61sze.js → chunk-DgLZ-dIi.js} +1 -1
  92. package/dist/packages/playground/browser/{chunk-DvVvDpcg.js → chunk-DkxgAarv.js} +1 -1
  93. package/dist/packages/playground/browser/{chunk-COjGAm8R.js → chunk-DoYDPF2-.js} +1 -1
  94. package/dist/packages/playground/browser/{chunk-PT1eAqp3.js → chunk-G1sQXMvG.js} +1 -1
  95. package/dist/packages/playground/browser/{chunk-B8F7hD0p.js → chunk-XTbjIUbx.js} +1 -1
  96. package/dist/packages/playground/browser/{chunk-DyfobgsU.js → chunk-lFsGUZ3A.js} +1 -1
  97. package/dist/packages/playground/browser/{chunk-cI3o8oNy.js → chunk-r4-UbXQJ.js} +1 -1
  98. package/dist/packages/playground/browser/index.html +1 -1
  99. package/dist/packages/playground/browser/main-D2PNGI4C.js +734 -0
  100. package/package.json +1 -1
  101. package/packages/angular-renderer/CHANGELOG.md +11 -0
  102. package/packages/angular-renderer/package.json +3 -3
  103. package/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.ts +6 -0
  104. package/packages/angular-renderer/src/components/primitives/button/button.component.ts +8 -7
  105. package/packages/angular-renderer/src/components/primitives/button-group/button-group.component.ts +6 -0
  106. package/packages/angular-renderer/src/components/primitives/card/card.component.ts +6 -0
  107. package/packages/angular-renderer/src/components/primitives/checkbox/checkbox.component.html +24 -15
  108. package/packages/angular-renderer/src/components/primitives/checkbox/checkbox.component.scss +25 -9
  109. package/packages/angular-renderer/src/components/primitives/checkbox/checkbox.component.ts +16 -0
  110. package/packages/angular-renderer/src/components/primitives/chip/chip.component.ts +3 -0
  111. package/packages/angular-renderer/src/components/primitives/data-grid/data-grid.component.ts +6 -0
  112. package/packages/angular-renderer/src/components/primitives/floating-action-button/floating-action-button.component.ts +8 -7
  113. package/packages/angular-renderer/src/components/primitives/form-field/form-field.component.ts +6 -0
  114. package/packages/angular-renderer/src/components/primitives/hbox/hbox.component.ts +6 -0
  115. package/packages/angular-renderer/src/components/primitives/icon-button/icon-button.component.ts +8 -7
  116. package/packages/angular-renderer/src/components/primitives/input-number/input-number.component.html +24 -0
  117. package/packages/angular-renderer/src/components/primitives/input-number/input-number.component.scss +80 -0
  118. package/packages/angular-renderer/src/components/primitives/input-number/input-number.component.ts +146 -0
  119. package/packages/angular-renderer/src/components/primitives/label/label.component.ts +6 -0
  120. package/packages/angular-renderer/src/components/primitives/list/list.component.ts +6 -0
  121. package/packages/angular-renderer/src/components/primitives/radio-group/radio-group.component.html +11 -1
  122. package/packages/angular-renderer/src/components/primitives/radio-group/radio-group.component.scss +20 -9
  123. package/packages/angular-renderer/src/components/primitives/radio-group/radio-group.component.ts +16 -0
  124. package/packages/angular-renderer/src/components/primitives/select/select.component.ts +6 -0
  125. package/packages/angular-renderer/src/components/primitives/sidebar/sidebar.component.ts +6 -0
  126. package/packages/angular-renderer/src/components/primitives/switch/switch.component.html +24 -15
  127. package/packages/angular-renderer/src/components/primitives/switch/switch.component.scss +40 -22
  128. package/packages/angular-renderer/src/components/primitives/switch/switch.component.ts +13 -0
  129. package/packages/angular-renderer/src/components/primitives/tabs/tabs.component.ts +6 -0
  130. package/packages/angular-renderer/src/components/primitives/text-input/text-input.component.html +21 -10
  131. package/packages/angular-renderer/src/components/primitives/text-input/text-input.component.scss +44 -18
  132. package/packages/angular-renderer/src/components/primitives/text-input/text-input.component.ts +48 -2
  133. package/packages/angular-renderer/src/components/primitives/textarea/textarea.component.html +22 -12
  134. package/packages/angular-renderer/src/components/primitives/textarea/textarea.component.scss +61 -23
  135. package/packages/angular-renderer/src/components/primitives/textarea/textarea.component.ts +58 -0
  136. package/packages/angular-renderer/src/components/primitives/vbox/vbox.component.ts +6 -0
  137. package/packages/angular-renderer/src/index.ts +1 -0
  138. package/packages/angular-renderer/src/lib/primitives.provider.ts +2 -0
  139. package/packages/cli/CHANGELOG.md +4 -0
  140. package/packages/cli/package.json +2 -2
  141. package/packages/core/CHANGELOG.md +4 -0
  142. package/packages/core/package.json +1 -1
  143. package/packages/design-tokens/CHANGELOG.md +4 -0
  144. package/packages/design-tokens/package.json +1 -1
  145. package/packages/devtools/CHANGELOG.md +4 -0
  146. package/packages/devtools/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  147. package/packages/devtools/package.json +3 -3
  148. package/packages/playground/CHANGELOG.md +4 -0
  149. package/packages/playground/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  150. package/packages/playground/package.json +3 -3
  151. package/dist/packages/playground/browser/main-DTJJSNK4.js +0 -733
@@ -0,0 +1,146 @@
1
+ import {
2
+ Component,
3
+ input,
4
+ model,
5
+ ChangeDetectionStrategy,
6
+ computed,
7
+ ViewEncapsulation,
8
+ inject,
9
+ effect,
10
+ untracked,
11
+ SecurityContext,
12
+ } from '@angular/core';
13
+ import { DomSanitizer } from '@angular/platform-browser';
14
+ import { InteractionContract } from '@origostudio/core';
15
+ import { OrigoAdapter, coerceContractProps } from '../../../adapters/web/adapter';
16
+ import { WebExperienceAdapterService } from '../../../adapters/web/experience-adapter.service';
17
+
18
+ export interface InputNumberProps {
19
+ permissions?: Record<string, string>;
20
+ rules?: Record<string, unknown>;
21
+ metadata?: Record<string, unknown>;
22
+ value?: number;
23
+ placeholder?: string;
24
+ disabled?: boolean;
25
+ readonly?: boolean;
26
+ min?: number;
27
+ max?: number;
28
+ step?: number;
29
+ 'aria-label'?: string;
30
+ 'aria-describedby'?: string;
31
+ required?: boolean;
32
+ invalid?: boolean;
33
+ errorText?: string;
34
+ helpText?: string;
35
+ variant?: 'outlined' | 'filled' | 'text';
36
+ fluid?: boolean;
37
+ }
38
+
39
+ @Component({
40
+ selector: 'origo-input-number',
41
+ standalone: true,
42
+ templateUrl: './input-number.component.html',
43
+ styleUrls: ['./input-number.component.scss'],
44
+ changeDetection: ChangeDetectionStrategy.OnPush,
45
+ encapsulation: ViewEncapsulation.ShadowDom,
46
+ host: {
47
+ '[class.origo-input-number]': 'true',
48
+ '[attr.data-testid]': 'contract().id',
49
+ '[class.origo-input-number--fluid]': 'computedFluid()',
50
+ '[class.origo-input-number--outlined]': 'computedVariant() === "outlined"',
51
+ '[class.origo-input-number--filled]': 'computedVariant() === "filled"',
52
+ '[class.origo-input-number--text]': 'computedVariant() === "text"',
53
+ },
54
+ })
55
+ export class InputNumberComponent implements OrigoAdapter<InputNumberProps> {
56
+ static readonly contractSchema: Record<
57
+ string,
58
+ 'string' | 'number' | 'boolean' | 'object' | 'array'
59
+ > = {
60
+ value: 'number',
61
+ placeholder: 'string',
62
+ disabled: 'boolean',
63
+ readonly: 'boolean',
64
+ min: 'number',
65
+ max: 'number',
66
+ step: 'number',
67
+ required: 'boolean',
68
+ invalid: 'boolean',
69
+ errorText: 'string',
70
+ helpText: 'string',
71
+ variant: 'string',
72
+ fluid: 'boolean',
73
+ };
74
+ static readonly strictContract = false;
75
+
76
+ contract = input.required<InteractionContract<InputNumberProps>>();
77
+ value = model<number | undefined>(undefined);
78
+
79
+ computedPlaceholder = computed(() => this.contract().props?.placeholder ?? '');
80
+ computedDisabled = computed(() => !!this.contract().props?.disabled);
81
+ computedReadonly = computed(() => !!this.contract().props?.readonly);
82
+ computedMin = computed(() => this.contract().props?.min);
83
+ computedMax = computed(() => this.contract().props?.max);
84
+ computedStep = computed(() => this.contract().props?.step);
85
+ computedRequired = computed(() => !!this.contract().props?.required);
86
+ computedInvalid = computed(() => !!this.contract().props?.invalid);
87
+ computedVariant = computed(() => this.contract().props?.variant ?? 'outlined');
88
+ computedFluid = computed(() => !!this.contract().props?.fluid);
89
+ computedErrorText = computed(() => this.contract().props?.errorText ?? '');
90
+ computedHelpText = computed(() => this.contract().props?.helpText ?? '');
91
+
92
+ computedAriaLabel = computed(() => {
93
+ const label = this.contract().props?.['aria-label'];
94
+ return label !== undefined && label !== null && String(label).trim() !== ''
95
+ ? String(label)
96
+ : undefined;
97
+ });
98
+ computedAriaDescribedBy = computed(() => {
99
+ const desc = this.contract().props?.['aria-describedby'];
100
+ return desc !== undefined && desc !== null && String(desc).trim() !== ''
101
+ ? String(desc)
102
+ : undefined;
103
+ });
104
+
105
+ private experienceAdapter = inject(WebExperienceAdapterService);
106
+ private sanitizer = inject(DomSanitizer);
107
+
108
+ constructor() {
109
+ effect(() => {
110
+ const props = this.contract().props;
111
+ const coerced = props
112
+ ? coerceContractProps<Record<string, unknown>>(props, InputNumberComponent.contractSchema)
113
+ : {};
114
+ const contractVal = coerced['value'];
115
+
116
+ const parsedVal = typeof contractVal === 'number' ? contractVal : undefined;
117
+ untracked(() => {
118
+ if (parsedVal === this.value()) return;
119
+ this.value.set(parsedVal);
120
+ });
121
+ });
122
+ }
123
+
124
+ onInput(event: Event) {
125
+ const target = event.target as HTMLInputElement | null;
126
+ if (!target || this.computedDisabled() || this.computedReadonly()) return;
127
+
128
+ const rawValue = target.value;
129
+ const sanitizedValue =
130
+ this.sanitizer.sanitize(SecurityContext.HTML, rawValue) || rawValue || '';
131
+
132
+ if (target.value !== sanitizedValue) {
133
+ target.value = sanitizedValue;
134
+ }
135
+
136
+ const numValue = sanitizedValue === '' ? undefined : Number(sanitizedValue);
137
+
138
+ // Check if it's a valid number. If not, don't update state but let the user type
139
+ if (sanitizedValue !== '' && isNaN(Number(sanitizedValue))) {
140
+ return;
141
+ }
142
+
143
+ this.value.set(numValue);
144
+ this.experienceAdapter.updateState(this.contract().id, 'value', numValue);
145
+ }
146
+ }
@@ -9,6 +9,9 @@ import { InteractionContract } from '@origostudio/core';
9
9
  import { OrigoAdapter } from '../../../adapters/web/adapter';
10
10
 
11
11
  export interface LabelProps {
12
+ permissions?: Record<string, string>;
13
+ rules?: Record<string, unknown>;
14
+ metadata?: Record<string, unknown>;
12
15
  text?: string;
13
16
  for?: string;
14
17
  required?: boolean;
@@ -30,6 +33,9 @@ export interface LabelProps {
30
33
  })
31
34
  export class LabelComponent implements OrigoAdapter<LabelProps> {
32
35
  static readonly contractSchema = {
36
+ permissions: 'object',
37
+ rules: 'object',
38
+ metadata: 'object',
33
39
  text: 'string',
34
40
  for: 'string',
35
41
  required: 'boolean',
@@ -13,6 +13,9 @@ import { OrigoAdapter } from '../../../adapters/web/adapter';
13
13
  import { WebExperienceAdapterService } from '../../../adapters/web/experience-adapter.service';
14
14
 
15
15
  export interface ListProps {
16
+ permissions?: Record<string, string>;
17
+ rules?: Record<string, unknown>;
18
+ metadata?: Record<string, unknown>;
16
19
  items?: Array<Record<string, unknown>>;
17
20
  maxItems?: number;
18
21
  disabled?: boolean;
@@ -37,6 +40,9 @@ export interface ListProps {
37
40
  })
38
41
  export class ListComponent implements OrigoAdapter<ListProps> {
39
42
  static readonly contractSchema = {
43
+ permissions: 'object',
44
+ rules: 'object',
45
+ metadata: 'object',
40
46
  items: 'array',
41
47
  maxItems: 'number',
42
48
  disabled: 'boolean',
@@ -1,4 +1,8 @@
1
- <fieldset [disabled]="computedDisabled()" [attr.aria-describedby]="computedAriaDescribedBy()">
1
+ <fieldset
2
+ [disabled]="computedDisabled()"
3
+ [attr.aria-describedby]="computedAriaDescribedBy()"
4
+ [attr.aria-invalid]="computedInvalid() ? 'true' : null"
5
+ >
2
6
  <legend class="visually-hidden">{{ computedAriaLabel() ?? 'Radio Group' }}</legend>
3
7
 
4
8
  <div class="radio-options">
@@ -18,3 +22,9 @@
18
22
  }
19
23
  </div>
20
24
  </fieldset>
25
+ @if (computedErrorText()) {
26
+ <div class="origo-radio-group__error">{{ computedErrorText() }}</div>
27
+ }
28
+ @if (computedHelpText()) {
29
+ <div class="origo-radio-group__help">{{ computedHelpText() }}</div>
30
+ }
@@ -8,7 +8,7 @@ fieldset {
8
8
  margin: 0;
9
9
 
10
10
  &:disabled {
11
- opacity: var(--origo-opacity-disabled, 0.5);
11
+ opacity: var(--origo-opacity-disabled);
12
12
 
13
13
  .radio-label {
14
14
  cursor: not-allowed;
@@ -30,25 +30,36 @@ fieldset {
30
30
  .radio-options {
31
31
  display: flex;
32
32
  flex-direction: column;
33
- gap: var(--origo-spacing-container-padding, 8px);
33
+ gap: var(--origo-spacing-container-padding);
34
34
  }
35
35
 
36
36
  .radio-label {
37
37
  display: inline-flex;
38
38
  align-items: center;
39
- gap: var(--origo-spacing-container-padding, 8px);
39
+ gap: var(--origo-spacing-container-padding);
40
40
  cursor: pointer;
41
- font-family: var(--origo-typography-input-font-family, inherit);
42
- font-size: var(--origo-typography-input-font-size, 1rem);
43
- color: var(--origo-color-text-primary, #333);
41
+ font-family: var(--origo-typography-input-font-family);
42
+ font-size: var(--origo-typography-input-font-size);
43
+ color: var(--origo-color-text-primary);
44
44
  }
45
45
 
46
46
  input[type='radio'] {
47
47
  margin: 0;
48
- accent-color: var(--origo-color-focus, #005fcc);
48
+ accent-color: var(--origo-color-focus);
49
49
 
50
50
  &:focus-visible {
51
- outline: 2px solid var(--origo-color-focus, #005fcc);
52
- outline-offset: 2px;
51
+ outline: var(--origo-border-width-thick) solid var(--origo-color-focus);
52
+ outline-offset: var(--origo-border-width-thick);
53
53
  }
54
54
  }
55
+
56
+ .origo-radio-group__error {
57
+ color: var(--origo-color-text-danger);
58
+ font-size: var(--origo-typography-caption-font-size);
59
+ margin-top: var(--origo-spacing-xs);
60
+ }
61
+ .origo-radio-group__help {
62
+ color: var(--origo-color-text-muted);
63
+ font-size: var(--origo-typography-caption-font-size);
64
+ margin-top: var(--origo-spacing-xs);
65
+ }
@@ -14,12 +14,18 @@ import { OrigoAdapter } from '../../../adapters/web/adapter';
14
14
  import { WebExperienceAdapterService } from '../../../adapters/web/experience-adapter.service';
15
15
 
16
16
  export interface RadioGroupProps {
17
+ permissions?: Record<string, string>;
18
+ rules?: Record<string, unknown>;
19
+ metadata?: Record<string, unknown>;
17
20
  options: Array<{ value: string; label: string }>;
18
21
  value?: string;
19
22
  disabled?: boolean;
20
23
  'aria-label'?: string;
21
24
  'aria-describedby'?: string;
22
25
  required?: boolean;
26
+ invalid?: boolean;
27
+ errorText?: string;
28
+ helpText?: string;
23
29
  }
24
30
 
25
31
  @Component({
@@ -36,10 +42,16 @@ export interface RadioGroupProps {
36
42
  })
37
43
  export class RadioGroupComponent implements OrigoAdapter<RadioGroupProps> {
38
44
  static readonly contractSchema = {
45
+ permissions: 'object',
46
+ rules: 'object',
47
+ metadata: 'object',
39
48
  options: 'array',
40
49
  value: 'string',
41
50
  disabled: 'boolean',
42
51
  required: 'boolean',
52
+ invalid: 'boolean',
53
+ errorText: 'string',
54
+ helpText: 'string',
43
55
  };
44
56
  static readonly strictContract = false;
45
57
 
@@ -65,6 +77,10 @@ export class RadioGroupComponent implements OrigoAdapter<RadioGroupProps> {
65
77
  : undefined;
66
78
  });
67
79
 
80
+ computedInvalid = computed(() => !!this.contract().props?.invalid);
81
+ computedErrorText = computed(() => this.contract().props?.errorText ?? '');
82
+ computedHelpText = computed(() => this.contract().props?.helpText ?? '');
83
+
68
84
  private experienceAdapter = inject(WebExperienceAdapterService);
69
85
 
70
86
  constructor() {
@@ -16,6 +16,9 @@ import { OrigoAdapter } from '../../../adapters/web/adapter';
16
16
  import { WebExperienceAdapterService } from '../../../adapters/web/experience-adapter.service';
17
17
 
18
18
  export interface SelectProps {
19
+ permissions?: Record<string, string>;
20
+ rules?: Record<string, unknown>;
21
+ metadata?: Record<string, unknown>;
19
22
  options: Array<{ value: string; label: string }>;
20
23
  value?: string;
21
24
  disabled?: boolean;
@@ -39,6 +42,9 @@ export interface SelectProps {
39
42
  })
40
43
  export class SelectComponent implements OrigoAdapter<SelectProps> {
41
44
  static readonly contractSchema = {
45
+ permissions: 'object',
46
+ rules: 'object',
47
+ metadata: 'object',
42
48
  options: 'array',
43
49
  value: 'string',
44
50
  disabled: 'boolean',
@@ -20,6 +20,9 @@ export interface SidebarItem {
20
20
  }
21
21
 
22
22
  export interface SidebarProps {
23
+ permissions?: Record<string, string>;
24
+ rules?: Record<string, unknown>;
25
+ metadata?: Record<string, unknown>;
23
26
  items?: Array<SidebarItem>;
24
27
  activeOutcome?: string;
25
28
  collapsed?: boolean;
@@ -45,6 +48,9 @@ export interface SidebarProps {
45
48
  })
46
49
  export class SidebarComponent implements OrigoAdapter<SidebarProps> {
47
50
  static readonly contractSchema = {
51
+ permissions: 'object',
52
+ rules: 'object',
53
+ metadata: 'object',
48
54
  items: 'array',
49
55
  collapsed: 'boolean',
50
56
  };
@@ -1,16 +1,25 @@
1
- <label [for]="contract().id" [class.disabled]="computedDisabled()">
2
- <input
3
- type="checkbox"
4
- role="switch"
5
- [id]="contract().id"
6
- [checked]="checked()"
7
- [disabled]="computedDisabled()"
8
- [attr.aria-checked]="checked().toString()"
9
- [attr.aria-label]="computedAriaLabel() ?? undefined"
10
- [attr.aria-describedby]="computedAriaDescribedBy() ?? undefined"
11
- (change)="onChange($event)"
12
- />
13
- @if (computedLabel()) {
14
- <span class="label-text">{{ computedLabel() }}</span>
1
+ <div class="origo-switch__wrapper">
2
+ <label [for]="contract().id" [class.disabled]="computedDisabled()">
3
+ <input
4
+ type="checkbox"
5
+ role="switch"
6
+ [id]="contract().id"
7
+ [checked]="checked()"
8
+ [disabled]="computedDisabled()"
9
+ [attr.aria-checked]="checked().toString()"
10
+ [attr.aria-label]="computedAriaLabel() ?? undefined"
11
+ [attr.aria-describedby]="computedAriaDescribedBy() ?? undefined"
12
+ [attr.aria-invalid]="computedInvalid() ? 'true' : null"
13
+ (change)="onChange($event)"
14
+ />
15
+ @if (computedLabel()) {
16
+ <span class="label-text">{{ computedLabel() }}</span>
17
+ }
18
+ </label>
19
+ @if (computedErrorText()) {
20
+ <div class="origo-switch__error">{{ computedErrorText() }}</div>
15
21
  }
16
- </label>
22
+ @if (computedHelpText()) {
23
+ <div class="origo-switch__help">{{ computedHelpText() }}</div>
24
+ }
25
+ </div>
@@ -2,65 +2,83 @@
2
2
  display: inline-block;
3
3
  }
4
4
 
5
+ .origo-switch__wrapper {
6
+ display: flex;
7
+ flex-direction: column;
8
+ }
9
+
5
10
  label {
6
11
  display: inline-flex;
7
12
  align-items: center;
8
- gap: var(--origo-spacing-container-padding, 8px);
13
+ gap: var(--origo-spacing-container-padding);
9
14
  cursor: pointer;
10
- font-family: var(--origo-typography-input-font-family, inherit);
11
- font-size: var(--origo-typography-input-font-size, 1rem);
12
- color: var(--origo-color-text-primary, #333333);
15
+ font-family: var(--origo-typography-input-font-family);
16
+ font-size: var(--origo-typography-input-font-size);
17
+ color: var(--origo-color-text-primary);
13
18
 
14
19
  &.disabled {
15
- opacity: var(--origo-opacity-disabled, 0.5);
20
+ opacity: var(--origo-opacity-disabled);
16
21
  cursor: not-allowed;
17
22
  }
18
23
  }
19
24
 
20
25
  input[type='checkbox'][role='switch'] {
21
26
  appearance: none;
22
- width: var(--origo-switch-track-width, 40px);
23
- height: var(--origo-switch-track-height, 22px);
24
- background-color: var(--origo-color-surface-variant, #e0e0e0);
25
- border-radius: var(--origo-radius-switch-track, 11px);
27
+ width: var(--origo-switch-track-width);
28
+ height: var(--origo-switch-track-height);
29
+ background-color: var(--origo-color-surface-variant);
30
+ border-radius: var(--origo-radius-switch-track);
26
31
  position: relative;
27
32
  outline: none;
28
33
  cursor: pointer;
29
34
  margin: 0;
30
- transition: background-color 0.2s ease-in-out;
35
+ transition: background-color var(--origo-duration-fast) ease-in-out;
31
36
 
32
37
  &:hover:not(:disabled) {
33
- background-color: var(--origo-color-surface-variant-hover, #d0d0d0);
38
+ background-color: var(--origo-color-surface-variant-hover);
34
39
  }
35
40
 
36
41
  &::after {
37
42
  content: '';
38
43
  position: absolute;
39
- top: 2px;
40
- inset-inline-start: 2px;
41
- width: var(--origo-switch-thumb-size, 18px);
42
- height: var(--origo-switch-thumb-size, 18px);
43
- background-color: var(--origo-color-on-accent, #ffffff);
44
+ top: var(--origo-border-width-md);
45
+ inset-inline-start: var(--origo-border-width-md);
46
+ width: var(--origo-switch-thumb-size);
47
+ height: var(--origo-switch-thumb-size);
48
+ background-color: var(--origo-color-on-accent);
44
49
  border-radius: 50%;
45
50
  transition:
46
- inset-inline-start 0.2s ease-in-out,
47
- transform 0.2s ease-in-out;
51
+ inset-inline-start var(--origo-duration-fast) ease-in-out,
52
+ transform var(--origo-duration-fast) ease-in-out;
48
53
  }
49
54
 
50
55
  &:checked {
51
- background-color: var(--origo-color-accent, var(--origo-color-primary, #005fcc));
56
+ background-color: var(--origo-color-accent);
52
57
 
53
58
  &::after {
54
- inset-inline-start: calc(100% - var(--origo-switch-thumb-size, 18px) - 2px);
59
+ inset-inline-start: calc(
60
+ 100% - var(--origo-switch-thumb-size) - var(--origo-border-width-md)
61
+ );
55
62
  }
56
63
  }
57
64
 
58
65
  &:focus-visible {
59
- outline: 2px solid var(--origo-color-focus, #005fcc);
60
- outline-offset: 2px;
66
+ outline: var(--origo-border-width-thick) solid var(--origo-color-focus);
67
+ outline-offset: var(--origo-border-width-thick);
61
68
  }
62
69
 
63
70
  &:disabled {
64
71
  cursor: not-allowed;
65
72
  }
66
73
  }
74
+
75
+ .origo-switch__error {
76
+ color: var(--origo-color-text-danger);
77
+ font-size: var(--origo-typography-caption-font-size);
78
+ margin-top: var(--origo-spacing-xs);
79
+ }
80
+ .origo-switch__help {
81
+ color: var(--origo-color-text-muted);
82
+ font-size: var(--origo-typography-caption-font-size);
83
+ margin-top: var(--origo-spacing-xs);
84
+ }
@@ -14,11 +14,17 @@ import { OrigoAdapter, coerceContractProps } from '../../../adapters/web/adapter
14
14
  import { WebExperienceAdapterService } from '../../../adapters/web/experience-adapter.service';
15
15
 
16
16
  export interface SwitchProps {
17
+ permissions?: Record<string, string>;
18
+ rules?: Record<string, unknown>;
19
+ metadata?: Record<string, unknown>;
17
20
  checked?: boolean;
18
21
  label?: string;
19
22
  disabled?: boolean;
20
23
  'aria-label'?: string;
21
24
  'aria-describedby'?: string;
25
+ invalid?: boolean;
26
+ errorText?: string;
27
+ helpText?: string;
22
28
  }
23
29
 
24
30
  @Component({
@@ -41,6 +47,9 @@ export class SwitchComponent implements OrigoAdapter<SwitchProps> {
41
47
  checked: 'boolean',
42
48
  label: 'string',
43
49
  disabled: 'boolean',
50
+ invalid: 'boolean',
51
+ errorText: 'string',
52
+ helpText: 'string',
44
53
  };
45
54
  static readonly strictContract = false;
46
55
 
@@ -58,6 +67,10 @@ export class SwitchComponent implements OrigoAdapter<SwitchProps> {
58
67
  return v !== undefined && v !== null && String(v).trim() !== '' ? String(v) : undefined;
59
68
  });
60
69
 
70
+ computedInvalid = computed(() => !!this.contract().props?.invalid);
71
+ computedErrorText = computed(() => this.contract().props?.errorText ?? '');
72
+ computedHelpText = computed(() => this.contract().props?.helpText ?? '');
73
+
61
74
  private experienceAdapter = inject(WebExperienceAdapterService);
62
75
 
63
76
  constructor() {
@@ -22,6 +22,9 @@ export interface TabItem {
22
22
  }
23
23
 
24
24
  export interface TabsProps {
25
+ permissions?: Record<string, string>;
26
+ rules?: Record<string, unknown>;
27
+ metadata?: Record<string, unknown>;
25
28
  tabs?: Array<TabItem>;
26
29
  activeTab?: string;
27
30
  'aria-label'?: string;
@@ -42,6 +45,9 @@ export interface TabsProps {
42
45
  })
43
46
  export class TabsComponent implements OrigoAdapter<TabsProps> {
44
47
  static readonly contractSchema = {
48
+ permissions: 'object',
49
+ rules: 'object',
50
+ metadata: 'object',
45
51
  tabs: 'array',
46
52
  };
47
53
  static readonly strictContract = false;
@@ -1,10 +1,21 @@
1
- <input
2
- type="text"
3
- [value]="value()"
4
- (input)="onInput($event)"
5
- [placeholder]="computedPlaceholder()"
6
- [disabled]="computedDisabled()"
7
- [readonly]="computedReadonly()"
8
- [attr.aria-label]="computedAriaLabel()"
9
- [attr.aria-describedby]="computedAriaDescribedBy()"
10
- />
1
+ <div class="origo-text-input__wrapper">
2
+ <input
3
+ [attr.type]="computedType()"
4
+ [value]="value()"
5
+ (input)="onInput($event)"
6
+ (paste)="onPaste($event)"
7
+ [placeholder]="computedPlaceholder()"
8
+ [disabled]="computedDisabled()"
9
+ [readonly]="computedReadonly()"
10
+ [attr.aria-label]="computedAriaLabel()"
11
+ [attr.aria-describedby]="computedAriaDescribedBy()"
12
+ [attr.aria-invalid]="computedInvalid() ? 'true' : null"
13
+ [attr.aria-required]="computedRequired() ? 'true' : null"
14
+ />
15
+ </div>
16
+ @if (computedErrorText()) {
17
+ <div class="origo-text-input__error">{{ computedErrorText() }}</div>
18
+ }
19
+ @if (computedHelpText()) {
20
+ <div class="origo-text-input__help">{{ computedHelpText() }}</div>
21
+ }
@@ -1,42 +1,68 @@
1
1
  :host {
2
2
  display: inline-block;
3
3
  }
4
+ :host(.origo-text-input--fluid) {
5
+ display: block;
6
+ width: 100%;
7
+ }
8
+ .origo-text-input__wrapper {
9
+ display: flex;
10
+ flex-direction: column;
11
+ }
4
12
  input {
5
13
  box-sizing: border-box;
6
14
  width: 100%;
7
15
  background-color: var(--origo-color-surface-background);
8
16
  color: var(--origo-color-text-primary);
9
17
  padding: var(--origo-spacing-container-padding);
10
- border: var(--origo-border-width-default, 1px) solid var(--origo-color-border-default, #ccc);
11
- border-radius: var(--origo-radius-sm, 4px);
12
- box-shadow: var(--origo-shadow-sm, none);
13
- font-family: var(--origo-typography-input-font-family, inherit);
14
- font-size: var(--origo-typography-input-font-size, inherit);
15
- font-weight: var(--origo-typography-input-font-weight, inherit);
16
- line-height: var(--origo-typography-input-line-height, inherit);
17
- transition: all 0.2s ease-in-out;
18
+ border: var(--origo-border-width-default) solid var(--origo-color-border-default);
19
+ border-radius: var(--origo-radius-sm);
20
+ box-shadow: var(--origo-shadow-sm);
21
+ font-family: var(--origo-typography-input-font-family);
22
+ font-size: var(--origo-typography-input-font-size);
23
+ font-weight: var(--origo-typography-input-font-weight);
24
+ line-height: var(--origo-typography-input-line-height);
25
+ transition: all var(--origo-duration-fast) ease-in-out;
26
+ }
27
+ :host(.origo-text-input--filled) input {
28
+ background-color: var(--origo-color-surface-subtle);
29
+ border: none;
30
+ }
31
+ :host(.origo-text-input--text) input {
32
+ background-color: transparent;
33
+ border: none;
18
34
  }
19
35
  input::placeholder {
20
- color: var(--origo-color-text-muted, #777);
36
+ color: var(--origo-color-text-muted);
21
37
  }
22
38
  input:hover:not(:disabled):not([readonly]) {
23
- border-color: var(--origo-color-border-hover, #999);
39
+ border-color: var(--origo-color-border-hover);
24
40
  }
25
41
  input:active:not(:disabled):not([readonly]) {
26
- border-color: var(--origo-color-border-active, #666);
42
+ border-color: var(--origo-color-border-active);
27
43
  }
28
44
  input:focus,
29
45
  input:focus-visible {
30
- outline: 2px solid var(--origo-color-focus, #005fcc);
31
- outline-offset: -1px;
32
- border-color: var(--origo-color-focus, #005fcc);
46
+ outline: var(--origo-border-width-thick) solid var(--origo-color-focus);
47
+ outline-offset: var(--origo-border-offset-negative);
48
+ border-color: var(--origo-color-focus);
33
49
  }
34
50
  input:disabled {
35
51
  cursor: not-allowed;
36
- opacity: var(--origo-opacity-disabled, 0.5);
37
- background-color: var(--origo-color-surface-disabled, #eee);
38
- color: var(--origo-color-text-disabled, #999);
52
+ opacity: var(--origo-opacity-disabled);
53
+ background-color: var(--origo-color-surface-disabled);
54
+ color: var(--origo-color-text-disabled);
39
55
  }
40
56
  input[readonly] {
41
- background-color: var(--origo-color-surface-readonly, #f9f9f9);
57
+ background-color: var(--origo-color-surface-readonly);
58
+ }
59
+ .origo-text-input__error {
60
+ color: var(--origo-color-text-danger);
61
+ font-size: var(--origo-typography-caption-font-size);
62
+ margin-top: var(--origo-spacing-xs);
63
+ }
64
+ .origo-text-input__help {
65
+ color: var(--origo-color-text-muted);
66
+ font-size: var(--origo-typography-caption-font-size);
67
+ margin-top: var(--origo-spacing-xs);
42
68
  }