teachable-design-system 0.1.16 → 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.
package/dist/index.esm.js CHANGED
@@ -4,6 +4,7 @@ import { css } from '@emotion/react';
4
4
  import React, { useState } from 'react';
5
5
  import element from './assets/icons/checked.png';
6
6
  import arrowDownIcon from './assets/icons/arrow-down.png';
7
+ import { Eye, EyeOff } from 'lucide-react';
7
8
  import icon from './assets/icons/icon_size.png';
8
9
 
9
10
  const colors = {
@@ -1074,87 +1075,117 @@ function Dropdown({ size, options, onSelect, label, placeholder }) {
1074
1075
  return (jsxs("div", { style: { position: 'relative' }, children: [jsx(StyledLabel, { children: label }), jsx(StyledDropDown, { onClick: () => setOpen((prev) => !prev), size: size, isOpen: open, children: jsxs(StyledBox, { children: [jsx(StyledText, { size: size, isOpen: open, children: selected ?? placeholder }), jsx(StyledIcon$1, { size: size, children: jsx("img", { src: arrowDownIcon, alt: "dropdown icon", style: { width: '100%', height: '100%' } }) })] }) }), open && (jsx(StyledOptions, { ref: ref, size: size, children: options?.map((option) => (jsx(StyledOption, { onClick: () => handleSelect(option), size: size, isSelected: option === selected, children: option }, option))) }))] }));
1075
1076
  }
1076
1077
 
1077
- const getInputWrapperStyle = (size) => {
1078
- let height = '48px';
1078
+ const getInputSizeStyle = (size) => {
1079
1079
  switch (size) {
1080
- case 'small':
1081
- height = '41px';
1082
- break;
1083
- case 'medium':
1084
- height = '48px';
1085
- break;
1086
- case 'large':
1087
- height = '56px';
1088
- break;
1089
- }
1090
- return {
1091
- display: 'flex',
1092
- flexDirection: 'column',
1093
- gap: '8px',
1094
- width: '306px',
1095
- height: height,
1096
- };
1097
- };
1098
- const labelStyle = {
1099
- display: 'flex',
1100
- justifyContent: 'flex-start',
1101
- ...typography.label.small,
1102
- color: '#333',
1103
- };
1104
- const getInputStyle = (inputSize, disabled, isFocused) => {
1105
- let padding = '0px 16px';
1106
- let fontSize = typography.label.medium.fontSize;
1107
- let lineHeight = typography.label.medium.lineHeight;
1108
- let fontWeight = typography.label.medium.fontWeight;
1109
- let height = '48px';
1110
- let width = '306px';
1111
- switch (inputSize) {
1112
- case 'small':
1113
- fontSize = typography.label.small.fontSize;
1114
- lineHeight = typography.label.small.lineHeight;
1115
- fontWeight = typography.label.small.fontWeight;
1116
- height = '40px';
1117
- break;
1118
- case 'medium':
1119
- fontSize = typography.label.medium.fontSize;
1120
- lineHeight = typography.label.medium.lineHeight;
1121
- fontWeight = typography.label.medium.fontWeight;
1122
- height = '48px';
1123
- break;
1124
- case 'large':
1125
- fontSize = typography.label.large.fontSize;
1126
- lineHeight = typography.label.large.lineHeight;
1127
- fontWeight = typography.label.large.fontWeight;
1128
- height = '56px';
1129
- break;
1080
+ case "small":
1081
+ return css `
1082
+ height: 40px;
1083
+ font-size: ${typography.label.small.fontSize};
1084
+ line-height: ${typography.label.small.lineHeight};
1085
+ font-weight: ${typography.label.small.fontWeight};
1086
+ `;
1087
+ case "medium":
1088
+ return css `
1089
+ height: 48px;
1090
+ font-size: ${typography.label.medium.fontSize};
1091
+ line-height: ${typography.label.medium.lineHeight};
1092
+ font-weight: ${typography.label.medium.fontWeight};
1093
+ `;
1094
+ case "large":
1095
+ return css `
1096
+ height: 56px;
1097
+ font-size: ${typography.label.large.fontSize};
1098
+ line-height: ${typography.label.large.lineHeight};
1099
+ font-weight: ${typography.label.large.fontWeight};
1100
+ `;
1101
+ default:
1102
+ return css `
1103
+ height: 48px;
1104
+ font-size: ${typography.label.medium.fontSize};
1105
+ line-height: ${typography.label.medium.lineHeight};
1106
+ font-weight: ${typography.label.medium.fontWeight};
1107
+ `;
1130
1108
  }
1131
- return {
1132
- width,
1133
- height,
1134
- minHeight: height,
1135
- maxHeight: height,
1136
- padding,
1137
- fontSize,
1138
- lineHeight,
1139
- fontWeight,
1140
- fontFamily: typography.fontFamily.primary,
1141
- border: isFocused ? '1px solid #4a90e2' : '1px solid #ddd',
1142
- borderRadius: '4px',
1143
- outline: 'none',
1144
- transition: 'all 0.2s ease',
1145
- boxShadow: isFocused ? '0 0 0 3px rgba(74, 144, 226, 0.1)' : 'none',
1146
- backgroundColor: disabled ? '#f5f5f5' : '#fff',
1147
- cursor: disabled ? 'not-allowed' : 'text',
1148
- color: '#333',
1149
- boxSizing: 'border-box',
1150
- display: 'flex',
1151
- alignItems: 'center',
1152
- };
1153
1109
  };
1110
+ const InputWrapper = styled.div `
1111
+ display: flex;
1112
+ flex-direction: column;
1113
+ gap: 8px;
1114
+ width: ${(props) => props.width || "306px"};
1115
+ `;
1116
+ const Label = styled.label `
1117
+ display: flex;
1118
+ justify-content: flex-start;
1119
+ font-size: ${typography.label.small.fontSize};
1120
+ line-height: ${typography.label.small.lineHeight};
1121
+ font-weight: ${typography.label.small.fontWeight};
1122
+ font-family: ${typography.fontFamily.primary};
1123
+ color: ${colors.text.subtle};
1124
+ `;
1125
+ const InputContainer = styled.div `
1126
+ position: relative;
1127
+ display: flex;
1128
+ align-items: center;
1129
+ width: 100%;
1130
+ `;
1131
+ const StyledInput = styled.input `
1132
+ width: ${(props) => props.width || "306px"};
1133
+ padding: ${(props) => (props.isPassword ? "0px 48px 0px 16px" : "0px 16px")};
1134
+ font-family: ${typography.fontFamily.primary};
1135
+ border: 1px solid ${colors.input.border};
1136
+ border-radius: 4px;
1137
+ outline: none;
1138
+ transition: all 0.2s ease;
1139
+ background-color: ${(props) => props.disabled ? colors.input["surface-disabled"] : colors.input.surface};
1140
+ cursor: ${(props) => (props.disabled ? "not-allowed" : "text")};
1141
+ color: ${colors.text.basic};
1142
+ box-sizing: border-box;
1143
+
1144
+ ${(props) => getInputSizeStyle(props.inputSize)}
1145
+
1146
+ ${(props) => props.height &&
1147
+ css `
1148
+ height: ${props.height};
1149
+ `}
1150
+
1151
+ &:focus {
1152
+ border: 1px solid ${colors.input["border-active"]};
1153
+ box-shadow: 0 0 0 3px ${colors.light.primary["5"]};
1154
+ }
1155
+
1156
+ &:disabled {
1157
+ border: 1px solid ${colors.input["border-disabled"]};
1158
+ color: ${colors.text.disabled};
1159
+ }
1160
+
1161
+ &::placeholder {
1162
+ color: ${colors.text.disabled};
1163
+ }
1164
+ `;
1165
+ const IconButton = styled.button `
1166
+ position: absolute;
1167
+ right: 12px;
1168
+ top: 50%;
1169
+ transform: translateY(-50%);
1170
+ background: none;
1171
+ border: none;
1172
+ cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")};
1173
+ padding: 4px;
1174
+ display: flex;
1175
+ align-items: center;
1176
+ justify-content: center;
1177
+ opacity: ${(props) => (props.disabled ? 0.5 : 1)};
1178
+ transition: opacity 0.2s ease;
1179
+
1180
+ svg {
1181
+ color: ${(props) => props.disabled ? colors.icon.disabled : colors.icon.gray};
1182
+ }
1183
+ `;
1154
1184
 
1155
- const Input = ({ size = 'medium', label = false, labelText = '', placeholder = '', value, onChange, disabled = false, }) => {
1156
- const [isFocused, setIsFocused] = useState(false);
1157
- return (jsxs("div", { style: getInputWrapperStyle(size), children: [label && labelText && jsx("label", { style: labelStyle, children: labelText }), jsx("input", { style: getInputStyle(size, disabled, isFocused), placeholder: placeholder, value: value, onChange: onChange, disabled: disabled, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false) })] }));
1185
+ const Input = ({ id, width, height, size = "medium", label = false, labelText = "", placeholder = "", value, onChange, disabled = false, isPassword = false, }) => {
1186
+ const [showPassword, setShowPassword] = useState(false);
1187
+ const inputType = isPassword ? (showPassword ? "text" : "password") : "text";
1188
+ return (jsxs(InputWrapper, { width: width, children: [label && labelText && jsx(Label, { htmlFor: id, children: labelText }), jsxs(InputContainer, { children: [jsx(StyledInput, { id: id, type: inputType, inputSize: size, width: width, height: height, disabled: disabled, isPassword: isPassword, placeholder: placeholder, value: value, onChange: onChange }), isPassword && (jsx(IconButton, { type: "button", disabled: disabled, onClick: () => setShowPassword(!showPassword), "aria-label": showPassword ? "Hide password" : "Show password", children: showPassword ? jsx(Eye, { size: 20 }) : jsx(EyeOff, { size: 20 }) }))] })] }));
1158
1189
  };
1159
1190
 
1160
1191
  const StyledIcon = styled.img `