@rovula/ui 0.0.7 → 0.0.8

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 (37) hide show
  1. package/dist/cjs/bundle.css +64 -28
  2. package/dist/cjs/bundle.js +1 -1
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/Select/Select copy.d.ts +23 -0
  5. package/dist/cjs/types/components/Select/Select.d.ts +23 -0
  6. package/dist/cjs/types/components/Select/Select.stories.d.ts +348 -0
  7. package/dist/cjs/types/components/Select/Select.styles.d.ts +14 -0
  8. package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +0 -1
  9. package/dist/cjs/types/index.d.ts +1 -0
  10. package/dist/components/Select/Select copy.js +42 -0
  11. package/dist/components/Select/Select.js +21 -0
  12. package/dist/components/Select/Select.stories.js +46 -0
  13. package/dist/components/Select/Select.styles.js +100 -0
  14. package/dist/components/TextInput/TextInput.js +2 -4
  15. package/dist/components/TextInput/TextInput.stories.js +1 -1
  16. package/dist/components/TextInput/TextInput.styles.js +13 -21
  17. package/dist/esm/bundle.css +64 -28
  18. package/dist/esm/bundle.js +1 -1
  19. package/dist/esm/bundle.js.map +1 -1
  20. package/dist/esm/types/components/Select/Select copy.d.ts +23 -0
  21. package/dist/esm/types/components/Select/Select.d.ts +23 -0
  22. package/dist/esm/types/components/Select/Select.stories.d.ts +348 -0
  23. package/dist/esm/types/components/Select/Select.styles.d.ts +14 -0
  24. package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +0 -1
  25. package/dist/esm/types/index.d.ts +1 -0
  26. package/dist/index.d.ts +24 -1
  27. package/dist/index.js +1 -0
  28. package/dist/src/theme/global.css +78 -32
  29. package/package.json +1 -1
  30. package/src/components/Select/Select copy.tsx +103 -0
  31. package/src/components/Select/Select.stories.tsx +52 -0
  32. package/src/components/Select/Select.styles.ts +111 -0
  33. package/src/components/Select/Select.tsx +54 -0
  34. package/src/components/TextInput/TextInput.stories.tsx +3 -3
  35. package/src/components/TextInput/TextInput.styles.ts +13 -21
  36. package/src/components/TextInput/TextInput.tsx +3 -3
  37. package/src/index.ts +1 -0
