@revikornmann/muka-ui 0.18.0 → 0.19.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 (118) hide show
  1. package/README.md +81 -60
  2. package/cli/bin/muka-ui.js +12 -5
  3. package/cli/commands/brand.js +33 -14
  4. package/cli/commands/init.js +21 -17
  5. package/cli/commands/install-skill.js +84 -26
  6. package/cli/templates/AGENTS.md +128 -0
  7. package/cli/templates/CLAUDE.md +8 -88
  8. package/cli/templates/muka-ui-guidelines.md +50 -14
  9. package/dist/cjs/components/Combobox/Combobox.css +116 -132
  10. package/dist/cjs/components/Combobox/Combobox.js +175 -52
  11. package/dist/cjs/components/Combobox/Combobox.js.map +1 -1
  12. package/dist/cjs/components/Combobox/index.js.map +1 -1
  13. package/dist/cjs/components/DropdownSelect/DropdownSelect.css +225 -0
  14. package/dist/cjs/components/DropdownSelect/DropdownSelect.js +106 -0
  15. package/dist/cjs/components/DropdownSelect/DropdownSelect.js.map +1 -0
  16. package/dist/cjs/components/DropdownSelect/index.js +6 -0
  17. package/dist/cjs/components/DropdownSelect/index.js.map +1 -0
  18. package/dist/cjs/components/Icon/custom/ArrowReturnIcon.js +11 -0
  19. package/dist/cjs/components/Icon/custom/ArrowReturnIcon.js.map +1 -0
  20. package/dist/cjs/components/Icon/iconRegistry.js +5 -0
  21. package/dist/cjs/components/Icon/iconRegistry.js.map +1 -1
  22. package/dist/cjs/components/Input/Input.css +45 -8
  23. package/dist/cjs/components/Input/Input.js +14 -3
  24. package/dist/cjs/components/Input/Input.js.map +1 -1
  25. package/dist/cjs/components/Menu/Menu.css +123 -37
  26. package/dist/cjs/components/Menu/Menu.js +283 -25
  27. package/dist/cjs/components/Menu/Menu.js.map +1 -1
  28. package/dist/cjs/components/ProgressTracker/ProgressTracker.css +273 -22
  29. package/dist/cjs/components/ProgressTracker/ProgressTracker.js +109 -9
  30. package/dist/cjs/components/ProgressTracker/ProgressTracker.js.map +1 -1
  31. package/dist/cjs/components/Scrollbar/Scrollbar.css +7 -6
  32. package/dist/cjs/components/index.js +5 -3
  33. package/dist/cjs/components/index.js.map +1 -1
  34. package/dist/esm/components/Combobox/Combobox.css +116 -132
  35. package/dist/esm/components/Combobox/Combobox.js +177 -54
  36. package/dist/esm/components/Combobox/Combobox.js.map +1 -1
  37. package/dist/esm/components/Combobox/index.js +1 -1
  38. package/dist/esm/components/Combobox/index.js.map +1 -1
  39. package/dist/esm/components/DropdownSelect/DropdownSelect.css +225 -0
  40. package/dist/esm/components/DropdownSelect/DropdownSelect.js +102 -0
  41. package/dist/esm/components/DropdownSelect/DropdownSelect.js.map +1 -0
  42. package/dist/esm/components/DropdownSelect/index.js +2 -0
  43. package/dist/esm/components/DropdownSelect/index.js.map +1 -0
  44. package/dist/esm/components/Icon/custom/ArrowReturnIcon.js +7 -0
  45. package/dist/esm/components/Icon/custom/ArrowReturnIcon.js.map +1 -0
  46. package/dist/esm/components/Icon/iconRegistry.js +5 -0
  47. package/dist/esm/components/Icon/iconRegistry.js.map +1 -1
  48. package/dist/esm/components/Input/Input.css +45 -8
  49. package/dist/esm/components/Input/Input.js +14 -3
  50. package/dist/esm/components/Input/Input.js.map +1 -1
  51. package/dist/esm/components/Menu/Menu.css +123 -37
  52. package/dist/esm/components/Menu/Menu.js +284 -26
  53. package/dist/esm/components/Menu/Menu.js.map +1 -1
  54. package/dist/esm/components/ProgressTracker/ProgressTracker.css +273 -22
  55. package/dist/esm/components/ProgressTracker/ProgressTracker.js +110 -10
  56. package/dist/esm/components/ProgressTracker/ProgressTracker.js.map +1 -1
  57. package/dist/esm/components/Scrollbar/Scrollbar.css +7 -6
  58. package/dist/esm/components/index.js +1 -0
  59. package/dist/esm/components/index.js.map +1 -1
  60. package/dist/styles/components/Combobox.css +116 -132
  61. package/dist/styles/components/DropdownSelect.css +225 -0
  62. package/dist/styles/components/Input.css +45 -8
  63. package/dist/styles/components/Menu.css +123 -37
  64. package/dist/styles/components/ProgressTracker.css +273 -22
  65. package/dist/styles/components/Scrollbar.css +7 -6
  66. package/dist/styles/components/Typography.css +89 -0
  67. package/dist/styles/index.css +1285 -605
  68. package/dist/styles/muka-dark.css +1285 -605
  69. package/dist/styles/muka-light.css +1285 -605
  70. package/dist/styles/tokens-bouwplan-dark.css +5 -4
  71. package/dist/styles/tokens-bouwplan-light.css +5 -4
  72. package/dist/styles/tokens-fscl-dark.css +25 -24
  73. package/dist/styles/tokens-fscl-light.css +25 -24
  74. package/dist/styles/tokens-grip-dark.css +4 -3
  75. package/dist/styles/tokens-grip-light.css +4 -3
  76. package/dist/styles/tokens-muka-dark.css +4 -3
  77. package/dist/styles/tokens-muka-light.css +4 -3
  78. package/dist/styles/tokens-wireframe-dark.css +49 -48
  79. package/dist/styles/tokens-wireframe-light.css +49 -48
  80. package/dist/styles/wireframe-dark.css +1330 -650
  81. package/dist/styles/wireframe-light.css +1330 -650
  82. package/dist/types/components/Combobox/Combobox.d.ts +38 -38
  83. package/dist/types/components/Combobox/Combobox.d.ts.map +1 -1
  84. package/dist/types/components/Combobox/index.d.ts +1 -1
  85. package/dist/types/components/Combobox/index.d.ts.map +1 -1
  86. package/dist/types/components/DropdownSelect/DropdownSelect.d.ts +71 -0
  87. package/dist/types/components/DropdownSelect/DropdownSelect.d.ts.map +1 -0
  88. package/dist/types/components/DropdownSelect/index.d.ts +2 -0
  89. package/dist/types/components/DropdownSelect/index.d.ts.map +1 -0
  90. package/dist/types/components/Icon/custom/ArrowReturnIcon.d.ts +9 -0
  91. package/dist/types/components/Icon/custom/ArrowReturnIcon.d.ts.map +1 -0
  92. package/dist/types/components/Icon/iconRegistry.d.ts.map +1 -1
  93. package/dist/types/components/Input/Input.d.ts +5 -0
  94. package/dist/types/components/Input/Input.d.ts.map +1 -1
  95. package/dist/types/components/Menu/Menu.d.ts +42 -2
  96. package/dist/types/components/Menu/Menu.d.ts.map +1 -1
  97. package/dist/types/components/ProgressTracker/ProgressTracker.d.ts +29 -8
  98. package/dist/types/components/ProgressTracker/ProgressTracker.d.ts.map +1 -1
  99. package/dist/types/components/index.d.ts +1 -0
  100. package/dist/types/components/index.d.ts.map +1 -1
  101. package/docs/consumers/README.md +116 -37
  102. package/docs/consumers/brand.md +261 -0
  103. package/docs/consumers/figma-console-mcp.md +116 -0
  104. package/docs/consumers/setup-instructions.md +98 -12
  105. package/docs/consumers/skills.md +79 -0
  106. package/package.json +4 -6
  107. package/scripts/postinstall-nudge.js +8 -4
  108. package/skills/add-brand/SKILL.md +204 -0
  109. package/skills/add-brand/reference.md +160 -0
  110. package/skills/figma-to-code/SKILL.md +127 -0
  111. package/skills/pull-from-figma/SKILL.md +123 -0
  112. package/skills/push-to-figma/SKILL.md +172 -0
  113. package/skills/setup-muka/SKILL.md +73 -13
  114. package/tokens/README.md +39 -17
  115. package/tokens/t2-alias/brand/bouwplan/fonts.json +1 -1
  116. package/tokens/t2-alias/brand/fscl/fonts.json +3 -3
  117. package/tokens/t2-alias/brand/wireframe/fonts.json +2 -2
  118. package/tokens/t4-components/menu.json +8 -3
