@raintonic/formaui 0.2.0 → 0.2.1

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 (99) hide show
  1. package/CHANGELOG.md +7 -7
  2. package/README.md +145 -145
  3. package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs.map +1 -1
  4. package/fesm2022/raintonic-formaui-cdk-form-field.mjs.map +1 -1
  5. package/fesm2022/raintonic-formaui-cdk-overlay.mjs +0 -26
  6. package/fesm2022/raintonic-formaui-cdk-overlay.mjs.map +1 -1
  7. package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs +2 -2
  8. package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs.map +1 -1
  9. package/fesm2022/raintonic-formaui-components-accordion.mjs +2 -2
  10. package/fesm2022/raintonic-formaui-components-accordion.mjs.map +1 -1
  11. package/fesm2022/raintonic-formaui-components-alert.mjs.map +1 -1
  12. package/fesm2022/raintonic-formaui-components-autocomplete.mjs.map +1 -1
  13. package/fesm2022/raintonic-formaui-components-avatar.mjs.map +1 -1
  14. package/fesm2022/raintonic-formaui-components-badge.mjs +2 -2
  15. package/fesm2022/raintonic-formaui-components-badge.mjs.map +1 -1
  16. package/fesm2022/raintonic-formaui-components-big-menu.mjs +2 -2
  17. package/fesm2022/raintonic-formaui-components-big-menu.mjs.map +1 -1
  18. package/fesm2022/raintonic-formaui-components-breadcrumb.mjs +4 -4
  19. package/fesm2022/raintonic-formaui-components-breadcrumb.mjs.map +1 -1
  20. package/fesm2022/raintonic-formaui-components-button-group.mjs.map +1 -1
  21. package/fesm2022/raintonic-formaui-components-button.mjs.map +1 -1
  22. package/fesm2022/raintonic-formaui-components-card.mjs.map +1 -1
  23. package/fesm2022/raintonic-formaui-components-checkbox.mjs +2 -2
  24. package/fesm2022/raintonic-formaui-components-checkbox.mjs.map +1 -1
  25. package/fesm2022/raintonic-formaui-components-data-table.mjs.map +1 -1
  26. package/fesm2022/raintonic-formaui-components-date-picker.mjs +4 -4
  27. package/fesm2022/raintonic-formaui-components-date-picker.mjs.map +1 -1
  28. package/fesm2022/raintonic-formaui-components-divider.mjs +2 -2
  29. package/fesm2022/raintonic-formaui-components-divider.mjs.map +1 -1
  30. package/fesm2022/raintonic-formaui-components-drawer.mjs +2 -2
  31. package/fesm2022/raintonic-formaui-components-drawer.mjs.map +1 -1
  32. package/fesm2022/raintonic-formaui-components-dynamic-form.mjs.map +1 -1
  33. package/fesm2022/raintonic-formaui-components-empty-state.mjs +2 -2
  34. package/fesm2022/raintonic-formaui-components-empty-state.mjs.map +1 -1
  35. package/fesm2022/raintonic-formaui-components-file-upload.mjs +2 -2
  36. package/fesm2022/raintonic-formaui-components-file-upload.mjs.map +1 -1
  37. package/fesm2022/raintonic-formaui-components-form-field.mjs.map +1 -1
  38. package/fesm2022/raintonic-formaui-components-icon.mjs.map +1 -1
  39. package/fesm2022/raintonic-formaui-components-input.mjs.map +1 -1
  40. package/fesm2022/raintonic-formaui-components-list.mjs +4 -4
  41. package/fesm2022/raintonic-formaui-components-list.mjs.map +1 -1
  42. package/fesm2022/raintonic-formaui-components-menu.mjs.map +1 -1
  43. package/fesm2022/raintonic-formaui-components-number-input.mjs +2 -2
  44. package/fesm2022/raintonic-formaui-components-number-input.mjs.map +1 -1
  45. package/fesm2022/raintonic-formaui-components-paginator.mjs +2 -2
  46. package/fesm2022/raintonic-formaui-components-paginator.mjs.map +1 -1
  47. package/fesm2022/raintonic-formaui-components-password-input.mjs +2 -2
  48. package/fesm2022/raintonic-formaui-components-password-input.mjs.map +1 -1
  49. package/fesm2022/raintonic-formaui-components-popover.mjs +2 -2
  50. package/fesm2022/raintonic-formaui-components-popover.mjs.map +1 -1
  51. package/fesm2022/raintonic-formaui-components-progressbar.mjs.map +1 -1
  52. package/fesm2022/raintonic-formaui-components-radio.mjs +4 -4
  53. package/fesm2022/raintonic-formaui-components-radio.mjs.map +1 -1
  54. package/fesm2022/raintonic-formaui-components-select.mjs +24 -24
  55. package/fesm2022/raintonic-formaui-components-select.mjs.map +1 -1
  56. package/fesm2022/raintonic-formaui-components-side-panel.mjs +2 -2
  57. package/fesm2022/raintonic-formaui-components-side-panel.mjs.map +1 -1
  58. package/fesm2022/raintonic-formaui-components-sidebar.mjs +2 -2
  59. package/fesm2022/raintonic-formaui-components-sidebar.mjs.map +1 -1
  60. package/fesm2022/raintonic-formaui-components-skeleton.mjs +2 -2
  61. package/fesm2022/raintonic-formaui-components-skeleton.mjs.map +1 -1
  62. package/fesm2022/raintonic-formaui-components-slider.mjs +2 -2
  63. package/fesm2022/raintonic-formaui-components-slider.mjs.map +1 -1
  64. package/fesm2022/raintonic-formaui-components-spinner.mjs +2 -2
  65. package/fesm2022/raintonic-formaui-components-spinner.mjs.map +1 -1
  66. package/fesm2022/raintonic-formaui-components-stepper.mjs +2 -2
  67. package/fesm2022/raintonic-formaui-components-stepper.mjs.map +1 -1
  68. package/fesm2022/raintonic-formaui-components-tab.mjs +10 -10
  69. package/fesm2022/raintonic-formaui-components-tab.mjs.map +1 -1
  70. package/fesm2022/raintonic-formaui-components-tag.mjs +2 -2
  71. package/fesm2022/raintonic-formaui-components-tag.mjs.map +1 -1
  72. package/fesm2022/raintonic-formaui-components-time-picker.mjs +4 -4
  73. package/fesm2022/raintonic-formaui-components-time-picker.mjs.map +1 -1
  74. package/fesm2022/raintonic-formaui-components-toggle.mjs.map +1 -1
  75. package/fesm2022/raintonic-formaui-components-toolbar.mjs.map +1 -1
  76. package/fesm2022/raintonic-formaui-components-tooltip.mjs.map +1 -1
  77. package/fesm2022/raintonic-formaui-components-tree-select.mjs +2 -2
  78. package/fesm2022/raintonic-formaui-components-tree-select.mjs.map +1 -1
  79. package/fesm2022/raintonic-formaui-components-tree-table.mjs +2 -2
  80. package/fesm2022/raintonic-formaui-components-tree-table.mjs.map +1 -1
  81. package/fesm2022/raintonic-formaui-components-tree.mjs +4 -4
  82. package/fesm2022/raintonic-formaui-components-tree.mjs.map +1 -1
  83. package/fesm2022/raintonic-formaui-core.mjs.map +1 -1
  84. package/fesm2022/raintonic-formaui-services-dialog.mjs +36 -36
  85. package/fesm2022/raintonic-formaui-services-dialog.mjs.map +1 -1
  86. package/fesm2022/raintonic-formaui-services-notification.mjs +2 -2
  87. package/fesm2022/raintonic-formaui-services-notification.mjs.map +1 -1
  88. package/fesm2022/raintonic-formaui-services-theme.mjs.map +1 -1
  89. package/fesm2022/raintonic-formaui-test-utils.mjs.map +1 -1
  90. package/fesm2022/raintonic-formaui.mjs.map +1 -1
  91. package/llms-full.txt +3 -97
  92. package/llms.txt +3 -3
  93. package/package.json +1 -1
  94. package/styles/index.scss +3 -3
  95. package/styles/partials/components/_button.scss +367 -0
  96. package/styles/partials/components/_dialog.scss +180 -0
  97. package/styles/partials/components/_overlay.scss +87 -0
  98. package/types/raintonic-formaui-cdk-overlay.d.ts +0 -1
  99. package/types/raintonic-formaui-cdk-overlay.d.ts.map +1 -1
