@kanda-libs/ks-component-ts 0.2.292 → 0.2.294

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.
package/dist/library.css CHANGED
@@ -4131,6 +4131,11 @@ input[type="range"]::-webkit-slider-thumb {
4131
4131
  color: rgb(156 173 196 / var(--tw-text-opacity));
4132
4132
  }
4133
4133
 
4134
+ .first\:text-orange-200:first-child {
4135
+ --tw-text-opacity: 1;
4136
+ color: rgb(235 125 50 / var(--tw-text-opacity));
4137
+ }
4138
+
4134
4139
  .last\:right-0:last-child {
4135
4140
  right: 0;
4136
4141
  }
@@ -4174,6 +4179,11 @@ input[type="range"]::-webkit-slider-thumb {
4174
4179
  color: rgb(156 173 196 / var(--tw-text-opacity));
4175
4180
  }
4176
4181
 
4182
+ .last\:text-orange-200:last-child {
4183
+ --tw-text-opacity: 1;
4184
+ color: rgb(235 125 50 / var(--tw-text-opacity));
4185
+ }
4186
+
4177
4187
  .checked\:translate-x-5:checked {
4178
4188
  --tw-translate-x: 20px;
4179
4189
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanda-libs/ks-component-ts",
3
- "version": "0.2.292",
3
+ "version": "0.2.294",
4
4
  "description": "Kanda form component library",
5
5
  "main": "dist/index.esm.js",
6
6
  "module": "dist/index.esm.js",
@@ -38,6 +38,10 @@ export interface Props {
38
38
  * Display options wrap
39
39
  */
40
40
  wrap?: boolean;
41
+ /**
42
+ * Adds a border to options when wrapping
43
+ */
44
+ wrapBorder?: boolean;
41
45
  /**
42
46
  * Display variant
43
47
  */
@@ -58,6 +62,14 @@ export interface Props {
58
62
  * Icon to display next to the option
59
63
  */
60
64
  icon?: string;
65
+ /**
66
+ * Class name for the option
67
+ */
68
+ className?: string;
69
+ /**
70
+ * Footer content that is shown outside of the option
71
+ */
72
+ footer?: JSX.Element;
61
73
  }
62
74
 
63
75
  const Option: FunctionComponent<Props> = function ({
@@ -70,9 +82,12 @@ const Option: FunctionComponent<Props> = function ({
70
82
  isLoading,
71
83
  inline = false,
72
84
  wrap = false,
85
+ wrapBorder = true,
73
86
  register,
74
87
  onClick = () => {},
75
88
  warning = false,
89
+ className = "",
90
+ footer,
76
91
  icon,
77
92
  }) {
78
93
  const { id, classNames, handleProps, Handle } = useOption(
@@ -82,48 +97,53 @@ const Option: FunctionComponent<Props> = function ({
82
97
  variant,
83
98
  inline,
84
99
  wrap,
100
+ wrapBorder,
85
101
  register,
86
102
  disabled,
87
- warning
103
+ warning,
104
+ className
88
105
  );
89
106
 
90
107
  return (
91
- <label htmlFor={id} key={value} className={classNames.option as string}>
92
- <div className={classNames.container as string}>
93
- <div
94
- className={classNames.handleContainer as string}
95
- onClick={() => {
96
- onClick();
97
- }}
98
- >
99
- <Handle
100
- id={id}
101
- {...handleProps}
102
- value={value}
103
- isLoading={isLoading}
104
- disabled={disabled}
105
- />
106
- </div>
107
- {isLoading ? (
108
- <div className={classNames.skeletonWrapper as string}>
109
- <div className={classNames.skeleton as string}>
110
- <Skeleton />
111
- </div>
108
+ <div className="flex flex-col items-start justify-start">
109
+ <label htmlFor={id} key={value} className={classNames.option as string}>
110
+ <div className={classNames.container as string}>
111
+ <div
112
+ className={classNames.handleContainer as string}
113
+ onClick={() => {
114
+ onClick();
115
+ }}
116
+ >
117
+ <Handle
118
+ id={id}
119
+ {...handleProps}
120
+ value={value}
121
+ isLoading={isLoading}
122
+ disabled={disabled}
123
+ />
112
124
  </div>
113
- ) : (
114
- <span className={classNames.span as string}>
115
- {icon && (
116
- <Icon
117
- icon={icon}
118
- size={12}
119
- className={classNames.icon as string}
120
- />
121
- )}
122
- {name}
123
- </span>
124
- )}
125
- </div>
126
- </label>
125
+ {isLoading ? (
126
+ <div className={classNames.skeletonWrapper as string}>
127
+ <div className={classNames.skeleton as string}>
128
+ <Skeleton />
129
+ </div>
130
+ </div>
131
+ ) : (
132
+ <span className={classNames.span as string}>
133
+ {icon && (
134
+ <Icon
135
+ icon={icon}
136
+ size={12}
137
+ className={classNames.icon as string}
138
+ />
139
+ )}
140
+ {name}
141
+ </span>
142
+ )}
143
+ </div>
144
+ </label>
145
+ {footer}
146
+ </div>
127
147
  );
128
148
  };
129
149
 
@@ -27,9 +27,11 @@ export default function useOption(
27
27
  variantName: RadioSelectVariant,
28
28
  inline: boolean,
29
29
  wrap: boolean,
30
+ wrapBorder: boolean,
30
31
  register: FieldRegisterMethod | null = null,
31
32
  disabled?: boolean,
32
- warning?: boolean
33
+ warning?: boolean,
34
+ className: string = ""
33
35
  ): Hook {
34
36
  const { skeletonClasses } = useFormTheme();
35
37
 
@@ -61,8 +63,9 @@ export default function useOption(
61
63
 
62
64
  const classNames = useClasses(variant, {
63
65
  option: [
66
+ className,
64
67
  optionFlex,
65
- wrap && "mt-2 ml-2",
68
+ wrap && wrapBorder && "mt-2 ml-2",
66
69
  disabled && variant?.disabled?.option
67
70
  ? `.disabled.option`
68
71
  : `.${selectedPrefix}.option`,
@@ -78,6 +81,7 @@ export default function useOption(
78
81
  variant?.skeleton ? `.${selectedPrefix}.skeleton` : skeletonClasses,
79
82
  ],
80
83
  icon: [variant?.[selectedPrefix]?.icon],
84
+ optionWrapper: "flex flex-col items-start justify-start",
81
85
  });
82
86
 
83
87
  /**
@@ -8,7 +8,7 @@ export const CLASS_NAMES = {
8
8
  optionWrapper: "flex flex-1",
9
9
  },
10
10
  wrap: {
11
- container: "w-full flex flex-row flex-wrap -mt-2 -ml-2",
11
+ container: "w-full flex flex-row flex-wrap -mt-2 -ml-2 gap-x-2",
12
12
  optionWrapper: "flex",
13
13
  },
14
14
  };
@@ -6,8 +6,20 @@ import Option from "./Option";
6
6
 
7
7
  const RadioSelectUncontrolled: FunctionComponent<
8
8
  DefaultFormFieldProps<RadioSelectUncontrolledProps>
9
- > = function ({ name, inline = false, wrap = false, options, ...restProps }) {
10
- const classNames = useRadioSelectUncontrolledClassNames(inline, wrap);
9
+ > = function ({
10
+ name,
11
+ inline = false,
12
+ wrap = false,
13
+ wrapBorder = true,
14
+ options,
15
+ className,
16
+ ...restProps
17
+ }) {
18
+ const classNames = useRadioSelectUncontrolledClassNames(
19
+ inline,
20
+ wrap,
21
+ className
22
+ );
11
23
 
12
24
  return (
13
25
  <div className={classNames.container}>
@@ -18,10 +30,13 @@ const RadioSelectUncontrolled: FunctionComponent<
18
30
  name={option.name}
19
31
  inline={inline}
20
32
  wrap={wrap}
33
+ wrapBorder={wrapBorder}
21
34
  key={option.value}
22
35
  disabled={option?.disabled || false}
23
36
  warning={option.warning || false}
24
37
  icon={option.icon}
38
+ className={option.className}
39
+ footer={option.footer}
25
40
  {...restProps}
26
41
  />
27
42
  ))}
@@ -2,10 +2,12 @@ import { useMemo } from "react";
2
2
 
3
3
  import { CLASS_NAMES } from "./constants";
4
4
  import { type StringIndexedObject } from "~/types";
5
+ import clsx from "clsx";
5
6
 
6
7
  export default function useRadioSelectUncontrolledClassNames(
7
8
  inline: boolean,
8
- wrap: boolean
9
+ wrap: boolean,
10
+ className?: string
9
11
  ): StringIndexedObject<string> {
10
12
  const classNames = useMemo(() => {
11
13
  if (wrap) return CLASS_NAMES.wrap;
@@ -13,5 +15,5 @@ export default function useRadioSelectUncontrolledClassNames(
13
15
  return CLASS_NAMES.multiline;
14
16
  }, [inline, wrap]);
15
17
 
16
- return classNames;
18
+ return { ...classNames, container: clsx(classNames.container, className) };
17
19
  }
@@ -16,7 +16,9 @@ export interface RadioSelectUncontrolledProps {
16
16
  multiple?: boolean;
17
17
  inline?: boolean;
18
18
  wrap?: boolean;
19
+ wrapBorder?: boolean;
19
20
  variant?: RadioSelectVariant;
20
21
  options?: SelectOption[];
21
22
  onClick?: () => void;
23
+ className?: string;
22
24
  }
@@ -11,6 +11,7 @@ export interface RangeInputUncontrolledProps
11
11
  steps?: string;
12
12
  formatter?: (value: string) => string;
13
13
  prefix?: string;
14
+ highlightLabel?: "min" | "max";
14
15
  suffix?: string;
15
16
  }
16
17
 
@@ -28,10 +29,21 @@ const RangeInputUncontrolled: FunctionComponent<
28
29
  prefix = "",
29
30
  suffix = "",
30
31
  name = "",
32
+ highlightLabel,
31
33
  ...restProps
32
34
  }) {
33
35
  const { ref, inputProps, minLabel, maxLabel, currentLabel, classNames } =
34
- useRangeInputProps(name, min, max, steps, formatter, prefix, suffix, error);
36
+ useRangeInputProps(
37
+ name,
38
+ min,
39
+ max,
40
+ steps,
41
+ formatter,
42
+ prefix,
43
+ suffix,
44
+ error,
45
+ highlightLabel
46
+ );
35
47
 
36
48
  return (
37
49
  <div className={classNames.container}>
@@ -61,11 +73,11 @@ const RangeInputUncontrolled: FunctionComponent<
61
73
  <div className={classNames.cap} />
62
74
  </div>
63
75
  <div className={classNames.labels}>
64
- <p className={classNames.lowerLabel}>{minLabel}</p>
76
+ <p className={classNames.minLowerLabel}>{minLabel}</p>
65
77
  {currentLabel && (
66
78
  <p className={classNames.lowerLabel}>{currentLabel}</p>
67
79
  )}
68
- <p className={classNames.lowerLabel}>{maxLabel}</p>
80
+ <p className={classNames.maxLowerLabel}>{maxLabel}</p>
69
81
  </div>
70
82
  </>
71
83
  }
@@ -9,6 +9,8 @@ export const CLASS_NAMES = {
9
9
  upperLabel: "text-10-17-em-up text-green-600",
10
10
  lowerLabel:
11
11
  "text-12-18-em text-green-600 first:text-neutral-500 last:text-neutral-500 w-20 min-w-20 text-center first:text-left last:text-right",
12
+ highlightedLowerLabel:
13
+ "text-12-18-em text-green-600 first:text-orange-200 last:text-orange-200 w-20 min-w-20 text-center first:text-left last:text-right",
12
14
  rangeWrapper: "flex flex-row relative",
13
15
  cap: "w-2.5 h-2.5 bg-green-600 rounded-full border border-neutral-000 absolute z-0 top-[5px] first:left-0 last:right-0",
14
16
  };
@@ -5,6 +5,7 @@ import clsx from "clsx";
5
5
  import { BG_COLOR, CLASS_NAMES } from "./constants";
6
6
 
7
7
  import { ErrorMessage } from "~/field/types";
8
+ import { RangeInputUncontrolledProps } from "./RangeInputUncontrolled";
8
9
 
9
10
  interface RangeClassNames {
10
11
  container: string;
@@ -14,6 +15,8 @@ interface RangeClassNames {
14
15
  upperLabel: string;
15
16
  lowerLabel: string;
16
17
  rangeWrapper: string;
18
+ minLowerLabel: string;
19
+ maxLowerLabel: string;
17
20
  cap: string;
18
21
  }
19
22
 
@@ -40,7 +43,8 @@ export default function useRangeInputProps(
40
43
  formatter: (input: string) => string,
41
44
  prefix: string,
42
45
  suffix: string,
43
- error?: string | ErrorMessage
46
+ error?: string | ErrorMessage,
47
+ highlightLabel?: RangeInputUncontrolledProps["highlightLabel"]
44
48
  ): Hook {
45
49
  const value = useWatch({ name });
46
50
 
@@ -70,6 +74,14 @@ export default function useRangeInputProps(
70
74
  CLASS_NAMES.container,
71
75
  error ? "border-red-200" : "border-neutral-100"
72
76
  ),
77
+ minLowerLabel: clsx(
78
+ CLASS_NAMES.lowerLabel,
79
+ highlightLabel === "min" && CLASS_NAMES.highlightedLowerLabel
80
+ ),
81
+ maxLowerLabel: clsx(
82
+ CLASS_NAMES.lowerLabel,
83
+ highlightLabel === "max" && CLASS_NAMES.highlightedLowerLabel
84
+ ),
73
85
  };
74
86
 
75
87
  useEffect(() => {
@@ -7,6 +7,8 @@ export interface SelectOption {
7
7
  disabled?: boolean;
8
8
  warning?: boolean;
9
9
  icon?: string;
10
+ className?: string;
11
+ footer?: JSX.Element;
10
12
  }
11
13
 
12
14
  export interface SelectUncontrolledProps {
@@ -1,16 +1,23 @@
1
1
  import * as t from "io-ts";
2
+ import { CustomerOptions } from "./CustomerOptions";
2
3
 
3
- export const JobOverride = t.type({
4
- action: t.union([
5
- t.literal("mark_job_as_sat_note_delayed"),
6
- t.literal("mark_job_as_pending"),
7
- t.literal("mark_job_as_referred"),
8
- t.literal("mark_job_as_action_customer"),
9
- t.literal("mark_job_as_accepted"),
10
- t.literal("mark_job_as_declined"),
11
- t.literal("mark_job_as_cancelled"),
12
- ]),
13
- });
4
+ export const JobOverride = t.intersection([
5
+ t.type({
6
+ action: t.union([
7
+ t.literal("mark_job_as_sat_note_delayed"),
8
+ t.literal("mark_job_as_pending"),
9
+ t.literal("mark_job_as_referred"),
10
+ t.literal("mark_job_as_action_customer"),
11
+ t.literal("mark_job_as_accepted"),
12
+ t.literal("mark_job_as_declined"),
13
+ t.literal("mark_job_as_cancelled"),
14
+ ]),
15
+ }),
16
+ t.partial({
17
+ customer_options: CustomerOptions,
18
+ xref: t.string,
19
+ }),
20
+ ]);
14
21
 
15
22
  export interface JobOverride {
16
23
  action:
@@ -21,4 +28,6 @@ export interface JobOverride {
21
28
  | "mark_job_as_accepted"
22
29
  | "mark_job_as_declined"
23
30
  | "mark_job_as_cancelled";
31
+ customer_options?: CustomerOptions;
32
+ xref?: string;
24
33
  }