@sakura-ui/sakura-ui 0.2.0 → 0.3.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.
Files changed (215) hide show
  1. package/README.md +16 -6
  2. package/package.json +21 -15
  3. package/packages/core/package.json +26 -15
  4. package/packages/core/src/components/Button.tsx +33 -32
  5. package/packages/core/src/components/Card.tsx +29 -17
  6. package/packages/core/src/components/Code.tsx +6 -4
  7. package/packages/core/src/components/Faq.tsx +13 -7
  8. package/packages/core/src/components/Heading.tsx +42 -32
  9. package/packages/core/src/components/Icon.tsx +43 -13
  10. package/packages/core/src/components/IconButton.tsx +54 -43
  11. package/packages/core/src/components/LangSelector.tsx +135 -0
  12. package/packages/core/src/components/Link.tsx +38 -66
  13. package/packages/core/src/components/LinkCard.tsx +91 -0
  14. package/packages/core/src/components/List.tsx +14 -12
  15. package/packages/core/src/components/MenuButton.tsx +112 -0
  16. package/packages/core/src/components/NavigationItem.tsx +41 -0
  17. package/packages/core/src/components/OverflowContainer.tsx +24 -0
  18. package/packages/core/src/components/PopoverMenu.tsx +81 -0
  19. package/packages/core/src/components/Pre.tsx +6 -4
  20. package/packages/core/src/components/Table.tsx +31 -25
  21. package/packages/core/src/components/buttonStyle.ts +42 -31
  22. package/packages/core/src/components/index.ts +13 -25
  23. package/packages/core/src/icons/Close.tsx +21 -0
  24. package/packages/core/src/icons/CloseMobile.tsx +43 -0
  25. package/packages/core/src/icons/KeyboardArrowDown.tsx +24 -0
  26. package/packages/core/src/icons/Language.tsx +25 -0
  27. package/packages/core/src/icons/LanguageMobile.tsx +40 -0
  28. package/packages/core/src/icons/Menu.tsx +24 -0
  29. package/packages/core/src/icons/MenuMobile.tsx +40 -0
  30. package/packages/core/src/icons/index.ts +8 -0
  31. package/packages/core/src/icons/props.ts +5 -0
  32. package/packages/core/src/index.ts +9 -28
  33. package/packages/core/src/type.d.ts +1 -0
  34. package/packages/core/tests/Button.test.tsx +20 -10
  35. package/packages/core/tests/Card.test.tsx +16 -11
  36. package/packages/core/tests/IconButton.test.tsx +57 -0
  37. package/packages/core/tests/Link.test.tsx +60 -0
  38. package/packages/core/tests/vitest.setup.ts +1 -0
  39. package/packages/core/tsconfig.node.json +3 -2
  40. package/packages/forms/.turbo/turbo-build.log +22 -0
  41. package/packages/forms/dist/index.cjs.js +199 -120
  42. package/packages/forms/dist/index.es.js +890 -1023
  43. package/packages/forms/dist/types/components/Checkbox.d.ts +9 -4
  44. package/packages/forms/dist/types/components/Checkbox.d.ts.map +1 -1
  45. package/packages/forms/dist/types/components/FieldsetControl.d.ts +14 -9
  46. package/packages/forms/dist/types/components/FieldsetControl.d.ts.map +1 -1
  47. package/packages/forms/dist/types/components/FileInput.d.ts +10 -3
  48. package/packages/forms/dist/types/components/FileInput.d.ts.map +1 -1
  49. package/packages/forms/dist/types/components/Input.d.ts +9 -4
  50. package/packages/forms/dist/types/components/Input.d.ts.map +1 -1
  51. package/packages/forms/dist/types/components/LabelControl.d.ts +13 -8
  52. package/packages/forms/dist/types/components/LabelControl.d.ts.map +1 -1
  53. package/packages/forms/dist/types/components/Radio.d.ts +9 -4
  54. package/packages/forms/dist/types/components/Radio.d.ts.map +1 -1
  55. package/packages/forms/dist/types/components/Select.d.ts +9 -4
  56. package/packages/forms/dist/types/components/Select.d.ts.map +1 -1
  57. package/packages/forms/dist/types/components/Textarea.d.ts +8 -3
  58. package/packages/forms/dist/types/components/Textarea.d.ts.map +1 -1
  59. package/packages/forms/dist/types/components/controlled/CheckboxGroup.d.ts +16 -11
  60. package/packages/forms/dist/types/components/controlled/CheckboxGroup.d.ts.map +1 -1
  61. package/packages/forms/dist/types/components/controlled/RadioGroup.d.ts +17 -12
  62. package/packages/forms/dist/types/components/controlled/RadioGroup.d.ts.map +1 -1
  63. package/packages/forms/dist/types/components/index.d.ts +8 -8
  64. package/packages/forms/dist/types/components/index.d.ts.map +1 -1
  65. package/packages/forms/dist/types/components/inputStyle.d.ts +1 -1
  66. package/packages/forms/dist/types/components/inputStyle.d.ts.map +1 -1
  67. package/packages/forms/dist/types/index.d.ts +0 -1
  68. package/packages/forms/dist/types/index.d.ts.map +1 -1
  69. package/packages/forms/node_modules/.bin/autoprefixer +2 -2
  70. package/packages/forms/node_modules/.bin/tailwind +2 -2
  71. package/packages/forms/node_modules/.bin/tailwindcss +2 -2
  72. package/packages/forms/node_modules/.bin/ts-node +4 -4
  73. package/packages/forms/node_modules/.bin/ts-node-cwd +4 -4
  74. package/packages/forms/node_modules/.bin/ts-node-esm +4 -4
  75. package/packages/forms/node_modules/.bin/ts-node-script +4 -4
  76. package/packages/forms/node_modules/.bin/ts-node-transpile-only +4 -4
  77. package/packages/forms/node_modules/.bin/ts-script +4 -4
  78. package/packages/forms/node_modules/.bin/tsc +17 -0
  79. package/packages/forms/node_modules/.bin/tsserver +17 -0
  80. package/packages/forms/node_modules/.vite/vitest/results.json +1 -0
  81. package/packages/forms/package.json +17 -14
  82. package/packages/forms/src/components/Checkbox.tsx +76 -80
  83. package/packages/forms/src/components/FieldsetControl.tsx +21 -28
  84. package/packages/forms/src/components/FileInput.tsx +87 -63
  85. package/packages/forms/src/components/Input.tsx +29 -31
  86. package/packages/forms/src/components/LabelControl.tsx +19 -25
  87. package/packages/forms/src/components/Radio.tsx +66 -69
  88. package/packages/forms/src/components/Select.tsx +65 -65
  89. package/packages/forms/src/components/Textarea.tsx +49 -54
  90. package/packages/forms/src/components/controlled/CheckboxGroup.tsx +15 -17
  91. package/packages/forms/src/components/controlled/RadioGroup.tsx +16 -18
  92. package/packages/forms/src/components/index.ts +8 -8
  93. package/packages/forms/src/components/inputStyle.ts +7 -8
  94. package/packages/forms/src/index.ts +0 -11
  95. package/packages/forms/tests/Checkbox.test.tsx +44 -0
  96. package/packages/forms/tests/FieldsetControl.test.tsx +62 -11
  97. package/packages/forms/tests/FileInput.test.tsx +25 -0
  98. package/packages/forms/tests/Input.test.tsx +12 -83
  99. package/packages/forms/tests/LabelControl.test.tsx +82 -20
  100. package/packages/forms/tests/Radio.test.tsx +23 -78
  101. package/packages/forms/tests/Select.test.tsx +30 -0
  102. package/packages/forms/tests/Textarea.test.tsx +25 -0
  103. package/packages/forms/tests/vitest.setup.ts +1 -0
  104. package/packages/forms/tsconfig.node.json +3 -2
  105. package/packages/helper/.turbo/turbo-build.log +23 -0
  106. package/packages/helper/dist/index.cjs.js +78 -0
  107. package/packages/helper/dist/index.es.js +119 -0
  108. package/packages/helper/dist/types/calc.d.ts +2 -0
  109. package/packages/helper/dist/types/calc.d.ts.map +1 -0
  110. package/packages/{forms/dist/types/utils/class.d.ts → helper/dist/types/cx.d.ts} +1 -1
  111. package/packages/helper/dist/types/cx.d.ts.map +1 -0
  112. package/packages/helper/dist/types/index.d.ts +6 -0
  113. package/packages/helper/dist/types/index.d.ts.map +1 -0
  114. package/packages/helper/dist/types/querySelector.d.ts +2 -0
  115. package/packages/helper/dist/types/querySelector.d.ts.map +1 -0
  116. package/packages/helper/dist/types/styles.d.ts +22 -0
  117. package/packages/helper/dist/types/styles.d.ts.map +1 -0
  118. package/packages/helper/dist/types/treefy.d.ts +8 -0
  119. package/packages/helper/dist/types/treefy.d.ts.map +1 -0
  120. package/packages/helper/package.json +40 -0
  121. package/packages/helper/src/calc.ts +1 -0
  122. package/packages/helper/src/index.ts +5 -0
  123. package/packages/helper/src/querySelector.ts +20 -0
  124. package/packages/helper/src/styles.ts +116 -0
  125. package/packages/helper/src/treefy.ts +22 -0
  126. package/packages/helper/tsconfig.json +13 -0
  127. package/packages/helper/tsconfig.node.json +6 -0
  128. package/packages/helper/vite.config.ts +26 -0
  129. package/packages/markdown/.turbo/turbo-build.log +22 -0
  130. package/packages/markdown/README.md +129 -0
  131. package/packages/markdown/dist/index.cjs.js +175 -0
  132. package/packages/markdown/dist/index.es.js +17098 -0
  133. package/packages/markdown/dist/types/components/Markdown.d.ts +15 -0
  134. package/packages/markdown/dist/types/components/Markdown.d.ts.map +1 -0
  135. package/packages/markdown/dist/types/components/index.d.ts +2 -0
  136. package/packages/markdown/dist/types/components/index.d.ts.map +1 -0
  137. package/packages/markdown/dist/types/index.d.ts +2 -0
  138. package/packages/markdown/dist/types/index.d.ts.map +1 -0
  139. package/packages/markdown/dist/types/plugins/attr.d.ts +3 -0
  140. package/packages/markdown/dist/types/plugins/attr.d.ts.map +1 -0
  141. package/packages/markdown/dist/types/plugins/card.d.ts +3 -0
  142. package/packages/markdown/dist/types/plugins/card.d.ts.map +1 -0
  143. package/packages/markdown/dist/types/plugins/cell.d.ts +3 -0
  144. package/packages/markdown/dist/types/plugins/cell.d.ts.map +1 -0
  145. package/packages/markdown/dist/types/plugins/faq.d.ts +3 -0
  146. package/packages/markdown/dist/types/plugins/faq.d.ts.map +1 -0
  147. package/packages/markdown/dist/types/plugins/grid.d.ts +3 -0
  148. package/packages/markdown/dist/types/plugins/grid.d.ts.map +1 -0
  149. package/packages/markdown/dist/types/plugins/headings.d.ts +9 -0
  150. package/packages/markdown/dist/types/plugins/headings.d.ts.map +1 -0
  151. package/packages/markdown/dist/types/plugins/helper.d.ts +9 -0
  152. package/packages/markdown/dist/types/plugins/helper.d.ts.map +1 -0
  153. package/packages/markdown/dist/types/plugins/index.d.ts +9 -0
  154. package/packages/markdown/dist/types/plugins/index.d.ts.map +1 -0
  155. package/packages/markdown/dist/types/plugins/linkButton.d.ts +3 -0
  156. package/packages/markdown/dist/types/plugins/linkButton.d.ts.map +1 -0
  157. package/packages/markdown/dist/types/plugins/youtube.d.ts +3 -0
  158. package/packages/markdown/dist/types/plugins/youtube.d.ts.map +1 -0
  159. package/packages/markdown/node_modules/.bin/autoprefixer +17 -0
  160. package/packages/markdown/node_modules/.bin/tailwind +17 -0
  161. package/packages/markdown/node_modules/.bin/tailwindcss +17 -0
  162. package/packages/markdown/node_modules/.bin/ts-node +17 -0
  163. package/packages/markdown/node_modules/.bin/ts-node-cwd +17 -0
  164. package/packages/markdown/node_modules/.bin/ts-node-esm +17 -0
  165. package/packages/markdown/node_modules/.bin/ts-node-script +17 -0
  166. package/packages/markdown/node_modules/.bin/ts-node-transpile-only +17 -0
  167. package/packages/markdown/node_modules/.bin/ts-script +17 -0
  168. package/packages/markdown/node_modules/.bin/tsc +17 -0
  169. package/packages/markdown/node_modules/.bin/tsserver +17 -0
  170. package/packages/markdown/package.json +83 -0
  171. package/packages/markdown/src/components/Markdown.tsx +361 -0
  172. package/packages/markdown/src/components/index.ts +1 -0
  173. package/packages/markdown/src/global.d.ts +9 -0
  174. package/packages/markdown/src/index.ts +1 -0
  175. package/packages/markdown/src/plugins/attr.ts +19 -0
  176. package/packages/markdown/src/plugins/card.ts +57 -0
  177. package/packages/markdown/src/plugins/cell.ts +47 -0
  178. package/packages/markdown/src/plugins/faq.ts +40 -0
  179. package/packages/markdown/src/plugins/grid.ts +51 -0
  180. package/packages/markdown/src/plugins/headings.ts +35 -0
  181. package/packages/markdown/src/plugins/helper.ts +27 -0
  182. package/packages/markdown/src/plugins/index.ts +8 -0
  183. package/packages/markdown/src/plugins/linkButton.ts +25 -0
  184. package/packages/markdown/src/plugins/youtube.ts +48 -0
  185. package/packages/markdown/tsconfig.json +13 -0
  186. package/packages/markdown/tsconfig.node.json +7 -0
  187. package/packages/markdown/vite.config.ts +30 -0
  188. package/packages/tailwind-theme-plugin/.turbo/turbo-build.log +22 -0
  189. package/packages/tailwind-theme-plugin/dist/index.cjs.js +1 -1
  190. package/packages/tailwind-theme-plugin/dist/index.es.js +5354 -6111
  191. package/packages/tailwind-theme-plugin/dist/types/index.d.ts +1 -1
  192. package/packages/tailwind-theme-plugin/dist/types/index.d.ts.map +1 -1
  193. package/packages/tailwind-theme-plugin/node_modules/.bin/autoprefixer +2 -2
  194. package/packages/tailwind-theme-plugin/node_modules/.bin/tailwind +2 -2
  195. package/packages/tailwind-theme-plugin/node_modules/.bin/tailwindcss +2 -2
  196. package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node +4 -4
  197. package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node-cwd +4 -4
  198. package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node-esm +4 -4
  199. package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node-script +4 -4
  200. package/packages/tailwind-theme-plugin/node_modules/.bin/ts-node-transpile-only +4 -4
  201. package/packages/tailwind-theme-plugin/node_modules/.bin/ts-script +4 -4
  202. package/packages/tailwind-theme-plugin/node_modules/.bin/tsc +17 -0
  203. package/packages/tailwind-theme-plugin/node_modules/.bin/tsserver +17 -0
  204. package/packages/tailwind-theme-plugin/package.json +6 -6
  205. package/packages/tailwind-theme-plugin/src/index.ts +226 -291
  206. package/packages/core/src/libs/forward-ref.ts +0 -44
  207. package/packages/core/src/types/component.ts +0 -83
  208. package/packages/forms/dist/types/utils/class.d.ts.map +0 -1
  209. package/packages/forms/node_modules/.bin/acorn +0 -17
  210. package/packages/forms/node_modules/.bin/browserslist +0 -17
  211. package/packages/forms/node_modules/.bin/eslint +0 -17
  212. package/packages/forms/node_modules/.bin/vitest +0 -17
  213. package/packages/forms/src/utils/class.ts +0 -2
  214. package/packages/tailwind-theme-plugin/node_modules/.bin/browserslist +0 -17
  215. /package/packages/{core/src/libs → helper/src}/cx.ts +0 -0
