@plastic-js/tsumiki 0.1.82 → 0.1.83

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.
@@ -4,9 +4,7 @@ import { css } from "@emotion/css";
4
4
  import { splitProps } from "@plastic-js/plastic";
5
5
  //#region src/components/MoneyInput.jsx
6
6
  var _tmpl = template("<span></span>");
7
- var affixPrefixClass = css({ color: "var(--tsu-fg)" });
8
7
  var affixSuffixClass = css({
9
- color: "var(--tsu-fg)",
10
8
  fontWeight: "var(--tsu-font-weight-semibold)",
11
9
  paddingLeft: "10px",
12
10
  marginLeft: "var(--tsu-spacing-xs)",
@@ -42,7 +40,6 @@ var MoneyInput = (props) => {
42
40
  prefix: () => () => {
43
41
  const _el0 = _tmpl.cloneNode(true);
44
42
  insert(_el0, () => local.currency ?? "₱");
45
- setProp(_el0, "className", () => affixPrefixClass);
46
43
  return _el0;
47
44
  },
48
45
  suffix: () => {
@@ -0,0 +1,99 @@
1
+ import Input from "./Input.js";
2
+ import { insert, jsx, mergeProps, setProp, template } from "@plastic-js/plastic/jsx-runtime";
3
+ import { css } from "@emotion/css";
4
+ import { mergeProps as mergeProps$1, splitProps } from "@plastic-js/plastic";
5
+ //#region src/components/PhoneInput.jsx
6
+ var _tmpl = template("<span></span>");
7
+ var countryCodeClass = css({ fontVariantNumeric: "tabular-nums" });
8
+ var read = (value) => typeof value === "function" ? value() : value;
9
+ var PHONE_PRESETS = {
10
+ "+63": {
11
+ digits: 10,
12
+ format: "###-###-####",
13
+ placeholder: "9XX-XXX-XXXX"
14
+ },
15
+ "+86": {
16
+ digits: 11,
17
+ format: "###-####-####",
18
+ placeholder: "1XX-XXXX-XXXX"
19
+ }
20
+ };
21
+ var presetFor = (countryCode) => PHONE_PRESETS[countryCode] || PHONE_PRESETS["+63"];
22
+ var parseFormat = (format) => {
23
+ const groups = [];
24
+ const seps = [];
25
+ let n = 0;
26
+ for (const ch of format) {
27
+ if (ch === "#") {
28
+ n += 1;
29
+ continue;
30
+ }
31
+ groups.push(n);
32
+ seps.push(ch);
33
+ n = 0;
34
+ }
35
+ groups.push(n);
36
+ return {
37
+ groups,
38
+ seps
39
+ };
40
+ };
41
+ var applyFormat = (digits, format) => {
42
+ const { groups, seps } = parseFormat(format);
43
+ const total = groups.reduce((a, b) => a + b, 0);
44
+ const d = (digits || "").replace(/\D/g, "").slice(0, total);
45
+ if (!d) return "";
46
+ const parts = [];
47
+ let pos = 0;
48
+ for (const g of groups) {
49
+ parts.push(d.slice(pos, pos + g));
50
+ pos += g;
51
+ }
52
+ const out = [parts[0]];
53
+ for (let i = 1; i < parts.length; i++) {
54
+ if (!parts[i]) break;
55
+ out.push(seps[i - 1], parts[i]);
56
+ }
57
+ return out.join("");
58
+ };
59
+ var PhoneInput = (props) => {
60
+ const [local, rest] = splitProps(mergeProps$1({ countryCode: "+63" }, props), [
61
+ "value",
62
+ "onValueChange",
63
+ "invalid",
64
+ "disabled",
65
+ "placeholder",
66
+ "countryCode"
67
+ ]);
68
+ const preset = () => presetFor(read(local.countryCode));
69
+ const placeholder = () => read(local.placeholder) ?? preset().placeholder;
70
+ const handleInput = (e) => {
71
+ const { digits } = presetFor(read(local.countryCode));
72
+ local.onValueChange?.(e.target.value.replace(/\D/g, "").slice(0, digits));
73
+ };
74
+ return jsx(Input, mergeProps({
75
+ type: "tel",
76
+ inputMode: "numeric",
77
+ maxLength: () => preset().format.length,
78
+ get invalid() {
79
+ return local.invalid;
80
+ },
81
+ get disabled() {
82
+ return local.disabled;
83
+ },
84
+ placeholder,
85
+ prefix: () => {
86
+ const cc = read(local.countryCode);
87
+ return cc ? () => {
88
+ const _el0 = _tmpl.cloneNode(true);
89
+ insert(_el0, () => cc);
90
+ setProp(_el0, "className", () => countryCodeClass);
91
+ return _el0;
92
+ } : null;
93
+ },
94
+ value: () => applyFormat(read(local.value), preset().format),
95
+ onInput: handleInput
96
+ }, rest));
97
+ };
98
+ //#endregion
99
+ export { PhoneInput as default };
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ import MoneyInput from "./components/MoneyInput.js";
33
33
  import NumberInput from "./components/NumberInput.js";
34
34
  import Pagination from "./components/Pagination.js";
35
35
  import PinInput from "./components/PinInput.js";
36
+ import PhoneInput from "./components/PhoneInput.js";
36
37
  import Popover from "./components/Popover.js";
37
38
  import Presence_default from "./components/Presence.js";
38
39
  import Progress, { ProgressLabel } from "./components/Progress.js";
@@ -59,4 +60,4 @@ import ToggleGroup, { ToggleGroupItem } from "./components/ToggleGroup.js";
59
60
  import FilterGroup from "./components/FilterGroup.js";
60
61
  import Tour, { TourCloseTrigger, TourContent } from "./components/Tour.js";
61
62
  import TreeView, { TreeViewBranch, TreeViewBranchContent, TreeViewBranchControl, TreeViewBranchTrigger, TreeViewItem } from "./components/TreeView.js";
62
- export { AccordionRoot as Accordion, AccordionContent, AccordionItem, AccordionTrigger, Avatar, AvatarFallback, AvatarImage, BackToTop, Badge, BottomNavigation, BottomNavigationItem, BottomSheet, Button, Card, CardNumberInput, Carousel_default as Carousel, CarouselAutoplayTrigger, CarouselControl, CarouselIndicator, CarouselIndicatorGroup, CarouselItem, CarouselItemGroup, CarouselNextTrigger, CarouselPrevTrigger, CarouselProgressText, Checkbox, ClearTrigger, Clipboard, CloseButton, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorPicker, Root as Combobox, ComboboxContent, Input as ComboboxInput, ComboboxItem, ConfirmDialog, DatePicker, Dialog, Root$1 as Drawer, DrawerContent, DrawerTrigger, Field, Fieldset, FileUpload, FileUploadClearTrigger, FileUploadItem, FileUploadItemGroup, FilterGroup, FocusTrap_default as FocusTrap, Icon, Input$1 as Input, Link, Listbox, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, MoneyInput, NumberInput, Pagination, PinInput, Popover, Portal_default as Portal, Presence_default as Presence, Progress, ProgressLabel, RadioGroup, RatingGroup, SafeArea, SearchInput, Select, SelectItem, SelectPc, SelectTrigger, SignaturePad, Skeleton, Slider, Spinner, Splitter, SplitterPanel, SplitterResizeTrigger, SplitterResizeTriggerIndicator, Steps, StickyHeader, SwipeReveal, Switch, Tabs, Tag, TagsInput, Toast, ToastCloseTrigger, ToastDescription, ToastIcon, ToastTitle, ToastToaster, Toggle, ToggleGroup, ToggleGroupItem, Tour, TourCloseTrigger, TourContent, TreeView, TreeViewBranch, TreeViewBranchContent, TreeViewBranchControl, TreeViewBranchTrigger, TreeViewItem, confirm, createToaster };
63
+ export { AccordionRoot as Accordion, AccordionContent, AccordionItem, AccordionTrigger, Avatar, AvatarFallback, AvatarImage, BackToTop, Badge, BottomNavigation, BottomNavigationItem, BottomSheet, Button, Card, CardNumberInput, Carousel_default as Carousel, CarouselAutoplayTrigger, CarouselControl, CarouselIndicator, CarouselIndicatorGroup, CarouselItem, CarouselItemGroup, CarouselNextTrigger, CarouselPrevTrigger, CarouselProgressText, Checkbox, ClearTrigger, Clipboard, CloseButton, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorPicker, Root as Combobox, ComboboxContent, Input as ComboboxInput, ComboboxItem, ConfirmDialog, DatePicker, Dialog, Root$1 as Drawer, DrawerContent, DrawerTrigger, Field, Fieldset, FileUpload, FileUploadClearTrigger, FileUploadItem, FileUploadItemGroup, FilterGroup, FocusTrap_default as FocusTrap, Icon, Input$1 as Input, Link, Listbox, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, MoneyInput, NumberInput, Pagination, PhoneInput, PinInput, Popover, Portal_default as Portal, Presence_default as Presence, Progress, ProgressLabel, RadioGroup, RatingGroup, SafeArea, SearchInput, Select, SelectItem, SelectPc, SelectTrigger, SignaturePad, Skeleton, Slider, Spinner, Splitter, SplitterPanel, SplitterResizeTrigger, SplitterResizeTriggerIndicator, Steps, StickyHeader, SwipeReveal, Switch, Tabs, Tag, TagsInput, Toast, ToastCloseTrigger, ToastDescription, ToastIcon, ToastTitle, ToastToaster, Toggle, ToggleGroup, ToggleGroupItem, Tour, TourCloseTrigger, TourContent, TreeView, TreeViewBranch, TreeViewBranchContent, TreeViewBranchControl, TreeViewBranchTrigger, TreeViewItem, confirm, createToaster };
package/docs/api.md CHANGED
@@ -187,6 +187,30 @@ Currency-formatted numeric input.
187
187
  | `placeholder` | `string` | — | Placeholder text. |
188
188
  | `disabled` | `boolean` | `false` | Disabled. |
189
189
 
190
+ ### PhoneInput
191
+
192
+ International phone input backed by a country preset map. Each preset defines how many digits the number has, the display `format` (mask of `#` + separators) and the empty-state `placeholder`. Typed digits are capped to the preset length, stored raw (no country prefix, no separators), and rendered with the preset format. The input renders `type="tel"`, `inputMode="numeric"` and a `maxLength` matching the fully formatted value.
193
+
194
+ **Exports:** `PhoneInput`
195
+
196
+ | Prop | Type | Default | Description |
197
+ |---|---|---|---|
198
+ | `value` | `string \| (() => string)` | — | Phone number (digits only, no country prefix/separators). |
199
+ | `onValueChange` | `(value) => void` | — | Called with the raw digits (capped to the preset length). |
200
+ | `countryCode` | `string \| (() => string)` | `'+63'` | Country code — selects the preset and renders as the prefix adornment. |
201
+ | `invalid` | `boolean` | `false` | Error state. |
202
+ | `disabled` | `boolean` | `false` | Disabled. |
203
+ | `placeholder` | `string` | preset | Placeholder text shown while empty (overrides the preset). |
204
+
205
+ **Supported presets** (add more entries to the internal map to extend):
206
+
207
+ | Country code | Digits | Format | Placeholder |
208
+ |---|---|---|---|
209
+ | `+63` (Philippines) | 10 | `###-###-####` | `9XX-XXX-XXXX` |
210
+ | `+86` (China) | 11 | `###-####-####` | `1XX-XXXX-XXXX` |
211
+
212
+ > The controlled value holds the raw digits only — read it directly (or strip non-digits) for the payload. Passing an unknown `countryCode` keeps the given prefix but falls back to the `+63` formatting preset.
213
+
190
214
  ### NumberInput
191
215
 
192
216
  **Exports:** `NumberInput` · Escape hatch: `NumberInput.origin.{Root, DecrementTrigger, Input, IncrementTrigger}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plastic-js/tsumiki",
3
- "version": "0.1.82",
3
+ "version": "0.1.83",
4
4
  "description": "A UI component library for Plastic JS.",
5
5
  "license": "MIT",
6
6
  "author": "tigre",