@origostudio/origo-design 0.0.53 → 0.0.55

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 (90) hide show
  1. package/CHANGELOG.md +4 -3
  2. package/dist/packages/angular-renderer/CHANGELOG.md +22 -0
  3. package/dist/packages/angular-renderer/package.json +9 -4
  4. package/dist/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.d.ts +17 -13
  5. package/dist/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.js +55 -20
  6. package/dist/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.js.map +1 -1
  7. package/dist/packages/angular-renderer/src/components/primitives/pagination/pagination.component.d.ts +64 -0
  8. package/dist/packages/angular-renderer/src/components/primitives/pagination/pagination.component.js +208 -0
  9. package/dist/packages/angular-renderer/src/components/primitives/pagination/pagination.component.js.map +1 -0
  10. package/dist/packages/angular-renderer/src/components/primitives/stepper/stepper.component.d.ts +65 -0
  11. package/dist/packages/angular-renderer/src/components/primitives/stepper/stepper.component.js +272 -0
  12. package/dist/packages/angular-renderer/src/components/primitives/stepper/stepper.component.js.map +1 -0
  13. package/dist/packages/angular-renderer/src/components/primitives/tabs/tabs.component.d.ts +24 -15
  14. package/dist/packages/angular-renderer/src/components/primitives/tabs/tabs.component.js +105 -45
  15. package/dist/packages/angular-renderer/src/components/primitives/tabs/tabs.component.js.map +1 -1
  16. package/dist/packages/angular-renderer/src/index.d.ts +5 -0
  17. package/dist/packages/angular-renderer/src/index.js +5 -0
  18. package/dist/packages/angular-renderer/src/index.js.map +1 -1
  19. package/dist/packages/angular-renderer/src/lib/overlay/overlay-ref.d.ts +40 -0
  20. package/dist/packages/angular-renderer/src/lib/overlay/overlay-ref.js +248 -0
  21. package/dist/packages/angular-renderer/src/lib/overlay/overlay-ref.js.map +1 -0
  22. package/dist/packages/angular-renderer/src/lib/overlay/overlay.models.d.ts +51 -0
  23. package/dist/packages/angular-renderer/src/lib/overlay/overlay.models.js +3 -0
  24. package/dist/packages/angular-renderer/src/lib/overlay/overlay.models.js.map +1 -0
  25. package/dist/packages/angular-renderer/src/lib/overlay/overlay.service.d.ts +12 -0
  26. package/dist/packages/angular-renderer/src/lib/overlay/overlay.service.js +211 -0
  27. package/dist/packages/angular-renderer/src/lib/overlay/overlay.service.js.map +1 -0
  28. package/dist/packages/angular-renderer/src/lib/primitives.provider.js +5 -0
  29. package/dist/packages/angular-renderer/src/lib/primitives.provider.js.map +1 -1
  30. package/dist/packages/cli/CHANGELOG.md +8 -0
  31. package/dist/packages/cli/package.json +2 -2
  32. package/dist/packages/cli/package.json.bak +2 -2
  33. package/dist/packages/core/CHANGELOG.md +8 -0
  34. package/dist/packages/core/package.json +1 -1
  35. package/dist/packages/core/package.json.bak +1 -1
  36. package/dist/packages/design-tokens/CHANGELOG.md +8 -0
  37. package/dist/packages/design-tokens/package.json +1 -1
  38. package/dist/packages/playground/browser/{chunk-CoyK3eaz.js → chunk-1qL4kcgA.js} +1 -1
  39. package/dist/packages/playground/browser/{chunk-DGFBCrz0.js → chunk-BrNyIaRu.js} +1 -1
  40. package/dist/packages/playground/browser/{chunk-BD3aW3fo.js → chunk-BtTuZVyy.js} +1 -1
  41. package/dist/packages/playground/browser/{chunk-CZYE6Vo5.js → chunk-COdU4TAE.js} +1 -1
  42. package/dist/packages/playground/browser/{chunk-D-gQXFhO.js → chunk-ChIFPhYz.js} +1 -1
  43. package/dist/packages/playground/browser/{chunk-CYa5xYdO.js → chunk-CkxX-6B-.js} +1 -1
  44. package/dist/packages/playground/browser/{chunk-kcBcpdDQ.js → chunk-CsaBv_7w.js} +1 -1
  45. package/dist/packages/playground/browser/{chunk-DoDHfFRC.js → chunk-DT7XZi8x.js} +1 -1
  46. package/dist/packages/playground/browser/{chunk-DjQs2rZT.js → chunk-DVT-phDq.js} +1 -1
  47. package/dist/packages/playground/browser/{chunk-DFUtHoSa.js → chunk-DYVZHQvW.js} +1 -1
  48. package/dist/packages/playground/browser/{chunk-OWSRr_rS.js → chunk-DYyPC2oE.js} +1 -1
  49. package/dist/packages/playground/browser/{chunk-BGrPMh-Q.js → chunk-DhQakfe5.js} +1 -1
  50. package/dist/packages/playground/browser/{chunk-Bb34YjCX.js → chunk-FZuwRWVL.js} +1 -1
  51. package/dist/packages/playground/browser/{chunk-Cxq4lcyl.js → chunk-x-oQTX69.js} +1 -1
  52. package/dist/packages/playground/browser/{chunk-K_6Vunnz.js → chunk-xkhVqkfX.js} +1 -1
  53. package/dist/packages/playground/browser/index.html +1 -1
  54. package/dist/packages/playground/browser/main-UNDFLKYI.js +889 -0
  55. package/package.json +3 -1
  56. package/packages/angular-renderer/CHANGELOG.md +22 -0
  57. package/packages/angular-renderer/package.json +9 -4
  58. package/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.html +79 -14
  59. package/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.scss +55 -9
  60. package/packages/angular-renderer/src/components/primitives/breadcrumbs/breadcrumbs.component.ts +82 -22
  61. package/packages/angular-renderer/src/components/primitives/pagination/pagination.component.html +95 -0
  62. package/packages/angular-renderer/src/components/primitives/pagination/pagination.component.scss +109 -0
  63. package/packages/angular-renderer/src/components/primitives/pagination/pagination.component.ts +275 -0
  64. package/packages/angular-renderer/src/components/primitives/stepper/stepper.component.html +68 -0
  65. package/packages/angular-renderer/src/components/primitives/stepper/stepper.component.scss +167 -0
  66. package/packages/angular-renderer/src/components/primitives/stepper/stepper.component.ts +325 -0
  67. package/packages/angular-renderer/src/components/primitives/tabs/tabs.component.html +56 -24
  68. package/packages/angular-renderer/src/components/primitives/tabs/tabs.component.scss +115 -17
  69. package/packages/angular-renderer/src/components/primitives/tabs/tabs.component.ts +134 -42
  70. package/packages/angular-renderer/src/index.ts +5 -0
  71. package/packages/angular-renderer/src/lib/overlay/overlay-ref.ts +298 -0
  72. package/packages/angular-renderer/src/lib/overlay/overlay.models.ts +59 -0
  73. package/packages/angular-renderer/src/lib/overlay/overlay.service.ts +227 -0
  74. package/packages/angular-renderer/src/lib/primitives.provider.ts +5 -0
  75. package/packages/angular-renderer/src/styles/overlay.scss +117 -0
  76. package/packages/cli/CHANGELOG.md +8 -0
  77. package/packages/cli/package.json +2 -2
  78. package/packages/core/CHANGELOG.md +8 -0
  79. package/packages/core/package.json +1 -1
  80. package/packages/design-tokens/CHANGELOG.md +8 -0
  81. package/packages/design-tokens/package.json +1 -1
  82. package/packages/devtools/CHANGELOG.md +8 -0
  83. package/packages/devtools/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/deps___vitest_vm__/_metadata.json +3 -3
  84. package/packages/devtools/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  85. package/packages/devtools/package.json +3 -3
  86. package/packages/playground/CHANGELOG.md +8 -0
  87. package/packages/playground/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/deps___vitest_vm__/_metadata.json +3 -3
  88. package/packages/playground/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  89. package/packages/playground/package.json +3 -3
  90. package/dist/packages/playground/browser/main-ZTUYGW6H.js +0 -748