@@ -1,5 +1,5 @@
1
- import React from 'react'
2
- import { cx } from '../utils/class'
1
+ import React, { type ComponentPropsWithRef } from 'react'
2
+ import { cx, Style } from '@sakura-ui/helper'
3
3
  import { ControllerContext } from './context'
4
4
  import {
5
5
  type InputSize,
@@ -8,78 +8,75 @@ import {
8
8
  iconStyles
9
9
  } from './inputStyle'
10
10
 
11
- export interface RadioProps
12
- extends Omit<React.ComponentPropsWithRef<'input'>, 'size'> {
13
- size?: InputSize
11
+ export namespace Radio {
12
+ export interface Props extends Omit<ComponentPropsWithRef<'input'>, 'size'> {
13
+ size?: InputSize
14
+ }
14
15
  }
15
16
 
16
- export const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
17
- (props, ref) => {
18
- const { id, className, size = 'lg', children, ...restProps } = props
19
- const radioId = id || React.useId()
20
- const ctx = React.useContext(ControllerContext)
21
- if (ctx.isRequired) {
22
- restProps.required = true
23
- }
24
- if (ctx.groupName) {
25
- restProps.name = ctx.groupName
26
- }
27
-
28
- const styleInput = `
29
- peer
30
- sr-only
31
- `
17
+ export const Radio = (props: Radio.Props) => {
18
+ const { id, className, size = 'lg', children, ...restProps } = props
19
+ const genId = React.useId()
20
+ const radioId = id || genId
21
+ const ctx = React.useContext(ControllerContext)
22
+ if (ctx.isRequired) {
23
+ restProps.required = true
24
+ }
25
+ if (ctx.groupName) {
26
+ restProps.name = ctx.groupName
27
+ }
32
28
 
33
- const styleRadio = `
34
- bg-clip-content
35
- rounded-full
36
- border
37
- border-solid
38
- border-sumi-900
39
- peer-checked:bg-sea-600
40
- peer-checked:border-sea-600
41
- peer-disabled:border-sumi-500
42
- peer-focus-visible:ring-2
43
- peer-focus-visible:ring-offset-2
44
- peer-focus-visible:ring-wood-500
45
- `
29
+ const styleInput = `
30
+ peer
31
+ sr-only
32
+ `
46
33
 
47
- const radioSizes: { [key in InputSize]: string } = {
48
- lg: 'p-1',
49
- md: 'p-[3px]',
50
- sm: 'p-[3px]'
51
- }
34
+ const styleRadio = `
35
+ bg-clip-content
36
+ rounded-full
37
+ border
38
+ border-solid
39
+ border-solid-gray-900
40
+ peer-checked:bg-blue-600
41
+ peer-checked:border-blue-600
42
+ peer-disabled:border-solid-gray-500
43
+ ${Style.Peer.focusRect}
44
+ `
52
45
 
53
- return (
54
- <label
55
- htmlFor={radioId}
56
- className={cx(
57
- borderlessInputBaseStyles,
58
- borderlessInputSizeStyles[size],
59
- className
60
- )}
61
- >
62
- <span className="flex items-center">
63
- <input
64
- id={radioId}
65
- className={styleInput}
66
- type="radio"
67
- aria-describedby={ctx.helperTextId}
68
- aria-errormessage={ctx.errorMessageId}
69
- aria-invalid={ctx.isInvalid ?? false}
70
- aria-required={ctx.isRequired ?? false}
71
- {...restProps}
72
- ref={ref}
73
- />
74
- <span
75
- aria-hidden={true}
76
- className={cx(styleRadio, radioSizes[size], iconStyles[size])}
77
- />
78
- <span className="peer-disabled:text-sumi-500">{children}</span>
79
- </span>
80
- </label>
81
- )
46
+ const radioSizes: { [key in InputSize]: string } = {
47
+ lg: 'p-1',
48
+ md: 'p-[3px]',
49
+ sm: 'p-[3px]'
82
50
  }
83
- )
51
+
52
+ return (
53
+ <label
54
+ htmlFor={radioId}
55
+ className={cx(
56
+ borderlessInputBaseStyles,
57
+ borderlessInputSizeStyles[size],
58
+ className
59
+ )}
60
+ >
61
+ <span className="flex items-center">
62
+ <input
63
+ id={radioId}
64
+ className={styleInput}
65
+ type="radio"
66
+ aria-describedby={ctx.helperTextId}
67
+ aria-errormessage={ctx.errorMessageId}
68
+ aria-invalid={ctx.isInvalid ?? false}
69
+ aria-required={ctx.isRequired ?? false}
70
+ {...restProps}
71
+ />
72
+ <span
73
+ aria-hidden={true}
74
+ className={cx(styleRadio, radioSizes[size], iconStyles[size])}
75
+ />
76
+ <span className="peer-disabled:text-solid-gray-500">{children}</span>
77
+ </span>
78
+ </label>
79
+ )
80
+ }
84
81
 
85
82
  Radio.displayName = 'Radio'
@@ -1,5 +1,5 @@
1
- import React from 'react'
2
- import { cx } from '../utils/class'
1
+ import React, { type ComponentPropsWithRef } from 'react'
2
+ import { cx } from '@sakura-ui/helper'
3
3
  import { ControllerContext } from './context'
4
4
  import {
5
5
  type InputSize,
@@ -7,71 +7,71 @@ import {
7
7
  borderedInputSizeStyles
8
8
  } from './inputStyle'
9
9
 
10
- export interface SelectProps
11
- extends Omit<React.ComponentPropsWithRef<'select'>, 'size'> {
12
- size?: InputSize
10
+ export namespace Select {
11
+ export interface Props extends Omit<ComponentPropsWithRef<'select'>, 'size'> {
12
+ size?: InputSize
13
+ }
13
14
  }
14
15
 
15
- export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
16
- (props, ref) => {
17
- const { id, className, size = 'lg', children, ...restProps } = props
18
- const ctx = React.useContext(ControllerContext)
19
- if (ctx.isRequired) {
20
- restProps.required = true
21
- }
16
+ export const Select = (props: Select.Props) => {
17
+ const { id, className, size = 'lg', children, ...restProps } = props
18
+ const ctx = React.useContext(ControllerContext)
19
+ if (ctx.isRequired) {
20
+ restProps.required = true
21
+ }
22
22
 
23
- const style = `
24
- !pr-8
25
- peer
26
- cursor-pointer
27
- appearance-none
28
- `
23
+ const style = `
24
+ !pr-8
25
+ peer
26
+ cursor-pointer
27
+ appearance-none
28
+ `
29
29
 
30
- const styleArrow = `
31
- pointer-events-none
32
- absolute
33
- right-4
34
- top-1/2
35
- -translate-y-1/2
36
- text-sumi-900
37
- peer-disabled:text-sumi-500
38
- `
30
+ const styleArrow = `
31
+ pointer-events-none
32
+ absolute
33
+ right-4
34
+ top-1/2
35
+ -translate-y-1/2
36
+ text-solid-gray-900
37
+ peer-disabled:text-solid-gray-500
38
+ `
39
39
 
40
- return (
41
- <div className="inline-block relative">
42
- <select
43
- id={id || ctx.id}
44
- className={cx(
45
- style,
46
- borderedInputBaseStyles,
47
- borderedInputSizeStyles[size],
48
- props.className
49
- )}
50
- aria-describedby={ctx.helperTextId}
51
- aria-errormessage={ctx.errorMessageId}
52
- aria-invalid={ctx.isInvalid ?? false}
53
- aria-required={ctx.isRequired ?? false}
54
- {...restProps}
55
- ref={ref}
56
- >
57
- {children}
58
- </select>
59
- <svg
60
- xmlns="http://www.w3.org/2000/svg"
61
- aria-hidden={true}
62
- className={styleArrow}
63
- fill="none"
64
- width="16"
65
- height="16"
66
- viewBox="0 0 16 16"
67
- >
68
- <title>arrow down</title>
69
- <path
70
- d="M12 15.05 6.35 9.4 7.4 8.35l4.6 4.6 4.6-4.6 1.05 1.05Z"
71
- fill="currentColor"
72
- />
73
- </svg>
74
- </div>
75
- )
76
- }
77
- )
40
+ return (
41
+ <div className="inline-block relative">
42
+ <select
43
+ id={id || ctx.id}
44
+ className={cx(
45
+ style,
46
+ borderedInputBaseStyles,
47
+ borderedInputSizeStyles[size],
48
+ className
49
+ )}
50
+ aria-describedby={ctx.helperTextId}
51
+ aria-errormessage={ctx.errorMessageId}
52
+ aria-invalid={ctx.isInvalid ?? false}
53
+ aria-required={ctx.isRequired ?? false}
54
+ {...restProps}
55
+ >
56
+ {children}
57
+ </select>
58
+ <svg
59
+ xmlns="http://www.w3.org/2000/svg"
60
+ aria-hidden={true}
61
+ className={styleArrow}
62
+ fill="none"
63
+ width="16"
64
+ height="16"
65
+ viewBox="0 0 16 16"
66
+ >
67
+ <title>arrow down</title>
68
+ <path
69
+ d="M12 15.05 6.35 9.4 7.4 8.35l4.6 4.6 4.6-4.6 1.05 1.05Z"
70
+ fill="currentColor"
71
+ />
72
+ </svg>
73
+ </div>
74
+ )
75
+ }
76
+
77
+ Select.displayName = 'Select'
@@ -1,73 +1,68 @@
1
- import React from 'react'
2
- import { cx } from '../utils/class'
1
+ import React, { type ComponentPropsWithRef } from 'react'
2
+ import { cx, Style } from '@sakura-ui/helper'
3
3
  import { ControllerContext } from './context'
4
4
 
5
- export interface TextareaProps
6
- extends React.ComponentPropsWithRef<'textarea'> {}
5
+ export namespace Textarea {
6
+ export interface Props extends ComponentPropsWithRef<'textarea'> {}
7
+ }
7
8
 
8
- export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
9
- (props, ref) => {
10
- const { id, className, children, onChange, maxLength, ...restProps } = props
9
+ export const Textarea = (props: Textarea.Props) => {
10
+ const { id, className, children, onChange, maxLength, ...restProps } = props
11
11
 
12
- const [count, setCount] = React.useState(0)
12
+ const [count, setCount] = React.useState(0)
13
13
 
14
- const onChangeHandler = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
15
- if (onChange) onChange(e)
14
+ const onChangeHandler = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
15
+ if (onChange) onChange(e)
16
16
 
17
- setCount(e.target.value.length)
18
- }
17
+ setCount(e.target.value.length)
18
+ }
19
19
 
20
- const ctx = React.useContext(ControllerContext)
21
- if (ctx.isRequired) {
22
- restProps.required = true
23
- }
20
+ const ctx = React.useContext(ControllerContext)
21
+ if (ctx.isRequired) {
22
+ restProps.required = true
23
+ }
24
24
 
25
- const overtextStyle =
26
- count > (maxLength || 0) ? 'text-sun-800' : 'text-sumi-700'
25
+ const overtextStyle =
26
+ count > (maxLength || 0) ? 'text-red-800' : 'text-solid-gray-700'
27
27
 
28
- const style = `
28
+ const style = `
29
29
  p-4
30
30
  text-label
31
31
  rounded-lg
32
32
  border
33
33
  border-solid
34
- border-sumi-900
35
- outline-offset-2
36
- focus:outline
37
- focus:outline-2
38
- focus:outline-wood-500
34
+ border-solid-gray-900
39
35
  disabled:bg-transparent
40
- disabled:text-sumi-500
41
- disabled:border-sumi-500
42
- aria-invalid:border-sun-800
36
+ disabled:text-solid-gray-500
37
+ disabled:border-solid-gray-500
38
+ aria-invalid:border-red-800
39
+ ${Style.focusRect}
43
40
  `
44
41
 
45
- return (
46
- <>
47
- <textarea
48
- id={id || ctx.id}
49
- className={cx(style, className)}
50
- aria-describedby={ctx.helperTextId}
51
- aria-errormessage={ctx.errorMessageId}
52
- aria-invalid={ctx.isInvalid ?? false}
53
- aria-required={ctx.isRequired ?? false}
54
- onChange={onChangeHandler}
55
- {...restProps}
56
- ref={ref}
57
- >
58
- {children}
59
- </textarea>
60
- {maxLength ? (
61
- <p className="text-label text-sumi-700">
62
- <span className={overtextStyle}>{count}</span>/
63
- <span>{maxLength}</span>
64
- </p>
65
- ) : (
66
- ''
67
- )}
68
- </>
69
- )
70
- }
71
- )
42
+ return (
43
+ <>
44
+ <textarea
45
+ id={id || ctx.id}
46
+ className={cx(style, className)}
47
+ aria-describedby={ctx.helperTextId}
48
+ aria-errormessage={ctx.errorMessageId}
49
+ aria-invalid={ctx.isInvalid ?? false}
50
+ aria-required={ctx.isRequired ?? false}
51
+ onChange={onChangeHandler}
52
+ {...restProps}
53
+ >
54
+ {children}
55
+ </textarea>
56
+ {maxLength ? (
57
+ <p className="text-label text-solid-gray-700">
58
+ <span className={overtextStyle}>{count}</span>/
59
+ <span>{maxLength}</span>
60
+ </p>
61
+ ) : (
62
+ ''
63
+ )}
64
+ </>
65
+ )
66
+ }
72
67
 
73
68
  Textarea.displayName = 'Textarea'
@@ -1,25 +1,24 @@
1
- import React from 'react'
1
+ import React, { type ComponentPropsWithRef } from 'react'
2
2
  import { Checkbox } from '../Checkbox'
3
3
  import { FieldsetControl } from '../FieldsetControl'
4
4
  import type { InputItem } from './InputItem'
5
5
  import type { InputSize } from '../inputStyle'
6
6
 
7
- export interface CheckboxGroupProps
8
- extends Omit<React.ComponentPropsWithRef<'fieldset'>, 'onChange'> {
9
- items: InputItem[]
10
- onChange: React.ChangeEventHandler<HTMLInputElement>
11
- labelText: string
12
- helperText?: string
13
- errorMessage?: string
14
- isInvalid?: boolean
15
- isRequired?: boolean
16
- size?: InputSize
7
+ export namespace CheckboxGroup {
8
+ export interface Props
9
+ extends Omit<ComponentPropsWithRef<'fieldset'>, 'onChange'> {
10
+ items: InputItem[]
11
+ onChange: React.ChangeEventHandler<HTMLInputElement>
12
+ labelText: string
13
+ helperText?: string
14
+ errorMessage?: string
15
+ isInvalid?: boolean
16
+ isRequired?: boolean
17
+ size?: InputSize
18
+ }
17
19
  }
18
20
 
19
- export const CheckboxGroup = React.forwardRef<
20
- HTMLFieldSetElement,
21
- CheckboxGroupProps
22
- >((props, ref) => {
21
+ export const CheckboxGroup = (props: CheckboxGroup.Props) => {
23
22
  const {
24
23
  items,
25
24
  onChange,
@@ -41,7 +40,6 @@ export const CheckboxGroup = React.forwardRef<
41
40
  errorMessage={errorMessage}
42
41
  isInvalid={isInvalid}
43
42
  isRequired={isRequired}
44
- ref={ref}
45
43
  {...restProps}
46
44
  >
47
45
  {items.map(({ label, value }) => {
@@ -58,6 +56,6 @@ export const CheckboxGroup = React.forwardRef<
58
56
  })}
59
57
  </FieldsetControl>
60
58
  )
61
- })
59
+ }
62
60
 
63
61
  CheckboxGroup.displayName = 'CheckboxGroup'
@@ -1,26 +1,25 @@
1
- import React from 'react'
1
+ import React, { type ComponentPropsWithRef } from 'react'
2
2
  import { Radio } from '../Radio'
3
3
  import { FieldsetControl } from '../FieldsetControl'
4
4
  import type { InputItem } from './InputItem'
5
5
  import type { InputSize } from '../inputStyle'
6
6
 
7
- export interface RadioGroupProps
8
- extends Omit<React.ComponentPropsWithRef<'fieldset'>, 'onChange'> {
9
- items: InputItem[]
10
- onChange: React.ChangeEventHandler<HTMLInputElement>
11
- labelText: string
12
- helperText?: string
13
- errorMessage?: string
14
- isInvalid?: boolean
15
- isRequired?: boolean
16
- defaultValue?: string
17
- size?: InputSize
7
+ export namespace RadioGroup {
8
+ export interface Props
9
+ extends Omit<ComponentPropsWithRef<'fieldset'>, 'onChange'> {
10
+ items: InputItem[]
11
+ onChange: React.ChangeEventHandler<HTMLInputElement>
12
+ labelText: string
13
+ helperText?: string
14
+ errorMessage?: string
15
+ isInvalid?: boolean
16
+ isRequired?: boolean
17
+ defaultValue?: string
18
+ size?: InputSize
19
+ }
18
20
  }
19
21
 
20
- export const RadioGroup = React.forwardRef<
21
- HTMLFieldSetElement,
22
- RadioGroupProps
23
- >((props, ref) => {
22
+ export const RadioGroup = (props: RadioGroup.Props) => {
24
23
  const {
25
24
  items,
26
25
  onChange,
@@ -43,7 +42,6 @@ export const RadioGroup = React.forwardRef<
43
42
  errorMessage={errorMessage}
44
43
  isInvalid={isInvalid}
45
44
  isRequired={isRequired}
46
- ref={ref}
47
45
  {...restProps}
48
46
  >
49
47
  {items.map(({ label, value }) => {
@@ -61,6 +59,6 @@ export const RadioGroup = React.forwardRef<
61
59
  })}
62
60
  </FieldsetControl>
63
61
  )
64
- })
62
+ }
65
63
 
66
64
  RadioGroup.displayName = 'RadioGroup'
@@ -1,8 +1,8 @@
1
- export { Checkbox, type CheckboxProps } from './Checkbox'
2
- export { Radio, type RadioProps } from './Radio'
3
- export { Select, type SelectProps } from './Select'
4
- export { FileInput, type FileInputProps } from './FileInput'
5
- export { Input, type InputProps } from './Input'
6
- export { Textarea, type TextareaProps } from './Textarea'
7
- export { LabelControl, type LabelControlProps } from './LabelControl'
8
- export { FieldsetControl, type FieldsetControlProps } from './FieldsetControl'
1
+ export { Checkbox } from './Checkbox'
2
+ export { Radio } from './Radio'
3
+ export { Select } from './Select'
4
+ export { FileInput } from './FileInput'
5
+ export { Input } from './Input'
6
+ export { Textarea } from './Textarea'
7
+ export { LabelControl } from './LabelControl'
8
+ export { FieldsetControl } from './FieldsetControl'
@@ -1,18 +1,17 @@
1
+ import { Style } from '@sakura-ui/helper'
2
+
1
3
  export type InputSize = 'lg' | 'md' | 'sm'
2
4
 
3
5
  export const borderedInputBaseStyles = `
4
6
  bg-white
5
7
  border
6
8
  border-solid
7
- border-sumi-900
8
- outline-offset-2
9
- focus:outline
10
- focus:outline-2
11
- focus:outline-wood-500
9
+ border-solid-gray-900
12
10
  disabled:bg-transparent
13
- disabled:text-sumi-500
14
- disabled:border-sumi-500
15
- aria-invalid:border-sun-800
11
+ disabled:text-solid-gray-500
12
+ disabled:border-solid-gray-500
13
+ aria-invalid:border-red-800
14
+ ${Style.focusRect}
16
15
  `
17
16
 
18
17
  // for text input and select
@@ -9,15 +9,4 @@ export {
9
9
  FieldsetControl
10
10
  } from './components'
11
11
 
12
- export type {
13
- CheckboxProps,
14
- RadioProps,
15
- SelectProps,
16
- FileInputProps,
17
- InputProps,
18
- TextareaProps,
19
- LabelControlProps,
20
- FieldsetControlProps
21
- } from './components'
22
-
23
12
  export { CheckboxGroup, RadioGroup } from './components/controlled'
@@ -0,0 +1,44 @@
1
+ import React from 'react'
2
+ import { describe, it, expect, vi } from 'vitest'
3
+ import { render, screen } from '@testing-library/react'
4
+
5
+ import { Checkbox } from '../src'
6
+
7
+ describe('Checkbox', () => {
8
+ it('should render a checkbox with a label text', async () => {
9
+ render(<Checkbox>test</Checkbox>)
10
+
11
+ const checkbox = screen.getByRole('checkbox')
12
+
13
+ expect(checkbox).toBeInTheDocument()
14
+
15
+ expect(screen.getByText('test')).toBeInTheDocument()
16
+ })
17
+
18
+ it('should render two checkbox with verify checked states', async () => {
19
+ render(
20
+ <>
21
+ <Checkbox id="test" value="test1" data-testid="checked" checked />
22
+ <Checkbox id="test" value="test2" data-testid="not_checked" />
23
+ </>
24
+ )
25
+
26
+ const checked = screen.getByTestId('checked')
27
+
28
+ expect(checked).toBeInTheDocument()
29
+ expect(checked).toBeChecked()
30
+
31
+ const notChecked = screen.getByTestId('not_checked')
32
+
33
+ expect(notChecked).toBeInTheDocument()
34
+ expect(notChecked).not.toBeChecked()
35
+ })
36
+
37
+ it('should pass an object to the ref property', async () => {
38
+ const ref = vi.fn()
39
+
40
+ render(<Checkbox ref={ref}>test</Checkbox>)
41
+
42
+ expect(ref).toHaveBeenCalledTimes(1)
43
+ })
44
+ })