@@ -0,0 +1,128 @@
1
+ # Project Guidelines for AI Development
2
+
3
+ > Generated by `muka-ui init` on {{DATE}}
4
+
5
+ This is the vendor-neutral brief every coding agent reads. `CLAUDE.md` points
6
+ here rather than repeating it, so there is one copy to keep current.
7
+
8
+ ---
9
+
10
+ ## UI Component Constraint
11
+
12
+ **This project uses Muka UI as its sole component library. All UI must be built with components from muka-ui.**
13
+
14
+ ### Rules
15
+
16
+ 1. **Only use components available in Muka UI**
17
+ - Check availability at {{STORYBOOK_URL}}
18
+ - Import from `'{{PACKAGE_NAME}}'`
19
+
20
+ 2. **No alternative styling solutions for UI components**
21
+ - No Tailwind utilities for component styling
22
+ - No CSS modules for UI elements
23
+ - No styled-components or Emotion
24
+ - No inline styles except for layout (using Muka tokens)
25
+
26
+ 3. **When a component doesn't exist**
27
+ - Do NOT create a local component as a workaround
28
+ - Note the missing component as a blocker
29
+ - The component must be built in muka-ui first
30
+ - Once available in Storybook, it can be used here
31
+
32
+ ### Imports
33
+
34
+ ```tsx
35
+ // Import components
36
+ import { Button, Card, Input, Chip } from '{{PACKAGE_NAME}}';
37
+
38
+ // Import styles (choose one theme) — these bundles include the brand's fonts
39
+ import '{{PACKAGE_NAME}}/styles'; // Default muka-light + muka fonts
40
+ import '{{PACKAGE_NAME}}/styles/muka-dark.css'; // muka-dark + muka fonts
41
+ import '{{PACKAGE_NAME}}/styles/wireframe-light.css'; // wireframe (system fonts)
42
+
43
+ // For a brand loaded via its raw token file (e.g. bouwplan/grip/fscl), also import fonts:
44
+ import '{{PACKAGE_NAME}}/styles/tokens-bouwplan-light.css';
45
+ import '{{PACKAGE_NAME}}/styles/fonts-bouwplan.css';
46
+ ```
47
+
48
+ ### Fonts come from Muka — never load them yourself
49
+
50
+ - Muka self-hosts every brand's fonts as `@font-face` (offline-ready, no CDN). The
51
+ default `/styles` bundle and the `/styles/muka-*.css` + `/styles/wireframe-*.css`
52
+ bundles already include them; only a brand loaded via a raw `tokens-<brand>-<mode>.css`
53
+ file needs a separate `{{PACKAGE_NAME}}/styles/fonts-<brand>.css` import.
54
+ - Do NOT load these fonts via `next/font` or a Google Fonts `<link>`.
55
+ - Do NOT override the `--*-fontFamily` / `--alias-font-*-family` tokens — their
56
+ values are the exact `@font-face` family names.
57
+
58
+ ### Acceptable Styling Patterns
59
+
60
+ ```tsx
61
+ // ✅ GOOD: Use Muka UI components
62
+ import { Button, Card } from '{{PACKAGE_NAME}}';
63
+
64
+ // ✅ GOOD: Use Muka UI tokens for layout
65
+ <div style={{
66
+ display: 'flex',
67
+ gap: 'var(--spacing-4)',
68
+ padding: 'var(--spacing-6)'
69
+ }}>
70
+
71
+ // ✅ GOOD: Use semantic color tokens
72
+ <span style={{ color: 'var(--color-text-subtle-default)' }}>
73
+
74
+ // ❌ BAD: Tailwind classes
75
+ <div className="flex gap-4 p-6">
76
+
77
+ // ❌ BAD: CSS modules
78
+ import styles from './Component.module.css';
79
+
80
+ // ❌ BAD: Arbitrary values
81
+ <div style={{ color: '#6366f1', padding: '24px' }}>
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Available Components
87
+
88
+ {{COMPONENT_LIST}}
89
+
90
+ For the full component API and examples, visit: {{STORYBOOK_URL}}
91
+
92
+ ---
93
+
94
+ ## Theme and brand selection
95
+
96
+ Muka's token stylesheets are `:root`-scoped. There are **no `[data-brand]` or
97
+ `[data-theme]` selectors**, so the active theme is whichever stylesheet loaded
98
+ last. Do not add those attributes expecting them to switch anything — to toggle
99
+ at runtime, swap a `<link href>` to a different `tokens-<brand>-<mode>.css`.
100
+
101
+ If this repo has a `brand/` directory, it owns a **custom brand** that overrides
102
+ Muka's brand layer. In that case:
103
+
104
+ - Edit colours and fonts only in `brand/light.json`, `brand/dark.json`, and
105
+ `brand/fonts.json`, using `{color.*}` primitive references rather than hex.
106
+ - Run `npm run build:tokens` after any change, and after every Muka upgrade.
107
+ - Never edit semantic or component tokens — they come from `node_modules` and are
108
+ replaced on upgrade.
109
+
110
+ ---
111
+
112
+ ## Muka skills
113
+
114
+ `npx muka-ui install-skill --list` shows the skills the installed version ships.
115
+ `/add-brand` creates or revises this repo's brand; `/figma-to-code` turns a Figma
116
+ link into a screen built from Muka components.
117
+
118
+ Skills install to `.claude/skills/`, which is the directory Claude Code and
119
+ Cursor both read. An agent that does not read that path can still follow the
120
+ skills, since each is a plain markdown file — point it at
121
+ `.claude/skills/<name>/SKILL.md`.
122
+
123
+ ## Human Docs
124
+ <!-- SYNC: Update paths when Storybook docs change -->
125
+ - Storybook: {{STORYBOOK_URL}}
126
+ - Local guidelines: `docs/muka-ui-guidelines.md`
127
+ - Consumer docs: `node_modules/{{PACKAGE_NAME}}/docs/consumers/README.md`
128
+ - Package: {{PACKAGE_NAME}} v{{VERSION}}
@@ -1,95 +1,15 @@
1
- # Project Guidelines for AI Development
1
+ # CLAUDE.md
2
2
 
3
3
  > Generated by `muka-ui init` on {{DATE}}
4
4
 
5
- ---
5
+ The guidelines for this project live in [`AGENTS.md`](AGENTS.md) — the
6
+ vendor-neutral file every coding agent reads. Read it before writing UI code.
6
7
 
7
- ## UI Component Constraint
8
-
9
- **This project uses Muka UI as its sole component library. All UI must be built with components from muka-ui.**
10
-
11
- ### Rules
12
-
13
- 1. **Only use components available in Muka UI**
14
- - Check availability at {{STORYBOOK_URL}}
15
- - Import from `'{{PACKAGE_NAME}}'`
16
-
17
- 2. **No alternative styling solutions for UI components**
18
- - No Tailwind utilities for component styling
19
- - No CSS modules for UI elements
20
- - No styled-components or Emotion
21
- - No inline styles except for layout (using Muka tokens)
22
-
23
- 3. **When a component doesn't exist**
24
- - Do NOT create a local component as a workaround
25
- - Note the missing component as a blocker
26
- - The component must be built in muka-ui first
27
- - Once available in Storybook, it can be used here
28
-
29
- ### Imports
30
-
31
- ```tsx
32
- // Import components
33
- import { Button, Card, Input, Chip } from '{{PACKAGE_NAME}}';
34
-
35
- // Import styles (choose one theme) — these bundles include the brand's fonts
36
- import '{{PACKAGE_NAME}}/styles'; // Default muka-light + muka fonts
37
- import '{{PACKAGE_NAME}}/styles/muka-dark.css'; // muka-dark + muka fonts
38
- import '{{PACKAGE_NAME}}/styles/wireframe-light.css'; // wireframe (system fonts)
39
-
40
- // For a brand loaded via its raw token file (e.g. bouwplan/grip/fscl), also import fonts:
41
- import '{{PACKAGE_NAME}}/styles/tokens-bouwplan-light.css';
42
- import '{{PACKAGE_NAME}}/styles/fonts-bouwplan.css';
43
- ```
44
-
45
- ### Fonts come from Muka — never load them yourself
46
-
47
- - Muka self-hosts every brand's fonts as `@font-face` (offline-ready, no CDN). The
48
- default `/styles` bundle and the `/styles/muka-*.css` + `/styles/wireframe-*.css`
49
- bundles already include them; only a brand loaded via a raw `tokens-<brand>-<mode>.css`
50
- file needs a separate `{{PACKAGE_NAME}}/styles/fonts-<brand>.css` import.
51
- - Do NOT load these fonts via `next/font` or a Google Fonts `<link>`.
52
- - Do NOT override the `--*-fontFamily` / `--alias-font-*-family` tokens — their
53
- values are the exact `@font-face` family names.
54
-
55
- ### Acceptable Styling Patterns
56
-
57
- ```tsx
58
- // ✅ GOOD: Use Muka UI components
59
- import { Button, Card } from '{{PACKAGE_NAME}}';
60
-
61
- // ✅ GOOD: Use Muka UI tokens for layout
62
- <div style={{
63
- display: 'flex',
64
- gap: 'var(--spacing-4)',
65
- padding: 'var(--spacing-6)'
66
- }}>
67
-
68
- // ✅ GOOD: Use semantic color tokens
69
- <span style={{ color: 'var(--color-text-subtle-default)' }}>
70
-
71
- // ❌ BAD: Tailwind classes
72
- <div className="flex gap-4 p-6">
73
-
74
- // ❌ BAD: CSS modules
75
- import styles from './Component.module.css';
76
-
77
- // ❌ BAD: Arbitrary values
78
- <div style={{ color: '#6366f1', padding: '24px' }}>
79
- ```
80
-
81
- ---
82
-
83
- ## Available Components
84
-
85
- {{COMPONENT_LIST}}
86
-
87
- For the full component API and examples, visit: {{STORYBOOK_URL}}
88
-
89
- ---
8
+ It covers: Muka UI as the sole component library, the styling patterns that are
9
+ and are not allowed, how fonts and theme selection work, and the Muka skills
10
+ available in this repo.
90
11
 
91
12
  ## Human Docs
92
- <!-- SYNC: Update paths when Storybook docs change -->
13
+ - Guidelines: `AGENTS.md`
93
14
  - Storybook: {{STORYBOOK_URL}}
94
- - Local guidelines: `docs/muka-ui-guidelines.md`
95
- - Package: {{PACKAGE_NAME}} v{{VERSION}}
15
+ - Consumer docs: `node_modules/{{PACKAGE_NAME}}/docs/consumers/README.md`
@@ -71,17 +71,25 @@ import '{{PACKAGE_NAME}}/styles/fonts-bouwplan.css';
71
71
 
72
72
  ### Theme Switching
73
73
 
74
- To support dynamic theme switching, import all themes and toggle via a CSS class or attribute:
74
+ Every Muka stylesheet declares its variables on `:root`. There are **no
75
+ `[data-brand]` or `[data-theme]` selectors**, so the active theme is simply
76
+ whichever stylesheet loaded last — importing two of them means one always wins.
77
+ Setting `data-theme` does nothing.
75
78
 
76
- ```tsx
77
- // In your root layout
78
- import '{{PACKAGE_NAME}}/styles/muka-light.css';
79
- import '{{PACKAGE_NAME}}/styles/muka-dark.css';
79
+ For a runtime light/dark toggle, swap a `<link>` rather than importing both:
80
80
 
