@rovula/ui 0.0.75 → 0.0.77

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 (43) hide show
  1. package/dist/cjs/bundle.css +12 -0
  2. package/dist/cjs/bundle.js +3 -3
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +7 -0
  5. package/dist/cjs/types/components/InputFilter/InputFilter.stories.d.ts +7 -0
  6. package/dist/cjs/types/components/NumberInput/NumberInput.d.ts +39 -0
  7. package/dist/cjs/types/components/NumberInput/NumberInput.stories.d.ts +18 -0
  8. package/dist/cjs/types/components/NumberInput/index.d.ts +2 -0
  9. package/dist/cjs/types/components/RadioGroup/RadioGroup.stories.d.ts +1 -1
  10. package/dist/cjs/types/components/Search/Search.stories.d.ts +7 -0
  11. package/dist/cjs/types/components/Slider/Slider.stories.d.ts +1 -1
  12. package/dist/cjs/types/components/TextInput/TextInput.d.ts +14 -0
  13. package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +14 -0
  14. package/dist/cjs/types/index.d.ts +2 -0
  15. package/dist/components/Button/Button.styles.js +1 -1
  16. package/dist/components/NumberInput/NumberInput.js +254 -0
  17. package/dist/components/NumberInput/NumberInput.stories.js +212 -0
  18. package/dist/components/NumberInput/index.js +1 -0
  19. package/dist/components/TextInput/TextInput.js +13 -11
  20. package/dist/esm/bundle.css +12 -0
  21. package/dist/esm/bundle.js +3 -3
  22. package/dist/esm/bundle.js.map +1 -1
  23. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +7 -0
  24. package/dist/esm/types/components/InputFilter/InputFilter.stories.d.ts +7 -0
  25. package/dist/esm/types/components/NumberInput/NumberInput.d.ts +39 -0
  26. package/dist/esm/types/components/NumberInput/NumberInput.stories.d.ts +18 -0
  27. package/dist/esm/types/components/NumberInput/index.d.ts +2 -0
  28. package/dist/esm/types/components/RadioGroup/RadioGroup.stories.d.ts +1 -1
  29. package/dist/esm/types/components/Search/Search.stories.d.ts +7 -0
  30. package/dist/esm/types/components/Slider/Slider.stories.d.ts +1 -1
  31. package/dist/esm/types/components/TextInput/TextInput.d.ts +14 -0
  32. package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +14 -0
  33. package/dist/esm/types/index.d.ts +2 -0
  34. package/dist/index.d.ts +52 -1
  35. package/dist/index.js +1 -0
  36. package/dist/src/theme/global.css +16 -0
  37. package/package.json +1 -1
  38. package/src/components/Button/Button.styles.ts +1 -1
  39. package/src/components/NumberInput/NumberInput.stories.tsx +350 -0
  40. package/src/components/NumberInput/NumberInput.tsx +428 -0
  41. package/src/components/NumberInput/index.ts +2 -0
  42. package/src/components/TextInput/TextInput.tsx +54 -12
  43. package/src/index.ts +2 -0