package/llms-full.txt CHANGED
@@ -178,7 +178,7 @@ No public inputs or outputs.
178
178
 
179
179
  ## button
180
180
 
181
- A versatile button directive for triggering user actions. Supports multiple visual variants, sizes, loading states, and icon-only mode. Works on both `<button>` and `<a>` elements.
181
+ A versatile button directive that can be applied to both `<button>` and `<a>` elements. Follows Carbon Design System patterns with full accessibility support.
182
182
 
183
183
  - **Import**: `import { FuiButtonDirective } from 'formaui/components/button'`
184
184
  - **Selector**: `button[fuiButton], a[fuiButton]`
@@ -196,40 +196,6 @@ A versatile button directive for triggering user actions. Supports multiple visu
196
196
  | aria-label | string | null | null | no |
197
197
  | type | ButtonType | 'button' | no |
198
198
 
199
- ### Usage
200
-
201
- ```html
202
- <!-- Primary button -->
203
- <button fuiButton>Click me</button>
204
-
205
- <!-- Button with variant and size -->
206
- <button fuiButton variant="secondary" size="lg">Large Secondary</button>
207
-
208
- <!-- Danger button for destructive actions -->
209
- <button fuiButton variant="danger">Delete</button>
210
-
211
- <!-- Loading state -->
212
- <button fuiButton [loading]="isLoading">Save</button>
213
-
214
- <!-- Icon-only button -->
215
- <button fuiButton variant="icon" iconOnly aria-label="Settings">
216
- <fui-icon name="settings" />
217
- </button>
218
-
219
- <!-- Link button -->
220
- <a fuiButton variant="link" href="/dashboard">Go to Dashboard</a>
221
-
222
- <!-- Full-width button -->
223
- <button fuiButton fullWidth>Full Width Action</button>
224
- ```
225
-
226
- ### Notes
227
-
228
- - Use `variant="danger"` only for destructive actions (delete, remove, etc.)
229
- - Always provide `aria-label` on icon-only buttons for accessibility
230
- - The `loading` state automatically disables the button and shows a spinner
231
- - On `<a>` elements, the `disabled` state removes the `href` attribute
232
-
233
199
  ---
