wini-web-components 2.8.2 → 2.8.4

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 (65) hide show
  1. package/package.json +6 -2
  2. package/src/component/button/button.module.css +210 -0
  3. package/src/component/button/button.tsx +57 -0
  4. package/src/component/calendar/calendar.module.css +153 -0
  5. package/src/component/calendar/calendar.tsx +389 -0
  6. package/src/component/carousel/carousel.css +622 -0
  7. package/src/component/carousel/carousel.tsx +91 -0
  8. package/src/component/checkbox/checkbox.module.css +48 -0
  9. package/src/component/checkbox/checkbox.tsx +80 -0
  10. package/src/component/ck-editor/ck-editor.css +206 -0
  11. package/src/component/ck-editor/ckeditor.tsx +522 -0
  12. package/src/component/component-status.tsx +53 -0
  13. package/src/component/date-time-picker/date-time-picker.module.css +94 -0
  14. package/src/component/date-time-picker/date-time-picker.tsx +663 -0
  15. package/src/component/dialog/dialog.module.css +111 -0
  16. package/src/component/dialog/dialog.tsx +109 -0
  17. package/src/component/import-file/import-file.module.css +83 -0
  18. package/src/component/import-file/import-file.tsx +174 -0
  19. package/src/component/infinite-scroll/infinite-scroll.module.css +34 -0
  20. package/src/component/infinite-scroll/infinite-scroll.tsx +35 -0
  21. package/src/component/input-multi-select/input-multi-select.module.css +121 -0
  22. package/src/component/input-multi-select/input-multi-select.tsx +263 -0
  23. package/src/component/input-otp/input-otp.module.css +41 -0
  24. package/src/component/input-otp/input-otp.tsx +110 -0
  25. package/src/component/number-picker/number-picker.module.css +137 -0
  26. package/src/component/number-picker/number-picker.tsx +107 -0
  27. package/src/component/pagination/pagination.module.css +48 -0
  28. package/src/component/pagination/pagination.tsx +88 -0
  29. package/src/component/popup/popup.css +136 -0
  30. package/src/component/popup/popup.tsx +125 -0
  31. package/src/component/progress-bar/progress-bar.module.css +42 -0
  32. package/src/component/progress-bar/progress-bar.tsx +33 -0
  33. package/src/component/progress-circle/progress-circle.css +0 -0
  34. package/src/component/progress-circle/progress-circle.tsx +25 -0
  35. package/src/component/radio-button/radio-button.module.css +51 -0
  36. package/src/component/radio-button/radio-button.tsx +60 -0
  37. package/src/component/rating/rating.module.css +11 -0
  38. package/src/component/rating/rating.tsx +65 -0
  39. package/src/component/select1/select1.module.css +108 -0
  40. package/src/component/select1/select1.tsx +271 -0
  41. package/src/component/switch/switch.module.css +53 -0
  42. package/src/component/switch/switch.tsx +68 -0
  43. package/src/component/table/table.css +74 -0
  44. package/src/component/table/table.tsx +108 -0
  45. package/src/component/tag/tag.module.css +108 -0
  46. package/src/component/tag/tag.tsx +31 -0
  47. package/src/component/text/text.css +27 -0
  48. package/src/component/text/text.tsx +24 -0
  49. package/src/component/text-area/text-area.module.css +57 -0
  50. package/src/component/text-area/text-area.tsx +65 -0
  51. package/src/component/text-field/text-field.module.css +71 -0
  52. package/src/component/text-field/text-field.tsx +102 -0
  53. package/src/component/toast-noti/toast-noti.css +866 -0
  54. package/src/component/toast-noti/toast-noti.tsx +22 -0
  55. package/src/component/wini-icon/winicon.module.css +110 -0
  56. package/src/component/wini-icon/winicon.tsx +9424 -0
  57. package/src/form/login/view.module.css +80 -0
  58. package/src/form/login/view.tsx +138 -0
  59. package/src/global.d.ts +5 -0
  60. package/src/index.tsx +66 -0
  61. package/src/language/i18n.tsx +143 -0
  62. package/src/skin/layout.css +649 -0
  63. package/src/skin/root.css +294 -0
  64. package/src/skin/typography.css +314 -0
  65. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,80 @@