81
- // Apply theme via data attribute or class
82
- <html data-theme="muka-dark">
81
+ ```html
82
+ <link id="muka-theme" rel="stylesheet" href="/styles/tokens-muka-light.css" />
83
83
  ```
84
84
 
85
+ ```ts
86
+ document.getElementById('muka-theme').href =
87
+ `/styles/tokens-${brand}-${mode}.css`;
88
+ ```
89
+
90
+ Copy the token CSS you need into this project's static/public directory so those
91
+ hrefs resolve. If the app only ever needs one theme, a plain import is simpler.
92
+
85
93
  ---
86
94
 
87
95
  ## Available Components
@@ -120,7 +128,8 @@ var(--spacing-12) /* 3rem */
120
128
  /* Text */
121
129
  var(--color-text-default-default)
122
130
  var(--color-text-subtle-default)
123
- var(--color-text-inverse-default)
131
+ var(--color-text-muted-default)
132
+ var(--color-text-default-inverse) /* on an inverted surface */
124
133
 
125
134
  /* Backgrounds */
126
135
  var(--color-surface-level1)
@@ -143,9 +152,16 @@ var(--color-action-pressed)
143
152
  ```css
144
153
  var(--alias-font-brand-family)
145
154
  var(--alias-font-brand-weight-semibold)
146
- var(--text-label-sm-fontSize)
147
- var(--text-label-md-fontSize)
148
- var(--text-label-lg-fontSize)
155
+
156
+ /* Text styles are composite: --text-<role>-<size>-<weight>-<property>.
157
+ The weight is part of the name, so there is no --text-label-md-fontSize.
158
+ Weights: regular | semibold | bold
159
+ label sizes: xs sm md lg xl 2xl
160
+ body sizes: xs sm base lg xl 2xl (body uses "base", not "md") */
161
+ var(--text-label-md-regular-fontSize)
162
+ var(--text-label-md-semibold-lineHeight)
163
+ var(--text-body-base-regular-fontSize)
164
+ var(--text-body-base-regular-lineHeight)
149
165
  ```
