@negative-space/radio 1.1.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import { FlexProps } from '@negative-space/flex';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+
5
+ interface RadioProps extends Omit<FlexProps<'label'>, 'className' | 'style'> {
6
+ disabled?: boolean;
7
+ value: string | number;
8
+ classNames?: {
9
+ label?: string;
10
+ radio?: string;
11
+ inner?: string;
12
+ };
13
+ styles?: {
14
+ label?: React.CSSProperties;
15
+ radio?: React.CSSProperties;
16
+ inner?: React.CSSProperties;
17
+ };
18
+ isPopDisabled?: boolean;
19
+ }
20
+ declare const Radio: React.ForwardRefExoticComponent<RadioProps & React.RefAttributes<HTMLDivElement>>;
21
+
22
+ interface RadioGroupProps extends Omit<FlexProps, 'onChange'> {
23
+ name?: string;
24
+ disabled?: boolean;
25
+ value?: string | number;
26
+ onChange?: (value: string | number) => void;
27
+ }
28
+ declare const RadioGroup: ({ direction, className, value: valueProp, onChange, name: nameProp, disabled, children, ...props }: RadioGroupProps) => react_jsx_runtime.JSX.Element;
29
+
30
+ export { Radio, RadioGroup, type RadioGroupProps, type RadioProps };
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import { FlexProps } from '@negative-space/flex';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+
5
+ interface RadioProps extends Omit<FlexProps<'label'>, 'className' | 'style'> {
6
+ disabled?: boolean;
7
+ value: string | number;
8
+ classNames?: {
9
+ label?: string;
10
+ radio?: string;
11
+ inner?: string;
12
+ };
13
+ styles?: {
14
+ label?: React.CSSProperties;
15
+ radio?: React.CSSProperties;
16
+ inner?: React.CSSProperties;
17
+ };
18
+ isPopDisabled?: boolean;
19
+ }
20
+ declare const Radio: React.ForwardRefExoticComponent<RadioProps & React.RefAttributes<HTMLDivElement>>;
21
+
22
+ interface RadioGroupProps extends Omit<FlexProps, 'onChange'> {
23
+ name?: string;
24
+ disabled?: boolean;
25
+ value?: string | number;
26
+ onChange?: (value: string | number) => void;
27
+ }
28
+ declare const RadioGroup: ({ direction, className, value: valueProp, onChange, name: nameProp, disabled, children, ...props }: RadioGroupProps) => react_jsx_runtime.JSX.Element;
29
+
30
+ export { Radio, RadioGroup, type RadioGroupProps, type RadioProps };
package/dist/index.js ADDED
@@ -0,0 +1,143 @@
1
+ 'use strict';
2
+
3
+ var React3 = require('react');
4
+ var system = require('@negative-space/system');
5
+ var flex = require('@negative-space/flex');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
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
+ };
17
+
18
+ // src/useRadioContext.ts
19
+ var useRadioContext = () => {
20
+ const ctx = React3.useContext(RadioContext);
21
+ if (!ctx) {
22
+ throw new Error("Radio must be used within RadioGroup");
23
+ }
24
+ return ctx;
25
+ };
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 }
85
+ }
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,
102
+ disabled = false,
103
+ children,
104
+ ...props
105
+ }) => {
106
+ const { global } = system.useNSUI();
107
+ const autoName = React3.useId();
108
+ 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,
131
+ {
132
+ ...props,
133
+ direction,
134
+ className: system.cn(`${global.prefixCls}-radio-group`, className),
135
+ children
136
+ }
137
+ ) });
138
+ };
139
+
140
+ exports.Radio = Radio;
141
+ exports.RadioGroup = RadioGroup;
142
+ //# sourceMappingURL=index.js.map
143
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,136 @@
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';
5
+
6
+ // src/Radio.tsx
7
+ var RadioContext = React3.createContext(null);
8
+ var RadioProvider = ({ children, ...value }) => {
9
+ return /* @__PURE__ */ jsx(RadioContext.Provider, { value, children });
10
+ };
11
+
12
+ // src/useRadioContext.ts
13
+ var useRadioContext = () => {
14
+ const ctx = useContext(RadioContext);
15
+ if (!ctx) {
16
+ throw new Error("Radio must be used within RadioGroup");
17
+ }
18
+ return ctx;
19
+ };
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 }
79
+ }
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,
96
+ disabled = false,
97
+ children,
98
+ ...props
99
+ }) => {
100
+ const { global } = useNSUI();
101
+ const autoName = useId();
102
+ 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,
125
+ {
126
+ ...props,
127
+ direction,
128
+ className: cn(`${global.prefixCls}-radio-group`, className),
129
+ children
130
+ }
131
+ ) });
132
+ };
133
+
134
+ export { Radio, RadioGroup };
135
+ //# sourceMappingURL=index.mjs.map
136
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@negative-space/radio",
3
- "version": "1.1.1",
3
+ "version": "1.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -30,12 +30,11 @@
30
30
  "url": "https://github.com/negative-space-ui/nsui/issues"
31
31
  },
32
32
  "dependencies": {
33
- "clsx": "^2.1.1",
34
- "@negative-space/flex": "1.0.3",
35
- "@negative-space/provider": "1.6.0"
33
+ "@negative-space/flex": "1.1.1",
34
+ "@negative-space/system": "1.0.1"
36
35
  },
37
36
  "peerDependencies": {
38
- "react": "^19.2.1"
37
+ "react": "^19.2.3"
39
38
  },
40
39
  "clean-package": "../../../../clean-package.config.json",
41
40
  "exports": {