@@ -0,0 +1,325 @@
1
+ import {
2
+ Component,
3
+ input,
4
+ output,
5
+ ChangeDetectionStrategy,
6
+ computed,
7
+ ViewEncapsulation,
8
+ inject,
9
+ ElementRef,
10
+ viewChildren,
11
+ viewChild,
12
+ ViewContainerRef,
13
+ PLATFORM_ID,
14
+ } from '@angular/core';
15
+ import { isPlatformBrowser } from '@angular/common';
16
+ import { InteractionContract } from '@origostudio/core';
17
+ import {
18
+ OrigoAdapter,
19
+ ContainerComponent as IContainerComponent,
20
+ coerceContractProps,
21
+ } from '../../../adapters/web/adapter';
22
+ import { WebExperienceAdapterService } from '../../../adapters/web/experience-adapter.service';
23
+
24
+ export interface StepItem {
25
+ key: string;
26
+ label: string;
27
+ description?: string;
28
+ icon?: string;
29
+ optional?: boolean;
30
+ disabled?: boolean;
31
+ completed?: boolean;
32
+ }
33
+
34
+ export interface StepChangeEvent {
35
+ activeStep: string;
36
+ previousStep?: string;
37
+ index: number;
38
+ }
39
+
40
+ export interface StepperProps {
41
+ steps?: Array<StepItem>;
42
+ value?: string;
43
+ linear?: boolean;
44
+ readonly?: boolean;
45
+ orientation?: 'horizontal' | 'vertical';
46
+ completedSteps?: Array<string>;
47
+ disabled?: boolean;
48
+ permissions?: Record<string, string>;
49
+ rules?: Record<string, unknown>;
50
+ metadata?: Record<string, unknown>;
51
+ 'aria-label'?: string;
52
+ 'aria-describedby'?: string;
53
+ }
54
+
55
+ export const StepperContractSchema: Record<
56
+ keyof StepperProps,
57
+ 'string' | 'number' | 'boolean' | 'array' | 'object'
58
+ > = {
59
+ steps: 'array',
60
+ value: 'string',
61
+ linear: 'boolean',
62
+ readonly: 'boolean',
63
+ orientation: 'string',
64
+ completedSteps: 'array',
65
+ disabled: 'boolean',
66
+ permissions: 'object',
67
+ rules: 'object',
68
+ metadata: 'object',
69
+ 'aria-label': 'string',
70
+ 'aria-describedby': 'string',
71
+ };
72
+
73
+ @Component({
74
+ selector: 'origo-stepper',
75
+ standalone: true,
76
+ templateUrl: './stepper.component.html',
77
+ styleUrls: ['./stepper.component.scss'],
78
+ changeDetection: ChangeDetectionStrategy.OnPush,
79
+ encapsulation: ViewEncapsulation.ShadowDom,
80
+ host: {
81
+ '[class.origo-stepper]': 'true',
82
+ '[class.origo-stepper--vertical]': "orientation() === 'vertical'",
83
+ '[attr.data-testid]': 'contract().id',
84
+ },
85
+ })
86
+ export class StepperComponent implements OrigoAdapter<StepperProps>, IContainerComponent {
87
+ static readonly contractSchema = StepperContractSchema;
88
+ static readonly strictContract = false;
89
+
90
+ contract = input.required<InteractionContract<StepperProps>>();
91
+ vc = viewChild.required('vc', { read: ViewContainerRef });
92
+
93
+ stepButtons = viewChildren<ElementRef<HTMLButtonElement>>('stepButton');
94
+
95
+ valueChange = output<string>();
96
+ stepChange = output<StepChangeEvent>();
97
+ next = output<string>();
98
+ previous = output<string>();
99
+ complete = output<void>();
100
+ stepClick = output<StepItem>();
101
+
102
+ private experienceAdapter = inject(WebExperienceAdapterService);
103
+ private platformId = inject(PLATFORM_ID);
104
+
105
+ protected props = computed(() =>
106
+ coerceContractProps<StepperProps>(this.contract().props, StepperContractSchema)
107
+ );
108
+
109
+ computedAriaLabel = computed(() => {
110
+ const label = this.props()['aria-label'];
111
+ return label !== undefined && label !== null ? String(label) : 'Stepper';
112
+ });
113
+
114
+ computedAriaDescribedBy = computed(() => {
115
+ const desc = this.props()['aria-describedby'];
116
+ return desc !== undefined && desc !== null ? String(desc) : undefined;
117
+ });
118
+
119
+ orientation = computed<'horizontal' | 'vertical'>(() => {
120
+ return this.props().orientation === 'vertical' ? 'vertical' : 'horizontal';
121
+ });
122
+
123
+ linear = computed<boolean>(() => {
124
+ return !!this.props().linear;
125
+ });
126
+
127
+ readonly = computed<boolean>(() => {
128
+ return !!this.props().readonly;
129
+ });
130
+
131
+ computedDisabled = computed<boolean>(() => {
132
+ return !!this.props().disabled;
133
+ });
134
+
135
+ computedSteps = computed<StepItem[]>(() => {
136
+ const rawSteps = this.props().steps;
137
+ if (!Array.isArray(rawSteps)) return [];
138
+
139
+ return rawSteps
140
+ .filter(s => s != null && s.key != null && s.label != null)
141
+ .map(s => ({
142
+ key: String(s.key),
143
+ label: String(s.label),
144
+ description: s.description ? String(s.description) : undefined,
145
+ icon: s.icon ? String(s.icon) : undefined,
146
+ optional: !!s.optional,
147
+ disabled: !!s.disabled,
148
+ completed: !!s.completed,
149
+ }));
150
+ });
151
+
152
+ activeStepKey = computed<string>(() => {
153
+ const val = this.props().value;
154
+ if (val && typeof val === 'string') return val;
155
+
156
+ const steps = this.computedSteps();
157
+ return steps.length > 0 ? steps[0].key : '';
158
+ });
159
+
160
+ activeStepIndex = computed<number>(() => {
161
+ const key = this.activeStepKey();
162
+ const steps = this.computedSteps();
163
+ const index = steps.findIndex(s => s.key === key);
164
+ return index >= 0 ? index : 0;
165
+ });
166
+
167
+ completedStepKeys = computed<Set<string>>(() => {
168
+ const set = new Set<string>();
169
+ const rawCompleted = this.props().completedSteps;
170
+ if (Array.isArray(rawCompleted)) {
171
+ for (const k of rawCompleted) {
172
+ if (k != null) set.add(String(k));
173
+ }
174
+ }
175
+ for (const step of this.computedSteps()) {
176
+ if (step.completed) {
177
+ set.add(step.key);
178
+ }
179
+ }
180
+ return set;
181
+ });
182
+
183
+ isStepCompleted(step: StepItem): boolean {
184
+ return this.completedStepKeys().has(step.key);
185
+ }
186
+
187
+ isStepActive(index: number): boolean {
188
+ return index === this.activeStepIndex();
189
+ }
190
+
191
+ isStepDisabled(step: StepItem, index: number): boolean {
192
+ if (this.computedDisabled() || this.readonly()) return true;
193
+ if (step.disabled) return true;
194
+
195
+ if (!this.linear()) return false;
196
+
197
+ // In linear mode, step at index is enabled if:
198
+ // 1) index <= activeStepIndex
199
+ // OR 2) all preceding steps 0..index-1 are completed
200
+ if (index <= this.activeStepIndex()) return false;
201
+
202
+ const steps = this.computedSteps();
203
+ for (let i = 0; i < index; i++) {
204
+ if (!this.isStepCompleted(steps[i])) {
205
+ return true;
206
+ }
207
+ }
208
+
209
+ return false;
210
+ }
211
+
212
+ onStepClick(step: StepItem, index: number) {
213
+ if (this.isStepDisabled(step, index)) return;
214
+
215
+ const previousStep = this.activeStepKey();
216
+ if (previousStep === step.key) {
217
+ this.stepClick.emit(step);
218
+ return;
219
+ }
220
+
221
+ this.experienceAdapter.updateState(this.contract().id, 'value', step.key);
222
+ this.experienceAdapter.updateState(this.contract().id, 'activeStep', step.key);
223
+
224
+ const changeEvent: StepChangeEvent = {
225
+ activeStep: step.key,
226
+ previousStep,
227
+ index,
228
+ };
229
+
230
+ const contractId = this.contract().id;
231
+ if (contractId) {
232
+ this.experienceAdapter.dispatchCapability(contractId, 'stepChange', changeEvent);
233
+ this.experienceAdapter.dispatchCapability(contractId, 'valueChange', step.key);
234
+ this.experienceAdapter.dispatchCapability(contractId, 'stepClick', step);
235
+ }
236
+
237
+ this.valueChange.emit(step.key);
238
+ this.stepChange.emit(changeEvent);
239
+ this.stepClick.emit(step);
240
+ }
241
+
242
+ goNext() {
243
+ const steps = this.computedSteps();
244
+ if (steps.length === 0) return;
245
+ const currIndex = this.activeStepIndex();
246
+ if (currIndex < steps.length - 1) {
247
+ const nextStep = steps[currIndex + 1];
248
+ this.onStepClick(nextStep, currIndex + 1);
249
+ this.next.emit(nextStep.key);
250
+ } else {
251
+ this.complete.emit();
252
+ const contractId = this.contract().id;
253
+ if (contractId) {
254
+ this.experienceAdapter.dispatchCapability(contractId, 'complete', undefined);
255
+ }
256
+ }
257
+ }
258
+
259
+ goPrevious() {
260
+ const steps = this.computedSteps();
261
+ const currIndex = this.activeStepIndex();
262
+ if (currIndex > 0) {
263
+ const prevStep = steps[currIndex - 1];
264
+ this.onStepClick(prevStep, currIndex - 1);
265
+ this.previous.emit(prevStep.key);
266
+ }
267
+ }
268
+
269
+ onKeyDown(event: KeyboardEvent, index: number) {
270
+ const steps = this.computedSteps();
271
+ if (steps.length === 0) return;
272
+
273
+ let nextIndex = index;
274
+ const isVertical = this.orientation() === 'vertical';
275
+
276
+ const isRtl =
277
+ isPlatformBrowser(this.platformId) &&
278
+ typeof window !== 'undefined' &&
279
+ event.target instanceof Element
280
+ ? window.getComputedStyle(event.target).direction === 'rtl'
281
+ : false;
282
+
283
+ if (!isVertical) {
284
+ if (event.key === 'ArrowRight') {
285
+ nextIndex = isRtl ? index - 1 : index + 1;
286
+ event.preventDefault();
287
+ } else if (event.key === 'ArrowLeft') {
288
+ nextIndex = isRtl ? index + 1 : index - 1;
289
+ event.preventDefault();
290
+ } else if (event.key === 'Home') {
291
+ nextIndex = 0;
292
+ event.preventDefault();
293
+ } else if (event.key === 'End') {
294
+ nextIndex = steps.length - 1;
295
+ event.preventDefault();
296
+ }
297
+ } else {
298
+ if (event.key === 'ArrowDown') {
299
+ nextIndex = index + 1;
300
+ event.preventDefault();
301
+ } else if (event.key === 'ArrowUp') {
302
+ nextIndex = index - 1;
303
+ event.preventDefault();
304
+ } else if (event.key === 'Home') {
305
+ nextIndex = 0;
306
+ event.preventDefault();
307
+ } else if (event.key === 'End') {
308
+ nextIndex = steps.length - 1;
309
+ event.preventDefault();
310
+ }
311
+ }
312
+
313
+ if (nextIndex < 0) nextIndex = steps.length - 1;
314
+ if (nextIndex >= steps.length) nextIndex = 0;
315
+
316
+ if (nextIndex !== index) {
317
+ setTimeout(() => {
318
+ const buttons = this.stepButtons();
319
+ if (buttons && buttons[nextIndex]) {
320
+ buttons[nextIndex].nativeElement.focus();
321
+ }
322
+ });
323
+ }
324
+ }
325
+ }
@@ -1,27 +1,59 @@
1
1
  <div