150
166
 
151
167
  ---
@@ -159,16 +175,36 @@ If you need a component that doesn't exist in Muka UI:
159
175
  2. **Don't create a local workaround** — this defeats the purpose of using a design system
160
176
 
161
177
  3. **Request the component** by:
162
- - Opening an issue in the muka-ui repository
163
- - Or building it yourself in muka-ui and submitting a PR
178
+ - Opening an issue at https://github.com/revikornmann/muka/issues
179
+ - Or building it yourself in muka and submitting a PR
164
180
 
165
181
  4. **Wait for availability** — once the component is in Storybook, you can use it
166
182
 
167
183
  ---
168
184
 
185
+ ## Muka skills available in this repo
186
+
187
+ Installed with `npx muka-ui install-skill` (run `--list` to see what the
188
+ installed version ships):
189
+
190
+ | Skill | Use it to |
191
+ |---|---|
192
+ | `/setup-muka` | Install and wire up Muka, including the auto-update workflow |
193
+ | `/add-brand` | Give this repo its own brand, overriding Muka's brand layer |
194
+ | `/figma-to-code` | Turn a Figma link into a screen composed from Muka components |
195
+ | `/push-to-figma` | Publish this repo's brand to Figma as variables |
196
+ | `/pull-from-figma` | Bring a designer's Figma brand edits back into the token files |
197
+
198
+ The two Figma sync skills need [Figma Console
199
+ MCP](https://github.com/southleft/figma-console-mcp); see
200
+ `node_modules/{{PACKAGE_NAME}}/docs/consumers/figma-console-mcp.md`.
201
+
202
+ ---
203
+
169
204
  ## Human Docs
170
205
  <!-- SYNC: Update paths when Storybook docs change -->
171
206
 
172
207
  - **Storybook:** {{STORYBOOK_URL}}
173
- - **GitHub:** https://github.com/uxdelta/muka
208
+ - **GitHub:** https://github.com/revikornmann/muka
209
+ - **Consumer docs:** `node_modules/{{PACKAGE_NAME}}/docs/consumers/README.md`
174
210
  - **Package:** {{PACKAGE_NAME}} v{{VERSION}}
@@ -1,186 +1,170 @@
1
- /* Combobox Component Styles */
1
+ /* Combobox — Figma Input Combobox (free-input chips + suggestion Menu) */
2
2
 
3
- /* ─── Trigger group (positioning context for the trailing controls) ── */
3
+ .muka-combobox {
4
+ display: inline-flex;
5
+ flex-direction: column;
6
+ gap: var(--spacing-2);
7
+ min-width: 200px;
8
+ }
4
9
 
5
- /*
6
- * The clear control is a sibling of the trigger, not a child (a <button> may
7
- * not contain interactive content), so it is overlaid on the trigger's trailing
8
- * padding. The trigger reserves that space with padding-right below.
9
- */
10
- .muka-combobox__trigger-group {
11
- position: relative;
12
- display: block;
10
+ .muka-combobox--full-width {
13
11
  width: 100%;
14
12
  }
15
13
 
16
- /* ─── Trigger (looks like an Input field, behaves like a button) ── */
14
+ .muka-combobox__label {
15
+ color: var(--color-text-default-default);
16
+ cursor: pointer;
17
+ }
18
+
19
+ .muka-combobox__label--sm {
20
+ font-family: var(--text-label-sm-semibold-fontFamily);
21
+ font-weight: var(--text-label-sm-semibold-fontWeight);
22
+ font-size: var(--text-label-sm-semibold-fontSize);
23
+ line-height: var(--text-label-sm-semibold-lineHeight);
24
+ }
17
25
 
18
- .muka-combobox {
19
- display: inline-flex;
26
+ .muka-combobox__label--md {
27
+ font-family: var(--text-label-md-semibold-fontFamily);
28
+ font-weight: var(--text-label-md-semibold-fontWeight);
29
+ font-size: var(--text-label-md-semibold-fontSize);
30
+ line-height: var(--text-label-md-semibold-lineHeight);
31
+ }
32
+
33
+ .muka-combobox__label--lg {
34
+ font-family: var(--text-label-lg-semibold-fontFamily);
35
+ font-weight: var(--text-label-lg-semibold-fontWeight);
36
+ font-size: var(--text-label-lg-semibold-fontSize);
37
+ line-height: var(--text-label-lg-semibold-lineHeight);
38
+ }
39
+
40
+ .muka-combobox__field {
41
+ display: flex;
20
42
  align-items: center;
21
- gap: var(--spacing-2);
22
43
  width: 100%;
23
- padding: 0 var(--muka-combobox-trailing-space) 0 var(--input-field-padding-x);
44
+ position: relative;
45
+ isolation: isolate;
46
+ box-sizing: border-box;
24
47
  background-color: var(--input-field-color-default-background);
25
48
  border: var(--border-width-regular) solid var(--input-field-color-default-border);
26
- color: var(--color-text-default-default);
27
- text-align: left;
28
- cursor: pointer;
29
- font-family: var(--text-body-md-regular-fontFamily);
30
- font-weight: var(--text-body-md-regular-fontWeight);
31
- font-size: var(--text-body-md-regular-fontSize);
32
- line-height: var(--text-body-md-regular-lineHeight);
33
- -webkit-tap-highlight-color: transparent;
34
- transition: border-color 0.12s ease;
35
-
36
- /* Room for the chevron overlaid on the trailing edge. */
37
- --muka-combobox-trailing-space: calc(
38
- var(--input-field-padding-x) + var(--icon-size-sm) + var(--spacing-2)
39
- );
49
+ border-radius: var(--input-field-radius-lg);
50
+ padding: var(--spacing-2);
51
+ cursor: text;
52
+ transition: border-color 0.12s ease, background-color 0.12s ease;
40
53
  }
41
54
 
42
- /* …and for the clear button next to it, when one is rendered. */
43
- .muka-combobox--clearable {
44
- --muka-combobox-trailing-space: calc(
45
- var(--input-field-padding-x) + var(--icon-size-sm) + var(--spacing-2) +
46
- var(--icon-size-xs) + var(--spacing-1) * 2 + var(--spacing-2)
47
- );
55
+ .muka-combobox__field::after {
56
+ content: '';
57
+ position: absolute;
58
+ inset: 0;
59
+ border-radius: inherit;
60
+ box-shadow: inset 0 1px 2px 0 rgba(26, 26, 26, 0.08);
61
+ pointer-events: none;
48
62
  }
49
63
 
50
- .muka-combobox--sm {
64
+ .muka-combobox__field--sm {
51
65
  min-height: var(--input-field-height-sm);
52
66
  border-radius: var(--input-field-radius-sm);
53
67
  }
54
68
 
55
- .muka-combobox--md {
69
+ .muka-combobox__field--md {
56
70
  min-height: var(--input-field-height-default);
57
71
  border-radius: var(--input-field-radius-md);
58
72
  }
59
73
 
60
- .muka-combobox--lg {
74
+ .muka-combobox__field--lg {
61
75
  min-height: var(--input-field-height-lg);
62
76
  border-radius: var(--input-field-radius-lg);
63
77
  }
64
78
 
65
- .muka-combobox:hover:not(:disabled) {
66
- border-color: var(--input-field-color-hover-border, var(--input-field-color-default-border));
79
+ .muka-combobox__field--focused:not(.muka-combobox__field--disabled) {
80
+ border-width: var(--border-width-bold);
81
+ border-color: var(--input-field-color-focus-border);
82
+ background-color: var(--input-field-color-focus-background);
83
+ padding: calc(var(--spacing-2) - 1px);
67
84
  }
68
85
 
69
- .muka-combobox:focus-visible {
70
- outline: none;
71
- border-color: var(--input-field-color-focus-border, var(--color-action-default));
86
+ .muka-combobox__field--error:not(.muka-combobox__field--disabled) {
87
+ border-color: var(--color-state-error-border, var(--color-state-error-foreground));
72
88
  }
73
89
 
74
- .muka-combobox--disabled,
75
- .muka-combobox:disabled {
90
+ .muka-combobox__field--disabled {
76
91
  opacity: 0.5;
77
92
  cursor: not-allowed;
78
93
  }
79
94
 
80
- .muka-combobox--placeholder .muka-combobox__label {
81
- color: var(--color-text-subtle-default);
82
- }
83
-
84
- .muka-combobox__leading {
85
- display: inline-flex;
86
- align-items: center;
87
- justify-content: center;
88
- flex-shrink: 0;
89
- color: var(--color-text-subtle-default);
90
- }
91
-
92
- .muka-combobox__label {
93
- flex: 1 1 auto;
94
- min-width: 0;
95
- white-space: nowrap;
96
- overflow: hidden;
97
- text-overflow: ellipsis;
95
+ .muka-combobox__field--multiline {
96
+ align-items: flex-start;
97
+ min-height: 7rem;
98
98
  }
99
99
 
100
- /* ─── Trailing controls (clear + chevron) ─────────────── */
101
-
102
- .muka-combobox__actions {
103
- position: absolute;
104
- top: 0;
105
- right: var(--input-field-padding-x);
106
- height: 100%;
100
+ .muka-combobox__chips {
107
101
  display: flex;
108
- align-items: center;
102
+ flex: 1 1 auto;
103
+ flex-wrap: wrap;
109
104
  gap: var(--spacing-2);
110
- /*
111
- * The strip sits on top of the trigger, so it must not swallow taps meant to
112
- * open the picker. Only the clear button takes pointer events back.
113
- */
114
- pointer-events: none;
115
- }
116
-
117
- .muka-combobox__clear,
118
- .muka-combobox__chevron {
119
- display: inline-flex;
120
105
  align-items: center;
121
- justify-content: center;
122
- flex-shrink: 0;
123
- color: var(--color-text-subtle-default);
106
+ min-width: 0;
107
+ width: 100%;
108
+ position: relative;
109
+ z-index: 1;
124
110
  }
125
111
 
126
- .muka-combobox__clear {
127
- pointer-events: auto;
128
- cursor: pointer;
129
- padding: var(--spacing-1);
112
+ .muka-combobox__input {
113
+ flex: 1 1 5rem;
114
+ min-width: 5rem;
115
+ min-height: 2rem;
116
+ margin: 0;
117
+ padding: 0 var(--spacing-1);
130
118
  border: none;
131
- background: none;
132
- border-radius: var(--radius-sm);
133
- -webkit-tap-highlight-color: transparent;
134
- }
135
-
136
- .muka-combobox__clear:hover {
137
- color: var(--color-text-default-default);
138
- background-color: var(--color-surface-level1);
139
- }
140
-
141
- .muka-combobox__clear:focus-visible {
142
- outline: 2px solid var(--color-border-focus);
143
- outline-offset: 2px;
144
- color: var(--color-text-default-default);
119
+ outline: none;
120
+ background: transparent;
121
+ color: var(--input-field-color-default-foreground);
122
+ caret-color: var(--input-field-color-default-foreground);
123
+ font-family: var(--text-label-md-regular-fontFamily);
124
+ font-size: var(--text-label-md-regular-fontSize);
125
+ font-weight: var(--text-label-md-regular-fontWeight);
126
+ line-height: var(--text-label-md-regular-lineHeight);
145
127
  }
146
128
 
147
- .muka-combobox--disabled ~ .muka-combobox__actions,
148
- .muka-combobox:disabled ~ .muka-combobox__actions {
149
- opacity: 0.5;
129
+ .muka-combobox__input::placeholder {
130
+ color: var(--color-text-subtle-default);
150
131
  }
151
132
 
152
- /* ─── Picker sheet body ───────────────────────────────── */
153
-
154
- .muka-combobox__picker {
155
- display: flex;
156
- flex-direction: column;
157
- gap: var(--spacing-3);
158
- padding: 0 var(--spacing-4) var(--spacing-4);
159
- min-height: 0;
160
- max-height: 80vh;
133
+ .muka-combobox__helper {
134
+ margin: 0;
135
+ color: var(--color-text-subtle-default);
136
+ font-family: var(--text-label-sm-regular-fontFamily);
137
+ font-size: var(--text-label-sm-regular-fontSize);
138
+ font-weight: var(--text-label-sm-regular-fontWeight);
139
+ line-height: var(--text-label-sm-regular-lineHeight);
161
140
  }
162
141
 
163
- .muka-combobox__title {
142
+ .muka-combobox__error {
164
143
  margin: 0;
165
- padding: var(--spacing-2) 0;
166
- color: var(--color-text-default-default);
167
- font-family: var(--text-heading-sm-fontFamily);
168
- font-weight: var(--text-heading-sm-fontWeight);
169
- font-size: var(--text-heading-sm-fontSize);
170
- line-height: var(--text-heading-sm-lineHeight);
144
+ color: var(--color-state-error-foreground);
145
+ font-family: var(--text-label-sm-regular-fontFamily);
146
+ font-size: var(--text-label-sm-regular-fontSize);
147
+ font-weight: var(--text-label-sm-regular-fontWeight);
148
+ line-height: var(--text-label-sm-regular-lineHeight);
171
149
  }
172
150
 
173
- .muka-combobox__search {
174
- position: sticky;
175
- top: 0;
176
- z-index: 1;
177
- padding-bottom: var(--spacing-2);
178
- background-color: var(--color-surface-level3);
151
+ .muka-combobox__menu-anchor {
152
+ position: absolute;
153
+ inset: 0;
154
+ z-index: 0;
155
+ width: 100%;
156
+ height: 100%;
157
+ margin: 0;
158
+ padding: 0;
159
+ border: none;
160
+ background: transparent;
161
+ pointer-events: none;
162
+ opacity: 0;
179
163
  }
180
164
 
181
- .muka-combobox__list {
182
- flex: 1 1 auto;
183
- min-height: 0;
184
- overflow-y: auto;
185
- -webkit-overflow-scrolling: touch;
165
+ .muka-combobox__menu {
166
+ /* Prefer Menu token min-width (280px); may exceed the field when left-aligned. */
167
+ min-width: var(--menu-content-min-width);
168
+ width: max-content;
169
+ max-width: min(100vw - 2rem, 24rem);
186
170
  }