input-number.js 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.97
  5. */
  6. import { h, Host } from "@stencil/core";
  7. import { getElementDir, getElementProp, getSlotted, isPrimaryPointerButton, setRequestedIcon } from "../../utils/dom";
  8. import { CSS, SLOTS, TEXT } from "./resources";
  9. import { connectLabel, disconnectLabel, getLabelText } from "../../utils/label";
  10. import { connectForm, disconnectForm, HiddenFormInputSlot, submitForm } from "../../utils/form";
  11. import { numberStringFormatter, defaultNumberingSystem, disconnectLocalized, connectLocalized, updateEffectiveLocale } from "../../utils/locale";
  12. import { numberKeys } from "../../utils/key";
  13. import { isValidNumber, parseNumberString, sanitizeNumberString } from "../../utils/number";
  14. import { CSS_UTILITY, TEXT as COMMON_TEXT } from "../../utils/resources";
  15. import { decimalPlaces } from "../../utils/math";
  16. import { createObserver } from "../../utils/observers";
  17. import { updateHostInteraction } from "../../utils/interactive";
  18. /**
  19. * @slot action - A slot for positioning a button next to the component.
  20. */
  21. export class InputNumber {
  22. constructor() {
  23. //--------------------------------------------------------------------------
  24. //
  25. // Properties
  26. //
  27. //--------------------------------------------------------------------------
  28. /** Specifies the text alignment of the component's value. */
  29. this.alignment = "start";
  30. /**
  31. * When `true`, the component is focused on page load.
  32. *
  33. * @mdn [autofocus](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus)
  34. */
  35. this.autofocus = false;
  36. /**
  37. * When `true`, a clear button is displayed when the component has a value.
  38. */
  39. this.clearable = false;
  40. /**
  41. * When `true`, interaction is prevented and the component is displayed with lower opacity.
  42. *
  43. * @mdn [disabled](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled)
  44. */
  45. this.disabled = false;
  46. /**
  47. * When `true`, number values are displayed with a group separator corresponding to the language and country format.
  48. */
  49. this.groupSeparator = false;
  50. /**
  51. * When `true`, the component will not be visible.
  52. *
  53. * @mdn [hidden](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden)
  54. */
  55. this.hidden = false;
  56. /**
  57. * Accessible name that will appear while loading.
  58. *
  59. * @default "Loading"
  60. */
  61. this.intlLoading = COMMON_TEXT.loading;
  62. /** When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`). */
  63. this.iconFlipRtl = false;
  64. /** When `true`, the component is in the loading state and `calcite-progress` is displayed. */
  65. this.loading = false;
  66. /**
  67. * Toggles locale formatting for numbers.
  68. *
  69. * @internal
  70. */
  71. this.localeFormat = false;
  72. /** Specifies the placement of the buttons. */
  73. this.numberButtonType = "vertical";
  74. /**
  75. * When `true`, the component's value can be read, but cannot be modified.
  76. *
  77. * @mdn [readOnly](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly)
  78. */
  79. this.readOnly = false;
  80. /** When `true`, the component must have a value in order for the form to submit. */
  81. this.required = false;
  82. /** Specifies the size of the component. */
  83. this.scale = "m";
  84. /** Specifies the status of the input field, which determines message and icons. */
  85. this.status = "idle";
  86. /**
  87. * @internal
  88. */
  89. this.editingEnabled = false;
  90. /** The component's value. */
  91. this.value = "";
  92. this.previousValueOrigin = "initial";
  93. this.mutationObserver = createObserver("mutation", () => this.setDisabledAction());
  94. this.userChangedValue = false;
  95. //--------------------------------------------------------------------------
  96. //
  97. // State
  98. //
  99. //--------------------------------------------------------------------------
  100. this.effectiveLocale = "";
  101. //--------------------------------------------------------------------------
  102. //
  103. // Private Methods
  104. //
  105. //--------------------------------------------------------------------------
  106. this.keyDownHandler = (event) => {
  107. if (this.readOnly || this.disabled) {
  108. return;
  109. }
  110. if (this.isClearable && event.key === "Escape") {
  111. this.clearInputValue(event);
  112. event.preventDefault();
  113. }
  114. if (event.key === "Enter" && !event.defaultPrevented) {
  115. if (submitForm(this)) {
  116. event.preventDefault();
  117. }
  118. }
  119. };
  120. this.clearInputValue = (nativeEvent) => {
  121. this.setNumberValue({
  122. committing: true,
  123. nativeEvent,
  124. origin: "user",
  125. value: ""
  126. });
  127. };
  128. this.emitChangeIfUserModified = () => {
  129. if (this.previousValueOrigin === "user" && this.value !== this.previousEmittedValue) {
  130. this.calciteInputNumberChange.emit();
  131. }
  132. this.previousEmittedValue = this.value;
  133. };
  134. this.inputNumberBlurHandler = () => {
  135. this.calciteInternalInputNumberBlur.emit();
  136. this.emitChangeIfUserModified();
  137. };
  138. this.inputNumberFocusHandler = (event) => {
  139. const slottedActionEl = getSlotted(this.el, "action");
  140. if (event.target !== slottedActionEl) {
  141. this.setFocus();
  142. }
  143. this.calciteInternalInputNumberFocus.emit();
  144. };
  145. this.inputNumberInputHandler = (nativeEvent) => {
  146. if (this.disabled || this.readOnly) {
  147. return;
  148. }
  149. const value = nativeEvent.target.value;
  150. numberStringFormatter.numberFormatOptions = {
  151. locale: this.effectiveLocale,
  152. numberingSystem: this.numberingSystem,
  153. useGrouping: this.groupSeparator
  154. };
  155. const delocalizedValue = numberStringFormatter.delocalize(value);
  156. if (nativeEvent.inputType === "insertFromPaste") {
  157. if (!isValidNumber(delocalizedValue)) {
  158. nativeEvent.preventDefault();
  159. }
  160. this.setNumberValue({
  161. nativeEvent,
  162. origin: "user",
  163. value: parseNumberString(delocalizedValue)
  164. });
  165. this.childNumberEl.value = this.localizedValue;
  166. }
  167. else {
  168. this.setNumberValue({
  169. nativeEvent,
  170. origin: "user",
  171. value: delocalizedValue
  172. });
  173. }
  174. };
  175. this.inputNumberKeyDownHandler = (event) => {
  176. if (this.disabled || this.readOnly) {
  177. return;
  178. }
  179. if (event.key === "ArrowUp") {
  180. /* prevent default behavior of moving cursor to the beginning of the input when holding down ArrowUp */
  181. event.preventDefault();
  182. this.nudgeNumberValue("up", event);
  183. return;
  184. }
  185. if (event.key === "ArrowDown") {
  186. this.nudgeNumberValue("down", event);
  187. return;
  188. }
  189. const supportedKeys = [
  190. ...numberKeys,
  191. "ArrowLeft",
  192. "ArrowRight",
  193. "Backspace",
  194. "Delete",
  195. "Enter",
  196. "Escape",
  197. "Tab"
  198. ];
  199. if (event.altKey || event.ctrlKey || event.metaKey) {
  200. return;
  201. }
  202. const isShiftTabEvent = event.shiftKey && event.key === "Tab";
  203. if (supportedKeys.includes(event.key) && (!event.shiftKey || isShiftTabEvent)) {
  204. if (event.key === "Enter") {
  205. this.emitChangeIfUserModified();
  206. }
  207. return;
  208. }
  209. numberStringFormatter.numberFormatOptions = {
  210. locale: this.effectiveLocale,
  211. numberingSystem: this.numberingSystem,
  212. useGrouping: this.groupSeparator
  213. };
  214. if (event.key === numberStringFormatter.decimal) {
  215. if (!this.value && !this.childNumberEl.value) {
  216. return;
  217. }
  218. if (this.value && this.childNumberEl.value.indexOf(numberStringFormatter.decimal) === -1) {
  219. return;
  220. }
  221. }
  222. if (/[eE]/.test(event.key)) {
  223. if (!this.value && !this.childNumberEl.value) {
  224. return;
  225. }
  226. if (this.value && !/[eE]/.test(this.childNumberEl.value)) {
  227. return;
  228. }
  229. }
  230. if (event.key === "-") {
  231. if (!this.value && !this.childNumberEl.value) {
  232. return;
  233. }
  234. if (this.value && this.childNumberEl.value.split("-").length <= 2) {
  235. return;
  236. }
  237. }
  238. event.preventDefault();
  239. };
  240. this.nudgeNumberValue = (direction, nativeEvent) => {
  241. if (nativeEvent instanceof KeyboardEvent && nativeEvent.repeat) {
  242. return;
  243. }
  244. const inputMax = this.maxString ? parseFloat(this.maxString) : null;
  245. const inputMin = this.minString ? parseFloat(this.minString) : null;
  246. const valueNudgeDelayInMs = 100;
  247. this.incrementOrDecrementNumberValue(direction, inputMax, inputMin, nativeEvent);
  248. if (this.nudgeNumberValueIntervalId) {
  249. window.clearInterval(this.nudgeNumberValueIntervalId);
  250. }
  251. let firstValueNudge = true;
  252. this.nudgeNumberValueIntervalId = window.setInterval(() => {
  253. if (firstValueNudge) {
  254. firstValueNudge = false;
  255. return;
  256. }
  257. this.incrementOrDecrementNumberValue(direction, inputMax, inputMin, nativeEvent);
  258. }, valueNudgeDelayInMs);
  259. };
  260. this.nudgeButtonPointerUpAndOutHandler = (event) => {
  261. if (!isPrimaryPointerButton(event)) {
  262. return;
  263. }
  264. window.clearInterval(this.nudgeNumberValueIntervalId);
  265. };
  266. this.nudgeButtonPointerDownHandler = (event) => {
  267. if (!isPrimaryPointerButton(event)) {
  268. return;
  269. }
  270. event.preventDefault();
  271. const direction = event.target.dataset.adjustment;
  272. if (!this.disabled) {
  273. this.nudgeNumberValue(direction, event);
  274. }
  275. };
  276. this.hiddenInputChangeHandler = (event) => {
  277. if (event.target.name === this.name) {
  278. this.setNumberValue({
  279. value: event.target.value,
  280. origin: "direct"
  281. });
  282. }
  283. event.stopPropagation();
  284. };
  285. this.setChildNumberElRef = (el) => {
  286. this.childNumberEl = el;
  287. };
  288. this.setInputNumberValue = (newInputValue) => {
  289. if (!this.childNumberEl) {
  290. return;
  291. }
  292. this.childNumberEl.value = newInputValue;
  293. };
  294. this.setPreviousEmittedNumberValue = (newPreviousEmittedValue) => {
  295. this.previousEmittedValue = isValidNumber(newPreviousEmittedValue)
  296. ? newPreviousEmittedValue
  297. : "";
  298. };
  299. this.setPreviousNumberValue = (newPreviousValue) => {
  300. this.previousValue = isValidNumber(newPreviousValue) ? newPreviousValue : "";
  301. };
  302. this.setNumberValue = ({ committing = false, nativeEvent, origin, previousValue, value }) => {
  303. numberStringFormatter.numberFormatOptions = {
  304. locale: this.effectiveLocale,
  305. numberingSystem: this.numberingSystem,
  306. useGrouping: this.groupSeparator
  307. };
  308. const sanitizedValue = sanitizeNumberString((this.numberingSystem && this.numberingSystem !== "latn") || defaultNumberingSystem !== "latn"
  309. ? numberStringFormatter.delocalize(value)
  310. : value);
  311. const newValue = value && !sanitizedValue
  312. ? isValidNumber(this.previousValue)
  313. ? this.previousValue
  314. : ""
  315. : sanitizedValue;
  316. const newLocalizedValue = numberStringFormatter.localize(newValue);
  317. this.setPreviousNumberValue(previousValue || this.value);
  318. this.previousValueOrigin = origin;
  319. this.userChangedValue = origin === "user" && this.value !== newValue;
  320. this.value = newValue;
  321. this.localizedValue = newLocalizedValue;
  322. if (origin === "direct") {
  323. this.setInputNumberValue(newLocalizedValue);
  324. }
  325. if (nativeEvent) {
  326. const calciteInputNumberInputEvent = this.calciteInputNumberInput.emit({
  327. element: this.childNumberEl,
  328. nativeEvent,
  329. value: this.value
  330. });
  331. if (calciteInputNumberInputEvent.defaultPrevented) {
  332. const previousLocalizedValue = numberStringFormatter.localize(this.previousValue);
  333. this.value = this.previousValue;
  334. this.localizedValue = previousLocalizedValue;
  335. }
  336. else if (committing) {
  337. this.emitChangeIfUserModified();
  338. }
  339. }
  340. };
  341. this.inputNumberKeyUpHandler = () => {
  342. window.clearInterval(this.nudgeNumberValueIntervalId);
  343. };
  344. }
  345. disabledWatcher() {
  346. this.setDisabledAction();
  347. }
  348. localeChanged() {
  349. updateEffectiveLocale(this);
  350. }
  351. /** watcher to update number-to-string for max */
  352. maxWatcher() {
  353. var _a;
  354. this.maxString = ((_a = this.max) === null || _a === void 0 ? void 0 : _a.toString()) || null;
  355. }
  356. /** watcher to update number-to-string for min */
  357. minWatcher() {
  358. var _a;
  359. this.minString = ((_a = this.min) === null || _a === void 0 ? void 0 : _a.toString()) || null;
  360. }
  361. valueWatcher(newValue, previousValue) {
  362. if (!this.userChangedValue) {
  363. this.setNumberValue({
  364. origin: "direct",
  365. previousValue,
  366. value: newValue == null || newValue == ""
  367. ? ""
  368. : isValidNumber(newValue)
  369. ? newValue
  370. : this.previousValue || ""
  371. });
  372. this.warnAboutInvalidNumberValue(newValue);
  373. }
  374. this.userChangedValue = false;
  375. }
  376. updateRequestedIcon() {
  377. this.requestedIcon = setRequestedIcon({}, this.icon, "number");
  378. }
  379. get isClearable() {
  380. return this.clearable && this.value.length > 0;
  381. }
  382. //--------------------------------------------------------------------------
  383. //
  384. // Lifecycle
  385. //
  386. //--------------------------------------------------------------------------
  387. connectedCallback() {
  388. var _a;
  389. connectLocalized(this);
  390. this.scale = getElementProp(this.el, "scale", this.scale);
  391. this.status = getElementProp(this.el, "status", this.status);
  392. this.inlineEditableEl = this.el.closest("calcite-inline-editable");
  393. if (this.inlineEditableEl) {
  394. this.editingEnabled = this.inlineEditableEl.editingEnabled || false;
  395. }
  396. connectLabel(this);
  397. connectForm(this);
  398. this.setPreviousEmittedNumberValue(this.value);
  399. this.setPreviousNumberValue(this.value);
  400. this.warnAboutInvalidNumberValue(this.value);
  401. this.setNumberValue({
  402. origin: "connected",
  403. value: isValidNumber(this.value) ? this.value : ""
  404. });
  405. (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.observe(this.el, { childList: true });
  406. this.setDisabledAction();
  407. this.el.addEventListener("calciteInternalHiddenInputChange", this.hiddenInputChangeHandler);
  408. }
  409. disconnectedCallback() {
  410. var _a;
  411. disconnectLabel(this);
  412. disconnectForm(this);
  413. disconnectLocalized(this);
  414. (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
  415. this.el.removeEventListener("calciteInternalHiddenInputChange", this.hiddenInputChangeHandler);
  416. }
  417. componentWillLoad() {
  418. var _a, _b;
  419. this.maxString = (_a = this.max) === null || _a === void 0 ? void 0 : _a.toString();
  420. this.minString = (_b = this.min) === null || _b === void 0 ? void 0 : _b.toString();
  421. this.requestedIcon = setRequestedIcon({}, this.icon, "number");
  422. }
  423. componentShouldUpdate(newValue, oldValue, property) {
  424. if (property === "value" && newValue && !isValidNumber(newValue)) {
  425. this.setNumberValue({
  426. origin: "reset",
  427. value: oldValue
  428. });
  429. return false;
  430. }
  431. return true;
  432. }
  433. componentDidRender() {
  434. updateHostInteraction(this);
  435. }
  436. //--------------------------------------------------------------------------
  437. //
  438. // Public Methods
  439. //
  440. //--------------------------------------------------------------------------
  441. /** Sets focus on the component. */
  442. async setFocus() {
  443. var _a;
  444. (_a = this.childNumberEl) === null || _a === void 0 ? void 0 : _a.focus();
  445. }
  446. /** Selects all text of the component's `value`. */
  447. async selectText() {
  448. var _a;
  449. (_a = this.childNumberEl) === null || _a === void 0 ? void 0 : _a.select();
  450. }
  451. onLabelClick() {
  452. this.setFocus();
  453. }
  454. incrementOrDecrementNumberValue(direction, inputMax, inputMin, nativeEvent) {
  455. const { value } = this;
  456. const inputStep = this.step === "any" ? 1 : Math.abs(this.step || 1);
  457. const inputVal = value && value !== "" ? parseFloat(value) : 0;
  458. const adjustment = direction === "up" ? 1 : -1;
  459. const nudgedValue = inputVal + inputStep * adjustment;
  460. const finalValue = (typeof inputMin === "number" && !isNaN(inputMin) && nudgedValue < inputMin) ||
  461. (typeof inputMax === "number" && !isNaN(inputMax) && nudgedValue > inputMax)
  462. ? inputVal
  463. : nudgedValue;
  464. const inputValPlaces = decimalPlaces(inputVal);
  465. const inputStepPlaces = decimalPlaces(inputStep);
  466. this.setNumberValue({
  467. committing: true,
  468. nativeEvent,
  469. origin: "user",
  470. value: finalValue.toFixed(Math.max(inputValPlaces, inputStepPlaces))
  471. });
  472. }
  473. onFormReset() {
  474. this.setNumberValue({
  475. origin: "reset",
  476. value: this.defaultValue
  477. });
  478. }
  479. syncHiddenFormInput(input) {
  480. var _a, _b, _c, _d;
  481. input.type = "number";
  482. input.min = (_b = (_a = this.min) === null || _a === void 0 ? void 0 : _a.toString(10)) !== null && _b !== void 0 ? _b : "";
  483. input.max = (_d = (_c = this.max) === null || _c === void 0 ? void 0 : _c.toString(10)) !== null && _d !== void 0 ? _d : "";
  484. }
  485. setDisabledAction() {
  486. const slottedActionEl = getSlotted(this.el, "action");
  487. if (!slottedActionEl) {
  488. return;
  489. }
  490. this.disabled
  491. ? slottedActionEl.setAttribute("disabled", "")
  492. : slottedActionEl.removeAttribute("disabled");
  493. }
  494. warnAboutInvalidNumberValue(value) {
  495. if (value && !isValidNumber(value)) {
  496. console.warn(`The specified value "${value}" cannot be parsed, or is out of range.`);
  497. }
  498. }
  499. // --------------------------------------------------------------------------
  500. //
  501. // Render Methods
  502. //
  503. // --------------------------------------------------------------------------
  504. render() {
  505. const dir = getElementDir(this.el);
  506. const loader = (h("div", { class: CSS.loader }, h("calcite-progress", { label: this.intlLoading, type: "indeterminate" })));
  507. const inputClearButton = (h("button", { "aria-label": this.intlClear || TEXT.clear, class: CSS.clearButton, disabled: this.disabled || this.readOnly, onClick: this.clearInputValue, tabIndex: -1, type: "button" }, h("calcite-icon", { icon: "x", scale: "s" })));
  508. const iconEl = (h("calcite-icon", { class: CSS.inputIcon, flipRtl: this.iconFlipRtl, icon: this.requestedIcon, scale: "s" }));
  509. const isHorizontalNumberButton = this.numberButtonType === "horizontal";
  510. const numberButtonsHorizontalUp = (h("button", { "aria-hidden": "true", class: {
  511. [CSS.numberButtonItem]: true,
  512. [CSS.buttonItemHorizontal]: isHorizontalNumberButton
  513. }, "data-adjustment": "up", disabled: this.disabled || this.readOnly, onPointerDown: this.nudgeButtonPointerDownHandler, onPointerOut: this.nudgeButtonPointerUpAndOutHandler, onPointerUp: this.nudgeButtonPointerUpAndOutHandler, tabIndex: -1, type: "button" }, h("calcite-icon", { icon: "chevron-up", scale: "s" })));
  514. const numberButtonsHorizontalDown = (h("button", { "aria-hidden": "true", class: {
  515. [CSS.numberButtonItem]: true,
  516. [CSS.buttonItemHorizontal]: isHorizontalNumberButton
  517. }, "data-adjustment": "down", disabled: this.disabled || this.readOnly, onPointerDown: this.nudgeButtonPointerDownHandler, onPointerOut: this.nudgeButtonPointerUpAndOutHandler, onPointerUp: this.nudgeButtonPointerUpAndOutHandler, tabIndex: -1, type: "button" }, h("calcite-icon", { icon: "chevron-down", scale: "s" })));
  518. const numberButtonsVertical = (h("div", { class: CSS.numberButtonWrapper }, numberButtonsHorizontalUp, numberButtonsHorizontalDown));
  519. const prefixText = h("div", { class: CSS.prefix }, this.prefixText);
  520. const suffixText = h("div", { class: CSS.suffix }, this.suffixText);
  521. const childEl = (h("input", { "aria-label": getLabelText(this), autofocus: this.autofocus ? true : null, defaultValue: this.defaultValue, disabled: this.disabled ? true : null, enterKeyHint: this.el.enterKeyHint, inputMode: this.el.inputMode, key: "localized-input", maxLength: this.maxLength, minLength: this.minLength, name: undefined, onBlur: this.inputNumberBlurHandler, onFocus: this.inputNumberFocusHandler, onInput: this.inputNumberInputHandler, onKeyDown: this.inputNumberKeyDownHandler, onKeyUp: this.inputNumberKeyUpHandler, placeholder: this.placeholder || "", readOnly: this.readOnly, ref: this.setChildNumberElRef, type: "text", value: this.localizedValue }));
  522. return (h(Host, { onClick: this.inputNumberFocusHandler, onKeyDown: this.keyDownHandler }, h("div", { class: { [CSS.inputWrapper]: true, [CSS_UTILITY.rtl]: dir === "rtl" } }, this.numberButtonType === "horizontal" && !this.readOnly
  523. ? numberButtonsHorizontalDown
  524. : null, this.prefixText ? prefixText : null, h("div", { class: CSS.wrapper }, childEl, this.isClearable ? inputClearButton : null, this.requestedIcon ? iconEl : null, this.loading ? loader : null), h("div", { class: CSS.actionWrapper }, h("slot", { name: SLOTS.action })), this.numberButtonType === "vertical" && !this.readOnly ? numberButtonsVertical : null, this.suffixText ? suffixText : null, this.numberButtonType === "horizontal" && !this.readOnly
  525. ? numberButtonsHorizontalUp
  526. : null, h(HiddenFormInputSlot, { component: this }))));
  527. }
  528. static get is() { return "calcite-input-number"; }
  529. static get encapsulation() { return "shadow"; }
  530. static get originalStyleUrls() {
  531. return {
  532. "$": ["input-number.scss"]
  533. };
  534. }
  535. static get styleUrls() {
  536. return {
  537. "$": ["input-number.css"]
  538. };
  539. }
  540. static get properties() {
  541. return {
  542. "alignment": {
  543. "type": "string",
  544. "mutable": false,
  545. "complexType": {
  546. "original": "Position",
  547. "resolved": "\"end\" | \"start\"",
  548. "references": {
  549. "Position": {
  550. "location": "import",
  551. "path": "../interfaces"
  552. }
  553. }
  554. },
  555. "required": false,
  556. "optional": false,
  557. "docs": {
  558. "tags": [],
  559. "text": "Specifies the text alignment of the component's value."
  560. },
  561. "attribute": "alignment",
  562. "reflect": true,
  563. "defaultValue": "\"start\""
  564. },
  565. "autofocus": {
  566. "type": "boolean",
  567. "mutable": false,
  568. "complexType": {
  569. "original": "boolean",
  570. "resolved": "boolean",
  571. "references": {}
  572. },
  573. "required": false,
  574. "optional": false,
  575. "docs": {
  576. "tags": [{
  577. "name": "mdn",
  578. "text": "[autofocus](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus)"
  579. }],
  580. "text": "When `true`, the component is focused on page load."
  581. },
  582. "attribute": "autofocus",
  583. "reflect": true,
  584. "defaultValue": "false"
  585. },
  586. "clearable": {
  587. "type": "boolean",
  588. "mutable": false,
  589. "complexType": {
  590. "original": "boolean",
  591. "resolved": "boolean",
  592. "references": {}
  593. },
  594. "required": false,
  595. "optional": false,
  596. "docs": {
  597. "tags": [],
  598. "text": "When `true`, a clear button is displayed when the component has a value."
  599. },
  600. "attribute": "clearable",
  601. "reflect": true,
  602. "defaultValue": "false"
  603. },
  604. "disabled": {
  605. "type": "boolean",
  606. "mutable": false,
  607. "complexType": {
  608. "original": "boolean",
  609. "resolved": "boolean",
  610. "references": {}
  611. },
  612. "required": false,
  613. "optional": false,
  614. "docs": {
  615. "tags": [{
  616. "name": "mdn",
  617. "text": "[disabled](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled)"
  618. }],
  619. "text": "When `true`, interaction is prevented and the component is displayed with lower opacity."
  620. },
  621. "attribute": "disabled",
  622. "reflect": true,
  623. "defaultValue": "false"
  624. },
  625. "groupSeparator": {
  626. "type": "boolean",
  627. "mutable": false,
  628. "complexType": {
  629. "original": "boolean",
  630. "resolved": "boolean",
  631. "references": {}
  632. },
  633. "required": false,
  634. "optional": false,
  635. "docs": {
  636. "tags": [],
  637. "text": "When `true`, number values are displayed with a group separator corresponding to the language and country format."
  638. },
  639. "attribute": "group-separator",
  640. "reflect": true,
  641. "defaultValue": "false"
  642. },
  643. "hidden": {
  644. "type": "boolean",
  645. "mutable": false,
  646. "complexType": {
  647. "original": "boolean",
  648. "resolved": "boolean",
  649. "references": {}
  650. },
  651. "required": false,
  652. "optional": false,
  653. "docs": {
  654. "tags": [{
  655. "name": "mdn",
  656. "text": "[hidden](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden)"
  657. }],
  658. "text": "When `true`, the component will not be visible."
  659. },
  660. "attribute": "hidden",
  661. "reflect": true,
  662. "defaultValue": "false"
  663. },
  664. "icon": {
  665. "type": "any",
  666. "mutable": false,
  667. "complexType": {
  668. "original": "string | boolean",
  669. "resolved": "boolean | string",
  670. "references": {}
  671. },
  672. "required": false,
  673. "optional": false,
  674. "docs": {
  675. "tags": [],
  676. "text": "When `true`, shows a default recommended icon. Alternatively, pass a Calcite UI Icon name to display a specific icon."
  677. },
  678. "attribute": "icon",
  679. "reflect": true
  680. },
  681. "intlClear": {
  682. "type": "string",
  683. "mutable": false,
  684. "complexType": {
  685. "original": "string",
  686. "resolved": "string",
  687. "references": {}
  688. },
  689. "required": false,
  690. "optional": true,
  691. "docs": {
  692. "tags": [],
  693. "text": "A text label that will appear on the clear button for screen readers."
  694. },
  695. "attribute": "intl-clear",
  696. "reflect": false
  697. },
  698. "intlLoading": {
  699. "type": "string",
  700. "mutable": false,
  701. "complexType": {
  702. "original": "string",
  703. "resolved": "string",
  704. "references": {}
  705. },
  706. "required": false,
  707. "optional": true,
  708. "docs": {
  709. "tags": [{
  710. "name": "default",
  711. "text": "\"Loading\""
  712. }],
  713. "text": "Accessible name that will appear while loading."
  714. },
  715. "attribute": "intl-loading",
  716. "reflect": false,
  717. "defaultValue": "COMMON_TEXT.loading"
  718. },
  719. "iconFlipRtl": {
  720. "type": "boolean",
  721. "mutable": false,
  722. "complexType": {
  723. "original": "boolean",
  724. "resolved": "boolean",
  725. "references": {}
  726. },
  727. "required": false,
  728. "optional": false,
  729. "docs": {
  730. "tags": [],
  731. "text": "When `true`, the icon will be flipped when the element direction is right-to-left (`\"rtl\"`)."
  732. },
  733. "attribute": "icon-flip-rtl",
  734. "reflect": true,
  735. "defaultValue": "false"
  736. },
  737. "label": {
  738. "type": "string",
  739. "mutable": false,
  740. "complexType": {
  741. "original": "string",
  742. "resolved": "string",
  743. "references": {}
  744. },
  745. "required": false,
  746. "optional": true,
  747. "docs": {
  748. "tags": [],
  749. "text": "Accessible name for the component's button or hyperlink."
  750. },
  751. "attribute": "label",
  752. "reflect": false
  753. },
  754. "loading": {
  755. "type": "boolean",
  756. "mutable": false,
  757. "complexType": {
  758. "original": "boolean",
  759. "resolved": "boolean",
  760. "references": {}
  761. },
  762. "required": false,
  763. "optional": false,
  764. "docs": {
  765. "tags": [],
  766. "text": "When `true`, the component is in the loading state and `calcite-progress` is displayed."
  767. },
  768. "attribute": "loading",
  769. "reflect": true,
  770. "defaultValue": "false"
  771. },
  772. "locale": {
  773. "type": "string",
  774. "mutable": false,
  775. "complexType": {
  776. "original": "string",
  777. "resolved": "string",
  778. "references": {}
  779. },
  780. "required": false,
  781. "optional": false,
  782. "docs": {
  783. "tags": [{
  784. "name": "deprecated",
  785. "text": "set the global `lang` attribute on the element instead."
  786. }, {
  787. "name": "mdn",
  788. "text": "[lang](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang)"
  789. }],
  790. "text": "Specifies the BCP 47 language tag for the desired language and country format."
  791. },
  792. "attribute": "locale",
  793. "reflect": false
  794. },
  795. "numberingSystem": {
  796. "type": "string",
  797. "mutable": false,
  798. "complexType": {
  799. "original": "NumberingSystem",
  800. "resolved": "\"arab\" | \"arabext\" | \"bali\" | \"beng\" | \"deva\" | \"fullwide\" | \"gujr\" | \"guru\" | \"hanidec\" | \"khmr\" | \"knda\" | \"laoo\" | \"latn\" | \"limb\" | \"mlym\" | \"mong\" | \"mymr\" | \"orya\" | \"tamldec\" | \"telu\" | \"thai\" | \"tibt\"",
  801. "references": {
  802. "NumberingSystem": {
  803. "location": "import",
  804. "path": "../../utils/locale"
  805. }
  806. }
  807. },
  808. "required": false,
  809. "optional": true,
  810. "docs": {
  811. "tags": [],
  812. "text": "Specifies the Unicode numeral system used by the component for localization."
  813. },
  814. "attribute": "numbering-system",
  815. "reflect": true
  816. },
  817. "localeFormat": {
  818. "type": "boolean",
  819. "mutable": false,
  820. "complexType": {
  821. "original": "boolean",
  822. "resolved": "boolean",
  823. "references": {}
  824. },
  825. "required": false,
  826. "optional": false,
  827. "docs": {
  828. "tags": [{
  829. "name": "internal",
  830. "text": undefined
  831. }],
  832. "text": "Toggles locale formatting for numbers."
  833. },
  834. "attribute": "locale-format",
  835. "reflect": false,
  836. "defaultValue": "false"
  837. },
  838. "max": {
  839. "type": "number",
  840. "mutable": false,
  841. "complexType": {
  842. "original": "number",
  843. "resolved": "number",
  844. "references": {}
  845. },
  846. "required": false,
  847. "optional": true,
  848. "docs": {
  849. "tags": [{
  850. "name": "mdn",
  851. "text": "[max](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#max)"
  852. }],
  853. "text": "Specifies the maximum value."
  854. },
  855. "attribute": "max",
  856. "reflect": true
  857. },
  858. "min": {
  859. "type": "number",
  860. "mutable": false,
  861. "complexType": {
  862. "original": "number",
  863. "resolved": "number",
  864. "references": {}
  865. },
  866. "required": false,
  867. "optional": true,
  868. "docs": {
  869. "tags": [{
  870. "name": "mdn",
  871. "text": "[min](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#min)"
  872. }],
  873. "text": "Specifies the minimum value."
  874. },
  875. "attribute": "min",
  876. "reflect": true
  877. },
  878. "maxLength": {
  879. "type": "number",
  880. "mutable": false,
  881. "complexType": {
  882. "original": "number",
  883. "resolved": "number",
  884. "references": {}
  885. },
  886. "required": false,
  887. "optional": true,
  888. "docs": {
  889. "tags": [{
  890. "name": "mdn",
  891. "text": "[maxlength](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#maxlength)"
  892. }],
  893. "text": "Specifies the maximum length of text for the component's value."
  894. },
  895. "attribute": "max-length",
  896. "reflect": true
  897. },
  898. "minLength": {
  899. "type": "number",
  900. "mutable": false,
  901. "complexType": {
  902. "original": "number",
  903. "resolved": "number",
  904. "references": {}
  905. },
  906. "required": false,
  907. "optional": true,
  908. "docs": {
  909. "tags": [{
  910. "name": "mdn",
  911. "text": "[minlength](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#minlength)"
  912. }],
  913. "text": "Specifies the minimum length of text for the component's value."
  914. },
  915. "attribute": "min-length",
  916. "reflect": true
  917. },
  918. "name": {
  919. "type": "string",
  920. "mutable": false,
  921. "complexType": {
  922. "original": "string",
  923. "resolved": "string",
  924. "references": {}
  925. },
  926. "required": false,
  927. "optional": false,
  928. "docs": {
  929. "tags": [{
  930. "name": "mdn",
  931. "text": "[name](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#name)"
  932. }],
  933. "text": "Specifies the name of the component."
  934. },
  935. "attribute": "name",
  936. "reflect": true
  937. },
  938. "numberButtonType": {
  939. "type": "string",
  940. "mutable": false,
  941. "complexType": {
  942. "original": "InputPlacement",
  943. "resolved": "\"horizontal\" | \"none\" | \"vertical\"",
  944. "references": {
  945. "InputPlacement": {
  946. "location": "import",
  947. "path": "./interfaces"
  948. }
  949. }
  950. },
  951. "required": false,
  952. "optional": true,
  953. "docs": {
  954. "tags": [],
  955. "text": "Specifies the placement of the buttons."
  956. },
  957. "attribute": "number-button-type",
  958. "reflect": true,
  959. "defaultValue": "\"vertical\""
  960. },
  961. "placeholder": {
  962. "type": "string",
  963. "mutable": false,
  964. "complexType": {
  965. "original": "string",
  966. "resolved": "string",
  967. "references": {}
  968. },
  969. "required": false,
  970. "optional": false,
  971. "docs": {
  972. "tags": [{
  973. "name": "mdn",
  974. "text": "[placeholder](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#placeholder)"
  975. }],
  976. "text": "Specifies placeholder text for the component."
  977. },
  978. "attribute": "placeholder",
  979. "reflect": false
  980. },
  981. "prefixText": {
  982. "type": "string",
  983. "mutable": false,
  984. "complexType": {
  985. "original": "string",
  986. "resolved": "string",
  987. "references": {}
  988. },
  989. "required": false,
  990. "optional": true,
  991. "docs": {
  992. "tags": [],
  993. "text": "Adds text to the start of the component."
  994. },
  995. "attribute": "prefix-text",
  996. "reflect": false
  997. },
  998. "readOnly": {
  999. "type": "boolean",
  1000. "mutable": false,
  1001. "complexType": {
  1002. "original": "boolean",
  1003. "resolved": "boolean",
  1004. "references": {}
  1005. },
  1006. "required": false,
  1007. "optional": false,
  1008. "docs": {
  1009. "tags": [{
  1010. "name": "mdn",
  1011. "text": "[readOnly](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly)"
  1012. }],
  1013. "text": "When `true`, the component's value can be read, but cannot be modified."
  1014. },
  1015. "attribute": "read-only",
  1016. "reflect": true,
  1017. "defaultValue": "false"
  1018. },
  1019. "required": {
  1020. "type": "boolean",
  1021. "mutable": false,
  1022. "complexType": {
  1023. "original": "boolean",
  1024. "resolved": "boolean",
  1025. "references": {}
  1026. },
  1027. "required": false,
  1028. "optional": false,
  1029. "docs": {
  1030. "tags": [],
  1031. "text": "When `true`, the component must have a value in order for the form to submit."
  1032. },
  1033. "attribute": "required",
  1034. "reflect": true,
  1035. "defaultValue": "false"
  1036. },
  1037. "scale": {
  1038. "type": "string",
  1039. "mutable": true,
  1040. "complexType": {
  1041. "original": "Scale",
  1042. "resolved": "\"l\" | \"m\" | \"s\"",
  1043. "references": {
  1044. "Scale": {
  1045. "location": "import",
  1046. "path": "../interfaces"
  1047. }
  1048. }
  1049. },
  1050. "required": false,
  1051. "optional": false,
  1052. "docs": {
  1053. "tags": [],
  1054. "text": "Specifies the size of the component."
  1055. },
  1056. "attribute": "scale",
  1057. "reflect": true,
  1058. "defaultValue": "\"m\""
  1059. },
  1060. "status": {
  1061. "type": "string",
  1062. "mutable": true,
  1063. "complexType": {
  1064. "original": "Status",
  1065. "resolved": "\"idle\" | \"invalid\" | \"valid\"",
  1066. "references": {
  1067. "Status": {
  1068. "location": "import",
  1069. "path": "../interfaces"
  1070. }
  1071. }
  1072. },
  1073. "required": false,
  1074. "optional": false,
  1075. "docs": {
  1076. "tags": [],
  1077. "text": "Specifies the status of the input field, which determines message and icons."
  1078. },
  1079. "attribute": "status",
  1080. "reflect": true,
  1081. "defaultValue": "\"idle\""
  1082. },
  1083. "step": {
  1084. "type": "any",
  1085. "mutable": false,
  1086. "complexType": {
  1087. "original": "number | \"any\"",
  1088. "resolved": "\"any\" | number",
  1089. "references": {}
  1090. },
  1091. "required": false,
  1092. "optional": true,
  1093. "docs": {
  1094. "tags": [{
  1095. "name": "mdn",
  1096. "text": "[step](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/step)"
  1097. }],
  1098. "text": "Specifies the granularity that the component's value must adhere to."
  1099. },
  1100. "attribute": "step",
  1101. "reflect": true
  1102. },
  1103. "suffixText": {
  1104. "type": "string",
  1105. "mutable": false,
  1106. "complexType": {
  1107. "original": "string",
  1108. "resolved": "string",
  1109. "references": {}
  1110. },
  1111. "required": false,
  1112. "optional": true,
  1113. "docs": {
  1114. "tags": [],
  1115. "text": "Adds text to the end of the component."
  1116. },
  1117. "attribute": "suffix-text",
  1118. "reflect": false
  1119. },
  1120. "editingEnabled": {
  1121. "type": "boolean",
  1122. "mutable": true,
  1123. "complexType": {
  1124. "original": "boolean",
  1125. "resolved": "boolean",
  1126. "references": {}
  1127. },
  1128. "required": false,
  1129. "optional": false,
  1130. "docs": {
  1131. "tags": [{
  1132. "name": "internal",
  1133. "text": undefined
  1134. }],
  1135. "text": ""
  1136. },
  1137. "attribute": "editing-enabled",
  1138. "reflect": true,
  1139. "defaultValue": "false"
  1140. },
  1141. "value": {
  1142. "type": "string",
  1143. "mutable": true,
  1144. "complexType": {
  1145. "original": "string",
  1146. "resolved": "string",
  1147. "references": {}
  1148. },
  1149. "required": false,
  1150. "optional": false,
  1151. "docs": {
  1152. "tags": [],
  1153. "text": "The component's value."
  1154. },
  1155. "attribute": "value",
  1156. "reflect": false,
  1157. "defaultValue": "\"\""
  1158. }
  1159. };
  1160. }
  1161. static get states() {
  1162. return {
  1163. "effectiveLocale": {},
  1164. "localizedValue": {}
  1165. };
  1166. }
  1167. static get events() {
  1168. return [{
  1169. "method": "calciteInternalInputNumberFocus",
  1170. "name": "calciteInternalInputNumberFocus",
  1171. "bubbles": true,
  1172. "cancelable": false,
  1173. "composed": true,
  1174. "docs": {
  1175. "tags": [{
  1176. "name": "internal",
  1177. "text": undefined
  1178. }],
  1179. "text": ""
  1180. },
  1181. "complexType": {
  1182. "original": "void",
  1183. "resolved": "void",
  1184. "references": {}
  1185. }
  1186. }, {
  1187. "method": "calciteInternalInputNumberBlur",
  1188. "name": "calciteInternalInputNumberBlur",
  1189. "bubbles": true,
  1190. "cancelable": false,
  1191. "composed": true,
  1192. "docs": {
  1193. "tags": [{
  1194. "name": "internal",
  1195. "text": undefined
  1196. }],
  1197. "text": ""
  1198. },
  1199. "complexType": {
  1200. "original": "void",
  1201. "resolved": "void",
  1202. "references": {}
  1203. }
  1204. }, {
  1205. "method": "calciteInputNumberInput",
  1206. "name": "calciteInputNumberInput",
  1207. "bubbles": true,
  1208. "cancelable": true,
  1209. "composed": true,
  1210. "docs": {
  1211. "tags": [],
  1212. "text": "Fires each time a new value is typed.\n\n**Note:**: The `el` and `value` event payload props are deprecated, please use the event's `target`/`currentTarget` instead"
  1213. },
  1214. "complexType": {
  1215. "original": "DeprecatedEventPayload",
  1216. "resolved": "any",
  1217. "references": {
  1218. "DeprecatedEventPayload": {
  1219. "location": "import",
  1220. "path": "../interfaces"
  1221. }
  1222. }
  1223. }
  1224. }, {
  1225. "method": "calciteInputNumberChange",
  1226. "name": "calciteInputNumberChange",
  1227. "bubbles": true,
  1228. "cancelable": false,
  1229. "composed": true,
  1230. "docs": {
  1231. "tags": [],
  1232. "text": "Fires each time a new value is typed and committed."
  1233. },
  1234. "complexType": {
  1235. "original": "void",
  1236. "resolved": "void",
  1237. "references": {}
  1238. }
  1239. }];
  1240. }
  1241. static get methods() {
  1242. return {
  1243. "setFocus": {
  1244. "complexType": {
  1245. "signature": "() => Promise<void>",
  1246. "parameters": [],
  1247. "references": {
  1248. "Promise": {
  1249. "location": "global"
  1250. }
  1251. },
  1252. "return": "Promise<void>"
  1253. },
  1254. "docs": {
  1255. "text": "Sets focus on the component.",
  1256. "tags": []
  1257. }
  1258. },
  1259. "selectText": {
  1260. "complexType": {
  1261. "signature": "() => Promise<void>",
  1262. "parameters": [],
  1263. "references": {
  1264. "Promise": {
  1265. "location": "global"
  1266. }
  1267. },
  1268. "return": "Promise<void>"
  1269. },
  1270. "docs": {
  1271. "text": "Selects all text of the component's `value`.",
  1272. "tags": []
  1273. }
  1274. }
  1275. };
  1276. }
  1277. static get elementRef() { return "el"; }
  1278. static get watchers() {
  1279. return [{
  1280. "propName": "disabled",
  1281. "methodName": "disabledWatcher"
  1282. }, {
  1283. "propName": "locale",
  1284. "methodName": "localeChanged"
  1285. }, {
  1286. "propName": "max",
  1287. "methodName": "maxWatcher"
  1288. }, {
  1289. "propName": "min",
  1290. "methodName": "minWatcher"
  1291. }, {
  1292. "propName": "value",
  1293. "methodName": "valueWatcher"
  1294. }, {
  1295. "propName": "icon",
  1296. "methodName": "updateRequestedIcon"
  1297. }];
  1298. }
  1299. }