myoperator-mcp 0.2.266 → 0.2.268

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 (2) hide show
  1. package/dist/index.js +108 -89
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1635,21 +1635,6 @@ const CreatableMultiSelect = React.forwardRef(
1635
1635
  )
1636
1636
  : availablePresets
1637
1637
 
1638
- const afterSanitizeDraft = sanitizeInput
1639
- ? sanitizeInput(inputValue)
1640
- : inputValue
1641
- const trimmedDraft = afterSanitizeDraft.trim()
1642
- const draftForCreate = trimmedDraft
1643
- ? maxLengthPerItem != null
1644
- ? trimmedDraft.slice(0, maxLengthPerItem)
1645
- : trimmedDraft
1646
- : ""
1647
-
1648
- const canShowEnterAffordance =
1649
- Boolean(draftForCreate) &&
1650
- !value.includes(draftForCreate) &&
1651
- (maxItems == null || value.length < maxItems)
1652
-
1653
1638
  const panelInputPlaceholder = createHintText ?? placeholder
1654
1639
 
1655
1640
  const summaryTriggerLabel =
@@ -1668,21 +1653,71 @@ const CreatableMultiSelect = React.forwardRef(
1668
1653
  creatableSelectTriggerVariants({ state: derivedState }),
1669
1654
  "flex h-auto min-h-[42px] cursor-text items-start gap-2 py-2 text-left"
1670
1655
  )}
1671
- onClick={() => !disabled && inputRef.current?.focus()}
1672
- aria-hidden="true"
1656
+ onClick={(e) => {
1657
+ if (disabled) return
1658
+ if ((e.target as HTMLElement).closest("[data-chip-remove]")) {
1659
+ return
1660
+ }
1661
+ inputRef.current?.focus()
1662
+ }}
1673
1663
  >