234
200
 
235
201
  ## button-group
@@ -477,7 +443,7 @@ A file upload component with drag-and-drop support, file previews, and validatio
477
443
 
478
444
  ## form-field
479
445
 
480
- A wrapper component that provides consistent layout, labeling, validation, and accessibility for form controls. Works with any component implementing the `FuiFormFieldControl` interface (select, input, date-picker, etc.).
446
+ A form field wrapper component that provides consistent styling and behavior for form controls. Follows Angular Material patterns with Carbon Design System styling.
481
447
 
482
448
  - **Import**: `import { FuiFormFieldComponent } from 'formaui/components/form-field'`
483
449
  - **Selector**: `fui-form-field`
@@ -488,33 +454,6 @@ A wrapper component that provides consistent layout, labeling, validation, and a
488
454
  |------|------|---------|----------|
489
455
  | appearance | FormFieldAppearance | 'outline' | no |
490
456
 
491
- ### Usage
492
-
493
- ```html
494
- <!-- Basic form field with input -->
495
- <fui-form-field>
496
- <fui-label>Email</fui-label>
497
- <input fuiInput type="email" [formControl]="emailControl" />
498
- <fui-hint>We'll never share your email</fui-hint>
499
- <fui-error>Please enter a valid email</fui-error>
500
- </fui-form-field>
501
-
502
- <!-- Form field with prefix and suffix -->
503
- <fui-form-field>
504
- <fui-label>Price</fui-label>
505
- <span fuiPrefix>$</span>
506
- <input fuiInput type="number" [formControl]="priceControl" />
507
- <span fuiSuffix>.00</span>
508
- </fui-form-field>
509
- ```
510
-
511
- ### Notes
512
-
513
- - `fui-error` is shown only when the form control is in an error state
514
- - `fui-hint` is hidden when an error is displayed
515
- - Use `fuiPrefix` and `fuiSuffix` directives on any element for adornments
516
- - The form field automatically associates the label with the control for accessibility
517
-
518
457
  ### Sub-components
