teachable-design-system 0.1.15 → 0.2.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.
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,88 +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
- border: '1px solid'
1104
- };
1105
- const getInputStyle = (inputSize, disabled, isFocused) => {
1106
- let padding = '0px 16px';
1107
- let fontSize = typography.label.medium.fontSize;
1108
- let lineHeight = typography.label.medium.lineHeight;
1109
- let fontWeight = typography.label.medium.fontWeight;
1110
- let height = '48px';
1111
- let width = '306px';
1112
- switch (inputSize) {
1113
- case 'small':
1114
- fontSize = typography.label.small.fontSize;
1115
- lineHeight = typography.label.small.lineHeight;
1116
- fontWeight = typography.label.small.fontWeight;
1117
- height = '40px';
1118
- break;
1119
- case 'medium':
1120
- fontSize = typography.label.medium.fontSize;
1121
- lineHeight = typography.label.medium.lineHeight;
1122
- fontWeight = typography.label.medium.fontWeight;
1123
- height = '48px';
1124
- break;
1125
- case 'large':
1126
- fontSize = typography.label.large.fontSize;
1127
- lineHeight = typography.label.large.lineHeight;
1128
- fontWeight = typography.label.large.fontWeight;
1129
- height = '56px';
1130
- 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
+ `;
1131
1108
  }
1132
- return {
1133
- width,
1134
- height,
1135
- minHeight: height,
1136
- maxHeight: height,
1137
- padding,
1138
- fontSize,
1139
- lineHeight,
1140
- fontWeight,
1141
- fontFamily: typography.fontFamily.primary,
1142
- border: isFocused ? '1px solid #4a90e2' : '1px solid #ddd',
1143
- borderRadius: '4px',
1144
- outline: 'none',
1145
- transition: 'all 0.2s ease',
1146
- boxShadow: isFocused ? '0 0 0 3px rgba(74, 144, 226, 0.1)' : 'none',
1147
- backgroundColor: disabled ? '#f5f5f5' : '#fff',
1148
- cursor: disabled ? 'not-allowed' : 'text',
1149
- color: '#333',
1150
- boxSizing: 'border-box',
1151
- display: 'flex',
1152
- alignItems: 'center',
1153
- };
1154
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
+ `;
1155
1184
 
1156
- const Input = ({ size = 'medium', label = false, labelText = '', placeholder = '', value, onChange, disabled = false, }) => {
1157
- const [isFocused, setIsFocused] = useState(false);
1158
- 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 }) }))] })] }));
1159
1189
  };
1160
1190
 
1161
1191
  const StyledIcon = styled.img `