@koobiq/react-components 0.1.2 → 0.2.1

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.
@@ -1,81 +1,86 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { forwardRef } from "react";
3
- import { isNotNil, clsx } from "@koobiq/react-core";
2
+ import { forwardRef, Children, isValidElement, cloneElement } from "react";
3
+ import { isNotNil, useFocusRing, mergeProps, clsx } from "@koobiq/react-core";
4
4
  import { useInputContext, Group } from "@koobiq/react-primitives";
5
5
  import s from "./FieldContentGroup.module.css.js";
6
6
  import { FieldContentGroupContext } from "./FieldContentGroupContext.js";
7
7
  import { FieldAddon } from "../FieldAddon/FieldAddon.js";
8
- const FieldContentGroup = forwardRef(
9
- ({
10
- variant = "filled",
11
- isInvalid = false,
12
- isDisabled = false,
13
- children,
14
- className,
15
- startAddon,
16
- endAddon,
17
- slotProps,
18
- ...other
19
- }, ref) => {
20
- const { value } = useInputContext();
21
- const hasStartAddon = !!startAddon;
22
- const hasEndAddon = !!endAddon;
23
- const hasValue = isNotNil(value);
24
- return /* @__PURE__ */ jsx(
25
- Group,
26
- {
27
- className: clsx(
28
- s.base,
29
- s[variant],
30
- isInvalid && s.invalid,
31
- isDisabled && s.disabled,
32
- hasStartAddon && s.hasStartAddon,
33
- hasEndAddon && s.hasEndAddon,
34
- className
35
- ),
36
- isInvalid,
37
- isDisabled,
38
- ...other,
39
- ref,
40
- children: ({ isHovered, isFocusWithin, isDisabled: isDisabled2, isInvalid: isInvalid2 }) => /* @__PURE__ */ jsxs(
41
- FieldContentGroupContext.Provider,
42
- {
43
- value: {
44
- hasValue,
45
- isHovered,
46
- isInvalid: isInvalid2,
47
- isDisabled: isDisabled2,
48
- isFocusWithin
49
- },
50
- children: [
51
- /* @__PURE__ */ jsx(
52
- FieldAddon,
53
- {
54
- placement: "start",
55
- isInvalid: isInvalid2,
56
- isDisabled: isDisabled2,
57
- ...slotProps?.startAddon,
58
- children: startAddon
59
- }
60
- ),
61
- children,
62
- /* @__PURE__ */ jsx(
63
- FieldAddon,
64
- {
65
- placement: "end",
66
- isInvalid: isInvalid2,
67
- isDisabled: isDisabled2,
68
- ...slotProps?.endAddon,
69
- children: endAddon
70
- }
71
- )
72
- ]
73
- }
74
- )
75
- }
76
- );
77
- }
78
- );
8
+ const FieldContentGroup = forwardRef(function FieldContentGroup2({
9
+ variant = "filled",
10
+ isInvalid = false,
11
+ isDisabled = false,
12
+ children,
13
+ className,
14
+ startAddon,
15
+ endAddon,
16
+ slotProps,
17
+ ...other
18
+ }, ref) {
19
+ const { value } = useInputContext();
20
+ const hasStartAddon = !!startAddon;
21
+ const hasEndAddon = !!endAddon;
22
+ const hasValue = isNotNil(value);
23
+ const { focusProps, isFocused } = useFocusRing({ within: true });
24
+ const focusManagedChildren = Children.map(children, (child) => {
25
+ if (!isValidElement(child)) return child;
26
+ const merged = mergeProps(focusProps, child.props);
27
+ return cloneElement(child, merged);
28
+ });
29
+ return /* @__PURE__ */ jsx(
30
+ Group,
31
+ {
32
+ className: clsx(
33
+ s.base,
34
+ s[variant],
35
+ isInvalid && s.invalid,
36
+ isDisabled && s.disabled,
37
+ isFocused && s.focused,
38
+ hasStartAddon && s.hasStartAddon,
39
+ hasEndAddon && s.hasEndAddon,
40
+ className
41
+ ),
42
+ isInvalid,
43
+ isDisabled,
44
+ ...other,
45
+ ref,
46
+ children: ({ isHovered, isFocusWithin }) => /* @__PURE__ */ jsxs(
47
+ FieldContentGroupContext.Provider,
48
+ {
49
+ value: {
50
+ hasValue,
51
+ isHovered,
52
+ isInvalid,
53
+ isDisabled,
54
+ isFocusWithin
55
+ },
56
+ children: [
57
+ /* @__PURE__ */ jsx(
58
+ FieldAddon,
59
+ {
60
+ placement: "start",
61
+ isInvalid,
62
+ isDisabled,
63
+ ...slotProps?.startAddon,
64
+ children: startAddon
65
+ }
66
+ ),
67
+ focusManagedChildren,
68
+ /* @__PURE__ */ jsx(
69
+ FieldAddon,
70
+ {
71
+ placement: "end",
72
+ isInvalid,
73
+ isDisabled,
74
+ ...slotProps?.endAddon,
75
+ children: endAddon
76
+ }
77
+ )
78
+ ]
79
+ }
80
+ )
81
+ }
82
+ );
83
+ });
79
84
  FieldContentGroup.displayName = "FieldContentGroup";
