mtrl 0.2.2 → 0.2.4

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 (97) hide show
  1. package/.typedocignore +11 -0
  2. package/DOCS.md +153 -0
  3. package/index.ts +18 -3
  4. package/package.json +7 -2
  5. package/src/components/badge/_styles.scss +174 -0
  6. package/src/components/badge/api.ts +292 -0
  7. package/src/components/badge/badge.ts +52 -0
  8. package/src/components/badge/config.ts +68 -0
  9. package/src/components/badge/constants.ts +30 -0
  10. package/src/components/badge/features.ts +185 -0
  11. package/src/components/badge/index.ts +4 -0
  12. package/src/components/badge/types.ts +105 -0
  13. package/src/components/button/types.ts +174 -29
  14. package/src/components/carousel/_styles.scss +645 -0
  15. package/src/components/carousel/api.ts +147 -0
  16. package/src/components/carousel/carousel.ts +178 -0
  17. package/src/components/carousel/config.ts +91 -0
  18. package/src/components/carousel/constants.ts +95 -0
  19. package/src/components/carousel/features/drag.ts +388 -0
  20. package/src/components/carousel/features/index.ts +8 -0
  21. package/src/components/carousel/features/slides.ts +682 -0
  22. package/src/components/carousel/index.ts +38 -0
  23. package/src/components/carousel/types.ts +327 -0
  24. package/src/components/dialog/_styles.scss +213 -0
  25. package/src/components/dialog/api.ts +283 -0
  26. package/src/components/dialog/config.ts +113 -0
  27. package/src/components/dialog/constants.ts +32 -0
  28. package/src/components/dialog/dialog.ts +56 -0
  29. package/src/components/dialog/features.ts +713 -0
  30. package/src/components/dialog/index.ts +15 -0
  31. package/src/components/dialog/types.ts +221 -0
  32. package/src/components/progress/_styles.scss +13 -1
  33. package/src/components/progress/api.ts +2 -2
  34. package/src/components/progress/progress.ts +2 -2
  35. package/src/components/progress/types.ts +3 -0
  36. package/src/components/radios/_styles.scss +232 -0
  37. package/src/components/radios/api.ts +100 -0
  38. package/src/components/radios/config.ts +60 -0
  39. package/src/components/radios/constants.ts +28 -0
  40. package/src/components/radios/index.ts +4 -0
  41. package/src/components/radios/radio.ts +269 -0
  42. package/src/components/radios/radios.ts +42 -0
  43. package/src/components/radios/types.ts +232 -0
  44. package/src/components/sheet/_styles.scss +236 -0
  45. package/src/components/sheet/api.ts +96 -0
  46. package/src/components/sheet/config.ts +66 -0
  47. package/src/components/sheet/constants.ts +20 -0
  48. package/src/components/sheet/features/content.ts +51 -0
  49. package/src/components/sheet/features/gestures.ts +177 -0
  50. package/src/components/sheet/features/index.ts +6 -0
  51. package/src/components/sheet/features/position.ts +42 -0
  52. package/src/components/sheet/features/state.ts +116 -0
  53. package/src/components/sheet/features/title.ts +86 -0
  54. package/src/components/sheet/index.ts +4 -0
  55. package/src/components/sheet/sheet.ts +57 -0
  56. package/src/components/sheet/types.ts +266 -0
  57. package/src/components/slider/_styles.scss +518 -0
  58. package/src/components/slider/api.ts +336 -0
  59. package/src/components/slider/config.ts +145 -0
  60. package/src/components/slider/constants.ts +28 -0
  61. package/src/components/slider/features/appearance.ts +140 -0
  62. package/src/components/slider/features/disabled.ts +43 -0
  63. package/src/components/slider/features/events.ts +164 -0
  64. package/src/components/slider/features/index.ts +5 -0
  65. package/src/components/slider/features/interactions.ts +256 -0
  66. package/src/components/slider/features/keyboard.ts +114 -0
  67. package/src/components/slider/features/slider.ts +336 -0
  68. package/src/components/slider/features/structure.ts +264 -0
  69. package/src/components/slider/features/ui.ts +518 -0
  70. package/src/components/slider/index.ts +9 -0
  71. package/src/components/slider/slider.ts +58 -0
  72. package/src/components/slider/types.ts +166 -0
  73. package/src/components/tabs/_styles.scss +224 -0
  74. package/src/components/tabs/api.ts +443 -0
  75. package/src/components/tabs/config.ts +80 -0
  76. package/src/components/tabs/constants.ts +12 -0
  77. package/src/components/tabs/index.ts +4 -0
  78. package/src/components/tabs/tabs.ts +52 -0
  79. package/src/components/tabs/types.ts +247 -0
  80. package/src/components/textfield/_styles.scss +97 -4
  81. package/src/components/tooltip/_styles.scss +241 -0
  82. package/src/components/tooltip/api.ts +411 -0
  83. package/src/components/tooltip/config.ts +78 -0
  84. package/src/components/tooltip/constants.ts +27 -0
  85. package/src/components/tooltip/index.ts +4 -0
  86. package/src/components/tooltip/tooltip.ts +60 -0
  87. package/src/components/tooltip/types.ts +178 -0
  88. package/src/core/build/_ripple.scss +79 -0
  89. package/src/core/build/constants.ts +48 -0
  90. package/src/core/build/icon.ts +137 -0
  91. package/src/core/build/ripple.ts +216 -0
  92. package/src/core/build/text.ts +91 -0
  93. package/src/index.ts +9 -1
  94. package/src/styles/abstract/_variables.scss +24 -12
  95. package/tsconfig.json +22 -0
  96. package/typedoc.json +28 -0
  97. package/typedoc.simple.json +14 -0