519
458
 
520
459
  #### FuiErrorComponent
@@ -855,7 +794,7 @@ A progress bar component compatible with Angular Material's mat-progress-bar int
855
794
 
856
795
  ## select
857
796
 
858
- A dropdown select component for single or multiple selection. Designed to work inside `fui-form-field` with full Reactive Forms support, keyboard navigation, and type-ahead search.
797
+ A select component designed to work seamlessly with fui-form-field. Similar to Angular Material's mat-select integration with mat-form-field. Provides full Reactive Forms support with validation and error handling.
859
798
 
860
799
  - **Import**: `import { FuiSelectComponent } from 'formaui/components/select'`
861
800
  - **Selector**: `fui-select`
@@ -874,39 +813,6 @@ A dropdown select component for single or multiple selection. Designed to work i
874
813
  | selectionChange | FuiSelectChange |
875
814
  | openedChange | boolean |
876
815
 
877
- ### Usage
878
-
879
- ```html
880
- <!-- Basic select inside form-field -->
881
- <fui-form-field>
882
- <fui-label>Country</fui-label>
883
- <fui-select placeholder="Choose a country" [formControl]="countryControl">
884
- <fui-option value="us">United States</fui-option>
885
- <fui-option value="uk">United Kingdom</fui-option>
886
- <fui-option value="de">Germany</fui-option>
887
- </fui-select>
888
- <fui-error>Country is required</fui-error>
889
- </fui-form-field>
890
-
891
- <!-- Multiple selection -->
892
- <fui-form-field>
893
- <fui-label>Tags</fui-label>
894
- <fui-select multiple [formControl]="tagsControl">
895
- <fui-option value="angular">Angular</fui-option>
896
- <fui-option value="react">React</fui-option>
897
- <fui-option value="vue">Vue</fui-option>
898
- </fui-select>
899
- </fui-form-field>
900
- ```
901
-
902
- ### Notes
903
-
904
- - Always wrap in `fui-form-field` for label, error, and hint support
905
- - Options are projected as `<fui-option>` child elements
906
- - Supports keyboard navigation: Arrow keys, Home/End, Enter/Space, Escape
907
- - Type-ahead search: start typing to jump to matching options
908
- - Use `compareWith` input for custom object comparison
909
-
910
816
  ### Sub-components
911
817
 
912
818
  #### FuiOptionComponent
package/llms.txt CHANGED
@@ -15,7 +15,7 @@ npm install formaui
15
15
  - badge: No description available. `import { FuiBadgeComponent } from 'formaui/components/badge'`
16
16
  - big-menu: No description available. `import { FuiBigMenuComponent } from 'formaui/components/big-menu'`
17
17
  - breadcrumb: No description available. `import { FuiBreadcrumbComponent } from 'formaui/components/breadcrumb'`
18
- - button: A versatile button directive for triggering user actions. Supports multiple visual variants, sizes, loading states, and `import { FuiButtonDirective } from 'formaui/components/button'`
18
+ - button: A versatile button directive that can be applied to both `<button>` and `<a>` elements. Follows Carbon Design System pat `import { FuiButtonDirective } from 'formaui/components/button'`
19
19
  - button-group: A container component that groups multiple buttons together, creating a unified visual element with connected borders. F `import { FuiButtonGroupComponent } from 'formaui/components/button-group'`
