@plexui/ui 0.6.0 → 0.7.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/README.md +2 -2
- package/dist/es/components/CodeBlock/CodeBlock.module.css +24 -11
- package/dist/es/components/Sidebar/Sidebar.module.css +0 -1
- package/dist/es/components/Switch/Switch.js +3 -2
- package/dist/es/components/Switch/Switch.js.map +1 -1
- package/dist/es/components/Switch/Switch.module.css +28 -2
- package/dist/types/components/Switch/Switch.d.ts +4 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @plexui/ui
|
|
2
2
|
|
|
3
|
-
A modern React component library
|
|
3
|
+
A modern React component library with 35 production-ready components, 14 hooks, a three-layer design token system, and a unified 9-step size scale — all powered by Radix primitives and Tailwind CSS 4.
|
|
4
4
|
|
|
5
5
|
[Documentation](https://plexui.com) • [GitHub](https://github.com/plex-ui/docs) • [Figma Kit](https://plexui.com/#pricing)
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ A modern React component library built on the same design foundations as OpenAI'
|
|
|
10
10
|
|
|
11
11
|
## Highlights
|
|
12
12
|
|
|
13
|
-
- **
|
|
13
|
+
- **Production-grade** — components designed and tested for real products at scale.
|
|
14
14
|
- **9-step size scale** — all key controls (Button, Input, Select, SegmentedControl, etc.) share a unified `ControlSize` scale from `3xs` (22 px) to `3xl` (48 px). Most competitors offer only 3–4.
|
|
15
15
|
- **Three-layer design tokens** — primitive → semantic → component CSS custom properties with `light-dark()` theming, alpha transparency scale, and 4-level elevation system.
|
|
16
16
|
- **Radix + Tailwind 4** — accessible primitives under the hood, utility-first styling on top.
|
|
@@ -5,18 +5,31 @@
|
|
|
5
5
|
background-color: var(--codeblock-background-color);
|
|
6
6
|
}.CopyButtonContainer {
|
|
7
7
|
position: absolute;
|
|
8
|
-
top:
|
|
9
|
-
right:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
top: 8px;
|
|
9
|
+
right: 8px;
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
display: grid;
|
|
12
|
+
place-items: center;
|
|
13
|
+
width: 32px;
|
|
14
|
+
height: 32px;
|
|
15
|
+
border-radius: 8px;
|
|
16
|
+
background-color: var(--color-surface-elevated-secondary);
|
|
17
|
+
color: var(--color-text-secondary);
|
|
13
18
|
}/* Force the CopyButton to inherit the container's color on all states.
|
|
14
19
|
Ghost hover background (::before) is preserved — it's the correct behavior. */.CopyButtonContainer button {
|
|
15
20
|
color: inherit !important;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
padding: 0 !important;
|
|
22
|
+
-webkit-tap-highlight-color: transparent;
|
|
23
|
+
}.CopyButtonContainer button::before {
|
|
24
|
+
opacity: 0 !important;
|
|
25
|
+
transform: none !important;
|
|
26
|
+
background-color: transparent !important;
|
|
27
|
+
box-shadow: none !important;
|
|
28
|
+
}.CopyButtonContainer button:focus,
|
|
29
|
+
.CopyButtonContainer button:focus-visible {
|
|
30
|
+
outline: none !important;
|
|
31
|
+
}.CopyButtonContainer button:focus-visible::after {
|
|
32
|
+
outline: none !important;
|
|
20
33
|
}.SyntaxHighlighter {
|
|
21
34
|
--syntax1: var(--codeblock-syntax-1);
|
|
22
35
|
--syntax2: var(--codeblock-syntax-2);
|
|
@@ -35,7 +48,7 @@
|
|
|
35
48
|
/* 14px to a 16px baseline */
|
|
36
49
|
font-weight: var(--font-weight-normal);
|
|
37
50
|
line-height: 1.714em;
|
|
38
|
-
/* 24px at 14px
|
|
51
|
+
/* 24px at 14px */
|
|
39
52
|
|
|
40
53
|
/* stylelint-disable selector-class-pattern */
|
|
41
54
|
|
|
@@ -115,4 +128,4 @@
|
|
|
115
128
|
align-items: center;
|
|
116
129
|
justify-content: center;
|
|
117
130
|
}
|
|
118
|
-
}
|
|
131
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
@layer components {/* =============================================
|
|
2
2
|
Sidebar Component Styles
|
|
3
|
-
Based on OpenAI Platform styling
|
|
4
3
|
============================================= *//* Layout container (wraps sidebar + content) */.SidebarLayout {
|
|
5
4
|
display: flex;
|
|
6
5
|
width: 100%;
|
|
@@ -4,9 +4,10 @@ import clsx from "clsx";
|
|
|
4
4
|
import { Switch as RadixSwitch } from "radix-ui";
|
|
5
5
|
import { useId } from "react";
|
|
6
6
|
import s from "./Switch.module.css";
|
|
7
|
-
export const Switch = ({ className, label, id: propsId, disabled, labelPosition = "end", ...restProps }) => {
|
|
7
|
+
export const Switch = ({ className, label, description, id: propsId, disabled, labelPosition = "end", ...restProps }) => {
|
|
8
8
|
const reactId = useId();
|
|
9
9
|
const id = propsId ?? reactId;
|
|
10
|
-
|
|
10
|
+
const descriptionId = description ? `${id}-description` : undefined;
|
|
11
|
+
return (_jsxs("div", { className: clsx(s.Container, className), "data-disabled": disabled ? "" : undefined, "data-has-label": label ? "" : undefined, "data-label-position": labelPosition, children: [_jsx(RadixSwitch.Root, { id: id, className: s.Track, disabled: disabled, "aria-describedby": descriptionId, ...restProps, children: _jsx(RadixSwitch.Thumb, { className: s.Thumb }) }), label && (description ? (_jsxs("div", { className: s.LabelGroup, children: [_jsx("label", { htmlFor: id, className: s.Label, children: label }), _jsx("span", { id: descriptionId, className: s.Description, children: description })] })) : (_jsx("label", { htmlFor: id, className: s.Label, children: label })))] }));
|
|
11
12
|
};
|
|
12
13
|
//# sourceMappingURL=Switch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.js","sourceRoot":"","sources":["../../../../src/components/Switch/Switch.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAA0C,KAAK,EAAE,MAAM,OAAO,CAAA;AACrE,OAAO,CAAC,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"Switch.js","sourceRoot":"","sources":["../../../../src/components/Switch/Switch.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAA0C,KAAK,EAAE,MAAM,OAAO,CAAA;AACrE,OAAO,CAAC,MAAM,qBAAqB,CAAA;AAoCnC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EACrB,SAAS,EACT,KAAK,EACL,WAAW,EACX,EAAE,EAAE,OAAO,EACX,QAAQ,EACR,aAAa,GAAG,KAAK,EACrB,GAAG,SAAS,EACA,EAAE,EAAE;IAChB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAA;IACvB,MAAM,EAAE,GAAG,OAAO,IAAI,OAAO,CAAA;IAC7B,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,SAAS,CAAA;IAEnE,OAAO,CACL,eACE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,mBACxB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,oBACxB,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,yBACjB,aAAa,aAElC,KAAC,WAAW,CAAC,IAAI,IACf,EAAE,EAAE,EAAE,EACN,SAAS,EAAE,CAAC,CAAC,KAAK,EAClB,QAAQ,EAAE,QAAQ,sBACA,aAAa,KAC3B,SAAS,YAEb,KAAC,WAAW,CAAC,KAAK,IAAC,SAAS,EAAE,CAAC,CAAC,KAAK,GAAI,GACxB,EAElB,KAAK,IAAI,CACR,WAAW,CAAC,CAAC,CAAC,CACZ,eAAK,SAAS,EAAE,CAAC,CAAC,UAAU,aAC1B,gBAAO,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,YACnC,KAAK,GACA,EACR,eAAM,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,WAAW,YAC9C,WAAW,GACP,IACH,CACP,CAAC,CAAC,CAAC,CACF,gBAAO,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,YACnC,KAAK,GACA,CACT,CACF,IACG,CACP,CAAA;AACH,CAAC,CAAA","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { Switch as RadixSwitch } from \"radix-ui\"\nimport { type FocusEventHandler, type ReactNode, useId } from \"react\"\nimport s from \"./Switch.module.css\"\n\nexport type SwitchProps = {\n /** The `id` of the switch. */\n id?: string\n /** The state of the switch when it is initially rendered. Use when you do not need to control its state. */\n defaultChecked?: boolean\n /** The controlled state of the switch. Must be used in conjunction with `onCheckedChange`. */\n checked?: boolean\n /** Optional accessible label rendered next to the switch. */\n label?: ReactNode\n /** Optional description rendered below the label. Linked via `aria-describedby`. */\n description?: ReactNode\n /** Event handler called when the state of the switch changes. */\n onCheckedChange?: (nextState: boolean) => void\n /** Event handler called when the checkbox looses focus. */\n onBlur?: FocusEventHandler<HTMLButtonElement>\n /** Event handler called when the checkbox gains focus. */\n onFocus?: FocusEventHandler<HTMLButtonElement>\n /** When `true`, prevents the user from interacting with the switch. */\n disabled?: boolean\n /** When `true`, indicates that the user must check the switch before the owning form can be submitted. */\n required?: boolean\n /** The name of the switch. Submitted with its owning form as part of a name/value pair. */\n name?: string\n /** The value given as data when submitted with a `name`. */\n value?: string\n /** CSS classes applied to wrapper node */\n className?: string\n /**\n * The position of the label relative to the switch.\n * @default end\n */\n labelPosition?: \"start\" | \"end\"\n}\n\nexport const Switch = ({\n className,\n label,\n description,\n id: propsId,\n disabled,\n labelPosition = \"end\",\n ...restProps\n}: SwitchProps) => {\n const reactId = useId()\n const id = propsId ?? reactId\n const descriptionId = description ? `${id}-description` : undefined\n\n return (\n <div\n className={clsx(s.Container, className)}\n data-disabled={disabled ? \"\" : undefined}\n data-has-label={label ? \"\" : undefined}\n data-label-position={labelPosition}\n >\n <RadixSwitch.Root\n id={id}\n className={s.Track}\n disabled={disabled}\n aria-describedby={descriptionId}\n {...restProps}\n >\n <RadixSwitch.Thumb className={s.Thumb} />\n </RadixSwitch.Root>\n\n {label && (\n description ? (\n <div className={s.LabelGroup}>\n <label htmlFor={id} className={s.Label}>\n {label}\n </label>\n <span id={descriptionId} className={s.Description}>\n {description}\n </span>\n </div>\n ) : (\n <label htmlFor={id} className={s.Label}>\n {label}\n </label>\n )\n )}\n </div>\n )\n}\n"]}
|
|
@@ -75,20 +75,46 @@
|
|
|
75
75
|
.Thumb[data-disabled] {
|
|
76
76
|
background: var(--switch-thumb-color-disabled);
|
|
77
77
|
box-shadow: none;
|
|
78
|
+
}.LabelGroup {
|
|
79
|
+
display: flex;
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
gap: 4px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Use padding so that the spacing is intrinsic to the group, remaining clickable. */
|
|
85
|
+
[data-label-position="end"] .LabelGroup {
|
|
86
|
+
padding-left: var(--switch-label-gap);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
[data-label-position="start"] .LabelGroup {
|
|
90
|
+
padding-right: var(--switch-label-gap);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[data-disabled] .LabelGroup {
|
|
94
|
+
cursor: not-allowed;
|
|
78
95
|
}.Label {
|
|
79
96
|
cursor: pointer;
|
|
80
97
|
}
|
|
81
98
|
|
|
82
99
|
/* Use padding so that the spacing is intrinsic to the label, remaining clickable. */
|
|
83
|
-
[data-label-position="end"] .Label {
|
|
100
|
+
[data-label-position="end"] > .Label {
|
|
84
101
|
padding-left: var(--switch-label-gap);
|
|
85
102
|
}
|
|
86
103
|
|
|
87
|
-
[data-label-position="start"] .Label {
|
|
104
|
+
[data-label-position="start"] > .Label {
|
|
88
105
|
padding-right: var(--switch-label-gap);
|
|
89
106
|
}
|
|
90
107
|
|
|
91
108
|
[data-disabled] .Label {
|
|
92
109
|
cursor: not-allowed;
|
|
110
|
+
}.Description {
|
|
111
|
+
color: var(--color-text-secondary);
|
|
112
|
+
font-size: var(--font-text-xs-size);
|
|
113
|
+
line-height: var(--font-text-xs-line-height);
|
|
114
|
+
cursor: pointer;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
[data-disabled] .Description {
|
|
118
|
+
cursor: not-allowed;
|
|
93
119
|
}
|
|
94
120
|
}
|
|
@@ -6,8 +6,10 @@ export type SwitchProps = {
|
|
|
6
6
|
defaultChecked?: boolean;
|
|
7
7
|
/** The controlled state of the switch. Must be used in conjunction with `onCheckedChange`. */
|
|
8
8
|
checked?: boolean;
|
|
9
|
-
/** Optional accessible label rendered to the
|
|
9
|
+
/** Optional accessible label rendered next to the switch. */
|
|
10
10
|
label?: ReactNode;
|
|
11
|
+
/** Optional description rendered below the label. Linked via `aria-describedby`. */
|
|
12
|
+
description?: ReactNode;
|
|
11
13
|
/** Event handler called when the state of the switch changes. */
|
|
12
14
|
onCheckedChange?: (nextState: boolean) => void;
|
|
13
15
|
/** Event handler called when the checkbox looses focus. */
|
|
@@ -30,4 +32,4 @@ export type SwitchProps = {
|
|
|
30
32
|
*/
|
|
31
33
|
labelPosition?: "start" | "end";
|
|
32
34
|
};
|
|
33
|
-
export declare const Switch: ({ className, label, id: propsId, disabled, labelPosition, ...restProps }: SwitchProps) => import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
export declare const Switch: ({ className, label, description, id: propsId, disabled, labelPosition, ...restProps }: SwitchProps) => import("react/jsx-runtime").JSX.Element;
|