1
+ .login-view-container {
2
+ gap: 4.8rem;
3
+ align-items: center;
4
+ min-width: 320px;
5
+ max-width: 460px;
6
+ }
7
+
8
+ .login-view-form-container {
9
+ gap: 2rem;
10
+ align-items: inherit;
11
+ width: 100%;
12
+ }
13
+
14
+ .login-view-form-container>div:last-child {
15
+ padding: 0.4rem 3.2rem;
16
+ gap: inherit;
17
+ align-items: inherit;
18
+ width: 100%;
19
+ }
20
+
21
+ .login-view-form-container>div:last-child>div {
22
+ width: 100%;
23
+ }
24
+
25
+ button.login-btn {
26
+ height: 4.8rem;
27
+ width: 100%;
28
+ justify-content: center;
29
+ background-color: var(--primary-main-color);
30
+ color: var(--neutral-text-stable-color);
31
+ }
32
+
33
+ button:disabled.login-btn {
34
+ background-color: var(--neutral-disable-background-color);
35
+ color: var(--neutral-text-disabled-color);
36
+ cursor: context-menu;
37
+ }
38
+
39
+ .forgot-password-btn {
40
+ color: var(--neutral-text-subtitle-color);
41
+ }
42
+
43
+ .forgot-password-btn:hover {
44
+ text-decoration: underline;
45
+ cursor: pointer;
46
+ }
47
+
48
+ .register-btn:hover {
49
+ text-decoration: underline;
50
+ cursor: pointer;
51
+ }
52
+
53
+ .login-social-media {
54
+ gap: 1.6rem;
55
+ flex-wrap: wrap;
56
+ }
57
+
58
+ .login-social-media>button {
59
+ height: 4.8rem;
60
+ width: calc((100% - 1.6rem) / 2);
61
+ gap: 1.6rem;
62
+ justify-content: center;
63
+ border: var(--neutral-bolder-border);
64
+ background-color: transparent;
65
+ }
66
+
67
+ .or-spacing {
68
+ gap: 1.2rem;
69
+ }
70
+
71
+ .or-spacing>div:nth-child(odd) {
72
+ height: 1px;
73
+ width: 100%;
74
+ flex: 1;
75
+ background-color: var(--neutral-text-body-reverse-color);
76
+ }
77
+
78
+ .or-spacing>div:nth-child(even) {
79
+ color: var(--neutral-text-subtitle-color);
80
+ }
@@ -0,0 +1,138 @@
1
+ import React, { CSSProperties } from 'react'
2
+ import { Button, Text, TextField, Winicon } from '../../index'
3
+ import styles from './view.module.css'
4
+ import { FieldValues, useForm, UseFormReturn } from 'react-hook-form'
5
+ import { useState } from 'react'
6
+ import { useTranslation } from 'react-i18next'
7
+
8
+ interface Props {
9
+ logo: React.ReactNode | string,
10
+ formData: {
11
+ "username": { label: string, name: string, prefix?: React.ReactNode, onValidate?: React.FocusEventHandler<HTMLInputElement>, maxLength?: number },
12
+ "password": { label: string, name: string, prefix?: React.ReactNode, onValidate?: React.FocusEventHandler<HTMLInputElement>, maxLength?: number },
13
+ },
14
+ onSubmit?: (data: FieldValues, methods?: UseFormReturn<any>) => void,
15
+ title?: string,
16
+ orText?: string,
17
+ methods?: UseFormReturn<any>,
18
+ buttonLoginLabel?: string,
19
+ loginWithGoogle?: React.MouseEventHandler<HTMLButtonElement>,
20
+ loginWithFacebook?: React.MouseEventHandler<HTMLButtonElement>,
21
+ loginWithApple?: React.MouseEventHandler<HTMLButtonElement>,
22
+ loginWithMicrosoft?: React.MouseEventHandler<HTMLButtonElement>,
23
+ onRegister?: React.MouseEventHandler<HTMLDivElement>,
24
+ registerPrefixText?: string,
25
+ registerText?: string,
26
+ forgotPasswordText?: string,
27
+ onForgotPassword?: React.MouseEventHandler<HTMLDivElement>,
28
+ style?: CSSProperties,
29
+ className?: string,
30
+ id?: string
31
+ }
32
+
33
+ export function WLoginView(props: Props) {
34
+ const methods = useForm<any>({ shouldFocusError: false })
35
+ const [isShowPass, setShowPass] = useState(false)
36
+ const { t } = useTranslation()
37
+
38
+ const _onSubmit = (ev: FieldValues) => {
39
+ if (props.onSubmit) props.onSubmit(ev, methods)
40
+ }
41
+
42
+ return <form id={props.id} className={`col login-view-container ${styles['login-view-container']} ${props.className ?? ''}`} style={props.style}>
43
+ {typeof props.logo === "string" ? <img alt='logo' src={props.logo} height={"36rem"} /> : props.logo}
44
+ <div className={`col login-view-form-container ${styles['login-view-form-container']}`}>
45
+ <Text className='heading-4'>{props.title ?? `${t("loginTo")} Wini`}</Text>
46
+ <div className='col'>
47
+ <div className='col' style={{ gap: "0.8rem", overflow: "visible" }}>
48
+ <Text className='label-3'>{props.formData.username.label ?? t("username")}</Text>
49
+ <TextField
50
+ autoComplete='username'
51
+ className="placeholder-2"
52
+ placeholder={props.formData.username.label}
53
+ style={{ height: "4.8rem" }}
54
+ prefix={props.formData.username.prefix}
55
+ name={props.formData.username.name}
56
+ register={(props.methods ?? methods).register(props.formData.username.name, {
57
+ onChange: (ev) => { ev.target.value = ev.target.value.trim() },
58
+ onBlur: props.formData.username.onValidate
59
+ }) as any}
60
+ onComplete={(ev: any) => { ev.target.blur() }}
61
+ helperText={(props.methods ?? methods).formState.errors?.[props.formData.username.name]?.message as any}
62
+ />
63
+ </div>
64
+ <div className='col' style={{ gap: "0.8rem", overflow: "visible" }}>
65
+ <Text className='label-3'>{props.formData.password.label ?? t("password")}</Text>
66
+ <TextField
67
+ autoComplete='current-password'
68
+ className="placeholder-2"
69
+ placeholder={props.formData.password.label}
70
+ style={{ height: "4.8rem" }}
71
+ prefix={props.formData.password.prefix}
72
+ suffix={<button type='button' onClick={() => { setShowPass(!isShowPass) }}><Winicon src={`outline/user interface/${isShowPass ? "view" : "hide"}`} size={"1.6rem"} /></button>}
73
+ name={props.formData.password.name}
74
+ type={isShowPass ? "text" : "password"}
75
+ register={(props.methods ?? methods).register(props.formData.password.name, {
76
+ onChange: (ev) => { ev.target.value = ev.target.value.trim() },
77
+ onBlur: props.formData.password.onValidate
78
+ }) as any}
79
+ onComplete={(ev: any) => {
80
+ if ((props.methods ?? methods).watch(props.formData.password.name)?.length) {
81
+ ev.target.blur()
82
+ if (!props.formData.password.onValidate && props.onSubmit) _onSubmit((props.methods ?? methods).getValues())
83
+ } else ev.target.blur()
84
+ }}
85
+ helperText={(props.methods ?? methods).formState.errors?.[props.formData.password.name]?.message as any}
86
+ />
87
+ </div>
88
+ <Text className={`button-text-3 ${styles['forgot-password-btn']}`} onClick={props.onForgotPassword}>{props.forgotPasswordText ?? t("forgotPassword")}</Text>
89
+ <div className='col' style={{ gap: "1.6rem" }}>
90
+ <Button
91
+ disabled={(props.methods ?? methods).watch(props.formData.username.name)?.length && (props.methods ?? methods).watch(props.formData.password.name)?.length ? false : true}
92
+ className={`button-text-1 ${styles['login-btn']}`}
93
+ onClick={props.onSubmit && (props.methods ?? methods).handleSubmit(_onSubmit)}
94
+ label={props.buttonLoginLabel ?? t("login")}
95
+ />
96
+ <div className='row' style={{ justifyContent: "center", gap: "0.4rem" }}>
97
+ <Text className='label-4'>{props.registerPrefixText ?? t("dontHaveAccount")}</Text>
98
+ <Text className={`button-text-3 ${styles['register-btn']}`} onClick={props.onRegister}>{props.registerText ?? `${t("signupFor")} Wini`}</Text>
99
+ </div>
100
+ </div>
101
+ {(props.loginWithGoogle || props.loginWithFacebook || props.loginWithApple || props.loginWithMicrosoft) ?
102
+ <>
103
+ <div className={`row ${styles['or-spacing']}`}>
104
+ <div />
105
+ <Text className="label-4">{props.orText ?? t("or")}</Text>
106
+ <div />
107
+ </div>
108
+ <div className={`row ${styles['login-social-media']}`}>
109
+ {props.loginWithGoogle && <Button
110
+ className={`label-1`}
111
+ onClick={props.loginWithGoogle}
112
+ prefix={<Winicon src='color/social media/google' size={"2rem"} />}
113
+ label="Google"
114
+ />}
115
+ {props.loginWithFacebook && <Button
116
+ className={`label-1`}
117
+ onClick={props.loginWithFacebook}
118
+ prefix={<Winicon src='color/social media/logo-facebook' size={"2rem"} />}
119
+ label="Facebook"
120
+ />}
121
+ {props.loginWithApple && <Button
122
+ className={`label-1`}
123
+ onClick={props.loginWithApple}
124
+ prefix={<Winicon src='color/development/apple' size={"2rem"} />}
125
+ label="Apple"
126
+ />}
127
+ {props.loginWithMicrosoft && <Button
128
+ className={`label-1`}
129
+ onClick={props.loginWithMicrosoft}
130
+ prefix={<Winicon src='color/development/microsoft' size={"2rem"} />}
131
+ label="Microsoft"
132
+ />}
133
+ </div>
134
+ </> : null}
135
+ </div>
136
+ </div>
137
+ </form>
138
+ }
@@ -0,0 +1,5 @@
1
+ declare module '*.css' {
2
+ const content: { [className: string]: string };
3
+ export default content;
4
+ }
5
+
package/src/index.tsx ADDED
@@ -0,0 +1,66 @@
1
+ import { Checkbox } from './component/checkbox/checkbox'
2
+ import { Select1, OptionsItem } from './component/select1/select1'
3
+ import { Switch } from './component/switch/switch'
4
+ import { showPopup, closePopup, Popup } from './component/popup/popup'
5
+ import { showDialog, Dialog, DialogAlignment } from './component/dialog/dialog'
6
+ import { DateTimePicker } from './component/date-time-picker/date-time-picker'
7
+ import { SelectMultiple } from './component/input-multi-select/input-multi-select'
8
+ import { ProgressBar } from './component/progress-bar/progress-bar'
9
+ import { ComponentStatus, getStatusIcon } from './component/component-status'
10
+ import { Text } from './component/text/text'
11
+ import { Pagination } from './component/pagination/pagination'
12
+ import { Table, TbCell, TbHeader, TbRow, TbBody, CellAlignItems } from './component/table/table'
13
+ import { TextField } from './component/text-field/text-field'
14
+ import { RadioButton } from './component/radio-button/radio-button'
15
+ import { TextArea } from './component/text-area/text-area'
16
+ import { ImportFile } from './component/import-file/import-file'
17
+ import { ToastMessage } from './component/toast-noti/toast-noti'
18
+ import { Calendar } from './component/calendar/calendar'
19
+ import { InfiniteScroll } from './component/infinite-scroll/infinite-scroll'
20
+ import { Rating } from './component/rating/rating'
21
+ import { ProgressCircle } from './component/progress-circle/progress-circle'
22
+ import { Carousel } from './component/carousel/carousel'
23
+ import { ToastContainer } from 'react-toastify'
24
+ import { Button } from './component/button/button'
25
+ import { Tag } from './component/tag/tag'
26
+ import { Winicon } from './component/wini-icon/winicon'
27
+ import { NumberPicker } from './component/number-picker/number-picker'
28
+ import { InputOtp } from './component/input-otp/input-otp'
29
+ import { WLoginView } from './form/login/view'
30
+ import { CustomCkEditor5 } from './component/ck-editor/ckeditor'
31
+
32
+
33
+ export {
34
+ Calendar,
35
+ ComponentStatus,
36
+ getStatusIcon,
37
+ Checkbox,
38
+ Select1, Switch,
39
+ Popup, showPopup, closePopup,
40
+ Dialog, showDialog, DialogAlignment,
41
+ DateTimePicker,
42
+ SelectMultiple,
43
+ ProgressBar,
44
+ Text,
45
+ Pagination,
46
+ Table, TbCell, TbHeader, TbBody, TbRow, CellAlignItems,
47
+ TextField,
48
+ RadioButton,
49
+ TextArea,
50
+ ImportFile,
51
+ ToastMessage,
52
+ InfiniteScroll,
53
+ Rating,
54
+ ProgressCircle,
55
+ Carousel,
56
+ ToastContainer,
57
+ Button,
58
+ Tag,
59
+ Winicon,
60
+ NumberPicker,
61
+ InputOtp,
62
+ WLoginView,
63
+ CustomCkEditor5
64
+ }
65
+ export type { OptionsItem }
66
+ export { i18n } from './language/i18n';
@@ -0,0 +1,143 @@
1
+ import i18n from 'i18next';
2
+ import { initReactI18next } from 'react-i18next';
3
+
4
+ // Translation resources
5
+ const resources = {
6
+ en: {
7
+ translation: {
8
+ su: 'Su',
9
+ mo: "Mo",
10
+ tu: "Tu",
11
+ we: "We",
12
+ th: "Th",
13
+ fr: "Fr",
14
+ sa: "Sa",
15
+ yesterday: "Yesterday",
16
+ lastWeek: "Last week",
17
+ lastMonth: "Last month",
18
+ lastYear: "Last year",
19
+ january: "January",
20
+ february: "February",
21
+ march: "March",
22
+ april: "April",
23
+ may: "May",
24
+ june: "June",
25
+ july: "July",
26
+ august: "August",
27
+ september: "September",
28
+ october: "October",
29
+ november: "November",
30
+ december: "December",
31
+ today: "Today",
32
+ apply: "Apply",
33
+ cancel: "Cancel",
34
+ submit: "Submit",
35
+ limitFileError: "File {{file.name}} exceeds the maximum size of {{sizeTitle}}",
36
+ limitFileWarning: "File size should not exceed {{sizeTitle}}.",
37
+ uploadFileAction: 'Click or drag and drop to upload file',
38
+ file: "File",
39
+ remove: "Remove",
40
+ choose: "Choose",
41
+ select: "Select",
42
+ add: "Add",
43
+ all: "All",
44
+ noResultFound: "No result found",
45
+ ofItems: "of {{totalItem}} items",
46
+ page: "Page",
47
+ go: "Go to",
48
+ or: "Or",
49
+ username: "Username",
50
+ password: "Password",
51
+ dontHaveAccount: "Don't have an account?",
52
+ forgotPassword: "Forgot your password?",
53
+ login: "Log in",
54
+ loginTo: "Log in to",
55
+ signup: "Sign up",
56
+ signupFor: "Sign up for",
57
+ "start-date": "Start date",
58
+ "end-date": "End date",
59
+ reset: "Reset",
60
+ date: "Date",
61
+ on: "On",
62
+ daily: "Daily",
63
+ weekly: "Weekly",
64
+ monthly: "Monthly",
65
+ last: "Last",
66
+ },
67
+ },
68
+ vi: {
69
+ translation: {
70
+ su: 'CN',
71
+ mo: "T2",
72
+ tu: "T3",
73
+ we: "T4",
74
+ th: "T5",
75
+ fr: "T6",
76
+ sa: "T7",
77
+ yesterday: "Hôm qua",
78
+ lastWeek: "Tuần trước",
79
+ lastMonth: "Tháng trước",
80
+ lastYear: "Năm trước",
81
+ january: "Tháng 1",
82
+ february: "Tháng 2",
83
+ march: "Tháng 3",
84
+ april: "Tháng 4",
85
+ may: "Tháng 5",
86
+ june: "Tháng 6",
87
+ july: "Tháng 7",
88
+ august: "Tháng 8",
89
+ september: "Tháng 9",
90
+ october: "Tháng 10",
91
+ november: "Tháng 11",
92
+ december: "Tháng 12",
93
+ today: "Hôm nay",
94
+ apply: "Áp dụng",
95
+ cancel: "Hủy",
96
+ submit: "Xác nhận",
97
+ limitFileError: "Tệp {{name}} vượt quá dung lượng tối đa {{sizeTitle}}",
98
+ limitFileWarning: "Tệp không được vượt quá {{sizeTitle}}.",
99
+ uploadFileAction: 'Nhấn hoặc kéo vào để tải tệp lên',
100
+ file: "Tệp",
101
+ remove: "Xóa",
102
+ choose: "Chọn",
103
+ select: "Chọn",
104
+ add: "Thêm",
105
+ all: "Tất cả",
106
+ noResultFound: "Không tìm thấy kết quả",
107
+ ofItems: "trên {{totalItem}} kết quả",
108
+ page: "Trang",
109
+ go: "Đi tới",
110
+ or: "Hoặc",
111
+ username: "Tên đăng nhập",
112
+ password: "Mật khẩu",
113
+ dontHaveAccount: "Chưa có tài khoản?",
114
+ forgotPassword: "Quên mật khẩu?",
115
+ login: "Đăng nhập",
116
+ loginTo: "Đăng nhập vào",
117
+ signup: "Đăng ký",
118
+ signupFor: "Đăng ký",
119
+ "start-date": "Ngày bắt đầu",
120
+ "end-date": "Ngày kết thúc",
121
+ reset: "Mặc định",
122
+ date: "Ngày",
123
+ on: "Vào",
124
+ daily: "Hàng ngày",
125
+ weekly: "Hàng tuần",
126
+ monthly: "Hàng tháng",
127
+ last: "Cuối tháng",
128
+ },
129
+ },
130
+ }
131
+
132
+ // Initialize i18n
133
+ i18n.use(initReactI18next).init({
134
+ resources,
135
+ lng: 'en', // Default language
136
+ fallbackLng: 'en', // Fallback language
137
+ // backend: {loadPath: "somevariables"},
138
+ interpolation: {
139
+ escapeValue: false, // React already escapes values
140
+ },
141
+ })
142
+
143
+ export { i18n }