@worknice/whiteboard 0.38.0 → 0.39.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.
@@ -9,5 +9,5 @@ type Props = ComponentProps<typeof NumberInput> & {
9
9
  labelFont?: LabelFontOption;
10
10
  required?: boolean;
11
11
  };
12
- declare const NumberField: ({ autoFocus, description, disabled, errors, id, label, labelFont, onChange, placeholder, required, value, prefix, suffix, }: Props) => import("react/jsx-runtime").JSX.Element;
12
+ declare const NumberField: ({ autoFocus, decimalPlaces, description, disabled, errors, format, id, label, labelFont, maxLength, onChange, placeholder, required, value, prefix, suffix, }: Props) => import("react/jsx-runtime").JSX.Element;
13
13
  export default NumberField;
@@ -1,7 +1,7 @@
1
1
  import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__ from "react/jsx-runtime";
2
2
  import * as __WEBPACK_EXTERNAL_MODULE__forms_RegularField_js_c54537ba__ from "../forms/RegularField.js";
3
3
  import * as __WEBPACK_EXTERNAL_MODULE__inputs_NumberInput_js_eaace22f__ from "../inputs/NumberInput.js";
4
- const NumberField = ({ autoFocus = false, description, disabled = false, errors, id, label, labelFont = "label", onChange, placeholder, required = false, value, prefix, suffix })=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__forms_RegularField_js_c54537ba__["default"], {
4
+ const NumberField = ({ autoFocus = false, decimalPlaces, description, disabled = false, errors, format, id, label, labelFont = "label", maxLength, onChange, placeholder, required = false, value, prefix, suffix })=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__forms_RegularField_js_c54537ba__["default"], {
5
5
  description: description,
6
6
  errors: errors,
7
7
  inputId: id,
@@ -10,10 +10,13 @@ const NumberField = ({ autoFocus = false, description, disabled = false, errors,
10
10
  required: required,
11
11
  children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__inputs_NumberInput_js_eaace22f__["default"], {
12
12
  autoFocus: autoFocus,
13
+ decimalPlaces: decimalPlaces,
13
14
  disabled: disabled,
15
+ format: format,
14
16
  id: id,
15
17
  value: value,
16
18
  onChange: onChange,
19
+ maxLength: maxLength,
17
20
  placeholder: placeholder,
18
21
  prefix: prefix,
19
22
  suffix: suffix
@@ -1,8 +1,10 @@
1
1
  import { type Dispatch } from "react";
2
2
  type Props = {
3
3
  autoFocus?: boolean;
4
+ decimalPlaces?: number;
4
5
  disabled?: boolean;
5
6
  id?: string;
7
+ format?: "integer" | "decimal";
6
8
  maxLength?: number;
7
9
  onChange: Dispatch<number | null>;
8
10
  placeholder?: string;
@@ -10,5 +12,5 @@ type Props = {
10
12
  prefix?: string;
11
13
  suffix?: string;
12
14
  };
13
- declare const NumberInput: ({ autoFocus, disabled, id, maxLength, onChange, placeholder, value, prefix, suffix, }: Props) => import("react/jsx-runtime").JSX.Element;
15
+ declare const NumberInput: ({ autoFocus, decimalPlaces, disabled, id, format, maxLength, onChange, placeholder, value, prefix, suffix, }: Props) => import("react/jsx-runtime").JSX.Element;
14
16
  export default NumberInput;
@@ -4,14 +4,38 @@ import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE__NumberInput_module_js_5606faf2__ from "./NumberInput.module.js";
5
5
  const DEFAULT_MAX_LENGTH = 10;
6
6
  const MAXIMUM_MAX_LENGTH = 15;
7
- const NumberInput = ({ autoFocus = false, disabled, id, maxLength = DEFAULT_MAX_LENGTH, onChange, placeholder, value, prefix, suffix })=>{
7
+ const INTEGER_REGEX = /^\d*$/;
8
+ const NumberInput = ({ autoFocus = false, decimalPlaces, disabled, id, format = "integer", maxLength = DEFAULT_MAX_LENGTH, onChange, placeholder, value, prefix, suffix })=>{
8
9
  const ref = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)(null);
9
10
  const actualMaxLength = Math.min(maxLength, MAXIMUM_MAX_LENGTH);
11
+ const [displayValue, setDisplayValue] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(null === value ? "" : value.toString());
10
12
  (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
11
13
  if (autoFocus && ref.current) ref.current.focus();
12
14
  }, [
13
15
  autoFocus
14
16
  ]);
17
+ (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
18
+ setDisplayValue(null === value ? "" : value.toString());
19
+ }, [
20
+ value
21
+ ]);
22
+ const handleChange = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((event)=>{
23
+ const rawValue = event.target.value;
24
+ if ("decimal" === format) {
25
+ const partialPattern = void 0 !== decimalPlaces ? new RegExp(`^(\\d+(\\.\\d{0,${decimalPlaces}})?)?$`) : /^(\d+(\.\d*)?)?$/;
26
+ if (!partialPattern.test(rawValue)) return;
27
+ }
28
+ if ("integer" === format && !INTEGER_REGEX.test(rawValue)) return;
29
+ setDisplayValue(rawValue);
30
+ if (!rawValue) return onChange(null);
31
+ if ("decimal" === format) {
32
+ if (isValidDecimal(rawValue, decimalPlaces)) onChange(parseFloat(rawValue));
33
+ } else if (isValidInteger(rawValue)) onChange(parseInt(rawValue));
34
+ }, [
35
+ format,
36
+ decimalPlaces,
37
+ onChange
38
+ ]);
15
39
  return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("div", {
16
40
  className: __WEBPACK_EXTERNAL_MODULE__NumberInput_module_js_5606faf2__["default"].container,
17
41
  children: [
@@ -29,13 +53,11 @@ const NumberInput = ({ autoFocus = false, disabled, id, maxLength = DEFAULT_MAX_
29
53
  disabled: disabled,
30
54
  id: id,
31
55
  maxLength: actualMaxLength,
32
- onChange: (event)=>{
33
- onChange(event.target.value ? isValidInteger(event.target.value) ? parseInt(event.target.value) : null : null);
34
- },
56
+ onChange: handleChange,
35
57
  placeholder: placeholder,
36
58
  type: "text",
37
- value: null === value ? "" : value.toString(),
38
- inputMode: "numeric"
59
+ value: displayValue,
60
+ inputMode: "decimal" === format ? "decimal" : "numeric"
39
61
  }),
40
62
  suffix ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
41
63
  className: __WEBPACK_EXTERNAL_MODULE__NumberInput_module_js_5606faf2__["default"].suffix,
@@ -45,9 +67,14 @@ const NumberInput = ({ autoFocus = false, disabled, id, maxLength = DEFAULT_MAX_
45
67
  });
46
68
  };
47
69
  const isValidInteger = (str)=>{
48
- if (!/^\d+$/.test(str)) return false;
70
+ if (!INTEGER_REGEX.test(str)) return false;
49
71
  const num = Number(str);
50
72
  return Number.isSafeInteger(num) && num >= 0;
51
73
  };
74
+ const isValidDecimal = (str, decimalPlaces)=>{
75
+ const pattern = void 0 !== decimalPlaces ? new RegExp(`^\\d+(\\.\\d{0,${decimalPlaces}})?$`) : /^\d+(\.\d+)?$/;
76
+ if (!pattern.test(str)) return false;
77
+ return Number.isFinite(Number(str));
78
+ };
52
79
  const NumberInput_rslib_entry_ = NumberInput;
53
80
  export { NumberInput_rslib_entry_ as default };
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from "react";
2
+ import { type MenuButtonOption } from "../controls/MenuButton";
3
+ type Props<Item> = {
4
+ items: Item[];
5
+ getItemId: (item: Item) => string;
6
+ itemToHref?: (item: Item) => string;
7
+ renderLeading?: (item: Item) => ReactNode;
8
+ Content: (props: {
9
+ item: Item;
10
+ }) => ReactNode;
11
+ renderTrailing?: (item: Item) => ReactNode;
12
+ rowActions?: (item: Item) => Array<MenuButtonOption | null>;
13
+ emptyState?: ReactNode;
14
+ };
15
+ declare const LightweightTable: <Item>({ items, getItemId, itemToHref, renderLeading, Content, renderTrailing, rowActions, emptyState, }: Props<Item>) => import("react/jsx-runtime").JSX.Element;
16
+ export default LightweightTable;
@@ -0,0 +1,68 @@
1
+ import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__ from "react/jsx-runtime";
2
+ import * as __WEBPACK_EXTERNAL_MODULE__controls_MenuButton_js_b23cdd05__ from "../controls/MenuButton.js";
3
+ import * as __WEBPACK_EXTERNAL_MODULE__utils_useNextContext_js_47529181__ from "../utils/useNextContext.js";
4
+ import * as __WEBPACK_EXTERNAL_MODULE__Icon_js_0d271bb6__ from "./Icon.js";
5
+ import * as __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__ from "./LightweightTable.module.js";
6
+ import * as __WEBPACK_EXTERNAL_MODULE__Placeholder_js_b43af71f__ from "./Placeholder.js";
7
+ const LightweightTable = ({ items, getItemId, itemToHref, renderLeading, Content, renderTrailing, rowActions, emptyState = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__Placeholder_js_b43af71f__["default"], {
8
+ children: "No results"
9
+ }) })=>{
10
+ const { Link } = (0, __WEBPACK_EXTERNAL_MODULE__utils_useNextContext_js_47529181__["default"])();
11
+ if (0 === items.length) return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
12
+ className: __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].emptyState,
13
+ children: emptyState
14
+ });
15
+ return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("ul", {
16
+ className: __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].list,
17
+ children: items.map((item)=>{
18
+ const href = itemToHref?.(item);
19
+ const rowBody = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)(__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.Fragment, {
20
+ children: [
21
+ renderLeading ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
22
+ className: __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].leading,
23
+ children: renderLeading(item)
24
+ }) : null,
25
+ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
26
+ className: __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].main,
27
+ children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(Content, {
28
+ item: item
29
+ })
30
+ }),
31
+ renderTrailing ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
32
+ className: __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].trailing,
33
+ children: renderTrailing ? renderTrailing(item) : null
34
+ }) : null
35
+ ]
36
+ });
37
+ return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("li", {
38
+ className: __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].item,
39
+ children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("div", {
40
+ className: __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].rowContainer,
41
+ children: [
42
+ href ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(Link, {
43
+ className: `${__WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].row} ${__WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].link}`,
44
+ href: href,
45
+ children: rowBody
46
+ }) : /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
47
+ className: __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].row,
48
+ children: rowBody
49
+ }),
50
+ rowActions ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
51
+ className: __WEBPACK_EXTERNAL_MODULE__LightweightTable_module_js_15596fa6__["default"].rowAction,
52
+ children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__controls_MenuButton_js_b23cdd05__["default"], {
53
+ type: "ghost",
54
+ size: "small",
55
+ options: rowActions(item).filter((action)=>null !== action),
56
+ icon: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__Icon_js_0d271bb6__["default"], {
57
+ symbol: "Overflow"
58
+ })
59
+ })
60
+ }) : null
61
+ ]
62
+ })
63
+ }, getItemId(item));
64
+ })
65
+ });
66
+ };
67
+ const LightweightTable_rslib_entry_ = LightweightTable;
68
+ export { LightweightTable_rslib_entry_ as default };
@@ -0,0 +1,14 @@
1
+ import "./LightweightTable_module.css";
2
+ const LightweightTable_module_rslib_entry_ = {
3
+ list: "list-E1CQI2",
4
+ item: "item-VbcWW0",
5
+ rowContainer: "rowContainer-sYzch8",
6
+ row: "row-pj1qr6",
7
+ link: "link-YrrPa1",
8
+ leading: "leading-lvOFvz",
9
+ main: "main-yvxuJs",
10
+ trailing: "trailing-EgnYr0",
11
+ rowAction: "rowAction-g1XoYD",
12
+ emptyState: "emptyState-UDJkMS"
13
+ };
14
+ export { LightweightTable_module_rslib_entry_ as default };
@@ -0,0 +1,103 @@
1
+ .list-E1CQI2 {
2
+ background: var(--color-white);
3
+ border-radius: var(--size-n3);
4
+ border: solid var(--size-n5) var(--color-grey-t08);
5
+ margin: 0;
6
+ padding: 0;
7
+ list-style: none;
8
+ overflow: hidden;
9
+ }
10
+
11
+ .item-VbcWW0 {
12
+ border-top: solid var(--size-n5) var(--color-grey-t08);
13
+ }
14
+
15
+ .item-VbcWW0:first-child {
16
+ border-top: none;
17
+ }
18
+
19
+ .rowContainer-sYzch8 {
20
+ grid-template-columns: minmax(0, 1fr) auto;
21
+ align-items: stretch;
22
+ width: 100%;
23
+ display: grid;
24
+ }
25
+
26
+ .row-pj1qr6 {
27
+ background-color: var(--color-white);
28
+ color: inherit;
29
+ align-items: center;
30
+ column-gap: var(--size-n1);
31
+ min-height: 72px;
32
+ padding: var(--size-00);
33
+ grid-template-columns: auto minmax(0, 1fr) auto;
34
+ width: 100%;
35
+ text-decoration: none;
36
+ display: grid;
37
+ }
38
+
39
+ .link-YrrPa1 {
40
+ cursor: pointer;
41
+ }
42
+
43
+ @media (hover: hover) {
44
+ .link-YrrPa1:hover {
45
+ background-color: var(--color-grey-t10);
46
+ }
47
+ }
48
+
49
+ .row-pj1qr6:focus-visible {
50
+ outline: var(--size-n4) solid var(--color-purple-000);
51
+ outline-offset: calc(var(--size-n4) * -1);
52
+ }
53
+
54
+ .leading-lvOFvz {
55
+ align-items: center;
56
+ display: grid;
57
+ }
58
+
59
+ .main-yvxuJs {
60
+ min-width: 0;
61
+ }
62
+
63
+ .trailing-EgnYr0 {
64
+ align-items: center;
65
+ gap: var(--size-n2);
66
+ justify-content: flex-end;
67
+ min-width: max-content;
68
+ display: inline-flex;
69
+ }
70
+
71
+ .rowAction-g1XoYD {
72
+ padding-right: var(--size-00);
73
+ align-items: center;
74
+ display: grid;
75
+ }
76
+
77
+ .emptyState-UDJkMS {
78
+ padding: var(--size-00);
79
+ }
80
+
81
+ @media (max-width: 768px) {
82
+ .row-pj1qr6 {
83
+ align-items: start;
84
+ row-gap: var(--size-n2);
85
+ grid-template-columns: minmax(0, 1fr);
86
+ min-height: auto;
87
+ }
88
+
89
+ .leading-lvOFvz {
90
+ margin-bottom: var(--size-n3);
91
+ }
92
+
93
+ .trailing-EgnYr0 {
94
+ margin-top: var(--size-n3);
95
+ justify-content: flex-end;
96
+ width: 100%;
97
+ }
98
+
99
+ .rowAction-g1XoYD {
100
+ padding: var(--size-n2) var(--size-00) var(--size-00) 0;
101
+ }
102
+ }
103
+
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@worknice/whiteboard",
3
3
  "description": "",
4
- "version": "0.38.0",
4
+ "version": "0.39.0",
5
5
  "license": "MIT",
6
6
  "private": false,
7
7
  "files": [
@@ -39,7 +39,7 @@
39
39
  "react-markdown": "^10.1.0",
40
40
  "utf8": "^3.0.0",
41
41
  "zod": "^4.1.13",
42
- "@worknice/utils": "^0.21.0"
42
+ "@worknice/utils": "^0.22.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@anolilab/semantic-release-pnpm": "^3.2.2",