@ayseaistudio/ui-components 3.0.2 → 3.1.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.
@@ -0,0 +1,23 @@
1
+ import PropTypes from "prop-types";
2
+ import "./style.css";
3
+ interface Props {
4
+ text?: string;
5
+ size?: "large" | "medium" | "small";
6
+ status?: "pressing" | "disabled" | "hover" | "default";
7
+ className?: any;
8
+ leftIcon?: React.JSX.Element;
9
+ withButton?: boolean;
10
+ onClick?: () => void;
11
+ }
12
+ export declare const ChipsButton: {
13
+ ({ text, size, status, className, leftIcon, withButton, onClick, }: Props): React.JSX.Element;
14
+ propTypes: {
15
+ text: PropTypes.Requireable<string>;
16
+ withLeftIcon: PropTypes.Requireable<boolean>;
17
+ withText: PropTypes.Requireable<boolean>;
18
+ withButton: PropTypes.Requireable<boolean>;
19
+ size: PropTypes.Requireable<string>;
20
+ status: PropTypes.Requireable<string>;
21
+ };
22
+ };
23
+ export {};
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import PropTypes from "prop-types";
3
+ import { useReducer } from "react";
4
+ import "./style.css";
5
+ import { TertiaryButton } from "../TertiaryButton/TertiaryButton";
6
+ import { IconX } from "@tabler/icons-react";
7
+ export const ChipsButton = ({ text, size, status, className, leftIcon, withButton, onClick, }) => {
8
+ const [state, dispatch] = useReducer(reducer, {
9
+ size: size || "large",
10
+ status: status || "default",
11
+ });
12
+ return (_jsxs("div", { className: `chips-button size-0-${state.size} status-0-${state.status} ${className}`, onMouseEnter: () => {
13
+ dispatch("mouse_enter");
14
+ }, onMouseLeave: () => {
15
+ dispatch("mouse_leave");
16
+ }, children: [leftIcon && (leftIcon), text && _jsx("div", { className: "button", children: text }), withButton && (_jsx(TertiaryButton, { className: `${state.status === "pressing" || (state.size === "large" && state.status === "hover") || (state.size === "small" && state.status === "hover") ? "class-5" : (state.status === "hover" && state.size === "medium") ? "class-6" : state.status === "disabled" && state.size === "medium" ? "class-7" : "class-8"}`, color: "black", leftIcon: _jsx(IconX, { size: 16, color: "#6D6D6D" }), size: state.size === "small" ? "x-small" : "small", status: "default", onClick: onClick }))] }));
17
+ };
18
+ function reducer(state, action) {
19
+ switch (action) {
20
+ case "mouse_enter":
21
+ return {
22
+ ...state,
23
+ status: "hover",
24
+ };
25
+ case "mouse_leave":
26
+ return {
27
+ ...state,
28
+ status: "default",
29
+ };
30
+ }
31
+ return state;
32
+ }
33
+ ChipsButton.propTypes = {
34
+ text: PropTypes.string,
35
+ withLeftIcon: PropTypes.bool,
36
+ withText: PropTypes.bool,
37
+ withButton: PropTypes.bool,
38
+ size: PropTypes.oneOf(["large", "medium", "small"]),
39
+ status: PropTypes.oneOf(["pressing", "disabled", "hover", "default"]),
40
+ };
@@ -0,0 +1 @@
1
+ export { ChipsButton } from "./ChipsButton";
@@ -0,0 +1 @@
1
+ export { ChipsButton } from "./ChipsButton";
@@ -0,0 +1,149 @@
1
+ .chips-button {
2
+ align-items: center;
3
+ gap: 4px;
4
+ justify-content: center;
5
+ padding: 4px;
6
+ position: relative;
7
+ }
8
+
9
+ .chips-button .class-2 {
10
+ height: 20px !important;
11
+ margin-left: -0.50px !important;
12
+ position: relative !important;
13
+ width: 20px !important;
14
+ }
15
+
16
+ .chips-button .class-3 {
17
+ height: 16px !important;
18
+ position: relative !important;
19
+ width: 16px !important;
20
+ }
21
+
22
+ .chips-button .class-4 {
23
+ height: 20px !important;
24
+ position: relative !important;
25
+ width: 20px !important;
26
+ }
27
+
28
+ .chips-button .button {
29
+ -webkit-box-orient: vertical;
30
+ -webkit-line-clamp: 1;
31
+ display: -webkit-box;
32
+ overflow: hidden;
33
+ position: relative;
34
+ text-overflow: ellipsis;
35
+ white-space: nowrap;
36
+ }
37
+
38
+ .chips-button .class-5 {
39
+ flex: 0 0 auto !important;
40
+ }
41
+
42
+ .chips-button .class-6 {
43
+ flex: 0 0 auto !important;
44
+ margin-right: -0.50px !important;
45
+ }
46
+
47
+ .chips-button .class-7 {
48
+ flex: 0 0 auto !important;
49
+ margin-right: -0.50px !important;
50
+ }
51
+
52
+ .chips-button .class-8 {
53
+ flex: 0 0 auto !important;
54
+ }
55
+
56
+ .chips-button.size-0-large {
57
+ border-radius: 12px;
58
+ display: inline-flex;
59
+ height: 48px;
60
+ min-width: 44px;
61
+ }
62
+
63
+ .chips-button.size-0-small {
64
+ border-radius: 8px;
65
+ display: flex;
66
+ height: 36px;
67
+ width: 107px;
68
+ }
69
+
70
+ .chips-button.size-0-medium {
71
+ border-radius: 12px;
72
+ display: flex;
73
+ height: 40px;
74
+ width: 107px;
75
+ }
76
+
77
+ .chips-button.status-0-pressing {
78
+ background-color: #2424241a;
79
+ }
80
+
81
+ .chips-button.status-0-hover {
82
+ background-color: #2424241a;
83
+ }
84
+
85
+ .chips-button.size-0-large .button {
86
+ flex: 1;
87
+ font-family: var(--h6-medium-font-family);
88
+ font-size: var(--h6-medium-font-size);
89
+ font-style: var(--h6-medium-font-style);
90
+ font-weight: var(--h6-medium-font-weight);
91
+ height: 24px;
92
+ letter-spacing: var(--h6-medium-letter-spacing);
93
+ line-height: var(--h6-medium-line-height);
94
+ }
95
+
96
+ .chips-button.size-0-small .button {
97
+ flex: 1;
98
+ font-family: var(--b1-medium-font-family);
99
+ font-size: var(--b1-medium-font-size);
100
+ font-style: var(--b1-medium-font-style);
101
+ font-weight: var(--b1-medium-font-weight);
102
+ height: 20px;
103
+ letter-spacing: var(--b1-medium-letter-spacing);
104
+ line-height: var(--b1-medium-line-height);
105
+ }
106
+
107
+ .chips-button.status-0-default .button {
108
+ color: #6d6d6d;
109
+ flex: 1;
110
+ }
111
+
112
+ .chips-button.status-0-disabled .button {
113
+ color: #b0b0b0;
114
+ }
115
+
116
+ .chips-button.size-0-medium .button {
117
+ font-family: var(--b1-medium-font-family);
118
+ font-size: var(--b1-medium-font-size);
119
+ font-style: var(--b1-medium-font-style);
120
+ font-weight: var(--b1-medium-font-weight);
121
+ letter-spacing: var(--b1-medium-letter-spacing);
122
+ line-height: var(--b1-medium-line-height);
123
+ }
124
+
125
+ .chips-button.status-0-pressing .button {
126
+ color: #3d3d3d;
127
+ flex: 1;
128
+ }
129
+
130
+ .chips-button.status-0-hover .button {
131
+ color: #454545;
132
+ }
133
+
134
+ .chips-button.size-0-medium.status-0-disabled .button {
135
+ width: fit-content;
136
+ }
137
+
138
+ .chips-button.status-0-default.size-0-medium .button {
139
+ height: 20px;
140
+ }
141
+
142
+ .chips-button.status-0-hover.size-0-medium .button {
143
+ width: fit-content;
144
+ }
145
+
146
+ .chips-button.status-0-pressing.size-0-medium .button {
147
+ height: 20px;
148
+ }
149
+
@@ -0,0 +1,23 @@
1
+ import PropTypes from "prop-types";
2
+ import "./style.css";
3
+ interface Props {
4
+ withClose?: boolean;
5
+ text?: string;
6
+ header?: string;
7
+ color?: "black" | "green" | "galliano" | "red" | "disabled";
8
+ className?: any;
9
+ textSpaceClassName?: any;
10
+ icon?: React.JSX.Element;
11
+ }
12
+ export declare const Flag: {
13
+ ({ withClose, text, header, color, className, textSpaceClassName, icon, }: Props): React.JSX.Element;
14
+ propTypes: {
15
+ withClose: PropTypes.Requireable<boolean>;
16
+ withIcon: PropTypes.Requireable<boolean>;
17
+ text: PropTypes.Requireable<string>;
18
+ header: PropTypes.Requireable<string>;
19
+ color: PropTypes.Requireable<string>;
20
+ description: PropTypes.Requireable<string>;
21
+ };
22
+ };
23
+ export {};
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import PropTypes from "prop-types";
3
+ import "./style.css";
4
+ import { TertiaryButton } from "../TertiaryButton/TertiaryButton";
5
+ export const Flag = ({ withClose = true, text, header, color, className, textSpaceClassName, icon, }) => {
6
+ return (_jsxs("div", { className: `flag ${color} ${className}`, children: [_jsxs("div", { className: `text-space ${textSpaceClassName}`, children: [text && (_jsxs(_Fragment, { children: [_jsx("div", { className: "flag-header", children: header }), _jsx(_Fragment, { children: text && _jsx("p", { className: "i-will-auto-dismiss", children: text }) })] })), header && _jsx(_Fragment, { children: header })] }), withClose && (_jsx(TertiaryButton, { className: "button-tertiary-instance", color: "black", leftIcon: icon, size: "small", status: "default" }))] }));
7
+ };
8
+ Flag.propTypes = {
9
+ withClose: PropTypes.bool,
10
+ withIcon: PropTypes.bool,
11
+ text: PropTypes.string,
12
+ header: PropTypes.string,
13
+ color: PropTypes.oneOf(["black", "green", "galliano", "red", "disabled"]),
14
+ description: PropTypes.oneOf(["off", "on"]),
15
+ };
@@ -0,0 +1 @@
1
+ export { Flag } from "./Flag";
@@ -0,0 +1 @@
1
+ export { Flag } from "./Flag";
@@ -0,0 +1,159 @@
1
+ .flag {
2
+ border: 1px solid;
3
+ border-radius: 12px;
4
+ gap: 8px;
5
+ padding: 8px;
6
+ position: relative;
7
+ }
8
+
9
+ .flag .icons-2 {
10
+ height: 24px !important;
11
+ position: relative !important;
12
+ width: 24px !important;
13
+ }
14
+
15
+ .flag .text-space {
16
+ flex: 1;
17
+ position: relative;
18
+ }
19
+
20
+ .flag .flag-header {
21
+ align-self: stretch;
22
+ font-family: var(--b1-bold-font-family);
23
+ font-size: var(--b1-bold-font-size);
24
+ font-style: var(--b1-bold-font-style);
25
+ font-weight: var(--b1-bold-font-weight);
26
+ letter-spacing: var(--b1-bold-letter-spacing);
27
+ line-height: var(--b1-bold-line-height);
28
+ margin-top: -1.00px;
29
+ position: relative;
30
+ }
31
+
32
+ .flag .i-will-auto-dismiss {
33
+ align-self: stretch;
34
+ font-family: var(--b2-medium-font-family);
35
+ font-size: var(--b2-medium-font-size);
36
+ font-style: var(--b2-medium-font-style);
37
+ font-weight: var(--b2-medium-font-weight);
38
+ letter-spacing: var(--b2-medium-letter-spacing);
39
+ line-height: var(--b2-medium-line-height);
40
+ position: relative;
41
+ }
42
+
43
+ .flag .button-tertiary-instance {
44
+ flex: 0 0 auto !important;
45
+ }
46
+
47
+ .flag.black {
48
+ border-color: #2424241a;
49
+ display: flex;
50
+ width: 309px;
51
+ }
52
+
53
+ .flag.red {
54
+ border-color: #ed151533;
55
+ display: flex;
56
+ width: 309px;
57
+ }
58
+
59
+ .flag.galliano {
60
+ border-color: rgba(170, 70, 19, 0.2);
61
+ }
62
+
63
+ .flag.disabled {
64
+ border-color: #2424241a;
65
+ }
66
+
67
+ .flag.green {
68
+ border-color: #28914033;
69
+ }
70
+
71
+ .flag.green {
72
+ display: inline-flex;
73
+ }
74
+
75
+ .flag.galliano {
76
+ display: inline-flex;
77
+ }
78
+
79
+ .flag.disabled {
80
+ display: inline-flex;
81
+ }
82
+
83
+ .flag.text-space {
84
+ align-items: flex-start;
85
+ display: flex;
86
+ flex-direction: column;
87
+ flex-grow: 1;
88
+ gap: 6px;
89
+ justify-content: center;
90
+ }
91
+
92
+ .flag.text-space {
93
+ font-family: var(--b1-medium-font-family);
94
+ font-size: var(--b1-medium-font-size);
95
+ font-style: var(--b1-medium-font-style);
96
+ font-weight: var(--b1-medium-font-weight);
97
+ letter-spacing: var(--b1-medium-letter-spacing);
98
+ line-height: var(--b1-medium-line-height);
99
+ }
100
+
101
+ .flag.red.text-space {
102
+ color: #ed1515;
103
+ }
104
+
105
+ .flag.galliano.text-space {
106
+ color: rgba(170, 70, 19, 1);
107
+ }
108
+
109
+ .flag.green.text-space {
110
+ color: #289140;
111
+ }
112
+
113
+ .flag.disabled.text-space {
114
+ color: #b0b0b0;
115
+ }
116
+
117
+ .flag.black.text-space {
118
+ color: #4f4f4f;
119
+ }
120
+
121
+ .flag.black .flag-header {
122
+ color: #4f4f4f;
123
+ }
124
+
125
+ .flag.red .flag-header {
126
+ color: #ed1515;
127
+ }
128
+
129
+ .flag.galliano .flag-header {
130
+ color: rgba(170, 70, 19, 1);
131
+ }
132
+
133
+ .flag.disabled .flag-header {
134
+ color: #b0b0b0;
135
+ }
136
+
137
+ .flag.green .flag-header {
138
+ color: #289140;
139
+ }
140
+
141
+ .flag.black .i-will-auto-dismiss {
142
+ color: #4f4f4f;
143
+ }
144
+
145
+ .flag.red .i-will-auto-dismiss {
146
+ color: #4f4f4f;
147
+ }
148
+
149
+ .flag.galliano .i-will-auto-dismiss {
150
+ color: #4f4f4f;
151
+ }
152
+
153
+ .flag.disabled .i-will-auto-dismiss {
154
+ color: #b0b0b0;
155
+ }
156
+
157
+ .flag.green .i-will-auto-dismiss {
158
+ color: #4f4f4f;
159
+ }
@@ -0,0 +1,18 @@
1
+ import PropTypes from "prop-types";
2
+ import "./style.css";
3
+ interface Props {
4
+ text?: string;
5
+ status?: "hover" | "active" | "default";
6
+ version?: "with-file" | "default";
7
+ className?: any;
8
+ chipsButtonIcon?: React.JSX.Element;
9
+ }
10
+ export declare const MessageInput: {
11
+ ({ text, status, version, className, chipsButtonIcon, }: Props): React.JSX.Element;
12
+ propTypes: {
13
+ text: PropTypes.Requireable<string>;
14
+ status: PropTypes.Requireable<string>;
15
+ version: PropTypes.Requireable<string>;
16
+ };
17
+ };
18
+ export {};
@@ -0,0 +1,119 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import PropTypes from "prop-types";
3
+ import { useReducer, useRef, useState } from "react";
4
+ import { PrimaryButton } from "../PrimaryButton/PrimaryButton";
5
+ import { TertiaryButton } from "../TertiaryButton/TertiaryButton";
6
+ import { ChipsButton } from "../ChipsButton";
7
+ import { IconPaperclip, IconSend } from "@tabler/icons-react";
8
+ import "./style.css";
9
+ export const MessageInput = ({ text = "Buraya isteğinizi belirtin.", status, version, className, chipsButtonIcon, }) => {
10
+ const [state, dispatch] = useReducer(reducer, {
11
+ status: status || "default",
12
+ version: version || "default",
13
+ });
14
+ const [selectedFiles, setSelectedFiles] = useState([]);
15
+ const fileInputRef = useRef(null);
16
+ const [messageText, setMessageText] = useState("");
17
+ const shouldShowPrimary = selectedFiles.length > 0 || messageText.trim().length > 0;
18
+ return (_jsxs("div", { className: `message-input status-1-${state.status} version-${state.version} ${className}`, onMouseEnter: () => {
19
+ dispatch("mouse_enter");
20
+ }, onClick: () => {
21
+ dispatch("click_111");
22
+ }, onMouseLeave: () => {
23
+ dispatch("mouse_leave");
24
+ }, children: [selectedFiles.length > 0 && (_jsx("div", { className: "chips-container", children: selectedFiles.map((file, index) => (_jsx(ChipsButton, { className: "chips-button-instance", leftIcon: chipsButtonIcon, size: "medium", status: "default", text: file.name, withButton: true, onClick: () => {
25
+ setSelectedFiles((prev) => {
26
+ const next = prev.filter((_, i) => i !== index);
27
+ if (next.length === 0) {
28
+ dispatch("set_default");
29
+ }
30
+ return next;
31
+ });
32
+ } }, `${file.name}-${file.size}-${file.lastModified}-${index}`))) })), _jsxs("div", { className: "section", children: [_jsx(TertiaryButton, { className: "tertiary-button-instance", color: "black", leftIcon: _jsx(IconPaperclip, { size: 20, color: "#6D6D6D" }), onClick: () => {
33
+ fileInputRef.current?.click();
34
+ }, size: "large", status: "default" }), _jsx("input", { ref: fileInputRef, type: "file", multiple: true, style: { display: "none" }, onChange: (e) => {
35
+ const filesList = e.target.files ? Array.from(e.target.files) : [];
36
+ if (filesList.length > 0) {
37
+ setSelectedFiles((prev) => {
38
+ const prevKeys = new Set(prev.map((f) => `${f.name}-${f.size}-${f.lastModified}`));
39
+ const uniqueNew = filesList.filter((f) => !prevKeys.has(`${f.name}-${f.size}-${f.lastModified}`));
40
+ const next = [...prev, ...uniqueNew];
41
+ return next;
42
+ });
43
+ dispatch("set_with_file");
44
+ }
45
+ else {
46
+ dispatch("set_default");
47
+ }
48
+ if (e.target) {
49
+ e.target.value = "";
50
+ }
51
+ } }), _jsx("input", { type: "text", className: "buraya-iste-inizi", placeholder: text, value: messageText, onChange: (e) => {
52
+ const next = e.target.value;
53
+ setMessageText(next);
54
+ if (next.trim().length === 0 && selectedFiles.length === 0) {
55
+ dispatch("set_default");
56
+ }
57
+ else {
58
+ if (state.status !== "active") {
59
+ dispatch("click_111");
60
+ }
61
+ }
62
+ } }), shouldShowPrimary && (_jsx(PrimaryButton, { className: `${state.status === "active" || state.version === "with-file" ? "tertiary-button-instance" : "class-2"}`, color: "lime", leftIcon: _jsx(IconSend, { size: 20, color: "rgba(61, 61, 61, 1)" }), size: "medium", status: "default" }))] })] }));
63
+ };
64
+ function reducer(state, action) {
65
+ switch (action) {
66
+ case "mouse_enter":
67
+ if (state.version === "default" && state.status === "default") {
68
+ return {
69
+ status: "hover",
70
+ version: state.version,
71
+ };
72
+ }
73
+ return state;
74
+ case "mouse_leave":
75
+ if (state.version === "default" && state.status === "hover") {
76
+ return {
77
+ status: "default",
78
+ version: state.version,
79
+ };
80
+ }
81
+ return state;
82
+ case "click_111":
83
+ if (state.status !== "active") {
84
+ return {
85
+ status: "active",
86
+ version: state.version,
87
+ };
88
+ }
89
+ return state;
90
+ case "click":
91
+ if (state.version === "default") {
92
+ return {
93
+ status: "active",
94
+ version: "with-file",
95
+ };
96
+ }
97
+ return {
98
+ status: state.status,
99
+ version: "default",
100
+ };
101
+ case "set_with_file":
102
+ return {
103
+ status: "active",
104
+ version: "with-file",
105
+ };
106
+ case "set_default":
107
+ return {
108
+ status: "default",
109
+ version: "default",
110
+ };
111
+ default:
112
+ return state;
113
+ }
114
+ }
115
+ MessageInput.propTypes = {
116
+ text: PropTypes.string,
117
+ status: PropTypes.oneOf(["hover", "active", "default"]),
118
+ version: PropTypes.oneOf(["with-file", "default"]),
119
+ };
@@ -0,0 +1 @@
1
+ export { MessageInput } from "./MessageInput";
@@ -0,0 +1 @@
1
+ export { MessageInput } from "./MessageInput";
@@ -0,0 +1,102 @@
1
+ .message-input {
2
+ align-items: flex-start;
3
+ border: 1px solid;
4
+ border-radius: 12px;
5
+ box-shadow: var(--drop-shadow-low);
6
+ display: flex;
7
+ flex-direction: column;
8
+ justify-content: flex-end;
9
+ padding: 6px;
10
+ position: relative;
11
+ border: none;
12
+ }
13
+
14
+ .message-input .chips-button-instance {
15
+ align-self: flex-start !important;
16
+ }
17
+
18
+ .message-input .chips-container {
19
+ display: flex;
20
+ flex-wrap: wrap;
21
+ gap: 6px;
22
+ width: 100%;
23
+ }
24
+
25
+ .message-input .section {
26
+ align-items: center;
27
+ align-self: stretch;
28
+ display: flex;
29
+ flex: 0 0 auto;
30
+ gap: 4px;
31
+ position: relative;
32
+ width: 100%;
33
+ }
34
+
35
+ .message-input .tertiary-button-instance {
36
+ flex: 0 0 auto !important;
37
+ }
38
+
39
+ .message-input .buraya-iste-inizi {
40
+ -webkit-box-orient: vertical;
41
+ -webkit-line-clamp: 1;
42
+ line-clamp: 1;
43
+ align-items: center;
44
+ align-self: stretch;
45
+ display: -webkit-box;
46
+ flex: 1;
47
+ font-family: var(--h6-medium-font-family);
48
+ font-size: var(--h6-medium-font-size);
49
+ font-style: var(--h6-medium-font-style);
50
+ font-weight: var(--h6-medium-font-weight);
51
+ justify-content: center;
52
+ letter-spacing: var(--h6-medium-letter-spacing);
53
+ line-height: var(--h6-medium-line-height);
54
+ margin-top: -1.00px;
55
+ overflow: hidden;
56
+ position: relative;
57
+ text-overflow: ellipsis;
58
+ border: none;
59
+ background: transparent;
60
+ outline: none;
61
+ }
62
+
63
+ .message-input .icon-instance-node {
64
+ height: 20px !important;
65
+ position: relative !important;
66
+ width: 20px !important;
67
+ }
68
+
69
+ .message-input.status-1-default {
70
+ background-color: #f7f7f7;
71
+ border-color: #2424241a;
72
+ }
73
+
74
+ .message-input.status-1-active {
75
+ background-color: rgba(231, 231, 231, 1);
76
+ border-color: #2424244c;
77
+ }
78
+
79
+ .message-input.version-with-file {
80
+ gap: 6px;
81
+ }
82
+
83
+ .message-input.version-default {
84
+ gap: 4px;
85
+ }
86
+
87
+ .message-input.status-1-hover {
88
+ background-color: #f7f7f7;
89
+ border-color: #2424241a;
90
+ }
91
+
92
+ .message-input.status-1-default .buraya-iste-inizi {
93
+ color: #b0b0b0;
94
+ }
95
+
96
+ .message-input.status-1-active .buraya-iste-inizi {
97
+ color: #303030;
98
+ }
99
+
100
+ .message-input.status-1-hover .buraya-iste-inizi {
101
+ color: #888888;
102
+ }
@@ -0,0 +1,36 @@
1
+ import PropTypes from "prop-types";
2
+ import React from "react";
3
+ import "./style.css";
4
+ interface Props {
5
+ text?: string;
6
+ enter?: boolean;
7
+ richTextFormattingTools?: boolean;
8
+ property1?: "default";
9
+ className?: string;
10
+ placeholder?: string;
11
+ withPicture?: boolean;
12
+ withEmoji?: boolean;
13
+ withBold?: boolean;
14
+ withItalic?: boolean;
15
+ withUnderline?: boolean;
16
+ withStrikethrough?: boolean;
17
+ withHash?: boolean;
18
+ }
19
+ export declare const MessageInputField: {
20
+ ({ text, enter, richTextFormattingTools, className, placeholder, withPicture, withEmoji, withBold, withItalic, withUnderline, withStrikethrough, withHash, }: Props): React.JSX.Element;
21
+ propTypes: {
22
+ text: PropTypes.Requireable<string>;
23
+ enter: PropTypes.Requireable<boolean>;
24
+ richTextFormattingTools: PropTypes.Requireable<boolean>;
25
+ property1: PropTypes.Requireable<string>;
26
+ placeholder: PropTypes.Requireable<string>;
27
+ withPicture: PropTypes.Requireable<boolean>;
28
+ withEmoji: PropTypes.Requireable<boolean>;
29
+ withBold: PropTypes.Requireable<boolean>;
30
+ withItalic: PropTypes.Requireable<boolean>;
31
+ withUnderline: PropTypes.Requireable<boolean>;
32
+ withStrikethrough: PropTypes.Requireable<boolean>;
33
+ withHash: PropTypes.Requireable<boolean>;
34
+ };
35
+ };
36
+ export {};
@@ -0,0 +1,87 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import PropTypes from "prop-types";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import "./style.css";
5
+ import { IconArrowDown, IconBold, IconHash, IconItalic, IconMoodSmile, IconPhoto, IconStrikethrough, IconUnderline, } from "@tabler/icons-react";
6
+ import { PrimaryButton } from "../PrimaryButton/PrimaryButton";
7
+ export const MessageInputField = ({ text = "", enter = true, richTextFormattingTools = true, className, placeholder = "Mesaj yazın...", withPicture = true, withEmoji = true, withBold = true, withItalic = true, withUnderline = true, withStrikethrough = true, withHash = true, }) => {
8
+ const editorRef = useRef(null);
9
+ const fileInputRef = useRef(null);
10
+ const [showEmoji, setShowEmoji] = useState(false);
11
+ const emojiTriggerRef = useRef(null);
12
+ const emojiPanelRef = useRef(null);
13
+ const [isEmpty, setIsEmpty] = useState(true);
14
+ useEffect(() => {
15
+ if (editorRef.current) {
16
+ const hasInitial = (text ?? "").length > 0;
17
+ if (!editorRef.current.textContent && hasInitial) {
18
+ editorRef.current.textContent = text;
19
+ }
20
+ setIsEmpty(!editorRef.current.textContent || editorRef.current.textContent.trim().length === 0);
21
+ }
22
+ }, [text]);
23
+ useEffect(() => {
24
+ if (!showEmoji)
25
+ return;
26
+ const onDocClick = (e) => {
27
+ const t = e.target;
28
+ if (emojiTriggerRef.current &&
29
+ (emojiTriggerRef.current.contains(t) || (emojiPanelRef.current && emojiPanelRef.current.contains(t)))) {
30
+ return;
31
+ }
32
+ setShowEmoji(false);
33
+ };
34
+ document.addEventListener("mousedown", onDocClick);
35
+ return () => document.removeEventListener("mousedown", onDocClick);
36
+ }, [showEmoji]);
37
+ const focusEditor = () => {
38
+ editorRef.current?.focus();
39
+ };
40
+ const onIconMouseDown = (e) => {
41
+ e.preventDefault();
42
+ };
43
+ const exec = (command, value) => {
44
+ focusEditor();
45
+ document.execCommand(command, false, value);
46
+ // update empty state after command
47
+ if (editorRef.current) {
48
+ setIsEmpty(!editorRef.current.textContent || editorRef.current.textContent.trim().length === 0);
49
+ }
50
+ };
51
+ const handleInsertImage = (file) => {
52
+ const url = URL.createObjectURL(file);
53
+ exec("insertImage", url);
54
+ };
55
+ const EMOJIS = [
56
+ "😀", "😁", "😂", "🤣", "😊", "😍", "🤔", "😎", "😅", "🙃",
57
+ "👍", "🙏", "🎉", "🔥", "💡", "✅", "❌", "⚠️", "🚀", "❤️"
58
+ ];
59
+ return (_jsxs("div", { className: `message-input-field ${className ?? ""}`, children: [_jsxs("div", { className: "frame", children: [_jsx("div", { ref: editorRef, className: `m-teri-sat-raporlar ${isEmpty ? "is-empty" : ""}`, contentEditable: true, suppressContentEditableWarning: true, tabIndex: 0, "data-placeholder": placeholder, onInput: () => {
60
+ if (editorRef.current) {
61
+ setIsEmpty(!editorRef.current.textContent || editorRef.current.textContent.trim().length === 0);
62
+ }
63
+ } }), enter && (_jsx("div", { className: "primary-button-wrapper", children: _jsx(PrimaryButton, { className: "primary-button-instance", color: "black", leftIcon: _jsx(IconArrowDown, { className: "icon-instance-node" }), size: "large", status: "default" }) }))] }), richTextFormattingTools && (_jsx("div", { className: "content", children: _jsxs("div", { className: "primary-feature", children: [_jsxs("div", { className: "text-feature", children: [withBold && _jsx(IconBold, { className: "icon-instance-node toolbar-icon", color: "#3D3D3D", size: 20, strokeWidth: 1.5, onMouseDown: onIconMouseDown, onClick: () => exec("bold") }), withItalic && _jsx(IconItalic, { className: "icon-instance-node toolbar-icon", size: 20, strokeWidth: 1.5, color: "#3D3D3D", onMouseDown: onIconMouseDown, onClick: () => exec("italic") }), withUnderline && _jsx(IconUnderline, { className: "icon-instance-node toolbar-icon", size: 20, strokeWidth: 1.5, color: "#3D3D3D", onMouseDown: onIconMouseDown, onClick: () => exec("underline") }), withStrikethrough && _jsx(IconStrikethrough, { className: "icon-instance-node toolbar-icon", size: 20, strokeWidth: 1.5, color: "#3D3D3D", onMouseDown: onIconMouseDown, onClick: () => exec("strikeThrough") })] }), _jsx("div", { className: "divide-vertical" }), _jsxs("div", { className: "text-feature", children: [withHash && _jsx(IconHash, { className: "icon-instance-node toolbar-icon", strokeWidth: 1.5, size: 20, color: "#3D3D3D", onMouseDown: onIconMouseDown, onClick: () => exec("insertText", "#") }), _jsxs("div", { className: "text-feature", children: [withPicture && _jsx(IconPhoto, { className: "icon-instance-node toolbar-icon", size: 20, strokeWidth: 1.5, color: "#3D3D3D", onMouseDown: onIconMouseDown, onClick: () => fileInputRef.current?.click() }), _jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", className: "hidden-file-input", onChange: (e) => {
64
+ const file = e.target.files?.[0];
65
+ if (file)
66
+ handleInsertImage(file);
67
+ if (fileInputRef.current)
68
+ fileInputRef.current.value = "";
69
+ } })] }), _jsxs("div", { ref: emojiTriggerRef, className: "emoji-trigger", children: [withEmoji && _jsx(IconMoodSmile, { className: "icon-instance-node toolbar-icon", size: 20, strokeWidth: 1.5, color: "#3D3D3D", onMouseDown: onIconMouseDown, onClick: () => setShowEmoji((s) => !s) }), withEmoji && showEmoji && (_jsx("div", { ref: emojiPanelRef, className: "emoji-panel", children: _jsx("div", { className: "emoji-grid", children: EMOJIS.map((e) => (_jsx("button", { type: "button", onMouseDown: (evt) => evt.preventDefault(), onClick: () => {
70
+ exec("insertText", e);
71
+ setShowEmoji(false);
72
+ }, className: "emoji-btn", children: e }, e))) }) }))] })] })] }) }))] }));
73
+ };
74
+ MessageInputField.propTypes = {
75
+ text: PropTypes.string,
76
+ enter: PropTypes.bool,
77
+ richTextFormattingTools: PropTypes.bool,
78
+ property1: PropTypes.oneOf(["default"]),
79
+ placeholder: PropTypes.string,
80
+ withPicture: PropTypes.bool,
81
+ withEmoji: PropTypes.bool,
82
+ withBold: PropTypes.bool,
83
+ withItalic: PropTypes.bool,
84
+ withUnderline: PropTypes.bool,
85
+ withStrikethrough: PropTypes.bool,
86
+ withHash: PropTypes.bool,
87
+ };
@@ -0,0 +1 @@
1
+ export { MessageInputField } from "./MessageInputField";
@@ -0,0 +1 @@
1
+ export { MessageInputField } from "./MessageInputField";
@@ -0,0 +1,178 @@
1
+ .message-input-field {
2
+ align-items: flex-start;
3
+ background-color: #2424240d;
4
+ border: 1px solid;
5
+ border-color: #2424241a;
6
+ border-radius: 12px;
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: 12px;
10
+ padding: 12px;
11
+ position: relative;
12
+ }
13
+
14
+ .message-input-field .frame {
15
+ align-items: flex-start;
16
+ align-self: stretch;
17
+ display: flex;
18
+ flex: 0 0 auto;
19
+ gap: 12px;
20
+ position: relative;
21
+ width: 100%;
22
+ }
23
+
24
+ .message-input-field .m-teri-sat-raporlar {
25
+ flex: 1;
26
+ font-family: var(--b1-medium-font-family);
27
+ font-size: var(--b1-medium-font-size);
28
+ font-style: var(--b1-medium-font-style);
29
+ font-weight: var(--b1-medium-font-weight);
30
+ letter-spacing: var(--b1-medium-letter-spacing);
31
+ line-height: var(--b1-medium-line-height);
32
+ background: transparent;
33
+ border: none;
34
+ outline: none;
35
+ padding: 0;
36
+ margin: 0;
37
+ min-height: 80px;
38
+ max-height: 80px;
39
+ overflow-y: auto;
40
+ white-space: pre-wrap;
41
+ word-break: break-word;
42
+ }
43
+
44
+ .message-input-field .m-teri-sat-raporlar.is-empty:before {
45
+ content: attr(data-placeholder);
46
+ color: rgba(176, 176, 176, 1);
47
+ pointer-events: none;
48
+ }
49
+
50
+ /* Hidden file input */
51
+ .message-input-field .hidden-file-input {
52
+ display: none;
53
+ }
54
+
55
+ .message-input-field .primary-button-wrapper {
56
+ align-items: flex-end;
57
+ align-self: stretch;
58
+ border-radius: 20px;
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: 10px;
62
+ justify-content: center;
63
+ position: relative;
64
+ width: 40px;
65
+ }
66
+
67
+ .message-input-field .primary-button-instance {
68
+ aspect-ratio: 1 !important;
69
+ border: 1px solid !important;
70
+ border-color: #3d3d3d !important;
71
+ border-radius: 24px !important;
72
+ display: flex !important;
73
+ height: 40px !important;
74
+ padding: 12px 6px !important;
75
+ width: 40px !important;
76
+ }
77
+
78
+ .message-input-field .content {
79
+ align-items: flex-start;
80
+ align-self: stretch;
81
+ border: 1px solid;
82
+ border-color: #d1d1d1;
83
+ border-radius: 8px;
84
+ display: flex;
85
+ flex: 0 0 auto;
86
+ gap: 12px;
87
+ margin-bottom: -1.00px;
88
+ margin-left: -1.00px;
89
+ margin-right: -1.00px;
90
+ position: relative;
91
+ width: 100%;
92
+ }
93
+
94
+ .message-input-field .primary-feature {
95
+ align-items: center;
96
+ display: inline-flex;
97
+ flex: 0 0 auto;
98
+ gap: 12px;
99
+ padding: 6px 8px;
100
+ position: relative;
101
+ }
102
+
103
+ .message-input-field .text-feature {
104
+ align-items: center;
105
+ display: inline-flex;
106
+ flex: 0 0 auto;
107
+ gap: 4px;
108
+ position: relative;
109
+ }
110
+
111
+ .message-input-field .icon-instance-node {
112
+ height: 20px !important;
113
+ position: relative !important;
114
+ width: 20px !important;
115
+ }
116
+
117
+ .message-input-field .divider {
118
+ align-self: stretch;
119
+ position: relative;
120
+ width: 1px;
121
+ }
122
+
123
+ .message-input-field .line-icons-arrow-down-filled-icons-default {
124
+ height: 20px !important;
125
+ margin-bottom: -2.00px !important;
126
+ margin-top: -2.00px !important;
127
+ position: relative !important;
128
+ width: 20px !important;
129
+ }
130
+
131
+ /* Toolbar clickable icons */
132
+ .message-input-field .toolbar-icon {
133
+ cursor: pointer;
134
+ }
135
+
136
+ /* Emoji trigger wrapper */
137
+ .message-input-field .emoji-trigger {
138
+ position: relative;
139
+ display: inline-block;
140
+ height: 20px;
141
+ }
142
+
143
+ /* Emoji panel overlay */
144
+ .message-input-field .emoji-panel {
145
+ position: absolute;
146
+ top: 28px;
147
+ right: 0;
148
+ background: #fff;
149
+ border: 1px solid #e5e7eb;
150
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
151
+ border-radius: 8px;
152
+ padding: 8px;
153
+ width: 195px;
154
+ z-index: 1000;
155
+ overflow-y: scroll;
156
+ }
157
+
158
+ /* Emoji grid */
159
+ .message-input-field .emoji-grid {
160
+ display: grid;
161
+ grid-template-columns: repeat(6, 1fr);
162
+ gap: 6px;
163
+ max-height: 180px;
164
+ overflow-y: auto;
165
+ }
166
+
167
+ /* Emoji button */
168
+ .message-input-field .emoji-btn {
169
+ font-size: 18px;
170
+ line-height: 24px;
171
+ width: 24px;
172
+ height: 24px;
173
+ padding: 0;
174
+ background: transparent;
175
+ border: none;
176
+ cursor: pointer;
177
+ }
178
+
@@ -0,0 +1,12 @@
1
+ import "./style.css";
2
+ type TimeSelectorProps = {
3
+ value?: string;
4
+ onChange: (value: string) => void;
5
+ onClose?: () => void;
6
+ hourMin?: number;
7
+ hourMax?: number;
8
+ wrapHours?: boolean;
9
+ adjustHourOnMinuteWrap?: boolean;
10
+ };
11
+ export declare function TimeSelector({ value, onChange, onClose, hourMin, hourMax, wrapHours, adjustHourOnMinuteWrap }: TimeSelectorProps): React.JSX.Element;
12
+ export {};
@@ -0,0 +1,106 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef, useState } from "react";
3
+ import { Label } from "../Label/Label";
4
+ import { TertiaryButton } from "../TertiaryButton/TertiaryButton";
5
+ import { IconChevronDown, IconChevronUp } from "@tabler/icons-react";
6
+ import "./style.css";
7
+ function clampToRange(value, min, max) {
8
+ if (value < min)
9
+ return min;
10
+ if (value > max)
11
+ return max;
12
+ return value;
13
+ }
14
+ function format2(n) {
15
+ return n.toString().padStart(2, "0");
16
+ }
17
+ export function TimeSelector({ value = "00:00", onChange, onClose, hourMin = 0, hourMax = 23, wrapHours = true, adjustHourOnMinuteWrap = false }) {
18
+ const initial = useMemo(() => {
19
+ const [h, m] = value.split(":").map((v) => parseInt(v || "0", 10));
20
+ const minutes = m === 30 ? 30 : 0; // restrict to 00 or 30
21
+ const safeHour = isNaN(h) ? hourMin : clampToRange(h, hourMin, hourMax);
22
+ return { hour: safeHour, minutes };
23
+ }, [value, hourMin, hourMax]);
24
+ const [hour, setHour] = useState(initial.hour);
25
+ const [minutes, setMinutes] = useState(initial.minutes);
26
+ const containerRef = useRef(null);
27
+ useEffect(() => {
28
+ const onKey = (e) => {
29
+ if (e.key === "Escape")
30
+ onClose?.();
31
+ };
32
+ document.addEventListener("keydown", onKey);
33
+ return () => document.removeEventListener("keydown", onKey);
34
+ }, [onClose]);
35
+ useEffect(() => {
36
+ const handleClickOutside = (event) => {
37
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
38
+ onClose?.();
39
+ }
40
+ };
41
+ document.addEventListener("mousedown", handleClickOutside);
42
+ return () => document.removeEventListener("mousedown", handleClickOutside);
43
+ }, [onClose]);
44
+ const applyChange = (h, m) => {
45
+ onChange(`${format2(h)}:${format2(m)}`);
46
+ };
47
+ const incHour = () => {
48
+ let next = hour + 1;
49
+ if (next > hourMax) {
50
+ next = wrapHours ? hourMin : hourMax;
51
+ }
52
+ setHour(next);
53
+ applyChange(next, minutes);
54
+ };
55
+ const decHour = () => {
56
+ let next = hour - 1;
57
+ if (next < hourMin) {
58
+ next = wrapHours ? hourMax : hourMin;
59
+ }
60
+ setHour(next);
61
+ applyChange(next, minutes);
62
+ };
63
+ const incMinutes = () => {
64
+ // 00 -> 30, 30 -> 00 (+inc hour if configured)
65
+ if (minutes === 0) {
66
+ setMinutes(30);
67
+ applyChange(hour, 30);
68
+ }
69
+ else {
70
+ setMinutes(0);
71
+ if (adjustHourOnMinuteWrap) {
72
+ // increment hour respecting bounds/wrap
73
+ let nextHour = hour + 1;
74
+ if (nextHour > hourMax)
75
+ nextHour = wrapHours ? hourMin : hourMax;
76
+ setHour(nextHour);
77
+ applyChange(nextHour, 0);
78
+ }
79
+ else {
80
+ applyChange(hour, 0);
81
+ }
82
+ }
83
+ };
84
+ const decMinutes = () => {
85
+ // 30 -> 00, 00 -> 30 (-dec hour if configured)
86
+ if (minutes === 30) {
87
+ setMinutes(0);
88
+ applyChange(hour, 0);
89
+ }
90
+ else {
91
+ setMinutes(30);
92
+ if (adjustHourOnMinuteWrap) {
93
+ // decrement hour respecting bounds/wrap
94
+ let nextHour = hour - 1;
95
+ if (nextHour < hourMin)
96
+ nextHour = wrapHours ? hourMax : hourMin;
97
+ setHour(nextHour);
98
+ applyChange(nextHour, 30);
99
+ }
100
+ else {
101
+ applyChange(hour, 30);
102
+ }
103
+ }
104
+ };
105
+ return (_jsxs("div", { className: `time-selector`, ref: containerRef, children: [_jsxs("div", { className: "frame", children: [_jsx(TertiaryButton, { className: "tertiary-button-instance", color: "black", leftIcon: _jsx(IconChevronUp, { className: "icons-instance", color: "#6D6D6D" }), size: "x-small", status: "default", onClick: incHour }), _jsx(Label, { bold: "on", className: "label-instance", color: "black", size: "medium", spacing: "off", stroke: "off", text: format2(hour), version: "primary" }), _jsx(TertiaryButton, { className: "tertiary-button-instance", color: "black", leftIcon: _jsx(IconChevronDown, { className: "icons-instance", color: "#6D6D6D" }), size: "x-small", status: "default", onClick: decHour })] }), _jsx(Label, { bold: "on", className: "design-component-instance-node", color: "black", divClassName: "label-2", size: "medium", spacing: "off", stroke: "off", text: ":", version: "primary" }), _jsxs("div", { className: "frame", children: [_jsx(TertiaryButton, { className: "tertiary-button-instance", color: "black", leftIcon: _jsx(IconChevronUp, { className: "icons-instance", color: "#6D6D6D" }), size: "x-small", status: "default", onClick: incMinutes }), _jsx(Label, { bold: "on", className: "label-instance", color: "black", size: "medium", spacing: "off", stroke: "off", text: format2(minutes), version: "primary" }), _jsx(TertiaryButton, { className: "tertiary-button-instance", color: "black", leftIcon: _jsx(IconChevronDown, { className: "icons-instance", color: "#6D6D6D" }), size: "x-small", status: "default", onClick: decMinutes })] })] }));
106
+ }
@@ -0,0 +1 @@
1
+ export { TimeSelector } from "./TimeSelector";
@@ -0,0 +1 @@
1
+ export { TimeSelector } from "./TimeSelector";
@@ -0,0 +1,55 @@
1
+ .time-selector {
2
+ align-items: center;
3
+ background-color: #ffffff;
4
+ border-radius: 8px;
5
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
6
+ display: inline-flex;
7
+ gap: 8px;
8
+ padding: 4px 12px;
9
+ width: 100%;
10
+ justify-content: center;
11
+ }
12
+
13
+ .time-selector .frame {
14
+ align-items: flex-start;
15
+ display: flex;
16
+ flex-direction: column;
17
+ position: relative;
18
+ }
19
+
20
+ .time-selector .tertiary-button-instance {
21
+ align-self: stretch !important;
22
+ display: flex !important;
23
+ height: 24px !important;
24
+ left: unset !important;
25
+ top: unset !important;
26
+ width: 100% !important;
27
+ }
28
+
29
+ .time-selector .label-instance {
30
+ align-self: stretch !important;
31
+ display: flex !important;
32
+ flex: 0 0 auto !important;
33
+ left: unset !important;
34
+ top: unset !important;
35
+ width: 100% !important;
36
+ justify-content: center !important;
37
+ }
38
+
39
+ .time-selector .design-component-instance-node {
40
+ flex: 0 0 auto !important;
41
+ left: unset !important;
42
+ top: unset !important;
43
+ }
44
+
45
+ .time-selector .label-2 {
46
+ text-align: center !important;
47
+ }
48
+
49
+ .time-selector .icons-instance {
50
+ height: 12px !important;
51
+ position: relative !important;
52
+ width: 12px !important;
53
+ }
54
+
55
+
package/dist/index.d.ts CHANGED
@@ -30,3 +30,5 @@ export { Strikethrough } from "./Strikethrough/Strikethrough";
30
30
  export { Switch } from "./Switch/Switch";
31
31
  export { SwitchButton } from "./SwitchButton/SwitchButton";
32
32
  export { TabButton } from "./TabButton/TabButton";
33
+ export { ChipsButton } from "./ChipsButton/ChipsButton";
34
+ export { MessageInput } from "./MessageInput/MessageInput";
package/dist/index.js CHANGED
@@ -30,3 +30,5 @@ export { Strikethrough } from "./Strikethrough/Strikethrough";
30
30
  export { Switch } from "./Switch/Switch";
31
31
  export { SwitchButton } from "./SwitchButton/SwitchButton";
32
32
  export { TabButton } from "./TabButton/TabButton";
33
+ export { ChipsButton } from "./ChipsButton/ChipsButton";
34
+ export { MessageInput } from "./MessageInput/MessageInput";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ayseaistudio/ui-components",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",