@negative-space/radio 1.3.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,10 +1,8 @@
1
- import React from 'react';
2
- import { FlexProps } from '@negative-space/flex';
3
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+ import { CollectionItemProps, CollectionProps } from '@negative-space/collection';
4
4
 
5
- interface RadioProps extends Omit<FlexProps<'label'>, 'className' | 'style'> {
6
- disabled?: boolean;
7
- value: string | number;
5
+ interface RadioOptionProps extends Omit<CollectionItemProps, 'onClick' | 'selected' | 'value' | 'role' | 'classNames' | 'styles'> {
8
6
  classNames?: {
9
7
  label?: string;
10
8
  radio?: string;
@@ -15,16 +13,46 @@ interface RadioProps extends Omit<FlexProps<'label'>, 'className' | 'style'> {
15
13
  radio?: React.CSSProperties;
16
14
  inner?: React.CSSProperties;
17
15
  };
18
- isPopDisabled?: boolean;
16
+ disabled?: boolean;
17
+ value: string;
18
+ label: React.ReactNode;
19
19
  }
20
- declare const Radio: React.ForwardRefExoticComponent<RadioProps & React.RefAttributes<HTMLDivElement>>;
21
20
 
22
- interface RadioGroupProps extends Omit<FlexProps, 'onChange'> {
21
+ interface RadioGroupProps extends Omit<CollectionProps, 'rovingOptions'> {
22
+ classNames?: {
23
+ field?: {
24
+ root?: string;
25
+ error?: string;
26
+ };
27
+ root?: string;
28
+ option?: {
29
+ label?: string;
30
+ radio?: string;
31
+ inner?: string;
32
+ };
33
+ };
34
+ styles?: {
35
+ field?: {
36
+ root?: React.CSSProperties;
37
+ error?: React.CSSProperties;
38
+ };
39
+ root?: React.CSSProperties;
40
+ option?: {
41
+ label?: React.CSSProperties;
42
+ radio?: React.CSSProperties;
43
+ inner?: React.CSSProperties;
44
+ };
45
+ };
23
46
  name?: string;
24
47
  disabled?: boolean;
25
- value?: string | number;
26
- onChange?: (value: string | number) => void;
48
+ options?: RadioOptionProps[];
49
+ error?: string;
50
+ defaultValue?: string;
51
+ onValueChange?: (value: string) => void;
52
+ }
53
+ declare function RadioGroup({ classNames, styles, disabled, options, error, name: nameProp, defaultValue, onValueChange, ...props }: RadioGroupProps): react_jsx_runtime.JSX.Element;
54
+ declare namespace RadioGroup {
55
+ var displayName: string;
27
56
  }
28
- declare const RadioGroup: ({ direction, className, value: valueProp, onChange, name: nameProp, disabled, children, ...props }: RadioGroupProps) => react_jsx_runtime.JSX.Element;
29
57
 
30
- export { Radio, RadioGroup, type RadioGroupProps, type RadioProps };
58
+ export { RadioGroup, type RadioGroupProps };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,8 @@
1
- import React from 'react';
2
- import { FlexProps } from '@negative-space/flex';
3
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+ import { CollectionItemProps, CollectionProps } from '@negative-space/collection';
4
4
 
5
- interface RadioProps extends Omit<FlexProps<'label'>, 'className' | 'style'> {
6
- disabled?: boolean;
7
- value: string | number;
5
+ interface RadioOptionProps extends Omit<CollectionItemProps, 'onClick' | 'selected' | 'value' | 'role' | 'classNames' | 'styles'> {
8
6
  classNames?: {
9
7
  label?: string;
10
8
  radio?: string;
@@ -15,16 +13,46 @@ interface RadioProps extends Omit<FlexProps<'label'>, 'className' | 'style'> {
15
13
  radio?: React.CSSProperties;
16
14
  inner?: React.CSSProperties;
17
15
  };
18
- isPopDisabled?: boolean;
16
+ disabled?: boolean;
17
+ value: string;
18
+ label: React.ReactNode;
19
19
  }
20
- declare const Radio: React.ForwardRefExoticComponent<RadioProps & React.RefAttributes<HTMLDivElement>>;
21
20
 
22
- interface RadioGroupProps extends Omit<FlexProps, 'onChange'> {
21
+ interface RadioGroupProps extends Omit<CollectionProps, 'rovingOptions'> {
22
+ classNames?: {
23
+ field?: {
24
+ root?: string;
25
+ error?: string;
26
+ };
27
+ root?: string;
28
+ option?: {
29
+ label?: string;
30
+ radio?: string;
31
+ inner?: string;
32
+ };
33
+ };
34
+ styles?: {
35
+ field?: {
36
+ root?: React.CSSProperties;
37
+ error?: React.CSSProperties;
38
+ };
39
+ root?: React.CSSProperties;
40
+ option?: {
41
+ label?: React.CSSProperties;
42
+ radio?: React.CSSProperties;
43
+ inner?: React.CSSProperties;
44
+ };
45
+ };
23
46
  name?: string;
24
47
  disabled?: boolean;
25
- value?: string | number;
26
- onChange?: (value: string | number) => void;
48
+ options?: RadioOptionProps[];
49
+ error?: string;
50
+ defaultValue?: string;
51
+ onValueChange?: (value: string) => void;
52
+ }
53
+ declare function RadioGroup({ classNames, styles, disabled, options, error, name: nameProp, defaultValue, onValueChange, ...props }: RadioGroupProps): react_jsx_runtime.JSX.Element;
54
+ declare namespace RadioGroup {
55
+ var displayName: string;
27
56
  }
28
- declare const RadioGroup: ({ direction, className, value: valueProp, onChange, name: nameProp, disabled, children, ...props }: RadioGroupProps) => react_jsx_runtime.JSX.Element;
29
57
 
30
- export { Radio, RadioGroup, type RadioGroupProps, type RadioProps };
58
+ export { RadioGroup, type RadioGroupProps };
package/dist/index.js CHANGED
@@ -1,143 +1,146 @@
1
1
  'use strict';
2
2
 
3
- var React3 = require('react');
3
+ var react = require('react');
4
4
  var system = require('@negative-space/system');
5
- var flex = require('@negative-space/flex');
5
+ var field = require('@negative-space/field');
6
+ var collection = require('@negative-space/collection');
6
7
  var jsxRuntime = require('react/jsx-runtime');
7
8
 
8
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
-
10
- var React3__default = /*#__PURE__*/_interopDefault(React3);
11
-
12
- // src/Radio.tsx
13
- var RadioContext = React3__default.default.createContext(null);
14
- var RadioProvider = ({ children, ...value }) => {
15
- return /* @__PURE__ */ jsxRuntime.jsx(RadioContext.Provider, { value, children });
16
- };
9
+ // src/RadioGroup.tsx
10
+ var RadioContext = react.createContext(null);
17
11
 
18
12
  // src/useRadioContext.ts
19
13
  var useRadioContext = () => {
20
- const ctx = React3.useContext(RadioContext);
14
+ const ctx = react.useContext(RadioContext);
21
15
  if (!ctx) {
22
16
  throw new Error("Radio must be used within RadioGroup");
23
17
  }
24
18
  return ctx;
25
19
  };
26
- var Radio = React3__default.default.forwardRef(
27
- ({
28
- classNames,
29
- alignItems = "center",
30
- styles,
31
- value,
32
- children,
33
- disabled,
34
- isPopDisabled,
35
- ...props
36
- }, ref) => {
37
- const { global, components } = system.useNSUI();
38
- const { selectedValue, onChange, disabled: groupDisabled } = useRadioContext();
39
- const Disabled = disabled ?? groupDisabled;
40
- const checked = selectedValue === value;
41
- const IsPopDisabled = isPopDisabled ?? components.radio.isPopDisabled;
42
- const handleClick = () => {
43
- if (!Disabled) onChange?.(value);
44
- };
45
- const handleKeyDown = (e) => {
46
- if (Disabled) return;
47
- if (e.key === "Enter" || e.key === " ") {
48
- e.preventDefault();
49
- onChange?.(value);
50
- }
51
- };
52
- return /* @__PURE__ */ jsxRuntime.jsxs(
53
- flex.Flex,
54
- {
55
- ...props,
56
- as: "label",
57
- alignItems,
58
- "aria-disabled": Disabled,
59
- "data-disabled": Disabled,
60
- onClick: handleClick,
61
- className: system.cn(`${global.prefixCls}-radio-label`, classNames?.label),
62
- style: styles?.label,
63
- children: [
64
- /* @__PURE__ */ jsxRuntime.jsx(
65
- "div",
66
- {
67
- ref,
68
- role: "radio",
69
- "aria-checked": checked,
70
- "data-checked": checked,
71
- tabIndex: Disabled ? -1 : 0,
72
- onKeyDown: handleKeyDown,
73
- "data-disabled": Disabled,
74
- className: system.cn(`${global.prefixCls}-radio`, classNames?.radio),
75
- style: { ...styles?.radio },
76
- children: /* @__PURE__ */ jsxRuntime.jsx(
77
- "div",
78
- {
79
- className: system.cn(
80
- `${global.prefixCls}-radio-inner`,
81
- checked && !IsPopDisabled && `${global.prefixCls}-pop`,
82
- classNames?.inner
83
- ),
84
- style: { ...styles?.inner }
20
+ function RadioOption({
21
+ value,
22
+ label,
23
+ disabled,
24
+ classNames,
25
+ styles,
26
+ ...props
27
+ }) {
28
+ const { global } = system.useNSUI();
29
+ const { selectedValue, onChange, disabled: groupDisabled } = useRadioContext();
30
+ const isDisabled = disabled ?? groupDisabled ?? false;
31
+ const checked = selectedValue === value;
32
+ const select = () => {
33
+ if (!isDisabled) onChange?.(value);
34
+ };
35
+ return /* @__PURE__ */ jsxRuntime.jsxs(
36
+ collection.CollectionItem,
37
+ {
38
+ ...props,
39
+ role: "radio",
40
+ value,
41
+ disabled: isDisabled,
42
+ onClick: select,
43
+ onSelect: select,
44
+ "data-checked": checked,
45
+ "aria-checked": checked,
46
+ classNames: {
47
+ root: system.cn(
48
+ `${global.prefixCls}-radio-label`,
49
+ `${global.prefixCls}-clickable`,
50
+ classNames?.label
51
+ )
52
+ },
53
+ styles: { root: styles?.label },
54
+ children: [
55
+ /* @__PURE__ */ jsxRuntime.jsx(
56
+ "div",
57
+ {
58
+ "data-checked": checked,
59
+ className: system.cn(`${global.prefixCls}-radio`, classNames?.radio),
60
+ style: {
61
+ borderRadius: "50%",
62
+ display: "flex",
63
+ alignItems: "center",
64
+ justifyContent: "center",
65
+ overflow: "hidden",
66
+ ...styles?.radio
67
+ },
68
+ children: /* @__PURE__ */ jsxRuntime.jsx(
69
+ "div",
70
+ {
71
+ "data-visible": checked,
72
+ className: system.cn(
73
+ `${global.prefixCls}-radio-inner ${global.prefixCls}-fade`,
74
+ classNames?.inner
75
+ ),
76
+ style: {
77
+ borderRadius: "50%",
78
+ ...styles?.inner
85
79
  }
86
- )
87
- }
88
- ),
89
- children
90
- ]
91
- }
92
- );
93
- }
94
- );
95
- Radio.displayName = "Radio";
96
- var RadioGroup = ({
97
- direction = "column",
98
- className,
99
- value: valueProp,
100
- onChange,
101
- name: nameProp,
80
+ }
81
+ )
82
+ }
83
+ ),
84
+ label
85
+ ]
86
+ }
87
+ );
88
+ }
89
+ RadioOption.displayName = "RadioOption";
90
+ function RadioGroup({
91
+ classNames,
92
+ styles,
102
93
  disabled = false,
103
- children,
94
+ options,
95
+ error,
96
+ name: nameProp,
97
+ defaultValue,
98
+ onValueChange,
104
99
  ...props
105
- }) => {
100
+ }) {
106
101
  const { global } = system.useNSUI();
107
- const autoName = React3.useId();
102
+ const autoName = react.useId();
108
103
  const name = nameProp ?? autoName;
109
- const [internalValue, setInternalValue] = React3.useState(valueProp);
110
- const value = valueProp !== void 0 ? valueProp : internalValue;
111
- const handleChange = (newValue) => {
112
- if (valueProp === void 0) setInternalValue(newValue);
113
- onChange?.(newValue);
114
- };
115
- if (process.env.NODE_ENV !== "production") {
116
- const countRadios = (nodes) => {
117
- return React3__default.default.Children.toArray(nodes).reduce((acc, child) => {
118
- if (!React3__default.default.isValidElement(child)) return acc;
119
- if (child.type === Radio) return acc + 1;
120
- const childChildren = child.props?.children;
121
- return acc + countRadios(childChildren);
122
- }, 0);
123
- };
124
- const radiosCount = countRadios(children);
125
- if (radiosCount === 1) {
126
- console.warn("RadioGroup has only one Radio. Consider using multiple options for clarity.");
127
- }
128
- }
129
- return /* @__PURE__ */ jsxRuntime.jsx(RadioProvider, { name, selectedValue: value, onChange: handleChange, disabled, children: /* @__PURE__ */ jsxRuntime.jsx(
130
- flex.Flex,
104
+ const [selectedValue, setSelectedValue] = react.useState(defaultValue);
105
+ const handleChange = react.useCallback(
106
+ (value) => {
107
+ setSelectedValue(value);
108
+ onValueChange?.(value);
109
+ },
110
+ [onValueChange]
111
+ );
112
+ const contextValue = react.useMemo(
113
+ () => ({
114
+ name,
115
+ disabled,
116
+ selectedValue,
117
+ onChange: handleChange
118
+ }),
119
+ [name, disabled, selectedValue, handleChange]
120
+ );
121
+ return /* @__PURE__ */ jsxRuntime.jsx(RadioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(field.Field, { classNames: classNames?.field, styles: styles?.field, error, children: /* @__PURE__ */ jsxRuntime.jsx(
122
+ collection.Collection,
131
123
  {
132
124
  ...props,
133
- direction,
134
- className: system.cn(`${global.prefixCls}-radio-group`, className),
135
- children
125
+ role: "radiogroup",
126
+ disabled,
127
+ rovingOptions: { containerRole: "radiogroup" },
128
+ className: system.cn(`${global.prefixCls}-radio-group`, classNames?.root),
129
+ style: styles?.root,
130
+ children: options?.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
131
+ RadioOption,
132
+ {
133
+ ...option,
134
+ classNames: system.mergeCn(classNames?.option, option.classNames),
135
+ styles: { ...styles?.option, ...option.styles }
136
+ },
137
+ option.value ?? index
138
+ ))
136
139
  }
137
- ) });
138
- };
140
+ ) }) });
141
+ }
142
+ RadioGroup.displayName = "RadioGroup";
139
143
 
140
- exports.Radio = Radio;
141
144
  exports.RadioGroup = RadioGroup;
142
145
  //# sourceMappingURL=index.js.map
143
146
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/RadioProvider.tsx","../src/useRadioContext.ts","../src/Radio.tsx","../src/RadioGroup.tsx"],"names":["React","jsx","useContext","useNSUI","jsxs","Flex","cn","useId","useState"],"mappings":"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","file":"index.js","sourcesContent":["import React from 'react'\n\nexport type RadioContextValue = {\n name: string\n disabled?: boolean\n selectedValue?: string | number\n onChange?: (value: string | number) => void\n}\n\nexport const RadioContext = React.createContext<RadioContextValue | null>(null)\n\nexport interface RadioProviderProps extends RadioContextValue {\n children: React.ReactNode\n}\n\nexport const RadioProvider = ({ children, ...value }: RadioProviderProps) => {\n return <RadioContext.Provider value={value}>{children}</RadioContext.Provider>\n}\n","import { useContext } from 'react'\nimport { RadioContext } from './RadioProvider'\n\nexport const useRadioContext = () => {\n const ctx = useContext(RadioContext)\n\n if (!ctx) {\n throw new Error('Radio must be used within RadioGroup')\n }\n\n return ctx\n}\n","import React from 'react'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { Flex, type FlexProps } from '@negative-space/flex'\nimport { useRadioContext } from './useRadioContext'\n\nexport interface RadioProps extends Omit<FlexProps<'label'>, 'className' | 'style'> {\n disabled?: boolean\n value: string | number\n classNames?: {\n label?: string\n radio?: string\n inner?: string\n }\n styles?: {\n label?: React.CSSProperties\n radio?: React.CSSProperties\n inner?: React.CSSProperties\n }\n isPopDisabled?: boolean\n}\n\nexport const Radio = React.forwardRef<HTMLDivElement, RadioProps>(\n (\n {\n classNames,\n alignItems = 'center',\n styles,\n value,\n children,\n disabled,\n isPopDisabled,\n ...props\n },\n ref\n ) => {\n const { global, components } = useNSUI()\n const { selectedValue, onChange, disabled: groupDisabled } = useRadioContext()\n const Disabled = disabled ?? groupDisabled\n const checked = selectedValue === value\n const IsPopDisabled = isPopDisabled ?? components.radio.isPopDisabled\n\n const handleClick = () => {\n if (!Disabled) onChange?.(value)\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (Disabled) return\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n onChange?.(value)\n }\n }\n\n return (\n <Flex\n {...props}\n as=\"label\"\n alignItems={alignItems}\n aria-disabled={Disabled}\n data-disabled={Disabled}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-radio-label`, classNames?.label)}\n style={styles?.label}\n >\n <div\n ref={ref}\n role=\"radio\"\n aria-checked={checked}\n data-checked={checked}\n tabIndex={Disabled ? -1 : 0}\n onKeyDown={handleKeyDown}\n data-disabled={Disabled}\n className={cn(`${global.prefixCls}-radio`, classNames?.radio)}\n style={{ ...styles?.radio }}\n >\n <div\n className={cn(\n `${global.prefixCls}-radio-inner`,\n checked && !IsPopDisabled && `${global.prefixCls}-pop`,\n classNames?.inner\n )}\n style={{ ...styles?.inner }}\n />\n </div>\n {children}\n </Flex>\n )\n }\n)\n\nRadio.displayName = 'Radio'\n","import React, { useState, useId } from 'react'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { Flex, FlexProps } from '@negative-space/flex'\nimport { RadioProvider } from './RadioProvider'\nimport { Radio } from './Radio'\n\nexport interface RadioGroupProps extends Omit<FlexProps, 'onChange'> {\n name?: string\n disabled?: boolean\n value?: string | number\n onChange?: (value: string | number) => void\n}\n\nexport const RadioGroup = ({\n direction = 'column',\n className,\n value: valueProp,\n onChange,\n name: nameProp,\n disabled = false,\n children,\n ...props\n}: RadioGroupProps) => {\n const { global } = useNSUI()\n\n const autoName = useId()\n const name = nameProp ?? autoName\n\n const [internalValue, setInternalValue] = useState<string | number | undefined>(valueProp)\n const value = valueProp !== undefined ? valueProp : internalValue\n\n const handleChange = (newValue: string | number) => {\n if (valueProp === undefined) setInternalValue(newValue)\n onChange?.(newValue)\n }\n\n if (process.env.NODE_ENV !== 'production') {\n const countRadios = (nodes: React.ReactNode): number => {\n return React.Children.toArray(nodes).reduce((acc: number, child) => {\n if (!React.isValidElement(child)) return acc\n if (child.type === Radio) return acc + 1\n const childChildren = (child.props as { children?: React.ReactNode })?.children\n return acc + countRadios(childChildren)\n }, 0)\n }\n\n const radiosCount = countRadios(children)\n if (radiosCount === 1) {\n console.warn('RadioGroup has only one Radio. Consider using multiple options for clarity.')\n }\n }\n\n return (\n <RadioProvider name={name} selectedValue={value} onChange={handleChange} disabled={disabled}>\n <Flex\n {...props}\n direction={direction}\n className={cn(`${global.prefixCls}-radio-group`, className)}\n >\n {children}\n </Flex>\n </RadioProvider>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/RadioContext.ts","../src/useRadioContext.ts","../src/RadioOption.tsx","../src/RadioGroup.tsx"],"names":["createContext","useContext","useNSUI","jsxs","CollectionItem","cn","jsx","useId","useState","useCallback","useMemo","Field","Collection","mergeCn"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext } from 'react'\n\nexport interface RadioContextValue {\n name: string\n disabled?: boolean\n selectedValue?: string\n onChange?: (value: string) => void\n}\n\nexport const RadioContext = createContext<RadioContextValue | null>(null)\n","import { useContext } from 'react'\nimport { RadioContext, type RadioContextValue } from './RadioContext'\n\nexport const useRadioContext = (): RadioContextValue => {\n const ctx = useContext(RadioContext)\n\n if (!ctx) {\n throw new Error('Radio must be used within RadioGroup')\n }\n\n return ctx\n}\n","import React from 'react'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { CollectionItem, type CollectionItemProps } from '@negative-space/collection'\nimport { useRadioContext } from './useRadioContext'\n\nexport interface RadioOptionProps extends Omit<\n CollectionItemProps,\n 'onClick' | 'selected' | 'value' | 'role' | 'classNames' | 'styles'\n> {\n classNames?: {\n label?: string\n radio?: string\n inner?: string\n }\n styles?: {\n label?: React.CSSProperties\n radio?: React.CSSProperties\n inner?: React.CSSProperties\n }\n disabled?: boolean\n value: string\n label: React.ReactNode\n}\n\nexport function RadioOption({\n value,\n label,\n disabled,\n classNames,\n styles,\n ...props\n}: RadioOptionProps) {\n const { global } = useNSUI()\n const { selectedValue, onChange, disabled: groupDisabled } = useRadioContext()\n\n const isDisabled = disabled ?? groupDisabled ?? false\n const checked = selectedValue === value\n\n const select = () => {\n if (!isDisabled) onChange?.(value)\n }\n\n return (\n <CollectionItem\n {...props}\n role=\"radio\"\n value={value}\n disabled={isDisabled}\n onClick={select}\n onSelect={select}\n data-checked={checked}\n aria-checked={checked}\n classNames={{\n root: cn(\n `${global.prefixCls}-radio-label`,\n `${global.prefixCls}-clickable`,\n classNames?.label\n )\n }}\n styles={{ root: styles?.label }}\n >\n <div\n data-checked={checked}\n className={cn(`${global.prefixCls}-radio`, classNames?.radio)}\n style={{\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n ...styles?.radio\n }}\n >\n <div\n data-visible={checked}\n className={cn(\n `${global.prefixCls}-radio-inner ${global.prefixCls}-fade`,\n classNames?.inner\n )}\n style={{\n borderRadius: '50%',\n ...styles?.inner\n }}\n />\n </div>\n\n {label}\n </CollectionItem>\n )\n}\n\nRadioOption.displayName = 'RadioOption'\n","import React, { useCallback, useMemo, useState, useId } from 'react'\nimport { cn, mergeCn, useNSUI } from '@negative-space/system'\nimport { Field } from '@negative-space/field'\nimport { Collection, type CollectionProps } from '@negative-space/collection'\nimport { RadioOption, type RadioOptionProps } from './RadioOption'\nimport { RadioContext } from './RadioContext'\n\nexport interface RadioGroupProps extends Omit<CollectionProps, 'rovingOptions'> {\n classNames?: {\n field?: {\n root?: string\n error?: string\n }\n root?: string\n option?: {\n label?: string\n radio?: string\n inner?: string\n }\n }\n styles?: {\n field?: {\n root?: React.CSSProperties\n error?: React.CSSProperties\n }\n root?: React.CSSProperties\n option?: {\n label?: React.CSSProperties\n radio?: React.CSSProperties\n inner?: React.CSSProperties\n }\n }\n name?: string\n disabled?: boolean\n options?: RadioOptionProps[]\n error?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n}\n\nexport function RadioGroup({\n classNames,\n styles,\n disabled = false,\n options,\n error,\n name: nameProp,\n defaultValue,\n onValueChange,\n ...props\n}: RadioGroupProps) {\n const { global } = useNSUI()\n const autoName = useId()\n const name = nameProp ?? autoName\n\n const [selectedValue, setSelectedValue] = useState(defaultValue)\n\n const handleChange = useCallback(\n (value: string) => {\n setSelectedValue(value)\n onValueChange?.(value)\n },\n [onValueChange]\n )\n\n const contextValue = useMemo(\n () => ({\n name,\n disabled,\n selectedValue,\n onChange: handleChange\n }),\n [name, disabled, selectedValue, handleChange]\n )\n\n return (\n <RadioContext.Provider value={contextValue}>\n <Field classNames={classNames?.field} styles={styles?.field} error={error}>\n <Collection\n {...props}\n role=\"radiogroup\"\n disabled={disabled}\n rovingOptions={{ containerRole: 'radiogroup' }}\n className={cn(`${global.prefixCls}-radio-group`, classNames?.root)}\n style={styles?.root}\n >\n {options?.map((option, index) => (\n <RadioOption\n key={option.value ?? index}\n {...option}\n classNames={mergeCn(classNames?.option, option.classNames)}\n styles={{ ...styles?.option, ...option.styles }}\n />\n ))}\n </Collection>\n </Field>\n </RadioContext.Provider>\n )\n}\n\nRadioGroup.displayName = 'RadioGroup'\n"]}
package/dist/index.mjs CHANGED
@@ -1,13 +1,11 @@
1
- import React3, { useContext, useId, useState } from 'react';
2
- import { useNSUI, cn } from '@negative-space/system';
3
- import { Flex } from '@negative-space/flex';
4
- import { jsxs, jsx } from 'react/jsx-runtime';
1
+ import { createContext, useId, useState, useCallback, useMemo, useContext } from 'react';
2
+ import { useNSUI, cn, mergeCn } from '@negative-space/system';
3
+ import { Field } from '@negative-space/field';
4
+ import { Collection, CollectionItem } from '@negative-space/collection';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
6
 
6
- // src/Radio.tsx
7
- var RadioContext = React3.createContext(null);
8
- var RadioProvider = ({ children, ...value }) => {
9
- return /* @__PURE__ */ jsx(RadioContext.Provider, { value, children });
10
- };
7
+ // src/RadioGroup.tsx
8
+ var RadioContext = createContext(null);
11
9
 
12
10
  // src/useRadioContext.ts
13
11
  var useRadioContext = () => {
@@ -17,120 +15,130 @@ var useRadioContext = () => {
17
15
  }
18
16
  return ctx;
19
17
  };
20
- var Radio = React3.forwardRef(
21
- ({
22
- classNames,
23
- alignItems = "center",
24
- styles,
25
- value,
26
- children,
27
- disabled,
28
- isPopDisabled,
29
- ...props
30
- }, ref) => {
31
- const { global, components } = useNSUI();
32
- const { selectedValue, onChange, disabled: groupDisabled } = useRadioContext();
33
- const Disabled = disabled ?? groupDisabled;
34
- const checked = selectedValue === value;
35
- const IsPopDisabled = isPopDisabled ?? components.radio.isPopDisabled;
36
- const handleClick = () => {
37
- if (!Disabled) onChange?.(value);
38
- };
39
- const handleKeyDown = (e) => {
40
- if (Disabled) return;
41
- if (e.key === "Enter" || e.key === " ") {
42
- e.preventDefault();
43
- onChange?.(value);
44
- }
45
- };
46
- return /* @__PURE__ */ jsxs(
47
- Flex,
48
- {
49
- ...props,
50
- as: "label",
51
- alignItems,
52
- "aria-disabled": Disabled,
53
- "data-disabled": Disabled,
54
- onClick: handleClick,
55
- className: cn(`${global.prefixCls}-radio-label`, classNames?.label),
56
- style: styles?.label,
57
- children: [
58
- /* @__PURE__ */ jsx(
59
- "div",
60
- {
61
- ref,
62
- role: "radio",
63
- "aria-checked": checked,
64
- "data-checked": checked,
65
- tabIndex: Disabled ? -1 : 0,
66
- onKeyDown: handleKeyDown,
67
- "data-disabled": Disabled,
68
- className: cn(`${global.prefixCls}-radio`, classNames?.radio),
69
- style: { ...styles?.radio },
70
- children: /* @__PURE__ */ jsx(
71
- "div",
72
- {
73
- className: cn(
74
- `${global.prefixCls}-radio-inner`,
75
- checked && !IsPopDisabled && `${global.prefixCls}-pop`,
76
- classNames?.inner
77
- ),
78
- style: { ...styles?.inner }
18
+ function RadioOption({
19
+ value,
20
+ label,
21
+ disabled,
22
+ classNames,
23
+ styles,
24
+ ...props
25
+ }) {
26
+ const { global } = useNSUI();
27
+ const { selectedValue, onChange, disabled: groupDisabled } = useRadioContext();
28
+ const isDisabled = disabled ?? groupDisabled ?? false;
29
+ const checked = selectedValue === value;
30
+ const select = () => {
31
+ if (!isDisabled) onChange?.(value);
32
+ };
33
+ return /* @__PURE__ */ jsxs(
34
+ CollectionItem,
35
+ {
36
+ ...props,
37
+ role: "radio",
38
+ value,
39
+ disabled: isDisabled,
40
+ onClick: select,
41
+ onSelect: select,
42
+ "data-checked": checked,
43
+ "aria-checked": checked,
44
+ classNames: {
45
+ root: cn(
46
+ `${global.prefixCls}-radio-label`,
47
+ `${global.prefixCls}-clickable`,
48
+ classNames?.label
49
+ )
50
+ },
51
+ styles: { root: styles?.label },
52
+ children: [
53
+ /* @__PURE__ */ jsx(
54
+ "div",
55
+ {
56
+ "data-checked": checked,
57
+ className: cn(`${global.prefixCls}-radio`, classNames?.radio),
58
+ style: {
59
+ borderRadius: "50%",
60
+ display: "flex",
61
+ alignItems: "center",
62
+ justifyContent: "center",
63
+ overflow: "hidden",
64
+ ...styles?.radio
65
+ },
66
+ children: /* @__PURE__ */ jsx(
67
+ "div",
68
+ {
69
+ "data-visible": checked,
70
+ className: cn(
71
+ `${global.prefixCls}-radio-inner ${global.prefixCls}-fade`,
72
+ classNames?.inner
73
+ ),
74
+ style: {
75
+ borderRadius: "50%",
76
+ ...styles?.inner
79
77
  }
80
- )
81
- }
82
- ),
83
- children
84
- ]
85
- }
86
- );
87
- }
88
- );
89
- Radio.displayName = "Radio";
90
- var RadioGroup = ({
91
- direction = "column",
92
- className,
93
- value: valueProp,
94
- onChange,
95
- name: nameProp,
78
+ }
79
+ )
80
+ }
81
+ ),
82
+ label
83
+ ]
84
+ }
85
+ );
86
+ }
87
+ RadioOption.displayName = "RadioOption";
88
+ function RadioGroup({
89
+ classNames,
90
+ styles,
96
91
  disabled = false,
97
- children,
92
+ options,
93
+ error,
94
+ name: nameProp,
95
+ defaultValue,
96
+ onValueChange,
98
97
  ...props
99
- }) => {
98
+ }) {
100
99
  const { global } = useNSUI();
101
100
  const autoName = useId();
102
101
  const name = nameProp ?? autoName;
103
- const [internalValue, setInternalValue] = useState(valueProp);
104
- const value = valueProp !== void 0 ? valueProp : internalValue;
105
- const handleChange = (newValue) => {
106
- if (valueProp === void 0) setInternalValue(newValue);
107
- onChange?.(newValue);
108
- };
109
- if (process.env.NODE_ENV !== "production") {
110
- const countRadios = (nodes) => {
111
- return React3.Children.toArray(nodes).reduce((acc, child) => {
112
- if (!React3.isValidElement(child)) return acc;
113
- if (child.type === Radio) return acc + 1;
114
- const childChildren = child.props?.children;
115
- return acc + countRadios(childChildren);
116
- }, 0);
117
- };
118
- const radiosCount = countRadios(children);
119
- if (radiosCount === 1) {
120
- console.warn("RadioGroup has only one Radio. Consider using multiple options for clarity.");
121
- }
122
- }
123
- return /* @__PURE__ */ jsx(RadioProvider, { name, selectedValue: value, onChange: handleChange, disabled, children: /* @__PURE__ */ jsx(
124
- Flex,
102
+ const [selectedValue, setSelectedValue] = useState(defaultValue);
103
+ const handleChange = useCallback(
104
+ (value) => {
105
+ setSelectedValue(value);
106
+ onValueChange?.(value);
107
+ },
108
+ [onValueChange]
109
+ );
110
+ const contextValue = useMemo(
111
+ () => ({
112
+ name,
113
+ disabled,
114
+ selectedValue,
115
+ onChange: handleChange
116
+ }),
117
+ [name, disabled, selectedValue, handleChange]
118
+ );
119
+ return /* @__PURE__ */ jsx(RadioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(Field, { classNames: classNames?.field, styles: styles?.field, error, children: /* @__PURE__ */ jsx(
120
+ Collection,
125
121
  {
126
122
  ...props,
127
- direction,
128
- className: cn(`${global.prefixCls}-radio-group`, className),
129
- children
123
+ role: "radiogroup",
124
+ disabled,
125
+ rovingOptions: { containerRole: "radiogroup" },
126
+ className: cn(`${global.prefixCls}-radio-group`, classNames?.root),
127
+ style: styles?.root,
128
+ children: options?.map((option, index) => /* @__PURE__ */ jsx(
129
+ RadioOption,
130
+ {
131
+ ...option,
132
+ classNames: mergeCn(classNames?.option, option.classNames),
133
+ styles: { ...styles?.option, ...option.styles }
134
+ },
135
+ option.value ?? index
136
+ ))
130
137
  }
131
- ) });
132
- };
138
+ ) }) });
139
+ }
140
+ RadioGroup.displayName = "RadioGroup";
133
141
 
134
- export { Radio, RadioGroup };
142
+ export { RadioGroup };
135
143
  //# sourceMappingURL=index.mjs.map
136
144
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/RadioProvider.tsx","../src/useRadioContext.ts","../src/Radio.tsx","../src/RadioGroup.tsx"],"names":["React","jsx","useNSUI","Flex","cn"],"mappings":"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","file":"index.mjs","sourcesContent":["import React from 'react'\n\nexport type RadioContextValue = {\n name: string\n disabled?: boolean\n selectedValue?: string | number\n onChange?: (value: string | number) => void\n}\n\nexport const RadioContext = React.createContext<RadioContextValue | null>(null)\n\nexport interface RadioProviderProps extends RadioContextValue {\n children: React.ReactNode\n}\n\nexport const RadioProvider = ({ children, ...value }: RadioProviderProps) => {\n return <RadioContext.Provider value={value}>{children}</RadioContext.Provider>\n}\n","import { useContext } from 'react'\nimport { RadioContext } from './RadioProvider'\n\nexport const useRadioContext = () => {\n const ctx = useContext(RadioContext)\n\n if (!ctx) {\n throw new Error('Radio must be used within RadioGroup')\n }\n\n return ctx\n}\n","import React from 'react'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { Flex, type FlexProps } from '@negative-space/flex'\nimport { useRadioContext } from './useRadioContext'\n\nexport interface RadioProps extends Omit<FlexProps<'label'>, 'className' | 'style'> {\n disabled?: boolean\n value: string | number\n classNames?: {\n label?: string\n radio?: string\n inner?: string\n }\n styles?: {\n label?: React.CSSProperties\n radio?: React.CSSProperties\n inner?: React.CSSProperties\n }\n isPopDisabled?: boolean\n}\n\nexport const Radio = React.forwardRef<HTMLDivElement, RadioProps>(\n (\n {\n classNames,\n alignItems = 'center',\n styles,\n value,\n children,\n disabled,\n isPopDisabled,\n ...props\n },\n ref\n ) => {\n const { global, components } = useNSUI()\n const { selectedValue, onChange, disabled: groupDisabled } = useRadioContext()\n const Disabled = disabled ?? groupDisabled\n const checked = selectedValue === value\n const IsPopDisabled = isPopDisabled ?? components.radio.isPopDisabled\n\n const handleClick = () => {\n if (!Disabled) onChange?.(value)\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (Disabled) return\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n onChange?.(value)\n }\n }\n\n return (\n <Flex\n {...props}\n as=\"label\"\n alignItems={alignItems}\n aria-disabled={Disabled}\n data-disabled={Disabled}\n onClick={handleClick}\n className={cn(`${global.prefixCls}-radio-label`, classNames?.label)}\n style={styles?.label}\n >\n <div\n ref={ref}\n role=\"radio\"\n aria-checked={checked}\n data-checked={checked}\n tabIndex={Disabled ? -1 : 0}\n onKeyDown={handleKeyDown}\n data-disabled={Disabled}\n className={cn(`${global.prefixCls}-radio`, classNames?.radio)}\n style={{ ...styles?.radio }}\n >\n <div\n className={cn(\n `${global.prefixCls}-radio-inner`,\n checked && !IsPopDisabled && `${global.prefixCls}-pop`,\n classNames?.inner\n )}\n style={{ ...styles?.inner }}\n />\n </div>\n {children}\n </Flex>\n )\n }\n)\n\nRadio.displayName = 'Radio'\n","import React, { useState, useId } from 'react'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { Flex, FlexProps } from '@negative-space/flex'\nimport { RadioProvider } from './RadioProvider'\nimport { Radio } from './Radio'\n\nexport interface RadioGroupProps extends Omit<FlexProps, 'onChange'> {\n name?: string\n disabled?: boolean\n value?: string | number\n onChange?: (value: string | number) => void\n}\n\nexport const RadioGroup = ({\n direction = 'column',\n className,\n value: valueProp,\n onChange,\n name: nameProp,\n disabled = false,\n children,\n ...props\n}: RadioGroupProps) => {\n const { global } = useNSUI()\n\n const autoName = useId()\n const name = nameProp ?? autoName\n\n const [internalValue, setInternalValue] = useState<string | number | undefined>(valueProp)\n const value = valueProp !== undefined ? valueProp : internalValue\n\n const handleChange = (newValue: string | number) => {\n if (valueProp === undefined) setInternalValue(newValue)\n onChange?.(newValue)\n }\n\n if (process.env.NODE_ENV !== 'production') {\n const countRadios = (nodes: React.ReactNode): number => {\n return React.Children.toArray(nodes).reduce((acc: number, child) => {\n if (!React.isValidElement(child)) return acc\n if (child.type === Radio) return acc + 1\n const childChildren = (child.props as { children?: React.ReactNode })?.children\n return acc + countRadios(childChildren)\n }, 0)\n }\n\n const radiosCount = countRadios(children)\n if (radiosCount === 1) {\n console.warn('RadioGroup has only one Radio. Consider using multiple options for clarity.')\n }\n }\n\n return (\n <RadioProvider name={name} selectedValue={value} onChange={handleChange} disabled={disabled}>\n <Flex\n {...props}\n direction={direction}\n className={cn(`${global.prefixCls}-radio-group`, className)}\n >\n {children}\n </Flex>\n </RadioProvider>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/RadioContext.ts","../src/useRadioContext.ts","../src/RadioOption.tsx","../src/RadioGroup.tsx"],"names":["useNSUI","jsx","cn"],"mappings":"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","file":"index.mjs","sourcesContent":["import { createContext } from 'react'\n\nexport interface RadioContextValue {\n name: string\n disabled?: boolean\n selectedValue?: string\n onChange?: (value: string) => void\n}\n\nexport const RadioContext = createContext<RadioContextValue | null>(null)\n","import { useContext } from 'react'\nimport { RadioContext, type RadioContextValue } from './RadioContext'\n\nexport const useRadioContext = (): RadioContextValue => {\n const ctx = useContext(RadioContext)\n\n if (!ctx) {\n throw new Error('Radio must be used within RadioGroup')\n }\n\n return ctx\n}\n","import React from 'react'\nimport { cn, useNSUI } from '@negative-space/system'\nimport { CollectionItem, type CollectionItemProps } from '@negative-space/collection'\nimport { useRadioContext } from './useRadioContext'\n\nexport interface RadioOptionProps extends Omit<\n CollectionItemProps,\n 'onClick' | 'selected' | 'value' | 'role' | 'classNames' | 'styles'\n> {\n classNames?: {\n label?: string\n radio?: string\n inner?: string\n }\n styles?: {\n label?: React.CSSProperties\n radio?: React.CSSProperties\n inner?: React.CSSProperties\n }\n disabled?: boolean\n value: string\n label: React.ReactNode\n}\n\nexport function RadioOption({\n value,\n label,\n disabled,\n classNames,\n styles,\n ...props\n}: RadioOptionProps) {\n const { global } = useNSUI()\n const { selectedValue, onChange, disabled: groupDisabled } = useRadioContext()\n\n const isDisabled = disabled ?? groupDisabled ?? false\n const checked = selectedValue === value\n\n const select = () => {\n if (!isDisabled) onChange?.(value)\n }\n\n return (\n <CollectionItem\n {...props}\n role=\"radio\"\n value={value}\n disabled={isDisabled}\n onClick={select}\n onSelect={select}\n data-checked={checked}\n aria-checked={checked}\n classNames={{\n root: cn(\n `${global.prefixCls}-radio-label`,\n `${global.prefixCls}-clickable`,\n classNames?.label\n )\n }}\n styles={{ root: styles?.label }}\n >\n <div\n data-checked={checked}\n className={cn(`${global.prefixCls}-radio`, classNames?.radio)}\n style={{\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n ...styles?.radio\n }}\n >\n <div\n data-visible={checked}\n className={cn(\n `${global.prefixCls}-radio-inner ${global.prefixCls}-fade`,\n classNames?.inner\n )}\n style={{\n borderRadius: '50%',\n ...styles?.inner\n }}\n />\n </div>\n\n {label}\n </CollectionItem>\n )\n}\n\nRadioOption.displayName = 'RadioOption'\n","import React, { useCallback, useMemo, useState, useId } from 'react'\nimport { cn, mergeCn, useNSUI } from '@negative-space/system'\nimport { Field } from '@negative-space/field'\nimport { Collection, type CollectionProps } from '@negative-space/collection'\nimport { RadioOption, type RadioOptionProps } from './RadioOption'\nimport { RadioContext } from './RadioContext'\n\nexport interface RadioGroupProps extends Omit<CollectionProps, 'rovingOptions'> {\n classNames?: {\n field?: {\n root?: string\n error?: string\n }\n root?: string\n option?: {\n label?: string\n radio?: string\n inner?: string\n }\n }\n styles?: {\n field?: {\n root?: React.CSSProperties\n error?: React.CSSProperties\n }\n root?: React.CSSProperties\n option?: {\n label?: React.CSSProperties\n radio?: React.CSSProperties\n inner?: React.CSSProperties\n }\n }\n name?: string\n disabled?: boolean\n options?: RadioOptionProps[]\n error?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n}\n\nexport function RadioGroup({\n classNames,\n styles,\n disabled = false,\n options,\n error,\n name: nameProp,\n defaultValue,\n onValueChange,\n ...props\n}: RadioGroupProps) {\n const { global } = useNSUI()\n const autoName = useId()\n const name = nameProp ?? autoName\n\n const [selectedValue, setSelectedValue] = useState(defaultValue)\n\n const handleChange = useCallback(\n (value: string) => {\n setSelectedValue(value)\n onValueChange?.(value)\n },\n [onValueChange]\n )\n\n const contextValue = useMemo(\n () => ({\n name,\n disabled,\n selectedValue,\n onChange: handleChange\n }),\n [name, disabled, selectedValue, handleChange]\n )\n\n return (\n <RadioContext.Provider value={contextValue}>\n <Field classNames={classNames?.field} styles={styles?.field} error={error}>\n <Collection\n {...props}\n role=\"radiogroup\"\n disabled={disabled}\n rovingOptions={{ containerRole: 'radiogroup' }}\n className={cn(`${global.prefixCls}-radio-group`, classNames?.root)}\n style={styles?.root}\n >\n {options?.map((option, index) => (\n <RadioOption\n key={option.value ?? index}\n {...option}\n classNames={mergeCn(classNames?.option, option.classNames)}\n styles={{ ...styles?.option, ...option.styles }}\n />\n ))}\n </Collection>\n </Field>\n </RadioContext.Provider>\n )\n}\n\nRadioGroup.displayName = 'RadioGroup'\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@negative-space/radio",
3
- "version": "1.3.1",
3
+ "version": "1.5.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -30,8 +30,9 @@
30
30
  "url": "https://github.com/negative-space-ui/nsui/issues"
31
31
  },
32
32
  "dependencies": {
33
- "@negative-space/flex": "1.1.2",
34
- "@negative-space/system": "1.0.2"
33
+ "@negative-space/collection": "2.0.0",
34
+ "@negative-space/field": "1.0.0",
35
+ "@negative-space/system": "1.2.0"
35
36
  },
36
37
  "peerDependencies": {
37
38
  "react": "^19.2.3"