1674
- <span
1675
- className={cn(
1676
- "line-clamp-2 min-w-0 flex-1 text-base",
1677
- value.length === 0
1678
- ? "text-semantic-text-muted"
1679
- : "text-semantic-text-primary"
1664
+ <div className="flex min-h-0 min-w-0 flex-1 flex-wrap content-start items-center gap-1.5">
1665
+ {triggerDisplay === "summary" ? (
1666
+ <span
1667
+ className={cn(
1668
+ "line-clamp-2 flex-1 text-base",
1669
+ value.length === 0
1670
+ ? "text-semantic-text-muted"
1671
+ : "text-semantic-text-primary"
1672
+ )}
1673
+ >
1674
+ {summaryTriggerLabel}
1675
+ </span>
1676
+ ) : value.length === 0 ? (
1677
+ <span
1678
+ className={cn(
1679
+ "line-clamp-2 flex-1 text-base",
1680
+ "text-semantic-text-muted"
1681
+ )}
1682
+ >
1683
+ {placeholder}
1684
+ </span>
1685
+ ) : (
1686
+ value.map((val) => (
1687
+ <span
1688
+ key={val}
1689
+ className="inline-flex max-w-full items-center gap-0.5 rounded bg-semantic-bg-ui py-1 pl-2 pr-0.5 text-sm text-semantic-text-primary"
1690
+ >
1691
+ <span className="min-w-0 truncate">
1692
+ {labelForValue(val, options)}
1693
+ </span>
1694
+ <button
1695
+ type="button"
1696
+ data-chip-remove
1697
+ disabled={disabled}
1698
+ aria-label={\`Remove \${labelForValue(val, options)}\`}
1699
+ className={cn(
1700
+ "inline-flex size-6 shrink-0 items-center justify-center rounded text-semantic-text-muted transition-colors",
1701
+ !disabled &&
1702
+ "hover:bg-semantic-bg-hover hover:text-semantic-text-primary"
1703
+ )}
1704
+ onMouseDown={(e) => {
1705
+ e.preventDefault()
1706
+ e.stopPropagation()
1707
+ }}
1708
+ onClick={(e) => {
1709
+ e.stopPropagation()
1710
+ if (!disabled) removeValue(val)
1711
+ }}
1712
+ >
1713
+ <X className="size-3.5" strokeWidth={2} aria-hidden />
1714
+ </button>
1715
+ </span>
1716
+ ))
1680
1717
  )}
1681
- >
1682
- {summaryTriggerLabel}
1683
- </span>
1718
+ </div>
1684
1719
  <ChevronDown
1685
- className="mt-1 size-5 shrink-0 self-start text-semantic-text-muted opacity-70"
1720
+ className="mt-1 size-4 shrink-0 self-start rotate-180 text-semantic-text-muted opacity-70 transition-transform"
1686
1721
  aria-hidden
1687
1722
  />
1688
1723
  </div>
@@ -1772,7 +1807,7 @@ const CreatableMultiSelect = React.forwardRef(
1772
1807
  )}
1773
1808
  </div>
1774
1809
  <ChevronDown
1775
- className="mt-1 size-5 shrink-0 self-start text-semantic-text-muted opacity-70"
1810
+ className="mt-1 size-4 shrink-0 self-start text-semantic-text-muted opacity-70 transition-transform"
1776
1811
  aria-hidden
1777
1812
  />
1778
1813
  </div>
@@ -1806,29 +1841,16 @@ const CreatableMultiSelect = React.forwardRef(
1806
1841
  onKeyDown={handleKeyDown}
1807
1842
  disabled={disabled}
1808
1843
  placeholder={panelInputPlaceholder}
1809
- className="min-w-0 flex-1 bg-transparent text-base text-semantic-text-primary outline-none placeholder:text-semantic-text-muted"
1844
+ className="min-w-0 flex-1 bg-transparent text-sm text-semantic-text-primary outline-none placeholder:text-semantic-text-muted"
1810
1845
  role="combobox"
1811
1846
  aria-expanded={isOpen}
1812
1847
  aria-controls={listboxId}
1813
1848
  aria-haspopup="listbox"
1814
1849
  aria-autocomplete="list"
1815
1850
  />
1816
- <button
1817
- type="button"
1818
- disabled={disabled || !canShowEnterAffordance}
1819
- onMouseDown={(e) => {
1820
- e.preventDefault()
1821
- }}
1822
- onClick={() => {
1823
- if (draftForCreate) addValue(inputValue)
1824
- }}
1825
- className={cn(
1826
- creatableEnterHintKbdClassName,
1827
- "shrink-0 enabled:cursor-pointer enabled:hover:bg-semantic-bg-hover disabled:opacity-50"
1828
- )}
1829
- >
1851
+ <kbd className={cn(creatableEnterHintKbdClassName, "shrink-0")}>
1830
1852
  Enter \u21B5
1831
- </button>
1853
+ </kbd>
1832
1854
  </div>
1833
1855
  </div>
1834
1856
 
@@ -1839,45 +1861,6 @@ const CreatableMultiSelect = React.forwardRef(
1839
1861
  </p>
1840
1862
  ) : null}
1841
1863
 
1842
- {value.length > 0 ? (
1843
- <div
1844
- className="flex flex-wrap gap-1.5 border-b border-solid border-semantic-border-layout pb-2.5"
1845
- aria-label="Selected values"
1846
- >
1847
- {value.map((val) => (
1848
- <span
1849
- key={val}
1850
- className="inline-flex max-w-full items-center gap-0.5 rounded bg-semantic-bg-ui py-1 pl-2 pr-0.5 text-sm text-semantic-text-primary"
1851
- >
1852
- <span className="min-w-0 truncate">
1853
- {labelForValue(val, options)}
1854
- </span>
1855
- <button
1856
- type="button"
1857
- data-chip-remove
1858
- disabled={disabled}
1859
- aria-label={\`Remove \${labelForValue(val, options)}\`}
1860
- className={cn(
1861
- "inline-flex size-6 shrink-0 items-center justify-center rounded text-semantic-text-muted transition-colors",
1862
- !disabled &&
1863
- "hover:bg-semantic-bg-hover hover:text-semantic-text-primary"
1864
- )}
1865
- onMouseDown={(e) => {
1866
- e.preventDefault()
1867
- e.stopPropagation()
1868
- }}
1869
- onClick={(e) => {
1870
- e.stopPropagation()
1871
- if (!disabled) removeValue(val)
1872
- }}
1873
- >
1874
- <X className="size-3.5" strokeWidth={2} aria-hidden />
1875
- </button>
1876
- </span>
1877
- ))}
1878
- </div>
1879
- ) : null}
1880
-
1881
1864
  <div
1882
1865
  id={listboxId}
1883
1866
  role="listbox"
@@ -1976,9 +1959,9 @@ export const creatablePrimaryRoleHintRowClassName = cn(
1976
1959
  "flex items-center justify-between border-b border-solid border-semantic-border-layout px-4 py-2"
1977
1960
  )
1978
1961
 
1979
- /** Tone / CreatableMultiSelect: inner hint row (place inside a full-bleed wrapper with \`-mx-4\` + \`border-b\` on the panel). */
1962
+ /** Tone / CreatableMultiSelect: inner hint row (place inside a full-bleed wrapper with \`-mx-4\` + \`border-b\` on the panel). Matches Roles' row dimensions for visual parity. */
1980
1963
  export const creatableToneHintRowClassName = cn(
1981
- "flex min-h-[45px] shrink-0 items-center justify-between gap-2.5 px-4 py-2.5"
1964
+ "flex shrink-0 items-center justify-between gap-2 px-4 py-2"
1982
1965
  )
1983
1966
 
1984
1967
  export interface CreatableSelectOption {
@@ -3172,6 +3155,7 @@ import { Check } from "lucide-react";
3172
3155
  import { cn } from "@/lib/utils";
3173
3156
 
3174
3157
  const blockedNumberKeys = new Set(["e", "E"]);
3158
+ const decimalSeparatorKeys = new Set([".", ","]);
3175
3159
 
3176
3160
  /**
3177
3161
  * Input variants for different visual states
@@ -3220,6 +3204,15 @@ export interface InputProps
3220
3204
  * Default \`true\` so amount-like fields cannot accept exponent values such as \`2e22\`.
3221
3205
  */
3222
3206
  preventNumberExponent?: boolean;
3207
+ /**
3208
+ * When \`type="number"\`, whether decimal separators (\`.\` / \`,\`) are allowed.
3209
+ * Default \`true\`. Set \`false\` for whole-number-only fields; uses \`inputMode="numeric"\` on supported agents.
3210
+ */
3211
+ decimal?: boolean;
3212
+ /**
3213
+ * Same as \`decimal\` for whole-number-only fields. If both are set, this wins.
3214
+ */
3215
+ allowDecimal?: boolean;
3223
3216
  }
3224
3217
 
3225
3218
  const Input = React.forwardRef(
@@ -3231,19 +3224,25 @@ const Input = React.forwardRef(
3231
3224
  showCheckIcon,
3232
3225
  hideNumberSpinners = true,
3233
3226
  preventNumberExponent = true,
3227
+ decimal = true,
3228
+ allowDecimal,
3234
3229
  onFocus,
3235
3230
  onBlur,
3236
3231
  onWheel,
3237
3232
  onKeyDown,
3238
3233
  onPaste,
3239
3234
  onChange,
3235
+ step,
3240
3236
  ...props
3241
3237
  }: InputProps,
3242
3238
  ref: React.Ref<HTMLInputElement>
3243
3239
  ) => {
3244
3240
  const [isFocused, setIsFocused] = React.useState(false);
3241
+ const decimalAllowed = allowDecimal ?? decimal;
3245
3242
  const shouldPreventNumberExponent =
3246
3243
  type === "number" && preventNumberExponent;
3244
+ const shouldBlockDecimals =
3245
+ type === "number" && !decimalAllowed;
3247
3246
 
3248
3247
  const inputEl = (
3249
3248
  <input
@@ -3256,6 +3255,16 @@ const Input = React.forwardRef(
3256
3255
  "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
3257
3256
  )}
3258
3257
  ref={ref}
3258
+ inputMode={
3259
+ type === "number"
3260
+ ? decimalAllowed
3261
+ ? "decimal"
3262
+ : "numeric"
3263
+ : undefined
3264
+ }
3265
+ step={
3266
+ type === "number" && !decimalAllowed ? (step ?? 1) : step
3267
+ }
3259
3268
  onFocus={(e) => {
3260
3269
  setIsFocused(true);
3261
3270
  onFocus?.(e);
@@ -3276,13 +3285,20 @@ const Input = React.forwardRef(
3276
3285
  if (shouldPreventNumberExponent && blockedNumberKeys.has(e.key)) {
3277
3286
  e.preventDefault();
3278
3287
  }
3288
+ if (
3289
+ shouldBlockDecimals &&
3290
+ decimalSeparatorKeys.has(e.key)
3291
+ ) {
3292
+ e.preventDefault();
3293
+ }
3279
3294
  onKeyDown?.(e);
3280
3295
  }}
3281
3296
  onPaste={(e) => {
3282
- if (
3283
- shouldPreventNumberExponent &&
3284
- /[eE]/.test(e.clipboardData.getData("text"))
3285
- ) {
3297
+ const text = e.clipboardData.getData("text");
3298
+ if (shouldPreventNumberExponent && /[eE]/.test(text)) {
3299
+ e.preventDefault();
3300
+ }
3301
+ if (shouldBlockDecimals && /[.,]/.test(text)) {
3286
3302
  e.preventDefault();
3287
3303
  }
3288
3304
  onPaste?.(e);
@@ -3291,6 +3307,9 @@ const Input = React.forwardRef(
3291
3307
  if (shouldPreventNumberExponent && /[eE]/.test(e.target.value)) {
3292
3308
  return;
3293
3309
  }
3310
+ if (shouldBlockDecimals && /[.,]/.test(e.target.value)) {
3311
+ return;
3312
+ }
3294
3313
  onChange?.(e);
3295
3314
  }}
3296
3315
  {...props}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-mcp",
3
- "version": "0.2.266",
3
+ "version": "0.2.268",
4
4
  "description": "MCP server for myOperator UI components - enables AI assistants to access component metadata, examples, and design tokens",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.js",