@fpkit/acss 5.0.0 → 6.1.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 (172) hide show
  1. package/libs/{chunk-DIJBIOFE.js → chunk-2ZJV6KQ3.js} +3 -3
  2. package/libs/{chunk-LXODKKA3.cjs → chunk-3D6WUYSL.cjs} +4 -4
  3. package/libs/{chunk-2JCDEC32.js → chunk-3ENBUQIB.js} +3 -3
  4. package/libs/{chunk-NCGVF2QS.cjs → chunk-3RVZZZWX.cjs} +4 -4
  5. package/libs/{chunk-M7JLT62Q.js → chunk-4F6SI5V5.js} +2 -2
  6. package/libs/chunk-4KJP3L35.js +7 -0
  7. package/libs/chunk-4KJP3L35.js.map +1 -0
  8. package/libs/chunk-66C2J4IX.cjs +13 -0
  9. package/libs/chunk-66C2J4IX.cjs.map +1 -0
  10. package/libs/{chunk-3XJC4XUG.js → chunk-6ADHES7B.js} +2 -2
  11. package/libs/{chunk-AOFQDQVS.cjs → chunk-6WMLG4O5.cjs} +3 -3
  12. package/libs/{chunk-Q7OAQLUT.js → chunk-AQAI6COH.js} +2 -2
  13. package/libs/{chunk-6BUJZ4DJ.cjs → chunk-BVPUT2PP.cjs} +3 -3
  14. package/libs/{chunk-F64GE6RG.cjs → chunk-GVVCXXKI.cjs} +4 -4
  15. package/libs/{chunk-75YQDONV.cjs → chunk-H4JRUNKU.cjs} +6 -6
  16. package/libs/{chunk-G3TFKMWB.js → chunk-H6A2CUWA.js} +5 -5
  17. package/libs/{chunk-2GJHKWEK.cjs → chunk-LQPWXSCK.cjs} +3 -3
  18. package/libs/{chunk-IBUTNPTQ.js → chunk-M5ES7OWP.js} +2 -2
  19. package/libs/{chunk-AWZLSWDO.js → chunk-MAG46S3P.js} +2 -2
  20. package/libs/{chunk-KAR3HDXK.js → chunk-MJJKNHVH.js} +2 -2
  21. package/libs/{chunk-5CJPTDK3.cjs → chunk-OZM455LO.cjs} +3 -3
  22. package/libs/{chunk-NPWHQVYB.cjs → chunk-QU5AQQ4S.cjs} +3 -3
  23. package/libs/{chunk-U5VA34SU.js → chunk-RQSMWB3J.js} +2 -2
  24. package/libs/{chunk-5QSNJQVH.cjs → chunk-S7NIA6PI.cjs} +3 -3
  25. package/libs/{chunk-MBWI67UT.js → chunk-SPESKPUA.js} +2 -2
  26. package/libs/{chunk-PMWL5XZ4.js → chunk-SQ44OCJ2.js} +3 -3
  27. package/libs/{chunk-EKJYOCLY.cjs → chunk-VISQ434C.cjs} +3 -3
  28. package/libs/{chunk-AFINOD2L.cjs → chunk-VN2CVD4H.cjs} +3 -3
  29. package/libs/{chunk-M5JARVJD.cjs → chunk-WTWGTWVI.cjs} +3 -3
  30. package/libs/{chunk-TF3GQKOY.js → chunk-X2RDXWH5.js} +2 -2
  31. package/libs/components/breadcrumbs/breadcrumb.cjs +6 -6
  32. package/libs/components/breadcrumbs/breadcrumb.d.cts +1 -1
  33. package/libs/components/breadcrumbs/breadcrumb.d.ts +1 -1
  34. package/libs/components/breadcrumbs/breadcrumb.js +3 -3
  35. package/libs/components/button.cjs +4 -4
  36. package/libs/components/button.d.cts +1 -1
  37. package/libs/components/button.d.ts +1 -1
  38. package/libs/components/button.js +2 -2
  39. package/libs/components/card.cjs +7 -7
  40. package/libs/components/card.d.cts +1 -1
  41. package/libs/components/card.d.ts +1 -1
  42. package/libs/components/card.js +2 -2
  43. package/libs/components/dialog/dialog.cjs +7 -7
  44. package/libs/components/dialog/dialog.js +5 -5
  45. package/libs/components/form/checkbox.css +1 -1
  46. package/libs/components/form/checkbox.css.map +1 -1
  47. package/libs/components/form/checkbox.min.css +2 -2
  48. package/libs/components/form/fields.cjs +4 -4
  49. package/libs/components/form/fields.d.cts +1 -1
  50. package/libs/components/form/fields.d.ts +1 -1
  51. package/libs/components/form/fields.js +2 -2
  52. package/libs/components/form/form.css +1 -1
  53. package/libs/components/form/form.css.map +1 -1
  54. package/libs/components/form/form.min.css +2 -2
  55. package/libs/components/form/select.css +1 -0
  56. package/libs/components/form/select.css.map +1 -0
  57. package/libs/components/form/select.min.css +3 -0
  58. package/libs/components/form/textarea.cjs +4 -4
  59. package/libs/components/form/textarea.js +2 -2
  60. package/libs/components/heading/heading.cjs +3 -3
  61. package/libs/components/heading/heading.d.cts +2 -2
  62. package/libs/components/heading/heading.d.ts +2 -2
  63. package/libs/components/heading/heading.js +2 -2
  64. package/libs/components/icons/icon.cjs +4 -4
  65. package/libs/components/icons/icon.d.cts +2 -2
  66. package/libs/components/icons/icon.d.ts +2 -2
  67. package/libs/components/icons/icon.js +2 -2
  68. package/libs/components/link/link.cjs +6 -6
  69. package/libs/components/link/link.js +2 -2
  70. package/libs/components/list/list.cjs +5 -5
  71. package/libs/components/list/list.d.cts +2 -2
  72. package/libs/components/list/list.d.ts +2 -2
  73. package/libs/components/list/list.js +2 -2
  74. package/libs/components/modal.cjs +4 -4
  75. package/libs/components/modal.js +3 -3
  76. package/libs/components/nav/nav.cjs +7 -7
  77. package/libs/components/nav/nav.d.cts +2 -2
  78. package/libs/components/nav/nav.d.ts +2 -2
  79. package/libs/components/nav/nav.js +3 -3
  80. package/libs/components/text/text.cjs +5 -5
  81. package/libs/components/text/text.d.cts +1 -1
  82. package/libs/components/text/text.d.ts +1 -1
  83. package/libs/components/text/text.js +2 -2
  84. package/libs/{heading-81eef89a.d.ts → heading-064675b6.d.ts} +1 -1
  85. package/libs/hooks.cjs +4 -4
  86. package/libs/hooks.d.cts +1 -1
  87. package/libs/hooks.d.ts +1 -1
  88. package/libs/hooks.js +3 -3
  89. package/libs/{icons-df8e744f.d.ts → icons-48788561.d.ts} +1 -1
  90. package/libs/icons.cjs +3 -3
  91. package/libs/icons.d.cts +2 -2
  92. package/libs/icons.d.ts +2 -2
  93. package/libs/icons.js +2 -2
  94. package/libs/index.cjs +49 -49
  95. package/libs/index.cjs.map +1 -1
  96. package/libs/index.css +1 -1
  97. package/libs/index.css.map +1 -1
  98. package/libs/index.d.cts +74 -25
  99. package/libs/index.d.ts +74 -25
  100. package/libs/index.js +21 -21
  101. package/libs/index.js.map +1 -1
  102. package/libs/{list.types-d26de310.d.ts → list.types-bf2c44c1.d.ts} +1 -1
  103. package/libs/{ui-d01b50d4.d.ts → ui-993fc2e2.d.ts} +5 -2
  104. package/package.json +4 -7
  105. package/src/components/alert/alert.stories.tsx +1 -1
  106. package/src/components/alert/elements/dismiss-button.stories.tsx +1 -2
  107. package/src/components/badge/badge.stories.tsx +1 -1
  108. package/src/components/breadcrumbs/breadcrumb.stories.tsx +1 -2
  109. package/src/components/buttons/button.stories.tsx +1 -3
  110. package/src/components/cards/card.stories.tsx +1 -1
  111. package/src/components/cards/card.test.tsx +1 -1
  112. package/src/components/details/details.stories.tsx +1 -2
  113. package/src/components/dialog/dialog-modal.stories.tsx +1 -2
  114. package/src/components/dialog/dialog.stories.tsx +1 -1
  115. package/src/components/dialog/views/dialog-header.stories.tsx +1 -2
  116. package/src/components/form/CHECKBOX-STYLES.mdx +766 -0
  117. package/src/components/form/CHECKBOX.mdx +665 -0
  118. package/src/components/form/checkbox.scss +28 -0
  119. package/src/components/form/checkbox.tsx +72 -22
  120. package/src/components/form/form.scss +11 -14
  121. package/src/components/form/form.stories.tsx +1 -1
  122. package/src/components/form/input.stories.tsx +72 -23
  123. package/src/components/form/select.scss +97 -0
  124. package/src/components/form/select.stories.tsx +225 -9
  125. package/src/components/form/select.test.tsx +541 -0
  126. package/src/components/form/select.tsx +133 -16
  127. package/src/components/heading/heading.stories.tsx +1 -2
  128. package/src/components/images/figure.stories.tsx +1 -2
  129. package/src/components/images/img.stories.tsx +1 -1
  130. package/src/components/nav/nav.stories.tsx +1 -2
  131. package/src/components/text/text.stories.tsx +1 -1
  132. package/src/components/text-to-speech/TextToSpeech.stories.tsx +1 -1
  133. package/src/components/title/title.stories.tsx +1 -2
  134. package/src/components/ui.tsx +11 -4
  135. package/src/styles/form/checkbox.css +19 -0
  136. package/src/styles/form/checkbox.css.map +1 -1
  137. package/src/styles/form/form.css +100 -14
  138. package/src/styles/form/form.css.map +1 -1
  139. package/src/styles/form/select.css +75 -0
  140. package/src/styles/form/select.css.map +1 -0
  141. package/src/styles/index.css +100 -14
  142. package/src/styles/index.css.map +1 -1
  143. package/libs/chunk-DDSXKOUB.js +0 -7
  144. package/libs/chunk-DDSXKOUB.js.map +0 -1
  145. package/libs/chunk-EJ6KYBFE.cjs +0 -13
  146. package/libs/chunk-EJ6KYBFE.cjs.map +0 -1
  147. /package/libs/{chunk-DIJBIOFE.js.map → chunk-2ZJV6KQ3.js.map} +0 -0
  148. /package/libs/{chunk-LXODKKA3.cjs.map → chunk-3D6WUYSL.cjs.map} +0 -0
  149. /package/libs/{chunk-2JCDEC32.js.map → chunk-3ENBUQIB.js.map} +0 -0
  150. /package/libs/{chunk-NCGVF2QS.cjs.map → chunk-3RVZZZWX.cjs.map} +0 -0
  151. /package/libs/{chunk-M7JLT62Q.js.map → chunk-4F6SI5V5.js.map} +0 -0
  152. /package/libs/{chunk-3XJC4XUG.js.map → chunk-6ADHES7B.js.map} +0 -0
  153. /package/libs/{chunk-AOFQDQVS.cjs.map → chunk-6WMLG4O5.cjs.map} +0 -0
  154. /package/libs/{chunk-Q7OAQLUT.js.map → chunk-AQAI6COH.js.map} +0 -0
  155. /package/libs/{chunk-6BUJZ4DJ.cjs.map → chunk-BVPUT2PP.cjs.map} +0 -0
  156. /package/libs/{chunk-F64GE6RG.cjs.map → chunk-GVVCXXKI.cjs.map} +0 -0
  157. /package/libs/{chunk-75YQDONV.cjs.map → chunk-H4JRUNKU.cjs.map} +0 -0
  158. /package/libs/{chunk-G3TFKMWB.js.map → chunk-H6A2CUWA.js.map} +0 -0
  159. /package/libs/{chunk-2GJHKWEK.cjs.map → chunk-LQPWXSCK.cjs.map} +0 -0
  160. /package/libs/{chunk-IBUTNPTQ.js.map → chunk-M5ES7OWP.js.map} +0 -0
  161. /package/libs/{chunk-AWZLSWDO.js.map → chunk-MAG46S3P.js.map} +0 -0
  162. /package/libs/{chunk-KAR3HDXK.js.map → chunk-MJJKNHVH.js.map} +0 -0
  163. /package/libs/{chunk-5CJPTDK3.cjs.map → chunk-OZM455LO.cjs.map} +0 -0
  164. /package/libs/{chunk-NPWHQVYB.cjs.map → chunk-QU5AQQ4S.cjs.map} +0 -0
  165. /package/libs/{chunk-U5VA34SU.js.map → chunk-RQSMWB3J.js.map} +0 -0
  166. /package/libs/{chunk-5QSNJQVH.cjs.map → chunk-S7NIA6PI.cjs.map} +0 -0
  167. /package/libs/{chunk-MBWI67UT.js.map → chunk-SPESKPUA.js.map} +0 -0
  168. /package/libs/{chunk-PMWL5XZ4.js.map → chunk-SQ44OCJ2.js.map} +0 -0
  169. /package/libs/{chunk-EKJYOCLY.cjs.map → chunk-VISQ434C.cjs.map} +0 -0
  170. /package/libs/{chunk-AFINOD2L.cjs.map → chunk-VN2CVD4H.cjs.map} +0 -0
  171. /package/libs/{chunk-M5JARVJD.cjs.map → chunk-WTWGTWVI.cjs.map} +0 -0
  172. /package/libs/{chunk-TF3GQKOY.js.map → chunk-X2RDXWH5.js.map} +0 -0