@@ -0,0 +1,15 @@
1
+ // src/components/dialog/index.ts
2
+ export { default } from './dialog';
3
+ export {
4
+ DIALOG_SIZES,
5
+ DIALOG_ANIMATIONS,
6
+ DIALOG_FOOTER_ALIGNMENTS,
7
+ DIALOG_EVENTS
8
+ } from './constants';
9
+ export {
10
+ DialogConfig,
11
+ DialogComponent,
12
+ DialogButton,
13
+ DialogEvent,
14
+ DialogConfirmOptions
15
+ } from './types';
@@ -0,0 +1,221 @@
1
+ // src/components/dialog/types.ts
2
+ import { DIALOG_SIZES, DIALOG_ANIMATIONS, DIALOG_FOOTER_ALIGNMENTS, DIALOG_EVENTS } from './constants';
3
+
4
+ /**
5
+ * Configuration interface for the Dialog component
6
+ */
7
+ export interface DialogConfig {
8
+ /** Dialog title text */
9
+ title?: string;
10
+
11
+ /** Dialog subtitle text */
12
+ subtitle?: string;
13
+
14
+ /** Dialog content (text or HTML) */
15
+ content?: string;
16
+
17
+ /** Whether to show close button in header */
18
+ closeButton?: boolean;
19
+
20
+ /** CSS class to add to dialog */
21
+ class?: string;
22
+
23
+ /** Dialog size variant */
24
+ size?: keyof typeof DIALOG_SIZES | DIALOG_SIZES;
25
+
26
+ /** Dialog animation variant */
27
+ animation?: keyof typeof DIALOG_ANIMATIONS | DIALOG_ANIMATIONS;
28
+
29
+ /** Footer buttons alignment */
30
+ footerAlignment?: keyof typeof DIALOG_FOOTER_ALIGNMENTS | DIALOG_FOOTER_ALIGNMENTS;
31
+
32
+ /** Whether dialog is initially open */
33
+ open?: boolean;
34
+
35
+ /** Whether to close when clicking overlay */
36
+ closeOnOverlayClick?: boolean;
37
+
38
+ /** Whether to close when Escape key is pressed */
39
+ closeOnEscape?: boolean;
40
+
41
+ /** Whether dialog should be modal (prevent interaction with background) */
42
+ modal?: boolean;
43
+
44
+ /** Whether to focus the first focusable element when opened */
45
+ autofocus?: boolean;
46
+
47
+ /** Whether to trap focus within dialog when opened */
48
+ trapFocus?: boolean;
49
+
50
+ /** Parent element to append dialog to (defaults to document.body) */
51
+ container?: HTMLElement;
52
+
53
+ /** Footer buttons configuration */
54
+ buttons?: DialogButton[];
55
+
56
+ /** Whether to show a divider between header and content */
57
+ headerDivider?: boolean;
58
+
59
+ /** Whether to show a divider between content and footer */
60
+ footerDivider?: boolean;
61
+
62
+ /** Dialog z-index (defaults to 1000) */
63
+ zIndex?: number;
64
+
65
+ /** Duration of open/close animations in ms */
66
+ animationDuration?: number;
67
+
68
+ /** Event handlers for dialog events */
69
+ on?: {
70
+ [key in keyof typeof DIALOG_EVENTS]?: (event: DialogEvent) => void;
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Dialog button configuration
76
+ */
77
+ export interface DialogButton {
78
+ /** Button text */
79
+ text: string;
80
+
81
+ /** Button variant (uses button component variants) */
82
+ variant?: string;
83
+
84
+ /** Button color */
85
+ color?: string;
86
+
87
+ /** Button size */
88
+ size?: string;
89
+
90
+ /** Button onclick handler */
91
+ onClick?: (event: MouseEvent, dialog: DialogComponent) => void | boolean;
92
+
93
+ /** Close dialog when button is clicked */
94
+ closeDialog?: boolean;
95
+
96
+ /** Autofocus this button when dialog opens */
97
+ autofocus?: boolean;
98
+
99
+ /** Additional button attributes */
100
+ attrs?: Record<string, any>;
101
+ }
102
+
103
+ /**
104
+ * Dialog event object
105
+ */
106
+ export interface DialogEvent {
107
+ /** Dialog component instance */
108
+ dialog: DialogComponent;
109
+
110
+ /** Original event if applicable */
111
+ originalEvent?: Event;
112
+
113
+ /** Whether to prevent the default action */
114
+ preventDefault: () => void;
115
+
116
+ /** Whether default action was prevented */
117
+ defaultPrevented: boolean;
118
+ }
119
+
120
+ /**
121
+ * Dialog component interface
122
+ */
123
+ export interface DialogComponent {
124
+ /** Dialog element */
125
+ element: HTMLElement;
126
+
127
+ /** Dialog overlay element */
128
+ overlay: HTMLElement;
129
+
130
+ /** Opens the dialog */
131
+ open: () => DialogComponent;
132
+
133
+ /** Closes the dialog */
134
+ close: () => DialogComponent;
135
+
136
+ /** Toggles dialog open/closed state */
137
+ toggle: (open?: boolean) => DialogComponent;
138
+
139
+ /** Checks if dialog is open */
140
+ isOpen: () => boolean;
141
+
142
+ /** Sets dialog title */
143
+ setTitle: (title: string) => DialogComponent;
144
+
145
+ /** Gets dialog title */
146
+ getTitle: () => string;
147
+
148
+ /** Sets dialog subtitle */
149
+ setSubtitle: (subtitle: string) => DialogComponent;
150
+
151
+ /** Gets dialog subtitle */
152
+ getSubtitle: () => string;
153
+
154
+ /** Sets dialog content */
155
+ setContent: (content: string) => DialogComponent;
156
+
157
+ /** Gets dialog content */
158
+ getContent: () => string;
159
+
160
+ /** Adds a button to the dialog footer */
161
+ addButton: (button: DialogButton) => DialogComponent;
162
+
163
+ /** Removes a button by index or text */
164
+ removeButton: (indexOrText: number | string) => DialogComponent;
165
+
166
+ /** Gets all footer buttons */
167
+ getButtons: () => DialogButton[];
168
+
169
+ /** Sets footer alignment */
170
+ setFooterAlignment: (alignment: keyof typeof DIALOG_FOOTER_ALIGNMENTS | DIALOG_FOOTER_ALIGNMENTS) => DialogComponent;
171
+
172
+ /** Sets dialog size */
173
+ setSize: (size: keyof typeof DIALOG_SIZES | DIALOG_SIZES) => DialogComponent;
174
+
175
+ /** Adds event listener */
176
+ on: (event: keyof typeof DIALOG_EVENTS | DIALOG_EVENTS, handler: (event: DialogEvent) => void) => DialogComponent;
177
+
178
+ /** Removes event listener */
179
+ off: (event: keyof typeof DIALOG_EVENTS | DIALOG_EVENTS, handler: (event: DialogEvent) => void) => DialogComponent;
180
+
181
+ /** Gets dialog header element */
182
+ getHeaderElement: () => HTMLElement | null;
183
+
184
+ /** Gets dialog content element */
185
+ getContentElement: () => HTMLElement | null;
186
+
187
+ /** Gets dialog footer element */
188
+ getFooterElement: () => HTMLElement | null;
189
+
190
+ /** Creates a confirmation dialog with Yes/No buttons */
191
+ confirm: (options?: DialogConfirmOptions) => Promise<boolean>;
192
+
193
+ /** Destroys the dialog and removes it from DOM */
194
+ destroy: () => void;
195
+ }
196
+
197
+ /**
198
+ * Options for confirmation dialog
199
+ */
200
+ export interface DialogConfirmOptions {
201
+ /** Confirmation title */
202
+ title?: string;
203
+
204
+ /** Confirmation message */
205
+ message: string;
206
+
207
+ /** Confirm button text */
208
+ confirmText?: string;
209
+
210
+ /** Cancel button text */
211
+ cancelText?: string;
212
+
213
+ /** Confirm button variant */
214
+ confirmVariant?: string;
215
+
216
+ /** Cancel button variant */
217
+ cancelVariant?: string;
218
+
219
+ /** Dialog size */
220
+ size?: keyof typeof DIALOG_SIZES | DIALOG_SIZES;
221
+ }
@@ -23,7 +23,7 @@ $component: '#{base.$prefix}-progress';
23
23
  &--linear {
24
24
  width: 100%;
25
25
  height: 4px; // Default height
26
-
26
+ border-radius: 2px;
27
27
  .#{$component}-track {
28
28
  position: absolute;
29
29
  top: 0;
@@ -31,6 +31,7 @@ $component: '#{base.$prefix}-progress';
31
31
  width: 100%;
32
32
  height: 100%;
33
33
  background-color: t.color('surface-container-highest');
34
+ border-radius: 2px;
34
35
  }
35
36
 
36
37
  .#{$component}-buffer {
@@ -41,6 +42,7 @@ $component: '#{base.$prefix}-progress';
41
42
  width: 0;
42
43
  background-color: t.alpha('primary', 0.4);
43
44
  transition: width 0.3s ease;
45
+ border-radius: 2px;
44
46
  }
45
47
 
46
48
  .#{$component}-indicator {
@@ -51,6 +53,7 @@ $component: '#{base.$prefix}-progress';
51
53
  width: 0;
52
54
  background-color: t.color('primary');
53
55
  transition: width 0.3s ease;
56
+ border-radius: 2px;
54
57
  }
