@locus-ui/components 0.0.1 → 0.0.12
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 +155 -0
- package/dist/index.css +53 -3
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +42 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +190 -149
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -1
package/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# @locus-ui/components
|
|
2
|
+
|
|
3
|
+
**GitHub:** [https://github.com/LocusInc/locus-ui](https://github.com/LocusInc/locus-ui)
|
|
4
|
+
|
|
5
|
+
An (optionally) unstyled modern React UI component library built with Tailwind CSS v4, featuring compound components, responsive props, and a powerful theming system.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Theming** — Light/dark mode, configurable radius, roundness, and spacing with nestable sub-themes
|
|
10
|
+
- **Compound Components** — Select, Accordion, Checkbox, and Portal use intuitive dot-notation APIs
|
|
11
|
+
- **Responsive Props** — Margin, padding, radius, and spacing support breakpoint objects (`{ initial: "sm", lg: "xl" }`)
|
|
12
|
+
- **Data-Attribute Styling** — Styling driven by `data-*` attributes for clean separation of logic and CSS
|
|
13
|
+
- **Tree-Shakeable** — ESM + CJS dual output with code splitting
|
|
14
|
+
- **Next.js Ready** — All components are `"use client"` compatible
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @locus-ui/components
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Peer Dependencies
|
|
23
|
+
|
|
24
|
+
- `react` ^18.0.0 || ^19.0.0
|
|
25
|
+
- `react-dom` ^18.0.0 || ^19.0.0
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
Import the stylesheet and wrap your app with the `Theme` provider:
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { Theme } from "@locus-ui/components";
|
|
33
|
+
import "@locus-ui/components/styles";
|
|
34
|
+
|
|
35
|
+
export default function App({ children }) {
|
|
36
|
+
return (
|
|
37
|
+
<Theme appearance="light" radius="md" spacing="md">
|
|
38
|
+
{children}
|
|
39
|
+
</Theme>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage Examples
|
|
45
|
+
|
|
46
|
+
### Button
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { Button } from "@locus-ui/components";
|
|
50
|
+
|
|
51
|
+
<Button variant="solid" color="primary" size="md">
|
|
52
|
+
Click me
|
|
53
|
+
</Button>;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Select
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { Select } from "@locus-ui/components";
|
|
60
|
+
|
|
61
|
+
<Select.Root variant="outlined" placeholder="Choose a fruit">
|
|
62
|
+
<Select.Trigger />
|
|
63
|
+
<Select.Content>
|
|
64
|
+
<Select.Item value="apple">Apple</Select.Item>
|
|
65
|
+
<Select.Item value="banana">Banana</Select.Item>
|
|
66
|
+
<Select.Item value="cherry">Cherry</Select.Item>
|
|
67
|
+
</Select.Content>
|
|
68
|
+
</Select.Root>;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Accordion
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { Accordion } from "@locus-ui/components";
|
|
75
|
+
|
|
76
|
+
<Accordion.Root variant="outlined" multiple>
|
|
77
|
+
<Accordion.Item value="item-1">
|
|
78
|
+
<Accordion.Header>Section 1</Accordion.Header>
|
|
79
|
+
<Accordion.Content>Content for section 1</Accordion.Content>
|
|
80
|
+
</Accordion.Item>
|
|
81
|
+
<Accordion.Item value="item-2">
|
|
82
|
+
<Accordion.Header>Section 2</Accordion.Header>
|
|
83
|
+
<Accordion.Content>Content for section 2</Accordion.Content>
|
|
84
|
+
</Accordion.Item>
|
|
85
|
+
</Accordion.Root>;
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Checkbox
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import { Checkbox } from "@locus-ui/components";
|
|
92
|
+
|
|
93
|
+
<Checkbox.Root
|
|
94
|
+
color="primary"
|
|
95
|
+
onCheckedChange={(checked) => console.log(checked)}
|
|
96
|
+
>
|
|
97
|
+
<Checkbox.Indicator />
|
|
98
|
+
<Checkbox.Label>Accept terms</Checkbox.Label>
|
|
99
|
+
</Checkbox.Root>;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Theming
|
|
103
|
+
|
|
104
|
+
By default, locus-ui components are unstyled so that you have complete control over the look and feel of your project.
|
|
105
|
+
|
|
106
|
+
However we do provide styles for each component as long as a variant is given to the component.
|
|
107
|
+
|
|
108
|
+
To use our provided styles, wrap your app in `<Theme>` to configure design tokens. Themes can be nested to create sub-themes that inherit and override parent values.
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
<Theme appearance="dark" radius="lg" roundness="4" spacing="md">
|
|
112
|
+
{/* Dark themed content */}
|
|
113
|
+
<Theme appearance="light" radius="sm">
|
|
114
|
+
{/* Light sub-theme inheriting roundness and spacing */}
|
|
115
|
+
</Theme>
|
|
116
|
+
</Theme>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Access theme values programmatically with the `useTheme` hook:
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { useTheme } from "@locus-ui/components";
|
|
123
|
+
|
|
124
|
+
const { appearance, setAppearance, radius, spacing } = useTheme();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
| Token | Values | Default |
|
|
128
|
+
| ------------ | ----------------------------------------------------------------------- | --------- |
|
|
129
|
+
| `appearance` | `"light"`, `"dark"`, `"inherit"` | `"light"` |
|
|
130
|
+
| `radius` | `"none"`, `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`, `"full"`, `"inherit"` | `"md"` |
|
|
131
|
+
| `roundness` | `"1"` – `"6"`, `"inherit"` | `"3"` |
|
|
132
|
+
| `spacing` | `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`, `"inherit"` | `"md"` |
|
|
133
|
+
|
|
134
|
+
## Shared Props
|
|
135
|
+
|
|
136
|
+
Most components accept these common props:
|
|
137
|
+
|
|
138
|
+
| Prop | Values |
|
|
139
|
+
| --------- | ---------------------------------------------------------------------------------------------------- |
|
|
140
|
+
| `color` | `"primary"`, `"secondary"`, `"tertiary"`, `"accent"`, `"success"`, `"warning"`, `"danger"`, `"info"` |
|
|
141
|
+
| `size` | `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"` |
|
|
142
|
+
| `variant` | `"solid"`, `"outlined"`, `"muted"`, `"clear"` |
|
|
143
|
+
| `radius` | `"none"`, `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`, `"full"`, `"inherit"` |
|
|
144
|
+
| `margin` | `-8` to `8`, `"auto"` (directional: `mt`, `mb`, `ml`, `mr`, `mx`, `my`) |
|
|
145
|
+
| `padding` | `0` to `8` (directional: `pt`, `pb`, `pl`, `pr`, `px`, `py`) |
|
|
146
|
+
|
|
147
|
+
All layout props support responsive breakpoint objects:
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
<Box p={{ initial: "2", md: "4", lg: "8" }} />
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
ISC
|
package/dist/index.css
CHANGED
|
@@ -90,6 +90,58 @@
|
|
|
90
90
|
padding: calc(8px * var(--lcs-spacing, 1)) calc(12px * var(--lcs-spacing, 1));
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
+
.badge[data-variant] {
|
|
94
|
+
--badge-color: var(--color, var(--primary));
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: center;
|
|
97
|
+
height: -moz-fit-content;
|
|
98
|
+
height: fit-content;
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
border-radius: var(--lcs-radius, 1);
|
|
101
|
+
padding: calc(1px * var(--lcs-spacing, 1)) calc(6px * var(--lcs-spacing, 1));
|
|
102
|
+
gap: calc(5px * var(--lcs-spacing, 1));
|
|
103
|
+
font-size: small;
|
|
104
|
+
&[data-size=xs] {
|
|
105
|
+
padding: calc(1px * var(--lcs-spacing, 1)) calc(4px * var(--lcs-spacing, 1));
|
|
106
|
+
gap: calc(3px * var(--lcs-spacing, 1));
|
|
107
|
+
font-size: xx-small;
|
|
108
|
+
}
|
|
109
|
+
&[data-size=sm] {
|
|
110
|
+
padding: calc(1px * var(--lcs-spacing, 1)) calc(4px * var(--lcs-spacing, 1));
|
|
111
|
+
gap: calc(4px * var(--lcs-spacing, 1));
|
|
112
|
+
font-size: x-small;
|
|
113
|
+
}
|
|
114
|
+
&[data-size=lg] {
|
|
115
|
+
padding: calc(1px * var(--lcs-spacing, 1)) calc(6px * var(--lcs-spacing, 1));
|
|
116
|
+
gap: calc(6px * var(--lcs-spacing, 1));
|
|
117
|
+
font-size: medium;
|
|
118
|
+
}
|
|
119
|
+
&[data-size=xl] {
|
|
120
|
+
padding: calc(1px * var(--lcs-spacing, 1)) calc(8px * var(--lcs-spacing, 1));
|
|
121
|
+
gap: calc(8px * var(--lcs-spacing, 1));
|
|
122
|
+
font-size: large;
|
|
123
|
+
}
|
|
124
|
+
&[data-variant=solid] {
|
|
125
|
+
border: 1px solid rgba(var(--badge-color), 0.8);
|
|
126
|
+
background-color: rgba(var(--badge-color), 0.7);
|
|
127
|
+
color: white;
|
|
128
|
+
}
|
|
129
|
+
&[data-variant=outlined] {
|
|
130
|
+
border: 1px solid rgba(var(--badge-color));
|
|
131
|
+
background-color: rgba(var(--badge-color), 0.12);
|
|
132
|
+
color: rgba(var(--badge-color));
|
|
133
|
+
}
|
|
134
|
+
&[data-variant=muted] {
|
|
135
|
+
border: 1px solid rgba(var(--badge-color), 0.1);
|
|
136
|
+
background-color: rgba(var(--badge-color), 0.2);
|
|
137
|
+
color: rgba(var(--badge-color));
|
|
138
|
+
}
|
|
139
|
+
&[data-variant=clear] {
|
|
140
|
+
border: 1px solid transparent;
|
|
141
|
+
background-color: transparent;
|
|
142
|
+
color: rgba(var(--badge-color));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
93
145
|
.button[data-variant] {
|
|
94
146
|
--button-color: var(--color, var(--primary));
|
|
95
147
|
height: -moz-fit-content;
|
|
@@ -375,7 +427,6 @@
|
|
|
375
427
|
}
|
|
376
428
|
&[data-variant=blurred] {
|
|
377
429
|
background-color: rgba(0, 0, 0, var(--backdrop-opacity, 0.3));
|
|
378
|
-
-webkit-backdrop-filter: blur(var(--backdrop-blur, 2px));
|
|
379
430
|
backdrop-filter: blur(var(--backdrop-blur, 2px));
|
|
380
431
|
}
|
|
381
432
|
}
|
|
@@ -567,7 +618,6 @@
|
|
|
567
618
|
background-color: rgba(var(--background-color-1), 0.9);
|
|
568
619
|
border-radius: min(var(--lcs-radius), 24px);
|
|
569
620
|
box-shadow: var(--shadow-md);
|
|
570
|
-
-webkit-backdrop-filter: blur(var(--lcs-backdrop-blur, 2px));
|
|
571
621
|
backdrop-filter: blur(var(--lcs-backdrop-blur, 2px));
|
|
572
622
|
overflow: hidden;
|
|
573
623
|
}
|
|
@@ -9818,5 +9868,5 @@
|
|
|
9818
9868
|
@custom-media --md (min-width: 1024px);
|
|
9819
9869
|
@custom-media --lg (min-width: 1280px);
|
|
9820
9870
|
@custom-media --xl (min-width: 1640px);
|
|
9821
|
-
/*! tailwindcss v4.
|
|
9871
|
+
/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
|
|
9822
9872
|
/*# sourceMappingURL=index.css.map */
|