20
20
  - card: A flexible container component following Carbon Design System patterns. Provides a structured layout with optional heade `import { FuiCardComponent } from 'formaui/components/card'`
21
21
  - checkbox: A checkbox component with full Angular Reactive Forms support. Compatible with Angular Material's mat-checkbox interface `import { FuiCheckboxComponent } from 'formaui/components/checkbox'`
@@ -26,7 +26,7 @@ npm install formaui
26
26
  - dynamic-form: A component that automatically renders forms based on a JSON configuration. It takes a FormGroup and a configuration obj `import { FuiDynamicFormRendererComponent } from 'formaui/components/dynamic-form'`
27
27
  - empty-state: No description available. `import { FuiEmptyStateComponent } from 'formaui/components/empty-state'`
28
28
  - file-upload: A file upload component with drag-and-drop support, file previews, and validation. `import { FuiFileUploadComponent } from 'formaui/components/file-upload'`
29
- - form-field: A wrapper component that provides consistent layout, labeling, validation, and accessibility for form controls. Works wi `import { FuiFormFieldComponent } from 'formaui/components/form-field'`
29
+ - form-field: A form field wrapper component that provides consistent styling and behavior for form controls. Follows Angular Material `import { FuiFormFieldComponent } from 'formaui/components/form-field'`
30
30
  - icon: A wrapper component for Phosphor Icons with consistent sizing and styling. Provides easy access to the complete Phosphor `import { FuiIconComponent } from 'formaui/components/icon'`
31
31
  - input: An input directive that integrates seamlessly with fui-form-field and Angular Forms. Follows Angular Material patterns w `import { FuiInputDirective } from 'formaui/components/input'`
32
32
  - list: No description available. `import { FuiListComponent } from 'formaui/components/list'`
@@ -37,7 +37,7 @@ npm install formaui
37
37
  - popover: Internal popover container component rendered inside the overlay. Provides a styled panel with optional arrow indicator. `import { FuiPopoverComponent } from 'formaui/components/popover'`
38
38
  - progressbar: A progress bar component compatible with Angular Material's mat-progress-bar interface. `import { FuiProgressbarComponent } from 'formaui/components/progressbar'`
39
39
  - radio: No description available. `import { FuiRadioButtonComponent } from 'formaui/components/radio'`
40
- - select: A dropdown select component for single or multiple selection. Designed to work inside `fui-form-field` with full Reactiv `import { FuiSelectComponent } from 'formaui/components/select'`
40
+ - select: A select component designed to work seamlessly with fui-form-field. Similar to Angular Material's mat-select integration `import { FuiSelectComponent } from 'formaui/components/select'`
41
41
  - side-panel: No description available. `import { FuiSidePanelComponent } from 'formaui/components/side-panel'`
42
42
  - sidebar: A flexible sidebar component following Carbon Design System principles. Provides navigation with Angular Material-like A `import { FuiSidebarComponent } from 'formaui/components/sidebar'`
43
43
  - skeleton: No description available. `import { FuiSkeletonComponent } from 'formaui/components/skeleton'`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raintonic/formaui",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "A modern Angular UI component library with theming support",
5
5
  "license": "MIT",
