@mirohq/design-system-radio 0.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.
package/dist/main.js ADDED
@@ -0,0 +1,180 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+ var designSystemStitches = require('@mirohq/design-system-stitches');
6
+ var reactRadioGroup = require('@radix-ui/react-radio-group');
7
+ var designSystemPrimitive = require('@mirohq/design-system-primitive');
8
+ var designSystemUseId = require('@mirohq/design-system-use-id');
9
+ var designSystemUtils = require('@mirohq/design-system-utils');
10
+
11
+ const StyledRadioGroup = designSystemStitches.styled(reactRadioGroup.Root, {
12
+ display: "flex",
13
+ gap: "$100",
14
+ "&[data-orientation=horizontal]": {
15
+ flexDirection: "row"
16
+ },
17
+ "&[data-orientation=vertical]": {
18
+ flexDirection: "column"
19
+ }
20
+ });
21
+ const StyledRadioItem = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
22
+ display: "inline-flex",
23
+ alignItems: "center",
24
+ gap: "$100"
25
+ });
26
+ const StyledRadioLabel = designSystemStitches.styled("label", {
27
+ cursor: "pointer"
28
+ });
29
+ const StyledRadioControl = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
30
+ boxSizing: "border-box",
31
+ square: "$5",
32
+ borderRadius: "$round",
33
+ border: "1px solid $border-option",
34
+ display: "block",
35
+ position: "relative",
36
+ margin: "auto",
37
+ transition: "background-color 120ms ease, border-color 120ms ease",
38
+ "@media (prefers-reduced-motion: reduce)": {
39
+ transition: "none"
40
+ }
41
+ });
42
+ const controlSelector = "& ".concat(StyledRadioControl);
43
+ const StyledRadioIndicator = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
44
+ square: "$2",
45
+ borderRadius: "$round",
46
+ position: "absolute",
47
+ top: "50%",
48
+ left: "50%",
49
+ backgroundColor: "$background-interactive-primary",
50
+ opacity: 0,
51
+ transform: "translate(-50%, -50%) scale(0.5)",
52
+ transition: "opacity 120ms cubic-bezier(0.25, 0.5, 0.5, 0.9), transform 120ms cubic-bezier(0.25, 0.5, 0.5, 0.9), background-color 120ms ease",
53
+ "@media (prefers-reduced-motion: reduce)": {
54
+ transition: "none"
55
+ }
56
+ });
57
+ const dotSelector = "".concat(controlSelector, " ").concat(StyledRadioIndicator);
58
+ const StyledRadio = designSystemStitches.styled(reactRadioGroup.Item, {
59
+ all: "unset",
60
+ square: "$6",
61
+ flexShrink: 0,
62
+ cursor: "pointer",
63
+ display: "inline-flex",
64
+ alignItems: "center",
65
+ justifyContent: "center",
66
+ "&:focus-visible, &[data-focused]": {
67
+ [controlSelector]: {
68
+ boxShadow: "$focus",
69
+ "@media (forced-colors: active)": {
70
+ outline: "Highlight solid"
71
+ }
72
+ }
73
+ },
74
+ "&[data-state=checked]": {
75
+ [controlSelector]: {
76
+ borderColor: "$border-interactive-primary"
77
+ },
78
+ [dotSelector]: {
79
+ opacity: 1,
80
+ transform: "translate(-50%, -50%) scale(1)"
81
+ }
82
+ },
83
+ "&:hover[data-state=unchecked]:not([aria-disabled=true]):not(:disabled)": {
84
+ [controlSelector]: {
85
+ borderColor: "$border-interactive-primary-hover"
86
+ }
87
+ },
88
+ "&:hover[data-state=checked]:not([aria-disabled=true]):not(:disabled)": {
89
+ [controlSelector]: {
90
+ borderColor: "$background-interactive-primary-hover"
91
+ },
92
+ [dotSelector]: {
93
+ backgroundColor: "$background-interactive-primary-hover"
94
+ }
95
+ },
96
+ "&[aria-disabled=true], &:disabled": {
97
+ cursor: "default",
98
+ [controlSelector]: {
99
+ borderColor: "$border-disabled",
100
+ backgroundColor: "$background-disabled",
101
+ "@media (forced-colors: active)": {
102
+ borderColor: "GrayText"
103
+ }
104
+ },
105
+ [dotSelector]: {
106
+ backgroundColor: "$icon-on-disabled",
107
+ "@media (forced-colors: active)": {
108
+ backgroundColor: "GrayText"
109
+ }
110
+ }
111
+ },
112
+ variants: {
113
+ invalid: {
114
+ true: {
115
+ "&[data-state=unchecked], &:hover[data-state=unchecked]:not([aria-disabled=true]):not(:disabled)": {
116
+ [controlSelector]: {
117
+ borderColor: "$border-interactive-danger"
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ });
124
+
125
+ const RadioItemContext = React.createContext(
126
+ null
127
+ );
128
+ const useRadioItemContext = () => React.useContext(RadioItemContext);
129
+
130
+ const RadioGroupItem = React.forwardRef(({ id: providedId, children, ...restProps }, forwardRef) => {
131
+ const id = designSystemUseId.useId(providedId);
132
+ return /* @__PURE__ */ jsxRuntime.jsx(RadioItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsxRuntime.jsx(StyledRadioItem, { ...restProps, ref: forwardRef, children }) });
133
+ });
134
+
135
+ const RadioGroupOption = React.forwardRef(
136
+ ({ "aria-disabled": ariaDisabled, onClick, id: providedId, ...restProps }, forwardRef) => {
137
+ var _a;
138
+ const itemContext = useRadioItemContext();
139
+ const generatedId = designSystemUseId.useId();
140
+ const id = (_a = providedId != null ? providedId : itemContext == null ? void 0 : itemContext.id) != null ? _a : generatedId;
141
+ const isAriaDisabled = designSystemUtils.booleanify(ariaDisabled != null ? ariaDisabled : false);
142
+ return /* @__PURE__ */ jsxRuntime.jsx(
143
+ StyledRadio,
144
+ {
145
+ ...restProps,
146
+ id,
147
+ "aria-disabled": ariaDisabled,
148
+ "data-form-element": "radio",
149
+ onClick: (e) => {
150
+ if (isAriaDisabled) {
151
+ e.preventDefault();
152
+ return;
153
+ }
154
+ onClick == null ? void 0 : onClick(e);
155
+ },
156
+ ref: forwardRef,
157
+ children: /* @__PURE__ */ jsxRuntime.jsx(StyledRadioControl, { children: /* @__PURE__ */ jsxRuntime.jsx(StyledRadioIndicator, {}) })
158
+ }
159
+ );
160
+ }
161
+ );
162
+
163
+ const RadioGroupLabel = React.forwardRef(({ htmlFor: htmlForProp, ...restProps }, forwardRef) => {
164
+ const itemContext = useRadioItemContext();
165
+ const htmlFor = htmlForProp != null ? htmlForProp : itemContext == null ? void 0 : itemContext.id;
166
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledRadioLabel, { ...restProps, htmlFor, ref: forwardRef });
167
+ });
168
+
169
+ const RadioGroupRoot = React.forwardRef(({ children, orientation = "vertical", ...restProps }, forwardRef) => /* @__PURE__ */ jsxRuntime.jsx(StyledRadioGroup, { orientation, ...restProps, ref: forwardRef, children }));
170
+ const RadioGroup = Object.assign(
171
+ RadioGroupRoot,
172
+ {
173
+ Item: RadioGroupItem,
174
+ Option: RadioGroupOption,
175
+ Label: RadioGroupLabel
176
+ }
177
+ );
178
+
179
+ exports.RadioGroup = RadioGroup;
180
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sources":["../src/radio.styled.tsx","../src/radio-item-context.ts","../src/radio-item.tsx","../src/radio.tsx","../src/radio-label.tsx","../src/radio-group.tsx"],"sourcesContent":["import { styled } from '@mirohq/design-system-stitches'\nimport { Root, Item } from '@radix-ui/react-radio-group'\nimport { Primitive } from '@mirohq/design-system-primitive'\nimport type { StrictComponentProps } from '@mirohq/design-system-stitches'\n\nexport const StyledRadioGroup = styled(Root, {\n display: 'flex',\n gap: '$100',\n '&[data-orientation=horizontal]': {\n flexDirection: 'row',\n },\n '&[data-orientation=vertical]': {\n flexDirection: 'column',\n },\n})\n\n/**\n * A single row: the control (`RadioGroup.Option`) next to its label\n * (`RadioGroup.Label`).\n */\nexport const StyledRadioItem = styled(Primitive.div, {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '$100',\n})\n\n/**\n * The label rendered next to the control. Associated with the control via\n * `htmlFor`, so clicking it toggles the selection.\n */\nexport const StyledRadioLabel = styled('label', {\n cursor: 'pointer',\n})\n\n/**\n * The visible circle. Border/background reflect the item state; the indicator\n * dot is centered inside.\n */\nexport const StyledRadioControl = styled(Primitive.div, {\n boxSizing: 'border-box',\n square: '$5',\n borderRadius: '$round',\n border: '1px solid $border-option',\n display: 'block',\n position: 'relative',\n margin: 'auto',\n transition: 'background-color 120ms ease, border-color 120ms ease',\n '@media (prefers-reduced-motion: reduce)': {\n transition: 'none',\n },\n})\n\nconst controlSelector = `& ${StyledRadioControl}`\n\n/**\n * The filled dot shown when the item is selected. Rendered as a styled div (not\n * an icon) since it is a plain circle. Absolutely centered inside the control\n * so its presence never affects layout (mirrors Checkbox marks). Visibility is\n * driven by the control's `data-state` rather than Radix's `Indicator`, so the\n * consumer never composes it directly.\n */\nexport const StyledRadioIndicator = styled(Primitive.div, {\n square: '$2',\n borderRadius: '$round',\n position: 'absolute',\n top: '50%',\n left: '50%',\n backgroundColor: '$background-interactive-primary',\n opacity: 0,\n transform: 'translate(-50%, -50%) scale(0.5)',\n transition:\n 'opacity 120ms cubic-bezier(0.25, 0.5, 0.5, 0.9), transform 120ms cubic-bezier(0.25, 0.5, 0.5, 0.9), background-color 120ms ease',\n '@media (prefers-reduced-motion: reduce)': {\n transition: 'none',\n },\n})\n\nconst dotSelector = `${controlSelector} ${StyledRadioIndicator}`\n\nexport const StyledRadio = styled(Item, {\n all: 'unset',\n square: '$6',\n flexShrink: 0,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n\n '&:focus-visible, &[data-focused]': {\n [controlSelector]: {\n boxShadow: '$focus',\n '@media (forced-colors: active)': {\n outline: 'Highlight solid',\n },\n },\n },\n\n '&[data-state=checked]': {\n [controlSelector]: {\n borderColor: '$border-interactive-primary',\n },\n [dotSelector]: {\n opacity: 1,\n transform: 'translate(-50%, -50%) scale(1)',\n },\n },\n '&:hover[data-state=unchecked]:not([aria-disabled=true]):not(:disabled)': {\n [controlSelector]: {\n borderColor: '$border-interactive-primary-hover',\n },\n },\n '&:hover[data-state=checked]:not([aria-disabled=true]):not(:disabled)': {\n [controlSelector]: {\n borderColor: '$background-interactive-primary-hover',\n },\n [dotSelector]: {\n backgroundColor: '$background-interactive-primary-hover',\n },\n },\n\n '&[aria-disabled=true], &:disabled': {\n cursor: 'default',\n [controlSelector]: {\n borderColor: '$border-disabled',\n backgroundColor: '$background-disabled',\n '@media (forced-colors: active)': {\n borderColor: 'GrayText',\n },\n },\n [dotSelector]: {\n backgroundColor: '$icon-on-disabled',\n '@media (forced-colors: active)': {\n backgroundColor: 'GrayText',\n },\n },\n },\n\n variants: {\n invalid: {\n true: {\n '&[data-state=unchecked], &:hover[data-state=unchecked]:not([aria-disabled=true]):not(:disabled)':\n {\n [controlSelector]: {\n borderColor: '$border-interactive-danger',\n },\n },\n },\n },\n },\n})\n\nexport type StyledRadioProps = StrictComponentProps<typeof StyledRadio>\nexport type StyledRadioGroupProps = StrictComponentProps<\n typeof StyledRadioGroup\n>\nexport type StyledRadioItemProps = StrictComponentProps<typeof StyledRadioItem>\nexport type StyledRadioLabelProps = StrictComponentProps<\n typeof StyledRadioLabel\n>\n","import { createContext, useContext } from 'react'\n\nexport interface RadioItemContextValue {\n /**\n * The id shared by the control (`RadioGroup.Option`) and its label\n * (`RadioGroup.Label`) so the two stay associated via `htmlFor`.\n */\n id: string\n}\n\nexport const RadioItemContext = createContext<RadioItemContextValue | null>(\n null\n)\n\n/**\n * Reads the enclosing `RadioGroup.Item` context, if any. Returns `null` when a\n * control or label is rendered standalone (outside an item).\n */\nexport const useRadioItemContext = (): RadioItemContextValue | null =>\n useContext(RadioItemContext)\n","import React from 'react'\nimport { useId } from '@mirohq/design-system-use-id'\nimport type { ElementRef, ReactNode } from 'react'\n\nimport { StyledRadioItem } from './radio.styled'\nimport type { StyledRadioItemProps } from './radio.styled'\nimport { RadioItemContext } from './radio-item-context'\n\nexport interface ItemProps extends StyledRadioItemProps {\n /**\n * The id shared by the nested `RadioGroup.Option` and `RadioGroup.Label`.\n * Generated automatically when omitted.\n */\n id?: string\n\n /**\n * The `RadioGroup.Option` and `RadioGroup.Label` that make up the row.\n */\n children: ReactNode\n}\n\n/**\n * A single row of a `RadioGroup`. Wraps a `RadioGroup.Option` (the control) and\n * a `RadioGroup.Label`, and owns the shared id that associates the two.\n */\nexport const RadioGroupItem = React.forwardRef<\n ElementRef<typeof StyledRadioItem>,\n ItemProps\n>(({ id: providedId, children, ...restProps }, forwardRef) => {\n const id = useId(providedId)\n\n return (\n <RadioItemContext.Provider value={{ id }}>\n <StyledRadioItem {...restProps} ref={forwardRef}>\n {children}\n </StyledRadioItem>\n </RadioItemContext.Provider>\n )\n})\n","import React from 'react'\nimport { booleanify } from '@mirohq/design-system-utils'\nimport { useId } from '@mirohq/design-system-use-id'\nimport type { ElementRef } from 'react'\nimport type { Booleanish } from '@mirohq/design-system-types'\n\nimport {\n StyledRadio,\n StyledRadioControl,\n StyledRadioIndicator,\n} from './radio.styled'\nimport type { StyledRadioProps } from './radio.styled'\nimport { useRadioItemContext } from './radio-item-context'\n\nexport interface OptionProps extends StyledRadioProps {\n /**\n * The value given as data when submitted with a name. Selecting this item\n * sets its owning group's value to this.\n */\n value: string\n\n /**\n * When true, indicates that the user must select a value in the owning group\n * before its form can be submitted.\n */\n required?: boolean\n\n /**\n * When true, prevents the user from interacting with the radio.\n */\n disabled?: boolean\n\n /**\n * When true, prevents the user from interacting with the radio but focus is\n * still possible.\n */\n 'aria-disabled'?: Booleanish\n\n /**\n * When true, displays the radio in an error state.\n * @default false\n */\n invalid?: boolean\n}\n\n/**\n * The selectable radio control. Reads the shared id from its enclosing\n * `RadioGroup.Item` so its `RadioGroup.Label` can target it.\n */\nexport const RadioGroupOption = React.forwardRef<\n ElementRef<typeof StyledRadio>,\n OptionProps\n>(\n (\n { 'aria-disabled': ariaDisabled, onClick, id: providedId, ...restProps },\n forwardRef\n ) => {\n const itemContext = useRadioItemContext()\n const generatedId = useId()\n const id = providedId ?? itemContext?.id ?? generatedId\n const isAriaDisabled = booleanify(ariaDisabled ?? false)\n\n return (\n <StyledRadio\n {...restProps}\n id={id}\n aria-disabled={ariaDisabled}\n data-form-element='radio'\n onClick={e => {\n if (isAriaDisabled) {\n e.preventDefault()\n return\n }\n onClick?.(e)\n }}\n ref={forwardRef}\n >\n <StyledRadioControl>\n <StyledRadioIndicator />\n </StyledRadioControl>\n </StyledRadio>\n )\n }\n)\n","import React from 'react'\nimport type { ElementRef, ReactNode } from 'react'\n\nimport { StyledRadioLabel } from './radio.styled'\nimport type { StyledRadioLabelProps } from './radio.styled'\nimport { useRadioItemContext } from './radio-item-context'\n\nexport interface LabelProps extends StyledRadioLabelProps {\n /**\n * The control this label targets. Defaults to the id owned by the enclosing\n * `RadioGroup.Item`.\n */\n htmlFor?: string\n\n /**\n * The label content.\n */\n children: ReactNode\n}\n\n/**\n * The label for a `RadioGroup.Option`. Associates itself with the control via\n * the shared id from its enclosing `RadioGroup.Item`.\n */\nexport const RadioGroupLabel = React.forwardRef<\n ElementRef<typeof StyledRadioLabel>,\n LabelProps\n>(({ htmlFor: htmlForProp, ...restProps }, forwardRef) => {\n const itemContext = useRadioItemContext()\n const htmlFor = htmlForProp ?? itemContext?.id\n\n return <StyledRadioLabel {...restProps} htmlFor={htmlFor} ref={forwardRef} />\n})\n","import React from 'react'\nimport type { ElementRef, ReactNode } from 'react'\n\nimport { StyledRadioGroup } from './radio.styled'\nimport type { StyledRadioGroupProps } from './radio.styled'\nimport { RadioGroupItem } from './radio-item'\nimport { RadioGroupOption } from './radio'\nimport { RadioGroupLabel } from './radio-label'\n\nexport interface RadioGroupProps extends StyledRadioGroupProps {\n /**\n * The controlled value of the selected item. Must be used in conjunction with\n * onValueChange.\n */\n value?: string\n\n /**\n * The value of the item that should be selected when initially rendered. Use\n * when you do not need to control the state of the items.\n */\n defaultValue?: string\n\n /**\n * Event handler called when the selected value changes.\n */\n onValueChange?: (value: string) => void\n\n /**\n * The name of the group. Submitted with its owning form as part of a\n * name/value pair.\n */\n name?: string\n\n /**\n * When true, prevents the user from interacting with any item in the group.\n */\n disabled?: boolean\n\n /**\n * When true, indicates that the user must select a value before the owning\n * form can be submitted.\n */\n required?: boolean\n\n /**\n * The orientation of the group. Also sets the axis for arrow-key navigation.\n * @default 'vertical'\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * The `Radio` items of the group.\n */\n children: ReactNode\n}\n\nexport interface Partials {\n Item: typeof RadioGroupItem\n Option: typeof RadioGroupOption\n Label: typeof RadioGroupLabel\n}\n\n/**\n * Container for a set of mutually exclusive `RadioGroup.Item` rows.\n */\nconst RadioGroupRoot = React.forwardRef<\n ElementRef<typeof StyledRadioGroup>,\n RadioGroupProps\n>(({ children, orientation = 'vertical', ...restProps }, forwardRef) => (\n <StyledRadioGroup orientation={orientation} {...restProps} ref={forwardRef}>\n {children}\n </StyledRadioGroup>\n))\n\nexport const RadioGroup: typeof RadioGroupRoot & Partials = Object.assign(\n RadioGroupRoot,\n {\n Item: RadioGroupItem,\n Option: RadioGroupOption,\n Label: RadioGroupLabel,\n }\n)\n"],"names":["styled","Root","Primitive","Item","createContext","useContext","useId","jsx","booleanify"],"mappings":"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"}
package/dist/module.js ADDED
@@ -0,0 +1,178 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import React, { createContext, useContext } from 'react';
3
+ import { styled } from '@mirohq/design-system-stitches';
4
+ import { Root, Item } from '@radix-ui/react-radio-group';
5
+ import { Primitive } from '@mirohq/design-system-primitive';
6
+ import { useId } from '@mirohq/design-system-use-id';
7
+ import { booleanify } from '@mirohq/design-system-utils';
8
+
9
+ const StyledRadioGroup = styled(Root, {
10
+ display: "flex",
11
+ gap: "$100",
12
+ "&[data-orientation=horizontal]": {
13
+ flexDirection: "row"
14
+ },
15
+ "&[data-orientation=vertical]": {
16
+ flexDirection: "column"
17
+ }
18
+ });
19
+ const StyledRadioItem = styled(Primitive.div, {
20
+ display: "inline-flex",
21
+ alignItems: "center",
22
+ gap: "$100"
23
+ });
24
+ const StyledRadioLabel = styled("label", {
25
+ cursor: "pointer"
26
+ });
27
+ const StyledRadioControl = styled(Primitive.div, {
28
+ boxSizing: "border-box",
29
+ square: "$5",
30
+ borderRadius: "$round",
31
+ border: "1px solid $border-option",
32
+ display: "block",
33
+ position: "relative",
34
+ margin: "auto",
35
+ transition: "background-color 120ms ease, border-color 120ms ease",
36
+ "@media (prefers-reduced-motion: reduce)": {
37
+ transition: "none"
38
+ }
39
+ });
40
+ const controlSelector = "& ".concat(StyledRadioControl);
41
+ const StyledRadioIndicator = styled(Primitive.div, {
42
+ square: "$2",
43
+ borderRadius: "$round",
44
+ position: "absolute",
45
+ top: "50%",
46
+ left: "50%",
47
+ backgroundColor: "$background-interactive-primary",
48
+ opacity: 0,
49
+ transform: "translate(-50%, -50%) scale(0.5)",
50
+ transition: "opacity 120ms cubic-bezier(0.25, 0.5, 0.5, 0.9), transform 120ms cubic-bezier(0.25, 0.5, 0.5, 0.9), background-color 120ms ease",
51
+ "@media (prefers-reduced-motion: reduce)": {
52
+ transition: "none"
53
+ }
54
+ });
55
+ const dotSelector = "".concat(controlSelector, " ").concat(StyledRadioIndicator);
56
+ const StyledRadio = styled(Item, {
57
+ all: "unset",
58
+ square: "$6",
59
+ flexShrink: 0,
60
+ cursor: "pointer",
61
+ display: "inline-flex",
62
+ alignItems: "center",
63
+ justifyContent: "center",
64
+ "&:focus-visible, &[data-focused]": {
65
+ [controlSelector]: {
66
+ boxShadow: "$focus",
67
+ "@media (forced-colors: active)": {
68
+ outline: "Highlight solid"
69
+ }
70
+ }
71
+ },
72
+ "&[data-state=checked]": {
73
+ [controlSelector]: {
74
+ borderColor: "$border-interactive-primary"
75
+ },
76
+ [dotSelector]: {
77
+ opacity: 1,
78
+ transform: "translate(-50%, -50%) scale(1)"
79
+ }
80
+ },
81
+ "&:hover[data-state=unchecked]:not([aria-disabled=true]):not(:disabled)": {
82
+ [controlSelector]: {
83
+ borderColor: "$border-interactive-primary-hover"
84
+ }
85
+ },
86
+ "&:hover[data-state=checked]:not([aria-disabled=true]):not(:disabled)": {
87
+ [controlSelector]: {
88
+ borderColor: "$background-interactive-primary-hover"
89
+ },
90
+ [dotSelector]: {
91
+ backgroundColor: "$background-interactive-primary-hover"
92
+ }
93
+ },
94
+ "&[aria-disabled=true], &:disabled": {
95
+ cursor: "default",
96
+ [controlSelector]: {
97
+ borderColor: "$border-disabled",
98
+ backgroundColor: "$background-disabled",
99
+ "@media (forced-colors: active)": {
100
+ borderColor: "GrayText"
101
+ }
102
+ },
103
+ [dotSelector]: {
104
+ backgroundColor: "$icon-on-disabled",
105
+ "@media (forced-colors: active)": {
106
+ backgroundColor: "GrayText"
107
+ }
108
+ }
109
+ },
110
+ variants: {
111
+ invalid: {
112
+ true: {
113
+ "&[data-state=unchecked], &:hover[data-state=unchecked]:not([aria-disabled=true]):not(:disabled)": {
114
+ [controlSelector]: {
115
+ borderColor: "$border-interactive-danger"
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ });
122
+
123
+ const RadioItemContext = createContext(
124
+ null
125
+ );
126
+ const useRadioItemContext = () => useContext(RadioItemContext);
127
+
128
+ const RadioGroupItem = React.forwardRef(({ id: providedId, children, ...restProps }, forwardRef) => {
129
+ const id = useId(providedId);
130
+ return /* @__PURE__ */ jsx(RadioItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx(StyledRadioItem, { ...restProps, ref: forwardRef, children }) });
131
+ });
132
+
133
+ const RadioGroupOption = React.forwardRef(
134
+ ({ "aria-disabled": ariaDisabled, onClick, id: providedId, ...restProps }, forwardRef) => {
135
+ var _a;
136
+ const itemContext = useRadioItemContext();
137
+ const generatedId = useId();
138
+ const id = (_a = providedId != null ? providedId : itemContext == null ? void 0 : itemContext.id) != null ? _a : generatedId;
139
+ const isAriaDisabled = booleanify(ariaDisabled != null ? ariaDisabled : false);
140
+ return /* @__PURE__ */ jsx(
141
+ StyledRadio,
142
+ {
143
+ ...restProps,
144
+ id,
145
+ "aria-disabled": ariaDisabled,
146
+ "data-form-element": "radio",
147
+ onClick: (e) => {
148
+ if (isAriaDisabled) {
149
+ e.preventDefault();
150
+ return;
151
+ }
152
+ onClick == null ? void 0 : onClick(e);
153
+ },
154
+ ref: forwardRef,
155
+ children: /* @__PURE__ */ jsx(StyledRadioControl, { children: /* @__PURE__ */ jsx(StyledRadioIndicator, {}) })
156
+ }
157
+ );
158
+ }
159
+ );
160
+
161
+ const RadioGroupLabel = React.forwardRef(({ htmlFor: htmlForProp, ...restProps }, forwardRef) => {
162
+ const itemContext = useRadioItemContext();
163
+ const htmlFor = htmlForProp != null ? htmlForProp : itemContext == null ? void 0 : itemContext.id;
164
+ return /* @__PURE__ */ jsx(StyledRadioLabel, { ...restProps, htmlFor, ref: forwardRef });
165
+ });
166
+
167
+ const RadioGroupRoot = React.forwardRef(({ children, orientation = "vertical", ...restProps }, forwardRef) => /* @__PURE__ */ jsx(StyledRadioGroup, { orientation, ...restProps, ref: forwardRef, children }));
168
+ const RadioGroup = Object.assign(
169
+ RadioGroupRoot,
170
+ {
171
+ Item: RadioGroupItem,
172
+ Option: RadioGroupOption,
173
+ Label: RadioGroupLabel
174
+ }
175
+ );
176
+
177
+ export { RadioGroup };
178
+ //# sourceMappingURL=module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.js","sources":["../src/radio.styled.tsx","../src/radio-item-context.ts","../src/radio-item.tsx","../src/radio.tsx","../src/radio-label.tsx","../src/radio-group.tsx"],"sourcesContent":["import { styled } from '@mirohq/design-system-stitches'\nimport { Root, Item } from '@radix-ui/react-radio-group'\nimport { Primitive } from '@mirohq/design-system-primitive'\nimport type { StrictComponentProps } from '@mirohq/design-system-stitches'\n\nexport const StyledRadioGroup = styled(Root, {\n display: 'flex',\n gap: '$100',\n '&[data-orientation=horizontal]': {\n flexDirection: 'row',\n },\n '&[data-orientation=vertical]': {\n flexDirection: 'column',\n },\n})\n\n/**\n * A single row: the control (`RadioGroup.Option`) next to its label\n * (`RadioGroup.Label`).\n */\nexport const StyledRadioItem = styled(Primitive.div, {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '$100',\n})\n\n/**\n * The label rendered next to the control. Associated with the control via\n * `htmlFor`, so clicking it toggles the selection.\n */\nexport const StyledRadioLabel = styled('label', {\n cursor: 'pointer',\n})\n\n/**\n * The visible circle. Border/background reflect the item state; the indicator\n * dot is centered inside.\n */\nexport const StyledRadioControl = styled(Primitive.div, {\n boxSizing: 'border-box',\n square: '$5',\n borderRadius: '$round',\n border: '1px solid $border-option',\n display: 'block',\n position: 'relative',\n margin: 'auto',\n transition: 'background-color 120ms ease, border-color 120ms ease',\n '@media (prefers-reduced-motion: reduce)': {\n transition: 'none',\n },\n})\n\nconst controlSelector = `& ${StyledRadioControl}`\n\n/**\n * The filled dot shown when the item is selected. Rendered as a styled div (not\n * an icon) since it is a plain circle. Absolutely centered inside the control\n * so its presence never affects layout (mirrors Checkbox marks). Visibility is\n * driven by the control's `data-state` rather than Radix's `Indicator`, so the\n * consumer never composes it directly.\n */\nexport const StyledRadioIndicator = styled(Primitive.div, {\n square: '$2',\n borderRadius: '$round',\n position: 'absolute',\n top: '50%',\n left: '50%',\n backgroundColor: '$background-interactive-primary',\n opacity: 0,\n transform: 'translate(-50%, -50%) scale(0.5)',\n transition:\n 'opacity 120ms cubic-bezier(0.25, 0.5, 0.5, 0.9), transform 120ms cubic-bezier(0.25, 0.5, 0.5, 0.9), background-color 120ms ease',\n '@media (prefers-reduced-motion: reduce)': {\n transition: 'none',\n },\n})\n\nconst dotSelector = `${controlSelector} ${StyledRadioIndicator}`\n\nexport const StyledRadio = styled(Item, {\n all: 'unset',\n square: '$6',\n flexShrink: 0,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n\n '&:focus-visible, &[data-focused]': {\n [controlSelector]: {\n boxShadow: '$focus',\n '@media (forced-colors: active)': {\n outline: 'Highlight solid',\n },\n },\n },\n\n '&[data-state=checked]': {\n [controlSelector]: {\n borderColor: '$border-interactive-primary',\n },\n [dotSelector]: {\n opacity: 1,\n transform: 'translate(-50%, -50%) scale(1)',\n },\n },\n '&:hover[data-state=unchecked]:not([aria-disabled=true]):not(:disabled)': {\n [controlSelector]: {\n borderColor: '$border-interactive-primary-hover',\n },\n },\n '&:hover[data-state=checked]:not([aria-disabled=true]):not(:disabled)': {\n [controlSelector]: {\n borderColor: '$background-interactive-primary-hover',\n },\n [dotSelector]: {\n backgroundColor: '$background-interactive-primary-hover',\n },\n },\n\n '&[aria-disabled=true], &:disabled': {\n cursor: 'default',\n [controlSelector]: {\n borderColor: '$border-disabled',\n backgroundColor: '$background-disabled',\n '@media (forced-colors: active)': {\n borderColor: 'GrayText',\n },\n },\n [dotSelector]: {\n backgroundColor: '$icon-on-disabled',\n '@media (forced-colors: active)': {\n backgroundColor: 'GrayText',\n },\n },\n },\n\n variants: {\n invalid: {\n true: {\n '&[data-state=unchecked], &:hover[data-state=unchecked]:not([aria-disabled=true]):not(:disabled)':\n {\n [controlSelector]: {\n borderColor: '$border-interactive-danger',\n },\n },\n },\n },\n },\n})\n\nexport type StyledRadioProps = StrictComponentProps<typeof StyledRadio>\nexport type StyledRadioGroupProps = StrictComponentProps<\n typeof StyledRadioGroup\n>\nexport type StyledRadioItemProps = StrictComponentProps<typeof StyledRadioItem>\nexport type StyledRadioLabelProps = StrictComponentProps<\n typeof StyledRadioLabel\n>\n","import { createContext, useContext } from 'react'\n\nexport interface RadioItemContextValue {\n /**\n * The id shared by the control (`RadioGroup.Option`) and its label\n * (`RadioGroup.Label`) so the two stay associated via `htmlFor`.\n */\n id: string\n}\n\nexport const RadioItemContext = createContext<RadioItemContextValue | null>(\n null\n)\n\n/**\n * Reads the enclosing `RadioGroup.Item` context, if any. Returns `null` when a\n * control or label is rendered standalone (outside an item).\n */\nexport const useRadioItemContext = (): RadioItemContextValue | null =>\n useContext(RadioItemContext)\n","import React from 'react'\nimport { useId } from '@mirohq/design-system-use-id'\nimport type { ElementRef, ReactNode } from 'react'\n\nimport { StyledRadioItem } from './radio.styled'\nimport type { StyledRadioItemProps } from './radio.styled'\nimport { RadioItemContext } from './radio-item-context'\n\nexport interface ItemProps extends StyledRadioItemProps {\n /**\n * The id shared by the nested `RadioGroup.Option` and `RadioGroup.Label`.\n * Generated automatically when omitted.\n */\n id?: string\n\n /**\n * The `RadioGroup.Option` and `RadioGroup.Label` that make up the row.\n */\n children: ReactNode\n}\n\n/**\n * A single row of a `RadioGroup`. Wraps a `RadioGroup.Option` (the control) and\n * a `RadioGroup.Label`, and owns the shared id that associates the two.\n */\nexport const RadioGroupItem = React.forwardRef<\n ElementRef<typeof StyledRadioItem>,\n ItemProps\n>(({ id: providedId, children, ...restProps }, forwardRef) => {\n const id = useId(providedId)\n\n return (\n <RadioItemContext.Provider value={{ id }}>\n <StyledRadioItem {...restProps} ref={forwardRef}>\n {children}\n </StyledRadioItem>\n </RadioItemContext.Provider>\n )\n})\n","import React from 'react'\nimport { booleanify } from '@mirohq/design-system-utils'\nimport { useId } from '@mirohq/design-system-use-id'\nimport type { ElementRef } from 'react'\nimport type { Booleanish } from '@mirohq/design-system-types'\n\nimport {\n StyledRadio,\n StyledRadioControl,\n StyledRadioIndicator,\n} from './radio.styled'\nimport type { StyledRadioProps } from './radio.styled'\nimport { useRadioItemContext } from './radio-item-context'\n\nexport interface OptionProps extends StyledRadioProps {\n /**\n * The value given as data when submitted with a name. Selecting this item\n * sets its owning group's value to this.\n */\n value: string\n\n /**\n * When true, indicates that the user must select a value in the owning group\n * before its form can be submitted.\n */\n required?: boolean\n\n /**\n * When true, prevents the user from interacting with the radio.\n */\n disabled?: boolean\n\n /**\n * When true, prevents the user from interacting with the radio but focus is\n * still possible.\n */\n 'aria-disabled'?: Booleanish\n\n /**\n * When true, displays the radio in an error state.\n * @default false\n */\n invalid?: boolean\n}\n\n/**\n * The selectable radio control. Reads the shared id from its enclosing\n * `RadioGroup.Item` so its `RadioGroup.Label` can target it.\n */\nexport const RadioGroupOption = React.forwardRef<\n ElementRef<typeof StyledRadio>,\n OptionProps\n>(\n (\n { 'aria-disabled': ariaDisabled, onClick, id: providedId, ...restProps },\n forwardRef\n ) => {\n const itemContext = useRadioItemContext()\n const generatedId = useId()\n const id = providedId ?? itemContext?.id ?? generatedId\n const isAriaDisabled = booleanify(ariaDisabled ?? false)\n\n return (\n <StyledRadio\n {...restProps}\n id={id}\n aria-disabled={ariaDisabled}\n data-form-element='radio'\n onClick={e => {\n if (isAriaDisabled) {\n e.preventDefault()\n return\n }\n onClick?.(e)\n }}\n ref={forwardRef}\n >\n <StyledRadioControl>\n <StyledRadioIndicator />\n </StyledRadioControl>\n </StyledRadio>\n )\n }\n)\n","import React from 'react'\nimport type { ElementRef, ReactNode } from 'react'\n\nimport { StyledRadioLabel } from './radio.styled'\nimport type { StyledRadioLabelProps } from './radio.styled'\nimport { useRadioItemContext } from './radio-item-context'\n\nexport interface LabelProps extends StyledRadioLabelProps {\n /**\n * The control this label targets. Defaults to the id owned by the enclosing\n * `RadioGroup.Item`.\n */\n htmlFor?: string\n\n /**\n * The label content.\n */\n children: ReactNode\n}\n\n/**\n * The label for a `RadioGroup.Option`. Associates itself with the control via\n * the shared id from its enclosing `RadioGroup.Item`.\n */\nexport const RadioGroupLabel = React.forwardRef<\n ElementRef<typeof StyledRadioLabel>,\n LabelProps\n>(({ htmlFor: htmlForProp, ...restProps }, forwardRef) => {\n const itemContext = useRadioItemContext()\n const htmlFor = htmlForProp ?? itemContext?.id\n\n return <StyledRadioLabel {...restProps} htmlFor={htmlFor} ref={forwardRef} />\n})\n","import React from 'react'\nimport type { ElementRef, ReactNode } from 'react'\n\nimport { StyledRadioGroup } from './radio.styled'\nimport type { StyledRadioGroupProps } from './radio.styled'\nimport { RadioGroupItem } from './radio-item'\nimport { RadioGroupOption } from './radio'\nimport { RadioGroupLabel } from './radio-label'\n\nexport interface RadioGroupProps extends StyledRadioGroupProps {\n /**\n * The controlled value of the selected item. Must be used in conjunction with\n * onValueChange.\n */\n value?: string\n\n /**\n * The value of the item that should be selected when initially rendered. Use\n * when you do not need to control the state of the items.\n */\n defaultValue?: string\n\n /**\n * Event handler called when the selected value changes.\n */\n onValueChange?: (value: string) => void\n\n /**\n * The name of the group. Submitted with its owning form as part of a\n * name/value pair.\n */\n name?: string\n\n /**\n * When true, prevents the user from interacting with any item in the group.\n */\n disabled?: boolean\n\n /**\n * When true, indicates that the user must select a value before the owning\n * form can be submitted.\n */\n required?: boolean\n\n /**\n * The orientation of the group. Also sets the axis for arrow-key navigation.\n * @default 'vertical'\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * The `Radio` items of the group.\n */\n children: ReactNode\n}\n\nexport interface Partials {\n Item: typeof RadioGroupItem\n Option: typeof RadioGroupOption\n Label: typeof RadioGroupLabel\n}\n\n/**\n * Container for a set of mutually exclusive `RadioGroup.Item` rows.\n */\nconst RadioGroupRoot = React.forwardRef<\n ElementRef<typeof StyledRadioGroup>,\n RadioGroupProps\n>(({ children, orientation = 'vertical', ...restProps }, forwardRef) => (\n <StyledRadioGroup orientation={orientation} {...restProps} ref={forwardRef}>\n {children}\n </StyledRadioGroup>\n))\n\nexport const RadioGroup: typeof RadioGroupRoot & Partials = Object.assign(\n RadioGroupRoot,\n {\n Item: RadioGroupItem,\n Option: RadioGroupOption,\n Label: RadioGroupLabel,\n }\n)\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ import * as react from 'react';
2
+ import react__default, { ReactNode } from 'react';
3
+ import * as _mirohq_design_system_primitive from '@mirohq/design-system-primitive';
4
+ import * as _mirohq_design_system_stitches from '@mirohq/design-system-stitches';
5
+ import { StrictComponentProps } from '@mirohq/design-system-stitches';
6
+ import * as _radix_ui_react_radio_group from '@radix-ui/react-radio-group';
7
+ import { Booleanish } from '@mirohq/design-system-types';
8
+
9
+ /* Utilities */
10
+ /* ========================================================================== */
11
+
12
+ /** Returns a string with the given prefix followed by the given values. */
13
+ type Prefixed<K extends string, T> = `${K}${Extract<T, boolean | number | string>}`
14
+
15
+ type TransformProps<Props, Media> = {
16
+ [K in keyof Props]: (
17
+ | Props[K]
18
+ | (
19
+ & {
20
+ [KMedia in Prefixed<'@', 'initial' | keyof Media>]?: Props[K]
21
+ }
22
+ & {
23
+ [KMedia in string]: Props[K]
24
+ }
25
+ )
26
+ )
27
+ }
28
+
29
+ declare const StyledRadioGroup: react.ForwardRefExoticComponent<Omit<Omit<_mirohq_design_system_stitches.StyledComponentProps<react.ForwardRefExoticComponent<_radix_ui_react_radio_group.RadioGroupProps & react.RefAttributes<HTMLDivElement>>>, never> & TransformProps<{}, {}> & _mirohq_design_system_stitches.CustomStylesProps, "ref"> & react.RefAttributes<HTMLDivElement>> & _mirohq_design_system_stitches.StitchesInternals<react.ForwardRefExoticComponent<_radix_ui_react_radio_group.RadioGroupProps & react.RefAttributes<HTMLDivElement>>, {}, {}>;
30
+ /**
31
+ * A single row: the control (`RadioGroup.Option`) next to its label
32
+ * (`RadioGroup.Label`).
33
+ */
34
+ declare const StyledRadioItem: react.ForwardRefExoticComponent<Omit<Omit<_mirohq_design_system_stitches.StyledComponentProps<react.ForwardRefExoticComponent<_mirohq_design_system_primitive.PrimitiveProps<"div">>>, never> & TransformProps<{}, {}> & _mirohq_design_system_stitches.CustomStylesProps, "ref"> & react.RefAttributes<HTMLDivElement>> & _mirohq_design_system_stitches.StitchesInternals<react.ForwardRefExoticComponent<_mirohq_design_system_primitive.PrimitiveProps<"div">>, {}, {}>;
35
+ /**
36
+ * The label rendered next to the control. Associated with the control via
37
+ * `htmlFor`, so clicking it toggles the selection.
38
+ */
39
+ declare const StyledRadioLabel: react.ForwardRefExoticComponent<Omit<Omit<_mirohq_design_system_stitches.StyledComponentProps<"label">, never> & TransformProps<{}, {}> & _mirohq_design_system_stitches.CustomStylesProps, "ref"> & react.RefAttributes<HTMLLabelElement>> & _mirohq_design_system_stitches.StitchesInternals<"label", {}, {}>;
40
+ declare const StyledRadio: react.ForwardRefExoticComponent<Omit<Omit<_mirohq_design_system_stitches.StyledComponentProps<react.ForwardRefExoticComponent<_radix_ui_react_radio_group.RadioGroupItemProps & react.RefAttributes<HTMLButtonElement>>>, "invalid"> & TransformProps<{
41
+ invalid?: boolean | "true" | undefined;
42
+ }, {}> & _mirohq_design_system_stitches.CustomStylesProps, "ref"> & react.RefAttributes<HTMLButtonElement>> & _mirohq_design_system_stitches.StitchesInternals<react.ForwardRefExoticComponent<_radix_ui_react_radio_group.RadioGroupItemProps & react.RefAttributes<HTMLButtonElement>>, {
43
+ invalid?: boolean | "true" | undefined;
44
+ }, {}>;
45
+ type StyledRadioProps = StrictComponentProps<typeof StyledRadio>;
46
+ type StyledRadioGroupProps = StrictComponentProps<typeof StyledRadioGroup>;
47
+ type StyledRadioItemProps = StrictComponentProps<typeof StyledRadioItem>;
48
+ type StyledRadioLabelProps = StrictComponentProps<typeof StyledRadioLabel>;
49
+
50
+ interface ItemProps extends StyledRadioItemProps {
51
+ /**
52
+ * The id shared by the nested `RadioGroup.Option` and `RadioGroup.Label`.
53
+ * Generated automatically when omitted.
54
+ */
55
+ id?: string;
56
+ /**
57
+ * The `RadioGroup.Option` and `RadioGroup.Label` that make up the row.
58
+ */
59
+ children: ReactNode;
60
+ }
61
+ /**
62
+ * A single row of a `RadioGroup`. Wraps a `RadioGroup.Option` (the control) and
63
+ * a `RadioGroup.Label`, and owns the shared id that associates the two.
64
+ */
65
+ declare const RadioGroupItem: react__default.ForwardRefExoticComponent<Omit<ItemProps, "ref"> & react__default.RefAttributes<HTMLDivElement>>;
66
+
67
+ interface OptionProps extends StyledRadioProps {
68
+ /**
69
+ * The value given as data when submitted with a name. Selecting this item
70
+ * sets its owning group's value to this.
71
+ */
72
+ value: string;
73
+ /**
74
+ * When true, indicates that the user must select a value in the owning group
75
+ * before its form can be submitted.
76
+ */
77
+ required?: boolean;
78
+ /**
79
+ * When true, prevents the user from interacting with the radio.
80
+ */
81
+ disabled?: boolean;
82
+ /**
83
+ * When true, prevents the user from interacting with the radio but focus is
84
+ * still possible.
85
+ */
86
+ 'aria-disabled'?: Booleanish;
87
+ /**
88
+ * When true, displays the radio in an error state.
89
+ * @default false
90
+ */
91
+ invalid?: boolean;
92
+ }
93
+ /**
94
+ * The selectable radio control. Reads the shared id from its enclosing
95
+ * `RadioGroup.Item` so its `RadioGroup.Label` can target it.
96
+ */
97
+ declare const RadioGroupOption: react__default.ForwardRefExoticComponent<Omit<OptionProps, "ref"> & react__default.RefAttributes<HTMLButtonElement>>;
98
+
99
+ interface LabelProps extends StyledRadioLabelProps {
100
+ /**
101
+ * The control this label targets. Defaults to the id owned by the enclosing
102
+ * `RadioGroup.Item`.
103
+ */
104
+ htmlFor?: string;
105
+ /**
106
+ * The label content.
107
+ */
108
+ children: ReactNode;
109
+ }
110
+ /**
111
+ * The label for a `RadioGroup.Option`. Associates itself with the control via
112
+ * the shared id from its enclosing `RadioGroup.Item`.
113
+ */
114
+ declare const RadioGroupLabel: react__default.ForwardRefExoticComponent<Omit<LabelProps, "ref"> & react__default.RefAttributes<HTMLLabelElement>>;
115
+
116
+ interface RadioGroupProps extends StyledRadioGroupProps {
117
+ /**
118
+ * The controlled value of the selected item. Must be used in conjunction with
119
+ * onValueChange.
120
+ */
121
+ value?: string;
122
+ /**
123
+ * The value of the item that should be selected when initially rendered. Use
124
+ * when you do not need to control the state of the items.
125
+ */
126
+ defaultValue?: string;
127
+ /**
128
+ * Event handler called when the selected value changes.
129
+ */
130
+ onValueChange?: (value: string) => void;
131
+ /**
132
+ * The name of the group. Submitted with its owning form as part of a
133
+ * name/value pair.
134
+ */
135
+ name?: string;
136
+ /**
137
+ * When true, prevents the user from interacting with any item in the group.
138
+ */
139
+ disabled?: boolean;
140
+ /**
141
+ * When true, indicates that the user must select a value before the owning
142
+ * form can be submitted.
143
+ */
144
+ required?: boolean;
145
+ /**
146
+ * The orientation of the group. Also sets the axis for arrow-key navigation.
147
+ * @default 'vertical'
148
+ */
149
+ orientation?: 'horizontal' | 'vertical';
150
+ /**
151
+ * The `Radio` items of the group.
152
+ */
153
+ children: ReactNode;
154
+ }
155
+ interface Partials {
156
+ Item: typeof RadioGroupItem;
157
+ Option: typeof RadioGroupOption;
158
+ Label: typeof RadioGroupLabel;
159
+ }
160
+ /**
161
+ * Container for a set of mutually exclusive `RadioGroup.Item` rows.
162
+ */
163
+ declare const RadioGroupRoot: react__default.ForwardRefExoticComponent<Omit<RadioGroupProps, "ref"> & react__default.RefAttributes<HTMLDivElement>>;
164
+ declare const RadioGroup: typeof RadioGroupRoot & Partials;
165
+
166
+ export { RadioGroup };
167
+ export type { ItemProps as RadioGroupItemProps, LabelProps as RadioGroupLabelProps, OptionProps as RadioGroupOptionProps, RadioGroupProps };
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@mirohq/design-system-radio",
3
+ "version": "0.1.0",
4
+ "description": "Radio component for the Miro Design System",
5
+ "author": "Miro",
6
+ "source": "src/index.ts",
7
+ "main": "dist/main.js",
8
+ "module": "dist/module.js",
9
+ "types": "dist/types.d.ts",
10
+ "sideEffects": false,
11
+ "exports": {
12
+ ".": {
13
+ "require": "./dist/main.js",
14
+ "import": "./dist/module.js",
15
+ "types": "./dist/types.d.ts"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "peerDependencies": {
25
+ "@stitches/react": "^1.2.8",
26
+ "react": "^16.14 || ^17 || ^18 || ^19"
27
+ },
28
+ "dependencies": {
29
+ "@radix-ui/react-radio-group": "^1.0.0",
30
+ "@mirohq/design-system-primitive": "^2.2.1",
31
+ "@mirohq/design-system-stitches": "^3.3.30",
32
+ "@mirohq/design-system-utils": "^1.3.0",
33
+ "@mirohq/design-system-types": "^1.0.3",
34
+ "@mirohq/design-system-use-id": "^1.1.1"
35
+ },
36
+ "scripts": {
37
+ "build": "rollup -c ../../../rollup.config.js",
38
+ "clean": "rm -rf dist",
39
+ "prebuild": "pnpm clean"
40
+ }
41
+ }