@@ -5,30 +5,142 @@ import { useDisabledState } from '../../hooks/use-disabled-state'
5
5
  export type { SelectProps } from './form.types'
6
6
  import type { SelectProps } from './form.types'
7
7
 
8
- export type SelectOptionsProps = {
8
+ /**
9
+ * Option component props interface
10
+ * Extends native HTML option props with fpkit component conventions
11
+ *
12
+ * @interface OptionProps
13
+ */
14
+ export interface OptionProps extends Omit<React.ComponentPropsWithoutRef<'option'>, 'className'> {
15
+ /**
16
+ * Value for the select option (required, unless using legacy selectValue)
17
+ */
18
+ value?: string | number
19
+
20
+ /**
21
+ * Display label for the option (defaults to value if not provided)
22
+ */
23
+ label?: string
24
+
25
+ /**
26
+ * CSS class names (preferred over 'className' for consistency with fpkit components)
27
+ */
28
+ classes?: string
29
+
30
+ /**
31
+ * Inline CSS styles object
32
+ */
33
+ styles?: React.CSSProperties
34
+
9
35
  /**
10
- * Label for the select option
36
+ * Disabled state for the option
37
+ * @default false
11
38
  */
12
- selectLabel: string
39
+ disabled?: boolean
13
40
 
14
41
  /**
15
- * Value for the select option. Can be a number or string.
42
+ * Children content (overrides label if provided)
16
43
  */
17
- selectValue: string
44
+ children?: React.ReactNode
45
+
46
+ /**
47
+ * Visual variant for styling via data-option attribute
48
+ * Use with CSS: option[data-option="primary"] { ... }
49
+ * @example 'primary' | 'secondary' | 'success' | 'error'
50
+ */
51
+ variant?: string
52
+
53
+ /**
54
+ * Size variant for styling via data-size attribute
55
+ * @example 'sm' | 'md' | 'lg'
56
+ */
57
+ size?: string
58
+
59
+ /**
60
+ * Additional data attributes for custom styling
61
+ * @example { 'data-highlighted': true, 'data-category': 'premium' }
62
+ */
63
+ dataAttributes?: Record<string, string | boolean | number>
18
64
  }
19
65
 
20
66
  /**
21
- * Option component for select.
22
- * @param {SelectOptionsProps} param0 - The component props.
23
- * @param {string} param0.selectValue - Value for the option.
24
- * @param {string} [param0.selectLabel] - Label for the option.
67
+ * Option component - Select dropdown option element
68
+ *
69
+ * A component for creating accessible option elements within Select components.
70
+ * Follows fpkit component conventions with support for ref forwarding, custom styling,
71
+ * and consistent prop naming.
72
+ *
73
+ * @component
74
+ * @example
75
+ * // Basic option
76
+ * <Select.Option value="us" label="United States" />
77
+ *
78
+ * @example
79
+ * // Option with children
80
+ * <Select.Option value="uk">
81
+ * United Kingdom
82
+ * </Select.Option>
83
+ *
84
+ * @example
85
+ * // Disabled option
86
+ * <Select.Option value="disabled" label="Not Available" disabled />
87
+ *
88
+ * @param {OptionProps} props - Component props
89
+ * @returns {JSX.Element} Option element
25
90
  */
26
- export const Option = ({ selectValue, selectLabel }: SelectOptionsProps) => {
27
- return (
28
- <option value={selectValue}>
29
- {selectLabel || selectValue}
30
- </option>
31
- )
91
+ export const Option = React.forwardRef<HTMLOptionElement, OptionProps & Partial<SelectOptionsProps>>(
92
+ (
93
+ {
94
+ value,
95
+ label,
96
+ classes,
97
+ styles,
98
+ disabled,
99
+ children,
100
+ variant,
101
+ size,
102
+ dataAttributes,
103
+ // Legacy props (backwards compatibility)
104
+ selectValue,
105
+ selectLabel,
106
+ ...props
107
+ },
108
+ ref
109
+ ) => {
110
+ // Map legacy props to new props
111
+ const optionValue = value ?? selectValue
112
+ const optionLabel = label ?? selectLabel
113
+
114
+ // Build data attributes object for styling
115
+ const combinedDataAttrs = {
116
+ ...(variant && { 'data-option': variant }),
117
+ ...(size && { 'data-size': size }),
118
+ ...dataAttributes,
119
+ }
120
+
121
+ return (
122
+ <UI
123
+ as="option"
124
+ ref={ref}
125
+ value={optionValue}
126
+ className={classes}
127
+ style={styles}
128
+ disabled={disabled}
129
+ {...combinedDataAttrs}
130
+ {...props}
131
+ >
132
+ {children || optionLabel || optionValue}
133
+ </UI>
134
+ )
135
+ }
136
+ )
137
+
138
+ Option.displayName = 'Select.Option'
139
+
140
+ // Legacy type export for backwards compatibility
141
+ export type SelectOptionsProps = Omit<OptionProps, 'classes' | 'styles'> & {
142
+ selectValue: string | number
143
+ selectLabel?: string
32
144
  }
33
145
 
34
146
  /**
@@ -151,8 +263,13 @@ export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
151
263
 
152
264
  Select.displayName = 'Select'
153
265
 
266
+ // Create a compound component with proper typing
267
+ type SelectComponent = typeof Select & {
268
+ Option: typeof Option
269
+ }
270
+
154
271
  // Type assertion to allow adding static property to ForwardRefExoticComponent
155
272
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
156
273
  ;(Select as any).Option = Option
157
274
 
158
- export default Select
275
+ export default Select as SelectComponent
@@ -7,11 +7,10 @@ import Heading from "./heading";
7
7
  * @deprecated This component is deprecated. Use Title component instead.
8
8
  */
9
9
  const meta: Meta<typeof Heading> = {
10
- title: "FP.REACT Components/Heading (Deprecated)",
10
+ title: "FP.React Components/Heading (Deprecated)",
11
11
  component: Heading,
12
12
  tags: ["version:1.0.0", "deprecated"],
13
13
  parameters: {
14
- actions: { argTypesRegex: "^on.*" },
15
14
  docs: {
16
15
  description: {
17
16
  component: `
@@ -4,11 +4,10 @@ import { within, expect } from "storybook/test";
4
4
  import Figure from "./figure";
5
5
 
6
6
  const meta: Meta<typeof Figure> = {
7
- title: "FP.REACT Components/Figure",
7
+ title: "FP.React Components/Figure",
8
8
  component: Figure,
9
9
  tags: ["version:1.0.0"],
10
10
  parameters: {
11
- actions: { argTypesRegex: "^on.*" },
12
11
  docs: {
13
12
  description: {
14
13
  component: `A semantic figure component for displaying images with captions, using CSS custom properties for flexible styling.
@@ -4,7 +4,7 @@ import { within, expect } from 'storybook/test'
4
4
  import Img from './img'
5
5
 
6
6
  const meta: Meta<typeof Img> = {
7
- title: 'FP.REACT Components/Img',
7
+ title: 'FP.React Components/Img',
8
8
  component: Img,
9
9
  tags: ['version:2.0.0', 'accessibility', 'responsive'],
10
10
  argTypes: {
@@ -8,11 +8,10 @@ import Link from "../link/link";
8
8
  import Button from "../buttons/button";
9
9
 
10
10
  const meta: Meta<typeof Nav> = {
11
- title: "FP.REACT Components/Nav",
11
+ title: "FP.React Components/Nav",
12
12
  component: Nav,
13
13
  tags: ["stable"],
14
14
  parameters: {
15
- actions: { argTypesRegex: "^on.*" },
16
15
  docs: {
17
16
  description: {
18
17
  component: `Navigation component with accessible markup and customizable styling via CSS variables.
@@ -4,7 +4,7 @@ import { within, expect } from "storybook/test";
4
4
  import Text from "./text";
5
5
 
6
6
  const meta: Meta<typeof Text> = {
7
- title: "FP.REACT Components/Text",
7
+ title: "FP.React Components/Text",
8
8
  component: Text,
9
9
  tags: ["version:1.0.0"],
10
10
  args: {
@@ -3,7 +3,7 @@ import TextToSpeech from "./TextToSpeech";
3
3
  import "./text-to-speech.scss";
4
4
 
5
5
  const meta: Meta<typeof TextToSpeech> = {
6
- title: "FP.REACT Components/TextToSpeech",
6
+ title: "FP.React Components/TextToSpeech",
7
7
  component: TextToSpeech,
8
8
  tags: ["experimental"],
9
9
  argTypes: {
@@ -4,11 +4,10 @@ import { within, expect } from "storybook/test";
4
4
  import Title from "./title";
5
5
 
6
6
  const meta: Meta<typeof Title> = {
7
- title: "FP.REACT Components/Title",
7
+ title: "FP.React Components/Title",
8
8
  component: Title,
9
9
  tags: ["version:2.0.0", "autodocs"],
10
10
  parameters: {
11
- actions: { argTypesRegex: "^on.*" },
12
11
  docs: {
13
12
  description: {
14
13
  component: `
@@ -117,7 +117,8 @@ type PolymorphicComponentPropWithRef<
117
117
  * Styles are always rendered regardless of this prop value.
118
118
  * @property {React.CSSProperties} [styles] - Inline styles to apply (overrides defaultStyles)
119
119
  * @property {React.CSSProperties} [defaultStyles] - Base styles that can be overridden by styles prop
120
- * @property {string} [classes] - CSS class names to apply to the element
120
+ * @property {string} [classes] - CSS class names to apply to the element (custom prop)
121
+ * @property {string} [className] - CSS class names to apply to the element (React standard prop)
121
122
  * @property {string} [id] - HTML id attribute
122
123
  * @property {React.ReactNode} [children] - Child elements to render
123
124
  *
@@ -137,6 +138,7 @@ type UIProps<C extends React.ElementType> = PolymorphicComponentPropWithRef<
137
138
  styles?: React.CSSProperties;
138
139
  defaultStyles?: React.CSSProperties;
139
140
  classes?: string;
141
+ className?: string;
140
142
  id?: string;
141
143
  children?: React.ReactNode;
142
144
  }
@@ -187,7 +189,8 @@ type UIComponent = (<C extends React.ElementType = "div">(
187
189
  *
188
190
  * @param {C} [as='div'] - The HTML element type to render. Defaults to 'div'.
189
191
  * @param {React.CSSProperties} [styles] - Inline styles to apply. Overrides defaultStyles.
190
- * @param {string} [classes] - CSS class names to apply to the element.
192
+ * @param {string} [classes] - CSS class names to apply (custom prop). Takes precedence over className.
193
+ * @param {string} [className] - CSS class names to apply (React standard). Used if classes is not provided.
191
194
  * @param {React.CSSProperties} [defaultStyles] - Base styles that can be overridden by styles prop.
192
195
  * @param {React.ReactNode} [children] - Child elements to render inside the component.
193
196
  * @param {PolymorphicRef<C>} [ref] - Forwarded ref with proper typing for the element type.
@@ -307,15 +310,19 @@ type UIComponent = (<C extends React.ElementType = "div">(
307
310
  */
308
311
  const UI: UIComponent = React.forwardRef(
309
312
  <C extends React.ElementType>(
310
- { as, styles, style, classes, children, defaultStyles, ...props }: UIProps<C>,
313
+ { as, styles, style, classes, className, children, defaultStyles, ...props }: UIProps<C>,
311
314
  ref?: PolymorphicRef<C>
312
315
  ) => {
313
316
  const Component = as ?? "div";
314
317
 
315
318
  const styleObj: React.CSSProperties = { ...defaultStyles, ...styles, ...style };
316
319
 
320
+ // Support both 'classes' (custom) and 'className' (React standard)
321
+ // 'classes' takes precedence if both are provided
322
+ const classNameValue = classes ?? className;
323
+
317
324
  return (
318
- <Component {...props} ref={ref} style={styleObj} className={classes}>
325
+ <Component {...props} ref={ref} style={styleObj} className={classNameValue}>
319
326
  {children}
320
327
  </Component>
321
328
  );
@@ -32,6 +32,9 @@ div:has(> input[type=checkbox]) {
32
32
  align-items: center;
33
33
  gap: var(--checkbox-gap, 0.5rem);
34
34
  position: relative;
35
+ /* ==========================================================================
36
+ Size Variants - Applied via data-checkbox-size attribute
37
+ ========================================================================== */
35
38
  }
36
39
  div:has(> input[type=checkbox]) > input[type=checkbox] {
37
40
  flex-shrink: 0;
@@ -59,6 +62,22 @@ div:has(> input[type=checkbox]):has(> input[aria-invalid=true]) .checkbox-label
59
62
  div:has(> input[type=checkbox]):has(> input[aria-invalid=false]:checked) label[for] {
60
63
  color: var(--checkbox-valid-label-color, currentColor);
61
64
  }
65
+ div:has(> input[type=checkbox])[data-checkbox-size~=xs] {
66
+ --checkbox-size: var(--checkbox-size-xs);
67
+ --checkbox-gap: var(--checkbox-gap-xs, 0.375rem);
68
+ }
69
+ div:has(> input[type=checkbox])[data-checkbox-size~=sm] {
70
+ --checkbox-size: var(--checkbox-size-sm);
71
+ --checkbox-gap: var(--checkbox-gap-sm, 0.5rem);
72
+ }
73
+ div:has(> input[type=checkbox])[data-checkbox-size~=md] {
74
+ --checkbox-size: var(--checkbox-size-md);
75
+ --checkbox-gap: var(--checkbox-gap-md, 0.5rem);
76
+ }
77
+ div:has(> input[type=checkbox])[data-checkbox-size~=lg] {
78
+ --checkbox-size: var(--checkbox-size-lg);
79
+ --checkbox-gap: var(--checkbox-gap-lg, 0.625rem);
80
+ }
62
81
 
63
82
  .checkbox-label {
64
83
  cursor: pointer;
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../components/form/checkbox.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+BA;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAKA;EACE;;AAOF;EACE;EAEA;EACA;;AAMJ;EACE;EACA;;AAEA;EACE;EACA;;AAOF;EACE;;AAMF;EACE;;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EAXF;IAYI;;;AAGF;EACE;EACA;EACA;;;AAQF;EAHF;IAII;;;;AAMJ;EACE;IACE;IACA","file":"checkbox.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../components/form/checkbox.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+BA;EACE;EACA;EACA;EACA;AAqDA;AAAA;AAAA;;AAlDA;EACE;EACA;;AAKA;EACE;;AAOF;EACE;EAEA;EACA;;AAMJ;EACE;EACA;;AAEA;EACE;EACA;;AAOF;EACE;;AAMF;EACE;;AASJ;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EAXF;IAYI;;;AAGF;EACE;EACA;EACA;;;AAQF;EAHF;IAII;;;;AAMJ;EACE;IACE;IACA","file":"checkbox.css"}
@@ -32,6 +32,9 @@ div:has(> input[type=checkbox]) {
32
32
  align-items: center;
33
33
  gap: var(--checkbox-gap, 0.5rem);
34
34
  position: relative;
35
+ /* ==========================================================================
36
+ Size Variants - Applied via data-checkbox-size attribute
37
+ ========================================================================== */
35
38
  }
36
39
  div:has(> input[type=checkbox]) > input[type=checkbox] {
37
40
  flex-shrink: 0;
@@ -59,6 +62,22 @@ div:has(> input[type=checkbox]):has(> input[aria-invalid=true]) .checkbox-label
59
62
  div:has(> input[type=checkbox]):has(> input[aria-invalid=false]:checked) label[for] {
60
63
  color: var(--checkbox-valid-label-color, currentColor);
61
64
  }
65
+ div:has(> input[type=checkbox])[data-checkbox-size~=xs] {
66
+ --checkbox-size: var(--checkbox-size-xs);
67
+ --checkbox-gap: var(--checkbox-gap-xs, 0.375rem);
68
+ }
69
+ div:has(> input[type=checkbox])[data-checkbox-size~=sm] {
70
+ --checkbox-size: var(--checkbox-size-sm);
71
+ --checkbox-gap: var(--checkbox-gap-sm, 0.5rem);
72
+ }
73
+ div:has(> input[type=checkbox])[data-checkbox-size~=md] {
74
+ --checkbox-size: var(--checkbox-size-md);
75
+ --checkbox-gap: var(--checkbox-gap-md, 0.5rem);
76
+ }
77
+ div:has(> input[type=checkbox])[data-checkbox-size~=lg] {
78
+ --checkbox-size: var(--checkbox-size-lg);
79
+ --checkbox-gap: var(--checkbox-gap-lg, 0.625rem);
80
+ }
62
81
 
63
82
  .checkbox-label {
64
83
  cursor: pointer;
@@ -93,6 +112,79 @@ div:has(> input[type=checkbox]):has(> input[aria-invalid=false]:checked) label[f
93
112
  align-items: flex-start;
94
113
  }
95
114
  }
115
+ :root {
116
+ --select-arrow-color: var(--color-text);
117
+ --select-width-mobile: 18.75rem; /* 300px minimum on mobile */
118
+ --select-width-desktop: 100%; /* Full width on larger screens */
119
+ }
120
+
121
+ select {
122
+ border: var(--input-outline);
123
+ border-radius: var(--input-radius);
124
+ outline: none;
125
+ background-color: var(--input-bg, var(--color-surface));
126
+ -webkit-appearance: none; /* Remove default arrow in Chrome and Safari */
127
+ -moz-appearance: none; /* Remove default arrow in Firefox */
128
+ appearance: none; /* Remove default arrow in other browsers */
129
+ background-image: linear-gradient(45deg, transparent 50%, var(--select-arrow-color, currentColor) 50%), linear-gradient(135deg, var(--select-arrow-color, currentColor) 50%, transparent 50%);
130
+ background-position: calc(100% - 1.25rem) center, calc(100% - 1rem) center;
131
+ background-size: 0.3125rem 0.3125rem, 0.3125rem 0.3125rem;
132
+ background-repeat: no-repeat;
133
+ padding-inline-start: var(--input-padding-inline);
134
+ padding-inline-end: 2.5rem;
135
+ padding-block: var(--input-padding-block);
136
+ width: max(var(--select-width-mobile), var(--select-width-desktop));
137
+ }
138
+
139
+ /* ==========================================================================
140
+ Option Styling with Data Attributes
141
+ ========================================================================== */
142
+ /*
143
+ option[data-option="primary"] {
144
+ background-color: var(--color-primary-light, #dbeafe);
145
+ color: var(--color-primary, #2563eb);
146
+ font-weight: 600;
147
+ }
148
+
149
+ option[data-option="success"] {
150
+ background-color: var(--color-success-bg, #dcfce7);
151
+ color: var(--color-success, #16a34a);
152
+ }
153
+
154
+ option[data-option="error"] {
155
+ background-color: var(--color-error-bg, #fee2e2);
156
+ color: var(--color-error, #dc2626);
157
+ }
158
+
159
+ option[data-option="warning"] {
160
+ background-color: var(--color-warning-bg, #fef3c7);
161
+ color: var(--color-warning, #d97706);
162
+ }
163
+ */
164
+ /*
165
+ option[data-size="sm"] {
166
+ font-size: 0.875rem; // 14px
167
+ padding: 0.25rem 0.5rem;
168
+ }
169
+
170
+ option[data-size="lg"] {
171
+ font-size: 1.125rem; // 18px
172
+ padding: 0.75rem 1rem;
173
+ font-weight: 500;
174
+ }
175
+ */
176
+ /*
177
+ option[data-featured="true"] {
178
+ font-weight: 700;
179
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
180
+ color: white;
181
+ }
182
+
183
+ option[data-category="premium"] {
184
+ background-color: #fef3c7;
185
+ font-style: italic;
186
+ }
187
+ */
96
188
  :root {
97
189
  --input-border-color: var(--color-border);
98
190
  --input-appearance: none;
@@ -101,9 +193,9 @@ div:has(> input[type=checkbox]):has(> input[aria-invalid=false]:checked) label[f
101
193
  --input-outline: thin solid var(--input-border-color);
102
194
  --input-padding-inline: 0.6rem;
103
195
  --input-padding-block: 0.4rem;
104
- --input-radius: --var(--radius);
196
+ --input-radius: var(--radius);
105
197
  --input-fs: var(--fs);
106
- --input-width: clamp(200px, 100%, 500px);
198
+ --input-width: clamp(12.5rem, 100%, 31.25rem);
107
199
  --input-focus-outline: medium solid var(--input-border-color);
108
200
  --input-focus-outline-offset: 0;
109
201
  --input-disabled-bg: var(--color-disabled-bg);
@@ -113,13 +205,18 @@ div:has(> input[type=checkbox]):has(> input[aria-invalid=false]:checked) label[f
113
205
  --placeholder-style: italic;
114
206
  --placeholder-fs: smaller;
115
207
  --form-direction: column;
116
- --select-arrow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20'><polyline points='6,9 10,13 14,9' stroke='%23000000' stroke-width='1.5' fill='none' /></svg>");
117
208
  /* ==========================================================================
118
209
  Size Tokens
119
210
  ========================================================================== */
211
+ --checkbox-size-xs: 0.875rem; /* 14px - extra small */
120
212
  --checkbox-size-sm: 1rem; /* 16px */
121
213
  --checkbox-size-md: 1.25rem; /* 20px */
122
214
  --checkbox-size-lg: 1.5rem; /* 24px */
215
+ /* Gap tokens for each size variant */
216
+ --checkbox-gap-xs: 0.375rem; /* 6px */
217
+ --checkbox-gap-sm: 0.5rem; /* 8px */
218
+ --checkbox-gap-md: 0.5rem; /* 8px - default */
219
+ --checkbox-gap-lg: 0.625rem; /* 10px */
123
220
  /* ==========================================================================
124
221
  Base Properties
125
222
  ========================================================================== */
@@ -210,15 +307,4 @@ input[type=checkbox]:checked {
210
307
  background: var(--checkbox-checked-bg) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='white'><path d='M6.173 11.414l-3.89-3.89 1.414-1.414 2.476 2.475 5.657-5.657 1.414 1.414z'/></svg>") no-repeat center center;
211
308
  }
212
309
 
213
- select {
214
- border: var(--input-outline);
215
- outline: none;
216
- -webkit-appearance: none; /* Remove default arrow in Chrome and Safari */
217
- -moz-appearance: none; /* Remove default arrow in Firefox */
218
- appearance: none; /* Remove default arrow in other browsers */
219
- background: var(--select-arrow) no-repeat;
220
- background-position: right 0.5rem top 50%;
221
- padding-inline-end: 0;
222
- }
223
-
224
310
  /*# sourceMappingURL=form.css.map */
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../components/form/checkbox.scss","../../components/form/form.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+BA;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAKA;EACE;;AAOF;EACE;EAEA;EACA;;AAMJ;EACE;EACA;;AAEA;EACE;EACA;;AAOF;EACE;;AAMF;EACE;;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EAXF;IAYI;;;AAGF;EACE;EACA;EACA;;;AAQF;EAHF;IAII;;;;AAMJ;EACE;IACE;IACA;;;AC3HJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EAGA;EACA;EACA;EAGA;EACA;EACA;EAEA;EACA;AAEA;AAAA;AAAA;EAIA;EACA;EACA;AAEA;AAAA;AAAA;EAIA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;AAAA;AAAA;EAIA;EACA;;;AAGF;EACE;EACA;EACA;;AACA;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAOF;AAAA;AAAA;EACE;EACA;EACA;EACA;;AAGA;AAAA;AAAA;EACE;EACA;;AACA;AAAA;AAAA;EACE;;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAMJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA","file":"form.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../components/form/checkbox.scss","../../components/form/select.scss","../../components/form/form.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+BA;EACE;EACA;EACA;EACA;AAqDA;AAAA;AAAA;;AAlDA;EACE;EACA;;AAKA;EACE;;AAOF;EACE;EAEA;EACA;;AAMJ;EACE;EACA;;AAEA;EACE;EACA;;AAOF;EACE;;AAMF;EACE;;AASJ;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EAXF;IAYI;;;AAGF;EACE;EACA;EACA;;;AAQF;EAHF;IAII;;;;AAMJ;EACE;IACE;IACA;;;ACxJJ;EAEE;EAGA;EACA;;;AAGF;EAEE;EACA;EACA;EACA;EAGA;EACA;EACA;EAGA;EAEA;EAEA;EAEA;EAGA;EACA;EACA;EAGA;;;AAGF;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AChFA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EAGA;EACA;EACA;EAGA;EACA;EACA;EAEA;AAEA;AAAA;AAAA;EAIA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;AAEA;AAAA;AAAA;EAIA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;AAAA;AAAA;EAIA;EACA;;;AAGF;EACE;EACA;EACA;;AACA;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAOF;AAAA;AAAA;EACE;EACA;EACA;EACA;;AAGA;AAAA;AAAA;EACE;EACA;;AACA;AAAA;AAAA;EACE;;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA","file":"form.css"}
@@ -0,0 +1,75 @@
1
+ :root {
2
+ --select-arrow-color: var(--color-text);
3
+ --select-width-mobile: 18.75rem; /* 300px minimum on mobile */
4
+ --select-width-desktop: 100%; /* Full width on larger screens */
5
+ }
6
+
7
+ select {
8
+ border: var(--input-outline);
9
+ border-radius: var(--input-radius);
10
+ outline: none;
11
+ background-color: var(--input-bg, var(--color-surface));
12
+ -webkit-appearance: none; /* Remove default arrow in Chrome and Safari */
13
+ -moz-appearance: none; /* Remove default arrow in Firefox */
14
+ appearance: none; /* Remove default arrow in other browsers */
15
+ background-image: linear-gradient(45deg, transparent 50%, var(--select-arrow-color, currentColor) 50%), linear-gradient(135deg, var(--select-arrow-color, currentColor) 50%, transparent 50%);
16
+ background-position: calc(100% - 1.25rem) center, calc(100% - 1rem) center;
17
+ background-size: 0.3125rem 0.3125rem, 0.3125rem 0.3125rem;
18
+ background-repeat: no-repeat;
19
+ padding-inline-start: var(--input-padding-inline);
20
+ padding-inline-end: 2.5rem;
21
+ padding-block: var(--input-padding-block);
22
+ width: max(var(--select-width-mobile), var(--select-width-desktop));
23
+ }
24
+
25
+ /* ==========================================================================
26
+ Option Styling with Data Attributes
27
+ ========================================================================== */
28
+ /*
29
+ option[data-option="primary"] {
30
+ background-color: var(--color-primary-light, #dbeafe);
31
+ color: var(--color-primary, #2563eb);
32
+ font-weight: 600;
33
+ }
34
+
35
+ option[data-option="success"] {
36
+ background-color: var(--color-success-bg, #dcfce7);
37
+ color: var(--color-success, #16a34a);
38
+ }
39
+
40
+ option[data-option="error"] {
41
+ background-color: var(--color-error-bg, #fee2e2);
42
+ color: var(--color-error, #dc2626);
43
+ }
44
+
45
+ option[data-option="warning"] {
46
+ background-color: var(--color-warning-bg, #fef3c7);
47
+ color: var(--color-warning, #d97706);
48
+ }
49
+ */
50
+ /*
51
+ option[data-size="sm"] {
52
+ font-size: 0.875rem; // 14px
53
+ padding: 0.25rem 0.5rem;
54
+ }
55
+
56
+ option[data-size="lg"] {
57
+ font-size: 1.125rem; // 18px
58
+ padding: 0.75rem 1rem;
59
+ font-weight: 500;
60
+ }
61
+ */
62
+ /*
63
+ option[data-featured="true"] {
64
+ font-weight: 700;
65
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
66
+ color: white;
67
+ }
68
+
69
+ option[data-category="premium"] {
70
+ background-color: #fef3c7;
71
+ font-style: italic;
72
+ }
73
+ */
74
+
75
+ /*# sourceMappingURL=select.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sourceRoot":"","sources":["../../components/form/select.scss"],"names":[],"mappings":"AAEA;EAEE;EAGA;EACA;;;AAGF;EAEE;EACA;EACA;EACA;EAGA;EACA;EACA;EAGA;EAEA;EAEA;EAEA;EAGA;EACA;EACA;EAGA;;;AAGF;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA","file":"select.css"}