@@ -0,0 +1,212 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { NumberInput } from "@/index";
3
+ const meta = {
4
+ title: "Components/NumberInput",
5
+ component: NumberInput,
6
+ parameters: {
7
+ layout: "fullscreen",
8
+ },
9
+ tags: ["autodocs"],
10
+ decorators: [
11
+ (Story) => (_jsx("div", { className: "p-5 flex h-screen w-full bg-base-bg2", children: _jsx(Story, {}) })),
12
+ ],
13
+ argTypes: {
14
+ size: {
15
+ control: { type: "radio" },
16
+ options: ["sm", "md", "lg"],
17
+ },
18
+ rounded: {
19
+ control: { type: "radio" },
20
+ options: ["none", "normal", "full"],
21
+ },
22
+ variant: {
23
+ control: { type: "radio" },
24
+ options: ["flat", "outline", "underline"],
25
+ },
26
+ isFloatingLabel: { control: "boolean" },
27
+ fullwidth: { control: "boolean" },
28
+ disabled: { control: "boolean" },
29
+ error: { control: "boolean" },
30
+ required: { control: "boolean" },
31
+ hideControls: { control: "boolean" },
32
+ allowDecimal: { control: "boolean" },
33
+ allowNegative: { control: "boolean" },
34
+ },
35
+ args: {
36
+ label: "Number",
37
+ placeholder: "Enter a number",
38
+ size: "md",
39
+ rounded: "normal",
40
+ variant: "outline",
41
+ isFloatingLabel: true,
42
+ fullwidth: true,
43
+ disabled: false,
44
+ error: false,
45
+ required: true,
46
+ hideControls: false,
47
+ allowDecimal: true,
48
+ allowNegative: true,
49
+ },
50
+ };
51
+ export default meta;
52
+ export const Default = {
53
+ render: (args) => {
54
+ console.log("args ", args);
55
+ const props = Object.assign({}, args);
56
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
57
+ },
58
+ };
59
+ export const WithMinMax = {
60
+ args: {
61
+ label: "Age",
62
+ min: 0,
63
+ max: 120,
64
+ helperText: "Age must be between 0 and 120",
65
+ },
66
+ render: (args) => {
67
+ const props = Object.assign({}, args);
68
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
69
+ },
70
+ };
71
+ export const WithStep = {
72
+ args: {
73
+ label: "Rating",
74
+ min: 0,
75
+ max: 5,
76
+ step: 0.5,
77
+ defaultValue: 2.5,
78
+ helperText: "Use 0.5 increments",
79
+ },
80
+ render: (args) => {
81
+ const props = Object.assign({}, args);
82
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
83
+ },
84
+ };
85
+ export const IntegerOnly = {
86
+ args: {
87
+ label: "Quantity",
88
+ allowDecimal: false,
89
+ min: 1,
90
+ defaultValue: 1,
91
+ helperText: "Integer values only",
92
+ },
93
+ render: (args) => {
94
+ const props = Object.assign({}, args);
95
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
96
+ },
97
+ };
98
+ export const ControllWithOutLine = {
99
+ args: {
100
+ label: "Quantity",
101
+ allowDecimal: false,
102
+ iconMode: "flat",
103
+ min: 1,
104
+ defaultValue: 1,
105
+ helperText: "Integer values only",
106
+ },
107
+ render: (args) => {
108
+ const props = Object.assign({}, args);
109
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
110
+ },
111
+ };
112
+ export const WithoutControls = {
113
+ args: {
114
+ label: "Custom Number",
115
+ hideControls: true,
116
+ helperText: "No increment/decrement buttons",
117
+ },
118
+ render: (args) => {
119
+ const props = Object.assign({}, args);
120
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
121
+ },
122
+ };
123
+ export const ErrorState = {
124
+ args: {
125
+ error: true,
126
+ errorMessage: "Value exceeds maximum allowed",
127
+ defaultValue: 150,
128
+ },
129
+ render: (args) => {
130
+ const props = Object.assign({}, args);
131
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
132
+ },
133
+ };
134
+ export const HelperText = {
135
+ args: {
136
+ helperText: "Enter a number between 0 and 100",
137
+ min: 0,
138
+ max: 100,
139
+ },
140
+ render: (args) => {
141
+ const props = Object.assign({}, args);
142
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
143
+ },
144
+ };
145
+ export const Disabled = {
146
+ args: {
147
+ disabled: true,
148
+ defaultValue: 50,
149
+ },
150
+ render: (args) => {
151
+ const props = Object.assign({}, args);
152
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
153
+ },
154
+ };
155
+ export const FormattedNumber = {
156
+ args: {
157
+ label: "Amount",
158
+ formatDisplay: true,
159
+ precision: 2,
160
+ defaultValue: 1234567.89,
161
+ helperText: "Number with thousand separator",
162
+ },
163
+ render: (args) => {
164
+ const props = Object.assign({}, args);
165
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
166
+ },
167
+ };
168
+ export const CurrencyFormat = {
169
+ args: {
170
+ label: "Price",
171
+ formatDisplay: true,
172
+ precision: 2,
173
+ prefix: "$",
174
+ defaultValue: 1230.0,
175
+ min: 0,
176
+ helperText: "Currency format with $ prefix",
177
+ },
178
+ render: (args) => {
179
+ const props = Object.assign({}, args);
180
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
181
+ },
182
+ };
183
+ export const CurrencyThailand = {
184
+ args: {
185
+ label: "ราคา",
186
+ formatDisplay: true,
187
+ precision: 2,
188
+ suffix: " ฿",
189
+ defaultValue: 15000.5,
190
+ min: 0,
191
+ helperText: "Thai Baht format",
192
+ },
193
+ render: (args) => {
194
+ const props = Object.assign({}, args);
195
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
196
+ },
197
+ };
198
+ export const CustomSeparators = {
199
+ args: {
200
+ label: "European Format",
201
+ formatDisplay: true,
202
+ precision: 2,
203
+ thousandSeparator: ".",
204
+ decimalSeparator: ",",
205
+ defaultValue: 9999.99,
206
+ helperText: "European number format (9.999,99)",
207
+ },
208
+ render: (args) => {
209
+ const props = Object.assign({}, args);
210
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(NumberInput, Object.assign({ id: "1" }, props, { size: "lg" })), _jsx(NumberInput, Object.assign({ id: "2" }, props, { size: "md" })), _jsx(NumberInput, Object.assign({ id: "3" }, props, { size: "sm" }))] }));
211
+ },
212
+ };
@@ -0,0 +1 @@
1
+ export { NumberInput, default } from "./NumberInput";
@@ -15,7 +15,7 @@ import { helperTextVariant, iconSearchWrapperVariant, iconVariant, iconWrapperVa
15
15
  import { XCircleIcon, ExclamationCircleIcon, MagnifyingGlassIcon, } from "@heroicons/react/16/solid";
16
16
  import { cn } from "@/utils/cn";
17
17
  export const TextInput = forwardRef((_a, ref) => {
18
- var { id, label, size = "md", rounded = "normal", variant = "outline", type = "text", iconMode = "solid", helperText, errorMessage, fullwidth = true, disabled = false, error = false, required = true, isFloatingLabel = true, keepCloseIconOnValue = false, hasClearIcon = true, hasSearchIcon = false, startIcon, endIcon, labelClassName, onClickStartIcon, onClickEndIcon, renderStartIcon, renderEndIcon } = _a, props = __rest(_a, ["id", "label", "size", "rounded", "variant", "type", "iconMode", "helperText", "errorMessage", "fullwidth", "disabled", "error", "required", "isFloatingLabel", "keepCloseIconOnValue", "hasClearIcon", "hasSearchIcon", "startIcon", "endIcon", "labelClassName", "onClickStartIcon", "onClickEndIcon", "renderStartIcon", "renderEndIcon"]);
18
+ var { id, label, size = "md", rounded = "normal", variant = "outline", type = "text", iconMode = "solid", helperText, errorMessage, fullwidth = true, disabled = false, error = false, required = true, isFloatingLabel = true, keepCloseIconOnValue = false, hasClearIcon = true, hasSearchIcon = false, startIcon, endIcon, labelClassName, onClickStartIcon, onClickEndIcon, renderStartIcon, renderEndIcon, classes } = _a, props = __rest(_a, ["id", "label", "size", "rounded", "variant", "type", "iconMode", "helperText", "errorMessage", "fullwidth", "disabled", "error", "required", "isFloatingLabel", "keepCloseIconOnValue", "hasClearIcon", "hasSearchIcon", "startIcon", "endIcon", "labelClassName", "onClickStartIcon", "onClickEndIcon", "renderStartIcon", "renderEndIcon", "classes"]);
19
19
  const inputRef = useRef(null);
20
20
  const _id = id || `${type}-${label}-input`;
21
21
  const hasLeftSectionIcon = !!startIcon || !!renderStartIcon;
@@ -86,12 +86,13 @@ export const TextInput = forwardRef((_a, ref) => {
86
86
  const startIconElement = useMemo(() => {
87
87
  if (!hasLeftSectionIcon)
88
88
  return;
89
- if (renderStartIcon)
90
- return renderStartIcon();
89
+ if (renderStartIcon) {
90
+ return (_jsx("div", { className: cn(iconSearchWrapperClassname, "flex", classes === null || classes === void 0 ? void 0 : classes.iconSearchWrapper), children: renderStartIcon() }));
91
+ }
91
92
  if (iconMode === "flat") {
92
- return (_jsx("div", { className: iconSearchWrapperClassname, children: _jsx("div", { className: iconClassname, onClick: handleOnClickLeftSectionIcon, children: startIcon }) }));
93
+ return (_jsx("div", { className: cn(iconSearchWrapperClassname, classes === null || classes === void 0 ? void 0 : classes.iconSearchWrapper), children: _jsx("div", { className: cn(iconClassname, classes === null || classes === void 0 ? void 0 : classes.icon), onClick: handleOnClickLeftSectionIcon, children: startIcon }) }));
93
94
  }
94
- return (_jsx("div", { className: startIconWrapperClassname, onClick: handleOnClickLeftSectionIcon, children: startIcon }));
95
+ return (_jsx("div", { className: cn(startIconWrapperClassname, classes === null || classes === void 0 ? void 0 : classes.startIconWrapper), onClick: handleOnClickLeftSectionIcon, children: startIcon }));
95
96
  }, [
96
97
  hasLeftSectionIcon,
97
98
  startIcon,
@@ -105,12 +106,13 @@ export const TextInput = forwardRef((_a, ref) => {
105
106
  const endIconElement = useMemo(() => {
106
107
  if (!hasRightSectionIcon)
107
108
  return;
108
- if (renderEndIcon)
109
- return renderEndIcon();
109
+ if (renderEndIcon) {
110
+ return (_jsx("div", { className: cn(iconWrapperClassname, "flex", classes === null || classes === void 0 ? void 0 : classes.iconWrapper), children: renderEndIcon() }));
111
+ }
110
112
  if (iconMode === "flat") {
111
- return (_jsx("div", { className: cn(iconWrapperClassname, "flex"), children: _jsx("div", { className: iconClassname, onClick: handleOnClickRightSectionIcon, children: endIcon }) }));
113
+ return (_jsx("div", { className: cn(iconWrapperClassname, "flex", classes === null || classes === void 0 ? void 0 : classes.iconWrapper), children: _jsx("div", { className: cn(iconClassname, classes === null || classes === void 0 ? void 0 : classes.icon), onClick: handleOnClickRightSectionIcon, children: endIcon }) }));
112
114
  }
113
- return (_jsx("div", { className: endIconWrapperClassname, onClick: handleOnClickRightSectionIcon, children: endIcon }));
115
+ return (_jsx("div", { className: cn(endIconWrapperClassname, classes === null || classes === void 0 ? void 0 : classes.endIconWrapper), onClick: handleOnClickRightSectionIcon, children: endIcon }));
114
116
  }, [
115
117
  hasRightSectionIcon,
116
118
  endIcon,
@@ -121,9 +123,9 @@ export const TextInput = forwardRef((_a, ref) => {
121
123
  renderEndIcon,
122
124
  handleOnClickRightSectionIcon,
123
125
  ]);
124
- return (_jsxs("div", { className: `inline-flex flex-col ${fullwidth ? "w-full" : ""}`, children: [_jsxs("div", { className: "relative", children: [hasSearchIcon && !hasLeftSectionIcon && (_jsx("div", { className: iconSearchWrapperClassname, children: _jsx(MagnifyingGlassIcon, { className: iconClassname }) })), _jsx("input", Object.assign({}, props, { placeholder: " ", ref: inputRef, type: type, id: _id, disabled: disabled, className: cn(inputClassname, props.className) })), startIconElement, hasClearIcon && !hasRightSectionIcon && (_jsx("div", { className: iconWrapperClassname, style: {
126
+ return (_jsxs("div", { className: `inline-flex flex-col ${fullwidth ? "w-full" : ""}`, children: [_jsxs("div", { className: "relative", children: [hasSearchIcon && !hasLeftSectionIcon && (_jsx("div", { className: cn(iconSearchWrapperClassname, classes === null || classes === void 0 ? void 0 : classes.iconSearchWrapper), children: _jsx(MagnifyingGlassIcon, { className: cn(iconClassname, classes === null || classes === void 0 ? void 0 : classes.icon) }) })), _jsx("input", Object.assign({}, props, { placeholder: " ", ref: inputRef, type: type, id: _id, disabled: disabled, className: cn(inputClassname, props.className) })), startIconElement, hasClearIcon && !hasRightSectionIcon && (_jsx("div", { className: cn(iconWrapperClassname, classes === null || classes === void 0 ? void 0 : classes.iconWrapper), style: {
125
127
  display: keepCloseIconOnValue && props.value ? "flex" : undefined,
126
- }, children: _jsx(XCircleIcon, { type: "button", className: iconClassname, onMouseDown: handleClearInput }) })), endIconElement, _jsxs("label", { htmlFor: _id, className: cn(labelClassname), children: [label, " ", required && (_jsx("span", { className: cn("text-error", {
128
+ }, children: _jsx(XCircleIcon, { type: "button", className: cn(iconClassname, classes === null || classes === void 0 ? void 0 : classes.icon), onMouseDown: handleClearInput }) })), endIconElement, _jsxs("label", { htmlFor: _id, className: cn(labelClassname), children: [label, " ", required && (_jsx("span", { className: cn("text-error", {
127
129
  "text-input-disable-text": disabled,
128
130
  }), children: "*" }))] })] }), (errorMessage || helperText) && (_jsxs("span", { className: helperTextClassname, children: [_jsx("span", { className: "h-full", children: _jsx(ExclamationCircleIcon, { width: 16, height: 16, className: error ? "fill-error" : "" }) }), errorMessage || helperText] }))] }));
129
131
  });
@@ -638,6 +638,12 @@ input[type=number] {
638
638
  .top-0{
639
639
  top: 0px;
640
640
  }
641
+ .top-0\.5{
642
+ top: 0.125rem;
643
+ }
644
+ .top-1{
645
+ top: 0.25rem;
646
+ }
641
647
  .top-4{
642
648
  top: 1rem;
643
649
  }
@@ -4086,6 +4092,9 @@ input[type=number] {
4086
4092
  --tw-bg-opacity: 1;
4087
4093
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
4088
4094
  }
4095
+ .hover\:bg-input-active-stroke\/10:hover{
4096
+ background-color: color-mix(in srgb, var(--input-color-active-stroke) calc(100% * 0.1), transparent);
4097
+ }
4089
4098
  .hover\:bg-input-disable-bg:hover{
4090
4099
  --tw-bg-opacity: 1;
4091
4100
  background-color: color-mix(in srgb, var(--input-color-disable-bg) calc(100% * var(--tw-bg-opacity, 1)), transparent);
@@ -5165,6 +5174,9 @@ input[type=number] {
5165
5174
  --tw-text-opacity: 1;
5166
5175
  color: color-mix(in srgb, var(--state-color-disable-outline) calc(100% * var(--tw-text-opacity, 1)), transparent);
5167
5176
  }
5177
+ .disabled\:opacity-30:disabled{
5178
+ opacity: 0.3;
5179
+ }
5168
5180
  .disabled\:opacity-50:disabled{
5169
5181
  opacity: 0.5;
5170
5182
  }