55
58
 
56
59
  // Indeterminate animation for linear progress
@@ -62,6 +65,7 @@ $component: '#{base.$prefix}-progress';
62
65
  .#{$component}-indicator {
63
66
  width: 30%;
64
67
  animation: linear-indeterminate 2s infinite;
68
+ border-radius: 2px;
65
69
  }
66
70
  }
67
71
 
@@ -99,6 +103,7 @@ $component: '#{base.$prefix}-progress';
99
103
  stroke-dasharray: 283; // 2*PI*45
100
104
  stroke-dashoffset: 283;
101
105
  transition: stroke-dashoffset 0.3s ease;
106
+ stroke-linecap: round;
102
107
  }
103
108
 
104
109
  // Indeterminate animation for circular progress
@@ -128,6 +133,8 @@ $component: '#{base.$prefix}-progress';
128
133
  .#{$component}-track,
129
134
  .#{$component}-indicator {
130
135
  stroke-width: 3;
136
+ border-radius: 1px;
137
+ linecap: round
131
138
  }
132
139
  }
133
140
  }
@@ -152,6 +159,11 @@ $component: '#{base.$prefix}-progress';
152
159
  &.#{$component}--linear {
153
160
  height: 8px;
154
161
 
162
+ .#{$component}-track,
163
+ .#{$component}-indicator {
164
+ border-radius: 4px;
165
+ }
166
+
155
167
  .#{$component}-label {