@@ -0,0 +1,103 @@
1
+ import React, { useState } from "react";
2
+
3
+ import { labelVariant, selectVariant } from "./Select.styles";
4
+ import { helperTextVariant } from "../TextInput/TextInput.styles";
5
+ import { ExclamationCircleIcon } from "@heroicons/react/16/solid";
6
+ import { twMerge } from "tailwind-merge";
7
+ import TextInput from "../TextInput/TextInput";
8
+
9
+ type Options = {
10
+ value: string;
11
+ label: string;
12
+ };
13
+
14
+ type SelectProps = {
15
+ id?: string;
16
+ label?: string;
17
+ size?: "sm" | "md" | "lg";
18
+ rounded?: "none" | "normal" | "full";
19
+ variant?: "flat" | "outline" | "underline";
20
+ type?: React.HTMLInputTypeAttribute;
21
+ helperText?: string;
22
+ errorMessage?: string;
23
+ fullwidth?: boolean;
24
+ disabled?: boolean;
25
+ error?: boolean;
26
+ required?: boolean;
27
+ className?: string;
28
+ options: Options[];
29
+ } & Omit<React.InputHTMLAttributes<HTMLSelectElement>, "size">;
30
+
31
+ const Select = ({
32
+ id,
33
+ options,
34
+ label,
35
+ size = "md",
36
+ rounded = "normal",
37
+ variant = "outline",
38
+ type = "text",
39
+ helperText,
40
+ errorMessage,
41
+ fullwidth = true,
42
+ disabled = false,
43
+ error = false,
44
+ required = true,
45
+ ...props
46
+ }: SelectProps) => {
47
+ const _id = id || `${type}-${label}-select`;
48
+
49
+ const [isPlaceholderShown, setIsPlaceholderShown] = useState(true);
50
+
51
+ return (
52
+ <div className={`relative ${fullwidth ? "w-full" : "w-auto"}`}>
53
+ <select
54
+ id={_id}
55
+ {...props}
56
+ className={twMerge(
57
+ selectVariant({
58
+ size,
59
+ variant,
60
+ rounded,
61
+ fullwidth,
62
+ disabled,
63
+ error,
64
+ }),
65
+ props.className
66
+ )}
67
+ disabled={disabled}
68
+ >
69
+ <option
70
+ value=""
71
+ disabled
72
+ selected={true}
73
+ className="hidden select-placeholder"
74
+ ></option>
75
+ {options.map((option) => (
76
+ <option key={option.value} value={option.value}>
77
+ {option.label}
78
+ </option>
79
+ ))}
80
+ </select>
81
+ {label && (
82
+ <label
83
+ className={labelVariant({ size, isPlaceholderShown })}
84
+ htmlFor="select"
85
+ >
86
+ {label} {required && <span className="text-error">*</span>}
87
+ </label>
88
+ )}
89
+ {(errorMessage || helperText) && (
90
+ <span className={helperTextVariant({ size, error, disabled })}>
91
+ <ExclamationCircleIcon
92
+ width={16}
93
+ height={16}
94
+ className={error ? "fill-error" : ""}
95
+ />{" "}
96
+ {errorMessage || helperText}
97
+ </span>
98
+ )}
99
+ </div>
100
+ );
101
+ };
102
+
103
+ export default Select;
@@ -0,0 +1,52 @@
1
+ import React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import Select from "./Select";
4
+
5
+ // More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
6
+ const meta = {
7
+ title: "Components/Select",
8
+ component: Select,
9
+ tags: ["autodocs"],
10
+ parameters: {
11
+ // More on how to position stories at: https://storybook.js.org/docs/7.0/react/configure/story-layout
12
+ layout: "fullscreen",
13
+ },
14
+ decorators: [
15
+ (Story) => (
16
+ <div className="p-5 flex w-full">
17
+ <Story />
18
+ </div>
19
+ ),
20
+ ],
21
+ } satisfies Meta<typeof Select>;
22
+
23
+ export default meta;
24
+
25
+ const options = [
26
+ { value: "option1", label: "Option 1" },
27
+ { value: "option2", label: "Option 2" },
28
+ { value: "option3", label: "Option 3" },
29
+ { value: "option4", label: "Option 4" },
30
+ ];
31
+
32
+ export const Default = {
33
+ args: {
34
+ label: "Choose an option:",
35
+ // value: "",
36
+ fullwidth: true,
37
+ options,
38
+ },
39
+ render: (args) => {
40
+ console.log("args ", args);
41
+ const props: typeof args = {
42
+ ...args,
43
+ };
44
+ return (
45
+ <div className="flex flex-row gap-4 w-full">
46
+ <Select id="1" size="lg" options={options} {...args} />
47
+ <Select id="2" size="md" options={options} {...args} />
48
+ <Select id="3" size="sm" options={options} {...args} />
49
+ </div>
50
+ );
51
+ },
52
+ } satisfies StoryObj;
@@ -0,0 +1,111 @@
1
+ import React from "react";
2
+ import { cva } from "class-variance-authority";
3
+
4
+ export const selectVariant = cva(
5
+ [
6
+ "border-0 outline-none",
7
+ "p-1 flex w-auto box-border",
8
+ "peer text-black placeholder:text-transparent",
9
+ ],
10
+ {
11
+ variants: {
12
+ size: {
13
+ sm: "p-2 px-3 typography-small1",
14
+ md: "py-2 px-3 typography-subtitile4",
15
+ lg: "p-4 typography-subtitile1",
16
+ },
17
+ rounded: {
18
+ none: "rounded-none",
19
+ normal: "rounded-xl",
20
+ full: "rounded-full",
21
+ },
22
+ variant: {
23
+ flat: "",
24
+ outline:
25
+ "ring-1 ring-inset ring-input-stroke hover:ring-input-active focus:ring-1 focus:ring-inset focus:ring-input-stroke-active",
26
+ underline:
27
+ "border-b-2 border-input-stroke transition-colors hover:border-input-stroke-active focus:border-input-stroke",
28
+ },
29
+ fullwidth: {
30
+ true: "w-full",
31
+ },
32
+ disabled: {
33
+ true: "text-input-text-disabled ring-input-stroke-disabled placeholder:text-input-text-disabled",
34
+ },
35
+ error: {
36
+ true: "ring-error focus:ring-error",
37
+ },
38
+ },
39
+ defaultVariants: {
40
+ size: "md",
41
+ variant: "outline",
42
+ rounded: "normal",
43
+ fullwidth: false,
44
+ disabled: false,
45
+ error: false,
46
+ },
47
+ }
48
+ );
49
+
50
+ export const labelVariant = cva(
51
+ [
52
+ "absolute block duration-450 transition-all px-[2px] text-input-text peer-focus:text-input-text-active peer-focus:bg-input-label-background",
53
+ ],
54
+ {
55
+ variants: {
56
+ size: {
57
+ sm: [
58
+ "left-3 -top-1.5 bg-input-label-background",
59
+ "peer-focus:-top-1.5 peer-focus:typography-label2",
60
+ ],
61
+ md: [
62
+ "left-3 -top-1.5 bg-input-label-background",
63
+ "peer-focus:-top-1.5 peer-focus:typography-label1",
64
+ ],
65
+ lg: [
66
+ "left-4 -top-1.5 bg-input-label-background",
67
+ "peer-focus:-top-1.5 peer-focus:typography-label1",
68
+ // "peer-placeholder-shown:top-4 peer-placeholder-shown:typography-subtitile1 peer-placeholder-shown:bg-transparent",
69
+ ],
70
+ },
71
+ disabled: {
72
+ true: "text-input-text-disabled ring-input-stroke-disabled placeholder:text-input-text-disabled",
73
+ },
74
+ error: {
75
+ true: "ring-error",
76
+ },
77
+ isPlaceholderShown: {
78
+ // true: "",
79
+ false: "typography-label1",
80
+ },
81
+ },
82
+ compoundVariants: [
83
+ {
84
+ size: "sm",
85
+ isPlaceholderShown: false,
86
+ className: "typography-label2",
87
+ },
88
+ {
89
+ isPlaceholderShown: true,
90
+ size: "sm",
91
+ className: "top-2 typography-small1 bg-transparent",
92
+ },
93
+ {
94
+ isPlaceholderShown: true,
95
+ size: "md",
96
+ className: "top-2 typography-subtitile4 bg-transparent",
97
+ },
98
+ {
99
+ isPlaceholderShown: true,
100
+ size: "lg",
101
+ className: "top-4 typography-subtitile1 bg-transparent",
102
+ },
103
+ ],
104
+ defaultVariants: {
105
+ size: "md",
106
+ disabled: false,
107
+ error: false,
108
+ isPlaceholderShown: false,
109
+ },
110
+ }
111
+ );
@@ -0,0 +1,54 @@
1
+ import React, { useState } from "react";
2
+
3
+ import TextInput from "../TextInput/TextInput";
4
+
5
+ type Options = {
6
+ value: string;
7
+ label: string;
8
+ };
9
+
10
+ type SelectProps = {
11
+ id?: string;
12
+ label?: string;
13
+ size?: "sm" | "md" | "lg";
14
+ rounded?: "none" | "normal" | "full";
15
+ variant?: "flat" | "outline" | "underline";
16
+ type?: React.HTMLInputTypeAttribute;
17
+ helperText?: string;
18
+ errorMessage?: string;
19
+ fullwidth?: boolean;
20
+ disabled?: boolean;
21
+ error?: boolean;
22
+ required?: boolean;
23
+ className?: string;
24
+ options: Options[];
25
+ } & Omit<React.InputHTMLAttributes<HTMLSelectElement>, "size">;
26
+
27
+ const Select = ({
28
+ id,
29
+ options,
30
+ label,
31
+ size = "md",
32
+ rounded = "normal",
33
+ variant = "outline",
34
+ type = "text",
35
+ helperText,
36
+ errorMessage,
37
+ fullwidth = true,
38
+ disabled = false,
39
+ error = false,
40
+ required = true,
41
+ ...props
42
+ }: SelectProps) => {
43
+ const _id = id || `${type}-${label}-select`;
44
+
45
+ const [isPlaceholderShown, setIsPlaceholderShown] = useState(true);
46
+
47
+ return (
48
+ <div className={`relative ${fullwidth ? "w-full" : "w-auto"}`}>
49
+ <TextInput label="Test" />
50
+ </div>
51
+ );
52
+ };
53
+
54
+ export default Select;
@@ -35,9 +35,9 @@ export const Default = {
35
35
  };