2
- class="origo-tabs__list"
3
- role="tablist"
4
- [attr.aria-label]="computedAriaLabel()"
5
- [attr.aria-describedby]="computedAriaDescribedBy()"
2
+ class="origo-tabs__container"
3
+ [class.origo-tabs--vertical]="computedOrientation() === 'vertical'"
4
+ [class.origo-tabs--scrollable]="computedScrollable()"
6
5
  >
7
- @for (tab of computedTabs(); track tab.key; let i = $index) {
8
- <button
9
- #tabButton
10
- type="button"
11
- role="tab"
12
- class="origo-tabs__tab"
13
- [class.origo-tabs__tab--active]="computedActiveTab() === tab.key"
14
- [attr.aria-selected]="computedActiveTab() === tab.key"
15
- [attr.aria-controls]="'tabpanel-' + tab.key"
16
- [attr.id]="'tab-' + tab.key"
17
- [attr.tabindex]="
18
- computedActiveTab() === tab.key || (computedActiveTab() == null && i === 0) ? 0 : -1
19
- "
20
- [disabled]="tab.disabled"
21
- (click)="onTabClick(tab)"
22
- (keydown)="onKeyDown($event, i)"
23
- >
24
- <span class="origo-tabs__label" [innerHTML]="tab.label"></span>
25
- </button>
26
- }
6
+ <div
7
+ class="origo-tabs__list"
8
+ role="tablist"
9
+ [attr.aria-label]="computedAriaLabel()"
10
+ [attr.aria-describedby]="computedAriaDescribedBy()"
11
+ [attr.aria-orientation]="computedOrientation()"
12
+ >
13
+ @for (tab of computedTabs(); track tab.key; let i = $index) {
14
+ <button
15
+ #tabButton
16
+ type="button"
17
+ role="tab"
18
+ class="origo-tabs__tab"
19
+ [class.origo-tabs__tab--active]="computedActiveTab() === tab.key"
20
+ [attr.aria-selected]="computedActiveTab() === tab.key"
21
+ [attr.aria-controls]="'tabpanel-' + tab.key"
22
+ [attr.id]="'tab-' + tab.key"
23
+ [attr.tabindex]="
24
+ computedActiveTab() === tab.key || (computedActiveTab() == null && i === 0) ? 0 : -1
25
+ "
26
+ [disabled]="tab.disabled"
27
+ (click)="onTabClick(tab)"
28
+ (keydown)="onKeyDown($event, i)"
29
+ >
30
+ @if (tab.icon) {
31
+ <span class="origo-tabs__icon" aria-hidden="true">{{ tab.icon }}</span>
32
+ }
33
+ <span class="origo-tabs__label" [innerHTML]="tab.label"></span>
34
+ @if (tab.badge) {
35
+ <span class="origo-tabs__badge">{{ tab.badge }}</span>
36
+ }
37
+ @if (tab.closable) {
38
+ <button
39
+ type="button"
40
+ class="origo-tabs__close"
41
+ [attr.aria-label]="'Close ' + tab.label"
42
+ (click)="onTabClose($event, tab)"
43
+ >
44
+ ×
45
+ </button>
46
+ }
47
+ </button>
48
+ }
49
+ </div>
50
+
51
+ <div
52
+ class="origo-tabs__panels"
53
+ role="region"
54
+ [attr.id]="computedActiveTab() ? 'tabpanel-' + computedActiveTab() : null"
55
+ >
56
+ <ng-container #vc></ng-container>
57
+ <ng-content></ng-content>
58
+ </div>
27
59
  </div>