80
85
  export {
81
86
  FieldContentGroup
@@ -3,6 +3,7 @@ const hasStartAddon = "kbq-fieldcontentgroup-hasStartAddon-62fb80";
3
3
  const hasEndAddon = "kbq-fieldcontentgroup-hasEndAddon-e8c20a";
4
4
  const transparent = "kbq-fieldcontentgroup-transparent-ac42b6";
5
5
  const filled = "kbq-fieldcontentgroup-filled-37bb93";
6
+ const focused = "kbq-fieldcontentgroup-focused-8fb205";
6
7
  const invalid = "kbq-fieldcontentgroup-invalid-e4973b";
7
8
  const disabled = "kbq-fieldcontentgroup-disabled-54827b";
8
9
  const s = {
@@ -11,6 +12,7 @@ const s = {
11
12
  hasEndAddon,
12
13
  transparent,
13
14
  filled,
15
+ focused,
14
16
  invalid,
15
17
  disabled
16
18
  };
@@ -19,6 +21,7 @@ export {
19
21
  s as default,
20
22
  disabled,
21
23
  filled,
24
+ focused,
22
25
  hasEndAddon,
23
26
  hasStartAddon,
24
27
  invalid,
@@ -1,12 +1,12 @@
1
1
  import type { ComponentPropsWithRef } from 'react';
2
- import type { InputPropVariant } from '../../Input';
2
+ import type { FieldInputGroupPropVariant } from '../FieldContentGroup';
3
3
  export type FieldInputBaseProps = {
4
4
  isInvalid?: boolean;
5
5
  isDisabled?: boolean;
6
6
  className?: string;
7
7
  'data-testid'?: string;
8
8
  as?: 'input' | 'textarea';
9
- variant?: InputPropVariant;
9
+ variant?: FieldInputGroupPropVariant;
10
10
  };
11
11
  export declare const FieldInput: import("@koobiq/react-core").PolyForwardComponent<"input", FieldInputBaseProps, "input" | "textarea">;
12
12
  export type FieldInputProps<As extends 'input' | 'textarea' = 'input'> = ComponentPropsWithRef<typeof FieldInput<As>>;
@@ -1,12 +1,12 @@
1
1
  import { type ReactNode, type Ref } from 'react';
2
- import type { InputPropVariant } from '../../Input';
2
+ import type { FieldInputGroupPropVariant } from '../FieldContentGroup';
3
3
  export type FieldInputDateProps = {
4
4
  isInvalid?: boolean;
5
5
  isDisabled?: boolean;
6
- variant?: InputPropVariant;
7
6
  className?: string;
8
7
  children?: ReactNode;
9
8
  'data-testid'?: string;
10
9
  ref?: Ref<HTMLDivElement>;
10
+ variant?: FieldInputGroupPropVariant;
11
11
  };
12
12
  export declare const FieldInputDate: import("react").ForwardRefExoticComponent<Omit<FieldInputDateProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,13 +1,4 @@
1
- import { type ReactNode, type Ref } from 'react';
2
- import type { InputPropVariant } from '../../Input';
3
- export type FieldSelectProps = {
4
- isInvalid?: boolean;
5
- isDisabled?: boolean;
6
- className?: string;
7
- children?: ReactNode;
8
- 'data-testid'?: string;
9
- variant?: InputPropVariant;
10
- placeholder?: string | number;
11
- ref?: Ref<HTMLButtonElement>;
12
- };
13
- export declare const FieldSelect: import("react").ForwardRefExoticComponent<Omit<FieldSelectProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
1
+ import type { ComponentPropsWithRef, ElementType } from 'react';
2
+ import type { FieldSelectBaseProps } from './index';
3
+ export declare const FieldSelect: import("@koobiq/react-core").PolyForwardComponent<"button", FieldSelectBaseProps, ElementType>;
4
+ export type FieldSelectProps<As extends ElementType = 'button'> = ComponentPropsWithRef<typeof FieldSelect<As>>;
@@ -1,10 +1,10 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import { forwardRef } from "react";
3
- import { clsx, isNotNil } from "@koobiq/react-core";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { polymorphicForwardRef, clsx, isString, isNumber, isNotNil } from "@koobiq/react-core";
4
3
  import { Button } from "@koobiq/react-primitives";
5
4
  import s from "./FieldSelect.module.css.js";
6
- const FieldSelect = forwardRef(
5
+ const FieldSelect = polymorphicForwardRef(
7
6
  ({
7
+ as = "button",
8
8
  isInvalid = false,
9
9
  isDisabled = false,
10
10
  variant = "filled",
@@ -12,10 +12,11 @@ const FieldSelect = forwardRef(
12
12
  children,
13
13
  className,
14
14
  ...other
15
- }, ref) => /* @__PURE__ */ jsx(
15
+ }, ref) => /* @__PURE__ */ jsxs(
16
16
  Button,
17
17
  {
18
18
  ...other,
19
+ as,
19
20
  isDisabled,
20
21
  "data-slot": "select-value",
21
22
  className: clsx(
@@ -27,7 +28,10 @@ const FieldSelect = forwardRef(
27
28
  className
28
29
  ),
29
30
  ref,
30
- children: /* @__PURE__ */ jsx("span", { className: s.content, children: children ?? placeholder })
31
+ children: [
32
+ isString(children) || isNumber(children) ? /* @__PURE__ */ jsx("span", { className: s.content, children }) : children,
33
+ !isNotNil(children) && /* @__PURE__ */ jsx("span", { className: s.content, children: placeholder })
34
+ ]
31
35
  }
32
36
  )
33
37
  );
@@ -1 +1,2 @@
1
1
  export * from './FieldSelect';
2
+ export * from './types';
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { FieldInputGroupPropVariant } from '../FieldContentGroup';
3
+ export type FieldSelectBaseProps = {
4
+ isInvalid?: boolean;
5
+ isDisabled?: boolean;
6
+ className?: string;
7
+ children?: ReactNode;
8
+ 'data-testid'?: string;
9
+ placeholder?: string | number;
10
+ variant?: FieldInputGroupPropVariant;
11
+ };
@@ -1,6 +1,6 @@
1
1
  import { TextField } from '@koobiq/react-primitives';
2
2
  import { type FieldLabelProps, type FieldInputGroupProps, type FieldCaptionProps, type FieldErrorProps, type FieldInputProps, type FieldControlProps } from '../FieldComponents';
3
- export declare const Input: import("react").ForwardRefExoticComponent<Omit<Omit<import("@koobiq/react-primitives").TextFieldProps<HTMLInputElement>, "children" | "validationBehavior" | "validate" | "description" | "inputElementType">, "caption" | "style" | "className" | "variant" | "slotProps" | "fullWidth" | "data-testid" | "errorMessage" | "startAddon" | "endAddon" | "isLabelHidden" | keyof {
3
+ export declare const Input: import("react").ForwardRefExoticComponent<Omit<Omit<import("@koobiq/react-primitives").TextFieldProps<HTMLInputElement>, "children" | "validationBehavior" | "validate" | "description" | "inputElementType">, "caption" | "style" | "className" | "variant" | "slotProps" | "fullWidth" | "data-testid" | "startAddon" | "endAddon" | "errorMessage" | "isLabelHidden" | keyof {
4
4
  disabled?: boolean;
5
5
  error?: boolean;
6
6
  required?: boolean;
@@ -1,6 +1,6 @@
1
1
  import { NumberField } from '@koobiq/react-primitives';
2
2
  import { type FieldControlProps, type FieldLabelProps, type FieldCaptionProps, type FieldErrorProps, type FieldInputGroupProps, type FieldInputProps } from '../FieldComponents';
3
- export declare const InputNumber: import("react").ForwardRefExoticComponent<Omit<Omit<import("@koobiq/react-primitives").NumberFieldProps, "children" | "validationState" | "description" | "inputElementType">, "caption" | "style" | "className" | "variant" | "slotProps" | "fullWidth" | "data-testid" | "errorMessage" | "startAddon" | "endAddon" | "isLabelHidden" | keyof {
3
+ export declare const InputNumber: import("react").ForwardRefExoticComponent<Omit<Omit<import("@koobiq/react-primitives").NumberFieldProps, "children" | "validationState" | "description" | "inputElementType">, "caption" | "style" | "className" | "variant" | "slotProps" | "fullWidth" | "data-testid" | "startAddon" | "endAddon" | "errorMessage" | "isLabelHidden" | keyof {
4
4
  disabled?: boolean;
5
5
  error?: boolean;
6
6
  required?: boolean;
@@ -6,11 +6,12 @@ import s from "./ListItemText.module.css.js";
6
6
  import { Typography } from "../../../Typography/Typography.js";
7
7
  const ListItemText = forwardRef(
8
8
  ({ className, children, caption, slotProps, ...other }, ref) => /* @__PURE__ */ jsxs("div", { className: clsx(s.base, className), ...other, ref, children: [
9
- /* @__PURE__ */ jsx(Typography, { as: "span", ...slotProps?.text, children }),
9
+ /* @__PURE__ */ jsx(Typography, { as: "span", align: "start", ellipsis: true, ...slotProps?.text, children }),
10
10
  isNotNil(caption) && /* @__PURE__ */ jsx(
11
11
  Typography,
12
12
  {
13
13
  as: "span",
14
+ align: "start",
14
15
  color: "contrast-secondary",
15
16
  className: s.caption,
16
17
  variant: "text-compact",
package/dist/style.css CHANGED
@@ -1905,6 +1905,7 @@
1905
1905
  --badge-color: var(--kbq-foreground-contrast);
1906
1906
  }
1907
1907
  .kbq-fieldcontrol-ef127a {
1908
+ --field-control-size-height: 32px;
1908
1909
  --field-input-padding-inline-start: var(--kbq-size-m);
1909
1910
  --field-input-padding-inline-end: var(--kbq-size-m);
1910
1911
  --field-input-padding-block-start: var(--kbq-size-xs);
@@ -2017,7 +2018,7 @@
2017
2018
  --field-content-border-color: var(--kbq-line-contrast-fade);
2018
2019
  }
2019
2020
 
2020
- .kbq-fieldcontentgroup-filled-37bb93:focus-within {
2021
+ .kbq-fieldcontentgroup-filled-37bb93:where(.kbq-fieldcontentgroup-focused-8fb205) {
2021
2022
  --field-content-outline-color: var(--kbq-states-line-focus-theme);
2022
2023
  }
2023
2024
 
@@ -2025,7 +2026,7 @@
2025
2026
  --field-content-border-color: var(--kbq-line-error);
2026
2027
  }
2027
2028
 
2028
- .kbq-fieldcontentgroup-filled-37bb93:where(.kbq-fieldcontentgroup-invalid-e4973b):focus-within {
2029
+ .kbq-fieldcontentgroup-filled-37bb93:where(.kbq-fieldcontentgroup-invalid-e4973b.kbq-fieldcontentgroup-focused-8fb205) {
2029
2030
  --field-content-outline-color: var(--field-content-border-color);
2030
2031
  }
2031
2032
 
@@ -2039,8 +2040,8 @@
2039
2040
  .kbq-fieldaddon-3388d3 {
2040
2041
  --field-addon-color: var(--kbq-icon-contrast-fade);
2041
2042
  z-index: 1;
2042
- block-size: 100%;
2043
2043
  color: var(--field-addon-color);
2044
+ block-size: var(--field-control-size-height);
2044
2045
  transition: color var(--kbq-transition-default);
2045
2046
  justify-content: center;
2046
2047
  align-items: center;
@@ -2099,11 +2100,11 @@
2099
2100
  }
2100
2101
 
2101
2102
  .kbq-fieldinput-77b90b:where(input) {
2102
- block-size: var(--kbq-size-3xl);
2103
+ block-size: var(--field-control-size-height);
2103
2104
  }
2104
2105
 
2105
2106
  .kbq-fieldinput-77b90b:where(textarea) {
2106
- min-block-size: var(--kbq-size-3xl);
2107
+ min-block-size: var(--field-control-size-height);
2107
2108
  resize: none;
2108
2109
  }
2109
2110
 
@@ -3127,13 +3128,14 @@
3127
3128
  --field-input-color: var(--kbq-foreground-contrast);
3128
3129
  --field-input-bg-color: var(--kbq-background-bg);
3129
3130
  --field-input-placeholder-color: var(--kbq-foreground-contrast-tertiary);
3131
+ gap: var(--kbq-size-s);
3130
3132
  cursor: pointer;
3131
3133
  box-sizing: border-box;
3132
3134
  border-radius: inherit;
3133
- min-block-size: 32px;
3134
3135
  inline-size: 100%;
3135
3136
  color: var(--field-input-color);
3136
3137
  background: var(--field-input-bg-color);
3138
+ min-block-size: var(--field-control-size-height);
3137
3139
  padding-block: 0;
3138
3140
  padding-inline: var(--field-input-padding-inline-start) var(--field-input-padding-inline-end);
3139
3141
  transition: color var(--kbq-transition-default), background-color var(--kbq-transition-default);
@@ -3153,11 +3155,9 @@
3153
3155
  }
3154
3156
 
3155
3157
  .kbq-fieldselect-content-c36142 {
3158
+ text-align: start;
3156
3159
  white-space: nowrap;
3157
- align-items: center;
3158
- gap: var(--kbq-size-s);
3159
3160
  text-overflow: ellipsis;
3160
- display: flex;
3161
3161
  overflow: hidden;
3162
3162
  }
3163
3163
 
@@ -3411,6 +3411,7 @@
3411
3411
  padding-inline: var(--kbq-size-xxs);
3412
3412
  min-inline-size: var(--kbq-size-xxl);
3413
3413
  background-color: var(--tag-bg-color);
3414
+ outline-offset: calc(-1 * var(--tag-outline-width) / 2);
3414
3415
  outline: var(--tag-outline-width) solid var(--tag-outline-color);
3415
3416
  transition: outline-color var(--kbq-transition-default), background-color var(--kbq-transition-default), color var(--kbq-transition-default);
3416
3417
  border: none;
@@ -3817,7 +3818,7 @@
3817
3818
  cursor: pointer;
3818
3819
  box-sizing: border-box;
3819
3820
  inline-size: 100%;
3820
- block-size: var(--kbq-size-3xl);
3821
+ block-size: var(--field-control-size-height);
3821
3822
  border-radius: inherit;
3822
3823
  color: var(--field-input-color);
3823
3824
  background: var(--field-input-bg-color);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koobiq/react-components",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -28,10 +28,10 @@
28
28
  "@koobiq/design-tokens": "^3.14.0",
29
29
  "@types/react-transition-group": "^4.4.12",
30
30
  "react-transition-group": "^4.4.5",
31
- "@koobiq/logger": "0.1.2",
32
- "@koobiq/react-icons": "0.1.2",
33
- "@koobiq/react-primitives": "0.1.2",
34
- "@koobiq/react-core": "0.1.2"
31
+ "@koobiq/logger": "0.2.1",
32
+ "@koobiq/react-core": "0.2.1",
33
+ "@koobiq/react-icons": "0.2.1",
34
+ "@koobiq/react-primitives": "0.2.1"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@koobiq/design-tokens": "^3.14.0",