36
36
  return (
37
37
  <div className="flex flex-row gap-4 w-full">
38
- <TextInput id="1" placeholder="placeholder" size="lg" {...args} />
39
- <TextInput id="2" placeholder="placeholder" size="md" {...args} />
40
- <TextInput id="3" placeholder="placeholder" size="sm" {...args} />
38
+ <TextInput id="1" size="lg" {...args} />
39
+ <TextInput id="2" size="md" {...args} />
40
+ <TextInput id="3" size="sm" {...args} />
41
41
  </div>
42
42
  );
43
43
  },
@@ -3,7 +3,7 @@ import { cva } from "class-variance-authority";
3
3
  export const inputVariant = cva(
4
4
  [
5
5
  "border-0 outline-none",
6
- "p-1 flex",
6
+ "p-1 flex w-auto box-border",
7
7
  "peer text-black placeholder:text-transparent",
8
8
  ],
9
9
  {
@@ -21,7 +21,7 @@ export const inputVariant = cva(
21
21
  variant: {
22
22
  flat: "",
23
23
  outline:
24
- "ring-1 ring-inset ring-input-stroke hover:ring-input-active focus:ring-2 focus:ring-inset focus:ring-input-active",
24
+ "ring-1 ring-inset ring-input-stroke hover:ring-input-active focus:ring-1 focus:ring-inset focus:ring-input-stroke-active",
25
25
  underline:
26
26
  "border-b-2 border-input-stroke transition-colors hover:border-input-stroke-active focus:border-input-stroke",
27
27
  },
@@ -32,7 +32,7 @@ export const inputVariant = cva(
32
32
  true: "text-input-text-disabled ring-input-stroke-disabled placeholder:text-input-text-disabled",
33
33
  },
34
34
  error: {
35
- true: "ring-error",
35
+ true: "ring-error focus:ring-error",
36
36
  },
37
37
  hasClearIcon: {
38
38
  true: "",
@@ -73,22 +73,25 @@ export const inputVariant = cva(
73
73
 
74
74
  export const labelVariant = cva(
75
75
  [
76
- "absolute block transition-all px-[2px] text-input-text peer-focus:text-input-text-active peer-focus:bg-input-label-background",
76
+ "absolute block duration-450 transition-all px-[2px] text-input-text peer-focus:text-input-text-active peer-focus:bg-input-label-background",
77
77
  ],
78
78
  {
79
79
  variants: {
80
80
  size: {
81
81
  sm: [
82
- "left-3 top-2 typography-small1 peer-focus:-top-1.5 peer-focus:typography-label2",
83
- "bg-input-label-background peer-[:not(:placeholder-shown)]:-top-1.5 peer-[:not(:placeholder-shown)]:typography-label2",
82
+ "left-3 -top-1.5 typography-label2 bg-input-label-background",
83
+ "peer-placeholder-shown:top-2 peer-placeholder-shown:typography-small1 peer-placeholder-shown:bg-transparent",
84
+ "peer-focus:-top-1.5 peer-focus:typography-label2",
84
85
  ],
85
86
  md: [
86
- "left-3 top-2 typography-subtitile4 peer-focus:-top-1.5 peer-focus:typography-label1",
87
- "bg-input-label-background peer-[:not(:placeholder-shown)]:-top-1.5 peer-[:not(:placeholder-shown)]:typography-label1",
87
+ "left-3 -top-1.5 typography-label1 bg-input-label-background",
88
+ "peer-placeholder-shown:top-2 peer-placeholder-shown:typography-subtitile4 peer-placeholder-shown:bg-transparent",
89
+ "peer-focus:-top-1.5 peer-focus:typography-label1",
88
90
  ],
89
91
  lg: [
90
- "left-4 top-4 typography-subtitile1 peer-focus:-top-1.5 peer-focus:typography-label1",
91
- "bg-input-label-background peer-[:not(:placeholder-shown)]:-top-1.5 peer-[:not(:placeholder-shown)]:typography-label1",
92
+ "left-4 -top-1.5 typography-label1 bg-input-label-background",
93
+ "peer-placeholder-shown:top-4 peer-placeholder-shown:typography-subtitile1 peer-placeholder-shown:bg-transparent",
94
+ "peer-focus:-top-1.5 peer-focus:typography-label1",
92
95
  ],
93
96
  },
94
97
  disabled: {
@@ -97,22 +100,11 @@ export const labelVariant = cva(
97
100
  error: {
98
101
  true: "ring-error",
99
102
  },
100
- isFloating: {
101
- true: "-top-1.5 typography-label1 bg-input-label-background",
102
- },
103
103
  },
104
- compoundVariants: [
105
- {
106
- size: "sm",
107
- isFloating: true,
108
- class: "-top-1.5 typography-label2 bg-input-label-background",
109
- },
110
- ],
111
104
  defaultVariants: {
112
105
  size: "md",
113
106
  disabled: false,
114
107
  error: false,
115
- isFloating: false,
116
108
  },
117
109
  }
118
110
  );
@@ -37,7 +37,7 @@ const TextInput: FC<InputProps> = forwardRef(
37
37
  type = "text",
38
38
  helperText,
39
39
  errorMessage,
40
- fullwidth = false,
40
+ fullwidth = true,
41
41
  disabled = false,
42
42
  error = false,
43
43
  required = true,
@@ -61,7 +61,6 @@ const TextInput: FC<InputProps> = forwardRef(
61
61
  size,
62
62
  disabled,
63
63
  error,
64
- isFloating: !!props.value ?? false,
65
64
  });
66
65
  const helperTextClassname = helperTextVariant({ size, error, disabled });
67
66
  const iconWrapperClassname = iconWrapperVariant({ size });
@@ -78,10 +77,11 @@ const TextInput: FC<InputProps> = forwardRef(
78
77
  };
79
78
 
80
79
  return (
81
- <div className={`flex flex-col ${fullwidth ? "w-full" : ""}`}>
80
+ <div className={`inline-flex flex-col ${fullwidth ? "w-full" : ""}`}>
82
81
  <div className="relative">
83
82
  <input
84
83
  {...props}
84
+ placeholder=" "
85
85
  ref={inputRef}
86
86
  type={type}
87
87
  id={_id}
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ export { default as Table } from "./components/Table/Table";
6
6
  export { default as TextInput } from "./components/TextInput/TextInput";
7
7
  export { default as Text } from "./components/Text/Text";
8
8
  export { default as Tabs } from "./components/Tabs/Tabs";
9
+ export { default as Select } from "./components/Select/Select";
9
10
 
10
11
  // UTILS
11
12
  export {