@fpkit/acss 6.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 (163) 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/fields.cjs +4 -4
  46. package/libs/components/form/fields.d.cts +1 -1
  47. package/libs/components/form/fields.d.ts +1 -1
  48. package/libs/components/form/fields.js +2 -2
  49. package/libs/components/form/form.css +1 -1
  50. package/libs/components/form/form.css.map +1 -1
  51. package/libs/components/form/form.min.css +2 -2
  52. package/libs/components/form/select.css +1 -0
  53. package/libs/components/form/select.css.map +1 -0
  54. package/libs/components/form/select.min.css +3 -0
  55. package/libs/components/form/textarea.cjs +4 -4
  56. package/libs/components/form/textarea.js +2 -2
  57. package/libs/components/heading/heading.cjs +3 -3
  58. package/libs/components/heading/heading.d.cts +2 -2
  59. package/libs/components/heading/heading.d.ts +2 -2
  60. package/libs/components/heading/heading.js +2 -2
  61. package/libs/components/icons/icon.cjs +4 -4
  62. package/libs/components/icons/icon.d.cts +2 -2
  63. package/libs/components/icons/icon.d.ts +2 -2
  64. package/libs/components/icons/icon.js +2 -2
  65. package/libs/components/link/link.cjs +6 -6
  66. package/libs/components/link/link.js +2 -2
  67. package/libs/components/list/list.cjs +5 -5
  68. package/libs/components/list/list.d.cts +2 -2
  69. package/libs/components/list/list.d.ts +2 -2
  70. package/libs/components/list/list.js +2 -2
  71. package/libs/components/modal.cjs +4 -4
  72. package/libs/components/modal.js +3 -3
  73. package/libs/components/nav/nav.cjs +7 -7
  74. package/libs/components/nav/nav.d.cts +2 -2
  75. package/libs/components/nav/nav.d.ts +2 -2
  76. package/libs/components/nav/nav.js +3 -3
  77. package/libs/components/text/text.cjs +5 -5
  78. package/libs/components/text/text.d.cts +1 -1
  79. package/libs/components/text/text.d.ts +1 -1
  80. package/libs/components/text/text.js +2 -2
  81. package/libs/{heading-81eef89a.d.ts → heading-064675b6.d.ts} +1 -1
  82. package/libs/hooks.cjs +4 -4
  83. package/libs/hooks.d.cts +1 -1
  84. package/libs/hooks.d.ts +1 -1
  85. package/libs/hooks.js +3 -3
  86. package/libs/{icons-df8e744f.d.ts → icons-48788561.d.ts} +1 -1
  87. package/libs/icons.cjs +3 -3
  88. package/libs/icons.d.cts +2 -2
  89. package/libs/icons.d.ts +2 -2
  90. package/libs/icons.js +2 -2
  91. package/libs/index.cjs +38 -38
  92. package/libs/index.css +1 -1
  93. package/libs/index.css.map +1 -1
  94. package/libs/index.d.cts +5 -5
  95. package/libs/index.d.ts +5 -5
  96. package/libs/index.js +18 -18
  97. package/libs/{list.types-d26de310.d.ts → list.types-bf2c44c1.d.ts} +1 -1
  98. package/libs/{ui-d01b50d4.d.ts → ui-993fc2e2.d.ts} +5 -2
  99. package/package.json +4 -7
  100. package/src/components/alert/alert.stories.tsx +1 -1
  101. package/src/components/alert/elements/dismiss-button.stories.tsx +1 -2
  102. package/src/components/badge/badge.stories.tsx +1 -1
  103. package/src/components/breadcrumbs/breadcrumb.stories.tsx +1 -2
  104. package/src/components/buttons/button.stories.tsx +1 -3
  105. package/src/components/cards/card.stories.tsx +1 -1
  106. package/src/components/cards/card.test.tsx +1 -1
  107. package/src/components/details/details.stories.tsx +1 -2
  108. package/src/components/dialog/dialog-modal.stories.tsx +1 -2
  109. package/src/components/dialog/dialog.stories.tsx +1 -1
  110. package/src/components/dialog/views/dialog-header.stories.tsx +1 -2
  111. package/src/components/form/CHECKBOX-STYLES.mdx +1 -1
  112. package/src/components/form/CHECKBOX.mdx +1 -1
  113. package/src/components/form/form.scss +4 -14
  114. package/src/components/form/form.stories.tsx +1 -1
  115. package/src/components/form/input.stories.tsx +1 -1
  116. package/src/components/form/select.scss +97 -0
  117. package/src/components/form/select.stories.tsx +225 -9
  118. package/src/components/form/select.test.tsx +541 -0
  119. package/src/components/form/select.tsx +133 -16
  120. package/src/components/heading/heading.stories.tsx +1 -2
  121. package/src/components/images/figure.stories.tsx +1 -2
  122. package/src/components/images/img.stories.tsx +1 -1
  123. package/src/components/nav/nav.stories.tsx +1 -2
  124. package/src/components/text/text.stories.tsx +1 -1
  125. package/src/components/text-to-speech/TextToSpeech.stories.tsx +1 -1
  126. package/src/components/title/title.stories.tsx +1 -2
  127. package/src/components/ui.tsx +11 -4
  128. package/src/styles/form/form.css +75 -14
  129. package/src/styles/form/form.css.map +1 -1
  130. package/src/styles/form/select.css +75 -0
  131. package/src/styles/form/select.css.map +1 -0
  132. package/src/styles/index.css +75 -14
  133. package/src/styles/index.css.map +1 -1
  134. package/libs/chunk-DDSXKOUB.js +0 -7
  135. package/libs/chunk-DDSXKOUB.js.map +0 -1
  136. package/libs/chunk-EJ6KYBFE.cjs +0 -13
  137. package/libs/chunk-EJ6KYBFE.cjs.map +0 -1
  138. /package/libs/{chunk-DIJBIOFE.js.map → chunk-2ZJV6KQ3.js.map} +0 -0
  139. /package/libs/{chunk-LXODKKA3.cjs.map → chunk-3D6WUYSL.cjs.map} +0 -0
  140. /package/libs/{chunk-2JCDEC32.js.map → chunk-3ENBUQIB.js.map} +0 -0
  141. /package/libs/{chunk-NCGVF2QS.cjs.map → chunk-3RVZZZWX.cjs.map} +0 -0
  142. /package/libs/{chunk-M7JLT62Q.js.map → chunk-4F6SI5V5.js.map} +0 -0
  143. /package/libs/{chunk-3XJC4XUG.js.map → chunk-6ADHES7B.js.map} +0 -0
  144. /package/libs/{chunk-AOFQDQVS.cjs.map → chunk-6WMLG4O5.cjs.map} +0 -0
  145. /package/libs/{chunk-Q7OAQLUT.js.map → chunk-AQAI6COH.js.map} +0 -0
  146. /package/libs/{chunk-6BUJZ4DJ.cjs.map → chunk-BVPUT2PP.cjs.map} +0 -0
  147. /package/libs/{chunk-F64GE6RG.cjs.map → chunk-GVVCXXKI.cjs.map} +0 -0
  148. /package/libs/{chunk-75YQDONV.cjs.map → chunk-H4JRUNKU.cjs.map} +0 -0
  149. /package/libs/{chunk-G3TFKMWB.js.map → chunk-H6A2CUWA.js.map} +0 -0
  150. /package/libs/{chunk-2GJHKWEK.cjs.map → chunk-LQPWXSCK.cjs.map} +0 -0
  151. /package/libs/{chunk-IBUTNPTQ.js.map → chunk-M5ES7OWP.js.map} +0 -0
  152. /package/libs/{chunk-AWZLSWDO.js.map → chunk-MAG46S3P.js.map} +0 -0
  153. /package/libs/{chunk-KAR3HDXK.js.map → chunk-MJJKNHVH.js.map} +0 -0
  154. /package/libs/{chunk-5CJPTDK3.cjs.map → chunk-OZM455LO.cjs.map} +0 -0
  155. /package/libs/{chunk-NPWHQVYB.cjs.map → chunk-QU5AQQ4S.cjs.map} +0 -0
  156. /package/libs/{chunk-U5VA34SU.js.map → chunk-RQSMWB3J.js.map} +0 -0
  157. /package/libs/{chunk-5QSNJQVH.cjs.map → chunk-S7NIA6PI.cjs.map} +0 -0
  158. /package/libs/{chunk-MBWI67UT.js.map → chunk-SPESKPUA.js.map} +0 -0
  159. /package/libs/{chunk-PMWL5XZ4.js.map → chunk-SQ44OCJ2.js.map} +0 -0
  160. /package/libs/{chunk-EKJYOCLY.cjs.map → chunk-VISQ434C.cjs.map} +0 -0
  161. /package/libs/{chunk-AFINOD2L.cjs.map → chunk-VN2CVD4H.cjs.map} +0 -0
  162. /package/libs/{chunk-M5JARVJD.cjs.map → chunk-WTWGTWVI.cjs.map} +0 -0
  163. /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
  );