@@ -1,49 +1,147 @@
1
1
  :host {
2
2
  display: block;
3
- width: 100%;
3
+ box-sizing: border-box;
4
+ inline-size: 100%;
5
+
6
+ *,
7
+ *::before,
8
+ *::after {
9
+ box-sizing: inherit;
10
+ }
11
+ }
12
+
13
+ :host([hidden]) {
14
+ display: none !important;
15
+ }
16
+
17
+ .origo-tabs__container {
18
+ display: flex;
19
+ flex-direction: column;
20
+ inline-size: 100%;
21
+
22
+ &.origo-tabs--vertical {
23
+ flex-direction: row;
24
+ align-items: flex-start;
25
+
26
+ .origo-tabs__list {
27
+ flex-direction: column;
28
+ border-block-end: none;
29
+ border-inline-end: var(--origo-border-width-default) solid var(--origo-color-border-default);
30
+ }
31
+
32
+ .origo-tabs__tab {
33
+ inline-size: 100%;
34
+ justify-content: flex-start;
35
+ border-block-end: none;
36
+ border-inline-end: var(--origo-border-width-thick) solid transparent;
37
+
38
+ &.origo-tabs__tab--active {
39
+ border-block-end-color: transparent;
40
+ border-inline-end-color: var(--origo-color-surface-primary);
41
+ }
42
+ }
43
+ }
44
+
45
+ &.origo-tabs--scrollable .origo-tabs__list {
46
+ overflow-x: auto;
47
+ scrollbar-width: thin;
48
+ }
4
49
  }