156
168
  font-size: 14px;
157
169
  top: 12px;
@@ -59,7 +59,7 @@ export const withAPI = (options: ApiOptions) =>
59
59
  if (!options.state.isIndeterminate()) {
60
60
  const percent = (value / options.value.getMax()) * 100;
61
61
 
62
- if (component.getClass('progress').includes('linear')) {
62
+ if (component.element.classList.contains(`${component.getClass('progress')}--linear`)) {
63
63
  component.indicatorElement.style.width = `${percent}%`;
64
64
  } else {
65
65
  // Circular progress calculation
@@ -91,7 +91,7 @@ export const withAPI = (options: ApiOptions) =>
91
91
  setBuffer(value: number) {
92
92
  options.buffer.setBuffer(value);
93
93
 
94
- if (component.getClass('progress').includes('linear')) {
94
+ if (component.element.classList.contains(`${component.getClass('progress')}--linear`)) {
95
95
  const bufferElement = component.element.querySelector(`.${component.getClass('progress')}-buffer`);
96
96
  if (bufferElement) {
97
97
  const percent = (value / options.value.getMax()) * 100;
@@ -37,7 +37,7 @@ const createCircularProgressDOM = (baseClass: string) => {
37
37
  track.setAttribute('r', '45');
38
38
  track.setAttribute('fill', 'none');
39
39
  track.setAttribute('stroke-width', '6');
40
- track.className = `${baseClass}-track`;
40
+ track.setAttribute('class', `${baseClass}-track`); // FIXED: use setAttribute instead of className
41
41
 
42
42
  const indicator = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
43
43
  indicator.setAttribute('cx', '48');
@@ -45,7 +45,7 @@ const createCircularProgressDOM = (baseClass: string) => {
45
45
  indicator.setAttribute('r', '45');
46
46
  indicator.setAttribute('fill', 'none');
47
47
  indicator.setAttribute('stroke-width', '6');
48
- indicator.className = `${baseClass}-indicator`;
48
+ indicator.setAttribute('class', `${baseClass}-indicator`); // FIXED: use setAttribute instead of className
49
49
 
50
50
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
51
51
  svg.setAttribute('viewBox', `0 0 ${size} ${size}`);
@@ -49,6 +49,9 @@ export interface ProgressComponent {
49
49
  /** The indicator element */
50
50
  indicatorElement: HTMLElement;
51
51
 
52
+ /** The buffer element (for linear variant) */
53
+ bufferElement?: HTMLElement;
54
+
52
55
  /** The label element (if enabled) */
53
56
  labelElement?: HTMLElement;
54
57
 
@@ -0,0 +1,232 @@
1
+ // src/components/radios/_styles.scss
2
+ @use '../../styles/abstract/base' as base;
3
+ @use '../../styles/abstract/variables' as v;
4
+ @use '../../styles/abstract/functions' as f;
5
+ @use '../../styles/abstract/mixins' as m;
6
+ @use '../../styles/abstract/theme' as t;
7
+
8
+ $component: '#{base.$prefix}-radios';
9
+
10
+ .#{$component} {
11
+ display: flex;
12
+ margin: 0;
13
+ padding: 0;
14
+
15
+ // Vertical layout (default)
16
+ &--vertical {
17
+ flex-direction: column;
18
+
19
+ .#{$component}-item {
20
+ margin-bottom: 12px;
21
+
22
+ &:last-child {
23
+ margin-bottom: 0;
24
+ }
25
+ }
26
+ }
27
+
28
+ // Horizontal layout
29
+ &--horizontal {
30
+ flex-direction: row;
31
+ flex-wrap: wrap;
32
+ align-items: flex-start;
33
+
34
+ .#{$component}-item {
35
+ margin-right: 16px;
36
+
37
+ &:last-child {
38
+ margin-right: 0;
39
+ }
40
+ }
41
+ }
42
+
43
+ // Disabled state
44
+ &--disabled {
45
+ opacity: 0.6;
46
+ pointer-events: none;
47
+ }
48
+
49
+ // Radio item
50
+ &-item {
51
+ position: relative;
52
+ display: inline-flex;
53
+ align-items: center;
54
+
55
+ &--disabled {
56
+ cursor: not-allowed;
57
+ opacity: 0.6;
58
+
59
+ .#{$component}-label {
60
+ cursor: not-allowed;
61
+ }
62
+ }
63
+ }
64
+
65
+ // Radio input
66
+ &-input {
67
+ position: absolute;
68
+ opacity: 0;
69
+ height: 0;
70
+ width: 0;
71
+ margin: 0;
72
+ padding: 0;
73
+
74
+ // Focus styles
75
+ &:focus ~ .#{$component}-label .#{$component}-ripple {
76
+ background-color: t.alpha('primary', 0.12);
77
+ }
78
+
79
+ // Checked styles
80
+ &:checked ~ .#{$component}-label {
81
+ .#{$component}-circle {
82
+ border-color: t.color('primary');
83
+ border-width: 1.5px;
84
+
85
+ &:after {
86
+ transform: translate(-50%, -50%) scale(1);
87
+ opacity: 1;
88
+ }
89
+ }
90
+ }
91
+
92
+ // Disabled styles
93
+ &:disabled ~ .#{$component}-label {
94
+ .#{$component}-circle {
95
+ border-color: t.alpha('on-surface', 0.38);
96
+
97
+ &:after {
98
+ background-color: t.alpha('on-surface', 0.38);
99
+ }
100
+ }
101
+
102
+ .#{$component}-text {
103
+ color: t.alpha('on-surface', 0.38);
104
+ }
105
+ }
106
+ }
107
+
108
+ // Radio label
109
+ &-label {
110
+ position: relative;
111
+ display: inline-flex;
112
+ align-items: center;
113
+ cursor: pointer;
114
+ padding: 8px 0;
115
+ height: 48px;
116
+
117
+ // Typography for label
118
+ @include m.typography('body-medium');
119
+
120
+ &--before {
121
+ flex-direction: row-reverse;
122
+
123
+ .#{$component}-text {
124
+ margin-right: 12px;
125
+ margin-left: 0;
126
+ }
127
+ }
128
+ }
129
+
130
+ // Radio control
131
+ &-control {
132
+ position: relative;
133
+ display: inline-flex;
134
+ align-items: center;
135
+ justify-content: center;
136
+ width: 40px;
137
+ height: 40px;
138
+ flex-shrink: 0;
139
+ }
140
+
141
+ // Radio circle
142
+ &-circle {
143
+ position: relative;
144
+ width: 20px;
145
+ height: 20px;
146
+ border: 1.5px solid t.color('outline');
147
+ border-radius: 50%;
148
+ box-sizing: border-box;
149
+ transition: border-color 0.2s ease;
150
+
151
+ &:after {
152
+ content: '';
153
+ position: absolute;
154
+ top: 50%;
155
+ left: 50%;
156
+ transform: translate(-50%, -50%) scale(0);
157
+ width: 12px;
158
+ height: 12px;
159
+ border-radius: 50%;
160
+ background-color: t.color('primary');
161
+ opacity: 0;
162
+ transition: transform 0.15s ease, opacity 0.15s ease;
163
+ }
164
+ }
165
+
166
+ // Ripple effect
167
+ &-ripple {
168
+ position: absolute;
169
+ top: 0;
170
+ left: 0;
171
+ right: 0;
172
+ bottom: 0;
173
+ border-radius: 50%;
174
+ transition: background-color 0.15s ease;
175
+
176
+ // Apply ripple effect on hover
177
+ .#{$component}-input:not(:disabled) ~ .#{$component}-label:hover & {
178
+ background-color: t.alpha('primary', 0.08);
179
+ }
180
+ }
181
+
182
+ // Radio text
183
+ &-text {
184
+ margin-left: 8px;
185
+ line-height: 1.2;
186
+ }
187
+
188
+ // Size variants
189
+ &--small {
190
+ .#{$component}-control {
191
+ width: 36px;
192
+ height: 36px;
193
+ }
194
+
195
+ .#{$component}-circle {
196
+ width: 18px;
197
+ height: 18px;
198
+
199
+ &:after {
200
+ width: 10px;
201
+ height: 10px;
202
+ }
203
+ }
204
+
205
+ .#{$component}-label {
206
+ font-size: 13px;
207
+ height: 36px;
208
+ }
209
+ }
210
+
211
+ &--large {
212
+ .#{$component}-control {
213
+ width: 48px;
214
+ height: 48px;
215
+ }
216
+
217
+ .#{$component}-circle {
218
+ width: 24px;
219
+ height: 24px;
220
+
221
+ &:after {
222
+ width: 14px;
223
+ height: 14px;
224
+ }
225
+ }
226
+
227
+ .#{$component}-label {
228
+ font-size: 16px;
229
+ height: 48px;
230
+ }
231
+ }
232
+ }
@@ -0,0 +1,100 @@
1
+ // src/components/radios/api.ts
2
+ import { RadiosComponent } from './types';
3
+
4
+ interface ApiOptions {
5
+ disabled: {
6
+ enable: () => void;
7
+ disable: () => void;
8
+ };
9
+ lifecycle: {
10
+ destroy: () => void;
11
+ };
12
+ }
13
+
14
+ interface ComponentWithRadio {
15
+ element: HTMLElement;
16
+ radios: any[];
17
+ getValue: () => string;
18
+ setValue: (value: string) => any;
19
+ getSelected: () => any;
20
+ addOption: (option: any) => any;
21
+ removeOption: (value: string) => any;
22
+ enable: () => any;
23
+ disable: () => any;
24
+ enableOption: (value: string) => any;
25
+ disableOption: (value: string) => any;
26
+ getClass: (name: string) => string;
27
+ events: {
28
+ on: (event: string, handler: Function) => void;
29
+ off: (event: string, handler: Function) => void;
30
+ };
31
+ }
32
+
33
+ /**
34
+ * Enhances a radios component with API methods
35
+ * @param {ApiOptions} options - API configuration options
36
+ * @returns {Function} Higher-order function that adds API methods to component
37
+ * @internal This is an internal utility for the Radios component
38
+ */
39
+ export const withAPI = ({ disabled, lifecycle }: ApiOptions) =>
40
+ (component: ComponentWithRadio): RadiosComponent => ({
41
+ ...component as any,
42
+ element: component.element,
43
+ radios: component.radios,
44
+
45
+ getValue: () => component.getValue(),
46
+
47
+ setValue(value: string) {
48
+ component.setValue(value);
49
+ return this;
50
+ },
51
+
52
+ getSelected: () => component.getSelected(),
53
+
54
+ addOption(option) {
55
+ component.addOption(option);
56
+ return this;
57
+ },
58
+
59
+ removeOption(value: string) {
60
+ component.removeOption(value);
61
+ return this;
62
+ },
63
+
64
+ enable() {
65
+ disabled.enable();
66
+ return this;
67
+ },
68
+
69
+ disable() {
70
+ disabled.disable();
71
+ return this;
72
+ },
73
+
74
+ enableOption(value: string) {
75
+ component.enableOption(value);
76
+ return this;
77
+ },
78
+
79
+ disableOption(value: string) {
80
+ component.disableOption(value);
81
+ return this;
82
+ },
83
+
84
+ on(event: string, handler: Function) {
85
+ component.events.on(event, handler);
86
+ return this;
87
+ },
88
+
89
+ off(event: string, handler: Function) {
90
+ component.events.off(event, handler);
91
+ return this;
92
+ },
93
+
94
+ destroy() {
95
+ // First destroy all radio items
96
+ component.radios.forEach(radio => radio.destroy());
97
+ // Then destroy the component
98
+ lifecycle.destroy();
99
+ }
100
+ });