@@ -112,6 +112,79 @@ div:has(> input[type=checkbox])[data-checkbox-size~=lg] {
112
112
  align-items: flex-start;
113
113
  }
114
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
+ */
115
188
  :root {
116
189
  --input-border-color: var(--color-border);
117
190
  --input-appearance: none;
@@ -120,9 +193,9 @@ div:has(> input[type=checkbox])[data-checkbox-size~=lg] {
120
193
  --input-outline: thin solid var(--input-border-color);
121
194
  --input-padding-inline: 0.6rem;
122
195
  --input-padding-block: 0.4rem;
123
- --input-radius: --var(--radius);
196
+ --input-radius: var(--radius);
124
197
  --input-fs: var(--fs);
125
- --input-width: clamp(200px, 100%, 500px);
198
+ --input-width: clamp(12.5rem, 100%, 31.25rem);
126
199
  --input-focus-outline: medium solid var(--input-border-color);
127
200
  --input-focus-outline-offset: 0;
128
201
  --input-disabled-bg: var(--color-disabled-bg);
@@ -132,7 +205,6 @@ div:has(> input[type=checkbox])[data-checkbox-size~=lg] {
132
205
  --placeholder-style: italic;
133
206
  --placeholder-fs: smaller;
134
207
  --form-direction: column;
135
- --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>");
136
208
  /* ==========================================================================
137
209
  Size Tokens
138
210
  ========================================================================== */
@@ -235,15 +307,4 @@ input[type=checkbox]:checked {
235
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;
236
308
  }
237
309
 
238
- select {
239
- border: var(--input-outline);
240
- outline: none;
241
- -webkit-appearance: none; /* Remove default arrow in Chrome and Safari */
242
- -moz-appearance: none; /* Remove default arrow in Firefox */
243
- appearance: none; /* Remove default arrow in other browsers */
244
- background: var(--select-arrow) no-repeat;
245
- background-position: right 0.5rem top 50%;
246
- padding-inline-end: 0;
247
- }
248
-
249
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;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;;;ACvJJ;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;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;;;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"}
@@ -3674,6 +3674,79 @@ div:has(> input[type=checkbox])[data-checkbox-size~=lg] {
3674
3674
  align-items: flex-start;
3675
3675
  }
3676
3676
  }
3677
+ :root {
3678
+ --select-arrow-color: var(--color-text);
3679
+ --select-width-mobile: 18.75rem; /* 300px minimum on mobile */
3680
+ --select-width-desktop: 100%; /* Full width on larger screens */
3681
+ }
3682
+
3683
+ select {
3684
+ border: var(--input-outline);
3685
+ border-radius: var(--input-radius);
3686
+ outline: none;
3687
+ background-color: var(--input-bg, var(--color-surface));
3688
+ -webkit-appearance: none; /* Remove default arrow in Chrome and Safari */
3689
+ -moz-appearance: none; /* Remove default arrow in Firefox */
3690
+ appearance: none; /* Remove default arrow in other browsers */
3691
+ background-image: linear-gradient(45deg, transparent 50%, var(--select-arrow-color, currentColor) 50%), linear-gradient(135deg, var(--select-arrow-color, currentColor) 50%, transparent 50%);
3692
+ background-position: calc(100% - 1.25rem) center, calc(100% - 1rem) center;
3693
+ background-size: 0.3125rem 0.3125rem, 0.3125rem 0.3125rem;
3694
+ background-repeat: no-repeat;
3695
+ padding-inline-start: var(--input-padding-inline);
3696
+ padding-inline-end: 2.5rem;
3697
+ padding-block: var(--input-padding-block);
3698
+ width: max(var(--select-width-mobile), var(--select-width-desktop));
3699
+ }
3700
+
3701
+ /* ==========================================================================
3702
+ Option Styling with Data Attributes
3703
+ ========================================================================== */
3704
+ /*
3705
+ option[data-option="primary"] {
3706
+ background-color: var(--color-primary-light, #dbeafe);
3707
+ color: var(--color-primary, #2563eb);
3708
+ font-weight: 600;
3709
+ }
3710
+
3711
+ option[data-option="success"] {
3712
+ background-color: var(--color-success-bg, #dcfce7);
3713
+ color: var(--color-success, #16a34a);
3714
+ }
3715
+
3716
+ option[data-option="error"] {
3717
+ background-color: var(--color-error-bg, #fee2e2);
3718
+ color: var(--color-error, #dc2626);
3719
+ }
3720
+
3721
+ option[data-option="warning"] {
3722
+ background-color: var(--color-warning-bg, #fef3c7);
3723
+ color: var(--color-warning, #d97706);
3724
+ }
3725
+ */
3726
+ /*
3727
+ option[data-size="sm"] {
3728
+ font-size: 0.875rem; // 14px
3729
+ padding: 0.25rem 0.5rem;
3730
+ }
3731
+
3732
+ option[data-size="lg"] {
3733
+ font-size: 1.125rem; // 18px
3734
+ padding: 0.75rem 1rem;
3735
+ font-weight: 500;
3736
+ }
3737
+ */
3738
+ /*
3739
+ option[data-featured="true"] {
3740
+ font-weight: 700;
3741
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
3742
+ color: white;
3743
+ }
3744
+
3745
+ option[data-category="premium"] {
3746
+ background-color: #fef3c7;
3747
+ font-style: italic;
3748
+ }
3749
+ */
3677
3750
  :root {
3678
3751
  --input-border-color: var(--color-border);
3679
3752
  --input-appearance: none;
@@ -3682,9 +3755,9 @@ div:has(> input[type=checkbox])[data-checkbox-size~=lg] {
3682
3755
  --input-outline: thin solid var(--input-border-color);
3683
3756
  --input-padding-inline: 0.6rem;
3684
3757
  --input-padding-block: 0.4rem;
3685
- --input-radius: --var(--radius);
3758
+ --input-radius: var(--radius);
3686
3759
  --input-fs: var(--fs);
3687
- --input-width: clamp(200px, 100%, 500px);
3760
+ --input-width: clamp(12.5rem, 100%, 31.25rem);
3688
3761
  --input-focus-outline: medium solid var(--input-border-color);
3689
3762
  --input-focus-outline-offset: 0;
3690
3763
  --input-disabled-bg: var(--color-disabled-bg);
@@ -3694,7 +3767,6 @@ div:has(> input[type=checkbox])[data-checkbox-size~=lg] {
3694
3767
  --placeholder-style: italic;
3695
3768
  --placeholder-fs: smaller;
3696
3769
  --form-direction: column;
3697
- --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>");
3698
3770
  /* ==========================================================================
3699
3771
  Size Tokens
3700
3772
  ========================================================================== */
@@ -3797,17 +3869,6 @@ input[type=checkbox]:checked {
3797
3869
  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;
3798
3870
  }
3799
3871
 
3800
- select {
3801
- border: var(--input-outline);
3802
- outline: none;
3803
- -webkit-appearance: none; /* Remove default arrow in Chrome and Safari */
3804
- -moz-appearance: none; /* Remove default arrow in Firefox */
3805
- appearance: none; /* Remove default arrow in other browsers */
3806
- background: var(--select-arrow) no-repeat;
3807
- background-position: right 0.5rem top 50%;
3808
- padding-inline-end: 0;
3809
- }
3810
-
3811
3872
  nav:not(body > nav),
3812
3873
  nav[data-breadcrumb] {
3813
3874
  --breadcrumb-padding-inline: unset;