5
50
 
6
51
  .origo-tabs__list {
7
52
  display: flex;
8
- border-block-end: 1px solid var(--color-border, #e0e0e0);
53
+ border-block-end: var(--origo-border-width-default) solid var(--origo-color-border-default);
9
54
  margin: 0;
10
55
  padding: 0;
11
- gap: var(--spacing-sm, 8px);
56
+ gap: var(--origo-spacing-sm);
57
+ background-color: transparent;
12
58
  }
13
59
 
14
60
  .origo-tabs__tab {
61
+ display: inline-flex;
62
+ align-items: center;
63
+ gap: var(--origo-spacing-xs);
15
64
  background: none;
16
65
  border: none;
17
- border-block-end: 2px solid transparent;
18
- padding-inline: var(--spacing-md, 16px);
19
- padding-block: var(--spacing-sm, 12px);
66
+ border-block-end: var(--origo-border-width-thick) solid transparent;
67
+ padding-inline: var(--origo-spacing-md);
68
+ padding-block: var(--origo-spacing-sm);
20
69
  font-family: inherit;
21
- font-size: 14px;
22
- color: var(--color-text-secondary, #666666);
70
+ font-size: var(--origo-typography-button-font-size);
71
+ color: var(--origo-color-text-muted);
23
72
  cursor: pointer;
24
- transition: all 0.2s ease;
73
+ transition: all var(--origo-duration-fast) ease;
25
74
  white-space: nowrap;
26
75
  outline: none;
27
76
 
28
77
  &:hover:not(:disabled) {
29
- color: var(--color-text, #333333);
30
- background-color: var(--color-surface-hover, #f5f5f5);
78
+ color: var(--origo-color-text-primary);
79
+ background-color: var(--origo-color-surface-subtle);
31
80
  }
32
81
 
33
82
  &:focus-visible {
34
- background-color: var(--color-surface-hover, #f5f5f5);
35
- border-radius: 4px 4px 0 0;
36
- box-shadow: inset 0 0 0 2px var(--color-primary, #1976d2);
83
+ background-color: var(--origo-color-surface-subtle);
84
+ border-radius: var(--origo-radius-sm) var(--origo-radius-sm) 0 0;
85
+ outline: var(--origo-border-width-thick) solid var(--origo-color-focus);
86
+ outline-offset: -2px;
37
87
  }
38
88
 
39
89
  &.origo-tabs__tab--active {
40
- color: var(--color-primary, #1976d2);
41
- border-block-end-color: var(--color-primary, #1976d2);
90
+ color: var(--origo-color-surface-primary);
91
+ border-block-end-color: var(--origo-color-surface-primary);
42
92
  font-weight: 500;
43
93
  }
44
94
 
45
95
  &:disabled {
46
96
  cursor: not-allowed;
47
- opacity: 0.5;
97
+ opacity: var(--origo-opacity-disabled);
98
+ color: var(--origo-color-text-disabled);
99
+ }
100
+ }
101
+
102
+ .origo-tabs__icon {
103
+ display: inline-flex;
104
+ align-items: center;
105
+ }
106
+
107
+ .origo-tabs__badge {
108
+ display: inline-flex;
109
+ align-items: center;
110
+ justify-content: center;
111
+ padding-inline: var(--origo-spacing-xs);
112
+ padding-block: var(--origo-spacing-base-1);
113
+ border-radius: var(--origo-radius-full);
114
+ background-color: var(--origo-color-surface-subtle);
115
+ color: var(--origo-color-text-primary);
116
+ font-size: var(--origo-typography-caption-font-size);
117
+ font-weight: 600;
118
+ }
119
+
120
+ .origo-tabs__close {
121
+ display: inline-flex;
122
+ align-items: center;
123
+ justify-content: center;
124
+ background: none;
125
+ border: none;
126
+ padding: 0;
127
+ margin-inline-start: var(--origo-spacing-xs);
128
+ cursor: pointer;
129
+ color: var(--origo-color-text-muted);
130
+ font-size: var(--origo-typography-button-font-size);
131
+ line-height: 1;
132
+ border-radius: var(--origo-radius-sm);
133
+
134
+ &:hover {
135
+ color: var(--origo-color-text-danger);
136
+ background-color: var(--origo-color-surface-subtle);
137
+ }
138
+
139
+ &:focus-visible {
140
+ outline: var(--origo-border-width-thick) solid var(--origo-color-focus);
48
141
  }
49
142
  }
143
+
144
+ .origo-tabs__panels {
145
+ display: block;
146
+ padding-block: var(--origo-spacing-sm);
147
+ }