oneslash-design-system 1.0.3

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,107 @@
1
+ 'use client';
2
+ import React, { useState } from 'react';
3
+
4
+ export default function TextField({
5
+ id,
6
+ label,
7
+ value,
8
+ onChange,
9
+ iconLeft,
10
+ iconRight,
11
+ multiline = false,
12
+ maxRows = 6,
13
+ disabled = false,
14
+ error = false,
15
+ }: TextFieldProps) {
16
+
17
+ const [isFocused, setIsFocused] = useState(false);
18
+
19
+ // Base styles
20
+ const baseClasses = 'w-full border rounded-[8px] p-2';
21
+
22
+ // Background color
23
+ const bgColor = 'bg-light-background-default dark:bg-dark-background-default transition-colors duration-300 ease-in-out';
24
+
25
+ // Border color
26
+ const borderColor = 'border-light-outlinedBorder-active dark:border-dark-outlinedBorder-active';
27
+
28
+ // State styles
29
+ const disabledClasses = 'bg-gray-200 cursor-not-allowed';
30
+ const errorClasses = 'border-red-500 focus:ring-red-500';
31
+ const focusClasses = 'focus:border-light-accent-main focus:dark:border-dark-accent-main outline-none';
32
+ const hoverClasses = 'hover:border-light-outlinedBorder-hover';
33
+ const defaultClasses = 'border-gray-300';
34
+
35
+ // Container styles
36
+ const containerClasses = `
37
+ ${bgColor}
38
+ ${borderColor}
39
+ ${baseClasses}
40
+ ${disabled ? disabledClasses : ''}
41
+ ${error ? errorClasses : ''}
42
+ ${isFocused ? focusClasses : ''}
43
+ ${!disabled && !error ? hoverClasses : ''}
44
+ ${defaultClasses}
45
+ `;
46
+
47
+ // Render iconRight in TextField
48
+ const renderIconRight = () => {
49
+ if (React.isValidElement(iconRight)) {
50
+ return iconRight;
51
+ }
52
+ if (typeof iconRight === 'function') {
53
+ return React.createElement(iconRight);
54
+ }
55
+ return null;
56
+ };
57
+
58
+ return (
59
+ <div className="flex flex-col w-full">
60
+ {label && (
61
+ <label htmlFor={id} className="mb-1 text-body2 text-light-text-secondary dark:text-dark-text-secondary">
62
+ {label}
63
+ </label>
64
+ )}
65
+ <div className="relative">
66
+ {iconLeft && (
67
+ <span className="absolute inset-y-0 left-0 pl-3 flex items-center">
68
+ {iconLeft}
69
+ </span>
70
+ )}
71
+ {iconRight && (
72
+ <span className="absolute inset-y-0 right-0 pr-3 flex items-center">
73
+ {renderIconRight()}
74
+ </span>
75
+ )}
76
+ {multiline ? (
77
+ <textarea
78
+ id={id}
79
+ rows={maxRows}
80
+ className={containerClasses}
81
+ value={value}
82
+ onChange={onChange}
83
+ onFocus={() => setIsFocused(true)}
84
+ onBlur={() => setIsFocused(false)}
85
+ disabled={disabled}
86
+ />
87
+ ) : (
88
+ <input
89
+ id={id}
90
+ type="text"
91
+ className={containerClasses}
92
+ value={value}
93
+ onChange={onChange}
94
+ onFocus={() => setIsFocused(true)}
95
+ onBlur={() => setIsFocused(false)}
96
+ disabled={disabled}
97
+ />
98
+ )}
99
+ </div>
100
+ {error && (
101
+ <p className="mt-1 text-light-error-main text-body2">
102
+ This field is required
103
+ </p>
104
+ )}
105
+ </div>
106
+ );
107
+ }
@@ -0,0 +1,61 @@
1
+ 'use client';
2
+ import React, { useState, useRef, useEffect } from 'react';
3
+
4
+ export default function Tooltip({ title, children }: TooltipProps) {
5
+ const [visible, setVisible] = useState(false);
6
+ const [position, setPosition] = useState<'top' | 'bottom'>('bottom');
7
+ const tooltipRef = useRef<HTMLDivElement>(null);
8
+ const buttonRef = useRef<HTMLDivElement>(null);
9
+
10
+ useEffect(() => {
11
+ const handlePosition = () => {
12
+ if (tooltipRef.current && buttonRef.current) {
13
+ const tooltipRect = tooltipRef.current.getBoundingClientRect();
14
+ const buttonRect = buttonRef.current.getBoundingClientRect();
15
+ // Check if there's enough space below; if not, place tooltip above
16
+ if (window.innerHeight - buttonRect.bottom < tooltipRect.height + 8) {
17
+ setPosition('top');
18
+ } else {
19
+ setPosition('bottom');
20
+ }
21
+ }
22
+ };
23
+ if (visible) {
24
+ handlePosition();
25
+ }
26
+ }, [visible]);
27
+
28
+ const handleClick = () => {
29
+ setVisible(false); // Hide tooltip on click
30
+ };
31
+
32
+ return (
33
+ <div
34
+ ref={buttonRef}
35
+ onMouseEnter={() => setVisible(true)}
36
+ onMouseLeave={() => setVisible(false)}
37
+ onClick={handleClick}
38
+ className="relative inline-block"
39
+ >
40
+ {children}
41
+ {visible && (
42
+ <div
43
+ ref={tooltipRef}
44
+ className={`absolute whitespace-nowrap text-caption rounded-[8px] py-1 px-2 z-50
45
+ dark:bg-light-background-accent300 bg-dark-background-accent300
46
+ dark:text-light-text-primary text-dark-text-primary
47
+ ${position === 'bottom' ? 'mt-1' : 'mb-1'}`}
48
+ style={{
49
+ bottom: position === 'top' ? '100%' : undefined,
50
+ top: position === 'bottom' ? '100%' : undefined,
51
+ left: '50%',
52
+ transform: 'translateX(-50%)',
53
+ }}
54
+ >
55
+ {title}
56
+ </div>
57
+ )
58
+ }
59
+ </div>
60
+ );
61
+ }
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+
3
+ export default function UserImage({
4
+ userHandle,
5
+ userImgUrl,
6
+ }: UserImageProps) {
7
+
8
+ const defaultInitial = userHandle.charAt(0).toUpperCase();
9
+
10
+ return (
11
+ <div
12
+ className="flex items-center justify-center w-6 h-6 rounded-full overflow-hidden
13
+ bg-light-background-accent200 dark:bg-dark-background-accent200
14
+ text-light-text-secondary dark:text-dark-text-secondary ">
15
+ {userImgUrl ? (
16
+ <img
17
+ src={userImgUrl}
18
+ alt={userHandle}
19
+ className="w-full h-full object-cover rounded-full"
20
+ />
21
+ ) : (
22
+ <span className="text-body1">
23
+ {defaultInitial}
24
+ </span>
25
+ )}
26
+ </div>
27
+ );
28
+ }
@@ -0,0 +1,234 @@
1
+ // design tokens definitions
2
+ module.exports = {
3
+ colors: {
4
+ // light
5
+ light:{
6
+ text:{
7
+ primary: '#000000',
8
+ secondary: '#6D6D6D',
9
+ disabled: '#9E9E9E',
10
+ contrast: '#ffffff',
11
+ },
12
+ accent:{
13
+ main: '#EEAE03',
14
+ dark: '#CE8602',
15
+ light: '#FFDD43',
16
+ contrast: '#000000',
17
+ },
18
+ primary:{
19
+ main: '#454545',
20
+ dark: '#262626',
21
+ light: '#888888',
22
+ },
23
+ secondary:{
24
+ main: '#B0B0B0',
25
+ dark: '#888888',
26
+ light: '#D1D1D1',
27
+ },
28
+ error:{
29
+ main: '#D32F2F',
30
+ dark: '#B22323',
31
+ light: '#F27777',
32
+ },
33
+ warning:{
34
+ main: '#EF6C00',
35
+ dark: '#CC5302',
36
+ light: '#FFA732',
37
+ },
38
+ info:{
39
+ main: '#0087D4',
40
+ dark: '#006BAB',
41
+ light: '#2CC1FF',
42
+ },
43
+ success:{
44
+ main: '#328736',
45
+ dark: '#2A6B2D',
46
+ light: '#67C16B',
47
+ },
48
+ background:{
49
+ default: '#FFFFFF',
50
+ accent100:'#F6F6F6',
51
+ accent200:'#E7E7E7',
52
+ accent300:'#D1D1D1',
53
+ },
54
+ action:{
55
+ active: '#888888',
56
+ hover: '#F3F3F3',
57
+ selected: '#E3E3E3',
58
+ disabledBackground: '#D1D1D1',
59
+ disabled: '#B0B0B0',
60
+ },
61
+ actionBackground:{
62
+ enabled: '#FFFFFF',
63
+ hovered: '#FFFFFF',
64
+ selected: '#FFFFFF',
65
+ disabled: '#EEEEEE',
66
+ },
67
+ actionOutlinedBorder:{
68
+ enabled: '#888888',
69
+ hovered: '#CDCDCD',
70
+ selected: '#E8E8E8',
71
+ disabled: '#B0B0B0',
72
+ },
73
+ misc:{
74
+ divider: '#D1D1D1',
75
+ },
76
+ },
77
+
78
+ // dark
79
+ dark:{
80
+ text:{
81
+ primary: '#FFFFFF',
82
+ secondary: '#B0B0B0',
83
+ disabled: '#6D6D6D',
84
+ contrast: '#000000',
85
+ },
86
+ accent:{
87
+ main: '#FFCD29',
88
+ dark: '#CE8602',
89
+ light: '#FFDD43',
90
+ contrast: '#000000',
91
+ },
92
+ primary:{
93
+ main: '#D5D5D5',
94
+ dark: '#E9E9E9',
95
+ light: '#9A9A9A',
96
+ },
97
+ secondary:{
98
+ main: '#4F4F4F',
99
+ dark: '#454545',
100
+ light: '#6D6D6D',
101
+ },
102
+ error:{
103
+ main: '#E74C4C',
104
+ dark: '#B22323',
105
+ light: '#F27777',
106
+ },
107
+ warning:{
108
+ main: '#FF8C0A',
109
+ dark: '#CC5302',
110
+ light: '#FFA732',
111
+ },
112
+ info:{
113
+ main: '#00AFFF',
114
+ dark: '#006BAB',
115
+ light: '#2CC1FF',
116
+ },
117
+ success:{
118
+ main: '#42A547',
119
+ dark: '#2A6B2D',
120
+ light: '#67C16B',
121
+ },
122
+ background:{
123
+ default: '#262626',
124
+ accent100:'#333333',
125
+ accent200:'#454545',
126
+ accent300:'#4F4F4F',
127
+ },
128
+ action:{
129
+ active: '#171717',
130
+ hover: '#3D3D3D',
131
+ selected: '#4E4E4E',
132
+ disabledBackground: '#3C3C3C',
133
+ disabled: '#383838',
134
+ },
135
+ actionBackground:{
136
+ enabled: '#FFFFFF',
137
+ hovered: '#FFFFFF',
138
+ selected: '#FFFFFF',
139
+ disabled: '#383838',
140
+ },
141
+ actionOutlinedBorder:{
142
+ enabled: '#7B7B7B',
143
+ hovered: '#2F2F2F',
144
+ selected: '#404040',
145
+ disabled: '#383838',
146
+ },
147
+ misc:{
148
+ divider: '#404040',
149
+ },
150
+ },
151
+ },
152
+
153
+ spacing: {
154
+ small: '4px',
155
+ medium: '8px',
156
+ large: '16px',
157
+ },
158
+
159
+ typography: {
160
+ family: 'Inter, sans-serif',
161
+ h1: {
162
+ weight: '300',
163
+ size: '96px',
164
+ lineHeight: '120%',
165
+ letterSpacing: '-1.5px',
166
+ },
167
+ h2: {
168
+ weight: '300',
169
+ size: '60px',
170
+ lineHeight: '120%',
171
+ letterSpacing: '-0.5px',
172
+ },
173
+ h3: {
174
+ weight: '400',
175
+ size: '48px',
176
+ lineHeight: '120%',
177
+ letterSpacing: '0px',
178
+ },
179
+ h4: {
180
+ weight: '400',
181
+ size: '34px',
182
+ lineHeight: '120%',
183
+ letterSpacing: '0.3px',
184
+ },
185
+ h5: {
186
+ weight: '400',
187
+ size: '24px',
188
+ lineHeight: '120%',
189
+ letterSpacing: '0px',
190
+ },
191
+ h6: {
192
+ weight: '500',
193
+ size: '20px',
194
+ lineHeight: '150%',
195
+ letterSpacing: '0.2px',
196
+ },
197
+ subtitle1: {
198
+ weight: '500',
199
+ size: '16px',
200
+ lineHeight: '150%',
201
+ letterSpacing: '0.2px',
202
+ },
203
+ subtitle2: {
204
+ weight: '500',
205
+ size: '14px',
206
+ lineHeight: '150%',
207
+ letterSpacing: '0.1px',
208
+ },
209
+ body1: {
210
+ weight: '400',
211
+ size: '16px',
212
+ lineHeight: '150%',
213
+ letterSpacing: '0.2px',
214
+ },
215
+ body2: {
216
+ weight: '400',
217
+ size: '14px',
218
+ lineHeight: '150%',
219
+ letterSpacing: '0.2px',
220
+ },
221
+ caption: {
222
+ weight: '400',
223
+ size: '12px',
224
+ lineHeight: '150%',
225
+ letterSpacing: '1.2px',
226
+ },
227
+ alignments: {
228
+ left: 'left',
229
+ center: 'center',
230
+ right: 'right',
231
+ justify: 'justify',
232
+ },
233
+ },
234
+ };