@med-o/ui 0.0.0-stage → 0.1.0

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 (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -2
  3. package/dist/index.d.ts +2021 -0
  4. package/dist/index.js +4721 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +78 -4
  7. package/src/accordion/accordion.css +184 -0
  8. package/src/alert/alert.css +147 -0
  9. package/src/avatar/avatar.css +221 -0
  10. package/src/badge/badge.css +153 -0
  11. package/src/bottom-sheet/bottom-sheet.css +202 -0
  12. package/src/breadcrumbs/breadcrumbs.css +147 -0
  13. package/src/bulk-action-bar/bulk-action-bar.css +98 -0
  14. package/src/button/button.css +319 -0
  15. package/src/card/card.css +217 -0
  16. package/src/checkbox/choice.css +196 -0
  17. package/src/combobox/combobox.css +125 -0
  18. package/src/date-time/date-time.css +474 -0
  19. package/src/dialog/dialog.css +319 -0
  20. package/src/drawer/drawer.css +156 -0
  21. package/src/empty-state/empty-state.css +161 -0
  22. package/src/field/field.css +115 -0
  23. package/src/link/link.css +103 -0
  24. package/src/list/list.css +172 -0
  25. package/src/list-view/list-view.css +473 -0
  26. package/src/listbox/listbox.css +203 -0
  27. package/src/media/media.css +298 -0
  28. package/src/menu/menu.css +183 -0
  29. package/src/navigation/navigation.css +626 -0
  30. package/src/pagination/pagination.css +132 -0
  31. package/src/popover/popover.css +166 -0
  32. package/src/progress/progress.css +225 -0
  33. package/src/search/search.css +309 -0
  34. package/src/select/select.css +229 -0
  35. package/src/slider/slider.css +212 -0
  36. package/src/styles.css +40 -0
  37. package/src/switch/switch.css +160 -0
  38. package/src/table/table.css +276 -0
  39. package/src/tabs/tabs.css +211 -0
  40. package/src/tag/tag.css +225 -0
  41. package/src/text-field/input.css +206 -0
  42. package/src/toast/toast.css +184 -0
  43. package/src/toggle-button/toggle-button.css +143 -0
  44. package/src/tooltip/tooltip.css +66 -0
  45. package/src/upload/upload.css +380 -0
  46. package/src/utils/utilities.css +14 -0
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Pagination – med.o Design System
3
+ *
4
+ * <nav class="medo-pagination medo-pagination--full" aria-label="Pagination">
5
+ * <div class="medo-pagination__info"><p class="medo-pagination__summary" role="status">81–100 of 380</p> [Rows per page]</div>
6
+ * <ul class="medo-pagination__pages">
7
+ * <li><button class="medo-button medo-button--ghost medo-button--md medo-page-item" aria-current="page">5</button></li> …
8
+ * </ul>
9
+ * </nav>
10
+ * Page items reuse the ghost button (state layers, inset focus ring): min width = height, padding space/2.
11
+ * Current page: action/selected (-hover/-pressed), text/brand, label strong – calm, never the primary colour.
12
+ */
13
+
14
+ .medo-pagination {
15
+ display: flex;
16
+ flex-wrap: wrap;
17
+ align-items: center;
18
+ justify-content: space-between;
19
+ gap: var(--medo-space-4) var(--medo-space-6);
20
+ }
21
+
22
+ .medo-pagination__info {
23
+ display: flex;
24
+ flex-wrap: wrap;
25
+ align-items: center;
26
+ gap: var(--medo-space-2) var(--medo-space-6);
27
+ }
28
+
29
+ .medo-pagination__summary {
30
+ margin: 0;
31
+ font: var(--medo-typography-body-sm);
32
+ font-variant-numeric: tabular-nums;
33
+ color: var(--medo-color-text-secondary);
34
+ white-space: nowrap;
35
+ }
36
+
37
+ /* Rows per page: label on the left, Select sm 80 wide. */
38
+ .medo-pagination__size {
39
+ flex-direction: row;
40
+ align-items: center;
41
+ gap: var(--medo-space-2);
42
+ }
43
+
44
+ .medo-pagination__size .medo-field__label {
45
+ padding-inline-start: 0;
46
+ font: var(--medo-typography-body-sm);
47
+ color: var(--medo-color-text-secondary);
48
+ white-space: nowrap;
49
+ }
50
+
51
+ .medo-pagination__size .medo-select__field {
52
+ inline-size: 5rem;
53
+ }
54
+
55
+ .medo-pagination__size .medo-field__footer {
56
+ display: none;
57
+ }
58
+
59
+ .medo-pagination__pages {
60
+ display: flex;
61
+ align-items: center;
62
+ gap: var(--medo-space-1);
63
+ margin: 0;
64
+ padding: 0;
65
+ list-style: none;
66
+ }
67
+
68
+ /* ---------- Page item – md 40 · lg 48 ---------- */
69
+
70
+ .medo-page-item {
71
+ min-inline-size: var(--medo-size-control-md);
72
+ padding-inline: var(--medo-space-2);
73
+ font-variant-numeric: tabular-nums;
74
+ }
75
+
76
+ .medo-page-item--lg {
77
+ min-inline-size: var(--medo-size-control-lg);
78
+ font: var(--medo-typography-label-lg);
79
+ }
80
+
81
+ .medo-page-item[aria-current='page'] {
82
+ --_bg: var(--medo-color-action-selected);
83
+ --_bg-hover: var(--medo-color-action-selected-hover);
84
+ --_bg-pressed: var(--medo-color-action-selected-pressed);
85
+ --_fg: var(--medo-color-text-brand);
86
+ font: var(--medo-typography-label-md-strong);
87
+ }
88
+
89
+ .medo-page-item--lg[aria-current='page'] {
90
+ font: var(--medo-typography-label-lg-strong);
91
+ }
92
+
93
+ .medo-page-item--ellipsis {
94
+ display: inline-flex;
95
+ align-items: center;
96
+ justify-content: center;
97
+ block-size: var(--medo-size-control-md);
98
+ font: var(--medo-typography-label-md);
99
+ color: var(--medo-color-text-secondary);
100
+ user-select: none;
101
+ }
102
+
103
+ .medo-page-item--ellipsis.medo-page-item--lg {
104
+ block-size: var(--medo-size-control-lg);
105
+ }
106
+
107
+ /* ---------- Compact (< 640 px): ‹ Page 5 of 19 › full width ---------- */
108
+
109
+ .medo-pagination--compact {
110
+ flex-wrap: nowrap;
111
+ inline-size: 100%;
112
+ }
113
+
114
+ .medo-pagination__compact-label {
115
+ margin: 0;
116
+ font: var(--medo-typography-label-lg);
117
+ font-variant-numeric: tabular-nums;
118
+ color: var(--medo-color-text-primary);
119
+ text-align: center;
120
+ }
121
+
122
+ /* Disabled previous / next: the ghost button has no fill; links keep the button look. */
123
+ .medo-pagination a.medo-button[data-disabled] {
124
+ pointer-events: none;
125
+ }
126
+
127
+ @media (forced-colors: active) {
128
+ .medo-page-item[aria-current='page'] {
129
+ outline: 2px solid Highlight;
130
+ outline-offset: -2px;
131
+ }
132
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Popover – med.o Design System
3
+ *
4
+ * Small non-modal panel anchored to its trigger. Same surface as Menu and Listbox.
5
+ * <div class="medo-popover medo-popover--md"> surface/raised, border, elevation/2, radius/md
6
+ * <section class="medo-popover__dialog" role="dialog">
7
+ * <div class="medo-popover__header"> title (label/md) · close X </div> optional
8
+ * <div class="medo-popover__body">…scrolls…</div>
9
+ * <div class="medo-popover__footer"> Button group (sm) </div> optional
10
+ * </section>
11
+ * </div>
12
+ * Toggletip: .medo-popover.medo-toggletip with .medo-toggletip__text + link.
13
+ * Sizes: sm 240 · md 320 · lg 400 · auto (hugs, no padding). Below 640 px popovers open as Bottom Sheet.
14
+ * State contract: [data-entering] [data-exiting] [data-placement] (React Aria).
15
+ */
16
+
17
+ .medo-popover {
18
+ --_width: 20rem; /* md 320 */
19
+ --_pad: var(--medo-space-4);
20
+
21
+ box-sizing: border-box;
22
+ display: flex;
23
+ inline-size: min(var(--_width), 100vw - 2 * var(--medo-space-4));
24
+ border: var(--medo-border-width-thin) solid var(--medo-color-border-default);
25
+ border-radius: var(--medo-radius-md);
26
+ background-color: var(--medo-color-surface-raised);
27
+ box-shadow: var(--medo-shadow-elevation-2);
28
+ color: var(--medo-color-text-primary);
29
+ z-index: var(--medo-layer-popover);
30
+ outline: none;
31
+ transform-origin: var(--trigger-anchor-point);
32
+ }
33
+
34
+ .medo-popover--sm {
35
+ --_width: 15rem; /* 240 */
36
+ }
37
+ .medo-popover--lg {
38
+ --_width: 25rem; /* 400 */
39
+ }
40
+ .medo-popover--auto {
41
+ --_pad: 0px;
42
+ inline-size: auto;
43
+ }
44
+
45
+ /* Motion (iOS): grows from the trigger with a snappy spring and fades in; out: a quick fade. Transitions, so a fast open–close reverses smoothly. */
46
+ .medo-popover {
47
+ transform-origin: var(--trigger-anchor-point, top);
48
+ transition:
49
+ opacity var(--medo-motion-duration-normal) var(--medo-motion-easing-enter),
50
+ scale var(--medo-motion-spring-snappy-duration) var(--medo-motion-spring-snappy);
51
+ }
52
+ .medo-popover[data-entering] {
53
+ opacity: 0;
54
+ scale: 0.96;
55
+ }
56
+ .medo-popover[data-exiting] {
57
+ opacity: 0;
58
+ scale: 0.98;
59
+ transition:
60
+ opacity var(--medo-motion-duration-fast) var(--medo-motion-easing-exit),
61
+ scale var(--medo-motion-duration-fast) var(--medo-motion-easing-exit);
62
+ }
63
+
64
+ .medo-popover__dialog {
65
+ display: flex;
66
+ flex: 1;
67
+ flex-direction: column;
68
+ gap: var(--medo-space-3);
69
+ min-block-size: 0;
70
+ padding: var(--_pad);
71
+ outline: none;
72
+ }
73
+
74
+ .medo-popover__header {
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: space-between;
78
+ gap: var(--medo-space-2);
79
+ }
80
+
81
+ .medo-popover__title {
82
+ margin: 0;
83
+ font: var(--medo-typography-label-md);
84
+ color: var(--medo-color-text-primary);
85
+ }
86
+
87
+ .medo-popover__body {
88
+ flex: 1;
89
+ min-block-size: 0;
90
+ overflow: auto;
91
+ overscroll-behavior: contain;
92
+ font: var(--medo-typography-body-sm);
93
+ /* Room for focus rings of the content, which the scroll container would clip. */
94
+ margin: calc(-1 * var(--medo-space-1));
95
+ padding: var(--medo-space-1);
96
+ }
97
+
98
+ .medo-popover--auto .medo-popover__body {
99
+ margin: 0;
100
+ padding: 0;
101
+ }
102
+
103
+ .medo-popover__footer {
104
+ padding-block-start: var(--medo-space-1);
105
+ }
106
+
107
+ /* auto: no padding around the content; header and footer keep an inset of 16. */
108
+ .medo-popover--auto .medo-popover__dialog {
109
+ gap: 0;
110
+ }
111
+ .medo-popover--auto .medo-popover__header,
112
+ .medo-popover--auto .medo-popover__footer {
113
+ padding: var(--medo-space-4);
114
+ }
115
+
116
+ /* ---------- Toggletip ---------- */
117
+
118
+ .medo-toggletip {
119
+ --_width: 15rem; /* 240 */
120
+ --_pad: var(--medo-space-3);
121
+ }
122
+
123
+ .medo-toggletip__dialog {
124
+ display: grid;
125
+ justify-items: start;
126
+ gap: var(--medo-space-1);
127
+ }
128
+
129
+ .medo-toggletip__text {
130
+ font: var(--medo-typography-body-sm);
131
+ color: var(--medo-color-text-primary);
132
+ }
133
+
134
+ .medo-toggletip__text > p {
135
+ margin: 0;
136
+ }
137
+
138
+ /* ---------- Bottom Sheet (mobile) ---------- */
139
+
140
+ .medo-popover__sheet-body {
141
+ padding: var(--medo-space-2) var(--medo-space-4) var(--medo-space-4);
142
+ font: var(--medo-typography-body-sm);
143
+ }
144
+
145
+ /* Mobile: the toggletip stays a popover, full width minus 16 px on each side. */
146
+ @media (max-width: 639.98px) {
147
+ .medo-toggletip {
148
+ inline-size: calc(100vw - 2 * var(--medo-space-4));
149
+ }
150
+ }
151
+
152
+ @media (forced-colors: active) {
153
+ .medo-popover {
154
+ border-color: CanvasText;
155
+ }
156
+ }
157
+
158
+ @media (prefers-reduced-motion: reduce) {
159
+ /* Reduced motion: a short cross-fade, no scaling. */
160
+ .medo-popover {
161
+ transition: opacity var(--medo-motion-duration-fast) var(--medo-motion-easing-standard);
162
+ }
163
+ .medo-popover:is([data-entering], [data-exiting]) {
164
+ scale: none;
165
+ }
166
+ }
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Loading & Progress – med.o Design System
3
+ *
4
+ * Spinner: <span class="medo-spinner medo-spinner--md" role="progressbar" aria-label="Loading"><svg>…</svg></span>
5
+ * Progress bar: label + value above, track, helper below. Modifiers --success · --error · --indeterminate
6
+ * Skeleton: <span class="medo-skeleton medo-skeleton--text" aria-hidden="true"></span>
7
+ * The loading region gets aria-busy="true".
8
+ */
9
+
10
+ /* ---------- Spinner ---------- */
11
+
12
+ .medo-spinner {
13
+ --_size: var(--medo-space-5);
14
+ --_stroke: 2.4; /* user units of the 24 × 24 viewBox: 2 px at 20 px */
15
+
16
+ display: inline-flex;
17
+ flex-shrink: 0;
18
+ inline-size: var(--_size);
19
+ block-size: var(--_size);
20
+ color: currentColor;
21
+ vertical-align: middle;
22
+ }
23
+
24
+ .medo-spinner--sm {
25
+ --_size: var(--medo-space-4);
26
+ --_stroke: 3; /* 2 px at 16 px */
27
+ }
28
+ .medo-spinner--lg {
29
+ --_size: var(--medo-space-6);
30
+ --_stroke: 2.5; /* 2.5 px at 24 px */
31
+ }
32
+ .medo-spinner--xl {
33
+ --_size: var(--medo-space-10);
34
+ --_stroke: 2.4; /* 4 px at 40 px */
35
+ }
36
+
37
+ .medo-spinner--brand {
38
+ color: var(--medo-color-text-brand);
39
+ }
40
+ .medo-spinner--neutral {
41
+ color: var(--medo-color-text-secondary);
42
+ }
43
+ .medo-spinner--on-brand {
44
+ color: var(--medo-color-text-on-brand);
45
+ }
46
+
47
+ .medo-spinner > svg {
48
+ inline-size: 100%;
49
+ block-size: 100%;
50
+ fill: none;
51
+ stroke: currentColor;
52
+ stroke-width: var(--_stroke);
53
+ animation: medo-spin 0.8s linear infinite;
54
+ }
55
+
56
+ /* The light ring keeps the shape visible, even without motion. */
57
+ .medo-spinner__track {
58
+ opacity: 0.2;
59
+ }
60
+
61
+ .medo-spinner__arc {
62
+ stroke-linecap: round;
63
+ stroke-dasharray: 25 100; /* 90° of pathLength 100 */
64
+ }
65
+
66
+ @keyframes medo-spin {
67
+ to {
68
+ transform: rotate(1turn);
69
+ }
70
+ }
71
+
72
+ /* ---------- Progress bar ---------- */
73
+
74
+ .medo-progress {
75
+ --_fill: var(--medo-color-action-primary);
76
+ --_h: var(--medo-space-2);
77
+
78
+ display: grid;
79
+ gap: var(--medo-space-2);
80
+ min-inline-size: 0;
81
+ }
82
+
83
+ .medo-progress--sm {
84
+ --_h: var(--medo-space-1);
85
+ }
86
+
87
+ .medo-progress--success {
88
+ --_fill: var(--medo-color-feedback-success-solid);
89
+ }
90
+ .medo-progress--error {
91
+ --_fill: var(--medo-color-feedback-danger-solid);
92
+ }
93
+
94
+ .medo-progress__header {
95
+ display: flex;
96
+ justify-content: space-between;
97
+ align-items: baseline;
98
+ gap: var(--medo-space-4);
99
+ }
100
+
101
+ .medo-progress__label {
102
+ font: var(--medo-typography-label-md);
103
+ color: var(--medo-color-text-primary);
104
+ }
105
+
106
+ .medo-progress__value {
107
+ font: var(--medo-typography-body-sm);
108
+ color: var(--medo-color-text-secondary);
109
+ font-variant-numeric: tabular-nums;
110
+ white-space: nowrap;
111
+ }
112
+
113
+ .medo-progress__track {
114
+ position: relative;
115
+ block-size: var(--_h);
116
+ border-radius: var(--medo-radius-full);
117
+ background-color: var(--medo-color-surface-subtle);
118
+ overflow: hidden;
119
+ }
120
+
121
+ .medo-progress__fill {
122
+ block-size: 100%;
123
+ border-radius: inherit;
124
+ background-color: var(--_fill);
125
+ transition: inline-size var(--medo-motion-spring-smooth-duration) var(--medo-motion-spring-smooth);
126
+ }
127
+
128
+ /* Indeterminate: a segment slides back and forth. */
129
+ .medo-progress--indeterminate .medo-progress__fill {
130
+ position: absolute;
131
+ inset-block: 0;
132
+ inline-size: 30%;
133
+ animation: medo-progress-slide 1.5s ease-in-out infinite;
134
+ }
135
+
136
+ @keyframes medo-progress-slide {
137
+ from {
138
+ inset-inline-start: -30%;
139
+ }
140
+ to {
141
+ inset-inline-start: 100%;
142
+ }
143
+ }
144
+
145
+ .medo-progress__description {
146
+ font: var(--medo-typography-caption);
147
+ color: var(--medo-color-text-secondary);
148
+ }
149
+
150
+ .medo-progress--error .medo-progress__description {
151
+ color: var(--medo-color-text-danger);
152
+ }
153
+
154
+ /* ---------- Skeleton ---------- */
155
+
156
+ .medo-skeleton {
157
+ display: block;
158
+ inline-size: 100%;
159
+ block-size: var(--medo-space-3);
160
+ border-radius: var(--medo-radius-sm);
161
+ background-color: var(--medo-color-surface-subtle);
162
+ animation: medo-skeleton-pulse 1.5s ease-in-out infinite alternate;
163
+ }
164
+
165
+ .medo-skeleton--circle {
166
+ inline-size: var(--medo-space-10);
167
+ block-size: var(--medo-space-10);
168
+ border-radius: var(--medo-radius-full);
169
+ }
170
+
171
+ .medo-skeleton--rect {
172
+ block-size: var(--medo-space-24);
173
+ border-radius: var(--medo-radius-md);
174
+ }
175
+
176
+ /* Text lines: the last one is shorter. */
177
+ .medo-skeleton-lines {
178
+ display: grid;
179
+ gap: var(--medo-space-2);
180
+ }
181
+ .medo-skeleton-lines > .medo-skeleton:last-child:not(:first-child) {
182
+ inline-size: 60%;
183
+ }
184
+
185
+ @keyframes medo-skeleton-pulse {
186
+ to {
187
+ opacity: 0.5;
188
+ }
189
+ }
190
+
191
+ /* ---------- System settings ---------- */
192
+
193
+ @media (prefers-reduced-motion: reduce) {
194
+ /* Slower spinner, static skeleton and segment – activity stays visible. */
195
+ .medo-spinner > svg {
196
+ animation-duration: 1.6s;
197
+ }
198
+ .medo-skeleton {
199
+ animation: none;
200
+ }
201
+ .medo-progress--indeterminate .medo-progress__fill {
202
+ animation: none;
203
+ inset-inline-start: 0;
204
+ inline-size: 40%;
205
+ }
206
+ .medo-progress__fill {
207
+ transition-duration: var(--medo-motion-duration-fast);
208
+ }
209
+ }
210
+
211
+ @media (forced-colors: active) {
212
+ .medo-spinner > svg {
213
+ stroke: CanvasText;
214
+ }
215
+ .medo-progress__track {
216
+ border: var(--medo-border-width-thin) solid CanvasText;
217
+ }
218
+ .medo-progress__fill {
219
+ forced-color-adjust: none;
220
+ background-color: Highlight;
221
+ }
222
+ .medo-skeleton {
223
+ border: var(--medo-border-width-thin) solid GrayText;
224
+ }
225
+ }