6
6
  "keywords": [
package/styles/index.scss CHANGED
@@ -23,9 +23,9 @@
23
23
  @forward './partials/utilities';
24
24
 
25
25
  // 8. Component global styles
26
- @use '../components/button/button.directive';
27
- @use '../cdk/overlay/overlay';
28
- @use '../services/dialog/dialog';
26
+ @use './partials/components/button';
27
+ @use './partials/components/overlay';
28
+ @use './partials/components/dialog';
29
29
 
30
30
  // Use the modules for this file's styles
31
31
  @use './partials/mixins' as *;
@@ -0,0 +1,367 @@
1
+ // Button component styles aligned with theme tokens
2
+ @use '../constants' as *;
3
+ @use '../mixins' as mixins;
4
+ @use '../motion' as motion;
5
+
6
+ .fui-button {
7
+ // Component tokens with fallbacks
8
+ --fui-button-height: var(--fui-button-height-md);
9
+ --fui-button-font-size: var(--fui-font-size-02);
10
+ --fui-button-border-radius: var(--fui-border-radius-sm);
11
+ --fui-button-padding-x: var(--fui-spacing-05);
12
+ --fui-button-padding-y: var(--fui-spacing-03);
13
+ --fui-button-gap: var(--fui-spacing-03);
14
+ --fui-button-font-weight: var(--fui-font-weight-semibold);
15
+ --fui-button-letter-spacing: var(--fui-letter-spacing-wide);
16
+
17
+ // Default spinner/text foreground used during loading
18
+ @include mixins.fui-button-reset();
19
+ @include motion.fui-motion(all, var(--fui-duration-fast-02));
20
+
21
+ position: relative;
22
+ display: inline-flex;
23
+ align-items: center;
24
+ justify-content: center;
25
+ gap: var(--fui-button-gap);
26
+ overflow: hidden;
27
+
28
+ font-family: var(--fui-font-family-sans);
29
+ font-weight: var(--fui-button-font-weight);
30
+ text-decoration: none;
31
+ text-align: center;
32
+ vertical-align: middle;
33
+ white-space: nowrap;
34
+ user-select: none;
35
+ letter-spacing: var(--fui-button-letter-spacing);
36
+ border-radius: var(--fui-button-border-radius);
37
+ box-sizing: border-box;
38
+ cursor: pointer;
39
+ min-height: var(--fui-button-height);
40
+
41
+ &:focus-visible {
42
+ @include mixins.fui-focus-ring();
43
+ }
44
+
45
+ // Loading spinner
46
+ &__spinner {
47
+ position: absolute;
48
+ top: 50%;
49
+ left: 50%;
50
+ transform: translate(-50%, -50%);
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: center;
54
+ }
55
+
56
+ &__spinner-icon {
57
+ width: var(--fui-icon-size-sm);
58
+ height: var(--fui-icon-size-sm);
59
+ border: 2px solid var(--fui-text-primary);
60
+ border-top-color: transparent;
61
+ border-radius: 50%;
62
+ animation: fui-spin var(--fui-duration-slow-02) linear infinite;
63
+ }
64
+
65
+ // WCAG 2.1 AA: ensure minimum 44x44px touch target for smaller sizes
66
+ // Uses a pseudo-element so visual size remains unchanged
67
+ &::after {
68
+ content: '';
69
+ position: absolute;
70
+ inset: 50% auto auto 50%;
71
+ min-width: 44px;
72
+ min-height: 44px;
73
+ width: 100%;
74
+ height: 100%;
75
+ transform: translate(-50%, -50%);
76
+ }
77
+
78
+ // States
79
+ &--disabled {
80
+ cursor: not-allowed;
81
+ opacity: var(--fui-opacity-disabled);
82
+ }
83
+
84
+ &--loading {
85
+ color: transparent !important;
86
+ cursor: wait;
87
+ }
88
+
89
+ &--full-width {
90
+ width: 100%;
91
+ }
92
+
93
+ // Sizes
94
+ &--sm {
95
+ min-height: var(--fui-button-height-sm);
96
+ padding: calc(var(--fui-spacing-03) - 2px) var(--fui-spacing-03);
97
+ font-size: var(--fui-font-size-01);
98
+
99
+ &.fui-button--icon-only {
100
+ width: var(--fui-button-height-sm);
101
+ padding: calc(var(--fui-spacing-03) - 2px);
102
+ }
103
+
104
+ .fui-icon {
105
+ width: var(--fui-icon-size-sm);
106
+ height: var(--fui-icon-size-sm);
107
+ }
108
+ }
109
+
110
+ &--md {
111
+ min-height: var(--fui-button-height-md);
112
+ padding: calc(var(--fui-spacing-03) + 2px) var(--fui-spacing-05);
113
+ font-size: var(--fui-font-size-02);
114
+
115
+ &.fui-button--icon-only {
116
+ padding: calc(var(--fui-spacing-03) + 2px);
117
+ }
118
+
119
+ .fui-icon {
120
+ width: var(--fui-icon-size-md);
121
+ height: var(--fui-icon-size-md);
122
+ }
123
+ }
124
+
125
+ &--lg {
126
+ min-height: var(--fui-button-height-lg);
127
+ padding: calc(var(--fui-spacing-04) - 2px) var(--fui-spacing-05);
128
+ font-size: var(--fui-font-size-03);
129
+
130
+ &.fui-button--icon-only {
131
+ width: var(--fui-button-height-lg);
132
+ padding: calc(var(--fui-spacing-04) - 2px);
133
+ }
134
+
135
+ .fui-icon {
136
+ width: var(--fui-icon-size-md);
137
+ height: var(--fui-icon-size-md);
138
+ }
139
+ }
140
+
141
+ &--xl {
142
+ min-height: var(--fui-button-height-xl);
143
+ padding: var(--fui-spacing-04) var(--fui-spacing-06);
144
+ font-size: var(--fui-font-size-03);
145
+
146
+ &.fui-button--icon-only {
147
+ width: var(--fui-button-height-xl);
148
+ padding: var(--fui-spacing-04);
149
+ }
150
+
151
+ .fui-icon {
152
+ width: var(--fui-icon-size-md);
153
+ height: var(--fui-icon-size-md);
154
+ }
155
+ }
156
+
157
+ &--2xl {
158
+ min-height: var(--fui-spacing-11);
159
+ padding: var(--fui-spacing-05) var(--fui-spacing-06);
160
+ font-size: var(--fui-font-size-03);
161
+
162
+ &.fui-button--icon-only {
163
+ width: var(--fui-spacing-11);
164
+ padding: var(--fui-spacing-05);
165
+ }
166
+
167
+ .fui-icon {
168
+ width: var(--fui-icon-size-md);
169
+ height: var(--fui-icon-size-md);
170
+ }
171
+ }
172
+
173
+ &--field {
174
+ min-height: var(--fui-input-height); // matches form field height
175
+ padding: calc(var(--fui-spacing-03) + 2px) var(--fui-spacing-04);
176
+ font-size: var(--fui-font-size-02);
177
+
178
+ &.fui-button--icon-only {
179
+ width: var(--fui-input-height);
180
+ padding: calc(var(--fui-spacing-03) + 2px);
181
+ }
182
+ }
183
+
184
+ // Variant and Kind combinations
185
+
186
+ // Primary variant
187
+ &--primary {
188
+ background-color: var(--fui-primary);
189
+ color: var(--fui-primary-text);
190
+ border-color: transparent;
191
+ letter-spacing: var(--fui-letter-spacing-wide);
192
+ box-shadow: var(--fui-shadow-02);
193
+
194
+ &:hover:not(.fui-button--disabled) {
195
+ background-color: var(--fui-primary-hover);
196
+ box-shadow: var(--fui-shadow-03);
197
+ }
198
+
199
+ &:active:not(.fui-button--disabled) {
200
+ background-color: var(--fui-primary-hover);
201
+ box-shadow: none;
202
+ }
203
+
204
+ &.fui-button--disabled {
205
+ background-color: var(--fui-primary);
206
+ }
207
+ }
208
+
209
+ // Secondary variant
210
+ &--secondary {
211
+ background-color: var(--fui-secondary-60);
212
+ color: var(--fui-text-primary);
213
+ border-color: var(--fui-border-color);
214
+ letter-spacing: var(--fui-letter-spacing-wide);
215
+
216
+ &:hover:not(.fui-button--disabled) {
217
+ background-color: var(--fui-secondary-90);
218
+ }
219
+
220
+ &:active:not(.fui-button--disabled) {
221
+ background-color: var(--fui-secondary-90);
222
+ }
223
+
224
+ &.fui-button--disabled {
225
+ background-color: var(--fui-secondary);
226
+ }
227
+ }
228
+
229
+ // Secondary variant
230
+ &--outline {
231
+ background-color: var(--fui-surface-01);
232
+ color: var(--fui-text-primary);
233
+ border: var(--fui-border-width-md) solid var(--fui-surface-03);
234
+
235
+ &:hover:not(.fui-button--disabled) {
236
+ background-color: var(--fui-primary-20);
237
+ }
238
+
239
+ &:active:not(.fui-button--disabled) {
240
+ background-color: var(--fui-primary-20);
241
+ }
242
+
243
+ &.fui-button--disabled {
244
+ background-color: var(--fui-surface-01);
245
+ }
246
+ }
247
+
248
+ // Danger variant
249
+ &--danger {
250
+ background-color: var(--fui-danger-60);
251
+ color: var(--fui-text-primary);
252
+ border-color: transparent;
253
+ letter-spacing: var(--fui-letter-spacing-wide);
254
+
255
+ &:hover:not(.fui-button--disabled) {
256
+ background-color: var(--fui-danger-80);
257
+ }
258
+
259
+ &:active:not(.fui-button--disabled) {
260
+ background-color: var(--fui-danger-80);
261
+ }
262
+
263
+ &.fui-button--disabled {
264
+ background-color: var(--fui-danger-60);
265
+ }
266
+ }
267
+
268
+ // Ghost variant (neutral)
269
+ &--ghost {
270
+ background-color: transparent;
271
+ color: var(--fui-text-primary);
272
+ border-color: transparent;
273
+
274
+ &:hover:not(.fui-button--disabled) {
275
+ background-color: var(--fui-surface-02);
276
+ }
277
+
278
+ &:active:not(.fui-button--disabled) {
279
+ background-color: var(--fui-surface-05);
280
+ }
281
+ }
282
+
283
+ &--link {
284
+ background-color: transparent;
285
+ color: var(--fui-primary);
286
+
287
+ &:hover:not(.fui-button--disabled) {
288
+ text-decoration: underline;
289
+ }
290
+
291
+ &:active:not(.fui-button--disabled) {
292
+ text-decoration: underline;
293
+ }
294
+ }
295
+
296
+ // Icon variant (ghost-like with circular shape)
297
+ &--icon {
298
+ background-color: transparent;
299
+ color: var(--fui-text-primary);
300
+ border-color: transparent;
301
+ border-radius: 50%;
302
+ aspect-ratio: 1;
303
+ padding: 0;
304
+
305
+ &:hover:not(.fui-button--disabled) {
306
+ background-color: var(--fui-surface-02);
307
+ }
308
+
309
+ &:active:not(.fui-button--disabled) {
310
+ background-color: var(--fui-surface-05);
311
+ }
312
+ }
313
+
314
+ // Icon adjustments
315
+ &--icon-only {
316
+ gap: 0;
317
+
318
+ .fui-icon {
319
+ margin: 0;
320
+ }
321
+ }
322
+ }
323
+
324
+ // Icon spacing within buttons
325
+ .fui-icon {
326
+ flex-shrink: 0;
327
+
328
+ &[fuiPrefix] {
329
+ margin-right: var(--fui-spacing-02);
330
+ }
331
+
332
+ &[fuiSuffix] {
333
+ margin-left: var(--fui-spacing-02);
334
+ }
335
+ }
336
+
337
+ // High contrast mode support
338
+ @media (prefers-contrast: more) {
339
+ .fui-button {
340
+ &--outlined {
341
+ border-width: 3px;
342
+ }
343
+
344
+ &:focus-visible {
345
+ outline-width: 3px;
346
+ }
347
+ }
348
+ }
349
+
350
+ // Keyframes
351
+ @keyframes fui-spin {
352
+ from {
353
+ transform: rotate(0deg);
354
+ }
355
+ to {
356
+ transform: rotate(360deg);
357
+ }
358
+ }
359
+
360
+ // Print styles
361
+ @media print {
362
+ .fui-button {
363
+ &__spinner {
364
+ display: none !important;
365
+ }
366
+ }
367
+ }