@aristobyte-ui/radio 1.0.0 → 1.0.6

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.
@@ -1,75 +0,0 @@
1
- import * as React from "react";
2
-
3
- import styles from "./Radio.module.scss";
4
-
5
- export interface IRadio {
6
- children: React.ReactNode;
7
- value: string;
8
- checked?: boolean;
9
- onChange?: (value: string) => void;
10
- name?: string;
11
- disabled?: boolean;
12
- className?: string;
13
- highlightLabel?: boolean;
14
- size?: "xsm" | "sm" | "md" | "lg" | "xlg";
15
- variant?:
16
- | "default"
17
- | "primary"
18
- | "secondary"
19
- | "success"
20
- | "error"
21
- | "warning";
22
- appearance?:
23
- | "default"
24
- | "solid"
25
- | "outline"
26
- | "outline-dashed"
27
- | "no-outline"
28
- | "glowing";
29
- alignLabel?: "top" | "right" | "bottom" | "left";
30
- }
31
-
32
- export const Radio: React.FC<IRadio> = ({
33
- children,
34
- value,
35
- checked,
36
- name,
37
- disabled = false,
38
- highlightLabel = false,
39
- className = "",
40
- size = "md",
41
- variant = "default",
42
- appearance = "default",
43
- alignLabel = "right",
44
- onChange,
45
- }) => {
46
- const handleChange = () => {
47
- if (!disabled && onChange) {
48
- onChange(value);
49
- }
50
- };
51
-
52
- return (
53
- <label
54
- className={`${styles["radio"]} ${styles[`radio-align-label--${alignLabel}`]} ${styles[`radio-appearance--${appearance}`]} ${styles[`radio-variant--${variant}`]} ${styles[`radio-size--${size}`]} ${disabled ? styles["radio--disabled"] : ""} ${className}`}
55
- >
56
- <input
57
- type="radio"
58
- name={name}
59
- value={value}
60
- checked={checked}
61
- disabled={disabled}
62
- onChange={handleChange}
63
- className={styles["radio__input"]}
64
- />
65
- <span className={styles["radio__control"]} />
66
- {children && (
67
- <span
68
- className={`${styles["radio__label"]} ${highlightLabel ? styles["radio__label--highlight-label"] : ""}`}
69
- >
70
- {children}
71
- </span>
72
- )}
73
- </label>
74
- );
75
- };
@@ -1,15 +0,0 @@
1
- @use "../../styles/settings" as *;
2
-
3
- .radio-group {
4
- display: flex;
5
- gap: 20px;
6
- min-width: max-content;
7
-
8
- &--horizontal {
9
- flex-direction: row;
10
- }
11
-
12
- &--vertical {
13
- flex-direction: column;
14
- }
15
- }
@@ -1,86 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { Radio, type IRadio } from "../Radio";
5
-
6
- import styles from "./RadioGroup.module.scss";
7
-
8
- export interface IRadioGroup {
9
- name: string;
10
- value: string;
11
- children: React.ReactElement<IRadio> | React.ReactElement<IRadio>[];
12
- onChange?: (newValue: string) => void;
13
- disabled?: boolean;
14
- className?: string;
15
- size?: "xsm" | "sm" | "md" | "lg" | "xlg";
16
- variant?:
17
- | "default"
18
- | "primary"
19
- | "secondary"
20
- | "success"
21
- | "error"
22
- | "warning";
23
- appearance?:
24
- | "solid"
25
- | "outline"
26
- | "outline-dashed"
27
- | "no-outline"
28
- | "glowing";
29
- align?: "horizontal" | "vertical";
30
- alignLabel?: "top" | "right" | "bottom" | "left";
31
- highlightLabel?: boolean;
32
- }
33
-
34
- export const RadioGroup: React.FC<IRadioGroup> = ({
35
- name,
36
- value,
37
- onChange,
38
- children,
39
- disabled = false,
40
- highlightLabel = false,
41
- className = "",
42
- size = "md",
43
- variant = "default",
44
- appearance = "outline",
45
- align = "horizontal",
46
- alignLabel = "right",
47
- }) => {
48
- const uniqueId = React.useId();
49
- const [currentValue, setCurrentValue] = React.useState<string>(value);
50
-
51
- const radios = React.Children.toArray(children).filter(
52
- (child): child is React.ReactElement<IRadio> =>
53
- React.isValidElement(child) && child.type === Radio
54
- );
55
-
56
- const handleChange = (currentRadioValue: string) => {
57
- if (onChange) {
58
- onChange(currentRadioValue);
59
- }
60
-
61
- setCurrentValue(currentRadioValue);
62
- };
63
-
64
- return (
65
- <div
66
- key={uniqueId}
67
- className={`${styles["radio-group"]} ${styles[`radio-group--${align}`]} ${className}`}
68
- >
69
- {radios.map(({ props }) => (
70
- <Radio
71
- {...props}
72
- key={`${name}-${props.value}-${uniqueId}`}
73
- name={`${name}-${props.value}-${uniqueId}`}
74
- checked={props.value === currentValue}
75
- onChange={() => handleChange(props.value)}
76
- disabled={props.disabled ?? disabled}
77
- size={props.size ?? size}
78
- variant={props.variant ?? variant}
79
- appearance={props.appearance ?? appearance}
80
- highlightLabel={props.highlightLabel ?? highlightLabel}
81
- alignLabel={props.alignLabel ?? alignLabel}
82
- />
83
- ))}
84
- </div>
85
- );
86
- };
@@ -1,2 +0,0 @@
1
- export { Radio } from "./Radio";
2
- export { RadioGroup } from "./RadioGroup";
package/eslint.config.mjs DELETED
@@ -1,2 +0,0 @@
1
- import { config } from "@aristobyte-ui/eslint-config/react";
2
- export default config;
package/index.ts DELETED
@@ -1 +0,0 @@
1
- export { Radio, RadioGroup } from "./components";
@@ -1,179 +0,0 @@
1
- // === Design Tokens — Color Palette ===
2
-
3
- // Base
4
- $white: #ffffff;
5
- $black: #000000;
6
- $transparent: transparent;
7
-
8
- // === Black Transparent Scale ===
9
- $black-transparent-100: rgba(0, 0, 0, 0.1);
10
- $black-transparent-200: rgba(0, 0, 0, 0.2);
11
- $black-transparent-300: rgba(0, 0, 0, 0.3);
12
- $black-transparent-400: rgba(0, 0, 0, 0.4);
13
- $black-transparent-500: rgba(0, 0, 0, 0.5);
14
- $black-transparent-600: rgba(0, 0, 0, 0.6);
15
- $black-transparent-700: rgba(0, 0, 0, 0.7);
16
- $black-transparent-800: rgba(0, 0, 0, 0.8);
17
- $black-transparent-900: rgba(0, 0, 0, 0.9);
18
-
19
- // === Black Transparent Scale ===
20
- $white-transparent-100: rgba(255, 255, 255, 0.1);
21
- $white-transparent-200: rgba(255, 255, 255, 0.2);
22
- $white-transparent-300: rgba(255, 255, 255, 0.3);
23
- $white-transparent-400: rgba(255, 255, 255, 0.4);
24
- $white-transparent-500: rgba(255, 255, 255, 0.5);
25
- $white-transparent-600: rgba(255, 255, 255, 0.6);
26
- $white-transparent-700: rgba(255, 255, 255, 0.7);
27
- $white-transparent-800: rgba(255, 255, 255, 0.8);
28
- $white-transparent-900: rgba(255, 255, 255, 0.9);
29
-
30
- // === Neutral Scale (Grey) ===
31
- $grey-50: #f9fafb;
32
- $grey-100: #f3f4f6;
33
- $grey-200: #e5e7eb;
34
- $grey-300: #d1d5db;
35
- $grey-400: #9ca3af;
36
- $grey-500: #6b7280;
37
- $grey-600: #4b5563;
38
- $grey-700: #374151;
39
- $grey-800: #1f2937;
40
- $grey-900: #111827;
41
-
42
- // === Primary Scale (Blue) ===
43
- $blue-50: #eff6ff;
44
- $blue-100: #dbeafe;
45
- $blue-200: #bfdbfe;
46
- $blue-300: #93c5fd;
47
- $blue-400: #60a5fa;
48
- $blue-500: #3b82f6;
49
- $blue-600: #2563eb; // Main
50
- $blue-700: #1d4ed8; // Hover
51
- $blue-800: #1e40af;
52
- $blue-900: #1e3a8a;
53
-
54
- // === Secondary Scale (Indigo) ===
55
- $indigo-50: #eef2ff;
56
- $indigo-100: #e0e7ff;
57
- $indigo-200: #c7d2fe;
58
- $indigo-300: #a5b4fc;
59
- $indigo-400: #818cf8;
60
- $indigo-500: #6366f1;
61
- $indigo-600: #4f46e5; // Main
62
- $indigo-700: #4338ca; // Hover
63
-
64
- // === Error Scale (Red) ===
65
- $red-50: #fef2f2;
66
- $red-100: #fee2e2;
67
- $red-200: #fecaca;
68
- $red-300: #fca5a5;
69
- $red-400: #f87171;
70
- $red-500: #ef4444;
71
- $red-600: #dc2626; // Main
72
- $red-700: #b91c1c; // Hover
73
-
74
- // === Success Scale (Green) ===
75
- $green-50: #f0fdf4;
76
- $green-100: #dcfce7;
77
- $green-200: #bbf7d0;
78
- $green-300: #86efac;
79
- $green-400: #4ade80;
80
- $green-500: #22c55e;
81
- $green-600: #16a34a; // Main
82
- $green-700: #15803d; // Hover
83
-
84
- // === Warning Scale (Amber) ===
85
- $amber-50: #fffbeb;
86
- $amber-100: #fef3c7;
87
- $amber-200: #fde68a;
88
- $amber-300: #fcd34d;
89
- $amber-400: #fbbf24;
90
- $amber-500: #f59e0b;
91
- $amber-600: #d97706; // Main
92
- $amber-700: #b45309; // Hover
93
-
94
- // === Semantic Tokens ===
95
- $color-default: $grey-800;
96
- $color-default-hover: $grey-900;
97
- $color-default-disabled: rgba($color-default, 0.5);
98
-
99
- $color-primary: $blue-600;
100
- $color-primary-hover: $blue-700;
101
- $color-primary-disabled: rgba($color-primary, 0.5);
102
-
103
- $color-secondary: $indigo-600;
104
- $color-secondary-hover: $indigo-700;
105
- $color-secondary-disabled: rgba($color-secondary, 0.5);
106
-
107
- $color-error: $red-600;
108
- $color-error-hover: $red-700;
109
- $color-error-disabled: rgba($color-error, 0.5);
110
-
111
- $color-success: $green-600;
112
- $color-success-hover: $green-700;
113
- $color-success-disabled: rgba($color-success, 0.5);
114
-
115
- $color-warning: $amber-600;
116
- $color-warning-hover: $amber-700;
117
- $color-warning-disabled: rgba($color-warning, 0.5);
118
-
119
- $text-color-white: $white;
120
- $text-color-black: $black;
121
- $text-color-white-disabled: rgba($white, 0.5);
122
- $text-color-black-disabled: rgba($black, 0.5);
123
-
124
- // === Shadows ===
125
- $shadow-sm: 0 1px 2px 0 rgba($black, 0.05);
126
- $shadow-md:
127
- 0 4px 6px -1px rgba($black, 0.1),
128
- 0 2px 4px -1px rgba($black, 0.06);
129
- $shadow-lg:
130
- 0 10px 15px -3px rgba($black, 0.1),
131
- 0 4px 6px -2px rgba($black, 0.05);
132
-
133
- // === Font families ===
134
- $font-family-sans: "Inter", sans-serif;
135
- $font-family-serif: "Georgia", serif;
136
- $font-family-mono: "Fira Code", monospace;
137
-
138
- // === Font weights ===
139
- $font-weight-regular: 400;
140
- $font-weight-medium: 500;
141
- $font-weight-semibold: 600;
142
- $font-weight-bold: 700;
143
-
144
- // === Line heights ===
145
- $line-height-tight: 1.2;
146
- $line-height-snug: 1.375;
147
- $line-height-normal: 1.5;
148
- $line-height-loose: 1.625;
149
-
150
- // === Font Sizes — Semantic Tokens ===
151
-
152
- // === Titles ===
153
- $font-size-hero: 3rem; // 48px
154
- $font-size-title-1: 2.25rem; // 36px
155
- $font-size-title-2: 1.875rem; // 30px
156
- $font-size-title-3: 1.5rem; // 24px
157
-
158
- // === Subtitles ===
159
- $font-size-subtitle-1: 1.25rem; // 20px
160
- $font-size-subtitle-2: 1.125rem; // 18px
161
-
162
- // === Body text ===
163
- $font-size-body-lg: 1rem; // 16px
164
- $font-size-body-md: 0.9375rem; // 15px
165
- $font-size-body-sm: 0.875rem; // 14px
166
-
167
- // === Captions / Descriptions ===
168
- $font-size-caption: 0.75rem; // 12px
169
- $font-size-footnote: 0.6875rem; // 11px
170
-
171
- // === Buttons ===
172
- $font-size-button-lg: 1rem; // 16px
173
- $font-size-button-md: 0.875rem; // 14px
174
- $font-size-button-sm: 0.75rem; // 12px
175
-
176
- // === Animations ===
177
-
178
- $cubic-bezier-primary: cubic-bezier(0.55, -0.19, 0.59, 0.95);
179
- $cubic-bezier-secondary: cubic-bezier(0.175, 0.885, 0.32, 1.275);
package/tsconfig.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "@aristobyte-ui/typescript-config/package",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "declarationDir": "dist/types",
6
- "baseUrl": ".",
7
- "typeRoots": ["./@types", "./node_modules/@types"]
8
- },
9
- "include": ["@types", "components", "utils", "index.ts"],
10
- "exclude": ["node_modules", "dist"]
11
- }
@@ -1,30 +0,0 @@
1
- import type { PlopTypes } from "@turbo/gen";
2
-
3
- // Learn more about Turborepo Generators at https://turborepo.com/docs/guides/generating-code
4
-
5
- export default function generator(plop: PlopTypes.NodePlopAPI): void {
6
- // A simple generator to add a new React component to the internal UI library
7
- plop.setGenerator("react-component", {
8
- description: "Adds a new react component",
9
- prompts: [
10
- {
11
- type: "input",
12
- name: "name",
13
- message: "What is the name of the component?",
14
- },
15
- ],
16
- actions: [
17
- {
18
- type: "add",
19
- path: "src/{{kebabCase name}}.tsx",
20
- templateFile: "templates/component.hbs",
21
- },
22
- {
23
- type: "append",
24
- path: "package.json",
25
- pattern: /"exports": {(?<insertion>)/g,
26
- template: ' "./{{kebabCase name}}": "./src/{{kebabCase name}}.tsx",',
27
- },
28
- ],
29
- });
30
- }
@@ -1,8 +0,0 @@
1
- export const {{ pascalCase name }} = ({ children }: { children: React.ReactNode }) => {
2
- return (
3
- <div>
4
- <h1>{{ pascalCase name }} Component</h1>
5
- {children}
6
- </div>
7
- );
8
- };
package/utils/Portal.tsx DELETED
@@ -1,17 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { createPortal } from "react-dom";
5
-
6
- export const Portal: React.FC<{ children: React.ReactNode }> = ({
7
- children,
8
- }) => {
9
- const [mounted, setMounted] = React.useState(false);
10
-
11
- React.useEffect(() => {
12
- setMounted(true);
13
- }, []);
14
-
15
- if (!mounted || typeof window === "undefined") return null;
16
- return createPortal(children, document.body);
17
- };
package/utils/icons.ts DELETED
@@ -1,13 +0,0 @@
1
- import Copy from "../assets/svg/i_Copy.svg";
2
- import Error from "../assets/svg/i_Error.svg";
3
- import Info from "../assets/svg/i_Info.svg";
4
- import Success from "../assets/svg/i_Success.svg";
5
- import Warning from "../assets/svg/i_Warning.svg";
6
-
7
- export const Icons = {
8
- Copy,
9
- Error,
10
- Info,
11
- Success,
12
- Warning,
13
- };
package/utils/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export { renderRipple, type RippleParams } from "./ripple";
2
- export { Icons } from "./icons";
package/utils/ripple.tsx DELETED
@@ -1,54 +0,0 @@
1
- type RippleParamsRef = HTMLButtonElement | HTMLAnchorElement;
2
-
3
- export type RippleParams<HTMLElementType extends RippleParamsRef> = {
4
- ref: React.RefObject<HTMLElementType | null>;
5
- clientX: number;
6
- clientY: number;
7
- };
8
-
9
- export const renderRipple = <HTMLElementType extends RippleParamsRef>({
10
- ref,
11
- clientX,
12
- clientY,
13
- }: RippleParams<HTMLElementType>) => {
14
- const button = ref.current;
15
- if (!button) return;
16
-
17
- const circle = document.createElement("span");
18
- const diameter = Math.max(button.clientWidth, button.clientHeight);
19
- const radius = diameter / 2;
20
-
21
- circle.id = "ripple";
22
-
23
- const style = document.createElement("style");
24
- style.innerHTML = `
25
- #ripple {
26
- animation: ripple 300ms linear;
27
- background-color: rgba(255, 255, 255, 0.3);
28
- border-radius: 50%;
29
- height: ${diameter}px;
30
- left: ${clientX - button.getBoundingClientRect().left - radius}px;
31
- pointer-events: none;
32
- position: absolute;
33
- top: ${clientY - button.getBoundingClientRect().top - radius}px;
34
- transform: scale(0);
35
- width: ${diameter}px;
36
- z-index: 0;
37
- }
38
-
39
- @keyframes ripple {
40
- to {
41
- opacity: 0;
42
- transform: scale(2);
43
- }
44
- }
45
- `;
46
-
47
- button.appendChild(style);
48
- button.appendChild(circle);
49
-
50
- circle.addEventListener("animationend", () => {
51
- circle.remove();
52
- style.remove();
53
- });
54
- };